pkg.re/essentialkaos/ek.10@v12.41.0+incompatible/netutil/netutil.go (about)

     1  //go:build linux || darwin
     2  // +build linux darwin
     3  
     4  // Package netutil provides methods for working with network
     5  package netutil
     6  
     7  // ////////////////////////////////////////////////////////////////////////////////// //
     8  //                                                                                    //
     9  //                         Copyright (c) 2022 ESSENTIAL KAOS                          //
    10  //      Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0>     //
    11  //                                                                                    //
    12  // ////////////////////////////////////////////////////////////////////////////////// //
    13  
    14  import (
    15  	"net"
    16  	"strings"
    17  )
    18  
    19  // ////////////////////////////////////////////////////////////////////////////////// //
    20  
    21  // GetIP returns main IPv4 address
    22  func GetIP() string {
    23  	return getMainIP(false)
    24  }
    25  
    26  // GetIP6 returns main IPv6 address
    27  func GetIP6() string {
    28  	return getMainIP(true)
    29  }
    30  
    31  // ////////////////////////////////////////////////////////////////////////////////// //
    32  
    33  func getMainIP(ipv6 bool) string {
    34  	interfaces, err := net.Interfaces()
    35  
    36  	if err != nil {
    37  		return ""
    38  	}
    39  
    40  	defaultInterface := getDefaultRouteInterface()
    41  
    42  	for i := len(interfaces) - 1; i >= 0; i-- {
    43  		if defaultInterface != "" && interfaces[i].Name != defaultInterface {
    44  			continue
    45  		}
    46  
    47  		// Ignore TUN/TAP interfaces
    48  		switch {
    49  		case strings.Contains(interfaces[i].Name, "tun"),
    50  			strings.Contains(interfaces[i].Name, "tap"):
    51  			continue
    52  		}
    53  
    54  		addr, err := interfaces[i].Addrs()
    55  
    56  		if err != nil || len(addr) == 0 {
    57  			continue
    58  		}
    59  
    60  		for _, a := range addr {
    61  			ipnet, ok := a.(*net.IPNet)
    62  
    63  			if ipnet.IP.IsLoopback() {
    64  				continue
    65  			}
    66  
    67  			if ok && strings.Contains(ipnet.IP.String(), "::") == ipv6 {
    68  				return ipnet.IP.String()
    69  			}
    70  		}
    71  	}
    72  
    73  	return ""
    74  }