1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00
2018-11-12 01:30:24 -08:00

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
}