直接上代码
package main
import (
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"net"
"strconv"
"strings"
)
func hexToByte(s byte) (byte, error) {
if s <= '9' && s >= '0' {
return s-'0', nil
} else if s >= 'a' && s <= 'f' {
return s-'a'+10, nil
} else if s >= 'A' && s <= 'F' {
return s-'A'+10, nil
} else {
return s, errors.New("invalid byte")
}
}
// cat /proc/net/tcp6:
// sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
// 36: 0000000000000000FFFF000032190A0A:1F96 0000000000000000FFFF000032190A0A:4F5F 01 00000000:00000000 00:00000000 00000000 0 0 1245464177 2 ffff8e714244d500 21 4 22 10 7
// AnalysisIpv6 可将上面的16进制的ipv6地址转为可识别的ipv6格式:例如“::ffff:10.10.25.50:48422”
func AnalysisIpv6(s string) (string, error) {
hexIP := s[:len(s)-5]
hexPort := s[len(s)-4:]
if hexIP == "00000000000000000000000000000000" {
// 忽略0.0.0.0
return "", nil
}
b := make(net.IP, 16)
for i:=0; i< 4; i++ {
for j :=0; j<4; j ++ {
srcIndex := i *4 +3 -j
targetIndex := i *4 + j
c, err := hexToByte(hexIP[srcIndex*2])
if err != nil {
return "", err
}
d, err := hexToByte(hexIP[srcIndex*2+1])
if err != nil {
return "", err
}
b[targetIndex] = c*16 + d
}
}
ip := b.String()
l := strings.Split(ip, ".")
if len(l) > 2 {
// 判断是否是真的ipv6格式, 如果不是则转为ipv6格式
ip = "::ffff:" + ip
}
port, err := strconv.ParseUint(hexPort, 16, 16)
return fmt.Sprintf("%s:%d", ip, port), err
}
// AnalysisIpv4 16进制的ipv4地址转为可识别的ipv4格式:例如“10.10.25.50:8888”
func AnalysisIpv4(s string) (string, error) {
hexIP := s[:len(s)-5]
hexPort := s[len(s)-4:]
bytesIP, err := hex.DecodeString(hexIP)
if err != nil {
return "", nil
}
uint32IP := binary.LittleEndian.Uint32(bytesIP) //转换为主机字节序
IP := make(net.IP, 4)
binary.BigEndian.PutUint32(IP, uint32IP)
port, err := strconv.ParseUint(hexPort, 16, 16)
return fmt.Sprintf("%s:%d", IP.String(), port), err
}
func main() {
strIpv6 := "0000000000000000FFFF000032190A0A:3D2D"
fmt.Println(AnalysisIpv6(strIpv6))
strIpv6 = "000080FE00000000FF5D1502020400FE:3D2D"
fmt.Println(AnalysisIpv6(strIpv6))
strIpv4 := "34190A0A:3D2D"
fmt.Println(AnalysisIpv4(strIpv4))
}
上面代码输出结果:
::ffff:10.10.25.50:15661 <nil>
fe80::215:5dff:fe00:402:15661 <nil>
10.10.25.52:15661 <nil>
结果与 ss -nt 命令看到的IP地址相同.