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