Linux内核源代码解析——IP切碎了又粘好
来源:互联网 发布:godaddy转阿里云 编辑:程序博客网 时间:2024/05/16 00:25
IP分片定义如下:
/* Describe an IP fragment. */struct ipfrag { intoffset;/* offset of fragment in IP datagram*/ intend;/* last byte of data in datagram*/ intlen;/* length of this fragment*/ struct sk_buff *skb;/* complete received fragment*/ unsigned char*ptr;/* pointer into real fragment data*/ struct ipfrag*next;/* linked list pointers*/ struct ipfrag*prev;};IP datagram定义如下:
/* Describe an entry in the "incomplete datagrams" queue. */struct ipq { unsigned char*mac;/* pointer to MAC header*/ struct iphdr*iph;/* pointer to IP header*/ intlen;/* total length of original datagram*/ shortihlen;/* length of the IP header*/ short maclen;/* length of the MAC header*/ struct timer_list timer;/* when will this queue expire?*/ struct ipfrag*fragments;/* linked list of received fragments*/ struct ipq*next;/* linked list pointers*/ struct ipq*prev; struct device *dev;/* Device - for icmp replies */};IP分片构建如下:
/* Create a new fragment entry. */static struct ipfrag *ip_frag_create(int offset, int end, struct sk_buff *skb, unsigned char *ptr){ struct ipfrag *fp; fp = (struct ipfrag *) kmalloc(sizeof(struct ipfrag), GFP_ATOMIC); if (fp == NULL) { printk("IP: frag_create: no memory left !\n"); return(NULL); } memset(fp, 0, sizeof(struct ipfrag)); /* Fill in the structure. */ fp->offset = offset; fp->end = end; fp->len = end - offset; fp->skb = skb; fp->ptr = ptr; return(fp);}IP分片完整性检查如下:
/* See if a fragment queue is complete. */static int ip_done(struct ipq *qp){ struct ipfrag *fp; int offset; /* Only possible if we received the final fragment. */ if (qp->len == 0) return(0); /* Check all fragment offsets to see if they connect. */ fp = qp->fragments; offset = 0; while (fp != NULL) { if (fp->offset > offset) return(0);/* fragment(s) missing */ offset = fp->end; fp = fp->next; } /* All fragments are present. */ return(1); }从所有的fragments构建出一个IP datagram的代码如下:
/* Build a new IP datagram from all its fragments. */static struct sk_buff *ip_glue(struct ipq *qp){ struct sk_buff *skb; struct iphdr *iph; struct ipfrag *fp; unsigned char *ptr; int count, len; /* Allocate a new buffer for the datagram. */ len = sizeof(struct sk_buff)+qp->maclen + qp->ihlen + qp->len; if ((skb = alloc_skb(len,GFP_ATOMIC)) == NULL) { printk("IP: queue_glue: no memory for glueing queue 0x%X\n", (int) qp); ip_free(qp); return(NULL); } /* Fill in the basic details. */ skb->len = (len - qp->maclen); skb->h.raw = skb->data; skb->free = 1; /* Copy the original MAC and IP headers into the new buffer. */ ptr = (unsigned char *) skb->h.raw; memcpy(ptr, ((unsigned char *) qp->mac), qp->maclen);/*printk("Copied %d bytes of mac header.\n",qp->maclen);*/ ptr += qp->maclen; memcpy(ptr, ((unsigned char *) qp->iph), qp->ihlen);/*printk("Copied %d byte of ip header.\n",qp->ihlen);*/ ptr += qp->ihlen; skb->h.raw += qp->maclen; /*printk("Protocol = %d\n",skb->h.iph->protocol);*/ count = 0; /* Copy the data portions of all fragments into the new buffer. */ fp = qp->fragments; while(fp != NULL) { if(count+fp->len>skb->len) { printk("Invalid fragment list: Fragment over size.\n"); ip_free(qp); kfree_skb(skb,FREE_WRITE); return NULL; }/*printk("Fragment %d size %d\n",fp->offset,fp->len);*/ memcpy((ptr + fp->offset), fp->ptr, fp->len); count += fp->len; fp = fp->next; } /* We glued together all fragments, so remove the queue entry. */ ip_free(qp); /* Done with all fragments. Fixup the new IP header. */ iph = skb->h.iph; iph->frag_off = 0; iph->tot_len = htons((iph->ihl * sizeof(unsigned long)) + count); skb->ip_hdr = iph; return(skb);}24岁生日之后写的第一篇技术文章。
年龄越大,人越懒,除了源代码什么都不想说了。
原谅我一生不羁放纵爱自由。。。
0 0
- Linux内核源代码解析——IP切碎了又粘好
- Linux内核源代码解析之——小弟我与神童聊Linux内核
- Linux内核源代码解析之——欲三次握手,先构造传输控制块!
- 【linux内核·ip碎片重组】IP Reassembly -- 比较透彻的注释解析了IP碎片重组的过程
- Linux内核源代码分析——Linux内核的入口
- linux内核ip分片函数ip_fragment解析
- 好状态又回来了
- 好开心!又下雨了!
- 你们好, 又重逢了
- linux内核ip分片函数ip_fragment解析(转贴)
- Linux内核源代码漫游
- Linux 内核源代码漫游
- linux 内核源代码学习
- Linux内核源代码结构
- linux内核源代码下载
- Linux内核源代码目录
- 安装Linux内核源代码
- linux内核源代码目录
- win7下卸载linux系统(不用windows光盘)
- block的底层实现
- 在 Xcode 7 中安装 Alcatraz(可用)
- 日常总结 windows的cmd窗口进入指定文件夹(即目录)和cmd默认窗口大小设置
- 微型嵌入式操作系统对比
- Linux内核源代码解析——IP切碎了又粘好
- 切换Fragment,改变Toolbar menu的显示样式
- Redis的Client设计
- MariaDB 5.5.34 QPS bug手记
- quick-cocos2d-x(一)开发环境配置
- Mysql与Oracle group by的不同之处
- 『Algorithm』守望者的逃离-解题报告
- C语言版Mysql存储块(page)格式读取工具(源代码)
- 数组指针的意义