QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1491|回复: 4

sk_buff问题

[复制链接]
发表于 2003-5-14 22:02:58 | 显示全部楼层 |阅读模式
想问一下sk_buff中的data包不包括各种协议的数据包头?
我看snort中通过调用pcap_loop->recvfrom只是把协议站中sk_buff结构
中的data指针所指的区域拷贝到用户空间了,它是怎样统计出各种类型的
数据包的呢?除非data所指的区域包括完整的协议包头.
请高手指点,不胜感激
发表于 2003-5-14 22:31:53 | 显示全部楼层
[code:1]
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 timeval  stamp;                  /* 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         struct  dst_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 short  protocol;               /* Packet protocol from driver.                 */
188         unsigned short  security;               /* 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 };
[/code:1]
that data includes all info. i am checking the code where it alloc space for data
回复

使用道具 举报

发表于 2003-5-14 22:56:34 | 显示全部楼层
check the  *alloc_skb() in net/core/skbuff.c
[code:1]
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 }
[/code:1]
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.
回复

使用道具 举报

发表于 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;
。。。
}
回复

使用道具 举报

发表于 2003-5-28 21:28:25 | 显示全部楼层
yes, the book ULK2 has description on these fun
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-16 07:02 , Processed in 0.072326 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表