Skip to content

Commit cb79f96

Browse files
parsing now creates new buffer for each packet
1 parent e0239c1 commit cb79f96

File tree

15 files changed

+123
-96
lines changed

15 files changed

+123
-96
lines changed

layers/arp.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -148,30 +148,32 @@ func (ap *ARPPacket) UnmarshalBinary(data []byte) error {
148148
if len(data) < headerSizeARP {
149149
return fmt.Errorf("minimum header size for ARP is %d bytes, got %d bytes", headerSizeARP, len(data))
150150
}
151-
ap.HardwareType = binary.BigEndian.Uint16(data[0:2])
152-
ap.ProtocolType = binary.BigEndian.Uint16(data[2:4])
151+
buf := make([]byte, 0, len(data))
152+
buf = append(buf, data...)
153+
ap.HardwareType = binary.BigEndian.Uint16(buf[0:2])
154+
ap.ProtocolType = binary.BigEndian.Uint16(buf[2:4])
153155
ap.ProtocolTypeDesc = ptypedesc(ap.ProtocolType)
154156
if ap.ProtocolTypeDesc == "Unknown" {
155157
return fmt.Errorf("unknown protocol type")
156158
}
157-
ap.Hlen = data[4]
158-
ap.Plen = data[5]
159-
op := Operation(binary.BigEndian.Uint16(data[6:8]))
159+
ap.Hlen = buf[4]
160+
ap.Plen = buf[5]
161+
op := Operation(binary.BigEndian.Uint16(buf[6:8]))
160162
opdesc := opdesc(op)
161163
if opdesc == "Unknown" {
162164
return fmt.Errorf("unknown operation")
163165
}
164166
ap.Op = &ARPOperation{Val: op, Desc: opdesc}
165167
hoffset := 8 + ap.Hlen
166-
ap.SenderMAC = net.HardwareAddr(data[8:hoffset])
168+
ap.SenderMAC = net.HardwareAddr(buf[8:hoffset])
167169
poffset := hoffset + ap.Plen
168170
var ok bool
169-
ap.SenderIP, ok = netip.AddrFromSlice(data[hoffset:poffset])
171+
ap.SenderIP, ok = netip.AddrFromSlice(buf[hoffset:poffset])
170172
if !ok {
171173
return fmt.Errorf("failed parsing sender IP address")
172174
}
173-
ap.TargetMAC = net.HardwareAddr(data[poffset : poffset+ap.Hlen])
174-
ap.TargetIP, ok = netip.AddrFromSlice(data[poffset+ap.Hlen : poffset+ap.Hlen+ap.Plen])
175+
ap.TargetMAC = net.HardwareAddr(buf[poffset : poffset+ap.Hlen])
176+
ap.TargetIP, ok = netip.AddrFromSlice(buf[poffset+ap.Hlen : poffset+ap.Hlen+ap.Plen])
175177
if !ok {
176178
return fmt.Errorf("failed parsing target IP address")
177179
}

layers/dns.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -241,14 +241,16 @@ func (d *DNSMessage) Parse(data []byte) error {
241241
if len(data) < headerSizeDNS {
242242
return fmt.Errorf("minimum header size for DNS is %d bytes, got %d bytes", headerSizeDNS, len(data))
243243
}
244-
d.TransactionID = binary.BigEndian.Uint16(data[0:2])
245-
d.Flags = newDNSFlags(binary.BigEndian.Uint16(data[2:4]))
246-
d.QDCount = binary.BigEndian.Uint16(data[4:6])
247-
d.ANCount = binary.BigEndian.Uint16(data[6:8])
248-
d.NSCount = binary.BigEndian.Uint16(data[8:10])
249-
d.ARCount = binary.BigEndian.Uint16(data[10:headerSizeDNS])
244+
buf := make([]byte, 0, len(data))
245+
buf = append(buf, data...)
246+
d.TransactionID = binary.BigEndian.Uint16(buf[0:2])
247+
d.Flags = newDNSFlags(binary.BigEndian.Uint16(buf[2:4]))
248+
d.QDCount = binary.BigEndian.Uint16(buf[4:6])
249+
d.ANCount = binary.BigEndian.Uint16(buf[6:8])
250+
d.NSCount = binary.BigEndian.Uint16(buf[8:10])
251+
d.ARCount = binary.BigEndian.Uint16(buf[10:headerSizeDNS])
250252
var tail []byte
251-
payload := data[headerSizeDNS:]
253+
payload := buf[headerSizeDNS:]
252254
d.Questions = nil
253255
d.AnswerRRs = nil
254256
d.AuthorityRRs = nil
@@ -459,7 +461,7 @@ type RDataSOA struct {
459461
}
460462

461463
func (d *RDataSOA) String() string {
462-
return fmt.Sprintf(`Primary name server: %s
464+
return fmt.Sprintf(`Primary name server: %s
463465
- Responsible authority's mailbox: %s
464466
- Serial number: %d
465467
- Refresh interval: %d
@@ -498,7 +500,6 @@ type RDataAAAA struct {
498500

499501
func (d *RDataAAAA) String() string {
500502
return fmt.Sprintf("Address: %s", d.Address)
501-
502503
}
503504

504505
type RDataOPT struct {
@@ -510,7 +511,7 @@ type RDataOPT struct {
510511
}
511512

512513
func (d *RDataOPT) String() string {
513-
return fmt.Sprintf(`UDP payload size: %d
514+
return fmt.Sprintf(`UDP payload size: %d
514515
- Higher bits in extended RCODE: %#02x
515516
- EDNS0 version: %d
516517
- Z: %d

layers/ethernet.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,14 @@ func (ef *EthernetFrame) UnmarshalBinary(data []byte) error {
9292
if len(data) < headerSizeEthernet {
9393
return fmt.Errorf("did not read a complete Ethernet frame, only %d bytes read", len(data))
9494
}
95-
ef.DstMAC = net.HardwareAddr(data[0:6])
96-
ef.SrcMAC = net.HardwareAddr(data[6:12])
97-
et := EtherType(binary.BigEndian.Uint16(data[12:14]))
95+
buf := make([]byte, 0, len(data))
96+
buf = append(buf, data...)
97+
ef.DstMAC = net.HardwareAddr(buf[0:6])
98+
ef.SrcMAC = net.HardwareAddr(buf[6:12])
99+
et := EtherType(binary.BigEndian.Uint16(buf[12:14]))
98100
etdesc := ethertypedesc(et)
99101
ef.EtherType = &EthernetType{Val: et, Desc: etdesc}
100-
ef.Payload = data[headerSizeEthernet:]
102+
ef.Payload = buf[headerSizeEthernet:]
101103
ef.DstVendor = oui.VendorWithMAC(ef.DstMAC)
102104
ef.SrcVendor = oui.VendorWithMAC(ef.SrcMAC)
103105
return nil

layers/ftp.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ func (f *FTPMessage) Summary() string {
2121
}
2222

2323
func (f *FTPMessage) Parse(data []byte) error {
24+
buf := make([]byte, 0, len(data))
25+
buf = append(buf, data...)
2426
f.summary = nil
2527
f.data = nil
26-
sp := bytes.Split(data, crlf)
28+
sp := bytes.Split(buf, crlf)
2729
lsp := len(sp)
2830
switch {
2931
case lsp > 2:

layers/http.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,21 +59,23 @@ func (h *HTTPMessage) Summary() string {
5959
}
6060

6161
func (h *HTTPMessage) Parse(data []byte) error {
62-
if !bytes.Contains(data, protohttp10) && !bytes.Contains(data, protohttp11) {
62+
buf := make([]byte, 0, len(data))
63+
buf = append(buf, data...)
64+
if !bytes.Contains(buf, protohttp10) && !bytes.Contains(buf, protohttp11) {
6365
h.Request = nil
6466
h.Response = nil
6567
return nil
6668
}
67-
reader := bufio.NewReader(bytes.NewReader(data))
68-
if bytes.HasPrefix(data, protohttp11) || bytes.HasPrefix(data, protohttp10) {
69+
reader := bufio.NewReader(bytes.NewReader(buf))
70+
if bytes.HasPrefix(buf, protohttp11) || bytes.HasPrefix(buf, protohttp10) {
6971
resp, err := http.ReadResponse(reader, nil)
7072
if err != nil {
7173
return err
7274
}
7375
h.Response = resp
7476
h.Request = nil
7577
} else {
76-
reader := bufio.NewReader(bytes.NewReader(data))
78+
reader := bufio.NewReader(bytes.NewReader(buf))
7779
req, err := http.ReadRequest(reader)
7880
if err != nil {
7981
return err

layers/icmp.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,12 @@ func (i *ICMPSegment) Parse(data []byte) error {
4646
if len(data) < headerSizeICMP {
4747
return fmt.Errorf("minimum header size for ICMP is %d bytes, got %d bytes", headerSizeICMP, len(data))
4848
}
49-
i.Type = data[0]
50-
i.Code = data[1]
51-
i.Checksum = binary.BigEndian.Uint16(data[2:4])
52-
i.Data = data[headerSizeICMP:]
49+
buf := make([]byte, 0, len(data))
50+
buf = append(buf, data...)
51+
i.Type = buf[0]
52+
i.Code = buf[1]
53+
i.Checksum = binary.BigEndian.Uint16(buf[2:4])
54+
i.Data = buf[headerSizeICMP:]
5355
var pLen int
5456
switch i.Type {
5557
case 0, 3, 5, 8, 11:

layers/icmpv6.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,12 @@ func (i *ICMPv6Segment) Parse(data []byte) error {
4444
if len(data) < headerSizeICMPv6 {
4545
return fmt.Errorf("minimum header size for ICMPv6 is %d bytes, got %d bytes", headerSizeICMPv6, len(data))
4646
}
47-
i.Type = data[0]
48-
i.Code = data[1]
49-
i.Checksum = binary.BigEndian.Uint16(data[2:headerSizeICMPv6])
50-
i.Data = data[headerSizeICMPv6:]
47+
buf := make([]byte, 0, len(data))
48+
buf = append(buf, data...)
49+
i.Type = buf[0]
50+
i.Code = buf[1]
51+
i.Checksum = binary.BigEndian.Uint16(buf[2:headerSizeICMPv6])
52+
i.Data = buf[headerSizeICMPv6:]
5153
var pLen int
5254
switch i.Type {
5355
case 1, 2, 3, 4, 128, 129, 133:

layers/ipv4.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -155,38 +155,40 @@ func (p *IPv4Packet) UnmarshalBinary(data []byte) error {
155155
if len(data) < headerSizeIPv4 {
156156
return fmt.Errorf("minimum header size for IPv4 is %d bytes, got %d bytes", headerSizeIPv4, len(data))
157157
}
158-
versionIHL := data[0]
158+
buf := make([]byte, 0, len(data))
159+
buf = append(buf, data...)
160+
versionIHL := buf[0]
159161
p.Version = versionIHL >> 4
160162
p.IHL = versionIHL & 15
161-
dscpECN := data[1]
163+
dscpECN := buf[1]
162164
p.DSCP = dscpECN >> 2
163165
p.DSCPDesc = dscpdesc(p.DSCP)
164166
p.ECN = dscpECN & 3
165-
p.TotalLength = binary.BigEndian.Uint16(data[2:4])
166-
p.Identification = binary.BigEndian.Uint16(data[4:6])
167-
flagsOffset := binary.BigEndian.Uint16(data[6:8])
167+
p.TotalLength = binary.BigEndian.Uint16(buf[2:4])
168+
p.Identification = binary.BigEndian.Uint16(buf[4:6])
169+
flagsOffset := binary.BigEndian.Uint16(buf[6:8])
168170
flags := uint8(flagsOffset >> 13)
169171
p.Flags = NewIPv4Flags(flags)
170172
p.FragmentOffset = flagsOffset & (1<<13 - 1)
171-
p.TTL = data[8]
172-
proto := IPProto(data[9])
173+
p.TTL = buf[8]
174+
proto := IPProto(buf[9])
173175
p.Protocol = &IPv4Proto{Val: proto, Desc: protodesc(proto)}
174-
p.HeaderChecksum = binary.BigEndian.Uint16(data[headerChecksumOffsetIPv4:12])
176+
p.HeaderChecksum = binary.BigEndian.Uint16(buf[headerChecksumOffsetIPv4:12])
175177
var ok bool
176-
p.SrcIP, ok = netip.AddrFromSlice(data[12:16])
178+
p.SrcIP, ok = netip.AddrFromSlice(buf[12:16])
177179
if !ok {
178180
return fmt.Errorf("malformed IPv4 address")
179181
}
180-
p.DstIP, ok = netip.AddrFromSlice(data[16:headerSizeIPv4])
182+
p.DstIP, ok = netip.AddrFromSlice(buf[16:headerSizeIPv4])
181183
if !ok {
182184
return fmt.Errorf("malformed IPv4 address")
183185
}
184186
if p.IHL > 5 {
185187
offset := headerSizeIPv4 + ((p.IHL - 5) << 2)
186-
p.Options = data[headerSizeIPv4:offset]
187-
p.Payload = data[offset:]
188+
p.Options = buf[headerSizeIPv4:offset]
189+
p.Payload = buf[offset:]
188190
} else {
189-
p.Payload = data[headerSizeIPv4:]
191+
p.Payload = buf[headerSizeIPv4:]
190192
}
191193
return nil
192194
}

layers/ipv6.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,19 @@ func (p *IPv6Packet) Parse(data []byte) error {
8080
if len(data) < headerSizeIPv6 {
8181
return fmt.Errorf("minimum header size for IPv6 is %d bytes, got %d bytes", headerSizeIPv6, len(data))
8282
}
83-
versionTrafficFlow := binary.BigEndian.Uint32(data[0:4])
83+
buf := make([]byte, 0, len(data))
84+
buf = append(buf, data...)
85+
versionTrafficFlow := binary.BigEndian.Uint32(buf[0:4])
8486
p.Version = uint8(versionTrafficFlow >> 28)
8587
p.TrafficClass = newTrafficiClass(uint8((versionTrafficFlow >> 20) & 0xFF))
8688
p.FlowLabel = versionTrafficFlow & (1<<20 - 1)
87-
p.PayloadLength = binary.BigEndian.Uint16(data[4:6])
88-
p.NextHeader = data[6]
89+
p.PayloadLength = binary.BigEndian.Uint16(buf[4:6])
90+
p.NextHeader = buf[6]
8991
p.NextHeaderDesc = p.nextHeader()
90-
p.HopLimit = data[7]
91-
p.SrcIP, _ = netip.AddrFromSlice(data[8:24])
92-
p.DstIP, _ = netip.AddrFromSlice(data[24:headerSizeIPv6])
93-
p.payload = data[headerSizeIPv6:]
92+
p.HopLimit = buf[7]
93+
p.SrcIP, _ = netip.AddrFromSlice(buf[8:24])
94+
p.DstIP, _ = netip.AddrFromSlice(buf[24:headerSizeIPv6])
95+
p.payload = buf[headerSizeIPv6:]
9496
return nil
9597
}
9698

layers/snmp.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ func (s *SNMPMessage) Summary() string {
1818
}
1919

2020
func (s *SNMPMessage) Parse(data []byte) error {
21-
s.Payload = data
21+
buf := make([]byte, 0, len(data))
22+
buf = append(buf, data...)
23+
s.Payload = buf
2224
return nil
2325
}
2426

0 commit comments

Comments
 (0)