ipv6addr.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. package sockaddr
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "fmt"
  6. "math/big"
  7. "net"
  8. )
  9. type (
  10. // IPv6Address is a named type representing an IPv6 address.
  11. IPv6Address *big.Int
  12. // IPv6Network is a named type representing an IPv6 network.
  13. IPv6Network *big.Int
  14. // IPv6Mask is a named type representing an IPv6 network mask.
  15. IPv6Mask *big.Int
  16. )
  17. // IPv6HostPrefix is a constant represents a /128 IPv6 Prefix.
  18. const IPv6HostPrefix = IPPrefixLen(128)
  19. // ipv6HostMask is an unexported big.Int representing a /128 IPv6 address.
  20. // This value must be a constant and always set to all ones.
  21. var ipv6HostMask IPv6Mask
  22. // ipv6AddrAttrMap is a map of the IPv6Addr type-specific attributes.
  23. var ipv6AddrAttrMap map[AttrName]func(IPv6Addr) string
  24. var ipv6AddrAttrs []AttrName
  25. func init() {
  26. biMask := new(big.Int)
  27. biMask.SetBytes([]byte{
  28. 0xff, 0xff,
  29. 0xff, 0xff,
  30. 0xff, 0xff,
  31. 0xff, 0xff,
  32. 0xff, 0xff,
  33. 0xff, 0xff,
  34. 0xff, 0xff,
  35. 0xff, 0xff,
  36. },
  37. )
  38. ipv6HostMask = IPv6Mask(biMask)
  39. ipv6AddrInit()
  40. }
  41. // IPv6Addr implements a convenience wrapper around the union of Go's
  42. // built-in net.IP and net.IPNet types. In UNIX-speak, IPv6Addr implements
  43. // `sockaddr` when the the address family is set to AF_INET6
  44. // (i.e. `sockaddr_in6`).
  45. type IPv6Addr struct {
  46. IPAddr
  47. Address IPv6Address
  48. Mask IPv6Mask
  49. Port IPPort
  50. }
  51. // NewIPv6Addr creates an IPv6Addr from a string. String can be in the form of
  52. // an an IPv6:port (e.g. `[2001:4860:0:2001::68]:80`, in which case the mask is
  53. // assumed to be a /128), an IPv6 address (e.g. `2001:4860:0:2001::68`, also
  54. // with a `/128` mask), an IPv6 CIDR (e.g. `2001:4860:0:2001::68/64`, which has
  55. // its IP port initialized to zero). ipv6Str can not be a hostname.
  56. //
  57. // NOTE: Many net.*() routines will initialize and return an IPv4 address.
  58. // Always test to make sure the address returned cannot be converted to a 4 byte
  59. // array using To4().
  60. func NewIPv6Addr(ipv6Str string) (IPv6Addr, error) {
  61. v6Addr := false
  62. LOOP:
  63. for i := 0; i < len(ipv6Str); i++ {
  64. switch ipv6Str[i] {
  65. case '.':
  66. break LOOP
  67. case ':':
  68. v6Addr = true
  69. break LOOP
  70. }
  71. }
  72. if !v6Addr {
  73. return IPv6Addr{}, fmt.Errorf("Unable to resolve %+q as an IPv6 address, appears to be an IPv4 address", ipv6Str)
  74. }
  75. // Attempt to parse ipv6Str as a /128 host with a port number.
  76. tcpAddr, err := net.ResolveTCPAddr("tcp6", ipv6Str)
  77. if err == nil {
  78. ipv6 := tcpAddr.IP.To16()
  79. if ipv6 == nil {
  80. return IPv6Addr{}, fmt.Errorf("Unable to resolve %+q as a 16byte IPv6 address", ipv6Str)
  81. }
  82. ipv6BigIntAddr := new(big.Int)
  83. ipv6BigIntAddr.SetBytes(ipv6)
  84. ipv6BigIntMask := new(big.Int)
  85. ipv6BigIntMask.Set(ipv6HostMask)
  86. ipv6Addr := IPv6Addr{
  87. Address: IPv6Address(ipv6BigIntAddr),
  88. Mask: IPv6Mask(ipv6BigIntMask),
  89. Port: IPPort(tcpAddr.Port),
  90. }
  91. return ipv6Addr, nil
  92. }
  93. // Parse as a naked IPv6 address. Trim square brackets if present.
  94. if len(ipv6Str) > 2 && ipv6Str[0] == '[' && ipv6Str[len(ipv6Str)-1] == ']' {
  95. ipv6Str = ipv6Str[1 : len(ipv6Str)-1]
  96. }
  97. ip := net.ParseIP(ipv6Str)
  98. if ip != nil {
  99. ipv6 := ip.To16()
  100. if ipv6 == nil {
  101. return IPv6Addr{}, fmt.Errorf("Unable to string convert %+q to a 16byte IPv6 address", ipv6Str)
  102. }
  103. ipv6BigIntAddr := new(big.Int)
  104. ipv6BigIntAddr.SetBytes(ipv6)
  105. ipv6BigIntMask := new(big.Int)
  106. ipv6BigIntMask.Set(ipv6HostMask)
  107. return IPv6Addr{
  108. Address: IPv6Address(ipv6BigIntAddr),
  109. Mask: IPv6Mask(ipv6BigIntMask),
  110. }, nil
  111. }
  112. // Parse as an IPv6 CIDR
  113. ipAddr, network, err := net.ParseCIDR(ipv6Str)
  114. if err == nil {
  115. ipv6 := ipAddr.To16()
  116. if ipv6 == nil {
  117. return IPv6Addr{}, fmt.Errorf("Unable to convert %+q to a 16byte IPv6 address", ipv6Str)
  118. }
  119. ipv6BigIntAddr := new(big.Int)
  120. ipv6BigIntAddr.SetBytes(ipv6)
  121. ipv6BigIntMask := new(big.Int)
  122. ipv6BigIntMask.SetBytes(network.Mask)
  123. ipv6Addr := IPv6Addr{
  124. Address: IPv6Address(ipv6BigIntAddr),
  125. Mask: IPv6Mask(ipv6BigIntMask),
  126. }
  127. return ipv6Addr, nil
  128. }
  129. return IPv6Addr{}, fmt.Errorf("Unable to parse %+q to an IPv6 address: %v", ipv6Str, err)
  130. }
  131. // AddressBinString returns a string with the IPv6Addr's Address represented
  132. // as a sequence of '0' and '1' characters. This method is useful for
  133. // debugging or by operators who want to inspect an address.
  134. func (ipv6 IPv6Addr) AddressBinString() string {
  135. bi := big.Int(*ipv6.Address)
  136. return fmt.Sprintf("%0128s", bi.Text(2))
  137. }
  138. // AddressHexString returns a string with the IPv6Addr address represented as
  139. // a sequence of hex characters. This method is useful for debugging or by
  140. // operators who want to inspect an address.
  141. func (ipv6 IPv6Addr) AddressHexString() string {
  142. bi := big.Int(*ipv6.Address)
  143. return fmt.Sprintf("%032s", bi.Text(16))
  144. }
  145. // CmpAddress follows the Cmp() standard protocol and returns:
  146. //
  147. // - -1 If the receiver should sort first because its address is lower than arg
  148. // - 0 if the SockAddr arg equal to the receiving IPv6Addr or the argument is of a
  149. // different type.
  150. // - 1 If the argument should sort first.
  151. func (ipv6 IPv6Addr) CmpAddress(sa SockAddr) int {
  152. ipv6b, ok := sa.(IPv6Addr)
  153. if !ok {
  154. return sortDeferDecision
  155. }
  156. ipv6aBigInt := new(big.Int)
  157. ipv6aBigInt.Set(ipv6.Address)
  158. ipv6bBigInt := new(big.Int)
  159. ipv6bBigInt.Set(ipv6b.Address)
  160. return ipv6aBigInt.Cmp(ipv6bBigInt)
  161. }
  162. // CmpPort follows the Cmp() standard protocol and returns:
  163. //
  164. // - -1 If the receiver should sort first because its port is lower than arg
  165. // - 0 if the SockAddr arg's port number is equal to the receiving IPv6Addr,
  166. // regardless of type.
  167. // - 1 If the argument should sort first.
  168. func (ipv6 IPv6Addr) CmpPort(sa SockAddr) int {
  169. var saPort IPPort
  170. switch v := sa.(type) {
  171. case IPv4Addr:
  172. saPort = v.Port
  173. case IPv6Addr:
  174. saPort = v.Port
  175. default:
  176. return sortDeferDecision
  177. }
  178. switch {
  179. case ipv6.Port == saPort:
  180. return sortDeferDecision
  181. case ipv6.Port < saPort:
  182. return sortReceiverBeforeArg
  183. default:
  184. return sortArgBeforeReceiver
  185. }
  186. }
  187. // CmpRFC follows the Cmp() standard protocol and returns:
  188. //
  189. // - -1 If the receiver should sort first because it belongs to the RFC and its
  190. // arg does not
  191. // - 0 if the receiver and arg both belong to the same RFC or neither do.
  192. // - 1 If the arg belongs to the RFC but receiver does not.
  193. func (ipv6 IPv6Addr) CmpRFC(rfcNum uint, sa SockAddr) int {
  194. recvInRFC := IsRFC(rfcNum, ipv6)
  195. ipv6b, ok := sa.(IPv6Addr)
  196. if !ok {
  197. // If the receiver is part of the desired RFC and the SockAddr
  198. // argument is not, sort receiver before the non-IPv6 SockAddr.
  199. // Conversely, if the receiver is not part of the RFC, punt on
  200. // sorting and leave it for the next sorter.
  201. if recvInRFC {
  202. return sortReceiverBeforeArg
  203. } else {
  204. return sortDeferDecision
  205. }
  206. }
  207. argInRFC := IsRFC(rfcNum, ipv6b)
  208. switch {
  209. case (recvInRFC && argInRFC), (!recvInRFC && !argInRFC):
  210. // If a and b both belong to the RFC, or neither belong to
  211. // rfcNum, defer sorting to the next sorter.
  212. return sortDeferDecision
  213. case recvInRFC && !argInRFC:
  214. return sortReceiverBeforeArg
  215. default:
  216. return sortArgBeforeReceiver
  217. }
  218. }
  219. // Contains returns true if the SockAddr is contained within the receiver.
  220. func (ipv6 IPv6Addr) Contains(sa SockAddr) bool {
  221. ipv6b, ok := sa.(IPv6Addr)
  222. if !ok {
  223. return false
  224. }
  225. return ipv6.ContainsNetwork(ipv6b)
  226. }
  227. // ContainsAddress returns true if the IPv6Address is contained within the
  228. // receiver.
  229. func (ipv6 IPv6Addr) ContainsAddress(x IPv6Address) bool {
  230. xAddr := IPv6Addr{
  231. Address: x,
  232. Mask: ipv6HostMask,
  233. }
  234. {
  235. xIPv6 := xAddr.FirstUsable().(IPv6Addr)
  236. yIPv6 := ipv6.FirstUsable().(IPv6Addr)
  237. if xIPv6.CmpAddress(yIPv6) >= 1 {
  238. return false
  239. }
  240. }
  241. {
  242. xIPv6 := xAddr.LastUsable().(IPv6Addr)
  243. yIPv6 := ipv6.LastUsable().(IPv6Addr)
  244. if xIPv6.CmpAddress(yIPv6) <= -1 {
  245. return false
  246. }
  247. }
  248. return true
  249. }
  250. // ContainsNetwork returns true if the network from IPv6Addr is contained within
  251. // the receiver.
  252. func (x IPv6Addr) ContainsNetwork(y IPv6Addr) bool {
  253. {
  254. xIPv6 := x.FirstUsable().(IPv6Addr)
  255. yIPv6 := y.FirstUsable().(IPv6Addr)
  256. if ret := xIPv6.CmpAddress(yIPv6); ret >= 1 {
  257. return false
  258. }
  259. }
  260. {
  261. xIPv6 := x.LastUsable().(IPv6Addr)
  262. yIPv6 := y.LastUsable().(IPv6Addr)
  263. if ret := xIPv6.CmpAddress(yIPv6); ret <= -1 {
  264. return false
  265. }
  266. }
  267. return true
  268. }
  269. // DialPacketArgs returns the arguments required to be passed to
  270. // net.DialUDP(). If the Mask of ipv6 is not a /128 or the Port is 0,
  271. // DialPacketArgs() will fail. See Host() to create an IPv6Addr with its
  272. // mask set to /128.
  273. func (ipv6 IPv6Addr) DialPacketArgs() (network, dialArgs string) {
  274. ipv6Mask := big.Int(*ipv6.Mask)
  275. if ipv6Mask.Cmp(ipv6HostMask) != 0 || ipv6.Port == 0 {
  276. return "udp6", ""
  277. }
  278. return "udp6", fmt.Sprintf("[%s]:%d", ipv6.NetIP().String(), ipv6.Port)
  279. }
  280. // DialStreamArgs returns the arguments required to be passed to
  281. // net.DialTCP(). If the Mask of ipv6 is not a /128 or the Port is 0,
  282. // DialStreamArgs() will fail. See Host() to create an IPv6Addr with its
  283. // mask set to /128.
  284. func (ipv6 IPv6Addr) DialStreamArgs() (network, dialArgs string) {
  285. ipv6Mask := big.Int(*ipv6.Mask)
  286. if ipv6Mask.Cmp(ipv6HostMask) != 0 || ipv6.Port == 0 {
  287. return "tcp6", ""
  288. }
  289. return "tcp6", fmt.Sprintf("[%s]:%d", ipv6.NetIP().String(), ipv6.Port)
  290. }
  291. // Equal returns true if a SockAddr is equal to the receiving IPv4Addr.
  292. func (ipv6a IPv6Addr) Equal(sa SockAddr) bool {
  293. ipv6b, ok := sa.(IPv6Addr)
  294. if !ok {
  295. return false
  296. }
  297. if ipv6a.NetIP().String() != ipv6b.NetIP().String() {
  298. return false
  299. }
  300. if ipv6a.NetIPNet().String() != ipv6b.NetIPNet().String() {
  301. return false
  302. }
  303. if ipv6a.Port != ipv6b.Port {
  304. return false
  305. }
  306. return true
  307. }
  308. // FirstUsable returns an IPv6Addr set to the first address following the
  309. // network prefix. The first usable address in a network is normally the
  310. // gateway and should not be used except by devices forwarding packets
  311. // between two administratively distinct networks (i.e. a router). This
  312. // function does not discriminate against first usable vs "first address that
  313. // should be used." For example, FirstUsable() on "2001:0db8::0003/64" would
  314. // return "2001:0db8::00011".
  315. func (ipv6 IPv6Addr) FirstUsable() IPAddr {
  316. return IPv6Addr{
  317. Address: IPv6Address(ipv6.NetworkAddress()),
  318. Mask: ipv6HostMask,
  319. }
  320. }
  321. // Host returns a copy of ipv6 with its mask set to /128 so that it can be
  322. // used by DialPacketArgs(), DialStreamArgs(), ListenPacketArgs(), or
  323. // ListenStreamArgs().
  324. func (ipv6 IPv6Addr) Host() IPAddr {
  325. // Nothing should listen on a broadcast address.
  326. return IPv6Addr{
  327. Address: ipv6.Address,
  328. Mask: ipv6HostMask,
  329. Port: ipv6.Port,
  330. }
  331. }
  332. // IPPort returns the Port number attached to the IPv6Addr
  333. func (ipv6 IPv6Addr) IPPort() IPPort {
  334. return ipv6.Port
  335. }
  336. // LastUsable returns the last address in a given network.
  337. func (ipv6 IPv6Addr) LastUsable() IPAddr {
  338. addr := new(big.Int)
  339. addr.Set(ipv6.Address)
  340. mask := new(big.Int)
  341. mask.Set(ipv6.Mask)
  342. negMask := new(big.Int)
  343. negMask.Xor(ipv6HostMask, mask)
  344. lastAddr := new(big.Int)
  345. lastAddr.And(addr, mask)
  346. lastAddr.Or(lastAddr, negMask)
  347. return IPv6Addr{
  348. Address: IPv6Address(lastAddr),
  349. Mask: ipv6HostMask,
  350. }
  351. }
  352. // ListenPacketArgs returns the arguments required to be passed to
  353. // net.ListenUDP(). If the Mask of ipv6 is not a /128, ListenPacketArgs()
  354. // will fail. See Host() to create an IPv6Addr with its mask set to /128.
  355. func (ipv6 IPv6Addr) ListenPacketArgs() (network, listenArgs string) {
  356. ipv6Mask := big.Int(*ipv6.Mask)
  357. if ipv6Mask.Cmp(ipv6HostMask) != 0 {
  358. return "udp6", ""
  359. }
  360. return "udp6", fmt.Sprintf("[%s]:%d", ipv6.NetIP().String(), ipv6.Port)
  361. }
  362. // ListenStreamArgs returns the arguments required to be passed to
  363. // net.ListenTCP(). If the Mask of ipv6 is not a /128, ListenStreamArgs()
  364. // will fail. See Host() to create an IPv6Addr with its mask set to /128.
  365. func (ipv6 IPv6Addr) ListenStreamArgs() (network, listenArgs string) {
  366. ipv6Mask := big.Int(*ipv6.Mask)
  367. if ipv6Mask.Cmp(ipv6HostMask) != 0 {
  368. return "tcp6", ""
  369. }
  370. return "tcp6", fmt.Sprintf("[%s]:%d", ipv6.NetIP().String(), ipv6.Port)
  371. }
  372. // Maskbits returns the number of network mask bits in a given IPv6Addr. For
  373. // example, the Maskbits() of "2001:0db8::0003/64" would return 64.
  374. func (ipv6 IPv6Addr) Maskbits() int {
  375. maskOnes, _ := ipv6.NetIPNet().Mask.Size()
  376. return maskOnes
  377. }
  378. // MustIPv6Addr is a helper method that must return an IPv6Addr or panic on
  379. // invalid input.
  380. func MustIPv6Addr(addr string) IPv6Addr {
  381. ipv6, err := NewIPv6Addr(addr)
  382. if err != nil {
  383. panic(fmt.Sprintf("Unable to create an IPv6Addr from %+q: %v", addr, err))
  384. }
  385. return ipv6
  386. }
  387. // NetIP returns the address as a net.IP.
  388. func (ipv6 IPv6Addr) NetIP() *net.IP {
  389. return bigIntToNetIPv6(ipv6.Address)
  390. }
  391. // NetIPMask create a new net.IPMask from the IPv6Addr.
  392. func (ipv6 IPv6Addr) NetIPMask() *net.IPMask {
  393. ipv6Mask := make(net.IPMask, IPv6len)
  394. m := big.Int(*ipv6.Mask)
  395. copy(ipv6Mask, m.Bytes())
  396. return &ipv6Mask
  397. }
  398. // Network returns a pointer to the net.IPNet within IPv4Addr receiver.
  399. func (ipv6 IPv6Addr) NetIPNet() *net.IPNet {
  400. ipv6net := &net.IPNet{}
  401. ipv6net.IP = make(net.IP, IPv6len)
  402. copy(ipv6net.IP, *ipv6.NetIP())
  403. ipv6net.Mask = *ipv6.NetIPMask()
  404. return ipv6net
  405. }
  406. // Network returns the network prefix or network address for a given network.
  407. func (ipv6 IPv6Addr) Network() IPAddr {
  408. return IPv6Addr{
  409. Address: IPv6Address(ipv6.NetworkAddress()),
  410. Mask: ipv6.Mask,
  411. }
  412. }
  413. // NetworkAddress returns an IPv6Network of the IPv6Addr's network address.
  414. func (ipv6 IPv6Addr) NetworkAddress() IPv6Network {
  415. addr := new(big.Int)
  416. addr.SetBytes((*ipv6.Address).Bytes())
  417. mask := new(big.Int)
  418. mask.SetBytes(*ipv6.NetIPMask())
  419. netAddr := new(big.Int)
  420. netAddr.And(addr, mask)
  421. return IPv6Network(netAddr)
  422. }
  423. // Octets returns a slice of the 16 octets in an IPv6Addr's Address. The
  424. // order of the bytes is big endian.
  425. func (ipv6 IPv6Addr) Octets() []int {
  426. x := make([]int, IPv6len)
  427. for i, b := range *bigIntToNetIPv6(ipv6.Address) {
  428. x[i] = int(b)
  429. }
  430. return x
  431. }
  432. // String returns a string representation of the IPv6Addr
  433. func (ipv6 IPv6Addr) String() string {
  434. if ipv6.Port != 0 {
  435. return fmt.Sprintf("[%s]:%d", ipv6.NetIP().String(), ipv6.Port)
  436. }
  437. if ipv6.Maskbits() == 128 {
  438. return ipv6.NetIP().String()
  439. }
  440. return fmt.Sprintf("%s/%d", ipv6.NetIP().String(), ipv6.Maskbits())
  441. }
  442. // Type is used as a type switch and returns TypeIPv6
  443. func (IPv6Addr) Type() SockAddrType {
  444. return TypeIPv6
  445. }
  446. // IPv6Attrs returns a list of attributes supported by the IPv6Addr type
  447. func IPv6Attrs() []AttrName {
  448. return ipv6AddrAttrs
  449. }
  450. // IPv6AddrAttr returns a string representation of an attribute for the given
  451. // IPv6Addr.
  452. func IPv6AddrAttr(ipv6 IPv6Addr, selector AttrName) string {
  453. fn, found := ipv6AddrAttrMap[selector]
  454. if !found {
  455. return ""
  456. }
  457. return fn(ipv6)
  458. }
  459. // ipv6AddrInit is called once at init()
  460. func ipv6AddrInit() {
  461. // Sorted for human readability
  462. ipv6AddrAttrs = []AttrName{
  463. "size", // Same position as in IPv6 for output consistency
  464. "uint128",
  465. }
  466. ipv6AddrAttrMap = map[AttrName]func(ipv6 IPv6Addr) string{
  467. "size": func(ipv6 IPv6Addr) string {
  468. netSize := big.NewInt(1)
  469. netSize = netSize.Lsh(netSize, uint(IPv6len*8-ipv6.Maskbits()))
  470. return netSize.Text(10)
  471. },
  472. "uint128": func(ipv6 IPv6Addr) string {
  473. b := big.Int(*ipv6.Address)
  474. return b.Text(10)
  475. },
  476. }
  477. }
  478. // bigIntToNetIPv6 is a helper function that correctly returns a net.IP with the
  479. // correctly padded values.
  480. func bigIntToNetIPv6(bi *big.Int) *net.IP {
  481. x := make(net.IP, IPv6len)
  482. ipv6Bytes := bi.Bytes()
  483. // It's possibe for ipv6Bytes to be less than IPv6len bytes in size. If
  484. // they are different sizes we to pad the size of response.
  485. if len(ipv6Bytes) < IPv6len {
  486. buf := new(bytes.Buffer)
  487. buf.Grow(IPv6len)
  488. for i := len(ipv6Bytes); i < IPv6len; i++ {
  489. if err := binary.Write(buf, binary.BigEndian, byte(0)); err != nil {
  490. panic(fmt.Sprintf("Unable to pad byte %d of input %v: %v", i, bi, err))
  491. }
  492. }
  493. for _, b := range ipv6Bytes {
  494. if err := binary.Write(buf, binary.BigEndian, b); err != nil {
  495. panic(fmt.Sprintf("Unable to preserve endianness of input %v: %v", bi, err))
  496. }
  497. }
  498. ipv6Bytes = buf.Bytes()
  499. }
  500. i := copy(x, ipv6Bytes)
  501. if i != IPv6len {
  502. panic("IPv6 wrong size")
  503. }
  504. return &x
  505. }