netaddr.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. /*
  2. * This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  5. */
  6. // General functions for network address parsing and manipulation
  7. package netaddr
  8. import (
  9. "bytes"
  10. "fmt"
  11. "io"
  12. "math"
  13. "net"
  14. "strconv"
  15. )
  16. func byteOp(u, v []byte, f func(byte, byte) byte) []byte {
  17. w := make([]byte, len(u))
  18. for i := 0; i < len(u); i++ {
  19. w[i] = f(u[i], v[i])
  20. }
  21. return w
  22. }
  23. func byteOr(u, v []byte) []byte {
  24. return byteOp(u, v, func(ui, vi byte) byte {
  25. return ui | vi
  26. })
  27. }
  28. func byteXor(u, v []byte) []byte {
  29. return byteOp(u, v, func(ui, vi byte) byte {
  30. return ui ^ vi
  31. })
  32. }
  33. func applyMask(address, mask []byte) {
  34. for i := range address {
  35. address[i] &= mask[i]
  36. }
  37. return
  38. }
  39. var rfc1918 = []*NetAddr{
  40. &NetAddr{[]byte{10, 0, 0, 0}, uint8(8)},
  41. &NetAddr{[]byte{172, 16, 0, 0}, uint8(12)},
  42. &NetAddr{[]byte{192, 168, 0, 0}, uint8(16)},
  43. }
  44. func NewNetAddr(a []byte, l int) *NetAddr {
  45. addr := make([]byte, len(a))
  46. copy(addr, a)
  47. return &NetAddr{
  48. address: addr,
  49. length: uint8(clamp(l, 0, len(a)*8)),
  50. }
  51. }
  52. /*
  53. NetAddr stores an address of S bytes together with a prefix
  54. length L.
  55. A prefix length L < S induces a partition on the entire
  56. address space, containing 2^L equivalence classes, each with
  57. 2^(S-L) elements. The canonical element for a given
  58. equivalence class is always the least (or lowest) address.
  59. However, as any element of the equivalence class is
  60. representative of the rest, we allow the host bits to vary,
  61. regardless of the prefix length. As this is not proper CIDR,
  62. it is useful to think of this construction as an address
  63. with context.
  64. */
  65. type NetAddr struct {
  66. address []byte
  67. length uint8
  68. }
  69. /* Address returns an address without context (length). */
  70. func (na *NetAddr) Address() []byte {
  71. return na.address
  72. }
  73. /* Length returns the prefix length. */
  74. func (na *NetAddr) Length() int {
  75. return int(na.length)
  76. }
  77. /* AddressSize returns the size of the address in bytes. */
  78. func (na *NetAddr) AddressSize() int {
  79. return len(na.Address())
  80. }
  81. /*
  82. SetLength changes the length.
  83. The NetAddr pointer is returned for convenience.
  84. */
  85. func (na *NetAddr) SetLength(length int) *NetAddr {
  86. na.length = uint8(min(length, na.AddressSize()*8))
  87. return na
  88. }
  89. /*
  90. FirstAddress sets the address to the first (lowest)
  91. address in the prefix.
  92. The NetAddr pointer is returned for convenience.
  93. */
  94. func (na *NetAddr) FirstAddress() *NetAddr {
  95. bitSize := na.AddressSize() * 8
  96. mask := net.CIDRMask(na.Length(), bitSize)
  97. applyMask(na.address, mask)
  98. return na
  99. }
  100. /*
  101. LastAddress sets the address to the last (highest) address
  102. in the prefix.
  103. The NetAddr pointer is returned for convenience.
  104. */
  105. func (na *NetAddr) LastAddress() *NetAddr {
  106. bitSize := na.AddressSize() * 8
  107. mask := net.CIDRMask(na.Length(), bitSize)
  108. allOnes := net.CIDRMask(bitSize, bitSize)
  109. invMask := byteXor(mask, allOnes)
  110. na.address = byteOr(na.FirstAddress().address, invMask)
  111. return na
  112. }
  113. /*
  114. Clone returns a pointer to a new (deep) copy of the
  115. provided NetAddr.
  116. */
  117. func (na *NetAddr) Clone() *NetAddr {
  118. next := &NetAddr{
  119. address: make([]byte, len(na.address)),
  120. length: na.length,
  121. }
  122. copy(next.address, na.address)
  123. return next
  124. }
  125. /*
  126. Mask returns a dotted decimal subnet mask corresponding
  127. to the given NetAddr prefix length.
  128. */
  129. func (na *NetAddr) Mask() []byte {
  130. onesToMask :=
  131. [9]byte{0, 128, 192, 224, 240, 248, 252, 254, 255}
  132. ones := na.Length()
  133. mask := make([]byte, na.AddressSize())
  134. for i := range mask {
  135. olen := min(8, ones)
  136. ones -= olen
  137. mask[i] = onesToMask[int(olen)]
  138. }
  139. return mask
  140. }
  141. /*
  142. Integer returns an aton-style integer representation for the
  143. address of the given NetAddr.
  144. */
  145. func (na *NetAddr) Integer() (dec uint64) {
  146. for _, b := range na.address {
  147. dec <<= 8
  148. dec += uint64(b)
  149. }
  150. return
  151. }
  152. /*
  153. String returns an appopriate string representation for
  154. the given NetAddr.
  155. */
  156. func (na *NetAddr) String() string {
  157. addr := net.IP(na.address).String()
  158. length := fmt.Sprintf("%d", na.length)
  159. return addr + "/" + length
  160. }
  161. /*
  162. IsRFC1918 returns true when the given NetAddr is a subset of
  163. an RFC1918 reserved range.
  164. */
  165. func (na *NetAddr) IsRFC1918() bool {
  166. for _, e := range rfc1918 {
  167. if na.IsSubset(e) {
  168. return true
  169. }
  170. }
  171. return false
  172. }
  173. /*
  174. IsEqual returns true when the given NetAddrs have the same
  175. address and length.
  176. */
  177. func (na1 *NetAddr) IsEqual(na2 *NetAddr) bool {
  178. return NetAddrIsEqual(na1, na2)
  179. }
  180. /*
  181. Contains returns true when na1 contains, or is equal to,
  182. na2.
  183. */
  184. func (na1 *NetAddr) Contains(na2 *NetAddr) bool {
  185. return NetAddrContains(na1, na2)
  186. }
  187. /*
  188. IsSubset returns true when na2 contains, or is equal to,
  189. na1.
  190. */
  191. func (na1 *NetAddr) IsSubset(na2 *NetAddr) bool {
  192. return NetAddrIsSubset(na1, na2)
  193. }
  194. /*
  195. Overlaps returns true when na1 Contains na2 or na2 Contains
  196. na1.
  197. */
  198. func (na1 *NetAddr) Overlaps(na2 *NetAddr) bool {
  199. return NetAddrOverlaps(na1, na2)
  200. }
  201. /* Test against sheared isometry on byte prefixes. */
  202. func octetLessThan(o1, m1, o2, m2 byte) bool {
  203. /* We seek an isometry from a binary trie embedded in R²
  204. * to the integral number line, with ones bits branching to
  205. * the right and zeros bits branching to the left. When
  206. * considering only the ones bits of an n-bit binary
  207. * number, the usual decimal encoding suffices, as each ith
  208. * bit, for 0 <= i <= n-1, shifts a point at the origin to
  209. * the right by 2^i. However, the zeros bits have no
  210. * effect, in this sense, as leading zeros do not
  211. * contribute to the integer value, resulting in many
  212. * binary strings occupying the same point. This mapping is
  213. * well-formed and surjective (every integer has a binary
  214. * encoding), but it is not injective.
  215. *
  216. * -> R 0 00 000 0000
  217. * -> 0001
  218. * -> 001 0010
  219. * -> 0011
  220. * -> 01 010 0100
  221. * -> 0101
  222. * -> 011 0110
  223. * -> 0111
  224. * -> 1 10 100 1000
  225. * -> 1001
  226. * -> 101 1010
  227. * -> 1011
  228. * -> 11 110 1100
  229. * -> 1101
  230. * -> 111 1110
  231. * -> 1111
  232. *
  233. * Instead, by allowing each zero bit to provide a negative
  234. * contribution, we ensure that every path (binary string)
  235. * maps to a unique point on the integral line. To see that
  236. * this is an isometry, project the nodes of a binary trie
  237. * embedded in R², with branch width w = 2^(n-j-1) at rank
  238. * j and arbitrary branch height h, onto the integral line.
  239. *
  240. * Here, we express the above isometry by simply
  241. * subtracting the contributions of the place values of the
  242. * zeros bits, which we obtain by ones complement (XOR).
  243. * Masking ensures we map only the prefix.
  244. *
  245. * Finally, we note that projecting the usual geometry of a
  246. * binary trie onto the integral line places each ancestor
  247. * at the midpoint of its descendants. This creates a
  248. * disagreement between the partial and total orders, which
  249. * makes it difficult to recover the original partial order
  250. * generated by the trie.
  251. *
  252. * -> 0000
  253. * -> 000
  254. * -> 0001
  255. * -> 00
  256. * -> 0010
  257. * -> 001
  258. * -> 0011
  259. * -> 0
  260. * -> 0100
  261. * -> 010
  262. * -> 0101
  263. * -> 01
  264. * -> 0110
  265. * -> 011
  266. * -> 0111
  267. * 0/0
  268. * -> 1000
  269. * -> 100
  270. * -> 1001
  271. * -> 10
  272. * -> 1010
  273. * -> 101
  274. * -> 1011
  275. * -> 1
  276. * -> 1100
  277. * -> 110
  278. * -> 1101
  279. * -> 11
  280. * -> 1110
  281. * -> 111
  282. * -> 1111
  283. *
  284. * Instead, we require that the total order < given by the
  285. * proposed isometry have the property that it always agree
  286. * with the partial order ≪ given by the binary trie. That
  287. * is, given nodes a, b of a binary trie, if a ≪ b, then a
  288. * < b. Note that the converse does not hold, nor would it
  289. * be useful if it did. To accomplish this, we effectively
  290. * apply a horizontal shear to the right on the binary trie
  291. * such that the root of each subtree falls to the right of
  292. * its descendants.
  293. *
  294. * -> 0000
  295. * -> 0001
  296. * -> 000
  297. * -> 0010
  298. * -> 0011
  299. * -> 001
  300. * -> 00
  301. * -> 0100
  302. * -> 0101
  303. * -> 010
  304. * -> 0110
  305. * -> 0111
  306. * -> 011
  307. * -> 01
  308. * -> 0
  309. * -> 1000
  310. * -> 1001
  311. * -> 100
  312. * -> 1010
  313. * -> 1011
  314. * -> 101
  315. * -> 10
  316. * -> 1100
  317. * -> 1101
  318. * -> 110
  319. * -> 1110
  320. * -> 1111
  321. * -> 111
  322. * -> 11
  323. * -> 1
  324. * 0/0
  325. *
  326. * In the unsheared isometry, the nodes we wish to reorder
  327. * are specifically those which precede their descendants--
  328. * that is, whenever a < b and b ≪ a, we would like to
  329. * move a to the right of b so that b < a, thereby agreeing
  330. * with the partial order. Since b ≪ a, it is the case
  331. * that a represents a shorter prefix than b. Furthermore,
  332. * since b is a descendant of a, b's prefix is guaranteed
  333. * to share all of the bits of a. Conversely, if a and b
  334. * share a prefix, then that prefix represents the most
  335. * recent shared ancestor (least upper bound). And if the
  336. * prefix shared by a and b is a's prefix, then it must be
  337. * the case that a's prefix is shorter, and b is a
  338. * descendant of a. Thus, b ≪ a.
  339. *
  340. * Therefore, we conclude that a must be reordered
  341. * precisely when a < b and b shares a's prefix. Hence our
  342. * assertion `f1 < f2 && o1 != o2&m1`. To reorder, we
  343. * simply place prefixes with longer masks before shorter
  344. * ones, as given by `m1 > m2`.
  345. **/
  346. f1 := int(o1&m1) - int((o1^byte(255))&m1)
  347. f2 := int(o2&m2) - int((o2^byte(255))&m2)
  348. return f1 < f2 && o1 != o2&m1 || m1 > m2
  349. }
  350. /*
  351. LessThan imposes a total order < on NetAddrs, returning
  352. true precisely when na1 < na2.
  353. */
  354. func LessThan(na1 *NetAddr, na2 *NetAddr) (less bool) {
  355. if na1.AddressSize() != na2.AddressSize() {
  356. return
  357. }
  358. mask1 := na1.Mask()
  359. mask2 := na2.Mask()
  360. for i := 0; i < na1.AddressSize(); i++ {
  361. if octetLessThan(
  362. na1.address[i], mask1[i],
  363. na2.address[i], mask2[i],
  364. ) {
  365. less = true
  366. break
  367. }
  368. if na1.address[i] == na2.address[i] &&
  369. mask1[i] == mask2[i] {
  370. continue
  371. }
  372. break
  373. }
  374. return
  375. }
  376. /*
  377. FirstAddress is a non-mutating version of the FirstAddress
  378. method.
  379. */
  380. func FirstAddress(na *NetAddr) *NetAddr {
  381. return na.Clone().FirstAddress()
  382. }
  383. /*
  384. LastAddress is a non-mutating version of the LastAddress
  385. method.
  386. */
  387. func LastAddress(na *NetAddr) *NetAddr {
  388. return na.Clone().LastAddress()
  389. }
  390. /*
  391. NetAddrIsEqual is a function implementation of the IsEqual
  392. method.
  393. */
  394. func NetAddrIsEqual(na1, na2 *NetAddr) bool {
  395. return na1.length == na2.length &&
  396. bytes.Equal(na1.address, na2.address)
  397. }
  398. /*
  399. NetAddrContains is a function implementation of the
  400. Contains method.
  401. */
  402. func NetAddrContains(na1, na2 *NetAddr) bool {
  403. tmp := na2.Clone().SetLength(na1.Length())
  404. return na1.length <= na2.length &&
  405. FirstAddress(na1).IsEqual(FirstAddress(tmp))
  406. }
  407. /*
  408. NetAddrIsSubset is a function implementation of the IsSubset
  409. method.
  410. */
  411. func NetAddrIsSubset(na1, na2 *NetAddr) bool {
  412. return na2.Contains(na1)
  413. }
  414. /*
  415. NetAddrOverlaps is a function implementation of the Overlaps
  416. method.
  417. */
  418. func NetAddrOverlaps(na1, na2 *NetAddr) bool {
  419. return na1.Contains(na2) || na2.Contains(na1)
  420. }
  421. /*
  422. Contiguous tests whether na1 and na2 can be summarized by
  423. a single prefix containing only na1 and na2.
  424. */
  425. func Contiguous(na1, na2 *NetAddr) bool {
  426. if na1.AddressSize() != na2.AddressSize() ||
  427. na1.Length() != na2.Length() ||
  428. Join(na1, na2).Length() != na1.Length()-1 {
  429. return false
  430. }
  431. return true
  432. }
  433. /*
  434. LeftAdjacent tests whether na1 is left-adjacent to na2.
  435. LeftAdjacent returns true if, and only if, the first address
  436. in the prefix of na2 is immediately preceded by the last
  437. address in the prefix of na1. If na1 and na2 are contiguous,
  438. then either na1 is adjacent to na2 or na2 is adjacent to
  439. na1. However, neither converse holds, in general.
  440. */
  441. func LeftAdjacent(na1, na2 *NetAddr) bool {
  442. if na1.AddressSize() != na2.AddressSize() {
  443. return false
  444. }
  445. b1 := na1.LastAddress().Integer()
  446. a2 := na2.FirstAddress().Integer()
  447. return b1+1 == a2
  448. }
  449. /*
  450. Join returns the smallest summary containing both na1 and
  451. na2.
  452. */
  453. func Join(na1, na2 *NetAddr) *NetAddr {
  454. minLen := min(na1.Length(), na2.Length())
  455. addrSize := min(na1.AddressSize(), na2.AddressSize())
  456. bitSize := addrSize * 8
  457. fa1 := na1.FirstAddress()
  458. fa2 := na2.FirstAddress()
  459. var bits int
  460. for i := 0; i < addrSize; i++ {
  461. xor := fa1.address[i] ^ fa2.address[i]
  462. if xor != 0 {
  463. bits += int(math.Trunc(1.0 + math.Log2(float64(xor))))
  464. bits += bitSize - 8*(i+1)
  465. break
  466. }
  467. }
  468. return fa1.
  469. Clone().
  470. SetLength(min(minLen, bitSize-bits)).
  471. FirstAddress()
  472. }
  473. /*
  474. Split returns the two halves of a given NetAddr. The input
  475. is unchanged.
  476. If the given NetAddr represents a single address, then
  477. Split returns the input for both the left and right outputs.
  478. */
  479. func Split(na *NetAddr) (*NetAddr, *NetAddr) {
  480. if na.Length() == na.AddressSize()*8 {
  481. return na, na
  482. }
  483. nextLen := na.Length() + 1
  484. lower :=
  485. na.
  486. Clone().
  487. FirstAddress().
  488. SetLength(nextLen)
  489. upper :=
  490. na.
  491. Clone().
  492. LastAddress().
  493. SetLength(nextLen).
  494. FirstAddress()
  495. return lower, upper
  496. }
  497. func parseTruncatedIPv4(s string) (na *NetAddr, err error) {
  498. na = &NetAddr{address: make([]byte, 4)}
  499. r := bytes.NewBufferString(s)
  500. buf := new(bytes.Buffer)
  501. i := 0
  502. onLen := false
  503. for i < 4 {
  504. var b byte
  505. b, err = r.ReadByte()
  506. switch {
  507. case err == io.EOF:
  508. na.length = byte(8*i - 8)
  509. if onLen {
  510. var o int
  511. o, err = strconv.Atoi(buf.String())
  512. if err != nil {
  513. return
  514. }
  515. if o < 0 || 32 < o {
  516. err = fmt.Errorf("length out of range: %v", o)
  517. return
  518. }
  519. na.length = byte(o)
  520. return
  521. }
  522. err = nil
  523. return
  524. case err != nil:
  525. return
  526. case '0' <= b && b <= '9':
  527. buf.WriteByte(b)
  528. continue
  529. case b == '.' || b == '/':
  530. var o int
  531. o, err = strconv.Atoi(buf.String())
  532. if err != nil {
  533. return
  534. }
  535. if o < 0 || 255 < o {
  536. err = fmt.Errorf("octet out of range: %v", o)
  537. return
  538. }
  539. na.address[i] = byte(o)
  540. i++
  541. buf = new(bytes.Buffer)
  542. if b == '/' {
  543. onLen = true
  544. }
  545. }
  546. }
  547. err = fmt.Errorf("input is longer than expected")
  548. return
  549. }
  550. /*
  551. IP parses a string as IPv4 or IPv6, returning a NetAddr or
  552. an error.
  553. Address strings without lengths are always interpreted as
  554. single addresses with maximal length.
  555. Sample inputs:
  556. - 192.0.2.9/24
  557. - 2001:DB8::/32
  558. - 192.0.2.1
  559. - 2001:db8::
  560. - 192.0.2/24
  561. */
  562. func IP(s string) (na *NetAddr, err error) {
  563. var ip net.IP
  564. var ipNet *net.IPNet
  565. ip, ipNet, err = net.ParseCIDR(s)
  566. switch err.(type) {
  567. case nil:
  568. case *net.ParseError:
  569. ip = net.ParseIP(s)
  570. if ip == nil {
  571. na, err = parseTruncatedIPv4(s)
  572. if err != nil {
  573. err = fmt.Errorf("invalid ip address %v: %v", s, err)
  574. }
  575. return
  576. }
  577. if test := ip.To4(); test != nil {
  578. ipNet = &net.IPNet{
  579. IP: ip,
  580. Mask: net.IPMask([]byte{255, 255, 255, 255}),
  581. }
  582. } else if test := ip.To16(); test != nil {
  583. ipNet = &net.IPNet{
  584. IP: ip,
  585. Mask: net.IPMask(
  586. []byte{
  587. 0xff, 0xff, 0xff, 0xff,
  588. 0xff, 0xff, 0xff, 0xff,
  589. 0xff, 0xff, 0xff, 0xff,
  590. 0xff, 0xff, 0xff, 0xff,
  591. },
  592. ),
  593. }
  594. }
  595. err = nil
  596. default:
  597. return
  598. }
  599. var length, _ int = net.IPMask.Size(ipNet.Mask)
  600. var address []byte = ip.To4()
  601. if address == nil {
  602. address = ip.To16()
  603. }
  604. if address == nil {
  605. panic(fmt.Sprintf("unexpected failure parsing '%s'\n", s))
  606. }
  607. na = &NetAddr{address, uint8(length)}
  608. return
  609. }