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_check
  5. ip_dev_find

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

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