- commit
- ba891c3
- parent
- dd6e485
- author
- Neale Pickett
- date
- 2020-09-24 16:57:02 -0600 MDT
Handle unaligned headers
3 files changed,
+42,
-36
+4,
-3
1@@ -10,15 +10,16 @@ package netshovel
2
3 import (
4 "flag"
5+ "log"
6+
7 "github.com/google/gopacket"
8 "github.com/google/gopacket/layers"
9 "github.com/google/gopacket/pcap"
10 "github.com/google/gopacket/tcpassembly"
11- "log"
12 )
13
14-// Mainloop to handle dispatching of PCAP files from command line
15-//
16+// Shovel handles dispatching of PCAP files from the command line.
17+// It's intended that you invoke this from your main function.
18 // This parses the command line arguments,
19 // and for each PCAP file specified on the command line,
20 // invokes a TCP assembler that sends streams to whatever is returned from factory.
+27,
-23
1@@ -4,12 +4,13 @@ import (
2 "encoding/binary"
3 "encoding/hex"
4 "fmt"
5- "github.com/dirtbags/netshovel/gapstring"
6 "strings"
7 "time"
8+
9+ "github.com/dirtbags/netshovel/gapstring"
10 )
11
12-// Error returned by convenience methods that are unable to get enough data
13+// ShortError is returned by convenience methods that are unable to get enough data
14 type ShortError struct {
15 Wanted int // How many bytes you needed
16 Available int // How many bytes were available
17@@ -19,7 +20,7 @@ func (e *ShortError) Error() string {
18 return fmt.Sprintf("Short read: wanted %d of %d available", e.Wanted, e.Available)
19 }
20
21-// Error returned by convenience methods that are unable to operate on gaps in data
22+// MissingError is returned by convenience methods that are unable to operate on gaps in data
23 type MissingError struct {
24 }
25
26@@ -58,7 +59,7 @@ type Packet struct {
27
28 var never = time.Unix(0, 0)
29
30-// Return a new packet
31+// NewPacket returns a new packet
32 func NewPacket() Packet {
33 return Packet{
34 Opcode: -1,
35@@ -70,7 +71,7 @@ func NewPacket() Packet {
36 }
37 }
38
39-// Return a string with timestamp, opcode, and description of this packet
40+// DescribeType returns a string with timestamp, opcode, and description of this packet
41 func (pkt *Packet) DescribeType() string {
42 return fmt.Sprintf(
43 " %s Opcode %d: %s",
44@@ -80,7 +81,7 @@ func (pkt *Packet) DescribeType() string {
45 )
46 }
47
48-// Return a multi-line string describing fields in this packet
49+// DescribeFields returns a multi-line string describing fields in this packet
50 func (pkt *Packet) DescribeFields() string {
51 out := new(strings.Builder)
52 for _, f := range pkt.fields {
53@@ -96,11 +97,11 @@ func center(s string, w int) string {
54 return fmt.Sprintf("%*s", -w, fmt.Sprintf("%*s", (w+len(s))/2, s))
55 }
56
57-// Return a multi-line string describing this packet's header structure
58+// DescribeHeader returns a multi-line string describing this packet's header structure
59 func (pkt *Packet) DescribeHeader() string {
60 out := new(strings.Builder)
61 fmt.Fprintln(out, " 0 1 ")
62- fmt.Fprintln(out, " 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")
63+ 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")
64
65 bitOffset := 0
66 for _, f := range pkt.header {
67@@ -128,11 +129,14 @@ func (pkt *Packet) DescribeHeader() string {
68 }
69 }
70 }
71+ if bitOffset > 0 {
72+ fmt.Fprintln(out, "|")
73+ }
74 fmt.Fprintln(out, "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+")
75 return out.String()
76 }
77
78-// Return a multi-line string describing this packet
79+// Describe returns a multi-line string describing this packet
80 //
81 // This shows the timestamp, opcode, description, and hex dump.
82 // If you set any values, those are displayed in the order they were set.
83@@ -157,32 +161,32 @@ func (pkt *Packet) Set(key, value string) {
84 pkt.fields = append(pkt.fields, namedField{key, value})
85 }
86
87-// Set a string value, displaying its Go string representation
88+// SetString sets a string value, displaying its Go string representation
89 func (pkt *Packet) SetString(key, value string) {
90 pkt.Set(key, fmt.Sprintf("%#v", value))
91 }
92
93-// Set an int value, displaying its decimal and hexadecimal representations
94+// SetInt sets an int value, displaying its decimal and hexadecimal representations
95 func (pkt *Packet) SetInt(key string, value int) {
96 pkt.Set(key, fmt.Sprintf("%d == 0x%x", value, value))
97 }
98
99-// Set an unsigned int value, displaying its decimal and hexadecimal representations
100+// SetUint sets an unsigned int value, displaying its decimal and hexadecimal representations
101 func (pkt *Packet) SetUint(key string, value uint) {
102 pkt.Set(key, fmt.Sprintf("%d == 0x%x", value, value))
103 }
104
105-// Set an Unt32 value, displaying its decimal and 0-padded hexadecimal representations
106+// SetUint32 sets an Unt32 value, displaying its decimal and 0-padded hexadecimal representations
107 func (pkt *Packet) SetUint32(key string, value uint32) {
108 pkt.Set(key, fmt.Sprintf("%d == 0x%04x", value, value))
109 }
110
111-// Set an []byte value, displaying the hex encoding of the bytes
112+// SetBytes sets a []byte value, displaying the hex encoding of the bytes
113 func (pkt *Packet) SetBytes(key string, value []byte) {
114 pkt.Set(key, hex.EncodeToString(value))
115 }
116
117-// Set a GapString value, displaying the hex encoding and runes encoding (like a hex dump)
118+// SetGapString sets a GapString value, displaying the hex encoding and runes encoding (like a hex dump)
119 func (pkt *Packet) SetGapString(key string, value gapstring.GapString) {
120 pkt.Set(key, fmt.Sprintf("%s %s", value.HexString(), value.Runes()))
121 }
122@@ -203,7 +207,7 @@ func (pkt *Packet) Peel(octets int) ([]byte, error) {
123 return b, nil
124 }
125
126-// Add a field to the header field description
127+// AddHeaderField adds a field to the header field description
128 func (pkt *Packet) AddHeaderField(order binary.ByteOrder, name string, bits int, value interface{}) {
129 h := headerField{
130 name: name,
131@@ -247,7 +251,7 @@ func (pkt *Packet) readUint(order binary.ByteOrder, bits int, name string) (inte
132 return value, nil
133 }
134
135-// Peel off a uint64, little-endian
136+// Uint64LE peels off a uint64, little-endian
137 func (pkt *Packet) Uint64LE(name string) (uint64, error) {
138 value, err := pkt.readUint(binary.LittleEndian, 64, name)
139 if err != nil {
140@@ -256,7 +260,7 @@ func (pkt *Packet) Uint64LE(name string) (uint64, error) {
141 return value.(uint64), err
142 }
143
144-// Peel off a uint32, little-endian
145+// Uint32LE peels off a uint32, little-endian
146 func (pkt *Packet) Uint32LE(name string) (uint32, error) {
147 value, err := pkt.readUint(binary.LittleEndian, 32, name)
148 if err != nil {
149@@ -265,7 +269,7 @@ func (pkt *Packet) Uint32LE(name string) (uint32, error) {
150 return value.(uint32), err
151 }
152
153-// Peel off a uint16, little-endian
154+// Uint16LE peels off a uint16, little-endian
155 func (pkt *Packet) Uint16LE(name string) (uint16, error) {
156 value, err := pkt.readUint(binary.LittleEndian, 16, name)
157 if err != nil {
158@@ -274,7 +278,7 @@ func (pkt *Packet) Uint16LE(name string) (uint16, error) {
159 return value.(uint16), err
160 }
161
162-// Peel off a uint64, big-endian
163+// Uint64BE peels off a uint64, big-endian
164 func (pkt *Packet) Uint64BE(name string) (uint64, error) {
165 value, err := pkt.readUint(binary.BigEndian, 64, name)
166 if err != nil {
167@@ -283,7 +287,7 @@ func (pkt *Packet) Uint64BE(name string) (uint64, error) {
168 return value.(uint64), err
169 }
170
171-// Peel off a uint32, big-endian
172+// Uint32BE peels off a uint32, big-endian
173 func (pkt *Packet) Uint32BE(name string) (uint32, error) {
174 value, err := pkt.readUint(binary.BigEndian, 32, name)
175 if err != nil {
176@@ -292,7 +296,7 @@ func (pkt *Packet) Uint32BE(name string) (uint32, error) {
177 return value.(uint32), err
178 }
179
180-// Peel off a uint16, big-endian
181+// Uint16BE peels off a uint16, big-endian
182 func (pkt *Packet) Uint16BE(name string) (uint16, error) {
183 value, err := pkt.readUint(binary.BigEndian, 16, name)
184 if err != nil {
185@@ -301,7 +305,7 @@ func (pkt *Packet) Uint16BE(name string) (uint16, error) {
186 return value.(uint16), err
187 }
188
189-// Peel off a uint8 (aka byte)
190+// Uint8 peels off a uint8 (aka byte)
191 func (pkt *Packet) Uint8(name string) (uint8, error) {
192 value, err := pkt.readUint(binary.BigEndian, 8, name)
193 if err != nil {
+11,
-10
1@@ -2,23 +2,24 @@ package netshovel
2
3 import (
4 "fmt"
5- "github.com/dirtbags/netshovel/gapstring"
6- "github.com/google/gopacket"
7- "github.com/google/gopacket/tcpassembly"
8 "io"
9 "net/url"
10 "os"
11 "strings"
12 "time"
13+
14+ "github.com/dirtbags/netshovel/gapstring"
15+ "github.com/google/gopacket"
16+ "github.com/google/gopacket/tcpassembly"
17 )
18
19-// A File and the path where it lives
20+// NamedFile stores a file and the path where it lives
21 type NamedFile struct {
22 *os.File
23 Name string
24 }
25
26-// An atomic communication within a Stream
27+// Utterance is an atomic communication within a Stream
28 //
29 // Streams consist of a string of Utterances.
30 // Each utterance has associated data, and a time stamp.
31@@ -38,7 +39,7 @@ type Stream struct {
32 pending Utterance
33 }
34
35-// Return a newly-built Stream
36+// NewStream returns a newly-built Stream
37 //
38 // You should embed Stream into your own Application protocol stream struct.
39 // Use this to initialize the internal stuff netshovel needs.
40@@ -50,7 +51,7 @@ func NewStream(net, transport gopacket.Flow) Stream {
41 }
42 }
43
44-// Called by the TCP assembler when an Utterance can be built
45+// Reassembled is called by the TCP assembler when an Utterance can be built
46 func (stream *Stream) Reassembled(rs []tcpassembly.Reassembly) {
47 ret := Utterance{
48 When: rs[0].Seen,
49@@ -68,7 +69,7 @@ func (stream *Stream) Reassembled(rs []tcpassembly.Reassembly) {
50 }
51 }
52
53-// Called by the TCP assemble when the Stream is closed
54+// ReassemblyComplete is called by the TCP assemble when the Stream is closed
55 func (stream *Stream) ReassemblyComplete() {
56 close(stream.conversation)
57 }
58@@ -137,7 +138,7 @@ func (stream *Stream) Read(length int) (Utterance, error) {
59 return ret, nil
60 }
61
62-// Return a string description of a packet
63+// Describe returns a string description of a packet
64 //
65 // This just prefixes our source and dest IP:Port to pkt.Describe()
66 func (stream *Stream) Describe(pkt Packet) string {
67@@ -151,7 +152,7 @@ func (stream *Stream) Describe(pkt Packet) string {
68 return out.String()
69 }
70
71-// Return a newly-created, truncated file
72+// CreateFile returns a newly-created, truncated file
73 //
74 // This function creates consistently-named files,
75 // which include a timestamp,