logo资料库

IPv4协议收发实验报告(含代码).docx

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
IPv4协议收发实验
IPv4 协议收发实验 一、 实验目的 IPv4 协议是互联网的核心协议,它保证了网络节点(包括网络设备和主机)在网络层 能够按照标准协议互相通信。IPv4 地址唯一标识了网络节点。在我们日常使用的计算机的 主机协议栈中,IPv4 协议必不可少,它能够接收网络中传送给本机的分组,同时也能根据 上层协议的要求将报文封装为 IPv4 分组发送出去。 本实验通过设计实现主机协议栈中的 IPv4 协议,让学生深入了解网络层协议的基本原 理,学习 IPv4 协议基本的分组接收和发送流程。 另外,通过本实验,学生可以初步接触互联网协议栈的结构和计算机网络实验系统,为 后面进行更为深入复杂的实验奠定良好的基础。 二、 实验要求 根据计算机网络实验系统所提供的上下层接口函数和协议中分组收发的主要流程,独立 设计实现一个简单的 IPv4 分组收发模块。要求实现的主要功能包括: 1.IPv4 分组的基本接收处理; 2.IPv4 分组的封装发送。 三、 实验内容 1. 实现 IPv4 分组的基本接收处理功能 对于接收到的 IPv4 分组,检查目的地址是否为本地地址,并检查 IPv4 分组头部中其它 字段的合法性。提交正确的分组给上层协议继续处理,丢弃错误的分组并说明错误类型。 2. 实现 IPv4 分组的封装发送 根据上层协议所提供的参数,封装 IPv4 分组,调用系统提供的发送接口函数将分组发 送出去。 四、 实验结果及讨论 实验代码见附录。实验结果如下图所示。 实验中,第一个内容发送 IP 包出现校验错误,而根据软件给出的正确校验和无法正确 校验,手动计算校验和后发现校验和的高低位反了,原来是前面的数据已经按照网络序填入, 校验和不需要再转换。更改高低位,就能正确发送了。 剩下的是正确接收 IP 包和错误目标地址的 IP 包实验失败。检查发现用 sum%=65535 来 生成校验和存在问题。当 sum=0xffff 时,经过运算后为 sum=0,从而校验码为 0xffff,而正
确的校验码应为 0,因此采用 sum = (sum >> 16) + (sum & 0xffff)的方法生成 sum。然而最后 一个实验仍然失败。经过调试发现,对于目的地址错误的包,报的是校验和错,因此将校验 和放在最后检验。 经过本实验,我更加深入地理解了校验和的校验机制,并对 IPv4 协议的收发有了更好 的理解。
附录: /* * THIS FILE IS FOR IP TEST */ // system support #include "sysInclude.h" extern void ip_DiscardPkt(char* pBuffer,int type); extern void ip_SendtoLower(char*pBuffer,int length); extern void ip_SendtoUp(char *pBuffer,int length); extern unsigned int getIpv4Address(); // implemented by students int stud_ip_recv(char *pBuffer,unsigned short length) { //获取 ip 头信息 int version = pBuffer[0] >> 4; int IHL = pBuffer[0] & 0x0f; int TTL = (unsigned int)pBuffer[8]; //int header_checksum = ntohs(*(unsigned short int*)(pBuffer + 10)); unsigned int des_add = ntohl(*(unsigned int*)(pBuffer + 16)); if(version != 4) { //检查 version ip_DiscardPkt(pBuffer, STUD_IP_TEST_VERSION_ERROR); return 1; } if(IHL < 5) { //检查 IHL ip_DiscardPkt(pBuffer, STUD_IP_TEST_HEADLEN_ERROR); return 1; } if(TTL <= 0) { //检查 TTL ip_DiscardPkt(pBuffer, STUD_IP_TEST_TTL_ERROR); return 1; } unsigned int myip = getIpv4Address(); if(des_add != myip && des_add !=0xffffffff) //检查目的地址 { ip_DiscardPkt(pBuffer, STUD_IP_TEST_DESTINATION_ERROR);
return 1; } unsigned int sum = 0; for(int i = 1; i <= IHL * 2; i++) { sum += ntohs(*(unsigned short int*)(pBuffer + 2 * (i - 1))); sum = (sum >> 16) + (sum & 0xffff); } sum = (sum >> 16) + (sum & 0xffff); if((unsigned short int)sum != 0xffff) { //检查校验和 ip_DiscardPkt(pBuffer, STUD_IP_TEST_CHECKSUM_ERROR); return 1; } //传给上层 char* ipreceive = new char[length - IHL * 4]; memcpy(ipreceive, pBuffer + IHL * 4, length - IHL * 4); ip_SendtoUp(ipreceive, length - IHL * 4); return 0; } int stud_ip_Upsend(char *pBuffer,unsigned short len,unsigned int srcAddr, unsigned int dstAddr,byte protocol,byte ttl) { char* ipsend = new char[len + 20]; memset(ipsend, 0, sizeof(char)*5 * 4); ipsend[0] = 0x45; unsigned short int total_len = htons(len + 20); ipsend[3] = (char)(total_len >> 8); ipsend[2] = (char)(total_len & 0xff); ipsend[8] = ttl; ipsend[9] = protocol; //校验和区域清零 ipsend[10] = 0; ipsend[11] = 0; unsigned int src = htonl(srcAddr); unsigned int dst = htonl(dstAddr); memcpy(ipsend + 12, &src, sizeof(unsigned int)); memcpy(ipsend + 16, &dst, sizeof(unsigned int)); unsigned int sum = 0; for(int i = 0; i < 10; i++) { sum += *(unsigned short int*)(ipsend + i * 2); sum = (sum >> 16) + (sum & 0xffff);
} sum = (sum >> 16) + (sum & 0xffff); unsigned short int check_sum = 0xffff - (unsigned short int)sum; memcpy(ipsend + 10, &check_sum, sizeof(unsigned short int)); memcpy(ipsend + 20, pBuffer, len); //发送 ip_SendtoLower(ipsend, len + 20); return 0; }
分享到:
收藏