This source file includes following definitions.
- skb_check
- skb_queue_head
- skb_queue_tail
- skb_dequeue
- skb_insert
- skb_append
- skb_unlink
- skb_new_list_head
- skb_peek
- skb_peek_copy
- kfree_skb
- alloc_skb
- kfree_skbmem
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <linux/config.h>
17 #include <linux/types.h>
18 #include <linux/kernel.h>
19 #include <asm/segment.h>
20 #include <asm/system.h>
21 #include <linux/mm.h>
22 #include <linux/interrupt.h>
23 #include <linux/in.h>
24 #include "inet.h"
25 #include "dev.h"
26 #include "ip.h"
27 #include "protocol.h"
28 #include "arp.h"
29 #include "route.h"
30 #include "tcp.h"
31 #include "udp.h"
32 #include "skbuff.h"
33 #include "sock.h"
34
35
36
37
38
39
40
41
42
43
44
45
46 volatile unsigned long net_memory=0;
47 volatile unsigned long net_skbcount=0;
48
49
50
51
52
53
54
55 void skb_check(struct sk_buff *skb, int line, char *file)
56 {
57 if(skb->magic_debug_cookie==SK_FREED_SKB)
58 {
59 printk("File: %s Line %d, found a freed skb lurking in the undergrowth!\n",
60 file,line);
61 printk("skb=%p, real size=%ld, claimed size=%ld, magic=%d, list=%p, free=%d\n",
62 skb,skb->truesize,skb->mem_len,skb->magic,skb->list,skb->free);
63 }
64 if(skb->magic_debug_cookie!=SK_GOOD_SKB)
65 {
66 printk("File: %s Line %d, passed a non skb!\n", file,line);
67 printk("skb=%p, real size=%ld, claimed size=%ld, magic=%d, list=%p, free=%d\n",
68 skb,skb->truesize,skb->mem_len,skb->magic,skb->list,skb->free);
69 }
70 if(skb->mem_len!=skb->truesize)
71 {
72 printk("File: %s Line %d, Dubious size setting!\n",file,line);
73 printk("skb=%p, real size=%ld, claimed size=%ld, magic=%d, list=%p\n",
74 skb,skb->truesize,skb->mem_len,skb->magic,skb->list);
75 }
76
77 }
78
79
80
81
82
83 void skb_queue_head(struct sk_buff *volatile* list,struct sk_buff *newsk)
84 {
85 unsigned long flags;
86
87 IS_SKB(newsk);
88 if(newsk->list)
89 printk("Suspicious queue head: sk_buff on list!\n");
90 save_flags(flags);
91 cli();
92 newsk->list=list;
93
94 newsk->next=*list;
95
96 if(*list)
97 newsk->prev=(*list)->prev;
98 else
99 newsk->prev=newsk;
100 newsk->prev->next=newsk;
101 newsk->next->prev=newsk;
102 IS_SKB(newsk->prev);
103 IS_SKB(newsk->next);
104 *list=newsk;
105 restore_flags(flags);
106 }
107
108
109
110
111
112 void skb_queue_tail(struct sk_buff *volatile* list, struct sk_buff *newsk)
113 {
114 unsigned long flags;
115
116 if(newsk->list)
117 printk("Suspicious queue tail: sk_buff on list!\n");
118
119 IS_SKB(newsk);
120 save_flags(flags);
121 cli();
122
123 newsk->list=list;
124 if(*list)
125 {
126 (*list)->prev->next=newsk;
127 newsk->prev=(*list)->prev;
128 newsk->next=*list;
129 (*list)->prev=newsk;
130 }
131 else
132 {
133 newsk->next=newsk;
134 newsk->prev=newsk;
135 *list=newsk;
136 }
137 IS_SKB(newsk->prev);
138 IS_SKB(newsk->next);
139 restore_flags(flags);
140
141 }
142
143
144
145
146
147
148 struct sk_buff *skb_dequeue(struct sk_buff *volatile* list)
149 {
150 long flags;
151 struct sk_buff *result;
152
153 save_flags(flags);
154 cli();
155
156 if(*list==NULL)
157 {
158 restore_flags(flags);
159 return(NULL);
160 }
161
162 result=*list;
163 if(result->next==result)
164 *list=NULL;
165 else
166 {
167 result->next->prev=result->prev;
168 result->prev->next=result->next;
169 *list=result->next;
170 }
171
172 IS_SKB(result);
173 restore_flags(flags);
174
175 if(result->list!=list)
176 printk("Dequeued packet has invalid list pointer\n");
177
178 result->list=0;
179 result->next=0;
180 result->prev=0;
181 return(result);
182 }
183
184
185
186
187
188 void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
189 {
190 unsigned long flags;
191
192 IS_SKB(old);
193 IS_SKB(newsk);
194
195 if(!old->list)
196 printk("insert before unlisted item!\n");
197 if(newsk->list)
198 printk("inserted item is already on a list.\n");
199
200 save_flags(flags);
201 cli();
202 newsk->list=old->list;
203 newsk->next=old;
204 newsk->prev=old->prev;
205 newsk->next->prev=newsk;
206 newsk->prev->next=newsk;
207
208 restore_flags(flags);
209 }
210
211
212
213
214
215 void skb_append(struct sk_buff *old, struct sk_buff *newsk)
216 {
217 unsigned long flags;
218
219 IS_SKB(old);
220 IS_SKB(newsk);
221
222 if(!old->list)
223 printk("append before unlisted item!\n");
224 if(newsk->list)
225 printk("append item is already on a list.\n");
226
227 save_flags(flags);
228 cli();
229 newsk->list=old->list;
230 newsk->prev=old;
231 newsk->next=old->next;
232 newsk->next->prev=newsk;
233 newsk->prev->next=newsk;
234
235 restore_flags(flags);
236 }
237
238
239
240
241
242
243
244
245 void skb_unlink(struct sk_buff *skb)
246 {
247 unsigned long flags;
248 save_flags(flags);
249 cli();
250
251 IS_SKB(skb);
252
253 if(skb->list)
254 {
255 skb->next->prev=skb->prev;
256 skb->prev->next=skb->next;
257 if(*skb->list==skb)
258 {
259 if(skb->next==skb)
260 *skb->list=NULL;
261 else
262 *skb->list=skb->next;
263 }
264 skb->next=0;
265 skb->prev=0;
266 skb->list=0;
267 }
268 restore_flags(flags);
269 }
270
271
272
273
274
275
276
277 void skb_new_list_head(struct sk_buff *volatile* list)
278 {
279 struct sk_buff *skb=skb_peek(list);
280 if(skb!=NULL)
281 {
282 do
283 {
284 IS_SKB(skb);
285 skb->list=list;
286 skb=skb->next;
287 }
288 while(skb!=*list);
289 }
290 }
291
292
293
294
295
296
297
298
299 struct sk_buff *skb_peek(struct sk_buff *volatile* list)
300 {
301 return *list;
302 }
303
304
305
306
307
308
309
310
311
312 struct sk_buff *skb_peek_copy(struct sk_buff *volatile* list)
313 {
314 struct sk_buff *orig,*newsk;
315 unsigned long flags;
316 unsigned int len;
317
318
319 do
320 {
321 save_flags(flags);
322 cli();
323 orig=skb_peek(list);
324 if(orig==NULL)
325 {
326 restore_flags(flags);
327 return NULL;
328 }
329 IS_SKB(orig);
330 len=orig->truesize;
331 restore_flags(flags);
332
333 newsk=alloc_skb(len,GFP_KERNEL);
334
335 if(newsk==NULL)
336 return NULL;
337
338 save_flags(flags);
339 cli();
340 if(skb_peek(list)!=orig)
341 {
342 restore_flags(flags);
343 newsk->sk=NULL;
344 newsk->free=1;
345 newsk->mem_addr=newsk;
346 newsk->mem_len=len;
347 kfree_skb(newsk, FREE_WRITE);
348 continue;
349 }
350
351 IS_SKB(orig);
352 IS_SKB(newsk);
353 memcpy(newsk,orig,len);
354 newsk->list=NULL;
355 newsk->magic=0;
356 newsk->next=NULL;
357 newsk->prev=NULL;
358 newsk->mem_addr=newsk;
359 newsk->h.raw+=((char *)newsk-(char *)orig);
360 newsk->link3=NULL;
361 newsk->sk=NULL;
362 newsk->free=1;
363 }
364 while(0);
365
366 restore_flags(flags);
367 return(newsk);
368 }
369
370
371
372
373
374
375 void kfree_skb(struct sk_buff *skb, int rw)
376 {
377 if (skb == NULL) {
378 printk("kfree_skb: skb = NULL\n");
379 return;
380 }
381 IS_SKB(skb);
382 if(skb->free == 2)
383 printk("Warning: kfree_skb passed an skb that nobody set the free flag on!\n");
384 if(skb->list)
385 printk("Warning: kfree_skb passed an skb still on a list.\n");
386 skb->magic = 0;
387 if (skb->sk) {
388 if (rw) {
389 skb->sk->prot->rfree(skb->sk, skb->mem_addr, skb->mem_len);
390 } else {
391 skb->sk->prot->wfree(skb->sk, skb->mem_addr, skb->mem_len);
392 }
393 } else {
394 kfree_skbmem(skb->mem_addr, skb->mem_len);
395 }
396 }
397
398
399
400
401
402
403 struct sk_buff *alloc_skb(unsigned int size,int priority)
404 {
405 struct sk_buff *skb=(struct sk_buff *)kmalloc(size,priority);
406 if(skb==NULL)
407 return NULL;
408 skb->free= 2;
409 skb->list= 0;
410 skb->truesize=size;
411 skb->mem_len=size;
412 skb->mem_addr=skb;
413 skb->fraglist=NULL;
414 net_memory+=size;
415 net_skbcount++;
416 skb->magic_debug_cookie=SK_GOOD_SKB;
417 skb->users=0;
418 return skb;
419 }
420
421
422
423
424
425 void kfree_skbmem(void *mem,unsigned size)
426 {
427 struct sk_buff *x=mem;
428 IS_SKB(x);
429 if(x->magic_debug_cookie==SK_GOOD_SKB)
430 {
431 x->magic_debug_cookie=SK_FREED_SKB;
432 kfree_s(mem,size);
433 net_skbcount--;
434 net_memory-=size;
435 }
436 }
437