netutils.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  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 netutils2
  15. import (
  16. "bytes"
  17. "fmt"
  18. "net"
  19. "strconv"
  20. "strings"
  21. "time"
  22. "unicode"
  23. "yunion.io/x/log"
  24. "yunion.io/x/pkg/errors"
  25. "yunion.io/x/pkg/util/netutils"
  26. "yunion.io/x/pkg/util/regutils"
  27. "yunion.io/x/pkg/utils"
  28. "yunion.io/x/onecloud/pkg/cloudcommon/types"
  29. "yunion.io/x/onecloud/pkg/util/procutils"
  30. "yunion.io/x/onecloud/pkg/util/stringutils2"
  31. )
  32. var PSEUDO_VIP = "169.254.169.231"
  33. // var MASKS = []string{"0", "128", "192", "224", "240", "248", "252", "254", "255"}
  34. var PRIVATE_PREFIXES = []string{
  35. "10.0.0.0/8",
  36. "172.16.0.0/12",
  37. "192.168.0.0/16",
  38. }
  39. func GetFreePort() (int, error) {
  40. return netutils.GetFreePort()
  41. }
  42. func IsTcpPortUsed(addr string, port int) bool {
  43. server, err := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port))
  44. if err != nil {
  45. return true
  46. }
  47. server.Close()
  48. return false
  49. }
  50. // MyIP returns source ip used to communicate with udp:114.114.114.114
  51. func MyIP() (ip string, err error) {
  52. return MyIPTo("114.114.114.114")
  53. }
  54. // MyIPTo returns source ip used to communicate with udp:dstIP
  55. func MyIPTo(dstIP string) (ip string, err error) {
  56. conn, err := net.Dial("udp4", dstIP+":53")
  57. if err != nil {
  58. return
  59. }
  60. defer conn.Close()
  61. addr, ok := conn.LocalAddr().(*net.UDPAddr)
  62. if !ok {
  63. err = fmt.Errorf("not a net.UDPAddr: %#v", conn.LocalAddr())
  64. return
  65. }
  66. ip = addr.IP.String()
  67. return
  68. }
  69. func MyIPSmart() (ip string, err error) {
  70. return MyIPSmartTo("114.114.114.114", "2001:4860:4860::8888")
  71. }
  72. func MyIPSmartTo(ipv4Target, ipv6Target string) (ip string, err error) {
  73. // try IPv4 connect
  74. if ipv4Target != "" {
  75. conn, err4 := net.Dial("udp4", ipv4Target+":53")
  76. if err4 == nil {
  77. defer conn.Close()
  78. if addr, ok := conn.LocalAddr().(*net.UDPAddr); ok {
  79. return addr.IP.String(), nil
  80. }
  81. }
  82. }
  83. // try IPv6 connect
  84. if ipv6Target != "" {
  85. conn, err6 := net.Dial("udp6", "["+ipv6Target+"]:53")
  86. if err6 == nil {
  87. defer conn.Close()
  88. if addr, ok := conn.LocalAddr().(*net.UDPAddr); ok {
  89. return addr.IP.String(), nil
  90. }
  91. }
  92. }
  93. // try locallink
  94. return getLocalIP()
  95. }
  96. func getLocalIP() (string, error) {
  97. // get default route
  98. if ip := getIPFromDefaultRoute(); ip != "" {
  99. return ip, nil
  100. }
  101. interfaces, err := net.Interfaces()
  102. if err != nil {
  103. return "", errors.Wrap(err, "get network interfaces")
  104. }
  105. var candidateIPs []string
  106. for _, iface := range interfaces {
  107. if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
  108. continue
  109. }
  110. addrs, err := iface.Addrs()
  111. if err != nil {
  112. continue
  113. }
  114. for _, addr := range addrs {
  115. if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
  116. if ipnet.IP.To4() != nil {
  117. return ipnet.IP.String(), nil
  118. } else if ipnet.IP.To16() != nil && !ipnet.IP.IsLinkLocalUnicast() {
  119. candidateIPs = append(candidateIPs, ipnet.IP.String())
  120. }
  121. }
  122. }
  123. }
  124. if len(candidateIPs) > 0 {
  125. return candidateIPs[0], nil
  126. }
  127. return "", fmt.Errorf("no suitable IP address found")
  128. }
  129. func getIPFromDefaultRoute() string {
  130. if ip := getIPFromDefaultRouteV4(); ip != "" {
  131. return ip
  132. }
  133. if ip := getIPFromDefaultRouteV6(); ip != "" {
  134. return ip
  135. }
  136. return ""
  137. }
  138. func getIPFromDefaultRouteV4() string {
  139. output, err := procutils.NewCommand("ip", "route", "show", "default").Output()
  140. if err != nil {
  141. return ""
  142. }
  143. lines := strings.Split(string(output), "\n")
  144. for _, line := range lines {
  145. if strings.Contains(line, "default") && strings.Contains(line, "src") {
  146. fields := strings.Fields(line)
  147. for i, field := range fields {
  148. if field == "src" && i+1 < len(fields) {
  149. return fields[i+1]
  150. }
  151. }
  152. }
  153. if strings.Contains(line, "default") && strings.Contains(line, "dev") {
  154. fields := strings.Fields(line)
  155. for i, field := range fields {
  156. if field == "dev" && i+1 < len(fields) {
  157. if ip := getIPFromInterface(fields[i+1]); ip != "" {
  158. return ip
  159. }
  160. }
  161. }
  162. }
  163. }
  164. return ""
  165. }
  166. func getIPFromDefaultRouteV6() string {
  167. output, err := procutils.NewCommand("ip", "-6", "route", "show", "default").Output()
  168. if err != nil {
  169. return ""
  170. }
  171. lines := strings.Split(string(output), "\n")
  172. for _, line := range lines {
  173. if strings.Contains(line, "default") && strings.Contains(line, "src") {
  174. fields := strings.Fields(line)
  175. for i, field := range fields {
  176. if field == "src" && i+1 < len(fields) {
  177. return fields[i+1]
  178. }
  179. }
  180. }
  181. if strings.Contains(line, "default") && strings.Contains(line, "dev") {
  182. fields := strings.Fields(line)
  183. for i, field := range fields {
  184. if field == "dev" && i+1 < len(fields) {
  185. if ip := getIPFromInterfaceV6(fields[i+1]); ip != "" {
  186. return ip
  187. }
  188. }
  189. }
  190. }
  191. }
  192. return ""
  193. }
  194. func getIPFromInterface(ifaceName string) string {
  195. iface, err := net.InterfaceByName(ifaceName)
  196. if err != nil {
  197. return ""
  198. }
  199. addrs, err := iface.Addrs()
  200. if err != nil {
  201. return ""
  202. }
  203. for _, addr := range addrs {
  204. if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
  205. if ipv4 := ipnet.IP.To4(); ipv4 != nil {
  206. return ipv4.String()
  207. }
  208. }
  209. }
  210. return ""
  211. }
  212. func getIPFromInterfaceV6(ifaceName string) string {
  213. iface, err := net.InterfaceByName(ifaceName)
  214. if err != nil {
  215. return ""
  216. }
  217. addrs, err := iface.Addrs()
  218. if err != nil {
  219. return ""
  220. }
  221. for _, addr := range addrs {
  222. if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
  223. if ipv6 := ipnet.IP.To16(); ipv6 != nil && ipnet.IP.To4() == nil && !ipnet.IP.IsLinkLocalUnicast() {
  224. return ipv6.String()
  225. }
  226. }
  227. }
  228. return ""
  229. }
  230. func GetPrivatePrefixes(privatePrefixes []string) []string {
  231. if privatePrefixes != nil {
  232. return privatePrefixes
  233. } else {
  234. return PRIVATE_PREFIXES
  235. }
  236. }
  237. func GetMainNicFromDeployApi(nics []*types.SServerNic) (*types.SServerNic, error) {
  238. var mainIp netutils.IPV4Addr
  239. var mainNic *types.SServerNic
  240. for _, n := range nics {
  241. if len(n.Gateway) > 0 {
  242. ip := n.Ip
  243. ipInt, err := netutils.NewIPV4Addr(ip)
  244. if err != nil {
  245. return nil, errors.Wrapf(err, "netutils.NewIPV4Addr %s", ip)
  246. }
  247. if mainIp == 0 {
  248. mainIp = ipInt
  249. mainNic = n
  250. } else if !netutils.IsPrivate(ipInt) && netutils.IsPrivate(mainIp) {
  251. mainIp = ipInt
  252. mainNic = n
  253. }
  254. }
  255. }
  256. if mainNic != nil {
  257. return mainNic, nil
  258. }
  259. for _, n := range nics {
  260. ip := n.Ip
  261. ipInt, err := netutils.NewIPV4Addr(ip)
  262. if err != nil {
  263. return nil, errors.Wrap(err, "netutils.NewIPV4Addr")
  264. }
  265. if mainIp == 0 {
  266. mainIp = ipInt
  267. mainNic = n
  268. } else if !netutils.IsPrivate(ipInt) && netutils.IsPrivate(mainIp) {
  269. mainIp = ipInt
  270. mainNic = n
  271. }
  272. }
  273. if mainNic != nil {
  274. return mainNic, nil
  275. }
  276. return nil, errors.Wrap(errors.ErrInvalidStatus, "no valid nic")
  277. }
  278. func Netlen2Mask(netmasklen int) string {
  279. return netutils.Netlen2Mask(netmasklen)
  280. }
  281. func addRoute(routes []SRouteInfo, net, gw string) []SRouteInfo {
  282. route, _ := ParseRouteInfo([]string{net, gw})
  283. if route != nil {
  284. for _, rt := range routes {
  285. if rt.Prefix.String() == route.Prefix.String() && rt.PrefixLen == route.PrefixLen {
  286. return routes
  287. }
  288. }
  289. // not found
  290. routes = append(routes, *route)
  291. }
  292. return routes
  293. }
  294. func extendRoutes(routes4, routes6 []SRouteInfo, nicRoutes []types.SRoute) ([]SRouteInfo, []SRouteInfo) {
  295. for i := 0; i < len(nicRoutes); i++ {
  296. if regutils.MatchCIDR6(nicRoutes[i][0]) {
  297. routes6 = addRoute(routes6, nicRoutes[i][0], nicRoutes[i][1])
  298. } else {
  299. routes4 = addRoute(routes4, nicRoutes[i][0], nicRoutes[i][1])
  300. }
  301. }
  302. return routes4, routes6
  303. }
  304. func isExitAddress(ip string) bool {
  305. ipv4, err := netutils.NewIPV4Addr(ip)
  306. if err != nil {
  307. log.Errorf("NewIPV4Addr %s fail %s", ip, err)
  308. return false
  309. }
  310. return netutils.IsExitAddress(ipv4)
  311. }
  312. var (
  313. Ip4MetadataServers = []string{
  314. "169.254.169.254",
  315. }
  316. Ip6MetadataServers = []string{
  317. "fd00:ec2::254",
  318. }
  319. )
  320. func SetIp4MetadataServers(ip4s []string) {
  321. if len(ip4s) == 0 {
  322. ip4s = []string{
  323. "169.254.169.254",
  324. }
  325. }
  326. Ip4MetadataServers = ip4s
  327. }
  328. func SetIp6MetadataServers(ip6s []string) {
  329. if len(ip6s) == 0 {
  330. ip6s = []string{
  331. "fd00:ec2::254",
  332. }
  333. }
  334. Ip6MetadataServers = ip6s
  335. }
  336. func AddNicRoutes(routes4 []SRouteInfo, routes6 []SRouteInfo, nicDesc *types.SServerNic, mainIp string, mainIp6 string, nicCnt int) ([]SRouteInfo, []SRouteInfo) {
  337. // always add static routes, even if this is the default NIC
  338. // if mainIp == nicDesc.Ip {
  339. // return routes
  340. // }
  341. if len(nicDesc.Routes) > 0 {
  342. routes4, routes6 = extendRoutes(routes4, routes6, nicDesc.Routes)
  343. } else if len(nicDesc.Gateway) > 0 && !isExitAddress(nicDesc.Ip) &&
  344. nicCnt == 2 && nicDesc.Ip != mainIp && isExitAddress(mainIp) {
  345. for _, pref := range netutils.GetPrivateIPRanges() {
  346. prefs := pref.ToPrefixes()
  347. for _, p := range prefs {
  348. routes4 = addRoute(routes4, p.String(), nicDesc.Gateway)
  349. }
  350. }
  351. }
  352. if len(mainIp) > 0 && nicDesc.Ip == mainIp {
  353. // always add 169.254.169.254 for default NIC
  354. for _, ip := range Ip4MetadataServers {
  355. pref := ip + "/32"
  356. routes4 = addRoute(routes4, pref, "0.0.0.0")
  357. }
  358. }
  359. if len(mainIp6) > 0 && nicDesc.Ip6 == mainIp6 {
  360. for _, ip6 := range Ip6MetadataServers {
  361. pref := ip6 + "/128"
  362. routes6 = addRoute(routes6, pref, "::")
  363. }
  364. }
  365. return routes4, routes6
  366. }
  367. func GetNicDns(nicdesc *types.SServerNic) ([]string, []string) {
  368. dns4list := []string{}
  369. dns6list := []string{}
  370. if len(nicdesc.Dns) > 0 {
  371. for _, dns := range strings.Split(nicdesc.Dns, ",") {
  372. if regutils.MatchIP6Addr(dns) {
  373. dns6list = append(dns6list, dns)
  374. } else {
  375. dns4list = append(dns4list, dns)
  376. }
  377. }
  378. }
  379. return dns4list, dns6list
  380. }
  381. func NetBytes2Mask(mask []byte) string {
  382. if len(mask) != 4 {
  383. return ""
  384. }
  385. var res string
  386. for i := range mask {
  387. res += strconv.Itoa(int(mask[i])) + "."
  388. }
  389. return res[:len(res)-1]
  390. }
  391. type SNetInterface struct {
  392. name string
  393. Addr string
  394. Mask net.IPMask
  395. mac string
  396. Addr6 string
  397. Mask6 net.IPMask
  398. Addr4LinkLocal string
  399. Addr6LinkLocal string
  400. Mtu int
  401. VlanId int
  402. VlanParent *SNetInterface
  403. BondingMode int
  404. BondingSlaves []*SNetInterface
  405. }
  406. var (
  407. SECRET_PREFIX = "169.254"
  408. SECRET_MASK = []byte{255, 255, 255, 255}
  409. SECRET_MASK_LEN = 32
  410. secretInterfaceIndex = 254
  411. )
  412. func NewNetInterface(name string) *SNetInterface {
  413. n := new(SNetInterface)
  414. n.name = name
  415. n.FetchConfig()
  416. return n
  417. }
  418. func NewNetInterfaceWithExpectIp(name string, expectIp string, expectIp6 string, excludeIps []string) *SNetInterface {
  419. n := new(SNetInterface)
  420. n.name = name
  421. n.FetchConfig2(expectIp, expectIp6, excludeIps)
  422. return n
  423. }
  424. func (n *SNetInterface) String() string {
  425. return n.name
  426. }
  427. func (n *SNetInterface) Exist() bool {
  428. _, err := net.InterfaceByName(n.name)
  429. return err == nil
  430. }
  431. func (n *SNetInterface) FetchInter() *net.Interface {
  432. inter, err := net.InterfaceByName(n.name)
  433. if err != nil {
  434. log.Errorf("fetch interface %s error %s", n.name, err)
  435. return nil
  436. }
  437. return inter
  438. }
  439. func (n *SNetInterface) FetchConfig() {
  440. n.FetchConfig2("", "", nil)
  441. }
  442. // FetchConfig2 is used to fetch config with expectIp and expectIp6
  443. func (n *SNetInterface) FetchConfig2(expectIp string, expectIp6 string, excludeIps []string) {
  444. n.Addr = ""
  445. n.Mask = nil
  446. n.mac = ""
  447. // n.Mtu = 0
  448. inter := n.FetchInter()
  449. if inter == nil {
  450. return
  451. }
  452. n.Mtu = inter.MTU
  453. n.mac = inter.HardwareAddr.String()
  454. addrs, err := inter.Addrs()
  455. if err == nil {
  456. for _, addr := range addrs {
  457. if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
  458. if ipnet.IP.To4() != nil {
  459. if strings.HasPrefix(ipnet.IP.To4().String(), SECRET_PREFIX) {
  460. n.Addr4LinkLocal = ipnet.IP.String()
  461. } else if (len(expectIp) > 0 && ipnet.IP.String() == expectIp) || (len(expectIp) == 0 && n.Addr == "") {
  462. if len(excludeIps) > 0 && utils.IsInStringArray(ipnet.IP.String(), excludeIps) {
  463. continue
  464. }
  465. n.Addr = ipnet.IP.String()
  466. n.Mask = ipnet.Mask
  467. }
  468. } else if ipnet.IP.To16() != nil {
  469. if ipnet.IP.IsLinkLocalUnicast() {
  470. n.Addr6LinkLocal = ipnet.IP.String()
  471. } else if (len(expectIp6) > 0 && ipnet.IP.String() == expectIp6) || (len(expectIp6) == 0 && n.Addr6 == "") {
  472. if len(excludeIps) > 0 && utils.IsInStringArray(ipnet.IP.String(), excludeIps) {
  473. continue
  474. }
  475. n.Addr6 = ipnet.IP.String()
  476. n.Mask6 = ipnet.Mask
  477. }
  478. }
  479. }
  480. }
  481. }
  482. // check vlanId
  483. vlanConf := getVlanConfig(n.name)
  484. if vlanConf != nil {
  485. n.VlanId = vlanConf.VlanId
  486. n.VlanParent = NewNetInterface(vlanConf.Parent)
  487. } else {
  488. n.VlanId = 1
  489. n.VlanParent = nil
  490. }
  491. // check bonding
  492. bondingConf := getBondingConfig(n.name)
  493. if bondingConf != nil {
  494. n.BondingMode = bondingConf.Mode
  495. for _, slave := range bondingConf.Slaves {
  496. n.BondingSlaves = append(n.BondingSlaves, NewNetInterface(slave))
  497. }
  498. }
  499. }
  500. func (n *SNetInterface) GetMac() string {
  501. return n.mac
  502. }
  503. func (n *SNetInterface) GetHardwareAddr() net.HardwareAddr {
  504. mac, err := net.ParseMAC(n.mac)
  505. if err != nil {
  506. return nil
  507. }
  508. return mac
  509. }
  510. func (n *SNetInterface) GetAllMacs() []string {
  511. macs := make([]string, 0, len(n.BondingSlaves)+1)
  512. find := false
  513. for _, inf := range n.BondingSlaves {
  514. macs = append(macs, inf.GetMac())
  515. if n.mac == inf.GetMac() {
  516. find = true
  517. }
  518. }
  519. if !find {
  520. macs = append(macs, n.mac)
  521. }
  522. return macs
  523. }
  524. // https://kris.io/2015/10/01/kvm-network-performance-tso-and-gso-turn-it-off/
  525. // General speaking, it is recommended to turn of GSO
  526. // however, this will degrade host network performance
  527. func (n *SNetInterface) SetupGso(on bool) {
  528. onoff := "off"
  529. if on {
  530. onoff = "on"
  531. }
  532. procutils.NewCommand(
  533. "ethtool", "-K", n.name,
  534. "tso", onoff, "gso", onoff,
  535. "ufo", onoff, "lro", onoff,
  536. "gro", onoff, "tx", onoff,
  537. "rx", onoff, "sg", onoff).Run()
  538. }
  539. func (n *SNetInterface) IsSecretInterface() bool {
  540. return n.Addr4LinkLocal != "" && n.Addr == ""
  541. }
  542. func (n *SNetInterface) IsSecretInterface6() bool {
  543. return n.Addr6LinkLocal != "" && n.Addr6 == ""
  544. }
  545. /*func (n *SNetInterface) IsSecretAddress(addr string, mask []byte) bool {
  546. log.Infof("MASK --- %s", mask)
  547. if reflect.DeepEqual(mask, SECRET_MASK) && strings.HasPrefix(addr, SECRET_PREFIX) {
  548. return true
  549. } else {
  550. return false
  551. }
  552. }*/
  553. func GetSecretInterfaceAddress() (string, int) {
  554. addr := fmt.Sprintf("%s.%d.1", SECRET_PREFIX, secretInterfaceIndex)
  555. secretInterfaceIndex -= 1
  556. return addr, SECRET_MASK_LEN
  557. }
  558. func (n *SNetInterface) GetSlaveAddresses() []SNicAddress {
  559. addrs := n.GetAddresses()
  560. var slaves = make([]SNicAddress, 0)
  561. for _, addr := range addrs {
  562. if addr.Addr != n.Addr && addr.Addr != n.Addr6 {
  563. slaves = append(slaves, addr)
  564. }
  565. }
  566. return slaves
  567. }
  568. func FormatMac(macStr string) string {
  569. var ret = []byte{}
  570. for i := 0; i < len(macStr); i++ {
  571. if bytes.IndexByte([]byte("0123456789abcdef"), macStr[i]) >= 0 {
  572. ret = append(ret, macStr[i])
  573. } else if bytes.IndexByte([]byte("ABCDEF"), macStr[i]) >= 0 {
  574. ret = append(ret, byte(unicode.ToLower(rune(macStr[i]))))
  575. }
  576. }
  577. if len(ret) == 12 {
  578. var res string
  579. for i := 0; i < 12; i += 2 {
  580. res += string(ret[i:i+2]) + ":"
  581. }
  582. return res[:len(res)-1]
  583. }
  584. return ""
  585. }
  586. func MacEqual(mac1, mac2 string) bool {
  587. mac1 = FormatMac(mac1)
  588. mac2 = FormatMac(mac2)
  589. if len(mac1) > 0 && len(mac2) > 0 && mac1 == mac2 {
  590. return true
  591. }
  592. return false
  593. }
  594. func netmask2len(mask string) int {
  595. masks := []string{"0", "128", "192", "224", "240", "248", "252", "254", "255"}
  596. for i := 0; i < len(masks); i++ {
  597. if masks[i] == mask {
  598. return i
  599. }
  600. }
  601. return -1
  602. }
  603. func Netmask2Len(mask string) int {
  604. data := strings.Split(mask, ".")
  605. mlen := 0
  606. for _, d := range data {
  607. if d != "0" {
  608. nle := netmask2len(d)
  609. log.Errorln(d)
  610. if nle < 0 {
  611. return -1
  612. }
  613. mlen += nle
  614. }
  615. }
  616. return mlen
  617. }
  618. func PrefixSplit(pref string) (string, int, error) {
  619. slash := strings.Index(pref, "/")
  620. var intMask int
  621. var err error
  622. if slash > 0 {
  623. ip := pref[:slash]
  624. mask := pref[slash+1:]
  625. if regutils.MatchIPAddr(mask) {
  626. intMask = Netmask2Len(mask)
  627. } else {
  628. intMask, err = strconv.Atoi(mask)
  629. if err != nil {
  630. return "", 0, err
  631. }
  632. }
  633. return ip, intMask, nil
  634. } else {
  635. return pref, 32, nil
  636. }
  637. }
  638. func TestTcpPort(ip string, port int, timeoutSecs int, tries int) error {
  639. if timeoutSecs <= 0 {
  640. timeoutSecs = 3
  641. }
  642. if tries <= 0 {
  643. tries = 3
  644. }
  645. address := net.JoinHostPort(ip, fmt.Sprintf("%d", port))
  646. // 3 second timeout
  647. errs := make([]error, 0)
  648. for i := 0; i < tries; i++ {
  649. conn, err := net.DialTimeout("tcp", address, time.Duration(timeoutSecs)*time.Second)
  650. if err != nil {
  651. errs = append(errs, err)
  652. } else {
  653. if conn != nil {
  654. _ = conn.Close()
  655. return nil
  656. } else {
  657. errs = append(errs, errors.Wrap(errors.ErrEmpty, "nil conn"))
  658. }
  659. }
  660. time.Sleep(10 * time.Millisecond)
  661. }
  662. return errors.NewAggregate(errs)
  663. }
  664. func IP2SolicitMcastIP(ip6 net.IP) net.IP {
  665. // Solicited-Node Multicast Address, FF02::1:FF00:0/104
  666. return net.IP{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, ip6[13], ip6[14], ip6[15]}
  667. }
  668. func IP2SolicitMcastMac(ip6 net.IP) net.HardwareAddr {
  669. // Solicited-Node Multicast Address, 33:33:ff:00:00:00
  670. return net.HardwareAddr{0x33, 0x33, 0xff, ip6[13], ip6[14], ip6[15]}
  671. }
  672. func SplitV46Addr(addrsStr string) ([]string, []string) {
  673. servers4 := stringutils2.NewSortedStrings(nil)
  674. servers6 := stringutils2.NewSortedStrings(nil)
  675. for _, ntp := range strings.Split(addrsStr, ",") {
  676. if regutils.MatchIP4Addr(ntp) {
  677. servers4 = servers4.Append(ntp)
  678. } else if regutils.MatchIP6Addr(ntp) {
  679. servers6 = servers6.Append(ntp)
  680. } else if regutils.MatchDomainName(ntp) {
  681. ntpAddrs, _ := net.LookupHost(ntp)
  682. for _, ntpAddr := range ntpAddrs {
  683. if regutils.MatchIP4Addr(ntpAddr) {
  684. servers4 = servers4.Append(ntpAddr)
  685. } else if regutils.MatchIP6Addr(ntpAddr) {
  686. servers6 = servers6.Append(ntpAddr)
  687. }
  688. }
  689. }
  690. }
  691. return servers4, servers6
  692. }
  693. func SplitV46Addr2IP(addrsStr string) ([]net.IP, []net.IP) {
  694. addrs4, addrs6 := SplitV46Addr(addrsStr)
  695. ip4s := make([]net.IP, len(addrs4))
  696. ip6s := make([]net.IP, len(addrs6))
  697. for i := range addrs4 {
  698. ip4s[i] = net.ParseIP(addrs4[i])
  699. }
  700. for i := range addrs6 {
  701. ip6s[i] = net.ParseIP(addrs6[i])
  702. }
  703. return ip4s, ip6s
  704. }