diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..2c7e10a --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/dirtbags/netshovel + +go 1.13 + +require github.com/google/gopacket v1.1.18 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..aa11271 --- /dev/null +++ b/go.sum @@ -0,0 +1,7 @@ +github.com/google/gopacket v1.1.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY= +github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/packet.go b/packet.go index 3c0f863..89c9dda 100644 --- a/packet.go +++ b/packet.go @@ -91,6 +91,9 @@ func (pkt *Packet) DescribeFields() string { } func center(s string, w int) string { + if w < 3 { + return "?" + } if len(s) > w { s = s[0:w-3] + "…" } @@ -100,39 +103,54 @@ func center(s string, w int) string { // DescribeHeader returns a multi-line string describing this packet's header structure func (pkt *Packet) DescribeHeader() string { out := new(strings.Builder) - fmt.Fprintln(out, " 0 1 ") - fmt.Fprintln(out, " mo0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f") + out.WriteString(" 0 1\n") + out.WriteString(" 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f\n") + out.WriteString("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n") bitOffset := 0 for _, f := range pkt.header { bits := f.bits for bits > 0 { - if bitOffset == 0 { - fmt.Fprintln(out, "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+") - } - linebits := bits if linebits+bitOffset > 0x20 { linebits = 0x20 - bitOffset } // Generate centered string - // TODO: right-align value, center name - nameval := fmt.Sprintf("%s (0x%x)", f.name, f.value) - fmt.Fprintf(out, "|%s", center(nameval, linebits*2-1)) + val := fmt.Sprintf("0x%x", f.value) + nameval := f.name + if f.bits == bits { + out.WriteString("|") + } else { + out.WriteString(" ") + val = "" + nameval = "..." + } + out.WriteString(center(nameval, linebits*2-len(val)-2)) + out.WriteString(val) + out.WriteString(" ") bitOffset += linebits bits -= linebits - if linebits == 0x20 { - fmt.Fprintln(out, "|") + if bitOffset == 0x20 { + if bits == 0 { + out.WriteString("|") + } else { + out.WriteString(" ") + } + out.WriteString("\n") + out.WriteString("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n") bitOffset = 0 } } } if bitOffset > 0 { - fmt.Fprintln(out, "|") + out.WriteString("|\n") + for o := 0; o < bitOffset; o++ { + out.WriteString("+-") + } + out.WriteString("+\n") } - fmt.Fprintln(out, "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+") return out.String() } diff --git a/packet_test.go b/packet_test.go new file mode 100644 index 0000000..4d2465f --- /dev/null +++ b/packet_test.go @@ -0,0 +1,60 @@ +package netshovel + +import ( + "strings" + "testing" + + "github.com/dirtbags/netshovel/gapstring" +) + +// BUG(neale): The DescribeHeader test is too simplistic. +func TestHeaders(t *testing.T) { + pkt := NewPacket() + pkt.Payload = gapstring.OfBytes([]byte{0, 1, 0, 1, 42, 0xff, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64}) + + a, err := pkt.Uint16LE("le") + if err != nil { + t.Error(err) + } + if a != 0x0100 { + t.Error("Uint16LE", a) + } + + b, err := pkt.Uint16BE("be") + if err != nil { + t.Error(err) + } + if b != 0x0001 { + t.Error("Uint16BE", b) + } + + fnord, err := pkt.Uint8("fnord") + if err != nil { + t.Error(err) + } + if fnord != 42 { + t.Error("Uint8", fnord) + } + + biggun, err := pkt.Uint32LE("biggun") + if err != nil { + t.Error(err) + } + if biggun != 0xff000001 { + t.Error("biggun", biggun) + } + + bignum, err := pkt.Uint64BE("bignum") + if err != nil { + t.Error(err) + } + if bignum != 64 { + t.Error("bignum", bignum) + } + + desc := pkt.DescribeHeader() + lines := strings.Split(desc, "\n") + if len(lines) != 14 { + t.Error(desc) + } +}