github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgNet/CurrentIp.go (about) 1 package kmgNet 2 3 import ( 4 "fmt" 5 "net" 6 "regexp" 7 "strconv" 8 9 "github.com/bronze1man/kmg/errors" 10 "github.com/bronze1man/kmg/kmgCmd" 11 "github.com/bronze1man/kmg/kmgPlatform" 12 ) 13 14 // 获取当前地址的列表的字符串 15 func GetCurrentAddrListString() string { 16 addrList, err := net.InterfaceAddrs() 17 if err != nil { 18 return "[GetCurrentAddrListString] fail " + err.Error() 19 } 20 out := "" 21 for _, addr := range addrList { 22 out += addr.String() + ";" 23 } 24 return out 25 } 26 27 //一个网络设备上面的地址 28 type DeviceAddr struct { 29 IP net.IP //地址上面的ip 30 IPNet *net.IPNet //地址上面的子网 31 DevString string //设备名称 eth0 什么的 32 } 33 34 // 返回nil表示没找到这个设备,或者这个设备上面没有ip 35 func MustGetFirstIPByNetDeviceName(devname string) net.IP { 36 if !kmgPlatform.IsLinux() { 37 panic("[GetFirstIPByNetDeviceName] only support linux now") 38 } 39 deviceAddrList, err := GetCurrentDeviceAddr() 40 if err != nil { 41 panic(err) 42 } 43 for _, deviceAddr := range deviceAddrList { 44 if deviceAddr.DevString == devname { 45 return deviceAddr.IP 46 } 47 } 48 return nil 49 } 50 51 //目前仅支持linux 52 func (a DeviceAddr) IpAddrDel() (err error) { 53 if !kmgPlatform.IsLinux() { 54 panic("[DeviceAddr.IpAddrDel] only support linux now") 55 } 56 one, _ := a.IPNet.Mask.Size() 57 return kmgCmd.CmdString(fmt.Sprintf("ip addr del %s/%d dev %s", a.IP.String(), one, a.DevString)).Run() 58 } 59 60 //目前仅支持linux 61 func GetCurrentDeviceAddr() (ipnets []DeviceAddr, err error) { 62 if !kmgPlatform.IsLinux() { 63 panic("[GetCurrentDeviceAddr] only support linux now") 64 } 65 out, err := kmgCmd.CmdString("ip addr").RunAndReturnOutput() 66 if err != nil { 67 return 68 } 69 return getCurrentDeviceAddrFromIPAddr(out) 70 } 71 72 //返回当前机器上面的所有ip列表.没有ip会报错 73 func MustGetCurrentIpList() (ipList []net.IP) { 74 if !kmgPlatform.IsLinux() { 75 panic("[MustGetCurrentIpList] only support linux now") 76 } 77 deviceAddrList, err := GetCurrentDeviceAddr() 78 if err != nil { 79 panic(err) 80 } 81 if len(deviceAddrList) == 0 { 82 panic(errors.New("[MustGetCurrentIpList] do not find any ip address.")) 83 } 84 ipList = make([]net.IP, len(deviceAddrList)) 85 for i, addr := range deviceAddrList { 86 ipList[i] = addr.IP 87 } 88 return ipList 89 } 90 91 func MustGetCurrentIpWithPortList(port uint16) (sList []string) { 92 if !kmgPlatform.IsLinux() { 93 panic("[MustGetCurrentIpWithPortList] only support linux now") 94 } 95 deviceAddrList, err := GetCurrentDeviceAddr() 96 if err != nil { 97 panic(err) 98 } 99 if len(deviceAddrList) == 0 { 100 panic(errors.New("[MustGetCurrentIpList] do not find any ip address.")) 101 } 102 sList = make([]string, 0, len(deviceAddrList)) 103 sPort := strconv.Itoa(int(port)) 104 for _, addr := range deviceAddrList { 105 ones, size := addr.IPNet.Mask.Size() 106 if ones == size { // 实践表明 不能监听这种子网只有一个ip的地址. 107 continue 108 } 109 sList = append(sList, net.JoinHostPort(addr.IP.String(), sPort)) 110 } 111 return sList 112 } 113 114 func getCurrentDeviceAddrFromIPAddr(cmdReturn []byte) (ipnets []DeviceAddr, err error) { 115 //可能性1 本地回路 inet 127.0.0.1/8 scope host lo 116 //可能性2 物理网卡 inet 10.169.224.99/21 brd 10.169.231.255 scope global eth0 117 //可能性3 pptp虚拟网卡 inet 172.20.0.1 peer 172.20.0.2/32 scope global ppp0 118 reg := regexp.MustCompile(`inet ([^ ]+).* ([^\s]+)`) 119 out := reg.FindAllSubmatch(cmdReturn, -1) 120 ipnets = make([]DeviceAddr, len(out)) 121 for i := range out { 122 ip, ipnet, err := net.ParseCIDR(string(out[i][1])) 123 if err != nil { 124 _, ok := err.(*net.ParseError) 125 if !ok { 126 return nil, err 127 } 128 ip, ipnet, err = net.ParseCIDR(string(out[i][1]) + "/32") 129 if err != nil { 130 return nil, fmt.Errorf("[getCurrentDeviceAddrFromIPAddr] can not parse CIDR or IP [%s]", out[i][0]) 131 } 132 } 133 ipnets[i] = DeviceAddr{ 134 IP: ip, 135 IPNet: ipnet, 136 DevString: string(out[i][2]), 137 } 138 } 139 return 140 }