第13章 原始套接字
Socket_RAW元生套接字捕获网卡数据

引言从事网络安全的技术人员和相当一部分准黑客(指那些使用现成的黑客软件进行攻击而不是根据需要去自己编写代码的人)都一定不会对网络嗅探器(sniffer)感到陌生,网络嗅探器无论是在网络安全还是在黑客攻击方面均扮演了很重要的角色。
通过使用网络嗅探器可以把网卡设置于混杂模式,并可实现对网络上传输的数据包的捕获与分析。
此分析结果可供网络安全分析之用,但如为黑客所利用也可以为其发动进一步的攻击提供有价值的信息。
可见,嗅探器实际是一把双刃剑。
虽然网络嗅探器技术被黑客利用后会对网络安全构成一定的威胁,但嗅探器本身的危害并不是很大,主要是用来为其他黑客软件提供网络情报,真正的攻击主要是由其他黑软来完成的。
而在网络安全方面,网络嗅探手段可以有效地探测在网络上传输的数据包信息,通过对这些信息的分析利用是有助于网络安全维护的。
权衡利弊,有必要对网络嗅探器的实现原理进行介绍。
嗅探器设计原理嗅探器作为一种网络通讯程序,也是通过对网卡的编程来实现网络通讯的,对网卡的编程也是使用通常的套接字(socket)方式来进行。
但是,通常的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取到达的数据包。
而网络嗅探器的目的恰恰在于从网卡接收所有经过它的数据包,这些数据包即可以是发给它的也可以是发往别处的。
显然,要达到此目的就不能再让网卡按通常的正常模式工作,而必须将其设置为混杂模式。
具体到编程实现上,这种对网卡混杂模式的设置是通过原始套接字(raw socket)来实现的,这也有别于通常经常使用的数据流套接字和数据报套接字。
在创建了原始套接字后,需要通过setsockopt()函数来设置IP头操作选项,然后再通过bind()函数将原始套接字绑定到本地网卡。
为了让原始套接字能接受所有的数据,还需要通过ioctlsocket()来进行设置,而且还可以指定是否亲自处理IP头。
Windows网络编程基础-习题解答

《Windows网络编程基础》习题解答第一章网络应用程序设计基础习题1.TCP/IP协议栈的五个层次是什么?在这些层次中,每层的主要任务是什么?解答:TCP/IP参考模型分为五个层次:应用层、传输层、网络层、链路层和物理层。
以下分别介绍各层的主要功能。
应用层是网络应用程序及其应用层协议存留的层次。
该层包括了所有与网络相关的高层协议,如文件传输协议(File Transfer Protocol,FTP)、超文本传输协议(Hypertext Transfer Protocol,HTTP)、Telent(远程终端协议)、简单邮件传送协议(Simple Mail Transfer Protocol,SMTP)、因特网中继聊天(Internet Relay Chat,IRC)、网络新闻传输协议(Network News Transfer Protocol,NNTP)等。
传输层的功能是使源端主机和目标端主机上的对等实体可以进行会话。
在传输层定义了两种服务质量不同的协议,即:传输控制协议(Transmission Control Protocol,TCP)和用户数据报协议(User Datagram Protocol,UDP)。
网络层是整个TCP/IP协议栈的核心。
它的功能是通过路径选择把分组发往目标网络或主机,进行网络拥塞控制以及差错控制。
链路层负责物理层和网络层之间的通信,将网络层接收到的数据分割成特定的可被物理层传输的帧,并交付物理层进行实际的数据传送。
物理层的任务是将该帧中的一个一个比特从一个节点移动到下一个节点。
该层中的协议仍然是链路相关的,并且进一步与链路(如双绞线、单模光纤)的实际传输媒体相关。
对应于不同的传输媒体,跨越这些链路移动一个比特的方式不同。
2.请分析路由器、链路层交换机和主机分别处理TCP/IP协议栈中的哪些层次?解答:路由器处理TCP/IP协议栈的物理层、链路层和网络层;链路层交换机处理TCP/IP协议栈的物理层和链路层;主机处理TCP/IP协议栈的物理层、链路层、网络层、传输层和应用层。
《原始套接字编程》课程设计报告

《原始套接字编程》课程设计报告姓名:***班级:9班学号:********《原始套接字编程》课程设计报告班级:11级9班学号:54110904 姓名:王延兴一、设计任务分析(一)实验环境操作系统:Windows编程工具及集成开发环境:VC++(二)实验目的和要求实验目的:掌握原始套接字编程。
实验要求:完成下列功能:(1)利用RAW SOCKET捕获网络数据包的程序模型SOCKET_STREAM 流式套接字SOCKET_DGRAMSOCKET_RAW 原始套接字IPPROTO_IP IP协议IPPROTO_ICMP INTERNET控制消息协议,配合原始套接字可以实现ping的功能IPPROTO_IGMP INTERNET 网关服务协议,在多播中用到在AF_INET地址族下,有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW三种套接字类型。
SOCK_STREAM也就是通常所说的TCP,而SOCK_DGRAM则是通常所说的UDP,而SOCK_RAW 则是用于提供一些较低级的控制的;第3个参数依赖于第2个参数,用于指定套接字所用的特定协议,设为0表示使用默认的协议。
RAW SOCKET能够对较低层次的协议直接访问,网络监听技术很大程度上依赖于它。
(2)能够抓取第二节课的并发服务器程序的服务器端或客户端的应用层数据,即:时间值,打印输出。
二、设计方案同一台主机不同进程可以用进程号来唯一标识,但是在网络环境下进程号并不能唯一标识该进程。
TCP/IP主要引入了网络地址、端口和连接等概念来解决网络间进程标识问题。
套接字(Socket)是一个指向传输提供者的句柄,TCP/IP协议支持3种类型的套接字,分别是流式套接字、数据报式套接字和原始套接字。
流式套接字(SOCKET_STREAM)提供了面向连接、双向可靠的数据流传输服务。
数据报式套接字(SOCKET_ DGRAM)提供了无连接服务,不提供无错保证。
原始套接字tcp包构造

原始套接字tcp包构造想象一下,我们要给远方的小伙伴寄一个超级特别的包裹。
这个包裹就像是tcp 包。
那这个包裹怎么构造呢?我们先来说说包裹里最基本的东西。
就好像我们写信的时候,要有收信人的地址一样,tcp包里面得有目标的地址信息。
比如说,你要把你的小秘密分享给住在隔壁街的好朋友,那你得知道他家的地址才能把你的信送过去。
在tcp包里面,这个地址信息就像是告诉网络这个包裹要送到哪里去。
再说说包裹里的内容。
假如你要给朋友送一个自己画的小画,这个小画就是内容。
在tcp包里面,也有内容部分,这个内容可能是一些文字信息,或者是一些数据。
就像你在纸上写了“今天我看到一只超级可爱的小猫咪”,这就是包裹里的内容。
那这个包裹怎么包起来呢?它有一定的格式。
就像我们折纸盒子包东西的时候,有一定的折法。
tcp包也是这样,它有头部和数据部分。
头部就像是包裹外面写着地址、包裹类型之类信息的地方。
比如说,头部可能会写着这是一个紧急的包裹还是普通的包裹。
如果是紧急的包裹,那网络就会优先把它送到目的地。
我给大家讲个小故事吧。
有一天,小猴子想给小兔子送一个特别的果子。
小猴子把果子放在一个小盒子里,这个小盒子就像是tcp包。
小猴子在盒子上写了小兔子的家的地址,这就是地址信息。
然后小猴子还在盒子上画了一个小标记,表示这个果子是刚摘下来的很新鲜,这就像是tcp包里面的一些特殊标记。
小猴子把盒子包好后,就交给森林邮递员小鸟。
小鸟就根据盒子上的地址把果子送到小兔子家了。
在构造tcp包的时候,还有一些小细节。
比如说,要有一个顺序号。
这个顺序号就像是我们给故事书的每一页标上页码一样。
这样接收的一方就能按照顺序把内容整理好。
就像你把画的好多小画按顺序寄给朋友,朋友就能按照你标的顺序一张一张看,知道这个故事是怎么发展的。
还有一个确认号呢。
这就像是你的朋友收到你的包裹后,给你回了一个小纸条说“我收到包裹啦”。
这个确认号就是告诉发送方,这个包裹已经安全到达啦。
套接字所用的类型

题目:套接字所用的类型摘要:本文探讨了在网络编程中使用的套接字类型,重点介绍了流套接字(SOCK_STREAM)、数据报套接字(SOCK_DGRAM)和原始套接字(SOCK_RAW)三种类型。
文章解释了每种类型的套接字如何工作以及它们在网络通信中的优缺点。
一、引言套接字(Socket)是计算机网络编程中的重要概念,它们被用来实现网络通信的不同层和模型中的数据交互和收发。
套接字类型决定了数据在网络中的传输方式,不同的套接字类型适用于不同的应用场景。
本文将深入探讨网络编程中常见的套接字类型以及它们的适用范围和特点。
二、流套接字(SOCK_STREAM)流套接字是一种面向连接的套接字类型,通常用于TCP协议。
它提供了一种可靠的、双向的、基于字节流的通信方式。
流套接字确保数据的按序交付和错误控制。
因此,它是实现基于TCP的应用层协议(如HTTP、SMTP等)的理想选择。
优点:1. 可靠的数据传输:通过确认机制、重传丢失的数据包和流量控制来确保数据的可靠传输。
2. 按序交付:确保数据包的顺序与发送时的顺序一致。
3. 错误控制:检测并处理数据传输过程中的错误。
缺点:1. 较高的开销:为确保可靠传输,TCP协议需要维护连接状态,这可能导致较高的开销。
2. 可能产生拥塞:在网络拥堵的情况下,流套接字的性能可能受到影响。
三、数据报套接字(SOCK_DGRAM)数据报套接字是一种无连接的套接字类型,通常用于UDP协议。
它提供了一种不可靠的、无连接的通信方式,适用于对实时性要求较高或能容忍数据丢失的应用场景。
数据报套接字以独立的数据包形式发送数据,不保证数据的按序交付或可靠性。
优点:1. 低开销:UDP协议开销小,适合于传输较少数据的场景。
2. 实时性:无需建立连接,传输延迟低,适合于实时应用场景如语音通话或视频流。
3. 灵活性:允许发送不同大小的数据包,且数据包独立传输。
缺点:1. 不可靠的数据传输:不保证数据包的可靠传输,可能会丢失或重复接收数据包。
rawsocket编程讲解

网络协议回顾对TCP/IP、UDP、Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵。
那么我想问:1. 什么是TCP/IP、UDP?2. Socket在哪里呢?3. Socket是什么呢?4. 你会使用它们吗?什么是TCP/IP、UDP?TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。
UDP(User Data Protocol,用户数据报协议)是与TCP 相对应的协议。
它是属于TCP/IP协议族中的一种。
这里有一张图,表明了这些协议的关系。
TCP/IP协议族包括运输层、网络层、链路层。
现在你知道TCP/IP与UDP的关系了吧。
ICMP协议格式ICMP协议有两种类型:查询报文和差错报文。
其格式如下:差错报文中,Type是差错类型;Code是差错类型中的子类型;Checksum是ICMP的校验和(校验和覆盖ICMP的头和数据)。
其数据部分包含出错包的IP头(包括选项)和IP数据的前八个字节。
地址伪装只处理三种协议(ICMP,TCP,UDP)的差错包,并且只处理三种类型的差错报文,如下:ICMP_DEST_UNREACH(目的不可达),ICMP_SOURCE_QUENCH(源端被关闭),ICMP_TIME_EXCEEDED(超时)。
差错报文中,Type是差错类型;Code是差错类型中的子类型;Checksum是ICMP的校验和(校验和覆盖ICMP的头和数据)。
其数据部分包含出错包的IP头(包括选项)和IP数据的前八个字节。
地址伪装只处理三种协议(ICMP,TCP,UDP)的差错包,并且只处理三种类型的差错报文,如下:ICMP_DEST_UNREACH(目的不可达),ICMP_SOURCE_QUENCH(源端被关闭),ICMP_TIME_EXCEEDED(超时)。
原始套接字网络嗅探器的实现与应用
1 . 3 U D P协议结构
U D P 数 据段 头 比较 简单 .由一 个 8 字 节 的头和 数 据部 分 组成 具体 格式 如表 2 所示。
表2 U D P报 文 格 式
源端 口 ( 1 6 位 )I 目的端 口 ( 1 6位)
U D P长度 ( 1 6位 U D P校验和
#d e f i n e I P DAD DR
9 1 2
1 6
g e t h o s t n a me函数获取 本地 主机 的名称 。
( 2) g e t h O S t b Y n a m e( h O S t —n a m e
#d e f i n e H I — I C M P
G MP #d e f i n e H II
—Байду номын сангаас
#d e f i n e H I — T C P
D P #d e f i n e H IU
—
#d e f i n e HI — OS P F
5
1 . 4 T C P协议结构
2 . 3实现的具体 函数
( 1 )g e t h o s t n a me (h o s t _ n a me .s i z e o f ( h o s t _ n a me ))
术
#d e f i n e I P — H I T Y P E #d e f i n e I P — S A D D R
而T C P 数 据 头则 比较 复 杂 ,以 2 0个 固定 字 节开
始 在 固定头 后 面还可 以有一 些长 度不 固定 的可 选项
2 . 2具体实现
根 据 前文 提 到的把 网卡设 置成 混杂模 式 ,进 而实
原始套接字
传输层 (TCP、UDP)
网络互联层 (IP)
主机到网络 (网络接口层)
应用程序
13.1
原始套接字概述
标准套接字
TCP/UDP IP
网络 核心
原始套接字 用户空间 内核空间
ICMP
套接字与内核的访问关系
13.1
原始套接字概述
原始套接字能够提供以下3种标准套接字不具备的功能:
(0 – 40字节)
数据
全长 ip_len
分片偏移 ip_off
首部校验和 ip_cksum
13.3.1 IP首部结构
31
20 字节
最大 65535 字节
Linux中 struct ip 结构体说明:
struct ip {
#if __BYTE_ORDER == __LITTLE_ENDIAN
接收时间戳
发送时间戳
13.3.2ICMP首部结构
类型:13或14,时间戳请求和应答 代码:0
Linux中 struct icmp 结构体说明(BSD):
struct icmp {
u_int8_t
u_int8_t
icmp_type; icmp_code;
u_int16_t
icmp_cksum;
③ 如果IP以分片形式到达,则所有分片都已经接收到并重组后才传给原始 套接字 。
④ 内核不能识别的协议、格式等传给原始套接字,因此,可以使用原始套 接字实现自定义协议格式。
13.2.3
原始套接收报文
⑤ 如果收到的数据中的协议类型与自定义的原始套接字匹配,则将接收到
的数据复制到原始套接字接收缓冲区中。
② 原始套接字创建完成后,一般还需要指定套接字数据格式类型,使得 原始套接字可确定以从网络接收哪种格式的数据。
Winsock通信原理之详解
详析Winsock通信原理1.Windows套接字技术套接字(Socket)是网络通信的基本构件,最初是由加利福尼亚大学Berke ley学院为UNIX开发的网络通信编程接口,它只能运行在UNIX操作系统,不支持DOS和Windows操作系统。
随着Windows操作系统的日益推广,90年代初,微软和第三方厂商共同制定了一套标准,即Windows Socket规范,简称WinSoc k。
套接字的概念与文件句柄类似,一个套接字就是一个通信标识,由一个短整数表示,实际上就是一个句柄,代表网络协议中的一组数据,该数据包含了通信双方的IP地址和当前的连接状态等信息。
我们知道,如果一个文件被打开,可以通过文件句柄对文件进行读写操作,套接字也一样,只不过套接字提供的函数更多一些。
2.WinSock的通信机制套接字存在于通信区域中,由协议、地址、端口来描述并在网络中用一个三元组来全局唯一标志一个进程:(协议,本地地址,本地端口号),这样一个三元组叫做一个半相关(half-association),它指定连接的每半部分。
一个完整的网间进程通信需要由两个进程组成,并且只能使用同一种高层协议。
也就是说,不可能通信的一端用TCP协议,而另一端用UDP协议。
因此一个完整的网间通信需要一个五元组来标识:(协议,本地地址,本地端口号,远地地址,远地端口号)这样一个五元组,叫做一个相关(association),即两个协议相同的半相关才能组合成一个合适的相关,或完全指定组成一连接。
根据传输协议的不同,套接字可分为3种类型:流式套接字、数据报套接字和原始套接字。
流式套接字提供了一个面向连接的、可靠的、数据无错且按顺序接收的服务,这种套接字对应的是面向连接的传输协议,如TCP/IP协议簇中的TCP。
数据报套接字提供了一个无连接服务,不提供无错保证,数据可能丢失或重复,且接受顺序混乱,该套接字所对应的是无连接传输协议,如TCP/IP协议簇中的UDP。
信息安全系统实践第十一次作业原始套接字、
四川大学计算机学院、软件学院
实验报告
学号:姓名:专业:__软件工程__ 班级:第 12 周
{
tcph=(struct tcphdr*)(buffer+sizeof(struct ether_header)+sizeof(struct ip));
printf("Sourport:%d\n",ntohs(tcph->source));
printf("Destport :%d\n",ntohs(tcph->dest));
}
}
}
}
这里主要修改的地方是:
1、原代码问题:在输出ip那部分需要利用inet_ntop函数,不然程序运行出问题。
2、加入了TCP头部解封,输出源端口和目的端口,当然还要把相应的头文件加入。
其实只要把上面这程序和这次的syn flood结合起来再做点修
*((u_char*)&oddbyte)=*(u_char*)ptr;
sum+=oddbyte;
}
sum = (sum>>16)+(sum & 0xffff);
sum = sum + (sum>>16);
answer=(short)~sum;
return(answer);
}
下面让我们看一下运行效果:
运行syn flood程序,使用不同的伪装IP攻击:
然后检验结果:
数据记录
和计算
结论
通过(结果)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
与发送函数一样,接收报文也用一个线程实现,使 用select()轮询等待报文到来。当接收到一个报文后 使用函数icmp_unpack()来解包和查找报文之前发送 时的记录,获取发送时间,计算收发差值并打印信 息。
(1)接收成功后将合法的报文记录重置为没有使 用,flag为0。
(2)接收报文数量增加1。
(1)获得当前的时间值,按照序列号packet_send 将ICMP报文打包到缓冲区send_buff中后,发送到 目的地址。发送成功后,记录发送报文的状态:
(3)在线程开始进入主循环while(alive)之前,将整 个程序的开始发送时间记录下来,用于在程序退出
的时候进行全局统计,即 gettimeofday(&tv_begin,NULL),将时间保存在变量 tv_begin中。
{
struct ih_idseq {
/*显示数据报*/
u_int16_t icd_id;
u_int16_t icd_seq;
}ih_idseq;
/*数据报ID*/ /*数据报的序号*/
}icmp_hun;
#define icmp_id
icmp_hun.ih_idseq.icd_id
}
原始套接字不需要使用bind()函数,因为进行发送 和接收数据的时候可以指定要发送和接收的目的地 址的IP。当系统对socket进行绑定的时候,发送和 接收的函数可以使用send()和recv()及read()和write() 等不需要指定目的地址的函数。
原始套接字发送报文有如下原则:
参数buf为剥去了以太网部分数据的IP数据报文, len为数据长度。可以利用IP头部的参数快速地跳到 ICMP报文部分,IP结构的ip_hl标识IP头部的长度, 由于ip_hl标识的是4字节单位,所以需要乘以4来获 得ICMP段的地址。
由于需要评估网络状况,在发送数据报文的时候保存发送时间,接收到报文后,计算两个时 刻之间的差值,生成了ICMP源主机和目标主机之间的网络状况的时间评估。
(3)为了防止丢包,select()的轮询时间设置的比 较短。
ping程序的实现使用了两个线程,一个线程 icmp_send()用于发送请求,一个线程icmp_recv()用 于接收远程主机的响应。当变量alive为0时,两个 线程退出。
1.ping数据的数据结构
2.信号SIGINT处理函数 3.查找数组中的标识函数icmp_findpacket() 4.统计数据结果函数icmp_statistics()
ping的客户端方式的类型为8,代码值为0,表示 ICMP的回显请求。类型为0,代码为0时,是ICMP 回显应答。校验和为16位的crc16的算法。
TCP/IP协议栈使用的校验算法是比较经典的,对16 位的数据进行累加计算,并返回计算结果。需要注 意的是对奇数个字节数据的计算,是将最后的有效 数据作为最高位的字节,低字节填充了0。
如果没有设置IP_RINCL,则发送缓冲区指向IP头部后 面数据区域的第一个字节,不需要用户填写IP头部,IP 头部的填写工作由内核进行,内核还进行校验和的计算。
与发送报文类似,接收报文也有相似的规则:
通常可以使用recvfrom()或者recv()及read()获得数据。 当设置了IP_RINCL后,接收的缓冲区为IP头部的第
子网掩码请求协议增加了标识符icmp_id、序列号 icmp_seq和掩码icmp_mask。
UDP的头部结构包含发送端的源端口号、数据接收 端的目的端口号、UDP数据的长度以及UDP的校验 和等信息。
TCP的头部结构主要包含发送端的源端口、接收端 的目的端口、数据的序列号、上一个数据的确认号、 滑动窗口大小、数据的校验和、紧急数据的偏移指 针以及一些控制位等信息。
static struct timeval icmp_tvsub(struct timeval end,struct timeval begin)
{
struct timeval tv;
/*计算差值*/
_sec = _sec - _sec;
_usec = _usec - _usec;
使用原始套接字,可以修改IP数据和IP层之上的各层 数据,构造自己的特定类型的TCP或者UDP的分组。
13.2.1 SOCK_RAW选项 13.2.2 IP_HDRINCL套接字选项 13.2.3 不需要bind()函数
创建原始套接字使用socket()函数。下面的代码创建一 个AF_INET协议族中的原始套接字,协议类型为 protocol。
类型为结构struct pingm_packet的变量pingpacket用于保 存发送数据报文的状态。
/*保存已经发送包的状态值*/ typedef struct pingm_pakcet{
struct timeval tv_begin; /*发送的时间*/
struct timeval tv_end;
对于回显请求的ICMP报文,13.5节的ICMP结构可以简化为如下形式:
struct icmp
{
u_int8_t icmp_type;
ቤተ መጻሕፍቲ ባይዱ
u_int8_t icmp_code;
u_int16_t icmp_cksum;
union
/*消息类型*/ /*消息类型的子码*/ /*校验和*/
ttl=128 time=28.2 ms ^C --- ping statistics -- 6 packets transmitted, 6 received, 0% packet loss, time 5009ms rtt min/avg/max/mdev = 28.199/28.763/30.349/0.744 ms
使用套接字选项IP_HDRINCL设置套接字,在之后 进行的接收和发送时,接收到的数据包含IP的头部。 用户之后需要对IP层相关的数据段进行处理,例如 IP头部数据的设置和分析,校验和的计算等。设置 方法如下:
int set = 1;
if(setsockopt(rawsock, IPPROTO_IP, IP_HDRINCL, &set, sizeof(set))<0){ /*错误处理*/
/*接收到的时间*/
short seq;
/*序列号*/
有接i收nt 到fla回g; 应包0,表示接收到/回*1,应表包示*/ 已经发送但没
}pingm_pakcet;
static pingm_pakcet pingpacket[128];
/*终端信号处理函数SIGINT*/ static void icmp_sigint(int signo) { alive = 0; /*告诉接收和发送线程结束程序*/ gettimeofday(&tv_end, NULL); /*读取程序结束时间*/ tv_interval = icmp_tvsub(tv_end, tv_begin); /*计算一
13.1 概述 13.2 原始套接字的创建 13.3 原始套接字发送报文 13.4 原始套接字接收报文 13.5 原始套接字报文处理时的结构 13.6 ping的例子 13.7 洪水攻击 13.8 ICMP洪水攻击 13.9 UDP洪水攻击 13.10 SYN洪水攻击
int rawsock = socket(AF_INET, SOCK_RAW, protocol);
IPPROTO_IP:IP协议,接收或者发送IP数据包,包含 IP头部。
IPPROTO_ICMP:ICMP协议,接收或者发送ICMP的数 据包,IP的头部不需要处理。
IPPROTO_TCP:TCP协议,接收或者发送TCP数据包。 IPPROTO_UDP:UDP协议,接收或者发送UDP数据包。 IPPROTO_RAW:原始IP包。
下总共所用时间*/ return;
}
函数icmp_findpacket()用于在数组pingpacket中查找 一个报文的标识,参数为–1时表示查找一个空包, 存放已经发送成功的数据报文;其他值表示查找seq 匹配的标识。
icmp_statistics()函数用于统计总体的结果,包含成 功发送的报文数量、成功接收的报文数量、丢失报 文的百分比和总共程序运行的时间。
/*如果接收时间的usec值小于发送时的usec值,从usec域借位*/
if(_usec < 0)
{
_sec --;
_usec += 1000000;
}
return tv;
}
发送报文函数是一个线程,每隔1s向目的主机发送 一个ICMP回显请求报文,它在整个程序处于激活 状态(alive为1)时一直发送报文。
通常情况下可以使用sendto()函数并指定发送目的地址 来发送数据,当已经指定了bind()目标地址的时候可以 使用write()或者send()发送数据。
如果使用setsockopt()设置了选项IP_RINCL,则发送的 数据缓冲区指向IP头部第一个字节的头部,用户发送的 数据包含IP头部之后的所有数据,需要用户自己填写IP 头部和计算校验和并需要对所包含数据进行处理和计算。
一个字节。
当没有设置IP_RINCL的时候,接收的缓冲区为IP数 据区域的第一个字节。
13.5.1 IP头部的结构 13.5.2 ICMP头部结构 13.5.3 UDP头部结构 13.5.4 TCP头部结构
ICMP的头部结构比较复杂,主要包含消息类型 icmp_type,消息代码icmp_code、校验和 icmp_cksum等,不同的ICMP类型其他部分有不同 的实现。