Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
addrconf_core.c
Go to the documentation of this file.
1 /*
2  * IPv6 library code, needed by static components when full IPv6 support is
3  * not configured or static.
4  */
5 
6 #include <linux/export.h>
7 #include <net/ipv6.h>
8 
9 #define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16)
10 
11 static inline unsigned int ipv6_addr_scope2type(unsigned int scope)
12 {
13  switch (scope) {
23  }
24  return IPV6_ADDR_SCOPE_TYPE(scope);
25 }
26 
27 int __ipv6_addr_type(const struct in6_addr *addr)
28 {
29  __be32 st;
30 
31  st = addr->s6_addr32[0];
32 
33  /* Consider all addresses with the first three bits different of
34  000 and 111 as unicasts.
35  */
36  if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
37  (st & htonl(0xE0000000)) != htonl(0xE0000000))
38  return (IPV6_ADDR_UNICAST |
40 
41  if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
42  /* multicast */
43  /* addr-select 3.1 */
44  return (IPV6_ADDR_MULTICAST |
45  ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr)));
46  }
47 
48  if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
50  IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.1 */
51  if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
53  IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL)); /* addr-select 3.1 */
54  if ((st & htonl(0xFE000000)) == htonl(0xFC000000))
55  return (IPV6_ADDR_UNICAST |
57 
58  if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
59  if (addr->s6_addr32[2] == 0) {
60  if (addr->s6_addr32[3] == 0)
61  return IPV6_ADDR_ANY;
62 
63  if (addr->s6_addr32[3] == htonl(0x00000001))
65  IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.4 */
66 
68  IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */
69  }
70 
71  if (addr->s6_addr32[2] == htonl(0x0000ffff))
72  return (IPV6_ADDR_MAPPED |
73  IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */
74  }
75 
76  return (IPV6_ADDR_UNICAST |
77  IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.4 */
78 }
80