home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / net / inet / devinet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-06  |  4.6 KB  |  214 lines

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