@@ -71,10 +71,17 @@ func decodemac(pkt []byte) uint64 {
7171
7272// Decode decodes the headers of a Packet.
7373func (p * Packet ) Decode () {
74+ if len (p .Data ) <= 14 {
75+ return
76+ }
77+
7478 p .Type = int (binary .BigEndian .Uint16 (p .Data [12 :14 ]))
7579 p .DestMac = decodemac (p .Data [0 :6 ])
7680 p .SrcMac = decodemac (p .Data [6 :12 ])
77- p .Payload = p .Data [14 :]
81+
82+ if len (p .Data ) >= 15 {
83+ p .Payload = p .Data [14 :]
84+ }
7885
7986 switch p .Type {
8087 case TYPE_IP :
@@ -163,20 +170,31 @@ func (arp *Arphdr) String() (s string) {
163170}
164171
165172func (p * Packet ) decodeArp () {
173+ if len (p .Payload ) < 8 {
174+ return
175+ }
176+
166177 pkt := p .Payload
167178 arp := new (Arphdr )
168179 arp .Addrtype = binary .BigEndian .Uint16 (pkt [0 :2 ])
169180 arp .Protocol = binary .BigEndian .Uint16 (pkt [2 :4 ])
170181 arp .HwAddressSize = pkt [4 ]
171182 arp .ProtAddressSize = pkt [5 ]
172183 arp .Operation = binary .BigEndian .Uint16 (pkt [6 :8 ])
184+
185+ if len (pkt ) < int (8 + 2 * arp .HwAddressSize + 2 * arp .ProtAddressSize ) {
186+ return
187+ }
173188 arp .SourceHwAddress = pkt [8 : 8 + arp .HwAddressSize ]
174189 arp .SourceProtAddress = pkt [8 + arp .HwAddressSize : 8 + arp .HwAddressSize + arp .ProtAddressSize ]
175190 arp .DestHwAddress = pkt [8 + arp .HwAddressSize + arp .ProtAddressSize : 8 + 2 * arp .HwAddressSize + arp .ProtAddressSize ]
176191 arp .DestProtAddress = pkt [8 + 2 * arp .HwAddressSize + arp .ProtAddressSize : 8 + 2 * arp .HwAddressSize + 2 * arp .ProtAddressSize ]
177192
178193 p .Headers = append (p .Headers , arp )
179- p .Payload = p .Payload [8 + 2 * arp .HwAddressSize + 2 * arp .ProtAddressSize :]
194+
195+ if len (pkt ) >= int (8 + 2 * arp .HwAddressSize + 2 * arp .ProtAddressSize ) {
196+ p .Payload = p .Payload [8 + 2 * arp .HwAddressSize + 2 * arp .ProtAddressSize :]
197+ }
180198}
181199
182200// IPadr is the header of an IP packet.
@@ -196,6 +214,10 @@ type Iphdr struct {
196214}
197215
198216func (p * Packet ) decodeIp () {
217+ if len (p .Payload ) < 20 {
218+ return
219+ }
220+
199221 pkt := p .Payload
200222 ip := new (Iphdr )
201223
@@ -212,11 +234,18 @@ func (p *Packet) decodeIp() {
212234 ip .Checksum = binary .BigEndian .Uint16 (pkt [10 :12 ])
213235 ip .SrcIp = pkt [12 :16 ]
214236 ip .DestIp = pkt [16 :20 ]
237+
215238 pEnd := int (ip .Length )
216239 if pEnd > len (pkt ) {
217240 pEnd = len (pkt )
218241 }
219- p .Payload = pkt [ip .Ihl * 4 : pEnd ]
242+
243+ if len (pkt ) >= pEnd && int (ip .Ihl * 4 ) < pEnd {
244+ p .Payload = pkt [ip .Ihl * 4 : pEnd ]
245+ } else {
246+ p .Payload = []byte {}
247+ }
248+
220249 p .Headers = append (p .Headers , ip )
221250 p .IP = ip
222251
@@ -250,12 +279,20 @@ func (v *Vlanhdr) String() {
250279func (p * Packet ) decodeVlan () {
251280 pkt := p .Payload
252281 vlan := new (Vlanhdr )
282+ if len (pkt ) < 4 {
283+ return
284+ }
285+
253286 vlan .Priority = (pkt [2 ] & 0xE0 ) >> 13
254287 vlan .DropEligible = pkt [2 ]& 0x10 != 0
255288 vlan .VlanIdentifier = int (binary .BigEndian .Uint16 (pkt [:2 ])) & 0x0FFF
256289 vlan .Type = int (binary .BigEndian .Uint16 (p .Payload [2 :4 ]))
257290 p .Headers = append (p .Headers , vlan )
258- p .Payload = p .Payload [4 :]
291+
292+ if len (pkt ) >= 5 {
293+ p .Payload = p .Payload [4 :]
294+ }
295+
259296 switch vlan .Type {
260297 case TYPE_IP :
261298 p .decodeIp ()
@@ -292,6 +329,10 @@ const (
292329)
293330
294331func (p * Packet ) decodeTcp () {
332+ if len (p .Payload ) < 20 {
333+ return
334+ }
335+
295336 pkt := p .Payload
296337 tcp := new (Tcphdr )
297338 tcp .SrcPort = binary .BigEndian .Uint16 (pkt [0 :2 ])
@@ -303,7 +344,9 @@ func (p *Packet) decodeTcp() {
303344 tcp .Window = binary .BigEndian .Uint16 (pkt [14 :16 ])
304345 tcp .Checksum = binary .BigEndian .Uint16 (pkt [16 :18 ])
305346 tcp .Urgent = binary .BigEndian .Uint16 (pkt [18 :20 ])
306- p .Payload = pkt [tcp .DataOffset * 4 :]
347+ if len (pkt ) >= int (tcp .DataOffset * 4 ) {
348+ p .Payload = pkt [tcp .DataOffset * 4 :]
349+ }
307350 p .Headers = append (p .Headers , tcp )
308351 p .TCP = tcp
309352}
@@ -354,6 +397,10 @@ type Udphdr struct {
354397}
355398
356399func (p * Packet ) decodeUdp () {
400+ if len (p .Payload ) < 8 {
401+ return
402+ }
403+
357404 pkt := p .Payload
358405 udp := new (Udphdr )
359406 udp .SrcPort = binary .BigEndian .Uint16 (pkt [0 :2 ])
@@ -362,7 +409,9 @@ func (p *Packet) decodeUdp() {
362409 udp .Checksum = binary .BigEndian .Uint16 (pkt [6 :8 ])
363410 p .Headers = append (p .Headers , udp )
364411 p .UDP = udp
365- p .Payload = pkt [8 :]
412+ if len (p .Payload ) >= 8 {
413+ p .Payload = pkt [8 :]
414+ }
366415}
367416
368417func (udp * Udphdr ) String (hdr addrHdr ) string {
@@ -381,6 +430,10 @@ type Icmphdr struct {
381430}
382431
383432func (p * Packet ) decodeIcmp () * Icmphdr {
433+ if len (p .Payload ) < 8 {
434+ return nil
435+ }
436+
384437 pkt := p .Payload
385438 icmp := new (Icmphdr )
386439 icmp .Type = pkt [0 ]
@@ -436,6 +489,10 @@ type Ip6hdr struct {
436489}
437490
438491func (p * Packet ) decodeIp6 () {
492+ if len (p .Payload ) < 40 {
493+ return
494+ }
495+
439496 pkt := p .Payload
440497 ip6 := new (Ip6hdr )
441498 ip6 .Version = uint8 (pkt [0 ]) >> 4
@@ -446,7 +503,11 @@ func (p *Packet) decodeIp6() {
446503 ip6 .HopLimit = pkt [7 ]
447504 ip6 .SrcIp = pkt [8 :24 ]
448505 ip6 .DestIp = pkt [24 :40 ]
449- p .Payload = pkt [40 :]
506+
507+ if len (p .Payload ) >= 40 {
508+ p .Payload = pkt [40 :]
509+ }
510+
450511 p .Headers = append (p .Headers , ip6 )
451512
452513 switch ip6 .NextHeader {
0 commit comments