github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/goip/util.go (about)

     1  package goip
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"io/ioutil"
     7  	"net"
     8  	"net/http"
     9  	"strconv"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  // External returns  the external IP address.
    15  func External() string {
    16  	ctx, cncl := context.WithTimeout(context.Background(), time.Second*10)
    17  	defer cncl()
    18  
    19  	addr := "http://myexternalip.com/raw"
    20  	resp, err := http.NewRequestWithContext(ctx, http.MethodGet, addr, nil)
    21  	if err != nil || resp.Body == nil {
    22  		return ""
    23  	}
    24  
    25  	defer resp.Body.Close()
    26  	content, _ := ioutil.ReadAll(resp.Body)
    27  	buf := new(bytes.Buffer)
    28  	_, _ = buf.ReadFrom(resp.Body)
    29  
    30  	return strings.ReplaceAll(string(content), "\n", "")
    31  }
    32  
    33  // ToDecimal converts IP to Decimal
    34  // https://www.ultratools.com/tools/decimalCalc
    35  // nolint gomnd
    36  func ToDecimal(ipnr net.IP) int64 {
    37  	bits := strings.Split(ipnr.String(), ".")
    38  
    39  	b0, _ := strconv.Atoi(bits[0])
    40  	b1, _ := strconv.Atoi(bits[1])
    41  	b2, _ := strconv.Atoi(bits[2])
    42  	b3, _ := strconv.Atoi(bits[3])
    43  
    44  	var sum int64
    45  
    46  	sum += int64(b0) << 24
    47  	sum += int64(b1) << 16
    48  	sum += int64(b2) << 8
    49  	sum += int64(b3)
    50  
    51  	return sum
    52  }
    53  
    54  // FromDecimal converts decimal number(base 10) to IPv4 address.
    55  // https://www.browserling.com/tools/dec-to-ip
    56  func FromDecimal(ipnr int64) net.IP {
    57  	var bs [4]byte
    58  
    59  	bs[0] = byte(ipnr & 0xFF)
    60  	bs[1] = byte((ipnr >> 8) & 0xFF)
    61  	bs[2] = byte((ipnr >> 16) & 0xFF)
    62  	bs[3] = byte((ipnr >> 24) & 0xFF)
    63  
    64  	return net.IPv4(bs[3], bs[2], bs[1], bs[0])
    65  }
    66  
    67  // Betweens ...
    68  func Betweens(test, from, to net.IP) bool {
    69  	if from == nil || to == nil || test == nil {
    70  		return false
    71  	}
    72  
    73  	from16 := from.To16()
    74  	to16 := to.To16()
    75  	test16 := test.To16()
    76  
    77  	if from16 == nil || to16 == nil || test16 == nil {
    78  		return false
    79  	}
    80  
    81  	return bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0
    82  }
    83  
    84  // IsPublic checks a IPv4 address  is a public or not.
    85  func IsPublic(ip net.IP) bool {
    86  	if ip.IsLoopback() || ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast() {
    87  		return false
    88  	}
    89  	if ip4 := ip.To4(); ip4 != nil {
    90  		switch {
    91  		case ip4[0] == 10:
    92  			return false
    93  		case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31:
    94  			return false
    95  		case ip4[0] == 192 && ip4[1] == 168:
    96  			return false
    97  		default:
    98  			return true
    99  		}
   100  	}
   101  
   102  	return false
   103  }