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

📄 dev.c

📁 An implementation of the TCP/IP protocol suite for the LINUX operating system. INET is implemented u
💻 C
📖 第 1 页 / 共 3 页
字号:
  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  *              Interface (streams) handling functions.
  7  *
  8  * Version:     @(#)dev.c       1.0.19  05/31/93
  9  *
 10  * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
 11  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 12  *              Mark Evans, <evansmp@uhura.aston.ac.uk>
 13  * 
 14  * Fixes:       
 15  *              Alan Cox:       check_addr returns a value for a wrong subnet
 16  *                              ie not us but don't forward this!
 17  *              Alan Cox:       block timer if the inet_bh handler is running
 18  *              Alan Cox:       generic queue code added. A lot neater now
 19  *              C.E.Hawkins:    SIOCGIFCONF only reports 'upped' interfaces
 20  *              C.E.Hawkins:    IFF_PROMISC support
 21  *              Alan Cox:       Supports Donald Beckers new hardware 
 22  *                              multicast layer, but not yet multicast lists.
 23  *              Alan Cox:       ip_addr_match problems with class A/B nets.
 24  *              C.E.Hawkins     IP 0.0.0.0 and also same net route fix. [FIXME: Ought to cause ICMP_REDIRECT]
 25  *              Alan Cox:       Removed bogus subnet check now the subnet code
 26  *                              a) actually works for all A/B nets
 27  *                              b) doesn't forward off the same interface.
 28  *              Alan Cox:       Multiple extra protocols
 29  *              Alan Cox:       Fixed ifconfig up of dud device setting the up flag
 30  *              Alan Cox:       Fixed verify_area errors
 31  *              Alan Cox:       Removed IP_SET_DEV as per Fred's comment. I hope this doesn't give
 32  *                              anything away 8)
 33  *
 34  *              This program is free software; you can redistribute it and/or
 35  *              modify it under the terms of the GNU General Public License
 36  *              as published by the Free Software Foundation; either version
 37  *              2 of the License, or (at your option) any later version.
 38  */
 39 #include <asm/segment.h>
 40 #include <asm/system.h>
 41 #include <asm/bitops.h>
 42 #include <linux/config.h>
 43 #include <linux/types.h>
 44 #include <linux/kernel.h>
 45 #include <linux/sched.h>
 46 #include <linux/string.h>
 47 #include <linux/mm.h>
 48 #include <linux/socket.h>
 49 #include <linux/sockios.h>
 50 #include <linux/in.h>
 51 #include <linux/errno.h>
 52 #include <linux/interrupt.h>
 53 #include <linux/if_ether.h>
 54 #include "inet.h"
 55 #include "dev.h"
 56 #include "eth.h"
 57 #include "ip.h"
 58 #include "route.h"
 59 #include "protocol.h"
 60 #include "tcp.h"
 61 #include "skbuff.h"
 62 #include "sock.h"
 63 #include "arp.h"
 64 #ifdef CONFIG_AX25
 65 #include "ax25.h"
 66 #endif
 67 
 68 
 69 #ifdef CONFIG_IPX
 70 
 71 static struct packet_type ipx_8023_type = {
 72   NET16(ETH_P_802_3),
 73   0,
 74   ipx_rcv,
 75   NULL,
 76   NULL
 77 };
 78 
 79 static struct packet_type ipx_packet_type = {
 80   NET16(ETH_P_IPX),
 81   0,
 82   ipx_rcv,
 83   NULL,
 84   &ipx_8023_type
 85 };
 86 
 87 #endif
 88 
 89 #ifdef CONFIG_AX25
 90 
 91 static struct packet_type ax25_packet_type = {
 92   NET16(ETH_P_AX25),
 93   0,
 94   ax25_rcv,
 95   NULL,
 96 #ifdef CONFIG_IPX
 97   &ipx_packet_type
 98 #else
 99   NULL
100 #endif
101 };
102 #endif
103 
104 
105 static struct packet_type arp_packet_type = {
106   NET16(ETH_P_ARP),
107   0,            /* copy */
108   arp_rcv,
109   NULL,
110 #ifdef CONFIG_IPX
111 #ifndef CONFIG_AX25
112   &ipx_packet_type
113 #else
114   &ax25_packet_type
115 #endif
116 #else
117 #ifdef CONFIG_AX25
118   &ax25_packet_type
119 #else
120   NULL          /* next */
121 #endif
122 #endif
123 };
124 
125 
126 static struct packet_type ip_packet_type = {
127   NET16(ETH_P_IP),
128   0,            /* copy */
129   ip_rcv,
130   NULL,
131   &arp_packet_type
132 };
133    
134 
135 struct packet_type *ptype_base = &ip_packet_type;
136 static struct sk_buff *volatile backlog = NULL;
137 static unsigned long ip_bcast = 0;
138 
139 
140 /* Return the lesser of the two values. */
141 static unsigned long
142 min(unsigned long a, unsigned long b)
143 {
144   if (a < b) return(a);
145   return(b);
146 }
147 
148 
149 /* Determine a default network mask, based on the IP address. */
150 static unsigned long
151 get_mask(unsigned long addr)
152 {
153   unsigned long dst;
154 
155   if (addr == 0L) 
156         return(0L);     /* special case */
157 
158   dst = ntohl(addr);
159   if (IN_CLASSA(dst)) 
160         return(htonl(IN_CLASSA_NET));
161   if (IN_CLASSB(dst)) 
162         return(htonl(IN_CLASSB_NET));
163   if (IN_CLASSC(dst)) 
164         return(htonl(IN_CLASSC_NET));
165   
166   /* Something else, probably a subnet. */
167   return(0);
168 }
169 
170 
171 int
172 ip_addr_match(unsigned long me, unsigned long him)
173 {
174   int i;
175   unsigned long mask=0xFFFFFFFF;
176   DPRINTF((DBG_DEV, "ip_addr_match(%s, ", in_ntoa(me)));
177   DPRINTF((DBG_DEV, "%s)\n", in_ntoa(him)));
178 
179   if (me == him) 
180         return(1);
181   for (i = 0; i < 4; i++, me >>= 8, him >>= 8, mask >>= 8) {
182         if ((me & 0xFF) != (him & 0xFF)) {
183                 /*
184                  * The only way this could be a match is for
185                  * the rest of addr1 to be 0 or 255.
186                  */
187                 if (me != 0 && me != mask) return(0);
188                 return(1);
189         }
190   }
191   return(1);
192 }
193 
194 
195 /* Check the address for our address, broadcasts, etc. */
196 int chk_addr(unsigned long addr)
197 {
198         struct device *dev;
199         unsigned long mask;
200 
201         /* Accept both `all ones' and `all zeros' as BROADCAST. */
202         if (addr == INADDR_ANY || addr == INADDR_BROADCAST)
203                 return IS_BROADCAST;
204 
205         mask = get_mask(addr);
206 
207         /* Accept all of the `loopback' class A net. */
208         if ((addr & mask) == htonl(0x7F000000L))
209                 return IS_MYADDR;
210 
211         /* OK, now check the interface addresses. */
212         for (dev = dev_base; dev != NULL; dev = dev->next) {
213                 if (!(dev->flags & IFF_UP))
214                         continue;
215                 if ((dev->pa_addr == 0)/* || (dev->flags&IFF_PROMISC)*/)
216                         return IS_MYADDR;
217                 /* Is it the exact IP address? */
218                 if (addr == dev->pa_addr)
219                         return IS_MYADDR;
220                 /* Is it our broadcast address? */
221                 if ((dev->flags & IFF_BROADCAST) && addr == dev->pa_brdaddr)
222                         return IS_BROADCAST;
223                 /* Nope. Check for a subnetwork broadcast. */
224                 if (((addr ^ dev->pa_addr) & dev->pa_mask) == 0) {
225                         if ((addr & ~dev->pa_mask) == 0)
226                                 return IS_BROADCAST;
227                         if ((addr & ~dev->pa_mask) == ~dev->pa_mask)
228                                 return IS_BROADCAST;
229                 }
230                 /* Nope. Check for Network broadcast. */
231                 if (((addr ^ dev->pa_addr) & mask) == 0) {
232                         if ((addr & ~mask) == 0)
233                                 return IS_BROADCAST;
234                         if ((addr & ~mask) == ~mask)
235                                 return IS_BROADCAST;
236                 }
237         }
238         return 0;               /* no match at all */
239 }
240 
241 
242 /*
243  * Retrieve our own address.
244  * Because the loopback address (127.0.0.1) is already recognized
245  * automatically, we can use the loopback interface's address as
246  * our "primary" interface.  This is the addressed used by IP et
247  * al when it doesn't know which address to use (i.e. it does not
248  * yet know from or to which interface to go...).
249  */
250 unsigned long
251 my_addr(void)
252 {
253   struct device *dev;
254 
255   for (dev = dev_base; dev != NULL; dev = dev->next) {
256         if (dev->flags & IFF_LOOPBACK) return(dev->pa_addr);
257   }
258   return(0);
259 }
260 
261 
262 static int dev_nit=0; /* Number of network taps running */
263 
264 /* Add a protocol ID to the list.  This will change soon. */
265 void
266 dev_add_pack(struct packet_type *pt)
267 {
268   struct packet_type *p1;
269   pt->next = ptype_base;
270 
271   /* Don't use copy counts on ETH_P_ALL. Instead keep a global
272      count of number of these and use it and pt->copy to decide
273      copies */
274   pt->copy=0;
275   if(pt->type==NET16(ETH_P_ALL))
276         dev_nit++;      /* I'd like a /dev/nit too one day 8) */
277   else
278   {
279         /* See if we need to copy it. */
280         for (p1 = ptype_base; p1 != NULL; p1 = p1->next) {
281                 if (p1->type == pt->type) {
282                         pt->copy = 1;
283                         break;
284                 }
285           }
286   }
287   
288   /*
289    *    NIT taps must go at the end or inet_bh will leak!
290    */
291    
292   if(pt->type==NET16(ETH_P_ALL))
293   {
294         pt->next=NULL;
295         if(ptype_base==NULL)
296                 ptype_base=pt;
297         else
298         {
299                 for(p1=ptype_base;p1->next!=NULL;p1=p1->next);
300                 p1->next=pt;
301         }
302   }
303   else
304         ptype_base = pt;
305 }
306 
307 
308 /* Remove a protocol ID from the list.  This will change soon. */
309 void
310 dev_remove_pack(struct packet_type *pt)
311 {
312   struct packet_type *lpt, *pt1;
313 
314   if (pt->type == NET16(ETH_P_ALL))
315         dev_nit--;
316   if (pt == ptype_base) {
317         ptype_base = pt->next;
318         return;
319   }
320 
321   lpt = NULL;
322   for (pt1 = ptype_base; pt1->next != NULL; pt1 = pt1->next) {
323         if (pt1->next == pt ) {
324                 cli();
325                 if (!pt->copy && lpt) 
326                         lpt->copy = 0;
327                 pt1->next = pt->next;
328                 sti();
329                 return;
330         }
331 
332         if (pt1->next -> type == pt ->type && pt->type != NET16(ETH_P_ALL)) {
333                 lpt = pt1->next;
334         }
335   }
336 }
337 
338 
339 /* Find an interface in the list. This will change soon. */
340 struct device *
341 dev_get(char *name)
342 {
343   struct device *dev;
344 
345   for (dev = dev_base; dev != NULL; dev = dev->next) {
346         if (strcmp(dev->name, name) == 0) 
347                 return(dev);
348   }
349   return(NULL);

⌨️ 快捷键说明

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