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 --- |