这几天在调试有关网卡驱动的东西,有很多地方不清楚。有关网卡驱动部分主要有两个很重要的结构体:struct net_device 和struct sk_buff。 驱动大部分都是围绕这两个东西进行操作的,包括加协议头尾,去头去尾等。为了搞清楚协议栈如何处理数据包,周末闲来无事就看看内核代码去了解下这部分东西,并做了简要记录:
/*
*sk_buff->h :传输层头 :udp头和tcp头
*sk_buff->nh :网络层头 :ip头
*sk_buff->mac :数据链路层头 :mac头
*
*
*sk_buff->head :指向数据缓冲区头部
*sk_buff->data :指向实际数据的头部
*sk_buff->tail :指向实际数据的尾部
*sk_buff->end :指向数据缓冲区尾部
*
*
*sk_buff控制区 :struct sk_buff所在的区域
*线性数据区 :数据缓冲区域 : sk_buff->head~sk_buff->end 之间的区域
*非线性数据区 :数据缓冲区域的补充区域 :skb_shared_info区域
*
*
*sk_buff->truesize:线性数据区+非线性数据区+sizeof(struct sk_buff)
*sk_buff->len :线性数据区+非线性数据区
*sk_buff->data_len:非线性数据区
*
*
*一个完整的网络帧(skb_buff)包括:
* 线性数据区 + 非线性数据区 + skb_buff控制区
*
* skb_clone() :只复制skb_buff控制区,其中新分配的skb_buff和原来的skb_buff共享线性数据区和非线性数据区
*
* pskb_copy() :复制skb_buff控制区 + 线性数据区,共享非线性数据区
*
* skb_copy() :复制skb_buff控制区 + 线性数据区 + 非线性数据区
*
*
*
*
*/
源码附上:
struct sk_buff { /*表示接收或发送数据包的包头信息,其成员变量在从一层向另一层传递时会发生修改*/
/* These two members must be first. */
struct sk_buff *next;
struct sk_buff *prev;
struct sk_buff_head *list;
struct sock *sk;
struct timeval stamp;
struct net_device *dev;
struct net_device *input_dev;
struct net_device *real_dev;
union {
struct tcphdr *th;
struct udphdr *uh;
struct icmphdr *icmph;
struct igmphdr *igmph;
struct iphdr *ipiph;
struct ipv6hdr *ipv6h;
unsigned char *raw;
} h; /*传输层*/
union {
struct iphdr *iph;
struct ipv6hdr *ipv6h;
struct arphdr *arph;
unsigned char *raw;
} nh; /*网络层*/
union {
unsigne