logo资料库

编程实现简单的IP协议分析器课程设计以及源代码.doc

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
《计算机网络》
课程设计报告
报告成绩 《计算机网络》 课程设计报告 项目名称 编程实现简单的 IP 协议分析器 学 院 专业班级 学 姓 号 名 指导教师 2011 年 1 月 10 日
一、课程设计要求 1.利用原始套接字实现简单的 IP 协议分析器。 2.系统功能包括: 2.1 原始套接字与网卡绑定,并接收流经网卡的所有数据包; 2.2 对 IP 数据包进行分析以获得源 IP 地址和目的 IP 地址; 2.3 对 IP 数据报进行分析以获得其首部详细信息; 2.4 显示分析结果 3 建议使用 VC++ 二、课程设计步骤与内容 首先,把这个程序的功能实现分为两部分,一部分是建立 socket,截取 IP 数据包,另 一部分是对 IP 数据进行分析,显示结果。对两个主要功能的实现详细的说明一下: 1、接收流经网卡的所有数据包 从创建 socket 开始到接收数据包的基本步骤与过程如下: (1)// 检查 Winsock 版本号,WSAData 为 WSADATA 结构对象 WSAStartup(wVersion,&wsadata); (2)// 创建原始套接字 ServerSock=socket(AF_INET,SOCK_RAW,IPPROTO_IP); (3)// 设置 IP 头操作选项,其中 flag 设置为 ture,亲自对 IP 头进行处理 setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)); (4)// 获取本机名 gethostbyname((char*)mname); (5)// 获取本地 IP 地址 pHost = gethostbyname((char*)LocalName)); (6)// 填充 SOCKADDR_IN 结构 myaddr.sin_addr = *(in_addr *)pHostent->h_addr_list[0]; myaddr.sin_family = AF_INET; myaddr.sin_port = htons(8888); (7)// 把原始套接字 ServerSock 绑定到本地网卡地址上 bind(ServerSock,(struct sockaddr *)&myaddr,sizeof(myaddr)); (8)// dwValue 为输入输出参数,为 1 时执行,0 时取消 DWORD dwValue = 1;
(9)// 设置 SOCK_RAW 为 SIO_RCVALL,以便接收所有的 IP 包。其中 SIO_RCVALL // 的定义为: #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) WSAIoctl(ServerSock,SIO_RCVALL,&sioarg,sizeof(sioarg),NULL,0,&dwValue,NULL,NULL); 这就是使套接字与网卡绑定,产接收流经网卡的所有数据包的 9 个基本步骤,按照这 9 个步骤可以很轻松地写绑定原始套接字和网卡,并接收数据包的功能块。 2、分析数据包 先定义 IP,TCP 的结构体: //定义 TCP 首部结构 typedef struct _TCP{ WORD SrcPort; // 源端口 WORD DstPort; // 目的端口 DWORD SeqNum; // 顺序号 DWORD AckNum; // 确认号 BYTE DataOff; // TCP 头长 BYTE Flags; // 标志(URG、ACK 等) WORD Window; // 窗口大小 WORD Chksum; // 校验和 WORD UrgPtr; // 紧急指针 } TCP; //定义 ICMP 首部结构 typedef struct _ICMP{ BYTE Type; BYTE Code; WORD ChkSum; // 类型 // 代码 // 检验和 } ICMP; //定义 UDP 首部结构 typedef struct _UDP { WORD SrcPort; WORD DstPort; WORD Len; WORD ChkSum; } UDP; // 源端口 // 目的端口 // 长度 // 检验和 //定义 IP 首部结构 typedef struct _IP{ union{ BYTE Version; // 版本 BYTE HdrLen; // IHL };
BYTE ServiceType; // 服务类型 WORD TotalLen; // 总长 WORD ID; // 标识 union{ WORD Flags; // 标志 WORD FragOff; // 分段偏移 }; BYTE TimeToLive; // 生命期 BYTE Protocol; // 协议 WORD HdrChksum; // 头校验和 DWORD SrcAddr; // 源地址 DWORD DstAddr; // 目的地址 BYTE Options; // 选项 } IP; 以上就是对这个 IP 数据包分析器所要分析的 IP、TCP、UDP、ICMP 协议的结构定义。接 下来,我们就可以通过相应的结构来取得数据包中相应的信息和内容。在程序中实现这些分 析功能的代码段如下: //相关变量的声明 CString strProtocol,strSrcAddr,strSrcPort,strDstAddr,strDstPort,strSize,strData;//分别为 要输出的要素 TCP* pTCPhead; IP *pIPhead; ICMP *pICMPhead; UDP *pUDPhead; int HdrLen, totallen; BYTE *pdata=NULL; IP ip; TCP tcp; //分析处理 ip=*(IP*)buf; //TCP 结构的指针 //IP 结构的指针 //ICMP 结构的指针 //UDP 结构的指针 //IP 结构对象 //TCP 结构对象 tcp=*(TCP*)(buf+ip.HdrLen); //协议 strProtocol=pDlg->GetProtocolTxt(ip.Protocol); pIPhead=(IP *)buf; HdrLen = pIPhead->HdrLen; HdrLen *= 4; totallen= pIPhead->TotalLen; //源地址 strSrcAddr=inet_ntoa(*(in_addr*)&ip.SrcAddr);
//目的地址 strDstAddr=inet_ntoa(*(in_addr*)&ip.DstAddr); // 以下分析源端口、目的端口和长度 if (!strcmp(strProtocol,"TCP")){ //若协议为 TCP pTCPhead=(TCP *)(buf+HdrLen); strSrcPort.Format("%d",ntohs(pTCPhead->SrcPort)); strDstPort.Format("%d",ntohs(pTCPhead->DstPort)); HdrLen = (pTCPhead->DataOff)>>4; HdrLen *= 4; pdata=((BYTE *)pTCPhead)+HdrLen; totallen -= HdrLen; strData.Format("%s",pdata); } else if (!strcmp(strProtocol,"UDP")){ //若协议为 UDP pUDPhead=(UDP *)(buf+HdrLen); strSrcPort.Format("%d",ntohs(pTCPhead->SrcPort)); strDstPort.Format("%d",ntohs(pTCPhead->DstPort)); pdata=((BYTE *)pUDPhead)+UDP_HEAD_LEN; totallen -= UDP_HEAD_LEN; strData.Format("%s",pdata); } else if (!strcmp(strProtocol,"ICMP")){ //若协议为 ICMP pICMPhead=(ICMP *)(buf+HdrLen); strSrcPort = "-"; strDstPort = "-"; pdata=((BYTE *)pICMPhead)+ICMP_HEAD_LEN; totallen -= ICMP_HEAD_LEN; strData.Format("type:%d code:%d data:%s",pICMPhead->Type,pICMPhead->Code,pdata); } else{ } strSrcPort="-"; strDstPort="-"; strData="-"; //若为其它协议 if(!strcmp(strProtocol,"TCP")||!strcmp(strProtocol,"UDP")||!strcmp(strProtocol,"ICMP")) strSize.Format("%d",totallen); else strSize="-"; pDlg->DisplayData(strProtocol,strSrcAddr,strSrcPort ,strDstAddr ,strDstPort ,strSize ,strData); //DisplayData 为相应的列表框输出函数 从上述代码中可以看到,简单的分析 IP 数据包的过程也就是分析协议类别、源地址、
源端口、目的地址、目的端口、长度、数据等这些基本的要素。然后用特定的方法把这些要 素转换为相应的字符串形式,输出到列表框中。 三、软件说明 本软件的功能主要是用来接收所有经过网卡的 IP 数据包并且作简单的分析,显示出协 议类别、源地址、源端口、目的地址、目的端口、数据长度和数据等,而且仅对 TCP、UDP、 ICMP 协议有效,对于其它协议,只显示协议为?,源地址和目的地址三个要素,其余均为 -。 四、操作界面与操作演示: 本 IP 数据包分析器的操作非常简单,只有三个按钮可以点击,分别为 “开始/停止”按 钮、 ”清空”按钮和”退出”按钮。当点击开始按钮时,按钮的显示变为“停止”,分析器开始 接收所有的 IP 数据包进行分析输出;当点击清空按钮时,列表框里面显示的所有内容将全 部清空;当点击停止按钮时,分析器停止接收数据包,等待响应。点击”退出”按钮可安全退 出软件。另外,对于列表框里某些项目没有显示完整,可拖拉项目的边栏增加长度。操作演 示如下图所示: 图 1 初始界面 初始的界面如图 1 所示,当点击“开始”按钮时,如果绑定成功,并且连接上网络,接 收到数据报时,界面会显示所接收到的所有 IP 数据包的分析后的要素信息。若获取主机名 失败,或绑定网卡失败,或接收数据包失败,则会显示相应的失败提示,如图 2 所示,是 在断开网络连接的情况下得到的失败提示。若按停止,则列表框里所有的内容将不再刷新, 如图 3 所示。此时若按清空按钮,则所有内容会清除,回到图 1 的显示界面。
图 2 接收数据失败 图 3 接收数据并分析输出
分享到:
收藏