educoder -- ip包的分片

任务说明

对超过帧长的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;
}


  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值