2020-10-22 21:19:26 +01:00
|
|
|
package proxy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Packet struct {
|
|
|
|
Data []byte
|
|
|
|
timestamp time.Time
|
|
|
|
}
|
|
|
|
|
2020-10-23 10:24:20 +01:00
|
|
|
// create a packet from the raw data of an IP packet
|
2020-10-22 21:19:26 +01:00
|
|
|
func NewPacket(data []byte) Packet {
|
|
|
|
return Packet{
|
2020-10-25 15:36:34 +00:00
|
|
|
Data: data,
|
2020-10-22 21:19:26 +01:00
|
|
|
timestamp: time.Now(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-23 10:24:20 +01:00
|
|
|
// rebuild a packet from the wrapped format
|
|
|
|
func UnmarshalPacket(raw []byte, verifier MacVerifier) (Packet, error) {
|
2020-10-22 21:19:26 +01:00
|
|
|
// the MAC is the last N bytes
|
|
|
|
data := raw[:len(raw)-verifier.CodeLength()]
|
|
|
|
sum := raw[len(raw)-verifier.CodeLength():]
|
|
|
|
|
2020-10-23 10:24:20 +01:00
|
|
|
if err := verifier.Verify(data, sum); err != nil {
|
|
|
|
return Packet{}, err
|
2020-10-22 21:19:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
p := Packet{
|
2020-10-25 15:36:34 +00:00
|
|
|
Data: data[:len(data)-8],
|
2020-10-22 21:19:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
unixTime := int64(binary.LittleEndian.Uint64(data[len(data)-8:]))
|
|
|
|
p.timestamp = time.Unix(unixTime, 0)
|
|
|
|
|
2020-10-23 10:24:20 +01:00
|
|
|
return p, nil
|
2020-10-22 21:19:26 +01:00
|
|
|
}
|
|
|
|
|
2020-10-23 10:24:20 +01:00
|
|
|
// get the raw data of the IP packet
|
|
|
|
func (p Packet) Raw() []byte {
|
|
|
|
return p.Data
|
|
|
|
}
|
|
|
|
|
|
|
|
// produce the wrapped format of a packet
|
2020-10-22 21:19:26 +01:00
|
|
|
func (p Packet) Marshal(generator MacGenerator) []byte {
|
|
|
|
// length of data + length of timestamp (8 byte) + length of checksum
|
|
|
|
slice := make([]byte, len(p.Data)+8+generator.CodeLength())
|
|
|
|
|
|
|
|
copy(slice, p.Data)
|
|
|
|
|
|
|
|
unixTime := uint64(p.timestamp.Unix())
|
|
|
|
binary.LittleEndian.PutUint64(slice[len(p.Data):], unixTime)
|
|
|
|
|
|
|
|
mac := generator.Generate(slice)
|
|
|
|
copy(slice[len(p.Data)+8:], mac)
|
|
|
|
|
|
|
|
return slice
|
|
|
|
}
|