struct sk_buff结构体解析
时间: 2023-06-17 18:06:05 浏览: 205
sk_buff 结构分析
`struct sk_buff` 是 Linux 内核中用来表示网络数据包的数据结构。它是一个很重要的数据结构,因为 Linux 内核中网络协议栈的所有数据包处理都是基于 sk_buff 进行的。
下面是 `struct sk_buff` 结构体的定义:
```c
struct sk_buff {
struct sk_buff *next;
struct sk_buff *prev;
ktime_t tstamp;
struct sock *sk;
struct net_device *dev;
char cb[48];
unsigned int len;
unsigned int data_len;
__u16 mac_len;
__u16 hdr_len;
union {
__u16 all;
struct {
__u16 nfmark : 16;
} nfctmark;
struct {
__u16 pkt_type : 3;
__u16 ignore_df : 1;
__u16 nf_trace : 1;
__u16 ip_summed : 2;
__u16 ooo_okay : 1;
__u16 l4_rxhash : 1;
__u16 sw_hash : 1;
__u16 sw_hash_valid : 1;
__u16 l5_hash_valid : 1;
__u16 l4_hash_valid : 1;
__u16 fclone : 2;
__u16 frag_list : 2;
__u16 rxhash : 1;
__u16 loopback : 1;
__u16 vlan_present : 1;
__u16 vlan_tci : 16;
__u16 inner_protocol : 16;
__u16 inner_transport_header : 16;
} parsed;
} encapsulation;
unsigned char protocol;
unsigned char pkt_type: 3;
unsigned char fclone: 2;
unsigned char ip_summed: 2;
unsigned char ooo_okay: 1;
__u16 vlan_proto;
__u16 vlan_tci;
union {
struct {
__be16 h_vlan_TCI;
__be16 h_vlan_encapsulated_proto;
};
__be32 ipv4;
struct ipv6hdr *ipv6h;
struct arphdr *arph;
struct tcphdr *hth;
struct udphdr *huh;
struct icmphdr *icmph;
} protocol_headers;
union {
struct tcphdr *th;
struct udphdr *uh;
struct icmphdr *icmph;
struct igmphdr *igmph;
struct iphdr *iph;
struct ipv6hdr *ipv6h;
struct arphdr *arph;
struct pppox_hdr *pppoe;
struct snap_header *llc;
struct cfm_pdu_header *cfm_pdu;
struct batadv_unicast_packet *batman_adv;
struct batadv_bcast_packet *batman_adv_bcast;
struct batadv_icmp_packet *batman_adv_icmp;
struct batadv_tvlv_packet *batman_adv_tvlv;
struct batadv_frag_packet *batman_adv_frag;
struct batadv_purge_packet *batman_adv_purge;
struct batadv_gw_packet *batman_adv_gw;
struct batadv_tt_change_packet *batman_adv_tt_change;
struct batadv_mcast_packet *batman_adv_mcast;
struct batadv_frag_list *batman_adv_frag_list;
struct batadv_unicast_4addr_packet *batman_adv_unicast_4addr;
struct batadv_bla_claim *batman_adv_bla_claim;
struct batadv_bla_backbone_gw *batman_adv_bla_backbone_gw;
struct batadv_bla_claim_reply *batman_adv_bla_claim_reply;
struct batadv_bla_claim_confirm *batman_adv_bla_claim_confirm;
struct batadv_bla_claim_ack *batman_adv_bla_claim_ack;
struct batadv_bla_update *batman_adv_bla_update;
struct batadv_bla_claim_broadcast *batman_adv_bla_claim_broadcast;
struct batadv_bla_claim_broadcast_reply *batman_adv_bla_claim_broadcast_reply;
} encapsulated;
char *head;
char *data;
char *tail;
char *end;
unsigned int truesize;
atomic_t users;
};
```
`struct sk_buff` 结构体中的字段含义如下:
- `next` 和 `prev`:`struct sk_buff` 是一个双向链表,这两个字段用于链表操作;
- `tstamp`:时间戳,用于记录数据包的接收或发送时间;
- `sk`:指向网络套接字的指针;
- `dev`:指向网络设备的指针;
- `cb`:可选的控制块,用于保存一些协议栈内部使用的数据;
- `len`:数据包的总长度;
- `data_len`:数据包实际负载的长度;
- `mac_len`:物理层帧头的长度;
- `hdr_len`:网络层协议头的长度;
- `encapsulation`:封装信息,用于保存协议头的解析结果;
- `protocol`:网络协议号;
- `pkt_type`:数据包类型;
- `fclone`:用于指示是否进行数据包复制;
- `ip_summed`:用于指示是否需要计算 IP 校验和;
- `ooo_okay`:用于指示是否允许乱序到达的数据包;
- `vlan_proto` 和 `vlan_tci`:VLAN 标签的协议号和标识符;
- `protocol_headers`:协议头指针的联合体;
- `encapsulated`:封装协议的联合体;
- `head`:指向数据包缓冲区首地址的指针;
- `data`:指向数据包负载首地址的指针;
- `tail`:指向数据包负载末地址的指针;
- `end`:指向数据包缓冲区末地址的指针;
- `truesize`:数据包缓冲区的实际大小;
- `users`:用于记录当前正在使用该数据包的线程数的原子计数器。
阅读全文