summaryrefslogtreecommitdiffstats
path: root/net/ipv4/devinet.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
committer <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
commitbeb116954b9b7f3bb56412b2494b562f02b864b1 (patch)
tree120e997879884e1b9d93b265221b939d2ef1ade1 /net/ipv4/devinet.c
parent908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff)
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r--net/ipv4/devinet.c74
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);
+}
+