⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skbuff.c

📁 An implementation of the TCP/IP protocol suite for the LINUX operating system. INET is implemented u
💻 C
📖 第 1 页 / 共 2 页
字号:
  1 /*
  2  * INET         An implementation of the TCP/IP protocol suite for the LINUX
  3  *              operating system.  INET is implemented using the  BSD Socket
  4  *              interface as the means of communication with the user level.
  5  *
  6  *              A saner implementation of the skbuff stuff scattered everywhere
  7  *              in the old NET2D code.
  8  *
  9  *      Authors:        Alan Cox <iiitac@pyr.swan.ac.uk>
 10  *
 11  *      Fixes:
 12  *              Alan Cox        :       Tracks memory and number of buffers for kernel memory report
 13  *                                      and memory leak hunting.
 14  *              Alan Cox        :       More generic kfree handler
 15  */
 16 
 17 #include <linux/config.h>
 18 #include <linux/types.h>
 19 #include <linux/kernel.h>
 20 #include <linux/sched.h>
 21 #include <asm/segment.h>
 22 #include <asm/system.h>
 23 #include <linux/mm.h>
 24 #include <linux/interrupt.h>
 25 #include <linux/in.h>
 26 #include "inet.h"
 27 #include "dev.h"
 28 #include "ip.h"
 29 #include "protocol.h"
 30 #include "arp.h"
 31 #include "route.h"
 32 #include "tcp.h"
 33 #include "udp.h"
 34 #include "skbuff.h"
 35 #include "sock.h"
 36 
 37 
 38 /* Socket buffer operations. Ideally much of this list swap stuff ought to be using
 39    exch instructions on the 386, and CAS/CAS2 on a 68K. This is the boring generic
 40    slow C version. No doubt when Linus sees this comment he'll do horrible things
 41    to this code 8-)
 42 */
 43 
 44 /*
 45  *      Resource tracking variables
 46  */
 47 
 48 volatile unsigned long net_memory=0;
 49 volatile unsigned long net_skbcount=0;
 50 
 51 /*
 52  *      Debugging paranoia. Can go later when this crud stack works
 53  */
 54 
 55 
 56 
 57 void skb_check(struct sk_buff *skb, int line, char *file)
 58 {
 59         if(skb->magic_debug_cookie==SK_FREED_SKB)
 60         {
 61                 printk("File: %s Line %d, found a freed skb lurking in the undergrowth!\n",
 62                         file,line);
 63                 printk("skb=%p, real size=%ld, claimed size=%ld, magic=%d, list=%p, free=%d\n",
 64                         skb,skb->truesize,skb->mem_len,skb->magic,skb->list,skb->free);
 65         }
 66         if(skb->magic_debug_cookie!=SK_GOOD_SKB)
 67         {
 68                 printk("File: %s Line %d, passed a non skb!\n", file,line);
 69                 printk("skb=%p, real size=%ld, claimed size=%ld, magic=%d, list=%p, free=%d\n",
 70                         skb,skb->truesize,skb->mem_len,skb->magic,skb->list,skb->free);
 71         }
 72         if(skb->mem_len!=skb->truesize)
 73         {
 74                 printk("File: %s Line %d, Dubious size setting!\n",file,line);
 75                 printk("skb=%p, real size=%ld, claimed size=%ld, magic=%d, list=%p\n",
 76                         skb,skb->truesize,skb->mem_len,skb->magic,skb->list);
 77         }
 78         /* Guess it might be acceptable then */
 79 }
 80 
 81 /*
 82  *      Insert an sk_buff at the start of a list.
 83  */
 84 
 85 void skb_queue_head(struct sk_buff *volatile* list,struct sk_buff *newsk)
 86 {
 87         unsigned long flags;
 88 
 89         IS_SKB(newsk);
 90         if(newsk->list)
 91                 printk("Suspicious queue head: sk_buff on list!\n");
 92         save_flags(flags);
 93         cli();
 94         newsk->list=list;
 95 
 96         newsk->next=*list;
 97 
 98         if(*list)
 99                 newsk->prev=(*list)->prev;
100         else
101                 newsk->prev=newsk;
102         newsk->prev->next=newsk;
103         newsk->next->prev=newsk;
104         IS_SKB(newsk->prev);
105         IS_SKB(newsk->next);
106         *list=newsk;
107         restore_flags(flags);
108 }
109 
110 /*
111  *      Insert an sk_buff at the end of a list.
112  */
113 
114 void skb_queue_tail(struct sk_buff *volatile* list, struct sk_buff *newsk)
115 {
116         unsigned long flags;
117 
118         if(newsk->list)
119                 printk("Suspicious queue tail: sk_buff on list!\n");
120 
121         IS_SKB(newsk);
122         save_flags(flags);
123         cli();
124 
125         newsk->list=list;
126         if(*list)
127         {
128                 (*list)->prev->next=newsk;
129                 newsk->prev=(*list)->prev;
130                 newsk->next=*list;
131                 (*list)->prev=newsk;
132         }
133         else
134         {
135                 newsk->next=newsk;
136                 newsk->prev=newsk;
137                 *list=newsk;
138         }
139         IS_SKB(newsk->prev);
140         IS_SKB(newsk->next);
141         restore_flags(flags);
142 
143 }
144 
145 /*
146  *      Remove an sk_buff from a list. This routine is also interrupt safe
147  *      so you can grab read and free buffers as another process adds them.
148  */
149 
150 struct sk_buff *skb_dequeue(struct sk_buff *volatile* list)
151 {
152         long flags;
153         struct sk_buff *result;
154 
155         save_flags(flags);
156         cli();
157 
158         if(*list==NULL)
159         {
160                 restore_flags(flags);
161                 return(NULL);
162         }
163 
164         result=*list;
165         if(result->next==result)
166                 *list=NULL;
167         else
168         {
169                 result->next->prev=result->prev;
170                 result->prev->next=result->next;
171                 *list=result->next;
172         }
173 
174         IS_SKB(result);
175         restore_flags(flags);
176 
177         if(result->list!=list)
178                 printk("Dequeued packet has invalid list pointer\n");
179 
180         result->list=0;
181         result->next=0;
182         result->prev=0;
183         return(result);
184 }
185 
186 /*
187  *      Insert a packet before another one in a list.
188  */
189 
190 void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
191 {
192         unsigned long flags;
193 
194         IS_SKB(old);
195         IS_SKB(newsk);
196 
197         if(!old->list)
198                 printk("insert before unlisted item!\n");
199         if(newsk->list)
200                 printk("inserted item is already on a list.\n");
201 
202         save_flags(flags);
203         cli();
204         newsk->list=old->list;
205         newsk->next=old;
206         newsk->prev=old->prev;
207         newsk->next->prev=newsk;
208         newsk->prev->next=newsk;
209 
210         restore_flags(flags);
211 }
212 
213 /*
214  *      Place a packet after a given packet in a list.
215  */
216 
217 void skb_append(struct sk_buff *old, struct sk_buff *newsk)
218 {
219         unsigned long flags;
220 
221         IS_SKB(old);
222         IS_SKB(newsk);
223 
224         if(!old->list)
225                 printk("append before unlisted item!\n");
226         if(newsk->list)
227                 printk("append item is already on a list.\n");
228 
229         save_flags(flags);
230         cli();
231         newsk->list=old->list;
232         newsk->prev=old;
233         newsk->next=old->next;
234         newsk->next->prev=newsk;
235         newsk->prev->next=newsk;
236 
237         restore_flags(flags);
238 }
239 
240 /*
241  *      Remove an sk_buff from its list. Works even without knowing the list it
242  *      is sitting on, which can be handy at times. It also means that THE LIST
243  *      MUST EXIST when you unlink. Thus a list must have its contents unlinked
244  *      _FIRST_.
245  */
246 
247 void skb_unlink(struct sk_buff *skb)
248 {
249         unsigned long flags;
250         save_flags(flags);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -