auking 发表于 2003-5-14 22:02:58

sk_buff问题

想问一下sk_buff中的data包不包括各种协议的数据包头?
我看snort中通过调用pcap_loop->recvfrom只是把协议站中sk_buff结构
中的data指针所指的区域拷贝到用户空间了,它是怎样统计出各种类型的
数据包的呢?除非data所指的区域包括完整的协议包头.
请高手指点,不胜感激

Dragonfly 发表于 2003-5-14 22:31:53


129 struct sk_buff {
130         /* These two members must be first. */
131         struct sk_buff* next;               /* Next buffer in list                        */
132         struct sk_buff* prev;               /* Previous buffer in list                      */
133
134         struct sk_buff_head * list;             /* List we are on                               */
135         struct sock   *sk;                  /* Socket we are owned by                     */
136         struct timevalstamp;                  /* Time we arrived                              */
137         struct net_device       *dev;         /* Device we arrived on/are leaving by          */
138
139         /* Transport layer header */
140         union
141         {
142               struct tcphdr   *th;
143               struct udphdr   *uh;
144               struct icmphdr*icmph;
145               struct igmphdr*igmph;
146               struct iphdr    *ipiph;
147               struct spxhdr   *spxh;
148               unsigned char   *raw;
149         } h;
150
151         /* Network layer header */
152         union
153         {
154               struct iphdr    *iph;
155               struct ipv6hdr*ipv6h;
156               struct arphdr   *arph;
157               struct ipxhdr   *ipxh;
158               unsigned char   *raw;
159         } nh;
160   
161         /* Link layer header */
162         union
163         {      
164               struct ethhdr   *ethernet;
165               unsigned char   *raw;
166         } mac;
167
168         structdst_entry *dst;
169
170         /*
171          * This is the control buffer. It is free to use for every
172          * layer. Please put your private variables there. If you
173          * want to keep them across layers you have to do a skb_clone()
174          * first. This is owned by whoever has the skb queued ATM.
175          */
176         char            cb[48];
177
178         unsigned int    len;                  /* Length of actual data                        */
179         unsigned int    data_len;
180         unsigned int    csum;                   /* Checksum                                     */
181         unsigned char   __unused,               /* Dead field, may be reused                  */
182                         cloned,               /* head may be cloned (check refcnt to be sure). */
183                         pkt_type,               /* Packet class                                 */
184                         ip_summed;            /* Driver fed us an IP checksum               */
185         __u32         priority;               /* Packet queueing priority                     */
186         atomic_t      users;                  /* User count - see datagram.c,tcp.c            */
187         unsigned shortprotocol;               /* Packet protocol from driver.               */
188         unsigned shortsecurity;               /* Security level of packet                     */
189         unsigned int    truesize;               /* Buffer size                                  */
190
191         unsigned char   *head;                  /* Head of buffer                               */
192         unsigned char   *data;                  /* Data head pointer                            */
193         unsigned char   *tail;                  /* Tail pointer                                 */
194         unsigned char   *end;                   /* End pointer                                  */
195
196         void            (*destructor)(struct sk_buff *);      /* Destruct function            */
197 #ifdef CONFIG_NETFILTER
198         /* Can be used for communication between hooks. */
199         unsigned long   nfmark;
200         /* Cache info */
201         __u32         nfcache;
202         /* Associated connection, if any */
203         struct nf_ct_info *nfct;
204 #ifdef CONFIG_NETFILTER_DEBUG
205         unsigned int nf_debug;
206 #endif
207 #endif /*CONFIG_NETFILTER*/
208
209 #if defined(CONFIG_HIPPI)
210         union{
211               __u32   ifield;
212         } private;
213 #endif
214
215 #ifdef CONFIG_NET_SCHED
216      __u32         tc_index;               /* traffic control index */
217 #endif
218 };

that data includes all info. i am checking the code where it alloc space for data

Dragonfly 发表于 2003-5-14 22:56:34

check the*alloc_skb() in net/core/skbuff.c

164 struct sk_buff *alloc_skb(unsigned int size,int gfp_mask)
165 {
166         struct sk_buff *skb;
167         u8 *data;
168
169         if (in_interrupt() && (gfp_mask & __GFP_WAIT)) {
170               static int count = 0;
171               if (++count < 5) {
172                         printk(KERN_ERR "alloc_skb called nonatomically "
173                              "from interrupt %p\n", NET_CALLER(size));
174                         BUG();
175               }
176               gfp_mask &= ~__GFP_WAIT;
177         }
178
179         /* Get the HEAD */
180         skb = skb_head_from_pool();
181         if (skb == NULL) {
182               skb = kmem_cache_alloc(skbuff_head_cache, gfp_mask & ~__GFP_DMA);
183               if (skb == NULL)
184                         goto nohead;
185         }
186
187         /* Get the DATA. Size must match skb_add_mtu(). */
188         size = SKB_DATA_ALIGN(size);
189         data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
190         if (data == NULL)
191               goto nodata;
192
193         /* XXX: does not include slab overhead */
194         skb->truesize = size + sizeof(struct sk_buff);
195
196         /* Load the data pointers. */
197         skb->head = data;
198         skb->data = data;
199         skb->tail = data;
200         skb->end = data + size;
201
202         /* Set up other state */
203         skb->len = 0;
204         skb->cloned = 0;
205         skb->data_len = 0;
206
207         atomic_set(&skb->users, 1);
208         atomic_set(&(skb_shinfo(skb)->dataref), 1);
209         skb_shinfo(skb)->nr_frags = 0;
210         skb_shinfo(skb)->frag_list = NULL;
211         return skb;
212
213 nodata:
214         skb_head_to_pool(skb);
215 nohead:
216         return NULL;
217 }

here allocate the skb header and data. see the assignment of head, end, tail, data.
and read ip_build_xmit() in net/ipv4/ip_output.c to see after allocate a skb, how it compute the header offset and operate on it.


am i right? rfc.

fist 发表于 2003-5-28 18:13:29

在不同的协议层,skbuff的指针都要进行调整,所以data也是调整的。这些有关的函数是
static inline unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
{
        skb->data-=len;
        skb->len+=len;
        if(skb->data<skb->head) {
                skb_under_panic(skb, len, current_text_addr());
        }
        return skb->data;
}
static inline char *__skb_pull(struct sk_buff *skb, unsigned int len)
{
        skb->len-=len;
        if (skb->len < skb->data_len)
                out_of_line_bug();
        return         skb->data+=len;
}

例如在linux\net\ipv4\ip_output.c中
int ip_build_and_send_pkt()
{
。。。
/* Build the IP header. */
        if (opt)
                iph=(struct iphdr *)skb_push(skb,sizeof(struct iphdr) + opt->optlen);
        else
                iph=(struct iphdr *)skb_push(skb,sizeof(struct iphdr));

/* Adjust data pointer and fill the ip header for the packet.Also we can conclude that the data contains the protocol header(IP header for example)
*
*/
        iph->version= 4;
        iph->ihl      = 5;
        iph->tos      = sk->protinfo.af_inet.tos;
。。。
}

Dragonfly 发表于 2003-5-28 21:28:25

yes, the book ULK2 has description on these fun
页: [1]
查看完整版本: sk_buff问题