root/net/inet/devinet.c

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

DEFINITIONS

This source file includes following definitions.
  1. ip_get_mask
  2. ip_addr_match
  3. ip_chk_addr
  4. ip_my_addr
  5. ip_dev_check

   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 <asm/segment.h>
  19 #include <asm/system.h>
  20 #include <asm/bitops.h>
  21 #include <linux/config.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 "ip.h"
  37 #include "route.h"
  38 #include "protocol.h"
  39 #include "tcp.h"
  40 #include <linux/skbuff.h>
  41 #include "sock.h"
  42 #include "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  *      Perform an IP address matching operation
  72  */
  73 
  74 int ip_addr_match(unsigned long me, unsigned long him)
     /* [previous][next][first][last][top][bottom][index][help] */
  75 {
  76         int i;
  77         unsigned long mask=0xFFFFFFFF;
  78         DPRINTF((DBG_DEV, "ip_addr_match(%s, ", in_ntoa(me)));
  79         DPRINTF((DBG_DEV, "%s)\n", in_ntoa(him)));
  80 
  81         /*
  82          *      Simple case
  83          */
  84         if (me == him) 
  85                 return(1);
  86                 
  87         /*
  88          *      Look for a match ending in all 1's 
  89          */
  90          
  91         for (i = 0; i < 4; i++, me >>= 8, him >>= 8, mask >>= 8) 
  92         {
  93                 if ((me & 0xFF) != (him & 0xFF)) 
  94                 {
  95                 /*
  96                  * The only way this could be a match is for
  97                  * the rest of addr1 to be 0 or 255.
  98                  */
  99                         if (me != 0 && me != mask) 
 100                                 return(0);
 101                         return(1);
 102                 }
 103         }
 104         return(1);
 105 }
 106 
 107 
 108 /* 
 109  *      Check the address for our address, broadcasts, etc. 
 110  *
 111  *      I intend to fix this to at the very least cache the last
 112  *      resolved entry.
 113  */
 114  
 115 int ip_chk_addr(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 116 {
 117         struct device *dev;
 118         unsigned long mask;
 119 
 120         /* 
 121          *      Accept both `all ones' and `all zeros' as BROADCAST. 
 122          *      (Support old BSD in other words). This old BSD 
 123          *      support will go very soon as it messes other things
 124          *      up.
 125          */
 126 
 127         if (addr == INADDR_ANY || addr == INADDR_BROADCAST)
 128                 return IS_BROADCAST;
 129 
 130         mask = ip_get_mask(addr);
 131 
 132         /*
 133          *      Accept all of the `loopback' class A net. 
 134          */
 135          
 136         if ((addr & mask) == htonl(0x7F000000L))
 137                 return IS_MYADDR;
 138 
 139         /*
 140          *      OK, now check the interface addresses. 
 141          */
 142          
 143         for (dev = dev_base; dev != NULL; dev = dev->next) 
 144         {
 145                 if (!(dev->flags & IFF_UP))
 146                         continue;
 147                 /*
 148                  *      If the protocol address of the device is 0 this is special
 149                  *      and means we are address hunting (eg bootp).
 150                  */
 151                  
 152                 if ((dev->pa_addr == 0)/* || (dev->flags&IFF_PROMISC)*/)
 153                         return IS_MYADDR;
 154                 /*
 155                  *      Is it the exact IP address? 
 156                  */
 157                  
 158                 if (addr == dev->pa_addr)
 159                         return IS_MYADDR;
 160                 /*
 161                  *      Is it our broadcast address? 
 162                  */
 163                  
 164                 if ((dev->flags & IFF_BROADCAST) && addr == dev->pa_brdaddr)
 165                         return IS_BROADCAST;
 166                 /*
 167                  *      Nope. Check for a subnetwork broadcast. 
 168                  */
 169                  
 170                 if (((addr ^ dev->pa_addr) & dev->pa_mask) == 0) 
 171                 {
 172                         if ((addr & ~dev->pa_mask) == 0)
 173                                 return IS_BROADCAST;
 174                         if ((addr & ~dev->pa_mask) == ~dev->pa_mask)
 175                                 return IS_BROADCAST;
 176                 }
 177                 
 178                 /*
 179                  *      Nope. Check for Network broadcast. 
 180                  */
 181                  
 182                 if (((addr ^ dev->pa_addr) & mask) == 0) 
 183                 {
 184                         if ((addr & ~mask) == 0)
 185                                 return IS_BROADCAST;
 186                         if ((addr & ~mask) == ~mask)
 187                                 return IS_BROADCAST;
 188                 }
 189         }
 190         return 0;               /* no match at all */
 191 }
 192 
 193 
 194 /*
 195  *      Retrieve our own address.
 196  *
 197  *      Because the loopback address (127.0.0.1) is already recognized
 198  *      automatically, we can use the loopback interface's address as
 199  *      our "primary" interface.  This is the addressed used by IP et
 200  *      al when it doesn't know which address to use (i.e. it does not
 201  *      yet know from or to which interface to go...).
 202  */
 203  
 204 unsigned long ip_my_addr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 205 {
 206         struct device *dev;
 207 
 208         for (dev = dev_base; dev != NULL; dev = dev->next) 
 209         {
 210                 if (dev->flags & IFF_LOOPBACK) 
 211                         return(dev->pa_addr);
 212         }
 213         return(0);
 214 }
 215 
 216 /*
 217  *      Find an interface that can handle addresses for a certain address. 
 218  *
 219  *      This needs optimising, since its relatively trivial to collapse
 220  *      the two loops into one.
 221  */
 222  
 223 struct device * ip_dev_check(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 224 {
 225         struct device *dev;
 226 
 227         for (dev = dev_base; dev; dev = dev->next) 
 228         {
 229                 if (!(dev->flags & IFF_UP))
 230                         continue;
 231                 if (!(dev->flags & IFF_POINTOPOINT))
 232                         continue;
 233                 if (addr != dev->pa_dstaddr)
 234                         continue;
 235                 return dev;
 236         }
 237         for (dev = dev_base; dev; dev = dev->next) 
 238         {
 239                 if (!(dev->flags & IFF_UP))
 240                         continue;
 241                 if (dev->flags & IFF_POINTOPOINT)
 242                         continue;
 243                 if (dev->pa_mask & (addr ^ dev->pa_addr))
 244                         continue;
 245                 return dev;
 246         }
 247         return NULL;
 248 }

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