|
|
|
@ -39,10 +39,10 @@ type ( |
|
|
|
|
// A d4 writer implements the io.Writer Interface by implementing Write() and Close()
|
|
|
|
|
// it accepts an io.Writer as sink
|
|
|
|
|
d4Writer struct { |
|
|
|
|
w io.Writer |
|
|
|
|
key []byte |
|
|
|
|
d4header []byte |
|
|
|
|
payload []byte |
|
|
|
|
w io.Writer |
|
|
|
|
key []byte |
|
|
|
|
fb []byte |
|
|
|
|
pb []byte |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
d4S struct { |
|
|
|
@ -122,7 +122,7 @@ func main() { |
|
|
|
|
|
|
|
|
|
if d4loadConfig(d4p) == true { |
|
|
|
|
if d4.dst.initHeader(d4p) == true { |
|
|
|
|
d4transfer(d4p) |
|
|
|
|
io.CopyBuffer(&d4.dst, d4.src, d4.dst.pb) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -202,6 +202,10 @@ func d4checkConfig(d4 *d4S) bool { |
|
|
|
|
f.Close() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Create the copy buffer
|
|
|
|
|
(*d4).dst.fb = make([]byte, HDR_SIZE+(*d4).conf.snaplen) |
|
|
|
|
(*d4).dst.pb = make([]byte, (*d4).conf.snaplen) |
|
|
|
|
|
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -214,107 +218,61 @@ func generateUUIDv4() []byte { |
|
|
|
|
return []byte(uuid[:]) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func d4transfer(d4 *d4S) { |
|
|
|
|
src := (*d4).src |
|
|
|
|
dst := (*d4).dst |
|
|
|
|
buf := make([]byte, (*d4).conf.snaplen) |
|
|
|
|
varybuf := make([]byte, 0) |
|
|
|
|
|
|
|
|
|
for { |
|
|
|
|
// Take a slice of snaplen
|
|
|
|
|
nread, err := src.Read(buf) |
|
|
|
|
if err != nil { |
|
|
|
|
// if EOF, we just wait for more data
|
|
|
|
|
if err != io.EOF { |
|
|
|
|
log.Fatal(err) |
|
|
|
|
} else if (*d4).debug { |
|
|
|
|
os.Exit(0) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// And push it into the d4writer -> sink chain
|
|
|
|
|
switch { |
|
|
|
|
case uint32(nread) == (*d4).conf.snaplen: |
|
|
|
|
dst.Write(buf) |
|
|
|
|
case nread > 0 && uint32(nread) < (*d4).conf.snaplen: |
|
|
|
|
varybuf = append(buf[:nread]) |
|
|
|
|
dst.Write(varybuf) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (d4w *d4Writer) Write(bs []byte) (int, error) { |
|
|
|
|
d4w.updateHeader(bs) |
|
|
|
|
d4w.payload = bs |
|
|
|
|
d4w.updateHMAC() |
|
|
|
|
// bs is pb
|
|
|
|
|
// zero out moving parts of the frame
|
|
|
|
|
copy(d4w.fb[18:62], make([]byte, 44)) |
|
|
|
|
copy(d4w.fb[62:], make([]byte, 62+len(bs))) |
|
|
|
|
// update headers
|
|
|
|
|
d4w.updateHeader(len(bs)) |
|
|
|
|
// Copy payload after the header
|
|
|
|
|
copy(d4w.fb[62:62+len(bs)], bs) |
|
|
|
|
// Now that the packet is complete, compute hmac
|
|
|
|
|
d4w.updateHMAC(len(bs)) |
|
|
|
|
// Eventually write binary in the sink
|
|
|
|
|
binary.Write(d4w.w, binary.LittleEndian, append(d4w.d4header, d4w.payload...)) |
|
|
|
|
err := binary.Write(d4w.w, binary.LittleEndian, d4w.fb[:62+len(bs)]) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Fatal(err) |
|
|
|
|
} |
|
|
|
|
return len(bs), nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO write go idiomatic err return values
|
|
|
|
|
func (d4w *d4Writer) updateHeader(bs []byte) bool { |
|
|
|
|
// zero out moving parts
|
|
|
|
|
copy(d4w.d4header[18:], make([]byte, 44)) |
|
|
|
|
func (d4w *d4Writer) updateHeader(lenbs int) bool { |
|
|
|
|
timeUnix := time.Now().Unix() |
|
|
|
|
ps := 18 |
|
|
|
|
pe := ps + TIMESTAMP_SIZE |
|
|
|
|
binary.LittleEndian.PutUint64(d4w.d4header[ps:pe], uint64(timeUnix)) |
|
|
|
|
// hmac is set to zero during hmac operations, so leave it alone
|
|
|
|
|
// still, we move the pointers
|
|
|
|
|
ps = pe |
|
|
|
|
pe = ps + HMAC_SIZE |
|
|
|
|
ps = pe |
|
|
|
|
pe = ps + 4 |
|
|
|
|
// Set payload size
|
|
|
|
|
binary.LittleEndian.PutUint32(d4w.d4header[ps:pe], uint32(len(bs))) |
|
|
|
|
binary.LittleEndian.PutUint64(d4w.fb[18:26], uint64(timeUnix)) |
|
|
|
|
binary.LittleEndian.PutUint32(d4w.fb[58:62], uint32(lenbs)) |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (d4w *d4Writer) updateHMAC() bool { |
|
|
|
|
func (d4w *d4Writer) updateHMAC(ps int) bool { |
|
|
|
|
h := hmac.New(sha256.New, d4w.key) |
|
|
|
|
// version
|
|
|
|
|
h.Write(d4w.d4header[0:1]) |
|
|
|
|
// type
|
|
|
|
|
h.Write(d4w.d4header[1:2]) |
|
|
|
|
// uuid
|
|
|
|
|
h.Write(d4w.d4header[2:18]) |
|
|
|
|
// timestamp
|
|
|
|
|
h.Write(d4w.d4header[18:26]) |
|
|
|
|
// hmac (0)
|
|
|
|
|
h.Write(d4w.fb[0:1]) |
|
|
|
|
h.Write(d4w.fb[1:2]) |
|
|
|
|
h.Write(d4w.fb[2:18]) |
|
|
|
|
h.Write(d4w.fb[18:26]) |
|
|
|
|
h.Write(make([]byte, 32)) |
|
|
|
|
// size
|
|
|
|
|
h.Write(d4w.d4header[58:]) |
|
|
|
|
// payload
|
|
|
|
|
h.Write(d4w.payload) |
|
|
|
|
// final hmac
|
|
|
|
|
copy(d4w.d4header[26:58], h.Sum(nil)) |
|
|
|
|
h.Write(d4w.fb[58:62]) |
|
|
|
|
h.Write(d4w.fb[62 : 62+ps]) |
|
|
|
|
copy(d4w.fb[26:58], h.Sum(nil)) |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (d4w *d4Writer) initHeader(d4 *d4S) bool { |
|
|
|
|
// zero out the header
|
|
|
|
|
d4w.d4header = make([]byte, HDR_SIZE) |
|
|
|
|
copy(d4w.fb[:HDR_SIZE], make([]byte, HDR_SIZE)) |
|
|
|
|
// put version a type into the header
|
|
|
|
|
d4w.d4header[0] = (*d4).conf.version |
|
|
|
|
d4w.d4header[1] = (*d4).conf.ttype |
|
|
|
|
d4w.fb[0] = (*d4).conf.version |
|
|
|
|
d4w.fb[1] = (*d4).conf.ttype |
|
|
|
|
// put uuid into the header
|
|
|
|
|
ps := 2 |
|
|
|
|
pe := ps + UUID_SIZE |
|
|
|
|
copy(d4w.d4header[ps:pe], (*d4).conf.uuid) |
|
|
|
|
copy(d4w.fb[2:18], (*d4).conf.uuid) |
|
|
|
|
// timestamp
|
|
|
|
|
timeUnix := time.Now().UnixNano() |
|
|
|
|
ps = pe |
|
|
|
|
pe = ps + TIMESTAMP_SIZE |
|
|
|
|
binary.LittleEndian.PutUint64(d4w.d4header[ps:pe], uint64(timeUnix)) |
|
|
|
|
binary.LittleEndian.PutUint64(d4w.fb[18:26], uint64(timeUnix)) |
|
|
|
|
// hmac is set to zero during hmac operations, so leave it alone
|
|
|
|
|
// still, we move the pointers
|
|
|
|
|
ps = pe |
|
|
|
|
pe = ps + HMAC_SIZE |
|
|
|
|
ps = pe |
|
|
|
|
pe = ps + 4 |
|
|
|
|
// init size of payload at 0
|
|
|
|
|
binary.LittleEndian.PutUint32(d4w.d4header[ps:pe], uint32(0)) |
|
|
|
|
infof(fmt.Sprintf("Initialized a %d bytes header:\n", len(d4w.d4header))) |
|
|
|
|
infof(fmt.Sprintf("%b\n", d4w.d4header)) |
|
|
|
|
binary.LittleEndian.PutUint32(d4w.fb[58:62], uint32(0)) |
|
|
|
|
infof(fmt.Sprintf("Initialized a %d bytes header:\n", HDR_SIZE)) |
|
|
|
|
infof(fmt.Sprintf("%b\n", d4w.fb[:HDR_SIZE])) |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|