We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
"Generating sets of packets" (as explained in the documentation) does not work for mixed sequence and range (e.g. IP(ttl=[1,2,(5,9)]))
Hi,
as explained in the [tutorial](http://scapy.readthedocs.io/en/latest/usage.html#generating-sets-of-packets)  
these two lines 
`b=IP(ttl=[1,2,(5,9)])`
`[p for p in b]` 
should create a set of 7 packets, like
`[<IP ttl=1 |>, <IP ttl=2 |>, <IP ttl=5 |>, <IP ttl=6 |>, <IP ttl=7 |>, <IP ttl=8 |>, <IP ttl=9 |>]`.

But the result is just:
`[<IP  ttl=1 |>, <IP  ttl=2 |>, <IP  ttl=(5, 9) |>]`

If I just use a "sequence" (`IP(ttl=[1,2,5,7,9])`) or "range" (`IP(ttl=(1,9)`), the result is that I expected. 

So, there are recent changesin scpay and the documentation is outdated or Is this a bug or I'm just stupid ;) ?

Thanks!

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scapy/base_classes.py`
Content:
```
1 ## This file is part of Scapy
2 ## See http://www.secdev.org/projects/scapy for more informations
3 ## Copyright (C) Philippe Biondi <phil@secdev.org>
4 ## This program is published under a GPLv2 license
5 
6 """
7 Generators and packet meta classes.
8 """
9 
10 ###############
11 ## Generators ##
12 ################
13 
14 from __future__ import absolute_import
15 import re,random,socket
16 import types
17 from scapy.modules.six.moves import range
18 
19 class Gen(object):
20     __slots__ = []
21     def __iter__(self):
22         return iter([])
23     
24 class SetGen(Gen):
25     def __init__(self, values, _iterpacket=1):
26         self._iterpacket=_iterpacket
27         if isinstance(values, (list, BasePacketList)):
28             self.values = list(values)
29         elif (isinstance(values, tuple) and (2 <= len(values) <= 3) and \
30              all(hasattr(i, "__int__") for i in values)):
31             # We use values[1] + 1 as stop value for (x)range to maintain
32             # the behavior of using tuples as field `values`
33             self.values = [range(*((int(values[0]), int(values[1]) + 1)
34                                     + tuple(int(v) for v in values[2:])))]
35         else:
36             self.values = [values]
37     def transf(self, element):
38         return element
39     def __iter__(self):
40         for i in self.values:
41             if (isinstance(i, Gen) and
42                 (self._iterpacket or not isinstance(i,BasePacket))) or (
43                     isinstance(i, (range, types.GeneratorType))):
44                 for j in i:
45                     yield j
46             else:
47                 yield i
48     def __repr__(self):
49         return "<SetGen %r>" % self.values
50 
51 class Net(Gen):
52     """Generate a list of IPs from a network address or a name"""
53     name = "ip"
54     ip_regex = re.compile(r"^(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)(/[0-3]?[0-9])?$")
55 
56     @staticmethod
57     def _parse_digit(a,netmask):
58         netmask = min(8,max(netmask,0))
59         if a == "*":
60             a = (0,256)
61         elif a.find("-") >= 0:
62             x, y = [int(d) for d in a.split('-')]
63             if x > y:
64                 y = x
65             a = (x &  (0xff<<netmask) , max(y, (x | (0xff>>(8-netmask))))+1)
66         else:
67             a = (int(a) & (0xff<<netmask),(int(a) | (0xff>>(8-netmask)))+1)
68         return a
69 
70     @classmethod
71     def _parse_net(cls, net):
72         tmp=net.split('/')+["32"]
73         if not cls.ip_regex.match(net):
74             tmp[0]=socket.gethostbyname(tmp[0])
75         netmask = int(tmp[1])
76         ret_list = [cls._parse_digit(x, y-netmask) for (x, y) in zip(tmp[0].split('.'), [8, 16, 24, 32])]
77         return ret_list, netmask
78 
79     def __init__(self, net):
80         self.repr=net
81         self.parsed,self.netmask = self._parse_net(net)
82 
83     def __str__(self):
84         try:
85             return next(self.__iter__())
86         except StopIteration:
87             return None
88                                                                                                
89     def __iter__(self):
90         for d in range(*self.parsed[3]):
91             for c in range(*self.parsed[2]):
92                 for b in range(*self.parsed[1]):
93                     for a in range(*self.parsed[0]):
94                         yield "%i.%i.%i.%i" % (a,b,c,d)
95     def choice(self):
96         ip = []
97         for v in self.parsed:
98             ip.append(str(random.randint(v[0],v[1]-1)))
99         return ".".join(ip) 
100                           
101     def __repr__(self):
102         return "Net(%r)" % self.repr
103     def __eq__(self, other):
104         if hasattr(other, "parsed"):
105             p2 = other.parsed
106         else:
107             p2,nm2 = self._parse_net(other)
108         return self.parsed == p2
109     def __contains__(self, other):
110         if hasattr(other, "parsed"):
111             p2 = other.parsed
112         else:
113             p2,nm2 = self._parse_net(other)
114         for (a1,b1),(a2,b2) in zip(self.parsed,p2):
115             if a1 > a2 or b1 < b2:
116                 return False
117         return True
118     def __rcontains__(self, other):        
119         return self in self.__class__(other)
120         
121 
122 class OID(Gen):
123     name = "OID"
124     def __init__(self, oid):
125         self.oid = oid        
126         self.cmpt = []
127         fmt = []        
128         for i in oid.split("."):
129             if "-" in i:
130                 fmt.append("%i")
131                 self.cmpt.append(tuple(map(int, i.split("-"))))
132             else:
133                 fmt.append(i)
134         self.fmt = ".".join(fmt)
135     def __repr__(self):
136         return "OID(%r)" % self.oid
137     def __iter__(self):        
138         ii = [k[0] for k in self.cmpt]
139         while True:
140             yield self.fmt % tuple(ii)
141             i = 0
142             while True:
143                 if i >= len(ii):
144                     raise StopIteration
145                 if ii[i] < self.cmpt[i][1]:
146                     ii[i]+=1
147                     break
148                 else:
149                     ii[i] = self.cmpt[i][0]
150                 i += 1
151 
152 
153  
154 ######################################
155 ## Packet abstract and base classes ##
156 ######################################
157 
158 class Packet_metaclass(type):
159     def __new__(cls, name, bases, dct):
160         if "fields_desc" in dct: # perform resolution of references to other packets
161             current_fld = dct["fields_desc"]
162             resolved_fld = []
163             for f in current_fld:
164                 if isinstance(f, Packet_metaclass): # reference to another fields_desc
165                     for f2 in f.fields_desc:
166                         resolved_fld.append(f2)
167                 else:
168                     resolved_fld.append(f)
169         else: # look for a fields_desc in parent classes
170             resolved_fld = None
171             for b in bases:
172                 if hasattr(b,"fields_desc"):
173                     resolved_fld = b.fields_desc
174                     break
175 
176         if resolved_fld: # perform default value replacements
177             final_fld = []
178             for f in resolved_fld:
179                 if f.name in dct:
180                     f = f.copy()
181                     f.default = dct[f.name]
182                     del(dct[f.name])
183                 final_fld.append(f)
184 
185             dct["fields_desc"] = final_fld
186 
187         if "__slots__" not in dct:
188             dct["__slots__"] = []
189         for attr in ["name", "overload_fields"]:
190             try:
191                 dct["_%s" % attr] = dct.pop(attr)
192             except KeyError:
193                 pass
194         newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct)
195         newcls.__all_slots__ = set(
196             attr
197             for cls in newcls.__mro__ if hasattr(cls, "__slots__")
198             for attr in cls.__slots__
199         )
200 
201         if hasattr(newcls, "aliastypes"):
202             newcls.aliastypes = [newcls] + newcls.aliastypes
203         else:
204             newcls.aliastypes = [newcls]
205 
206         if hasattr(newcls,"register_variant"):
207             newcls.register_variant()
208         for f in newcls.fields_desc:
209             if hasattr(f, "register_owner"):
210                 f.register_owner(newcls)
211         from scapy import config
212         config.conf.layers.register(newcls)
213         return newcls
214 
215     def __getattr__(self, attr):
216         for k in self.fields_desc:
217             if k.name == attr:
218                 return k
219         raise AttributeError(attr)
220 
221     def __call__(cls, *args, **kargs):
222         if "dispatch_hook" in cls.__dict__:
223             try:
224                 cls = cls.dispatch_hook(*args, **kargs)
225             except:
226                 from scapy import config
227                 if config.conf.debug_dissector:
228                     raise
229                 cls = config.conf.raw_layer
230         i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)
231         i.__init__(*args, **kargs)
232         return i
233 
234 class Field_metaclass(type):
235     def __new__(cls, name, bases, dct):
236         if "__slots__" not in dct:
237             dct["__slots__"] = []
238         newcls = super(Field_metaclass, cls).__new__(cls, name, bases, dct)
239         return newcls
240 
241 class NewDefaultValues(Packet_metaclass):
242     """NewDefaultValues is deprecated (not needed anymore)
243     
244     remove this:
245         __metaclass__ = NewDefaultValues
246     and it should still work.
247     """    
248     def __new__(cls, name, bases, dct):
249         from scapy.error import log_loading
250         import traceback
251         try:
252             for tb in traceback.extract_stack()+[("??",-1,None,"")]:
253                 f,l,_,line = tb
254                 if line.startswith("class"):
255                     break
256         except:
257             f,l="??",-1
258             raise
259         log_loading.warning("Deprecated (no more needed) use of NewDefaultValues  (%s l. %i).", f, l)
260         
261         return super(NewDefaultValues, cls).__new__(cls, name, bases, dct)
262 
263 class BasePacket(Gen):
264     __slots__ = []
265 
266 
267 #############################
268 ## Packet list base class  ##
269 #############################
270 
271 class BasePacketList(object):
272     __slots__ = []
273
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/scapy/base_classes.py b/scapy/base_classes.py
--- a/scapy/base_classes.py
+++ b/scapy/base_classes.py
@@ -20,20 +20,29 @@
     __slots__ = []
     def __iter__(self):
         return iter([])
-    
+
+
+def _get_values(value):
+    """Generate a range object from (start, stop[, step]) tuples, or
+return value.
+
+    """
+    if (isinstance(value, tuple) and (2 <= len(value) <= 3) and \
+        all(hasattr(i, "__int__") for i in value)):
+        # We use values[1] + 1 as stop value for (x)range to maintain
+        # the behavior of using tuples as field `values`
+        return range(*((int(value[0]), int(value[1]) + 1)
+                       + tuple(int(v) for v in value[2:])))
+    return value
+
+
 class SetGen(Gen):
     def __init__(self, values, _iterpacket=1):
         self._iterpacket=_iterpacket
         if isinstance(values, (list, BasePacketList)):
-            self.values = list(values)
-        elif (isinstance(values, tuple) and (2 <= len(values) <= 3) and \
-             all(hasattr(i, "__int__") for i in values)):
-            # We use values[1] + 1 as stop value for (x)range to maintain
-            # the behavior of using tuples as field `values`
-            self.values = [range(*((int(values[0]), int(values[1]) + 1)
-                                    + tuple(int(v) for v in values[2:])))]
+            self.values = [_get_values(val) for val in values]
         else:
-            self.values = [values]
+            self.values = [_get_values(values)]
     def transf(self, element):
         return element
     def __iter__(self):

{"golden_diff": "diff --git a/scapy/base_classes.py b/scapy/base_classes.py\n--- a/scapy/base_classes.py\n+++ b/scapy/base_classes.py\n@@ -20,20 +20,29 @@\n     __slots__ = []\n     def __iter__(self):\n         return iter([])\n-    \n+\n+\n+def _get_values(value):\n+    \"\"\"Generate a range object from (start, stop[, step]) tuples, or\n+return value.\n+\n+    \"\"\"\n+    if (isinstance(value, tuple) and (2 <= len(value) <= 3) and \\\n+        all(hasattr(i, \"__int__\") for i in value)):\n+        # We use values[1] + 1 as stop value for (x)range to maintain\n+        # the behavior of using tuples as field `values`\n+        return range(*((int(value[0]), int(value[1]) + 1)\n+                       + tuple(int(v) for v in value[2:])))\n+    return value\n+\n+\n class SetGen(Gen):\n     def __init__(self, values, _iterpacket=1):\n         self._iterpacket=_iterpacket\n         if isinstance(values, (list, BasePacketList)):\n-            self.values = list(values)\n-        elif (isinstance(values, tuple) and (2 <= len(values) <= 3) and \\\n-             all(hasattr(i, \"__int__\") for i in values)):\n-            # We use values[1] + 1 as stop value for (x)range to maintain\n-            # the behavior of using tuples as field `values`\n-            self.values = [range(*((int(values[0]), int(values[1]) + 1)\n-                                    + tuple(int(v) for v in values[2:])))]\n+            self.values = [_get_values(val) for val in values]\n         else:\n-            self.values = [values]\n+            self.values = [_get_values(values)]\n     def transf(self, element):\n         return element\n     def __iter__(self):\n", "issue": "\"Generating sets of packets\" (as explained in the documentation) does not work for mixed sequence and range (e.g. IP(ttl=[1,2,(5,9)]))\nHi,\r\nas explained in the [tutorial](http://scapy.readthedocs.io/en/latest/usage.html#generating-sets-of-packets)  \r\nthese two lines \r\n`b=IP(ttl=[1,2,(5,9)])`\r\n`[p for p in b]` \r\nshould create a set of 7 packets, like\r\n`[<IP ttl=1 |>, <IP ttl=2 |>, <IP ttl=5 |>, <IP ttl=6 |>, <IP ttl=7 |>, <IP ttl=8 |>, <IP ttl=9 |>]`.\r\n\r\nBut the result is just:\r\n`[<IP  ttl=1 |>, <IP  ttl=2 |>, <IP  ttl=(5, 9) |>]`\r\n\r\nIf I just use a \"sequence\" (`IP(ttl=[1,2,5,7,9])`) or \"range\" (`IP(ttl=(1,9)`), the result is that I expected. \r\n\r\nSo, there are recent changesin scpay and the documentation is outdated or Is this a bug or I'm just stupid ;) ?\r\n\r\nThanks!\n", "before_files": [{"content": "## This file is part of Scapy\n## See http://www.secdev.org/projects/scapy for more informations\n## Copyright (C) Philippe Biondi <phil@secdev.org>\n## This program is published under a GPLv2 license\n\n\"\"\"\nGenerators and packet meta classes.\n\"\"\"\n\n###############\n## Generators ##\n################\n\nfrom __future__ import absolute_import\nimport re,random,socket\nimport types\nfrom scapy.modules.six.moves import range\n\nclass Gen(object):\n    __slots__ = []\n    def __iter__(self):\n        return iter([])\n    \nclass SetGen(Gen):\n    def __init__(self, values, _iterpacket=1):\n        self._iterpacket=_iterpacket\n        if isinstance(values, (list, BasePacketList)):\n            self.values = list(values)\n        elif (isinstance(values, tuple) and (2 <= len(values) <= 3) and \\\n             all(hasattr(i, \"__int__\") for i in values)):\n            # We use values[1] + 1 as stop value for (x)range to maintain\n            # the behavior of using tuples as field `values`\n            self.values = [range(*((int(values[0]), int(values[1]) + 1)\n                                    + tuple(int(v) for v in values[2:])))]\n        else:\n            self.values = [values]\n    def transf(self, element):\n        return element\n    def __iter__(self):\n        for i in self.values:\n            if (isinstance(i, Gen) and\n                (self._iterpacket or not isinstance(i,BasePacket))) or (\n                    isinstance(i, (range, types.GeneratorType))):\n                for j in i:\n                    yield j\n            else:\n                yield i\n    def __repr__(self):\n        return \"<SetGen %r>\" % self.values\n\nclass Net(Gen):\n    \"\"\"Generate a list of IPs from a network address or a name\"\"\"\n    name = \"ip\"\n    ip_regex = re.compile(r\"^(\\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\\.(\\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\\.(\\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\\.(\\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)(/[0-3]?[0-9])?$\")\n\n    @staticmethod\n    def _parse_digit(a,netmask):\n        netmask = min(8,max(netmask,0))\n        if a == \"*\":\n            a = (0,256)\n        elif a.find(\"-\") >= 0:\n            x, y = [int(d) for d in a.split('-')]\n            if x > y:\n                y = x\n            a = (x &  (0xff<<netmask) , max(y, (x | (0xff>>(8-netmask))))+1)\n        else:\n            a = (int(a) & (0xff<<netmask),(int(a) | (0xff>>(8-netmask)))+1)\n        return a\n\n    @classmethod\n    def _parse_net(cls, net):\n        tmp=net.split('/')+[\"32\"]\n        if not cls.ip_regex.match(net):\n            tmp[0]=socket.gethostbyname(tmp[0])\n        netmask = int(tmp[1])\n        ret_list = [cls._parse_digit(x, y-netmask) for (x, y) in zip(tmp[0].split('.'), [8, 16, 24, 32])]\n        return ret_list, netmask\n\n    def __init__(self, net):\n        self.repr=net\n        self.parsed,self.netmask = self._parse_net(net)\n\n    def __str__(self):\n        try:\n            return next(self.__iter__())\n        except StopIteration:\n            return None\n                                                                                               \n    def __iter__(self):\n        for d in range(*self.parsed[3]):\n            for c in range(*self.parsed[2]):\n                for b in range(*self.parsed[1]):\n                    for a in range(*self.parsed[0]):\n                        yield \"%i.%i.%i.%i\" % (a,b,c,d)\n    def choice(self):\n        ip = []\n        for v in self.parsed:\n            ip.append(str(random.randint(v[0],v[1]-1)))\n        return \".\".join(ip) \n                          \n    def __repr__(self):\n        return \"Net(%r)\" % self.repr\n    def __eq__(self, other):\n        if hasattr(other, \"parsed\"):\n            p2 = other.parsed\n        else:\n            p2,nm2 = self._parse_net(other)\n        return self.parsed == p2\n    def __contains__(self, other):\n        if hasattr(other, \"parsed\"):\n            p2 = other.parsed\n        else:\n            p2,nm2 = self._parse_net(other)\n        for (a1,b1),(a2,b2) in zip(self.parsed,p2):\n            if a1 > a2 or b1 < b2:\n                return False\n        return True\n    def __rcontains__(self, other):        \n        return self in self.__class__(other)\n        \n\nclass OID(Gen):\n    name = \"OID\"\n    def __init__(self, oid):\n        self.oid = oid        \n        self.cmpt = []\n        fmt = []        \n        for i in oid.split(\".\"):\n            if \"-\" in i:\n                fmt.append(\"%i\")\n                self.cmpt.append(tuple(map(int, i.split(\"-\"))))\n            else:\n                fmt.append(i)\n        self.fmt = \".\".join(fmt)\n    def __repr__(self):\n        return \"OID(%r)\" % self.oid\n    def __iter__(self):        \n        ii = [k[0] for k in self.cmpt]\n        while True:\n            yield self.fmt % tuple(ii)\n            i = 0\n            while True:\n                if i >= len(ii):\n                    raise StopIteration\n                if ii[i] < self.cmpt[i][1]:\n                    ii[i]+=1\n                    break\n                else:\n                    ii[i] = self.cmpt[i][0]\n                i += 1\n\n\n \n######################################\n## Packet abstract and base classes ##\n######################################\n\nclass Packet_metaclass(type):\n    def __new__(cls, name, bases, dct):\n        if \"fields_desc\" in dct: # perform resolution of references to other packets\n            current_fld = dct[\"fields_desc\"]\n            resolved_fld = []\n            for f in current_fld:\n                if isinstance(f, Packet_metaclass): # reference to another fields_desc\n                    for f2 in f.fields_desc:\n                        resolved_fld.append(f2)\n                else:\n                    resolved_fld.append(f)\n        else: # look for a fields_desc in parent classes\n            resolved_fld = None\n            for b in bases:\n                if hasattr(b,\"fields_desc\"):\n                    resolved_fld = b.fields_desc\n                    break\n\n        if resolved_fld: # perform default value replacements\n            final_fld = []\n            for f in resolved_fld:\n                if f.name in dct:\n                    f = f.copy()\n                    f.default = dct[f.name]\n                    del(dct[f.name])\n                final_fld.append(f)\n\n            dct[\"fields_desc\"] = final_fld\n\n        if \"__slots__\" not in dct:\n            dct[\"__slots__\"] = []\n        for attr in [\"name\", \"overload_fields\"]:\n            try:\n                dct[\"_%s\" % attr] = dct.pop(attr)\n            except KeyError:\n                pass\n        newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct)\n        newcls.__all_slots__ = set(\n            attr\n            for cls in newcls.__mro__ if hasattr(cls, \"__slots__\")\n            for attr in cls.__slots__\n        )\n\n        if hasattr(newcls, \"aliastypes\"):\n            newcls.aliastypes = [newcls] + newcls.aliastypes\n        else:\n            newcls.aliastypes = [newcls]\n\n        if hasattr(newcls,\"register_variant\"):\n            newcls.register_variant()\n        for f in newcls.fields_desc:\n            if hasattr(f, \"register_owner\"):\n                f.register_owner(newcls)\n        from scapy import config\n        config.conf.layers.register(newcls)\n        return newcls\n\n    def __getattr__(self, attr):\n        for k in self.fields_desc:\n            if k.name == attr:\n                return k\n        raise AttributeError(attr)\n\n    def __call__(cls, *args, **kargs):\n        if \"dispatch_hook\" in cls.__dict__:\n            try:\n                cls = cls.dispatch_hook(*args, **kargs)\n            except:\n                from scapy import config\n                if config.conf.debug_dissector:\n                    raise\n                cls = config.conf.raw_layer\n        i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)\n        i.__init__(*args, **kargs)\n        return i\n\nclass Field_metaclass(type):\n    def __new__(cls, name, bases, dct):\n        if \"__slots__\" not in dct:\n            dct[\"__slots__\"] = []\n        newcls = super(Field_metaclass, cls).__new__(cls, name, bases, dct)\n        return newcls\n\nclass NewDefaultValues(Packet_metaclass):\n    \"\"\"NewDefaultValues is deprecated (not needed anymore)\n    \n    remove this:\n        __metaclass__ = NewDefaultValues\n    and it should still work.\n    \"\"\"    \n    def __new__(cls, name, bases, dct):\n        from scapy.error import log_loading\n        import traceback\n        try:\n            for tb in traceback.extract_stack()+[(\"??\",-1,None,\"\")]:\n                f,l,_,line = tb\n                if line.startswith(\"class\"):\n                    break\n        except:\n            f,l=\"??\",-1\n            raise\n        log_loading.warning(\"Deprecated (no more needed) use of NewDefaultValues  (%s l. %i).\", f, l)\n        \n        return super(NewDefaultValues, cls).__new__(cls, name, bases, dct)\n\nclass BasePacket(Gen):\n    __slots__ = []\n\n\n#############################\n## Packet list base class  ##\n#############################\n\nclass BasePacketList(object):\n    __slots__ = []\n", "path": "scapy/base_classes.py"}], "after_files": [{"content": "## This file is part of Scapy\n## See http://www.secdev.org/projects/scapy for more informations\n## Copyright (C) Philippe Biondi <phil@secdev.org>\n## This program is published under a GPLv2 license\n\n\"\"\"\nGenerators and packet meta classes.\n\"\"\"\n\n###############\n## Generators ##\n################\n\nfrom __future__ import absolute_import\nimport re,random,socket\nimport types\nfrom scapy.modules.six.moves import range\n\nclass Gen(object):\n    __slots__ = []\n    def __iter__(self):\n        return iter([])\n\n\ndef _get_values(value):\n    \"\"\"Generate a range object from (start, stop[, step]) tuples, or\nreturn value.\n\n    \"\"\"\n    if (isinstance(value, tuple) and (2 <= len(value) <= 3) and \\\n        all(hasattr(i, \"__int__\") for i in value)):\n        # We use values[1] + 1 as stop value for (x)range to maintain\n        # the behavior of using tuples as field `values`\n        return range(*((int(value[0]), int(value[1]) + 1)\n                       + tuple(int(v) for v in value[2:])))\n    return value\n\n\nclass SetGen(Gen):\n    def __init__(self, values, _iterpacket=1):\n        self._iterpacket=_iterpacket\n        if isinstance(values, (list, BasePacketList)):\n            self.values = [_get_values(val) for val in values]\n        else:\n            self.values = [_get_values(values)]\n    def transf(self, element):\n        return element\n    def __iter__(self):\n        for i in self.values:\n            if (isinstance(i, Gen) and\n                (self._iterpacket or not isinstance(i,BasePacket))) or (\n                    isinstance(i, (range, types.GeneratorType))):\n                for j in i:\n                    yield j\n            else:\n                yield i\n    def __repr__(self):\n        return \"<SetGen %r>\" % self.values\n\nclass Net(Gen):\n    \"\"\"Generate a list of IPs from a network address or a name\"\"\"\n    name = \"ip\"\n    ip_regex = re.compile(r\"^(\\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\\.(\\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\\.(\\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\\.(\\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)(/[0-3]?[0-9])?$\")\n\n    @staticmethod\n    def _parse_digit(a,netmask):\n        netmask = min(8,max(netmask,0))\n        if a == \"*\":\n            a = (0,256)\n        elif a.find(\"-\") >= 0:\n            x, y = [int(d) for d in a.split('-')]\n            if x > y:\n                y = x\n            a = (x &  (0xff<<netmask) , max(y, (x | (0xff>>(8-netmask))))+1)\n        else:\n            a = (int(a) & (0xff<<netmask),(int(a) | (0xff>>(8-netmask)))+1)\n        return a\n\n    @classmethod\n    def _parse_net(cls, net):\n        tmp=net.split('/')+[\"32\"]\n        if not cls.ip_regex.match(net):\n            tmp[0]=socket.gethostbyname(tmp[0])\n        netmask = int(tmp[1])\n        ret_list = [cls._parse_digit(x, y-netmask) for (x, y) in zip(tmp[0].split('.'), [8, 16, 24, 32])]\n        return ret_list, netmask\n\n    def __init__(self, net):\n        self.repr=net\n        self.parsed,self.netmask = self._parse_net(net)\n\n    def __str__(self):\n        try:\n            return next(self.__iter__())\n        except StopIteration:\n            return None\n                                                                                               \n    def __iter__(self):\n        for d in range(*self.parsed[3]):\n            for c in range(*self.parsed[2]):\n                for b in range(*self.parsed[1]):\n                    for a in range(*self.parsed[0]):\n                        yield \"%i.%i.%i.%i\" % (a,b,c,d)\n    def choice(self):\n        ip = []\n        for v in self.parsed:\n            ip.append(str(random.randint(v[0],v[1]-1)))\n        return \".\".join(ip) \n                          \n    def __repr__(self):\n        return \"Net(%r)\" % self.repr\n    def __eq__(self, other):\n        if hasattr(other, \"parsed\"):\n            p2 = other.parsed\n        else:\n            p2,nm2 = self._parse_net(other)\n        return self.parsed == p2\n    def __contains__(self, other):\n        if hasattr(other, \"parsed\"):\n            p2 = other.parsed\n        else:\n            p2,nm2 = self._parse_net(other)\n        for (a1,b1),(a2,b2) in zip(self.parsed,p2):\n            if a1 > a2 or b1 < b2:\n                return False\n        return True\n    def __rcontains__(self, other):        \n        return self in self.__class__(other)\n        \n\nclass OID(Gen):\n    name = \"OID\"\n    def __init__(self, oid):\n        self.oid = oid        \n        self.cmpt = []\n        fmt = []        \n        for i in oid.split(\".\"):\n            if \"-\" in i:\n                fmt.append(\"%i\")\n                self.cmpt.append(tuple(map(int, i.split(\"-\"))))\n            else:\n                fmt.append(i)\n        self.fmt = \".\".join(fmt)\n    def __repr__(self):\n        return \"OID(%r)\" % self.oid\n    def __iter__(self):        \n        ii = [k[0] for k in self.cmpt]\n        while True:\n            yield self.fmt % tuple(ii)\n            i = 0\n            while True:\n                if i >= len(ii):\n                    raise StopIteration\n                if ii[i] < self.cmpt[i][1]:\n                    ii[i]+=1\n                    break\n                else:\n                    ii[i] = self.cmpt[i][0]\n                i += 1\n\n\n \n######################################\n## Packet abstract and base classes ##\n######################################\n\nclass Packet_metaclass(type):\n    def __new__(cls, name, bases, dct):\n        if \"fields_desc\" in dct: # perform resolution of references to other packets\n            current_fld = dct[\"fields_desc\"]\n            resolved_fld = []\n            for f in current_fld:\n                if isinstance(f, Packet_metaclass): # reference to another fields_desc\n                    for f2 in f.fields_desc:\n                        resolved_fld.append(f2)\n                else:\n                    resolved_fld.append(f)\n        else: # look for a fields_desc in parent classes\n            resolved_fld = None\n            for b in bases:\n                if hasattr(b,\"fields_desc\"):\n                    resolved_fld = b.fields_desc\n                    break\n\n        if resolved_fld: # perform default value replacements\n            final_fld = []\n            for f in resolved_fld:\n                if f.name in dct:\n                    f = f.copy()\n                    f.default = dct[f.name]\n                    del(dct[f.name])\n                final_fld.append(f)\n\n            dct[\"fields_desc\"] = final_fld\n\n        if \"__slots__\" not in dct:\n            dct[\"__slots__\"] = []\n        for attr in [\"name\", \"overload_fields\"]:\n            try:\n                dct[\"_%s\" % attr] = dct.pop(attr)\n            except KeyError:\n                pass\n        newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct)\n        newcls.__all_slots__ = set(\n            attr\n            for cls in newcls.__mro__ if hasattr(cls, \"__slots__\")\n            for attr in cls.__slots__\n        )\n\n        if hasattr(newcls, \"aliastypes\"):\n            newcls.aliastypes = [newcls] + newcls.aliastypes\n        else:\n            newcls.aliastypes = [newcls]\n\n        if hasattr(newcls,\"register_variant\"):\n            newcls.register_variant()\n        for f in newcls.fields_desc:\n            if hasattr(f, \"register_owner\"):\n                f.register_owner(newcls)\n        from scapy import config\n        config.conf.layers.register(newcls)\n        return newcls\n\n    def __getattr__(self, attr):\n        for k in self.fields_desc:\n            if k.name == attr:\n                return k\n        raise AttributeError(attr)\n\n    def __call__(cls, *args, **kargs):\n        if \"dispatch_hook\" in cls.__dict__:\n            try:\n                cls = cls.dispatch_hook(*args, **kargs)\n            except:\n                from scapy import config\n                if config.conf.debug_dissector:\n                    raise\n                cls = config.conf.raw_layer\n        i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)\n        i.__init__(*args, **kargs)\n        return i\n\nclass Field_metaclass(type):\n    def __new__(cls, name, bases, dct):\n        if \"__slots__\" not in dct:\n            dct[\"__slots__\"] = []\n        newcls = super(Field_metaclass, cls).__new__(cls, name, bases, dct)\n        return newcls\n\nclass NewDefaultValues(Packet_metaclass):\n    \"\"\"NewDefaultValues is deprecated (not needed anymore)\n    \n    remove this:\n        __metaclass__ = NewDefaultValues\n    and it should still work.\n    \"\"\"    \n    def __new__(cls, name, bases, dct):\n        from scapy.error import log_loading\n        import traceback\n        try:\n            for tb in traceback.extract_stack()+[(\"??\",-1,None,\"\")]:\n                f,l,_,line = tb\n                if line.startswith(\"class\"):\n                    break\n        except:\n            f,l=\"??\",-1\n            raise\n        log_loading.warning(\"Deprecated (no more needed) use of NewDefaultValues  (%s l. %i).\", f, l)\n        \n        return super(NewDefaultValues, cls).__new__(cls, name, bases, dct)\n\nclass BasePacket(Gen):\n    __slots__ = []\n\n\n#############################\n## Packet list base class  ##\n#############################\n\nclass BasePacketList(object):\n    __slots__ = []\n", "path": "scapy/base_classes.py"}]}