Blame view

net/ipv6/addrconf_core.c 2.42 KB
8c14b7ce2   YOSHIFUJI Hideaki   [IPV6] ADDRCONF: ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  /*
   * IPv6 library code, needed by static components when full IPv6 support is
   * not configured or static.
   */
  
  #include <net/ipv6.h>
  
  #define IPV6_ADDR_SCOPE_TYPE(scope)	((scope) << 16)
  
  static inline unsigned ipv6_addr_scope2type(unsigned scope)
  {
  	switch(scope) {
  	case IPV6_ADDR_SCOPE_NODELOCAL:
  		return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL) |
  			IPV6_ADDR_LOOPBACK);
  	case IPV6_ADDR_SCOPE_LINKLOCAL:
  		return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL) |
  			IPV6_ADDR_LINKLOCAL);
  	case IPV6_ADDR_SCOPE_SITELOCAL:
  		return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL) |
  			IPV6_ADDR_SITELOCAL);
  	}
  	return IPV6_ADDR_SCOPE_TYPE(scope);
  }
  
  int __ipv6_addr_type(const struct in6_addr *addr)
  {
  	__be32 st;
  
  	st = addr->s6_addr32[0];
  
  	/* Consider all addresses with the first three bits different of
  	   000 and 111 as unicasts.
  	 */
  	if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
  	    (st & htonl(0xE0000000)) != htonl(0xE0000000))
  		return (IPV6_ADDR_UNICAST |
  			IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));
  
  	if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
  		/* multicast */
  		/* addr-select 3.1 */
  		return (IPV6_ADDR_MULTICAST |
  			ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr)));
  	}
  
  	if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
  		return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST |
  			IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL));		/* addr-select 3.1 */
  	if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
  		return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST |
  			IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL));		/* addr-select 3.1 */
c61a7d10e   Dave Johnson   [IPV6]: ipv6_addr...
53
54
55
  	if ((st & htonl(0xFE000000)) == htonl(0xFC000000))
  		return (IPV6_ADDR_UNICAST |
  			IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));			/* RFC 4193 */
8c14b7ce2   YOSHIFUJI Hideaki   [IPV6] ADDRCONF: ...
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  
  	if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
  		if (addr->s6_addr32[2] == 0) {
  			if (addr->s6_addr32[3] == 0)
  				return IPV6_ADDR_ANY;
  
  			if (addr->s6_addr32[3] == htonl(0x00000001))
  				return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST |
  					IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL));	/* addr-select 3.4 */
  
  			return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST |
  				IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));	/* addr-select 3.3 */
  		}
  
  		if (addr->s6_addr32[2] == htonl(0x0000ffff))
  			return (IPV6_ADDR_MAPPED |
  				IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));	/* addr-select 3.3 */
  	}
45bb00609   Ulrich Weber   ipv6: Remove IPV6...
74
  	return (IPV6_ADDR_UNICAST |
8c14b7ce2   YOSHIFUJI Hideaki   [IPV6] ADDRCONF: ...
75
76
  		IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));	/* addr-select 3.4 */
  }
7401055b5   David S. Miller   [IPV6]: Fix __ipv...
77
  EXPORT_SYMBOL(__ipv6_addr_type);
8c14b7ce2   YOSHIFUJI Hideaki   [IPV6] ADDRCONF: ...
78