mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
174 lines
3.6 KiB
Go
174 lines
3.6 KiB
Go
package linux
|
|
|
|
import (
|
|
"errors"
|
|
"net"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
ipv4RegExp = regexp.MustCompile("^[0-9a-fA-F]{8}:[0-9a-fA-F]{4}$") // Regex for NetIPv4Decoder
|
|
ipv6RegExp = regexp.MustCompile("^[0-9a-fA-F]{32}:[0-9a-fA-F]{4}$") // Regex for NetIPv6Decoder
|
|
)
|
|
|
|
type NetIPDecoder func(string) (string, error) // Either NetIPv4Decoder or NetIPv6Decoder
|
|
|
|
type NetSocket struct {
|
|
LocalAddress string `json:"local_address"`
|
|
RemoteAddress string `json:"remote_address"`
|
|
Status uint8 `json:"st"`
|
|
TxQueue uint64 `json:"tx_queue"`
|
|
RxQueue uint64 `json:"rx_queue"`
|
|
Uid uint32 `json:"uid"`
|
|
Inode uint64 `json:"inode"`
|
|
SocketReferenceCount uint64 `json:"ref"`
|
|
}
|
|
|
|
func parseNetSocket(f []string, ip NetIPDecoder) (*NetSocket, error) {
|
|
|
|
if len(f) < 11 {
|
|
return nil, errors.New("Cannot parse net socket line: " + strings.Join(f, " "))
|
|
}
|
|
|
|
if strings.Index(f[4], ":") == -1 {
|
|
return nil, errors.New("Cannot parse tx/rx queues: " + f[4])
|
|
}
|
|
|
|
q := strings.Split(f[4], ":")
|
|
|
|
socket := &NetSocket{}
|
|
|
|
var s uint64 // socket.Status
|
|
var u uint64 // socket.Uid
|
|
var err error // parse error
|
|
|
|
if socket.LocalAddress, err = ip(f[1]); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if socket.RemoteAddress, err = ip(f[2]); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if s, err = strconv.ParseUint(f[3], 16, 8); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if socket.TxQueue, err = strconv.ParseUint(q[0], 16, 64); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if socket.RxQueue, err = strconv.ParseUint(q[1], 16, 64); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if u, err = strconv.ParseUint(f[7], 10, 32); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if socket.Inode, err = strconv.ParseUint(f[9], 10, 64); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if socket.SocketReferenceCount, err = strconv.ParseUint(f[10], 10, 64); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
socket.Status = uint8(s)
|
|
socket.Uid = uint32(u)
|
|
|
|
return socket, nil
|
|
}
|
|
|
|
// Decode an IPv4 address with port from a given hex string
|
|
// NOTE: This function match NetIPDecoder type
|
|
func NetIPv4Decoder(s string) (string, error) {
|
|
|
|
if !ipv4RegExp.MatchString(s) {
|
|
return "", errors.New("Cannot decode ipv4 address: " + s)
|
|
}
|
|
|
|
i := strings.Split(s, ":")
|
|
|
|
b := make([]byte, 4)
|
|
|
|
for j := 0; j < 4; j++ {
|
|
|
|
x := j * 2
|
|
y := x + 2
|
|
z := 3 - j
|
|
|
|
// Extract 2 characters from hex string, 4 times.
|
|
//
|
|
// s: "0100007F" -> [
|
|
// h: "01", h: "00", h: "00", h: "7F",
|
|
// ]
|
|
h := i[0][x:y]
|
|
|
|
// Reverse byte order
|
|
n, _ := strconv.ParseUint(h, 16, 8)
|
|
b[z] = byte(n)
|
|
|
|
}
|
|
|
|
h := net.IP(b).String()
|
|
n, _ := strconv.ParseUint(i[1], 16, 64)
|
|
p := strconv.FormatUint(n, 10)
|
|
|
|
// ipv4:port
|
|
v := h + ":" + p
|
|
|
|
return v, nil
|
|
}
|
|
|
|
// Decode an IPv6 address with port from a given hex string
|
|
// NOTE: This function match NetIPDecoder type
|
|
func NetIPv6Decoder(s string) (string, error) {
|
|
|
|
if !ipv6RegExp.MatchString(s) {
|
|
return "", errors.New("Cannot decode ipv6 address: " + s)
|
|
}
|
|
|
|
i := strings.Split(s, ":")
|
|
|
|
b := make([]byte, 16)
|
|
|
|
for j := 0; j < 4; j++ {
|
|
|
|
x := j * 8
|
|
y := x + 8
|
|
|
|
// Extract 8 characters from hex string, 4 times.
|
|
//
|
|
// s: "350E012A900F122E85EDEAADA64DAAD1" -> [
|
|
// h: "350E012A", h: "900F122E",
|
|
// h: "85EDEAAD", h: "A64DAAD1",
|
|
// ]
|
|
h := i[0][x:y]
|
|
|
|
for k := 0; k < 4; k++ {
|
|
|
|
// Reverse byte order
|
|
// "350E012A" -> [ 0x2A, 0x01, 0x0E, 0x35 ]
|
|
z := (j * 4) + k
|
|
g := 8 - (k * 2)
|
|
f := g - 2
|
|
|
|
n, _ := strconv.ParseUint(h[f:g], 16, 8)
|
|
b[z] = byte(n)
|
|
|
|
}
|
|
}
|
|
|
|
h := net.IP(b).String()
|
|
n, _ := strconv.ParseUint(i[1], 16, 64)
|
|
p := strconv.FormatUint(n, 10)
|
|
|
|
// ipv6:port
|
|
v := h + ":" + p
|
|
|
|
return v, nil
|
|
}
|