Implement the Writer interface + io.CopyBuffer
parent
066f29e8d1
commit
3d5feca4e7
126
d4-goclient.go
126
d4-goclient.go
|
@ -39,10 +39,10 @@ type (
|
||||||
// A d4 writer implements the io.Writer Interface by implementing Write() and Close()
|
// A d4 writer implements the io.Writer Interface by implementing Write() and Close()
|
||||||
// it accepts an io.Writer as sink
|
// it accepts an io.Writer as sink
|
||||||
d4Writer struct {
|
d4Writer struct {
|
||||||
w io.Writer
|
w io.Writer
|
||||||
key []byte
|
key []byte
|
||||||
d4header []byte
|
fb []byte
|
||||||
payload []byte
|
pb []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
d4S struct {
|
d4S struct {
|
||||||
|
@ -122,7 +122,7 @@ func main() {
|
||||||
|
|
||||||
if d4loadConfig(d4p) == true {
|
if d4loadConfig(d4p) == true {
|
||||||
if d4.dst.initHeader(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()
|
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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,107 +218,61 @@ func generateUUIDv4() []byte {
|
||||||
return []byte(uuid[:])
|
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) {
|
func (d4w *d4Writer) Write(bs []byte) (int, error) {
|
||||||
d4w.updateHeader(bs)
|
// bs is pb
|
||||||
d4w.payload = bs
|
// zero out moving parts of the frame
|
||||||
d4w.updateHMAC()
|
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
|
// 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
|
return len(bs), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO write go idiomatic err return values
|
// TODO write go idiomatic err return values
|
||||||
func (d4w *d4Writer) updateHeader(bs []byte) bool {
|
func (d4w *d4Writer) updateHeader(lenbs int) bool {
|
||||||
// zero out moving parts
|
|
||||||
copy(d4w.d4header[18:], make([]byte, 44))
|
|
||||||
timeUnix := time.Now().Unix()
|
timeUnix := time.Now().Unix()
|
||||||
ps := 18
|
binary.LittleEndian.PutUint64(d4w.fb[18:26], uint64(timeUnix))
|
||||||
pe := ps + TIMESTAMP_SIZE
|
binary.LittleEndian.PutUint32(d4w.fb[58:62], uint32(lenbs))
|
||||||
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)))
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d4w *d4Writer) updateHMAC() bool {
|
func (d4w *d4Writer) updateHMAC(ps int) bool {
|
||||||
h := hmac.New(sha256.New, d4w.key)
|
h := hmac.New(sha256.New, d4w.key)
|
||||||
// version
|
h.Write(d4w.fb[0:1])
|
||||||
h.Write(d4w.d4header[0:1])
|
h.Write(d4w.fb[1:2])
|
||||||
// type
|
h.Write(d4w.fb[2:18])
|
||||||
h.Write(d4w.d4header[1:2])
|
h.Write(d4w.fb[18:26])
|
||||||
// uuid
|
|
||||||
h.Write(d4w.d4header[2:18])
|
|
||||||
// timestamp
|
|
||||||
h.Write(d4w.d4header[18:26])
|
|
||||||
// hmac (0)
|
|
||||||
h.Write(make([]byte, 32))
|
h.Write(make([]byte, 32))
|
||||||
// size
|
h.Write(d4w.fb[58:62])
|
||||||
h.Write(d4w.d4header[58:])
|
h.Write(d4w.fb[62 : 62+ps])
|
||||||
// payload
|
copy(d4w.fb[26:58], h.Sum(nil))
|
||||||
h.Write(d4w.payload)
|
|
||||||
// final hmac
|
|
||||||
copy(d4w.d4header[26:58], h.Sum(nil))
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d4w *d4Writer) initHeader(d4 *d4S) bool {
|
func (d4w *d4Writer) initHeader(d4 *d4S) bool {
|
||||||
// zero out the header
|
// 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
|
// put version a type into the header
|
||||||
d4w.d4header[0] = (*d4).conf.version
|
d4w.fb[0] = (*d4).conf.version
|
||||||
d4w.d4header[1] = (*d4).conf.ttype
|
d4w.fb[1] = (*d4).conf.ttype
|
||||||
// put uuid into the header
|
// put uuid into the header
|
||||||
ps := 2
|
copy(d4w.fb[2:18], (*d4).conf.uuid)
|
||||||
pe := ps + UUID_SIZE
|
|
||||||
copy(d4w.d4header[ps:pe], (*d4).conf.uuid)
|
|
||||||
// timestamp
|
// timestamp
|
||||||
timeUnix := time.Now().UnixNano()
|
timeUnix := time.Now().UnixNano()
|
||||||
ps = pe
|
binary.LittleEndian.PutUint64(d4w.fb[18:26], uint64(timeUnix))
|
||||||
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
|
// 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
|
// init size of payload at 0
|
||||||
binary.LittleEndian.PutUint32(d4w.d4header[ps:pe], uint32(0))
|
binary.LittleEndian.PutUint32(d4w.fb[58:62], uint32(0))
|
||||||
infof(fmt.Sprintf("Initialized a %d bytes header:\n", len(d4w.d4header)))
|
infof(fmt.Sprintf("Initialized a %d bytes header:\n", HDR_SIZE))
|
||||||
infof(fmt.Sprintf("%b\n", d4w.d4header))
|
infof(fmt.Sprintf("%b\n", d4w.fb[:HDR_SIZE]))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue