root/net/ipv4/devinet.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ip_get_mask
  2. ip_chk_addr
  3. ip_my_addr
  4. ip_dev_bynet
  5. ip_dev_find
  6. dev_getbytype

   1 /*
   2  *      NET3    IP device support routines.
   3  *
   4  *              This program is free software; you can redistribute it and/or
   5  *              modify it under the terms of the GNU General Public License
   6  *              as published by the Free Software Foundation; either version
   7  *              2 of the License, or (at your option) any later version.
   8  *
   9  *      Derived from the IP parts of dev.c 1.0.19
  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  *      Additional Authors:
  15  *              Alan Cox, <gw4pts@gw4pts.ampr.org>
  16  */
  17 
  18 #include <linux/config.h>       /* For CONFIG_IP_CLASSLESS */
  19  
  20 #include <asm/segment.h>
  21 #include <asm/system.h>
  22 #include <asm/bitops.h>
  23 #include <linux/types.h>
  24 #include <linux/kernel.h>
  25 #include <linux/sched.h>
  26 #include <linux/string.h>
  27 #include <linux/mm.h>
  28 #include <linux/socket.h>
  29 #include <linux/sockios.h>
  30 #include <linux/in.h>
  31 #include <linux/errno.h>
  32 #include <linux/interrupt.h>
  33 #include <linux/if_ether.h>
  34 #include <linux/inet.h>
  35 #include <linux/netdevice.h>
  36 #include <linux/etherdevice.h>
  37 #include <net/ip.h>
  38 #include <net/route.h>
  39 #include <net/protocol.h>
  40 #include <net/tcp.h>
  41 #include <linux/skbuff.h>
  42 #include <net/sock.h>
  43 #include <net/arp.h>
  44 
  45 /* 
  46  *      Determine a default network mask, based on the IP address. 
  47  */
  48  
  49 unsigned long ip_get_mask(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  50 {
  51         unsigned long dst;
  52 
  53         if (addr == 0L) 
  54                 return(0L);     /* special case */
  55 
  56         dst = ntohl(addr);
  57         if (IN_CLASSA(dst)) 
  58                 return(htonl(IN_CLASSA_NET));
  59         if (IN_CLASSB(dst)) 
  60                 return(htonl(IN_CLASSB_NET));
  61         if (IN_CLASSC(dst)) 
  62                 return(htonl(IN_CLASSC_NET));
  63   
  64         /*
  65          *      Something else, probably a multicast. 
  66          */
  67          
  68         return(0);
  69 }
  70 
  71 /* 
  72  *      Check the address for our address, broadcasts, etc. 
  73  *
  74  *      I intend to fix this to at the very least cache the last
  75  *      resolved entry.
  76  */
  77  
  78 int ip_chk_addr(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  79 {
  80         struct device *dev;
  81 #ifndef CONFIG_IP_CLASSLESS
  82         unsigned long mask;
  83 #endif
  84 
  85         /* 
  86          *      Accept both `all ones' and `all zeros' as BROADCAST. 
  87          *      (Support old BSD in other words). This old BSD 
  88          *      support will go very soon as it messes other things
  89          *      up.
  90          *      Also accept `loopback broadcast' as BROADCAST.
  91          */
  92 
  93         if (addr == INADDR_ANY || addr == INADDR_BROADCAST ||
  94             addr == htonl(0x7FFFFFFFL))
  95                 return IS_BROADCAST;
  96 
  97 #ifndef  CONFIG_IP_CLASSLESS
  98         mask = ip_get_mask(addr);
  99 
 100         /*
 101          *      Accept all of the `loopback' class A net. 
 102          */
 103          
 104         if ((addr & mask) == htonl(0x7F000000L))
 105                 return IS_MYADDR;
 106 #else
 107         if ((addr & htonl(0x7F000000L)) == htonl(0x7F000000L))
 108                 return IS_MYADDR;
 109 #endif
 110 
 111         /*
 112          *      OK, now check the interface addresses. We could
 113          *      speed this by keeping a dev and a dev_up chain.
 114          */
 115          
 116         for (dev = dev_base; dev != NULL; dev = dev->next) 
 117         {
 118                 if ((!(dev->flags & IFF_UP)) || dev->family!=AF_INET)
 119                         continue;
 120                 /*
 121                  *      If the protocol address of the device is 0 this is special
 122                  *      and means we are address hunting (eg bootp).
 123                  */
 124                  
 125                 if (dev->pa_addr == 0)
 126                         return IS_MYADDR;
 127                 /*
 128                  *      Is it the exact IP address? 
 129                  */
 130                  
 131                 if (addr == dev->pa_addr)
 132                         return IS_MYADDR;
 133                 /*
 134                  *      Is it our broadcast address? 
 135                  */
 136                  
 137                 if ((dev->flags & IFF_BROADCAST) && addr == dev->pa_brdaddr)
 138                         return IS_BROADCAST;
 139                 /*
 140                  *      Nope. Check for a subnetwork broadcast. 
 141                  */
 142                  
 143                 if (((addr ^ dev->pa_addr) & dev->pa_mask) == 0) 
 144                 {
 145                         if ((addr & ~dev->pa_mask) == 0)
 146                                 return IS_BROADCAST;
 147                         if ((addr & ~dev->pa_mask) == ~dev->pa_mask)
 148                                 return IS_BROADCAST;
 149                 }
 150                 
 151 #ifndef CONFIG_IP_CLASSLESS
 152                 /*
 153                  *      Nope. Check for Network broadcast. 
 154                  */
 155                  
 156                 if (((addr ^ dev->pa_addr) & mask) == 0) 
 157                 {
 158                         if ((addr & ~mask) == 0)
 159                                 return IS_BROADCAST;
 160                         if ((addr & ~mask) == ~mask)
 161                                 return IS_BROADCAST;
 162                 }
 163 #endif
 164         }
 165         if(IN_MULTICAST(ntohl(addr)))
 166                 return IS_MULTICAST;
 167         return 0;               /* no match at all */
 168 }
 169 
 170 
 171 /*
 172  *      Retrieve our own address.
 173  *
 174  *      Because the loopback address (127.0.0.1) is already recognized
 175  *      automatically, we can use the loopback interface's address as
 176  *      our "primary" interface.  This is the address used by IP et
 177  *      al when it doesn't know which address to use (i.e. it does not
 178  *      yet know from or to which interface to go...).
 179  */
 180  
 181 unsigned long ip_my_addr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 182 {
 183         struct device *dev;
 184 
 185         for (dev = dev_base; dev != NULL; dev = dev->next) 
 186         {
 187                 if (dev->flags & IFF_LOOPBACK) 
 188                         return(dev->pa_addr);
 189         }
 190         return(0);
 191 }
 192 
 193 /*
 194  *      Find an interface that can handle addresses for a certain address. 
 195  */
 196 
 197 struct device * ip_dev_bynet(unsigned long addr, unsigned long mask)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199         struct device *dev;
 200         struct device *best_dev = NULL;
 201         __u32  best_mask = mask;
 202 
 203         for (dev = dev_base; dev; dev = dev->next) 
 204         {
 205                 if (!(dev->flags & IFF_UP))
 206                         continue;
 207                 if (dev->flags & IFF_POINTOPOINT)
 208                 {
 209                         if (addr == dev->pa_dstaddr)
 210                                 return dev;
 211                         continue;
 212                 }
 213                 if (dev->pa_mask & (addr ^ dev->pa_addr))
 214                         continue;
 215                 if (mask == dev->pa_mask)
 216                         return dev;
 217                 if (best_dev && (best_mask & dev->pa_mask) != best_mask)
 218                         continue;
 219                 best_dev = dev;
 220                 best_mask = dev->pa_mask;
 221         }
 222         return best_dev;
 223 }
 224 
 225 /*
 226  *      Find the first device with a given source address.
 227  */
 228  
 229 struct device *ip_dev_find(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 230 {
 231         struct device *dev;
 232         for(dev = dev_base; dev; dev=dev->next)
 233         {
 234                 if((dev->flags&IFF_UP) && dev->pa_addr==addr)
 235                         return dev;
 236         }
 237         return NULL;
 238 }
 239 
 240 struct device *dev_getbytype(unsigned short type)
     /* [previous][next][first][last][top][bottom][index][help] */
 241 {
 242         struct device *dev;
 243 
 244         for (dev = dev_base; dev != NULL; dev = dev->next) 
 245         {
 246                 if (dev->type == type && !(dev->flags&(IFF_LOOPBACK|IFF_NOARP)))
 247                         return(dev);
 248         }
 249         return(NULL);
 250 }
 251 

/* [previous][next][first][last][top][bottom][index][help] */