diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-01-07 02:33:00 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1997-01-07 02:33:00 +0000 |
commit | beb116954b9b7f3bb56412b2494b562f02b864b1 (patch) | |
tree | 120e997879884e1b9d93b265221b939d2ef1ade1 /net/ipv4/devinet.c | |
parent | 908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff) |
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r-- | net/ipv4/devinet.c | 74 |
1 files changed, 55 insertions, 19 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 794a7e897..0c2d70cae 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -14,8 +14,10 @@ * Additional Authors: * Alan Cox, <gw4pts@gw4pts.ampr.org> */ + +#include <linux/config.h> /* For CONFIG_IP_CLASSLESS */ -#include <asm/segment.h> +#include <asm/uaccess.h> #include <asm/system.h> #include <asm/bitops.h> #include <linux/types.h> @@ -76,7 +78,9 @@ unsigned long ip_get_mask(unsigned long addr) int ip_chk_addr(unsigned long addr) { struct device *dev; +#ifndef CONFIG_IP_CLASSLESS unsigned long mask; +#endif /* * Accept both `all ones' and `all zeros' as BROADCAST. @@ -90,6 +94,7 @@ int ip_chk_addr(unsigned long addr) addr == htonl(0x7FFFFFFFL)) return IS_BROADCAST; +#ifndef CONFIG_IP_CLASSLESS mask = ip_get_mask(addr); /* @@ -98,6 +103,10 @@ int ip_chk_addr(unsigned long addr) if ((addr & mask) == htonl(0x7F000000L)) return IS_MYADDR; +#else + if ((addr & htonl(0x7F000000L)) == htonl(0x7F000000L)) + return IS_MYADDR; +#endif /* * OK, now check the interface addresses. We could @@ -106,14 +115,14 @@ int ip_chk_addr(unsigned long addr) for (dev = dev_base; dev != NULL; dev = dev->next) { - if (!(dev->flags & IFF_UP)) + if ((!(dev->flags & IFF_UP)) || dev->family!=AF_INET) continue; /* * If the protocol address of the device is 0 this is special * and means we are address hunting (eg bootp). */ - if ((dev->pa_addr == 0)/* || (dev->flags&IFF_PROMISC)*/) + if (dev->pa_addr == 0) return IS_MYADDR; /* * Is it the exact IP address? @@ -139,6 +148,7 @@ int ip_chk_addr(unsigned long addr) return IS_BROADCAST; } +#ifndef CONFIG_IP_CLASSLESS /* * Nope. Check for Network broadcast. */ @@ -150,6 +160,7 @@ int ip_chk_addr(unsigned long addr) if ((addr & ~mask) == ~mask) return IS_BROADCAST; } +#endif } if(IN_MULTICAST(ntohl(addr))) return IS_MULTICAST; @@ -181,35 +192,60 @@ unsigned long ip_my_addr(void) /* * Find an interface that can handle addresses for a certain address. - * - * This needs optimising, since it's relatively trivial to collapse - * the two loops into one. */ - -struct device * ip_dev_check(unsigned long addr) + +struct device * ip_dev_bynet(unsigned long addr, unsigned long mask) { struct device *dev; + struct device *best_dev = NULL; + __u32 best_mask = mask; for (dev = dev_base; dev; dev = dev->next) { if (!(dev->flags & IFF_UP)) continue; - if (!(dev->flags & IFF_POINTOPOINT)) - continue; - if (addr != dev->pa_dstaddr) - continue; - return dev; - } - for (dev = dev_base; dev; dev = dev->next) - { - if (!(dev->flags & IFF_UP)) - continue; if (dev->flags & IFF_POINTOPOINT) + { + if (addr == dev->pa_dstaddr) + return dev; continue; + } if (dev->pa_mask & (addr ^ dev->pa_addr)) continue; - return dev; + if (mask == dev->pa_mask) + return dev; + if (best_dev && (best_mask & dev->pa_mask) != best_mask) + continue; + best_dev = dev; + best_mask = dev->pa_mask; + } + return best_dev; +} + +/* + * Find the first device with a given source address. + */ + +struct device *ip_dev_find(unsigned long addr) +{ + struct device *dev; + for(dev = dev_base; dev; dev=dev->next) + { + if((dev->flags&IFF_UP) && dev->pa_addr==addr) + return dev; } return NULL; } +struct device *dev_getbytype(unsigned short type) +{ + struct device *dev; + + for (dev = dev_base; dev != NULL; dev = dev->next) + { + if (dev->type == type && !(dev->flags&(IFF_LOOPBACK|IFF_NOARP))) + return(dev); + } + return(NULL); +} + |