当前位置:文档之家› ip数据报解析源地址目的地址

ip数据报解析源地址目的地址

ip数据报解析源地址目的地址青岛农业大学理学与信息科学学院计算机网络综合实习报告题目IP数据报解析源地址/目的地址专业计算机科学与技术学号姓名指导教师日期2014年11月8日目录一、设计任务和目的 .............................................. - 2 -二、设计要求 .......................................................... - 2 -三、设计内容 .......................................................... - 2 -3.1原理概述: ................................................... - 2 -3.1.1 点分十进制表示法:..................... - 2 -3.1.2 IP数据报格式:.......................... - 2 -3.2 运行结果及分析........................................ - 4 -3.2.1程序运行及截图.............................. - 4 -3.2.2 分析................................................. - 5 -四、设计方案改进及建议 ...................................... - 5 -五、总结体会 .......................................................... - 6 -六、主要参考文献 .................................................. - 6 -七、附录 .................................................................. - 6 -附录1 程序流程图.......................................... - 6 - 附录2 程序源代码及解释.............................. - 8 -一、设计任务和目的设计一个解析IP数据包的程序,并根据这个程序,从IP数据报头中解析出源地址和目的地址等相关问题,从而对IP层的工作原理有更好的理解和认识。

通过实际操作,加深对计算机网络的理解,了解计算机网络应用的灵活性,加深对IP数据报格式的了解,点分十进制理解,巩固所学习的C语言。

二、设计要求编写计算机程序,从网络捕获数据包,从IP数据报头中解析出源地址和目的地址,将它们以点分十进制形式输出。

三、设计内容3.1原理概述:3.1.1 点分十进制表示法:对主机或路由器来说,ip地址都是32位的二进制代码,为了提高可读性,我们常常把32位的ip地址中的每8位用其等效的十进制数字表示,并且在这些数字之间加上一个点,这就叫做点分十进制表示法(dotted decimal notation)。

例如:一个ip地址:100000000 00001011 00000011 00011111 用点分十进制表示为:128.11.3.31读起来要方便得多。

3.1.2 IP数据报格式:IP协议所处理的数据单元称为IP数据报。

其格式如下:图3-1 数据报格式图[1]IP数据报由首部和数据两部分组成,首部又分为定长部分和变长部分。

◆版本(VER):4位,表示数据报的IP协议版本,当前的IP协议版本号为4,即IPv4;下一代网络协议IPv6,版本号为6.◆首部长度(HLEN):4位,表示以字长(4字节)为单位的数据报首部长度。

◆服务类型(SERVICE TYPE): 8位,规定本数据报的处理方式。

前三位是优先级,0-7,0表示最低,7最高(最重要),但目前的IPv4没有使用优先级。

后4位是TOS,表示本数据报在传输过程中所希望得到的服务,D--最小延迟(minimize delay);T--最大吞吐率(maximize throughout);R--最高可靠性(maximize reliability);C--最低成本(minimize cost)。

值得注意的有2点:①服务类型代表用户的希望,并不具有强制性,目前许多设备TCP/IP中不支持服务类型特性。

②在D、T、R、C这4个参数中只能设置其中一个。

◆数据报总长度:在IP数据报封装到以太网帧中进行传输时很有用.◆标识(IDENTIFICATION):16位每个IP数据报都有一个本地唯一的标识符,它由信源机赋予IP数据报。

每次自动加1.◆标志(FLAGS):3位,表示该IP数据报是否允许分片以及是否最后一片。

◆片偏移(FRAGMENTATION OFFSET):表示本片数据在他所属原始数据报数据区的偏移量。

◆生存时间(time to live,TTL): 8位,◆协议(PROTOCOL):8位,指明被IP数据报封装的协议:ICMP=1,IGMP=2,TCP=6,EGP=8,UDP=17,OSPF=89.◆首部校验和(HEADER CHECKSUM):16位,保证首部数据完整性。

◆源IP地址(SOURCE ADDRESS):32位(IPv4中),发送方源地址。

◆目的地址(DESTINATION ADDRESS): 32位(IPv4中),最总接收方IP地址。

◆IP选项(IP OPTIONS):变长字段,传输数据报时的附加功能。

本实验的功能主要是实现将32位的二进制表示成十进制数图3-2 IP组成结构图[2]3.2 运行结果及分析3.2.1程序运行及截图图3-2-1 程序运行图图3-2-2 运行结果图3.2.2 分析IP数据报的首部长度和数据长度都是可变长的,但总是4字节的整数倍。

对于IPv4,4位版本字段是4。

4位首部长度的数值是以4字节为单位的,最小值为5,也就是说首部长度最小是4x5=20字节,也就是不带任何选项的IP首部,4位能表示的最大值是15,也就是说首部长度最大是60字节。

8位TOS字段有3个位用来指定IP数据报的优先级(目前已经废弃不用),还有4个位表示可选的服务类型(最小延迟、最大呑吐量、最大可靠性、最小成本),还有一个位总是0。

总长度是整个数据报(包括IP首部和IP 层payload)的字节数。

每传一个IP数据报,16位的标识加1,可用于分片和重新组装数据报。

3位标志和13位片偏移用于分片。

TTL(Time to live)是这样用的:源主机为数据包设定一个生存时间,比如64,每过一个路由器就把该值减1,如果减到0就表示路由已经太长了仍然找不到目的主机的网络,就丢弃该包,因此这个生存时间的单位不是秒,而是跳(hop)。

协议字段指示上层协议是TCP、UDP、ICMP还有IGMP。

然后是校验和,只校验IP首部,数据的校验由更高层协议负责。

IPv4的IP地址长度为32位。

选项字段的解释从略。

四、设计方案改进及建议首先理解点分十进制表示方法的运用,理解IP数据报的格式,利用C语言设计程序以点分十进制表示输出IP数据报头源/目的地址。

从网络抓取数据包作为源操作数,再生成32位二进制数作为目的操作数,用编程实现将二进制数转化成十进制数,以点分的形式输出在屏幕上。

五、总结体会通过本次课程设计,让我学到了很多。

经过实习,通过实际操作,对计算机网络加深了理解。

才知道计算机网络的可以应用的很灵活,而且加深了对IP数据报格式的了解,点分十进制理解,而且对于C语言也进行了巩固。

在实习中并不是一番风顺的,但是经过努力最终解决了这些困难,让我认识到了坚持的重要性。

总的来说通过实习是我收获不小,也让我认识到了认真学习知识的重要性。

希望学校以后多提供这样的机会。

本次实习,其目的是将以前所学的计算机网络理论知识上升为实践,在编程的基础上进一步了解计算机通信交流以及组网的方法,实践就要求对知识的掌握更加的系统化。

在实习之初,仔细的查找了相关的资料,了解与本实习有关的知识,对IP数据报报头的格式更进一步的复习和掌握,并查找最前沿的资料充实自己,力求将自己的实习做得的更加全面,在实习的准备过程中了解到,在实际的网络管理中大多使用的sniffer 软件对流经网络的数据进行抓取和处理以及分析的过程也可以通过软件的设置将所需数据显示在终端上,本实验所要求处理的任务是将IP数据报报头中的源和目的IP地址以点分十进制的形式输出,程序的实现比较简单,结合以前C语言的基础和编程方法使用随机数生成指令,以及调用C语言库函数实现将二进制的源和目的IP地址转化为点分十进制。

在实验过程中曾试图使用套接字编程实现数据包的抓取,然后使用解析程序分析数据报的报头,但是在具体的实现过程中由于现在使用的VC++平台不包含mstcpip.h库文件,所以程序没有得到验证,但也在思考和设计的过程中学到了很多知识。

六、主要参考文献[1] 谢希仁《计算机网络》(第5版)电子工业出版社 2008[2] 殷肖川《网络编程与开发技术》西安交通大学出版社 2003七、附录附录1 程序流程图图7-1 程序流程图附录2 程序源代码及解释#include "winsock2.h"#include "ws2tcpip.h"#include "iostream.h"#include "stdio.h"#pragma comment(lib,"ws2_32.lib")typedef struct _IP_HEADER //定义IP头{union{BYTE Version; //版本(前4位)BYTE HdrLen; //IHL(后4位),报头标长};BYTE ServiceType; //服务类型WORD TotalLen; //总长WORD ID; //标识union{WORD Flags; //标志(前3位)WORD FragOff; //分段偏移(后13位)};BYTE TimeToLive; //生命期BYTE Protocol; //协议WORD HdrChksum; //头校验和DWORD SrcAddr; //源地址DWORD DstAddr; //目的地址BYTE Options; //选项}IP_HEADER;//逐位解析IP头中的信息void getVersion(BYTE b, BYTE & version){version=b>>4; //右移4位,获取版本字段}void getIHL(BYTE b,BYTE & result){result=(b&0x0f)*4; //获取头部长度字段}char * parseServiceType_getProcedence(BYTE b) {switch(b>>5) //获取服务类型字段中优先级子域{case 7:return "Network Control"; break;case 6:return "Internet work Control"; break;case 5:return "CRITIC/ECP"; break;case 4:return "Flash Override"; break;case 3:return "Flsah";break;case 2:return "Immediate";break;case 1:return "Priority";break;case 0:return "Routine";break;default:return "Unknow";break;}}char * parseServiceType_getTOS(BYTE b){b=(b>>1)&0x0f; //获取服务类型字段中的TOS子域switch(b){case 0:return "Normal service";break;case 1:return "Minimize monetary cost";break;case 2:return "Maximize reliability";break;case 4:return "Maximize throughput";break;case 8:return "Minimize delay";break;case 15:return "Maximize security";break;default:return "Unknow";}}void getFlags(WORD w,BYTE & DF,BYTE & MF) //解析标志字段{DF=(w>>14)&0x01;MF=(w>>13)&0x01;}void getFragOff(WORD w,WORD & fragOff) //获取分段偏移字段{fragOff=w&0x1fff;}char * getProtocol(BYTE Protocol) //获取协议字段共8位{switch(Protocol) //以下为协议号说明:{case 1:return "ICMP";case 2:return "IGMP";case 4:return "IP in IP";case 6:return "TCP";case 8:return "EGP";case 17:return "UDP";case 41:return "IPv6";case 46:return "RSVP";case 89:return "OSPF";default:return "UNKNOW";}}void ipparse(FILE* file,char* buffer){IP_HEADER ip=*(IP_HEADER*)buffer; //通过指针把缓冲区的内容强制转化为IP_HEADER 数据结构fseek(file,0,SEEK_END);BYTE version;getVersion(ip.Version,version);fprintf(file,"版本号=%d\r\n",version);BYTE headerLen;getIHL(ip.HdrLen,headerLen);fprintf(file,"报头标长=%d(BYTE)\r\n",headerLen);fprintf(file,"服务类型=%s,%s\r\n",parseServiceType_getProcedence(ip.ServiceType),parseServiceType_getTOS(ip.ServiceType));fprintf(file,"总长度=%d(BYTE)\r\n",ip.TotalLen);fprintf(file,"标识=%d\r\n",ip.ID);BYTE DF,MF;getFlags(ip.Flags,DF,MF);fprintf(file,"标志DF=%d,MF=%d\r\n",DF,MF);WORD fragOff;getFragOff(ip.FragOff,fragOff);fprintf(file,"分段偏移值=%d\r\n",fragOff);fprintf(file,"生存期=%d (hopes)\r\n",ip.TimeToLive);fprintf(file,"协议=%s\r\n",getProtocol(ip.Protocol));fprintf(file,"头校验和=0x%0x\r\n",ip.HdrChksum);fprintf(file,"源IP地址=%s\r\n",inet_ntoa(*(in_addr*)&ip.SrcAddr));fprintf(file,"目的IP地址=%s\r\n",inet_ntoa(*(in_addr*)&ip.DstAddr));fprintf(file,"---------------------------------------------\r\n" );}int main(int argc,char* argv[]){if(argc !=2){printf("usage eror!\n");return -1;}FILE * file;if((file=fopen(argv[1],"wb+"))==NULL){printf("fail to open file %s",argv[1]);return -1;}WSADATA wsData;if(WSAStartup(MAKEWORD(2,2),&wsData)!=0)printf("WSAStartup failed!\n");return -1;}//建立套接字SOCKET sock;if((sock=socket(AF_INET,SOCK_RAW,IPPROTO _IP))==INV ALID_SOCKET){printf("create socket failed!\n");return -1;}BOOL flag=TRUE;//设置IP头操作选项,用户可对IP头处理if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(c har*)&flag,sizeof(flag))==SOCKET_ERROR){printf("setsockopt failed!\n");return -1;}char hostName[128];if(gethostname(hostName,100)==SOCKET_ERR{printf("gethostname failed!\n");return -1;}//获取本地地址hostent * pHostIP;if((pHostIP=gethostbyname(hostName))==NULL) {printf("gethostname failed!\n");return -1;}//填充SOCKADDR_IN结构sockaddr_in addr_in;addr_in.sin_addr=*(in_addr*)pHostIP->h_addr_l ist[0];addr_in.sin_family=AF_INET;addr_in.sin_port=htons(6000);if(bind(sock,(PSOCKADDR)&addr_in,sizeof(addr _in))==SOCKET_ERROR){printf("bind failed!\n");return -1;}//把socket绑定到本地网卡DWORD dwValue=1;//设置SOCK_RAW为SIO_RCV ALL,能接收所有IP包#define IO_RCV ALL _WSAIOW(IOC_VENDOR,1) DWORD dwBufferLen[10];DWORD dwBufferInLen=1;DWORD dwBytesReturned=0;if(WSAIoctl(sock,IO_RCV ALL,&dwBufferInLen, sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBuff erLen),&dwBytesReturned,NULL,NULL)==SOCKE T_ERROR){printf("ioctlsocket failed!\n");return -1;}//设置接受数据包缓冲区长度#define BUFFER_SIZE 65535char buffer[BUFFER_SIZE];//监听网卡printf("开始解析经过本机的IP数据包:\n");while(true){int size=recv(sock,buffer,BUFFER_SIZE,0);if (size>0){ipparse(stdout,buffer);ipparse(file,buffer);}}fclose(file);return 0;}课程设计成绩评定表。

相关主题