首页 > 其他分享 >go解析IP

go解析IP

时间:2023-03-02 14:55:06浏览次数:35  
标签:err return string nil IP ip go net 解析

// Copyright © 2021 sealos.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package iputils

import (
"errors"
"fmt"
"math/big"
"net"
"strings"

"k8s.io/apimachinery/pkg/util/sets"

"github.com/labring/sealos/pkg/utils/logger"
)

// use only one
func GetHostIP(host string) string {
if !strings.ContainsRune(host, ':') {
return host
}
return strings.Split(host, ":")[0]
}

func GetDiffHosts(hostsOld, hostsNew []string) (add, sub []string) {
// Difference returns a set of objects that are not in s2
// For example:
// s1 = {a1, a2, a3}
// s2 = {a1, a2, a4, a5}
// s1.Difference(s2) = {a3}
// s2.Difference(s1) = {a4, a5}
oldSet := sets.NewString(GetHostIPs(hostsOld)...)
newSet := sets.NewString(GetHostIPs(hostsNew)...)
addIPs := newSet.Difference(oldSet).List()
subIPs := oldSet.Difference(newSet).List()

for _, ip := range hostsNew {
for _, aIP := range addIPs {
if aIP == GetHostIP(ip) {
add = append(add, ip)
}
}
}
for _, ip := range hostsOld {
for _, aIP := range subIPs {
if aIP == GetHostIP(ip) {
sub = append(sub, ip)
}
}
}
return
}

func GetHostIPs(hosts []string) []string {
var ips []string
for _, name := range hosts {
ips = append(ips, GetHostIP(name))
}
return ips
}

func GetHostIPAndPortOrDefault(host, Default string) (string, string) {
if !strings.ContainsRune(host, ':') {
return host, Default
}
split := strings.Split(host, ":")
return split[0], split[1]
}

func GetSSHHostIPAndPort(host string) (string, string) {
return GetHostIPAndPortOrDefault(host, "22")
}

func GetHostIPAndPortSlice(hosts []string, Default string) (res []string) {
for _, ip := range hosts {
_ip, port := GetHostIPAndPortOrDefault(ip, Default)
res = append(res, fmt.Sprintf("%s:%s", _ip, port))
}
return
}

func GetHostIPSlice(hosts []string) (res []string) {
for _, ip := range hosts {
res = append(res, GetHostIP(ip))
}
return
}

func ListLocalHostAddrs() (*[]net.Addr, error) {
netInterfaces, err := net.Interfaces()
if err != nil {
logger.Warn("net.Interfaces failed, err:", err.Error())
return nil, err
}
var allAddrs []net.Addr
for i := 0; i < len(netInterfaces); i++ {
if (netInterfaces[i].Flags & net.FlagUp) == 0 {
continue
}
addrs, err := netInterfaces[i].Addrs()
if err != nil {
logger.Warn("failed to get Addrs, %s", err.Error())
}
for j := 0; j < len(addrs); j++ {
allAddrs = append(allAddrs, addrs[j])
}
}
return &allAddrs, nil
}

func IsLocalIP(ip string, addrs *[]net.Addr) bool {
if defaultIP, _, err := net.SplitHostPort(ip); err == nil {
ip = defaultIP
}
for _, address := range *addrs {
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && ipnet.IP.To4() != nil && ipnet.IP.String() == ip {
return true
}
}
return false
}

func LocalIP(addrs *[]net.Addr) string {
for _, address := range *addrs {
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && ipnet.IP.To4() != nil {
return ipnet.IP.String()
}
}
return ""
}

func inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}

func ParseIPList(s string) ([]string, error) {
s = strings.TrimSpace(s)
if s == "" {
return nil, nil
}
var ret []string
if strings.Contains(s, ",") {
ss := strings.Split(s, ",")
for i := range ss {
ret2, err := ParseIPList(ss[i])
if err != nil {
return nil, err
}
ret = append(ret, ret2...)
}
} else if strings.Contains(s, "/") {
ip, ipnet, err := net.ParseCIDR(s)
if err != nil {
return nil, err
}
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
ret = append(ret, ip.String())
}
// network address and broadcast address are included
} else if strings.Contains(s, "-") {
ips := strings.Split(s, "-")
if len(ips) != 2 {
return nil, errors.New("ip range format is invalid")
}
for i := range ips {
if !CheckIP(ips[i]) {
return nil, fmt.Errorf("invalid ip: %v", ips[i])
}
}
first := true
for {
res, _ := CompareIP(ips[0], ips[1])
if res > 0 {
if first {
return nil, fmt.Errorf("start ip %s cannot greater than end ip %s", ips[0], ips[1])
}
break
}
ret = append(ret, ips[0])
ips[0] = NextIP(ips[0]).String()
first = false
}
} else {
ip := net.ParseIP(GetHostIP(s))
if ip == nil {
return nil, fmt.Errorf("invalid ip: %v", s)
}
ret = append(ret, s)
}
return ret, nil
}

func CheckIP(i string) bool {
if !strings.Contains(i, ":") {
return net.ParseIP(i) != nil
}
return false
}

func IPToInt(v string) *big.Int {
ip := net.ParseIP(v).To4()
if val := ip.To4(); val != nil {
return big.NewInt(0).SetBytes(val)
}
return big.NewInt(0).SetBytes(ip.To16())
}

func CompareIP(v1, v2 string) (int, error) {
i := IPToInt(v1)
j := IPToInt(v2)

if i == nil || j == nil {
return 2, fmt.Errorf("ip is invalid,check you command args")
}
return i.Cmp(j), nil
}

func NextIP(ip string) net.IP {
i := IPToInt(ip)
return i.Add(i, big.NewInt(1)).Bytes()
}

func Contains(sub, s string) (bool, error) {
_, ipNet, err := net.ParseCIDR(sub)
if err != nil {
return false, err
}
ip := net.ParseIP(s)
if ip == nil {
return false, fmt.Errorf("%s is not a valid IP address", s)
}
return ipNet.Contains(ip), nil
}

标签:err,return,string,nil,IP,ip,go,net,解析
From: https://www.cnblogs.com/cheyunhua/p/17171768.html

相关文章

  • Java Web程序设计——MyEclipse的安装、配置
    JavaWeb程序设计——MyEclipse的安装、配置具体安装、配置过程请参考下面的博客MyEclipse安装、配置、测试——博客园原博客中所需文件均存放于百度网盘中,如下......
  • docker+go+gin部署
    一、准备工作1、先确保项目可以正常运行二、编写Dockerfile文件,生成镜像FROMgolang:1.18.1WORKDIR/go/src/appADD.//go/src/appRUNgoenv-wGO111MODULE=......
  • go build
    gohelpbuildgotoollink--helpgotoolcompile--help   gobuild-ldflags"-s-w"x.go (goinstall类似)-s去掉符号表,然后panic的时候stacktrace......
  • ImmutablePair和ImmutableTriple的使用
    场景当我们调用某个方法,需要有超过一个值的返回时,我们通常会怎么做,比如现在需要调用方法返回姓名和年龄两个属性(假如姓名为张三,年龄为12)。方式一:使用Map,将Map中分别放......
  • BIP 两个请求成功后,才能做某一件事
    //保存前校验letSetXStatus=0;viewModel.on("beforeSave",function(args){let_this=this;console.log(_this);......
  • linux服务器解压缩zip文件时报错End-of-central-directory signature not found
    在向服务器上传一个windows上压缩的zip文件时出现报错End-of-central-directorysignaturenotfound. Eitherthisfileisnotazipfile,oritconstitutesonedis......
  • Android图像处理实例解析
    一、概述本篇文章介绍的是关于Android图像处理相关的,主要有动态修改图像的色相、饱和度及亮度,颜色矩阵,图像像素点调整、图像矩阵实现图像的平移缩放等,Xfermode相关知识点,......
  • 【JavaScript】33_递归
    17、递归递归调用自身的函数称为递归函数递归的作用和循环是基本一直递归的核心思想就是将一个大的问题拆分为一个一个小的问题,小的问题解决了,大的问题也就解决了编写递归函......
  • Google Chrome Version 110 All In One
    GoogleChromeVersion110AllInOneGoogleChromeVersion110.0.5481.177(OfficialBuild)(x86_64)chrome://whats-new/效率边浏览,边利用侧边栏整理和标记重点......
  • 【javascript】slice()、substring()和substr() 三种字符串截取方法区别
    slice(start,end):slice(start,end)方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。 1、start(包含)和end(不包含)参数来指定字符串提取的部分;2、......