| 186 | # there are many others like that. |
| 187 | # TODO : integrate Unique Local Addresses |
| 188 | def in6_getAddrType(addr): |
| 189 | # type: (str) -> int |
| 190 | naddr = inet_pton(socket.AF_INET6, addr) |
| 191 | paddr = inet_ntop(socket.AF_INET6, naddr) # normalize |
| 192 | addrType = 0 |
| 193 | # _Assignable_ Global Unicast Address space |
| 194 | # is defined in RFC 3513 as those in 2000::/3 |
| 195 | if ((orb(naddr[0]) & 0xE0) == 0x20): |
| 196 | addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_GLOBAL) |
| 197 | if naddr[:2] == b' \x02': # Mark 6to4 @ |
| 198 | addrType |= IPV6_ADDR_6TO4 |
| 199 | elif orb(naddr[0]) == 0xff: # multicast |
| 200 | addrScope = paddr[3] |
| 201 | if addrScope == '2': |
| 202 | addrType = (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_MULTICAST) |
| 203 | elif addrScope == 'e': |
| 204 | addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST) |
| 205 | else: |
| 206 | addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST) |
| 207 | elif ((orb(naddr[0]) == 0xfe) and ((int(paddr[2], 16) & 0xC) == 0x8)): |
| 208 | addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL) |
| 209 | elif paddr == "::1": |
| 210 | addrType = IPV6_ADDR_LOOPBACK |
| 211 | elif paddr == "::": |
| 212 | addrType = IPV6_ADDR_UNSPECIFIED |
| 213 | else: |
| 214 | # Everything else is global unicast (RFC 3513) |
| 215 | # Even old deprecated (RFC3879) Site-Local addresses |
| 216 | addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST) |
| 217 | |
| 218 | return addrType |
| 219 | |
| 220 | |
| 221 | def in6_mactoifaceid(mac, ulbit=None): |