@@ -71,10 +71,17 @@ func decodemac(pkt []byte) uint64 {
71
71
72
72
// Decode decodes the headers of a Packet.
73
73
func (p * Packet ) Decode () {
74
+ if len (p .Data ) <= 14 {
75
+ return
76
+ }
77
+
74
78
p .Type = int (binary .BigEndian .Uint16 (p .Data [12 :14 ]))
75
79
p .DestMac = decodemac (p .Data [0 :6 ])
76
80
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
+ }
78
85
79
86
switch p .Type {
80
87
case TYPE_IP :
@@ -163,20 +170,31 @@ func (arp *Arphdr) String() (s string) {
163
170
}
164
171
165
172
func (p * Packet ) decodeArp () {
173
+ if len (p .Payload ) < 8 {
174
+ return
175
+ }
176
+
166
177
pkt := p .Payload
167
178
arp := new (Arphdr )
168
179
arp .Addrtype = binary .BigEndian .Uint16 (pkt [0 :2 ])
169
180
arp .Protocol = binary .BigEndian .Uint16 (pkt [2 :4 ])
170
181
arp .HwAddressSize = pkt [4 ]
171
182
arp .ProtAddressSize = pkt [5 ]
172
183
arp .Operation = binary .BigEndian .Uint16 (pkt [6 :8 ])
184
+
185
+ if len (pkt ) < int (8 + 2 * arp .HwAddressSize + 2 * arp .ProtAddressSize ) {
186
+ return
187
+ }
173
188
arp .SourceHwAddress = pkt [8 : 8 + arp .HwAddressSize ]
174
189
arp .SourceProtAddress = pkt [8 + arp .HwAddressSize : 8 + arp .HwAddressSize + arp .ProtAddressSize ]
175
190
arp .DestHwAddress = pkt [8 + arp .HwAddressSize + arp .ProtAddressSize : 8 + 2 * arp .HwAddressSize + arp .ProtAddressSize ]
176
191
arp .DestProtAddress = pkt [8 + 2 * arp .HwAddressSize + arp .ProtAddressSize : 8 + 2 * arp .HwAddressSize + 2 * arp .ProtAddressSize ]
177
192
178
193
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
+ }
180
198
}
181
199
182
200
// IPadr is the header of an IP packet.
@@ -196,6 +214,10 @@ type Iphdr struct {
196
214
}
197
215
198
216
func (p * Packet ) decodeIp () {
217
+ if len (p .Payload ) < 20 {
218
+ return
219
+ }
220
+
199
221
pkt := p .Payload
200
222
ip := new (Iphdr )
201
223
@@ -212,11 +234,18 @@ func (p *Packet) decodeIp() {
212
234
ip .Checksum = binary .BigEndian .Uint16 (pkt [10 :12 ])
213
235
ip .SrcIp = pkt [12 :16 ]
214
236
ip .DestIp = pkt [16 :20 ]
237
+
215
238
pEnd := int (ip .Length )
216
239
if pEnd > len (pkt ) {
217
240
pEnd = len (pkt )
218
241
}
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
+
220
249
p .Headers = append (p .Headers , ip )
221
250
p .IP = ip
222
251
@@ -250,12 +279,20 @@ func (v *Vlanhdr) String() {
250
279
func (p * Packet ) decodeVlan () {
251
280
pkt := p .Payload
252
281
vlan := new (Vlanhdr )
282
+ if len (pkt ) < 4 {
283
+ return
284
+ }
285
+
253
286
vlan .Priority = (pkt [2 ] & 0xE0 ) >> 13
254
287
vlan .DropEligible = pkt [2 ]& 0x10 != 0
255
288
vlan .VlanIdentifier = int (binary .BigEndian .Uint16 (pkt [:2 ])) & 0x0FFF
256
289
vlan .Type = int (binary .BigEndian .Uint16 (p .Payload [2 :4 ]))
257
290
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
+
259
296
switch vlan .Type {
260
297
case TYPE_IP :
261
298
p .decodeIp ()
@@ -292,6 +329,10 @@ const (
292
329
)
293
330
294
331
func (p * Packet ) decodeTcp () {
332
+ if len (p .Payload ) < 20 {
333
+ return
334
+ }
335
+
295
336
pkt := p .Payload
296
337
tcp := new (Tcphdr )
297
338
tcp .SrcPort = binary .BigEndian .Uint16 (pkt [0 :2 ])
@@ -303,7 +344,9 @@ func (p *Packet) decodeTcp() {
303
344
tcp .Window = binary .BigEndian .Uint16 (pkt [14 :16 ])
304
345
tcp .Checksum = binary .BigEndian .Uint16 (pkt [16 :18 ])
305
346
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
+ }
307
350
p .Headers = append (p .Headers , tcp )
308
351
p .TCP = tcp
309
352
}
@@ -354,6 +397,10 @@ type Udphdr struct {
354
397
}
355
398
356
399
func (p * Packet ) decodeUdp () {
400
+ if len (p .Payload ) < 8 {
401
+ return
402
+ }
403
+
357
404
pkt := p .Payload
358
405
udp := new (Udphdr )
359
406
udp .SrcPort = binary .BigEndian .Uint16 (pkt [0 :2 ])
@@ -362,7 +409,9 @@ func (p *Packet) decodeUdp() {
362
409
udp .Checksum = binary .BigEndian .Uint16 (pkt [6 :8 ])
363
410
p .Headers = append (p .Headers , udp )
364
411
p .UDP = udp
365
- p .Payload = pkt [8 :]
412
+ if len (p .Payload ) >= 8 {
413
+ p .Payload = pkt [8 :]
414
+ }
366
415
}
367
416
368
417
func (udp * Udphdr ) String (hdr addrHdr ) string {
@@ -381,6 +430,10 @@ type Icmphdr struct {
381
430
}
382
431
383
432
func (p * Packet ) decodeIcmp () * Icmphdr {
433
+ if len (p .Payload ) < 8 {
434
+ return nil
435
+ }
436
+
384
437
pkt := p .Payload
385
438
icmp := new (Icmphdr )
386
439
icmp .Type = pkt [0 ]
@@ -436,6 +489,10 @@ type Ip6hdr struct {
436
489
}
437
490
438
491
func (p * Packet ) decodeIp6 () {
492
+ if len (p .Payload ) < 40 {
493
+ return
494
+ }
495
+
439
496
pkt := p .Payload
440
497
ip6 := new (Ip6hdr )
441
498
ip6 .Version = uint8 (pkt [0 ]) >> 4
@@ -446,7 +503,11 @@ func (p *Packet) decodeIp6() {
446
503
ip6 .HopLimit = pkt [7 ]
447
504
ip6 .SrcIp = pkt [8 :24 ]
448
505
ip6 .DestIp = pkt [24 :40 ]
449
- p .Payload = pkt [40 :]
506
+
507
+ if len (p .Payload ) >= 40 {
508
+ p .Payload = pkt [40 :]
509
+ }
510
+
450
511
p .Headers = append (p .Headers , ip6 )
451
512
452
513
switch ip6 .NextHeader {
0 commit comments