github.com/rkt/rkt@v1.30.1-0.20200224141603-171c416fac02/tests/testutils/iputils.go (about)

     1  // Copyright 2015 The rkt Authors
     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  
    15  package testutils
    16  
    17  import (
    18  	"bufio"
    19  	"fmt"
    20  	"net"
    21  	"os"
    22  	"regexp"
    23  	"strconv"
    24  	"strings"
    25  
    26  	"github.com/vishvananda/netlink"
    27  )
    28  
    29  func getDefaultGW(family int) (string, error) {
    30  	routes, err := netlink.RouteList(nil, family)
    31  	if err != nil {
    32  		return "", err
    33  	}
    34  
    35  	for _, route := range routes {
    36  		if route.Src == nil && route.Dst == nil {
    37  			return route.Gw.String(), nil
    38  		}
    39  	}
    40  
    41  	return "", fmt.Errorf("Default route is not set")
    42  }
    43  func GetDefaultGWv4() (string, error) {
    44  	return getDefaultGW(netlink.FAMILY_V4)
    45  }
    46  
    47  func GetDefaultGWv6() (string, error) {
    48  	return getDefaultGW(netlink.FAMILY_V6)
    49  }
    50  
    51  func GetIPs(ifaceWanted string, familyWanted int) ([]string, error) {
    52  	ips := make([]string, 0)
    53  	ifaces, err := net.Interfaces()
    54  	if err != nil {
    55  		return ips, err
    56  	}
    57  	for _, iface := range ifaces {
    58  		if iface.Name != ifaceWanted {
    59  			continue
    60  		}
    61  
    62  		addrs, _ := iface.Addrs()
    63  		for _, addr := range addrs {
    64  			addrString := addr.String()
    65  			ip, _, err := net.ParseCIDR(addrString)
    66  			if err != nil {
    67  				return ips, err
    68  			}
    69  
    70  			if strings.Contains(addrString, ".") && familyWanted == netlink.FAMILY_V4 ||
    71  				strings.Contains(addrString, ":") && familyWanted == netlink.FAMILY_V6 {
    72  				ips = append(ips, ip.String())
    73  			}
    74  		}
    75  	}
    76  	return ips, err
    77  }
    78  
    79  func GetIPsv4(iface string) ([]string, error) {
    80  	return GetIPs(iface, netlink.FAMILY_V4)
    81  }
    82  func GetIPsv6(iface string) ([]string, error) {
    83  	return GetIPs(iface, netlink.FAMILY_V6)
    84  }
    85  
    86  func GetGW(iface string, family int) (string, error) {
    87  	return "", fmt.Errorf("Not implemented")
    88  }
    89  func GetGWv4(iface string) (string, error) {
    90  	return GetGW(iface, netlink.FAMILY_V4)
    91  }
    92  
    93  func GetGWv6(iface string) (string, error) {
    94  	return GetGW(iface, netlink.FAMILY_V4)
    95  }
    96  
    97  func GetNonLoIfaceWithAddrs(ipFamily int) (iface net.Interface, addrs []string, err error) {
    98  	ifaces, err := net.Interfaces()
    99  	if err != nil {
   100  		return iface, nil, err
   101  	}
   102  
   103  	for _, i := range ifaces {
   104  		if i.Flags&net.FlagLoopback == 0 {
   105  			addrs, err = GetIPs(i.Name, ipFamily)
   106  			if err != nil {
   107  				return iface, addrs, fmt.Errorf("Cannot get IP address for interface %v: %v", i.Name, err)
   108  			}
   109  
   110  			if len(addrs) == 0 {
   111  				continue
   112  			}
   113  			iface = i
   114  
   115  			ifaceNameLower := strings.ToLower(i.Name)
   116  			// Don't use rkt's interfaces
   117  			if strings.Contains(ifaceNameLower, "cni") ||
   118  				strings.Contains(ifaceNameLower, "veth") {
   119  				continue
   120  			}
   121  			break
   122  		}
   123  	}
   124  	return iface, addrs, err
   125  }
   126  
   127  func GetNonLoIfaceIPv4() (string, error) {
   128  	iface, ifaceIPsv4, err := GetNonLoIfaceWithAddrs(netlink.FAMILY_V4)
   129  	if err != nil {
   130  		return "", fmt.Errorf("Error while getting non-lo host interface: %v\n", err)
   131  	}
   132  
   133  	if iface.Name == "" || ifaceIPsv4 == nil {
   134  		return "", nil
   135  	}
   136  
   137  	return ifaceIPsv4[0], nil
   138  }
   139  
   140  func CheckTcp4Port(port int) (bool, error) {
   141  	tcpFile, err := os.Open("/proc/net/tcp")
   142  	if err != nil {
   143  		return false, err
   144  	}
   145  	defer tcpFile.Close()
   146  
   147  	re := regexp.MustCompile(`:([A-Z0-9]+) `)
   148  	scanner := bufio.NewScanner(tcpFile)
   149  	for scanner.Scan() {
   150  		line := scanner.Text()
   151  		result := re.FindAllStringSubmatch(line, -1)
   152  		if result != nil {
   153  			i, err := strconv.ParseInt(result[0][1], 16, 32)
   154  			if err != nil {
   155  				return false, err
   156  			}
   157  			if int(i) == port {
   158  				return false, nil
   159  			}
   160  		}
   161  	}
   162  	return true, nil
   163  }
   164  
   165  func GetNextFreePort4() (int, error) {
   166  	return GetNextFreePort4Banned(map[int]struct{}{})
   167  }
   168  
   169  func GetNextFreePort4Banned(bannedPorts map[int]struct{}) (int, error) {
   170  	for port := 49152; port <= 65535; port++ {
   171  		if _, portBanned := bannedPorts[port]; portBanned {
   172  			continue
   173  		}
   174  
   175  		avail, err := CheckTcp4Port(port)
   176  		if err != nil {
   177  			return 0, err
   178  		}
   179  		if avail {
   180  			return port, nil
   181  		}
   182  	}
   183  	return 0, fmt.Errorf("No available ports")
   184  }
   185  
   186  func GetIfaceCount() (int, error) {
   187  	ifaces, err := net.Interfaces()
   188  	if err != nil {
   189  		return 0, err
   190  	}
   191  	return len(ifaces), nil
   192  }