bitbucket.org/Aishee/synsec@v0.0.0-20210414005726-236fc01a153d/pkg/types/ip.go (about) 1 package types 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "math" 7 "net" 8 "strings" 9 10 "github.com/pkg/errors" 11 ) 12 13 func LastAddress(n net.IPNet) net.IP { 14 ip := n.IP.To4() 15 if ip == nil { 16 ip = n.IP 17 return net.IP{ 18 ip[0] | ^n.Mask[0], ip[1] | ^n.Mask[1], ip[2] | ^n.Mask[2], 19 ip[3] | ^n.Mask[3], ip[4] | ^n.Mask[4], ip[5] | ^n.Mask[5], 20 ip[6] | ^n.Mask[6], ip[7] | ^n.Mask[7], ip[8] | ^n.Mask[8], 21 ip[9] | ^n.Mask[9], ip[10] | ^n.Mask[10], ip[11] | ^n.Mask[11], 22 ip[12] | ^n.Mask[12], ip[13] | ^n.Mask[13], ip[14] | ^n.Mask[14], 23 ip[15] | ^n.Mask[15]} 24 } 25 26 return net.IPv4( 27 ip[0]|^n.Mask[0], 28 ip[1]|^n.Mask[1], 29 ip[2]|^n.Mask[2], 30 ip[3]|^n.Mask[3]) 31 } 32 33 /*returns a range for any ip or range*/ 34 func Addr2Ints(any string) (int, int64, int64, int64, int64, error) { 35 if strings.Contains(any, "/") { 36 _, net, err := net.ParseCIDR(any) 37 if err != nil { 38 return -1, 0, 0, 0, 0, errors.Wrapf(err, "while parsing range %s", any) 39 } 40 return Range2Ints(*net) 41 } else { 42 ip := net.ParseIP(any) 43 if ip == nil { 44 return -1, 0, 0, 0, 0, fmt.Errorf("invalid address") 45 } 46 sz, start, end, err := IP2Ints(ip) 47 if err != nil { 48 return -1, 0, 0, 0, 0, errors.Wrapf(err, "while parsing ip %s", any) 49 } 50 return sz, start, end, start, end, nil 51 } 52 } 53 54 /*size (16|4), nw_start, suffix_start, nw_end, suffix_end, error*/ 55 func Range2Ints(network net.IPNet) (int, int64, int64, int64, int64, error) { 56 57 szStart, nwStart, sfxStart, err := IP2Ints(network.IP) 58 if err != nil { 59 return -1, 0, 0, 0, 0, errors.Wrap(err, "converting first ip in range") 60 } 61 lastAddr := LastAddress(network) 62 szEnd, nwEnd, sfxEnd, err := IP2Ints(lastAddr) 63 if err != nil { 64 return -1, 0, 0, 0, 0, errors.Wrap(err, "transforming last address of range") 65 } 66 if szEnd != szStart { 67 return -1, 0, 0, 0, 0, fmt.Errorf("inconsistent size for range first(%d) and last(%d) ip", szStart, szEnd) 68 } 69 return szStart, nwStart, sfxStart, nwEnd, sfxEnd, nil 70 } 71 72 func uint2int(u uint64) int64 { 73 var ret int64 74 if u == math.MaxInt64 { 75 ret = 0 76 } else if u == math.MaxUint64 { 77 ret = math.MaxInt64 78 } else if u > math.MaxInt64 { 79 u -= math.MaxInt64 80 ret = int64(u) 81 } else { 82 ret = int64(u) 83 ret -= math.MaxInt64 84 } 85 return ret 86 } 87 88 /*size (16|4), network, suffix, error*/ 89 func IP2Ints(pip net.IP) (int, int64, int64, error) { 90 var ip_nw, ip_sfx uint64 91 92 pip4 := pip.To4() 93 pip16 := pip.To16() 94 95 if pip4 != nil { 96 ip_nw32 := binary.BigEndian.Uint32(pip4) 97 98 return 4, uint2int(uint64(ip_nw32)), uint2int(ip_sfx), nil 99 } else if pip16 != nil { 100 ip_nw = binary.BigEndian.Uint64(pip16[0:8]) 101 ip_sfx = binary.BigEndian.Uint64(pip16[8:16]) 102 return 16, uint2int(ip_nw), uint2int(ip_sfx), nil 103 } else { 104 return -1, 0, 0, fmt.Errorf("unexpected len %d for %s", len(pip), pip) 105 } 106 }