blob: 0ce3bef7534ea738dd9b737251ab3df5e436986f [file] [log] [blame]
// Copyright 2016 ~ 2018 AlexStocks(https://github.com/AlexStocks).
// All rights reserved. Use of this source code is
// governed by Apache License 2.0.
// Package gxnet encapsulates some network functions
package gxnet
import (
"encoding/binary"
"fmt"
"net"
jerrors "github.com/juju/errors"
)
var (
privateBlocks []*net.IPNet
)
func init() {
for _, b := range []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"} {
if _, block, err := net.ParseCIDR(b); err == nil {
privateBlocks = append(privateBlocks, block)
}
}
}
func isPrivateIP(ipAddr string) bool {
ip := net.ParseIP(ipAddr)
for _, priv := range privateBlocks {
if priv.Contains(ip) {
return true
}
}
return false
}
// ref: https://stackoverflow.com/questions/23558425/how-do-i-get-the-local-ip-address-in-go
func GetLocalIP() (string, error) {
ifs, err := net.Interfaces()
if err != nil {
return "", jerrors.Trace(err)
}
var ipAddr []byte
for _, i := range ifs {
addrs, err := i.Addrs()
if err != nil {
return "", jerrors.Trace(err)
}
var ip net.IP
for _, addr := range addrs {
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
if !ip.IsLoopback() && ip.To4() != nil && isPrivateIP(ip.String()) {
ipAddr = ip
break
}
}
}
if ipAddr == nil {
return "", jerrors.Errorf("can not get local IP")
}
return net.IP(ipAddr).String(), nil
}
// Get preferred outbound ip of this machine
func GetOutboundIP() (string, error) {
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
return "", jerrors.Trace(err)
}
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP.String(), nil
}
// CheckIPValidity checks whether @IPString is a valid ip
func CheckIPValidity(IPString string) bool {
ip := net.ParseIP(IPString)
if ip.To4() == nil {
return false
}
return true
}
// IPItoa returns the string representation of @ip
func IPItoa(ip uint32) string {
return fmt.Sprintf("%d.%d.%d.%d", ip>>24, ip<<8>>24, ip<<16>>24, ip<<24>>24)
}
// IPAtoi returns the integer format of ip string @s
func IPAtoi(s string) uint32 {
ip := net.ParseIP(s)
if ip == nil {
return 0
}
ip = ip.To4()
return binary.BigEndian.Uint32(ip)
}