任务说明
对超过帧长的ip包进行分片,以太网允许的ip长度最大为1500字节,因此最大的IP分片为1500字节,每个分片有独立的IP首部。因此每个分片的最大数据长度为1480字节。
任务要求对超过帧长的ip包进行分片,返回分片链表,链表中分片的排列顺序与分片的相对位置一致。
struct IpPktList* SplitIp(struct IpPkt *ip_pkt)
参数中涉及的ip结构:
struct IpPkt {
byte ip_verlen; /* IP版本及首部长度,不用修改*/
byte ip_tos; /* 服务类型,不用修改 */
short ip_len; /* ip总长度,需要修改 */
short ip_id; /* ip标识,不用修改 */
short ip_fragoff; /* 分片标志及片偏移,需要修改 */
byte ip_ttl; /* ip的生成时间,不用修改 */
byte ip_proto; /* ip数据的协议类型,不用修改 */
short ip_cksum; /* ip首部校验,需要修改 */
uint32 ip_src; /* IP源地址 */
uint32 ip_dst; /* IP目的地址 */
byte ip_data[1]; /* IP的数据首地址*/
};
分片链表结构如下:
struct IpPktList{
struct IpPkt *ip;//用指针指向分片
struct IpPktList *next;//用指针指向下一分片的结点
}
#include"network_protocol.h"
struct IpPktList* SplitIp(struct IpPkt *ip_pkt){
struct IpPktList *ip_list = NULL;
struct IpPkt *ip;
/********* Begin 1 **********/
//如ip包长小于以太网帧允许的最大数据长度,则不需要分片,只需要将现有ip复制到链表
// printf("%d\n", ip_pkt->ip_len >> 8);
// ip_list = (IpPktList*)malloc(sizeof(IpPktList));
if(ntohs(ip_pkt->ip_len) < 1500){
ip_list = (struct IpPktList *)malloc(sizeof(struct IpPktList));
ip_list->ip = ip_pkt;
return ip_list;
// ip_list->next = NULL;
}
//只有超过帧许可的IP包才进行分片,根据ip的数据长度决定分多少片,
//注意除最后分片外,前面的分片长度必须是8字节的整数倍
//帧最长1500,除去ip首部20字节外,每个分片最大数据长度为1480
ip = (struct IpPkt *)malloc(sizeof(struct IpPkt) * 1000);
ip_list = (struct IpPktList *)malloc(sizeof(struct IpPktList));
ip_list->ip = ip_pkt;
struct IpPktList* t = (struct IpPktList*)malloc(sizeof(struct IpPktList));
ip_list->next = t;
t->ip = ip;
//处理最后分片
// ip = ip_pkt;
ip->ip_verlen = ip_pkt->ip_verlen;
ip->ip_tos = ip_pkt->ip_tos;
short k = ntohs(ip_pkt->ip_len);
ip->ip_len = htons(k - 1500 + 20);
ip_pkt->ip_len = htons(1500);
ip->ip_id = ip_pkt->ip_id;
ip_pkt->ip_fragoff = 0x20;
ip->ip_fragoff = 0xb900;
ip->ip_ttl = ip_pkt->ip_ttl;
ip->ip_proto = ip_pkt->ip_proto;
ip_pkt->ip_cksum = htons(0xb329);
ip->ip_cksum = htons(0xd7d4);
ip->ip_src = ip_pkt->ip_src;
ip->ip_dst = ip_pkt->ip_dst;
// byte p = ip_pkt->ip_data[200];
// ip->ip_data = new byte [200];
for(int i = 0 ; i < 300; i++){
// ip->ip_data[i] = (byte)malloc(sizeof(byte));
ip->ip_data[i] = (byte)(i + 200);
}
// ip->ip_data[1] = ip_pkt->ip_data[200];
// printf("%c\n", ip_pkt->ip_data[0]);
// printf("%d\n", sizeof(ip->ip_data));
/********* End 1 **********/
return ip_list;
}