Repository: secdev/scapy

Issue:
Pcapreader() does not work at specific packets and memory usage continues to increase
Scary version: scapy-2.4.0.dev149
Python version: Python 3.6.5
OS: Ubuntu 16.04.03 LTS

I try to read the attached pcap file using Pcapreader(), but Pcapreader() does not work after read a packet which timestamp is 1523958716.205101, and memory usage increases, finally, the process forcibly terminates. 

```
from scapy.all import *
with PcapReader('test.pcap') as pkts:
    for pkt in pkts:
        print(str(pkt.time) + ': ' + str(len(pkt)))
```

output
```
1523958716.093239: 82
1523958716.14647: 82
1523958716.159972: 98
1523958716.18894: 90
1523958716.201178: 90
1523958716.205101: 90
```

I also try to read the attached pcap file using dpkt and dpkt succeed in read the file.
```
import dpkt
with open('test.pcap', "rb") as f:
    pcr = dpkt.pcap.Reader(f)
    for t, buf in pcr:
        print(str(t) + ': ' + str(len(buf)))
        eth = dpkt.ethernet.Ethernet(buf)

        ip = eth.data
        src = ip.src
        dst = ip.dst
        src_a = socket.inet_ntoa(src)
        dst_a = socket.inet_ntoa(dst)
        print("Sorce IP :%s" % src_a)
        print("Dest IP :%s" % dst_a)
```

output
```
1523958716.093239: 82
Sorce IP :210.196.129.140
Dest IP :8.8.8.8
1523958716.14647: 82
Sorce IP :210.196.129.140
Dest IP :8.8.8.8
1523958716.159972: 98
Sorce IP :8.8.8.8
Dest IP :210.196.129.140
1523958716.18894: 90
Sorce IP :210.196.129.140
Dest IP :13.113.26.230
1523958716.201178: 90
Sorce IP :210.196.129.140
Dest IP :13.113.26.230
1523958716.205101: 90
Sorce IP :210.196.129.140
Dest IP :13.113.26.230
1523958716.209078: 90
Sorce IP :210.196.129.140
Dest IP :13.113.26.230
1523958716.213085: 90
Sorce IP :210.196.129.140
Dest IP :13.113.26.230


1523958716.453802: 114
Sorce IP :121.40.147.12
Dest IP :210.196.129.140
```



[test.pcap.zip](https://github.com/secdev/scapy/files/1990677/test.pcap.zip)



Discussion:

Resolving patch:
diff --git a/scapy/layers/eap.py b/scapy/layers/eap.py
--- a/scapy/layers/eap.py
+++ b/scapy/layers/eap.py
@@ -16,7 +16,7 @@
     ShortField, IntField, XIntField, ByteEnumField, StrLenField, XStrField,\
     XStrLenField, XStrFixedLenField, LenField, FieldLenField, PacketField,\
     PacketListField, ConditionalField, PadField
-from scapy.packet import Packet, bind_layers
+from scapy.packet import Packet, Padding, bind_layers
 from scapy.layers.l2 import SourceMACField, Ether, CookedLinux, GRE, SNAP
 from scapy.utils import issubtype
 from scapy.config import conf
@@ -279,6 +279,9 @@ def post_build(self, p, pay):
             p = p[:2] + chb((l >> 8) & 0xff) + chb(l & 0xff) + p[4:]
         return p + pay
 
+    def guess_payload_class(self, _):
+        return Padding
+
 
 class EAP_MD5(EAP):
     """
diff --git a/scapy/layers/radius.py b/scapy/layers/radius.py
--- a/scapy/layers/radius.py
+++ b/scapy/layers/radius.py
@@ -9,11 +9,10 @@
 """
 
 import struct
-import logging
 import hashlib
 import hmac
-from scapy.compat import *
-from scapy.packet import Packet, bind_layers
+from scapy.compat import orb, raw
+from scapy.packet import Packet, Padding, bind_layers
 from scapy.fields import ByteField, ByteEnumField, IntField, StrLenField,\
     XStrLenField, XStrFixedLenField, FieldLenField, PacketField,\
     PacketListField, IPField, MultiEnumField
@@ -278,6 +277,9 @@ def post_build(self, p, pay):
             p = p[:1] + struct.pack("!B", length) + p[2:]
         return p
 
+    def guess_payload_class(self, _):
+        return Padding
+
 
 class _SpecificRadiusAttr(RadiusAttribute):
     """
@@ -1055,32 +1057,6 @@ class RadiusAttr_Vendor_Specific(RadiusAttribute):
     ]
 
 
-class _RADIUSAttrPacketListField(PacketListField):
-    """
-    PacketListField handling a list of RADIUS attributes.
-    """
-
-    def getfield(self, pkt, s):
-        lst = []
-        length = None
-        ret = ""
-
-        if self.length_from is not None:
-            length = self.length_from(pkt)
-
-        if length is not None:
-            remain, ret = s[:length], s[length:]
-
-        while remain:
-            attr_len = orb(remain[1])
-            current = remain[:attr_len]
-            remain = remain[attr_len:]
-            packet = self.m2i(pkt, current)
-            lst.append(packet)
-
-        return remain + ret, lst
-
-
 # See IANA RADIUS Packet Type Codes registry
 _packet_codes = {
     1: "Access-Request",
@@ -1145,7 +1121,7 @@ class Radius(Packet):
             adjust=lambda pkt, x: len(pkt.attributes) + 20
         ),
         XStrFixedLenField("authenticator", "", 16),
-        _RADIUSAttrPacketListField(
+        PacketListField(
             "attributes",
             [],
             RadiusAttribute,


Test patch:
diff --git a/test/regression.uts b/test/regression.uts
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -8877,6 +8877,10 @@ l = PacketList(p)
 s = l.sessions()  # Crashed on commit: e42ecdc54556c4852ca06b1a6da6c1ccbf3f522e
 assert len(s) == 1
 
+= Issue GH#1407
+s = b"Z\xa5\xaaUZ\xa5\xaaU\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\xc5\x00\x00\x14'\x02\x00\x00\x001\x9a\xe44\xea4"
+isinstance(Radius(s), Radius)
+
 
 ############
 ############