Linux网络编程---ICMP协议分析及ping程序实现.docx

上传人:wj 文档编号:82172 上传时间:2022-10-02 格式:DOCX 页数:18 大小:294.20KB
下载 相关 举报
Linux网络编程---ICMP协议分析及ping程序实现.docx_第1页
第1页 / 共18页
Linux网络编程---ICMP协议分析及ping程序实现.docx_第2页
第2页 / 共18页
Linux网络编程---ICMP协议分析及ping程序实现.docx_第3页
第3页 / 共18页
Linux网络编程---ICMP协议分析及ping程序实现.docx_第4页
第4页 / 共18页
Linux网络编程---ICMP协议分析及ping程序实现.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

Linux网络编程---ICMP协议分析及ping程序实现.docx

《Linux网络编程---ICMP协议分析及ping程序实现.docx》由会员分享,可在线阅读,更多相关《Linux网络编程---ICMP协议分析及ping程序实现.docx(18页珍藏版)》请在冰豆网上搜索。

Linux网络编程---ICMP协议分析及ping程序实现.docx

⼀、IP协议

Linux⽹络编程---ICMP协议分析及ping程序实现

IP协议是TCP/IP协议族所依赖的传送机制,提供⽆连接不可靠的数据报服务。

IP的⽆连接特性意味着每个IP报⽂都是独⽴寻径的,因此当

⼀个源主机发送多个报⽂给同⼀⽬的主机时,这些报⽂可能出现错序,丢失或者部分报⽂产⽣错误等现象,因此为了保证数据传送的可靠性,必须在IP层之上通过TCP协议提供有序,带确认数据的传输服务。

1.IP协议格式

IP报⽂由报⽂头部和数据两部分构成,其中头部信息格式如下图所⽰,头部占20-60个字节,⽆选项option时,头部为20字节,最多可以携带40字节选项,报⽂最⼤长度为65535字节。

(1)版本(version)4⽐特,定义了当前IP协议的版本,⽬前通常是数字4,即IPV4

(2)头部长度(ihl)4⽐特,按4字节单位定义IP报⽂的头部总长度,因此未携带任何选项的IP报⽂头部长度为20字节,则ihl值为5(5*4=20),当选项长度达到最⼤值40字节时,ihl长度为15(15*4=60)。

(3)服务类型(tos)8⽐特,⽤于指⽰路由器将如何处理IP报⽂

(4)总长度(tot_len)16⽐特,报⽂头部加数据的总长度,IP报⽂携带的上层数据长度为:

数据长度=总长度-头部长度=总长

度-(ihl*4)。

之所以需要总长度这个字段,是因为在某些情况下底层协议为了满⾜最⼩帧长的限制,会添加填充数据,例如以太协议要求每个数据帧最⼩必须为46字节,当来⾃上层的IP报⽂总长度⼩于46字节时,将添加填充数据以满⾜最⼩帧长,于是必须通过总长度这个字段来记录实际IP层报⽂的总长度,参考如图所⽰:

(5)报⽂标识(id)16⽐特,⽤于标识多个IP分段所对应的原始IP分组的ID。

(6)分段标识(frag)3⽐特,⽤于声明⼀个IP报⽂是否是某个原始报⽂的分段,或者声明是否允许⼀个IP原始报⽂被分段。

(7)分段偏移(offset)13⽐特,标识⼀个IP分段的数据在原始IP报⽂中的偏移值,注意该值,必须是8的整数倍。

(8)⽣存时间(ttl)8⽐特,⼀个IP报⽂在⽹上所允许的最⼤⽣存时间,该值实际为最⼤跳数,当源主机产⽣⼀个IP报⽂后,该字段将填写⼀个初始值,随后该报⽂每经过⼀个路由器则路由器将对该字段值进⾏减⼀操作,当该字段值变成0后,路由器将丢弃此报⽂。

(9)协议(protocol)8⽐特,⽤于标识IP报⽂承载的上层数据的协议类型,例如可以是TCP,UDP,ICMP和IGMP等。

(10)头部校验和(check)16⽐特,IP头部数据的检验和。

(11)源地址(saddr)32⽐特,报⽂的源IP地址。

(12)⽬的地址(daddr)32⽐特,报⽂的⽬的IP地址。

(13)选项(option)变长且最⼤不超过40字节。

2.IP协议头的c语⾔定义

structiphdr

{

#ifdefined_LITTLE_ENDIAN_BITFIELD//⼩端机u8hlen:

4,

ver:

4;

#elifdefined_BIG_ENFIAN_BITFELD//⼤端机u8ver:

4,

hlen:

4;#endif

u8tos;

u16tot_len;u16id;

u16frag_off;u8ttl;

u8protocol;u16check;u32saddr;u32daddr;

};

⼆、ICMP协议

(1)ICMP消息类型

ICMP消息分为两⼤类,错误报告消息和查询消息,这⾥仅介绍查询消息,每个查询消息类型均包括⼀对请求和应答消息。

(2)ICMP消息通⽤格式

ICMP消息包括8字节的头部和变长数据两个部分,其中所有消息类型头部的前4个字节均相同,头部其余4个字节随消息的不同⽽不同。

如图所⽰:

ICMP消息头部的头4个字节分别是消息类型tye,消息代码code和校验和checksum,其中checksum字段包括头部和数据两部分,⽽并⾮仅头部,查询消息的数据部分data包含了⽤于查询所需要的额外数据。

(3)ICMP查询请求和应答消息格式

ICMP回应请求(echo-request)和应答消息(echo-reply)⽤于诊断两个系统(主机或路由器)之间是否能够进⾏通信,当其中⼀⽅发送回应请求消息给另⼀⽅时,接收到回应请求消息的主机或者路由器将以应答消息进⾏应答,常⽤的⽹络ping命令就是基于此消息类型的,如下图所⽰其中type字段为8表⽰回应请求,0表⽰应答,code字段暂未是要你管,为0.

(4)ICMP消息格式的C语⾔定义

structicmphdr

{

u8type;u8code;

u16checksum;union

{

struct

{

u16id;

u16sequence;

}echo;

u32gateway;struct

{

u16unused;u16mtu;

}frag;//pmtu发现

}un;

//u32icmp_timestamp[2];//时间戳

//ICMP数据占位符

u8data[0];

#defineicmp_idun.echo.id

#defineicmp_sequn.echo.sequence

};

ping程序实现:

#include

#include#include#include#include#include#include#include#include#include#include#include

#ifndef_LITTLE_ENDIAN_BITFIELD#define_LITTLE_ENDIAN_BITFIELD#endif

#defineIP_HSIZEsizeof(structiphdr)//定义IP_HSIZE为ip头部长度#defineIPVERSION4//定义IPVERSION为4,指出⽤ipv4

#defineICMP_ECHOREPLY0//Echo应答

#defineICMP_ECHO 8//Echo请求

#defineBUFSIZE1500 //发送缓存最⼤值

#defineDEFAULT_LEN56//ping消息数据默认⼤⼩

//数据类型别名

typedefunsignedcharu8;

typedefunsignedshortu16;

typedefunsignedintu32;

//ICMP消息头部structicmphdr

{

u8type;u8code;

u16checksum;union

{

struct

{

u16id;

u16sequence;

}echo;

u32gateway;struct

{

u16unused;u16mtu;

}frag;//pmtu发现

}un;

u32icmp_timestamp[2];//时间戳

//ICMP数据占位符

u8data[0];

#defineicmp_idun.echo.id

#defineicmp_sequn.echo.sequence

};

#defineICMP_HSIZEsizeof(structicmphdr)structiphdr

{

#ifdefined_LITTLE_ENDIAN_BITFIELDu8hlen:

4,

ver:

4;

#elifdefined_BIG_ENFIAN_BITFELDu8ver:

4,

hlen:

4;#endif

u8tos;

u16tot_len;u16id;

u16frag_off;u8ttl;

u8protocol;u16check;u32saddr;u32daddr;

};

charhello[]="hellothisisapingtest.";char*hostname;//被ping的主机

intdatalen=DEFAULT_LEN;//ICMP消息携带的数据长度

charsendbuf[BUFSIZE];charrecvbuf[BUFSIZE];

intnsent;//发送的ICMP消息序号

intnrecv;

pid_tpid;//ping程序的进程pid

structtimevalrecvtime;//收到ICMP应答的时间戳intsockfd;//发送和接收原始套接字

structsockaddr_indest;//被ping主机的ip

structsockaddr_infrom;//发送ping应答消息的主机ip

structsigactionact_alarm;structsigactionact_int;

//设置的时间是⼀个结构体,倒计时设置,重复倒时,超时值设为1秒structitimervalval_alarm;

//函数原型

voidalarm_handler(int);//SIGALRM处理程序voidint_handler(int);//SIGINT处理程序

voidset_sighandler();//设置信号处理程序voidsend_ping();//发送ping消息

voidrecv_reply();//接收ping应答

u16checksum(u8*buf,intlen);//计算校验和inthandle_pkt();//ICMP应答消息处理

voidget_statistics(int,int);//统计ping命令的检测结果voidbail(constchar*);//错误报告

intmain(intargc,char**argv)//argc表⽰隐形程序命令⾏中参数的数⽬,argv是⼀个指向字符串数组指针,其中每⼀个字符对应⼀个参数

{

val_alarm.it_interval.tv_sec=1;val_alarm.it_interval.tv_usec=0;val_alarm.it_value.tv_sec=0;val_alarm.it_value.tv_usec=1;

structhostent*host;//该结构体属于include

inton=1;

if((host=gethostbyname(argv[1]))==NULL)

{//gethostbyname()返回对应于给定主机名的包含主机名字和地址信息的结构指针,perror("cannotunderstandthehostname");//理解不了输⼊的地址

exit

(1);

}

hostname=argv[1];//取出地址名

memset(&dest,0,sizeofdest);//将dest中前sizeof(dest)个字节替换为0并返回s,此处为初始化,给最⼤内存清零dest.sin_family=PF_IN

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1