计算机网络课程设计实验报告(北京科技大学--arp、ftp、ip包)(3)

2019-08-30 17:51

据包的最大长度是65535B,因此缓冲区的大小不能小于65535B。设置缓冲区后,可利用循环来反复监听接收IP包,用recv()函数实现接收功能。

定义IP头部的数据结构

? 程序需要定义一个数据结构表示IP头部。其代码如下: ? struct IP_HEADER {

? unsigned short ip_version, /*IP的版本号 */ ip_hdr_len; /*IP包头的长度*/ ip_tos; /*IP包的服务类型*/ ip_total_len; /*IP包的总长度*/ ip_id; /*IP包的分段标识*/ ip_flags; /*IP包的分段标志*/

ip_frag_offset; /*IP包的分段偏移*/ ip_ttl; /*IP包的生存时间*/ ip_proto; /*IP包的高层协议*/ ip_hdr_chksum; /*IP包的校验和*/

struct IPADDRESS ip_src_addr; /*IP包的源IP地址*/ ip_dest_addr; /*IP包的目的IP地址*/ }ipheader;

IP包的解析

? 解析IP包的字段有两种策略。针对长度为8位、16位和32位的字段(或子字段)时,可以利用IP-HEADER的成员直接获取。要解析长度不是8位

11 / 37

倍数的字段(或子字段)时,可以利用C语言中的移位以人、及与、或操作完成。

协议的定义

? (包含相应的头文件#include #include):

? DWORD dwIoControlCode=SIO_RCVALL, /*接收所有的IP包*/ dwProtocol=IPPROTO_IP; /*协议类型为IP*/

捕获处理

? 1.加载 Winsock;

? 2.创建一个接收原始IP包的socket连接; 3.绑定到一个接口;

4.进行WSAIoctl设置,接收所有的IP数据包。 ? 代码如下:

if (WSAIoctl(s, dwIoControlCode, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR) 5.接着设定一个线程进行捕获: (1)创建一个接收IP包的链表头;

(2)设置一个标识,为真,则不断进行IP包的捕获; (3)建立一个新的结点,将捕获的数据包加入到该结点;

(4)如果链表的长度达到指定的长度,创建一个线程对该链表的IP包进行解析;再设置一个在IP数据包链表不足给定的长度,而又中止IP捕获时,对链表的处理;

(5)为下一个IP包链表创建一个链表头。

12 / 37

6.建立一个进行IP包解析并显示的线程,进行解析IP数据包,然后显示IP数据包。

实验结果

源代码

#include \

#include \#include #include #include #include

#pragma comment(lib,\#pragma comment(lib,%using namespace std;

//定义IP头

typedef struct _IP_HEADER { union {

13 / 37

BYTE Version; //版本(前4位) BYTE HdrLen; //IHL(后4位),IP头的长度 }; 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;

int main () { SOCKET sock;

WSADATA wsData; ofstream outfile(\ //如果初始化失败,程序退出 if(WSAStartup(MAKEWORD(2,2),&wsData) != 0) { printf(\ return -1; } //建立原始socket if((sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP)) == INVALID_SOCKET) { printf(\ return -1; } //设置IP头操作选项,其中flag设置为true,用户可以亲自对IP头进行处理 BOOL flag = true; if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag)) SOCKET_ERROR) { printf(\ return -1; }

14 / 37

==

//获取主机名 char hostName[128]; if(gethostname(hostName,100) == SOCKET_ERROR) { printf(\ return -1; } //获取本地IP地址 hostent *pHostIP; if((pHostIP = gethostbyname(hostName)) == NULL) { printf(\ return -1; } //填充SOCKADDR_IN结构 sockaddr_in addr_in; addr_in.sin_addr = *(in_addr*)pHostIP->h_addr_list[0]; addr_in.sin_family = AF_INET; addr_in.sin_port = htons(6000); //把原始socket绑定到本地网卡上 if(bind(sock,(PSOCKADDR)&addr_in,sizeof(addr_in)) == SOCKET_ERROR) { printf(\ return -1; } //设置SOCK_RAW为SIORCVALL,以便接收所有的确IP包 #define IO_RCVALL _WSAIOW(IOC_VENDOR,1) DWORD dwBufferLen[10]; DWORD dwBufferInLen = 1; DWORD dwBytesReturned = 0; if(WSAIoctl(sock,IO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen), &dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL) SOCKET_ERROR) { printf(\ return -1; } //设置接收数据包的缓冲区长度 #define BUFFER_SIZE 65535 char buffer[BUFFER_SIZE]; //监听网卡 printf(\开始解析经过本机的IP数据包!\\n\\n\ while(true) {

15 / 37

==


计算机网络课程设计实验报告(北京科技大学--arp、ftp、ip包)(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:怎样成为一名合格的咨询顾问 - 咨询顾问成功宝典 - 图文

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: