netutils.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package netutils
  15. import (
  16. "encoding/binary"
  17. "fmt"
  18. "math/bits"
  19. "math/rand"
  20. "net"
  21. "sort"
  22. "strconv"
  23. "strings"
  24. "yunion.io/x/pkg/errors"
  25. "yunion.io/x/pkg/util/regutils"
  26. "yunion.io/x/pkg/util/sortutils"
  27. )
  28. const macChars = "0123456789abcdef"
  29. const macCapChars = "ABCDEF"
  30. func FormatMacAddr(macAddr string) string {
  31. buf := make([]byte, 12)
  32. bufIdx := 0
  33. for i := 0; i < len(macAddr) && bufIdx < len(buf); i += 1 {
  34. c := macAddr[i]
  35. if strings.IndexByte(macChars, c) >= 0 {
  36. buf[bufIdx] = c
  37. bufIdx += 1
  38. } else if strings.IndexByte(macCapChars, c) >= 0 {
  39. buf[bufIdx] = c - 'A' + 'a'
  40. bufIdx += 1
  41. }
  42. }
  43. if len(buf) == bufIdx {
  44. return fmt.Sprintf("%c%c:%c%c:%c%c:%c%c:%c%c:%c%c", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
  45. buf[6], buf[7], buf[8], buf[9], buf[10], buf[11])
  46. } else {
  47. return ""
  48. }
  49. }
  50. func IP2Number(ipstr string) (uint32, error) {
  51. parts := strings.Split(ipstr, ".")
  52. if len(parts) == 4 {
  53. bytes := make([]byte, 4)
  54. for i := 0; i < 4; i += 1 {
  55. n, e := strconv.Atoi(strings.TrimSpace(parts[i]))
  56. if e != nil {
  57. return 0, ErrInvalidNumber // fmt.Errorf("invalid number %s", parts[i])
  58. }
  59. if n < 0 || n > 255 {
  60. return 0, ErrOutOfRange
  61. }
  62. bytes[i] = byte(n)
  63. }
  64. return binary.BigEndian.Uint32(bytes), nil
  65. }
  66. return 0, ErrInvalidIPAddr // fmt.Errorf("invalid ip address %s", ipstr)
  67. }
  68. func Number2Bytes(num uint32) []byte {
  69. ret := make([]byte, 4)
  70. binary.BigEndian.PutUint32(ret, num)
  71. return ret
  72. }
  73. func Number2IP(num uint32) string {
  74. bytes := Number2Bytes(num)
  75. return fmt.Sprintf("%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3])
  76. }
  77. type IPV4Addr uint32
  78. func NewIPV4Addr(ipstr string) (IPV4Addr, error) {
  79. var addr IPV4Addr
  80. if len(ipstr) > 0 {
  81. num, err := IP2Number(ipstr)
  82. if err != nil {
  83. return addr, errors.Wrap(err, "IP2Number")
  84. }
  85. addr = IPV4Addr(num)
  86. }
  87. return addr, nil
  88. }
  89. func (addr IPV4Addr) StepDown() IPV4Addr {
  90. naddr := addr - 1
  91. return naddr
  92. }
  93. func (addr IPV4Addr) StepUp() IPV4Addr {
  94. naddr := addr + 1
  95. return naddr
  96. }
  97. func (addr IPV4Addr) NetAddr(maskLen int8) IPV4Addr {
  98. mask := Masklen2Mask(maskLen)
  99. return IPV4Addr(mask & addr)
  100. }
  101. func (addr IPV4Addr) BroadcastAddr(maskLen int8) IPV4Addr {
  102. mask := Masklen2Mask(maskLen)
  103. return IPV4Addr(addr | (0xffffffff - mask))
  104. }
  105. func (addr IPV4Addr) CliAddr(maskLen int8) IPV4Addr {
  106. mask := Masklen2Mask(maskLen)
  107. return IPV4Addr(addr - (addr & mask))
  108. }
  109. func (addr IPV4Addr) String() string {
  110. return Number2IP(uint32(addr))
  111. }
  112. func (addr IPV4Addr) ToBytes() []byte {
  113. return Number2Bytes(uint32(addr))
  114. }
  115. func (addr IPV4Addr) ToIP() net.IP {
  116. return net.IP(addr.ToBytes())
  117. }
  118. func (addr IPV4Addr) ToMac(prefix string) string {
  119. bytes := addr.ToBytes()
  120. return fmt.Sprintf("%s%02x:%02x:%02x:%02x", prefix, bytes[0], bytes[1], bytes[2], bytes[3])
  121. }
  122. func (addr IPV4Addr) IsZero() bool {
  123. return addr == 0
  124. }
  125. type IPV4AddrRange struct {
  126. start IPV4Addr
  127. end IPV4Addr
  128. }
  129. func NewIPV4AddrRange(ip1 IPV4Addr, ip2 IPV4Addr) IPV4AddrRange {
  130. ar := IPV4AddrRange{}
  131. ar.Set(ip1, ip2)
  132. return ar
  133. }
  134. func (ar *IPV4AddrRange) Set(ip1 IPV4Addr, ip2 IPV4Addr) {
  135. if ip1 < ip2 {
  136. ar.start = ip1
  137. ar.end = ip2
  138. } else {
  139. ar.start = ip2
  140. ar.end = ip1
  141. }
  142. }
  143. // n.IP and n.Mask must be ipv4 type. n.Mask must be canonical
  144. func NewIPV4AddrRangeFromIPNet(n *net.IPNet) IPV4AddrRange {
  145. pref, err := NewIPV4Prefix(n.String())
  146. if err != nil {
  147. panic("unexpected IPNet: " + n.String())
  148. }
  149. return pref.ToIPRange()
  150. }
  151. func (ar IPV4AddrRange) Contains(ip IPV4Addr) bool {
  152. return (ip >= ar.start) && (ip <= ar.end)
  153. }
  154. func (ar IPV4AddrRange) ContainsRange(ar2 IPV4AddrRange) bool {
  155. return ar.start <= ar2.start && ar.end >= ar2.end
  156. }
  157. func (ar IPV4AddrRange) Random() IPV4Addr {
  158. return IPV4Addr(uint32(ar.start) + uint32(rand.Intn(int(uint32(ar.end)-uint32(ar.start)))))
  159. }
  160. func (ar IPV4AddrRange) AddressCount() int {
  161. return int(uint32(ar.end) - uint32(ar.start) + 1)
  162. }
  163. func (ar IPV4AddrRange) String() string {
  164. return fmt.Sprintf("%s-%s", ar.start, ar.end)
  165. }
  166. func (ar IPV4AddrRange) StartIp() IPV4Addr {
  167. return ar.start
  168. }
  169. func (ar IPV4AddrRange) EndIp() IPV4Addr {
  170. return ar.end
  171. }
  172. func (ar IPV4AddrRange) Merge(ar2 IPV4AddrRange) (IPV4AddrRange, bool) {
  173. if ar.IsOverlap(ar2) || ar.end+1 == ar2.start || ar2.end+1 == ar.start {
  174. if ar2.start < ar.start {
  175. ar.start = ar2.start
  176. }
  177. if ar2.end > ar.end {
  178. ar.end = ar2.end
  179. }
  180. return ar, true
  181. }
  182. return ar, false
  183. }
  184. func (ar IPV4AddrRange) IsOverlap(ar2 IPV4AddrRange) bool {
  185. if ar.start > ar2.end || ar.end < ar2.start {
  186. return false
  187. } else {
  188. return true
  189. }
  190. }
  191. func (pref IPV4Prefix) ToIPNet() *net.IPNet {
  192. return &net.IPNet{
  193. IP: pref.Address.ToIP(),
  194. Mask: net.CIDRMask(int(pref.MaskLen), 32),
  195. }
  196. }
  197. func (ar IPV4AddrRange) ToIPNets() []*net.IPNet {
  198. r := []*net.IPNet{}
  199. mms := ar.ToPrefixes()
  200. for _, mm := range mms {
  201. r = append(r, mm.ToIPNet())
  202. }
  203. return r
  204. }
  205. /*func (ar IPV4AddrRange) ToIPNets() []*net.IPNet {
  206. r := []*net.IPNet{}
  207. mms := ar.ToMaskMatches()
  208. for _, mm := range mms {
  209. a := mm[0]
  210. m := mm[1]
  211. addr := net.IPv4(byte((a>>24)&0xff), byte((a>>16)&0xff), byte((a>>8)&0xff), byte(a&0xff))
  212. mask := net.IPv4Mask(byte((m>>24)&0xff), byte((m>>16)&0xff), byte((m>>8)&0xff), byte(m&0xff))
  213. r = append(r, &net.IPNet{
  214. IP: addr,
  215. Mask: mask,
  216. })
  217. }
  218. return r
  219. }
  220. func (ar IPV4AddrRange) ToMaskMatches() [][2]uint32 {
  221. r := [][2]uint32{}
  222. s := uint32(ar.start)
  223. e := uint32(ar.end)
  224. if s == e {
  225. r = append(r, [2]uint32{s, ^uint32(0)})
  226. return r
  227. }
  228. sp, ep := uint64(s), uint64(e)
  229. ep = ep + 1
  230. for sp < ep {
  231. b := uint64(1)
  232. for (sp+b) <= ep && (sp&(b-1)) == 0 {
  233. b <<= 1
  234. }
  235. b >>= 1
  236. r = append(r, [2]uint32{uint32(sp), uint32(^(b - 1))})
  237. sp = sp + b
  238. }
  239. return r
  240. }*/
  241. func (ar IPV4AddrRange) ToPrefixes() []IPV4Prefix {
  242. prefixes := make([]IPV4Prefix, 0)
  243. sp := ar.StartIp()
  244. ep := ar.EndIp()
  245. for sp <= ep {
  246. masklen := int8(32)
  247. for masklen > 0 && sp.NetAddr(masklen-1) == sp && sp.BroadcastAddr(masklen-1) <= ep {
  248. masklen--
  249. }
  250. if masklen == 0 {
  251. prefixes = append(prefixes, NewIPV4PrefixFromAddr(sp, 0))
  252. break
  253. }
  254. prefixes = append(prefixes, NewIPV4PrefixFromAddr(sp, masklen))
  255. sp = sp.BroadcastAddr(masklen).StepUp()
  256. }
  257. return prefixes
  258. }
  259. func (ar IPV4AddrRange) Substract(ar2 IPV4AddrRange) ([]IPV4AddrRange, *IPV4AddrRange) {
  260. lefts, overlap, sub := ar.Substract2(ar2)
  261. var subp *IPV4AddrRange
  262. if overlap {
  263. subp = &sub
  264. }
  265. return lefts, subp
  266. }
  267. func (ar IPV4AddrRange) Substract2(ar2 IPV4AddrRange) ([]IPV4AddrRange, bool, IPV4AddrRange) {
  268. lefts := []IPV4AddrRange{}
  269. // no intersection, no substract
  270. if ar.end < ar2.start || ar.start > ar2.end {
  271. lefts = append(lefts, ar)
  272. return lefts, false, IPV4AddrRange{}
  273. }
  274. // ar contains ar2
  275. if ar.ContainsRange(ar2) {
  276. if ar.start == ar2.start && ar.end == ar2.end {
  277. // lefts empty
  278. } else if ar.start < ar2.start && ar.end == ar2.end {
  279. lefts = append(lefts,
  280. NewIPV4AddrRange(ar.start, ar2.start.StepDown()),
  281. )
  282. } else if ar.start == ar2.start && ar.end > ar2.end {
  283. lefts = append(lefts,
  284. NewIPV4AddrRange(ar2.end.StepUp(), ar.end),
  285. )
  286. } else {
  287. lefts = append(lefts,
  288. NewIPV4AddrRange(ar.start, ar2.start.StepDown()),
  289. NewIPV4AddrRange(ar2.end.StepUp(), ar.end),
  290. )
  291. }
  292. return lefts, true, ar2
  293. }
  294. // ar contained by ar2
  295. if ar2.ContainsRange(ar) {
  296. return lefts, true, ar
  297. }
  298. // intersect, ar on the left
  299. if ar.start < ar2.start && ar.end >= ar2.start {
  300. lefts = append(lefts, NewIPV4AddrRange(ar.start, ar2.start.StepDown()))
  301. sub_ := NewIPV4AddrRange(ar2.start, ar.end)
  302. return lefts, true, sub_
  303. }
  304. // intersect, ar on the right
  305. if ar.start <= ar2.end && ar.end > ar2.end {
  306. lefts = append(lefts, NewIPV4AddrRange(ar2.end.StepUp(), ar.end))
  307. sub_ := NewIPV4AddrRange(ar.start, ar2.end)
  308. return lefts, true, sub_
  309. }
  310. // no intersection
  311. return lefts, false, IPV4AddrRange{}
  312. }
  313. func (ar IPV4AddrRange) equals(ar2 IPV4AddrRange) bool {
  314. return ar.start == ar2.start && ar.end == ar2.end
  315. }
  316. func Masklen2Mask(maskLen int8) IPV4Addr {
  317. if maskLen < 0 {
  318. panic("negative masklen")
  319. }
  320. return IPV4Addr(^(uint32(1<<(32-uint8(maskLen))) - 1))
  321. }
  322. type IPV4Prefix struct {
  323. Address IPV4Addr
  324. MaskLen int8
  325. ipRange IPV4AddrRange
  326. }
  327. func (pref *IPV4Prefix) String() string {
  328. if pref.MaskLen == 32 {
  329. return pref.Address.String()
  330. } else {
  331. return fmt.Sprintf("%s/%d", pref.Address.NetAddr(pref.MaskLen).String(), pref.MaskLen)
  332. }
  333. }
  334. func (pref *IPV4Prefix) Equals(pref1 *IPV4Prefix) bool {
  335. if pref1 == nil {
  336. return false
  337. }
  338. return pref.ipRange.equals(pref1.ipRange)
  339. }
  340. func Mask2Len(mask IPV4Addr) int8 {
  341. return int8(bits.LeadingZeros32(^uint32(mask)))
  342. }
  343. func ParsePrefix(prefix string) (IPV4Addr, int8, error) {
  344. slash := strings.IndexByte(prefix, '/')
  345. if slash > 0 {
  346. addr, err := NewIPV4Addr(prefix[:slash])
  347. if err != nil {
  348. return 0, 0, errors.Wrap(err, "NewIPV4Addr")
  349. }
  350. if regutils.MatchIP4Addr(prefix[slash+1:]) {
  351. mask, err := NewIPV4Addr(prefix[slash+1:])
  352. if err != nil {
  353. return 0, 0, errors.Wrap(err, "NewIPV4Addr")
  354. }
  355. maskLen := Mask2Len(mask)
  356. return addr.NetAddr(maskLen), maskLen, nil
  357. } else {
  358. maskLen, err := strconv.Atoi(prefix[slash+1:])
  359. if err != nil {
  360. return 0, 0, ErrInvalidMask // fmt.Errorf("invalid masklen %s", err)
  361. }
  362. if maskLen < 0 || maskLen > 32 {
  363. return 0, 0, ErrOutOfRangeMask // fmt.Errorf("out of range masklen")
  364. }
  365. return addr.NetAddr(int8(maskLen)), int8(maskLen), nil
  366. }
  367. } else {
  368. addr, err := NewIPV4Addr(prefix)
  369. if err != nil {
  370. return 0, 0, errors.Wrap(err, "NewIPV4Addr")
  371. }
  372. return addr, 32, nil
  373. }
  374. }
  375. func NewIPV4Prefix(prefix string) (IPV4Prefix, error) {
  376. addr, maskLen, err := ParsePrefix(prefix)
  377. if err != nil {
  378. return IPV4Prefix{}, errors.Wrap(err, "ParsePrefix")
  379. }
  380. pref := IPV4Prefix{
  381. Address: addr,
  382. MaskLen: maskLen,
  383. }
  384. pref.ipRange = pref.ToIPRange()
  385. return pref, nil
  386. }
  387. func NewIPV4PrefixFromAddr(addr IPV4Addr, masklen int8) IPV4Prefix {
  388. pref := IPV4Prefix{
  389. Address: addr.NetAddr(masklen),
  390. MaskLen: masklen,
  391. }
  392. pref.ipRange = pref.ToIPRange()
  393. return pref
  394. }
  395. func (prefix IPV4Prefix) ToIPRange() IPV4AddrRange {
  396. start := prefix.Address.NetAddr(prefix.MaskLen)
  397. end := prefix.Address.BroadcastAddr(prefix.MaskLen)
  398. return IPV4AddrRange{start: start, end: end}
  399. }
  400. func (prefix IPV4Prefix) Contains(ip IPV4Addr) bool {
  401. return prefix.ipRange.Contains(ip)
  402. }
  403. const (
  404. hostlocalPrefix = "127.0.0.0/8"
  405. linklocalPrefix = "169.254.0.0/16"
  406. multicastPrefix = "224.0.0.0/4"
  407. )
  408. var privateIPRanges []IPV4AddrRange
  409. var customizedPrivateIPRanges []IPV4AddrRange
  410. var hostLocalIPRange IPV4AddrRange
  411. var linkLocalIPRange IPV4AddrRange
  412. var multicastIPRange IPV4AddrRange
  413. func init() {
  414. initPrivateIPRanges()
  415. prefix, _ := NewIPV4Prefix(hostlocalPrefix)
  416. hostLocalIPRange = prefix.ToIPRange()
  417. prefix, _ = NewIPV4Prefix(linklocalPrefix)
  418. linkLocalIPRange = prefix.ToIPRange()
  419. prefix, _ = NewIPV4Prefix(multicastPrefix)
  420. multicastIPRange = prefix.ToIPRange()
  421. }
  422. func initPrivateIPRanges() {
  423. // https://zh.wikipedia.org/wiki/%E4%BF%9D%E7%95%99IP%E5%9C%B0%E5%9D%80
  424. prefs := []string{
  425. "10.0.0.0/8",
  426. "100.64.0.0/10",
  427. "172.16.0.0/12",
  428. "192.0.0.0/24",
  429. "198.18.0.0/15",
  430. "192.168.0.0/16",
  431. }
  432. privateIPRanges = make([]IPV4AddrRange, len(prefs))
  433. for i, prefix := range prefs {
  434. prefix, err := NewIPV4Prefix(prefix)
  435. if err != nil {
  436. continue
  437. }
  438. privateIPRanges[i] = prefix.ToIPRange()
  439. }
  440. }
  441. func SetPrivatePrefixes(pref []string) {
  442. customizedPrivateIPRanges = make([]IPV4AddrRange, 0)
  443. for _, prefix := range pref {
  444. prefix, err := NewIPV4Prefix(prefix)
  445. if err != nil {
  446. continue
  447. }
  448. customizedPrivateIPRanges = append(customizedPrivateIPRanges, prefix.ToIPRange())
  449. }
  450. }
  451. func GetPrivateIPRanges() []IPV4AddrRange {
  452. return append(privateIPRanges, customizedPrivateIPRanges...)
  453. }
  454. func IsPrivate(addr IPV4Addr) bool {
  455. for _, ipRange := range GetPrivateIPRanges() {
  456. if ipRange.Contains(addr) {
  457. return true
  458. }
  459. }
  460. return false
  461. }
  462. func IsHostLocal(addr IPV4Addr) bool {
  463. return hostLocalIPRange.Contains(addr)
  464. }
  465. func IsLinkLocal(addr IPV4Addr) bool {
  466. return linkLocalIPRange.Contains(addr)
  467. }
  468. func IsMulticast(addr IPV4Addr) bool {
  469. return multicastIPRange.Contains(addr)
  470. }
  471. func IsExitAddress(addr IPV4Addr) bool {
  472. return !IsPrivate(addr) && !IsHostLocal(addr) && !IsLinkLocal(addr) && !IsMulticast(addr)
  473. }
  474. func MacUnpackHex(mac string) string {
  475. if regutils.MatchCompactMacAddr(mac) {
  476. parts := make([]string, 6)
  477. for i := 0; i < 12; i += 2 {
  478. parts[i/2] = strings.ToLower(mac[i : i+2])
  479. }
  480. return strings.Join(parts, ":")
  481. }
  482. return ""
  483. }
  484. func GetFreePort() (int, error) {
  485. addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
  486. if err != nil {
  487. return 0, err
  488. }
  489. l, err := net.ListenTCP("tcp", addr)
  490. if err != nil {
  491. return 0, err
  492. }
  493. defer l.Close()
  494. return l.Addr().(*net.TCPAddr).Port, nil
  495. }
  496. var MASKS = []string{"0", "128", "192", "224", "240", "248", "252", "254", "255"}
  497. func Netlen2Mask(netmasklen int) string {
  498. var mask = ""
  499. var segCnt = 0
  500. for netmasklen > 0 {
  501. var m string
  502. if netmasklen > 8 {
  503. m = MASKS[8]
  504. netmasklen -= 8
  505. } else {
  506. m = MASKS[netmasklen]
  507. netmasklen = 0
  508. }
  509. if mask != "" {
  510. mask += "."
  511. }
  512. mask += m
  513. segCnt += 1
  514. }
  515. for i := 0; i < (4 - segCnt); i++ {
  516. if mask != "" {
  517. mask += "."
  518. }
  519. mask += "0"
  520. }
  521. return mask
  522. }
  523. type IPV4AddrRangeList []IPV4AddrRange
  524. func (rl IPV4AddrRangeList) Len() int {
  525. return len(rl)
  526. }
  527. func (rl IPV4AddrRangeList) Swap(i, j int) {
  528. rl[i], rl[j] = rl[j], rl[i]
  529. }
  530. func (rl IPV4AddrRangeList) Less(i, j int) bool {
  531. return rl[i].Compare(rl[j]) == sortutils.Less
  532. }
  533. func (v4range IPV4AddrRange) Compare(r2 IPV4AddrRange) sortutils.CompareResult {
  534. if v4range.start < r2.start {
  535. return sortutils.Less
  536. } else if v4range.start > r2.start {
  537. return sortutils.More
  538. } else {
  539. // start equals, compare ends
  540. if v4range.end > r2.end {
  541. return sortutils.Less
  542. } else if v4range.end < r2.end {
  543. return sortutils.More
  544. } else {
  545. return sortutils.Equal
  546. }
  547. }
  548. }
  549. func (rl IPV4AddrRangeList) Merge() []IPV4AddrRange {
  550. sort.Sort(rl)
  551. ret := make([]IPV4AddrRange, 0, len(rl))
  552. for i := range rl {
  553. if i == 0 {
  554. ret = append(ret, rl[i])
  555. } else {
  556. result, isMerged := ret[len(ret)-1].Merge(rl[i])
  557. if isMerged {
  558. ret[len(ret)-1] = result
  559. } else {
  560. ret = append(ret, rl[i])
  561. }
  562. }
  563. }
  564. return ret
  565. }
  566. func (rl IPV4AddrRangeList) String() string {
  567. strs := make([]string, len(rl))
  568. for i := range rl {
  569. strs[i] = rl[i].String()
  570. }
  571. return strings.Join(strs, ",")
  572. }
  573. var IPV4Zero = IPV4Addr(0)
  574. var IPV4Ones = IPV4Addr(0xffffffff)
  575. var AllIPV4AddrRange = IPV4AddrRange{
  576. start: IPV4Zero,
  577. end: IPV4Ones,
  578. }
  579. func (r IPV4AddrRange) IsAll() bool {
  580. return r.start == IPV4Zero && r.end == IPV4Ones
  581. }
  582. func (rl IPV4AddrRangeList) Substract(addrRange IPV4AddrRange) []IPV4AddrRange {
  583. ret := make([]IPV4AddrRange, 0)
  584. for i := range rl {
  585. lefts, _ := rl[i].Substract(addrRange)
  586. ret = append(ret, lefts...)
  587. }
  588. return ret
  589. }