addrconf.c (0ad3a96f8ad910ecf87a25ec69ed360b284dee2e) addrconf.c (b1cacb6820e0afc4aeeea67bcb5296a316862cad)
1/*
2 * IPv6 Address [auto]configuration
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *

--- 21 unchanged lines hidden (view full) ---

30 * address validation timer.
31 * YOSHIFUJI Hideaki @USAGI : Privacy Extensions (RFC3041)
32 * support.
33 * Yuji SEKIYA @USAGI : Don't assign a same IPv6
34 * address on a same interface.
35 * YOSHIFUJI Hideaki @USAGI : ARCnet support
36 * YOSHIFUJI Hideaki @USAGI : convert /proc/net/if_inet6 to
37 * seq_file.
1/*
2 * IPv6 Address [auto]configuration
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *

--- 21 unchanged lines hidden (view full) ---

30 * address validation timer.
31 * YOSHIFUJI Hideaki @USAGI : Privacy Extensions (RFC3041)
32 * support.
33 * Yuji SEKIYA @USAGI : Don't assign a same IPv6
34 * address on a same interface.
35 * YOSHIFUJI Hideaki @USAGI : ARCnet support
36 * YOSHIFUJI Hideaki @USAGI : convert /proc/net/if_inet6 to
37 * seq_file.
38 * YOSHIFUJI Hideaki @USAGI : improved source address
39 * selection; consider scope,
40 * status etc.
38 */
39
40#include <linux/config.h>
41#include <linux/errno.h>
42#include <linux/types.h>
43#include <linux/socket.h>
44#include <linux/sockios.h>
45#include <linux/sched.h>

--- 142 unchanged lines hidden (view full) ---

188};
189
190/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
191#if 0
192const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
193#endif
194const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
195
41 */
42
43#include <linux/config.h>
44#include <linux/errno.h>
45#include <linux/types.h>
46#include <linux/socket.h>
47#include <linux/sockios.h>
48#include <linux/sched.h>

--- 142 unchanged lines hidden (view full) ---

191};
192
193/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
194#if 0
195const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
196#endif
197const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
198
196int ipv6_addr_type(const struct in6_addr *addr)
199#define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16)
200
201static inline unsigned ipv6_addr_scope2type(unsigned scope)
197{
202{
198 int type;
203 switch(scope) {
204 case IPV6_ADDR_SCOPE_NODELOCAL:
205 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL) |
206 IPV6_ADDR_LOOPBACK);
207 case IPV6_ADDR_SCOPE_LINKLOCAL:
208 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL) |
209 IPV6_ADDR_LINKLOCAL);
210 case IPV6_ADDR_SCOPE_SITELOCAL:
211 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL) |
212 IPV6_ADDR_SITELOCAL);
213 }
214 return IPV6_ADDR_SCOPE_TYPE(scope);
215}
216
217int __ipv6_addr_type(const struct in6_addr *addr)
218{
199 u32 st;
200
201 st = addr->s6_addr32[0];
202
219 u32 st;
220
221 st = addr->s6_addr32[0];
222
203 if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
204 type = IPV6_ADDR_MULTICAST;
205
206 switch((st & htonl(0x00FF0000))) {
207 case __constant_htonl(0x00010000):
208 type |= IPV6_ADDR_LOOPBACK;
209 break;
210
211 case __constant_htonl(0x00020000):
212 type |= IPV6_ADDR_LINKLOCAL;
213 break;
214
215 case __constant_htonl(0x00050000):
216 type |= IPV6_ADDR_SITELOCAL;
217 break;
218 };
219 return type;
220 }
221
222 type = IPV6_ADDR_UNICAST;
223
224 /* Consider all addresses with the first three bits different of
223 /* Consider all addresses with the first three bits different of
225 000 and 111 as finished.
224 000 and 111 as unicasts.
226 */
227 if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
228 (st & htonl(0xE0000000)) != htonl(0xE0000000))
225 */
226 if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
227 (st & htonl(0xE0000000)) != htonl(0xE0000000))
229 return type;
230
231 if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
232 return (IPV6_ADDR_LINKLOCAL | type);
228 return (IPV6_ADDR_UNICAST |
229 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));
233
230
231 if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
232 /* multicast */
233 /* addr-select 3.1 */
234 return (IPV6_ADDR_MULTICAST |
235 ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr)));
236 }
237
238 if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
239 return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST |
240 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.1 */
234 if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
241 if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
235 return (IPV6_ADDR_SITELOCAL | type);
242 return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST |
243 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL)); /* addr-select 3.1 */
236
237 if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
238 if (addr->s6_addr32[2] == 0) {
239 if (addr->s6_addr32[3] == 0)
240 return IPV6_ADDR_ANY;
241
242 if (addr->s6_addr32[3] == htonl(0x00000001))
244
245 if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
246 if (addr->s6_addr32[2] == 0) {
247 if (addr->s6_addr32[3] == 0)
248 return IPV6_ADDR_ANY;
249
250 if (addr->s6_addr32[3] == htonl(0x00000001))
243 return (IPV6_ADDR_LOOPBACK | type);
251 return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST |
252 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.4 */
244
253
245 return (IPV6_ADDR_COMPATv4 | type);
254 return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST |
255 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */
246 }
247
248 if (addr->s6_addr32[2] == htonl(0x0000ffff))
256 }
257
258 if (addr->s6_addr32[2] == htonl(0x0000ffff))
249 return IPV6_ADDR_MAPPED;
259 return (IPV6_ADDR_MAPPED |
260 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */
250 }
251
261 }
262
252 st &= htonl(0xFF000000);
253 if (st == 0)
254 return IPV6_ADDR_RESERVED;
255 st &= htonl(0xFE000000);
256 if (st == htonl(0x02000000))
257 return IPV6_ADDR_RESERVED; /* for NSAP */
258 if (st == htonl(0x04000000))
259 return IPV6_ADDR_RESERVED; /* for IPX */
260 return type;
263 return (IPV6_ADDR_RESERVED |
264 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.4 */
261}
262
263static void addrconf_del_timer(struct inet6_ifaddr *ifp)
264{
265 if (del_timer(&ifp->timer))
266 __in6_ifa_put(ifp);
267}
268

--- 3332 unchanged lines hidden ---
265}
266
267static void addrconf_del_timer(struct inet6_ifaddr *ifp)
268{
269 if (del_timer(&ifp->timer))
270 __in6_ifa_put(ifp);
271}
272

--- 3332 unchanged lines hidden ---