diff --git a/fixtures.ttar b/fixtures.ttar index 12494d742..7ecfa0231 100644 --- a/fixtures.ttar +++ b/fixtures.ttar @@ -2189,7 +2189,7 @@ Mode: 644 Path: fixtures/proc/net/udp Lines: 4 sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode - 0: 0A000005:0016 00000000:0000 0A 00000000:00000001 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 + 0: 0500000A:0016 00000000:0000 0A 00000000:00000001 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 1: 00000000:0016 00000000:0000 0A 00000001:00000000 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000001:00000001 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 Mode: 644 diff --git a/net_udp.go b/net_udp.go index d017e3f18..7e91aabc9 100644 --- a/net_udp.go +++ b/net_udp.go @@ -147,6 +147,33 @@ func newNetUDPSummary(file string) (*NetUDPSummary, error) { return netUDPSummary, nil } +// NOTE: this function assumes the architecture is little endian, like x86 and amd64 +// /proc/net/{t,u}dp{,6} files are network byte order for ipv4 +// for ipv6 the address is four words consisting of four bytes each. In each of those four words the four bytes are written in reverse order. + +func parseIP(hexIP string) (net.IP, error) { + var byteIP []byte + byteIP, err := hex.DecodeString(hexIP) + if err != nil { + return nil, fmt.Errorf( + "cannot parse address field in socket line: %s", hexIP) + } + switch len(byteIP) { + case 4: + return net.IP{byteIP[3], byteIP[2], byteIP[1], byteIP[0]}, nil + case 16: + i := net.IP{ + byteIP[3], byteIP[2], byteIP[1], byteIP[0], + byteIP[7], byteIP[6], byteIP[5], byteIP[4], + byteIP[11], byteIP[10], byteIP[9], byteIP[8], + byteIP[15], byteIP[14], byteIP[13], byteIP[12], + } + return i, nil + default: + return nil, fmt.Errorf("Unable to parse IP %s", hexIP) + } +} + // parseNetUDPLine parses a single line, represented by a list of fields. func parseNetUDPLine(fields []string) (*netUDPLine, error) { line := &netUDPLine{} @@ -174,9 +201,8 @@ func parseNetUDPLine(fields []string) (*netUDPLine, error) { return nil, fmt.Errorf( "cannot parse local_address field in udp socket line: %s", fields[1]) } - if line.LocalAddr, err = hex.DecodeString(l[0]); err != nil { - return nil, fmt.Errorf( - "cannot parse local_address value in udp socket line: %s", err) + if line.LocalAddr, err = parseIP(l[0]); err != nil { + return nil, err } if line.LocalPort, err = strconv.ParseUint(l[1], 16, 64); err != nil { return nil, fmt.Errorf( @@ -189,9 +215,8 @@ func parseNetUDPLine(fields []string) (*netUDPLine, error) { return nil, fmt.Errorf( "cannot parse rem_address field in udp socket line: %s", fields[1]) } - if line.RemAddr, err = hex.DecodeString(r[0]); err != nil { - return nil, fmt.Errorf( - "cannot parse rem_address value in udp socket line: %s", err) + if line.RemAddr, err = parseIP(r[0]); err != nil { + return nil, err } if line.RemPort, err = strconv.ParseUint(r[1], 16, 64); err != nil { return nil, fmt.Errorf( diff --git a/net_udp_test.go b/net_udp_test.go index 363fdb287..0add2d45c 100644 --- a/net_udp_test.go +++ b/net_udp_test.go @@ -171,7 +171,7 @@ func Test_newNetUDP(t *testing.T) { }, &netUDPLine{ Sl: 6073, - LocalAddr: net.IP{0, 0, 128, 254, 0, 0, 0, 0, 255, 173, 225, 86, 9, 102, 124, 254}, + LocalAddr: net.IP{254, 128, 0, 0, 0, 0, 0, 0, 86, 225, 173, 255, 254, 124, 102, 9}, LocalPort: 51073, RemAddr: net.IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, RemPort: 0,