go fmt
This commit is contained in:
parent
a860c7f069
commit
d06ca08456
|
@ -14,8 +14,8 @@ package gapstring
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf16"
|
||||
)
|
||||
|
@ -25,7 +25,7 @@ import (
|
|||
// XXX: I'll have to fix it later; it doesn't matter much for performance
|
||||
|
||||
type chunk struct {
|
||||
gap int // This takes precedence over data
|
||||
gap int // This takes precedence over data
|
||||
data []byte
|
||||
}
|
||||
|
||||
|
@ -135,11 +135,11 @@ func (g GapString) AppendString(s string) GapString {
|
|||
// if g were a string or byte slice.
|
||||
func (g GapString) Slice(start, end int) GapString {
|
||||
outchunks := make([]chunk, 0, len(g.chunks))
|
||||
|
||||
|
||||
if end > g.Length() {
|
||||
panic("runtime error: slice bounds out of range")
|
||||
}
|
||||
|
||||
|
||||
for _, c := range g.chunks {
|
||||
chunklen := c.length()
|
||||
|
||||
|
@ -160,12 +160,12 @@ func (g GapString) Slice(start, end int) GapString {
|
|||
}
|
||||
start = 0
|
||||
end -= cend
|
||||
|
||||
|
||||
if end == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return GapString{chunks: outchunks}
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ func (g GapString) Xor(mask ...byte) GapString {
|
|||
pos := 0
|
||||
for _, c := range g.chunks {
|
||||
ret = ret.AppendGap(c.gap)
|
||||
|
||||
|
||||
out := make([]byte, len(c.data))
|
||||
for i, b := range c.data {
|
||||
m := mask[(pos+i)%len(mask)]
|
||||
|
@ -198,7 +198,7 @@ func (g GapString) Bytes(fill ...byte) []byte {
|
|||
// Fill in gap
|
||||
if len(fill) > 0 {
|
||||
for i := 0; i < c.gap; i += 1 {
|
||||
ret[pos] = fill[pos % len(fill)]
|
||||
ret[pos] = fill[pos%len(fill)]
|
||||
pos += 1
|
||||
}
|
||||
}
|
||||
|
@ -243,9 +243,9 @@ func (g GapString) HexString() string {
|
|||
// There's probably a faster way to do this. Do we care?
|
||||
fmt.Fprintf(out, "%02x", c)
|
||||
}
|
||||
if i + 1 < glen {
|
||||
if i+1 < glen {
|
||||
out.WriteRune(' ')
|
||||
if i % 8 == 7 {
|
||||
if i%8 == 7 {
|
||||
out.WriteRune(' ')
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ func (g GapString) HexString() string {
|
|||
}
|
||||
|
||||
var fluffych = []rune{
|
||||
'·', '☺', '☻', '♥', '♦', '♣', '♠', '•', '◘', '○', '◙', '♂', '♀', '♪', '♫', '☼',
|
||||
'·', '☺', '☻', '♥', '♦', '♣', '♠', '•', '◘', '○', '◙', '♂', '♀', '♪', '♫', '☼',
|
||||
'►', '◄', '↕', '‼', '¶', '§', '▬', '↨', '↑', '↓', '→', '←', '∟', '↔', '▲', '▼',
|
||||
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
|
||||
|
@ -298,7 +298,7 @@ func (g GapString) Hexdump() string {
|
|||
glen := g.Length()
|
||||
pos := 0
|
||||
prev := []byte{}
|
||||
for ; pos < glen; {
|
||||
for pos < glen {
|
||||
// Check for repeats
|
||||
end := pos + 16
|
||||
if end > glen {
|
||||
|
@ -307,7 +307,7 @@ func (g GapString) Hexdump() string {
|
|||
cur := g.Slice(pos, end)
|
||||
curBytes := cur.Bytes()
|
||||
if 0 == bytes.Compare(prev, curBytes) {
|
||||
if ! skipping {
|
||||
if !skipping {
|
||||
fmt.Fprintln(out, "*")
|
||||
skipping = true
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ func (g GapString) Hexdump() string {
|
|||
pos += cur.Length()
|
||||
}
|
||||
fmt.Fprintf(out, "%08x\n", pos)
|
||||
|
||||
|
||||
return out.String()
|
||||
}
|
||||
|
||||
|
@ -343,7 +343,7 @@ func (g GapString) Uint16LE() (uint16, GapString) {
|
|||
func (g GapString) Utf16(order binary.ByteOrder, fill string) string {
|
||||
in := g.Bytes([]byte(fill)...)
|
||||
ints := make([]uint16, len(in)/2)
|
||||
|
||||
|
||||
for i := 0; i < len(in); i += 2 {
|
||||
ints[i/2] = order.Uint16(in[i:])
|
||||
}
|
||||
|
@ -361,4 +361,3 @@ func (g GapString) Utf16LE(gap string) string {
|
|||
func (g GapString) Utf16BE(gap string) string {
|
||||
return g.Utf16(binary.BigEndian, gap)
|
||||
}
|
||||
|
||||
|
|
|
@ -13,13 +13,13 @@ func assertEqual(t *testing.T, name string, a, b interface{}) {
|
|||
|
||||
func TestChunk(t *testing.T) {
|
||||
var c chunk
|
||||
|
||||
|
||||
c = chunk{gap: 2}
|
||||
assertEqual(t, "gap chunk", c.length(), 2)
|
||||
|
||||
|
||||
c = chunk{data: []byte("moo")}
|
||||
assertEqual(t, "byte chunk", c.length(), 3)
|
||||
assertEqual(t, "byte slice", string(c.slice(1,3).data), "oo")
|
||||
assertEqual(t, "byte slice", string(c.slice(1, 3).data), "oo")
|
||||
}
|
||||
|
||||
func TestGapString(t *testing.T) {
|
||||
|
@ -36,12 +36,12 @@ func TestGapString(t *testing.T) {
|
|||
if g.Length() != 0 {
|
||||
t.Errorf("Appending two emtpy gapstrings")
|
||||
}
|
||||
|
||||
|
||||
g = g.AppendString("moo")
|
||||
if 0 != bytes.Compare(g.Bytes(), []byte("moo")) {
|
||||
t.Errorf("Simple string")
|
||||
}
|
||||
|
||||
|
||||
g = g.AppendString("bar")
|
||||
if g.String("") != "moobar" {
|
||||
t.Errorf("Append")
|
||||
|
@ -49,7 +49,7 @@ func TestGapString(t *testing.T) {
|
|||
if g.Missing() != 0 {
|
||||
t.Errorf("Missing when there shouldn't be any missing")
|
||||
}
|
||||
|
||||
|
||||
g = g.AppendGap(8)
|
||||
if g.Length() != 3+3+8 {
|
||||
t.Errorf("Length after gap append")
|
||||
|
@ -57,20 +57,20 @@ func TestGapString(t *testing.T) {
|
|||
if g.Missing() != 8 {
|
||||
t.Errorf("Gap miscounted")
|
||||
}
|
||||
|
||||
|
||||
g = g.AppendString("baz")
|
||||
assertEqual(t, "string", g.String(""), "moobarbaz")
|
||||
assertEqual(t, "string drop", g.String("DROP"), "moobarOPDROPDRbaz")
|
||||
|
||||
assertEqual(t, "xor", g.Xor(1).String(""), "lnnc`sc`{")
|
||||
assertEqual(t, "xor drop", g.Xor(1).String("DROP"), "lnnc`sOPDROPDRc`{")
|
||||
|
||||
|
||||
assertEqual(t, "slice", g.Slice(2, 5).String(""), "oba")
|
||||
assertEqual(t, "slice+xor", g.Slice(2, 5).Xor(1).String(""), "nc`")
|
||||
|
||||
hexdump :=
|
||||
"00000000 6d 6f 6f 62 61 72 -- -- -- -- -- -- -- -- 62 61 moobar<61><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ba\n" +
|
||||
"00000010 7a z\n" +
|
||||
"00000011\n"
|
||||
"00000010 7a z\n" +
|
||||
"00000011\n"
|
||||
assertEqual(t, "hexdump", g.Hexdump(), hexdump)
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ package netshovel
|
|||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
"github.com/google/gopacket/pcap"
|
||||
"github.com/google/gopacket/tcpassembly"
|
||||
"log"
|
||||
)
|
||||
|
||||
// Mainloop to handle dispatching of PCAP files from command line
|
||||
|
@ -25,16 +25,16 @@ import (
|
|||
func Shovel(factory tcpassembly.StreamFactory) {
|
||||
//verbose := flag.Bool("verbose", false, "Write lots of information out")
|
||||
flag.Parse()
|
||||
|
||||
|
||||
streamPool := tcpassembly.NewStreamPool(factory)
|
||||
assembler := tcpassembly.NewAssembler(streamPool)
|
||||
|
||||
|
||||
for _, fn := range flag.Args() {
|
||||
handle, err := pcap.OpenOffline(fn)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
|
||||
packets := packetSource.Packets()
|
||||
for packet := range packets {
|
||||
|
|
55
packet.go
55
packet.go
|
@ -4,16 +4,17 @@ import (
|
|||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/dirtbags/netshovel/gapstring"
|
||||
"strings"
|
||||
"time"
|
||||
"github.com/dirtbags/netshovel/gapstring"
|
||||
)
|
||||
|
||||
// Error returned by convenience methods that are unable to get enough data
|
||||
type ShortError struct {
|
||||
Wanted int // How many bytes you needed
|
||||
Wanted int // How many bytes you needed
|
||||
Available int // How many bytes were available
|
||||
}
|
||||
|
||||
func (e *ShortError) Error() string {
|
||||
return fmt.Sprintf("Short read: wanted %d of %d available", e.wanted, e.available)
|
||||
}
|
||||
|
@ -21,6 +22,7 @@ func (e *ShortError) Error() string {
|
|||
// Error returned by convenience methods that are unable to operate on gaps in data
|
||||
type MissingError struct {
|
||||
}
|
||||
|
||||
func (e *MissingError) Error() string {
|
||||
return "Operation on missing bytes"
|
||||
}
|
||||
|
@ -32,8 +34,8 @@ type namedField struct {
|
|||
|
||||
// An application protocol header field
|
||||
type headerField struct {
|
||||
name string
|
||||
bits int
|
||||
name string
|
||||
bits int
|
||||
value interface{}
|
||||
order binary.ByteOrder
|
||||
}
|
||||
|
@ -46,12 +48,12 @@ type headerField struct {
|
|||
// and
|
||||
// documenting header structure.
|
||||
type Packet struct {
|
||||
Opcode int
|
||||
Opcode int
|
||||
Description string
|
||||
When time.Time
|
||||
Payload gapstring.GapString
|
||||
header []headerField
|
||||
fields []namedField
|
||||
When time.Time
|
||||
Payload gapstring.GapString
|
||||
header []headerField
|
||||
fields []namedField
|
||||
}
|
||||
|
||||
var never = time.Unix(0, 0)
|
||||
|
@ -59,12 +61,12 @@ var never = time.Unix(0, 0)
|
|||
// Return a new packet
|
||||
func NewPacket() Packet {
|
||||
return Packet{
|
||||
Opcode: -1,
|
||||
Opcode: -1,
|
||||
Description: "Undefined",
|
||||
When: never,
|
||||
Payload: gapstring.GapString{},
|
||||
header: []headerField{},
|
||||
fields: []namedField{},
|
||||
When: never,
|
||||
Payload: gapstring.GapString{},
|
||||
header: []headerField{},
|
||||
fields: []namedField{},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,12 +78,12 @@ func (pkt *Packet) Describe() string {
|
|||
out := new(strings.Builder)
|
||||
|
||||
fmt.Fprintf(out, " %s Opcode %d: %s\n",
|
||||
pkt.When.UTC().Format(time.RFC3339Nano),
|
||||
pkt.When.UTC().Format(time.RFC3339Nano),
|
||||
pkt.Opcode,
|
||||
pkt.Description,
|
||||
)
|
||||
|
||||
for _, f := range(pkt.Fields) {
|
||||
|
||||
for _, f := range pkt.Fields {
|
||||
fmt.Fprintf(out, " %s: %s\n", f.key, f.value)
|
||||
}
|
||||
fmt.Fprint(out, pkt.Payload.Hexdump())
|
||||
|
@ -145,8 +147,8 @@ func (pkt *Packet) Peel(octets int) ([]byte, error) {
|
|||
// Add a field to the header field description
|
||||
func (pkt *Packet) AddHeaderField(order binary.ByteOrder, name string, bits int, value interface{}) {
|
||||
h := headerField{
|
||||
name: name,
|
||||
bits: bits,
|
||||
name: name,
|
||||
bits: bits,
|
||||
value: value,
|
||||
order: order,
|
||||
}
|
||||
|
@ -161,28 +163,28 @@ func (pkt *Packet) readUint(order binary.ByteOrder, bits int, name string) (inte
|
|||
case 32:
|
||||
case 64:
|
||||
default:
|
||||
return 0, fmt.Errorf("Weird number of bits: %d", bits)
|
||||
return 0, fmt.Errorf("Weird number of bits: %d", bits)
|
||||
}
|
||||
|
||||
|
||||
octets := bits >> 3
|
||||
b, err := pkt.Peel(octets)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
|
||||
var value interface{}
|
||||
switch bits {
|
||||
case 8:
|
||||
value = b[0]
|
||||
value = b[0]
|
||||
case 16:
|
||||
value = order.Uint16(b)
|
||||
case 32:
|
||||
value = order.Uint32(b)
|
||||
value = order.Uint32(b)
|
||||
case 64:
|
||||
value = order.Uint64(b)
|
||||
value = order.Uint64(b)
|
||||
}
|
||||
pkt.AddheaderField(order, name, bits, value)
|
||||
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
|
@ -248,4 +250,3 @@ func (pkt *Packet) Uint8(name string) (uint8, error) {
|
|||
}
|
||||
return value.(uint8), err
|
||||
}
|
||||
|
||||
|
|
54
stream.go
54
stream.go
|
@ -2,14 +2,14 @@ package netshovel
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
"github.com/dirtbags/netshovel/gapstring"
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/tcpassembly"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// A File and the path where it lives
|
||||
|
@ -34,8 +34,8 @@ type Utterance struct {
|
|||
// A Stream is one half of a two-way conversation
|
||||
type Stream struct {
|
||||
Net, Transport gopacket.Flow
|
||||
conversation chan Utterance
|
||||
pending Utterance
|
||||
conversation chan Utterance
|
||||
pending Utterance
|
||||
}
|
||||
|
||||
// Return a newly-built Stream
|
||||
|
@ -44,8 +44,8 @@ type Stream struct {
|
|||
// Use this to initialize the internal stuff netshovel needs.
|
||||
func NewStream(net, transport gopacket.Flow) Stream {
|
||||
return Stream{
|
||||
Net: net,
|
||||
Transport: transport,
|
||||
Net: net,
|
||||
Transport: transport,
|
||||
conversation: make(chan Utterance, 100),
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func (stream *Stream) Reassembled(rs []tcpassembly.Reassembly) {
|
|||
}
|
||||
ret.Data = ret.Data.AppendBytes(r.Bytes)
|
||||
}
|
||||
|
||||
|
||||
// Throw away utterances with no data (SYN, ACK, FIN, &c)
|
||||
if ret.Data.Length() > 0 {
|
||||
stream.conversation <- ret
|
||||
|
@ -90,7 +90,7 @@ func (stream *Stream) Read(length int) (Utterance, error) {
|
|||
if length == 0 {
|
||||
return Utterance{}, nil
|
||||
}
|
||||
|
||||
|
||||
// Special case: length=-1 means "give me the next utterance"
|
||||
if length == -1 {
|
||||
var ret Utterance
|
||||
|
@ -99,8 +99,8 @@ func (stream *Stream) Read(length int) (Utterance, error) {
|
|||
ret = stream.pending
|
||||
stream.pending.Data = gapstring.GapString{}
|
||||
} else {
|
||||
r, more := <- stream.conversation
|
||||
if ! more {
|
||||
r, more := <-stream.conversation
|
||||
if !more {
|
||||
err = io.EOF
|
||||
}
|
||||
ret = r
|
||||
|
@ -111,8 +111,8 @@ func (stream *Stream) Read(length int) (Utterance, error) {
|
|||
// Pull in utterances until we have enough data.
|
||||
// .When will always be the timestamp on the last received utterance
|
||||
for stream.pending.Data.Length() < length {
|
||||
u, more := <- stream.conversation
|
||||
if ! more {
|
||||
u, more := <-stream.conversation
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
stream.pending.Data = stream.pending.Data.Append(u.Data)
|
||||
|
@ -124,7 +124,7 @@ func (stream *Stream) Read(length int) (Utterance, error) {
|
|||
if pendingLen == 0 {
|
||||
return Utterance{}, io.EOF
|
||||
}
|
||||
|
||||
|
||||
sliceLen := length
|
||||
if sliceLen > pendingLen {
|
||||
sliceLen = pendingLen
|
||||
|
@ -145,9 +145,9 @@ func (stream *Stream) Describe(pkt Packet) string {
|
|||
|
||||
fmt.Fprintf(out, "%v:%v → %v:%v\n",
|
||||
stream.Net.Src().String(), stream.Transport.Src().String(),
|
||||
stream.Net.Dst().String(), stream.Transport.Dst().String(),
|
||||
)
|
||||
out.WriteString(pkt.Describe())
|
||||
stream.Net.Dst().String(), stream.Transport.Dst().String(),
|
||||
)
|
||||
out.WriteString(pkt.Describe())
|
||||
return out.String()
|
||||
}
|
||||
|
||||
|
@ -160,17 +160,17 @@ func (stream *Stream) Describe(pkt Packet) string {
|
|||
// Best practice is to pass in as full a path as you can find,
|
||||
// including drive letters and all parent directories.
|
||||
func (stream *Stream) CreateFile(when time.Time, path string) (NamedFile, error) {
|
||||
name := fmt.Sprintf(
|
||||
name := fmt.Sprintf(
|
||||
"xfer/%s,%sp%s,%sp%s,%s",
|
||||
when.UTC().Format(time.RFC3339Nano),
|
||||
stream.Net.Src().String(), stream.Transport.Src().String(),
|
||||
stream.Net.Dst().String(), stream.Transport.Dst().String(),
|
||||
stream.Net.Dst().String(), stream.Transport.Dst().String(),
|
||||
url.PathEscape(path),
|
||||
)
|
||||
f, err := os.Create(name)
|
||||
outf := NamedFile{
|
||||
File: f,
|
||||
Name: name,
|
||||
}
|
||||
return outf, err
|
||||
f, err := os.Create(name)
|
||||
outf := NamedFile{
|
||||
File: f,
|
||||
Name: name,
|
||||
}
|
||||
return outf, err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue