diff --git a/.coveragerc b/.coveragerc index 86186c571..cec0a085f 100644 --- a/.coveragerc +++ b/.coveragerc @@ -9,3 +9,5 @@ omit = # Libraries scapy/modules/six.py scapy/modules/winpcapy.py + # Python 3: not tested yet + scapy/compat.py diff --git a/.travis/test.sh b/.travis/test.sh index 2c27c3e8d..9eb1992f6 100644 --- a/.travis/test.sh +++ b/.travis/test.sh @@ -1,3 +1,10 @@ +# Report installed versions +echo "### INSTALLED VERSIONS ###" +for DEPENDENCY in "six" "cryptography" "mock" +do + python -c 'import '$DEPENDENCY'; print("'$DEPENDENCY': "+str('$DEPENDENCY'.__version__))' +done + # Dump environment variables echo "SCAPY_SUDO=" $SCAPY_SUDO echo "TRAVIS_OS_NAME=" $TRAVIS_OS_NAME diff --git a/run_scapy3 b/run_scapy3 new file mode 100644 index 000000000..964debe33 --- /dev/null +++ b/run_scapy3 @@ -0,0 +1,4 @@ +#! /bin/sh +DIR=$(dirname $0) +PYTHONDONTWRITEBYTECODE="True" # Disable __pycache__ +PYTHONPATH=$DIR exec python3 -m scapy.__init__ $@ diff --git a/run_scapy3.bat b/run_scapy3.bat new file mode 100644 index 000000000..e03740590 --- /dev/null +++ b/run_scapy3.bat @@ -0,0 +1,7 @@ +@echo off +set PYTHONPATH=%cd% +set PYTHONDONTWRITEBYTECODE=True +"C:\Program Files (x86)\Python3\python.exe" -m scapy.__init__ %* +if errorlevel 1 ( + PAUSE +) diff --git a/scapy/arch/__init__.py b/scapy/arch/__init__.py index f8cb4bf91..0e8785f26 100644 --- a/scapy/arch/__init__.py +++ b/scapy/arch/__init__.py @@ -19,7 +19,7 @@ from scapy.pton_ntop import inet_pton from scapy.data import * def str2mac(s): - return ("%02x:"*6)[:-1] % tuple(ord(x) for x in s) + return ("%02x:"*6)[:-1] % tuple(ord(x) for x in s) if not WINDOWS: if not scapy.config.conf.use_pcap and not scapy.config.conf.use_dnet: diff --git a/scapy/arch/bpf/core.py b/scapy/arch/bpf/core.py index df1264a40..19225454a 100644 --- a/scapy/arch/bpf/core.py +++ b/scapy/arch/bpf/core.py @@ -210,8 +210,8 @@ def get_working_ifaces(): os.close(fd) # Sort to mimic pcap_findalldevs() order - interfaces.sort(lambda (ifname_left, ifid_left), - (ifname_right, ifid_right): ifid_left-ifid_right) + interfaces.sort(lambda ifname_left_and_ifid_left, + ifname_right_and_ifid_right: ifname_left_and_ifid_left[1]-ifname_right_and_ifid_right[1]) return interfaces diff --git a/scapy/arch/bpf/supersocket.py b/scapy/arch/bpf/supersocket.py index 3903fa457..34c8f1506 100644 --- a/scapy/arch/bpf/supersocket.py +++ b/scapy/arch/bpf/supersocket.py @@ -20,6 +20,7 @@ from scapy.consts import FREEBSD, NETBSD from scapy.data import ETH_P_ALL from scapy.error import Scapy_Exception, warning from scapy.supersocket import SuperSocket +from scapy.compat import raw if FREEBSD or NETBSD: @@ -288,7 +289,7 @@ class L2bpfSocket(L2bpfListenSocket): def send(self, x): """Send a frame""" - return os.write(self.outs, str(x)) + return os.write(self.outs, raw(x)) def nonblock_recv(self): """Non blocking receive""" @@ -329,7 +330,7 @@ class L3bpfSocket(L2bpfSocket): self.assigned_interface = iff # Build the frame - frame = str(self.guessed_cls()/pkt) + frame = raw(self.guessed_cls()/pkt) pkt.sent_time = time.time() # Send the frame diff --git a/scapy/arch/common.py b/scapy/arch/common.py index 39e8c457d..6b309c7af 100644 --- a/scapy/arch/common.py +++ b/scapy/arch/common.py @@ -11,11 +11,10 @@ import socket from fcntl import ioctl import struct - def get_if(iff, cmd): """Ease SIOCGIF* ioctl calls""" sck = socket.socket() - ifreq = ioctl(sck, cmd, struct.pack("16s16x", iff)) + ifreq = ioctl(sck, cmd, struct.pack("16s16x", iff.encode("utf8"))) sck.close() return ifreq diff --git a/scapy/arch/linux.py b/scapy/arch/linux.py index fed35df38..a035f00f4 100644 --- a/scapy/arch/linux.py +++ b/scapy/arch/linux.py @@ -13,6 +13,7 @@ from select import select from fcntl import ioctl import array +from scapy.compat import * from scapy.consts import LOOPBACK_NAME, IS_64BITS import scapy.utils import scapy.utils6 @@ -105,7 +106,7 @@ def get_if_raw_addr(iff): def get_if_list(): try: - f=open("/proc/net/dev","rb") + f=open("/proc/net/dev", "rb") except IOError: warning("Can't open /proc/net/dev !") return [] @@ -113,6 +114,7 @@ def get_if_list(): f.readline() f.readline() for l in f: + l = plain_str(l) lst.append(l.split(":")[0].strip()) return lst def get_working_if(): @@ -194,7 +196,7 @@ def get_alias_address(iface_name, ip_mask): # Look for the IP address for ifname in names: # Only look for a matching interface name - if not ifname.startswith(iface_name): + if not ifname.decode("utf8").startswith(iface_name): continue # Retrieve and convert addresses @@ -221,16 +223,16 @@ def get_alias_address(iface_name, ip_mask): def read_routes(): try: - f=open("/proc/net/route","rb") + f=open("/proc/net/route", "rb") except IOError: warning("Can't open /proc/net/route !") return [] routes = [] s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",LOOPBACK_NAME)) + ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x", LOOPBACK_NAME.encode("utf8"))) addrfamily = struct.unpack("h",ifreq[16:18])[0] if addrfamily == socket.AF_INET: - ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x",LOOPBACK_NAME)) + ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x", LOOPBACK_NAME.encode("utf8"))) msk = socket.ntohl(struct.unpack("I",ifreq2[20:24])[0]) dst = socket.ntohl(struct.unpack("I",ifreq[20:24])[0]) & msk ifaddr = scapy.utils.inet_ntoa(ifreq[20:24]) @@ -239,6 +241,7 @@ def read_routes(): warning("Interface lo: unkown address family (%i)"% addrfamily) for l in f.readlines()[1:]: + l = plain_str(l) iff,dst,gw,flags,x,x,x,msk,x,x,x = l.split() flags = int(flags,16) if flags & RTF_UP == 0: @@ -246,7 +249,7 @@ def read_routes(): if flags & RTF_REJECT: continue try: - ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",iff)) + ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x", iff.encode("utf8"))) except IOError: # interface is present in routing tables but does not have any assigned IP ifaddr="0.0.0.0" else: @@ -288,15 +291,16 @@ def in6_getifaddr(): """ ret = [] try: - f = open("/proc/net/if_inet6","rb") + f = open("/proc/net/if_inet6", "rb") except IOError as err: return ret l = f.readlines() for i in l: + l = plain_str(l) # addr, index, plen, scope, flags, ifname tmp = i.split() addr = struct.unpack('4s4s4s4s4s4s4s4s', tmp[0]) - addr = scapy.utils6.in6_ptop(':'.join(addr)) + addr = scapy.utils6.in6_ptop(b':'.join(addr)) ret.append((addr, int(tmp[3], 16), tmp[5])) # (addr, scope, iface) return ret @@ -317,12 +321,13 @@ def read_routes6(): # 10. device name routes = [] def proc2r(p): - ret = struct.unpack('4s4s4s4s4s4s4s4s', p) - ret = ':'.join(ret) + ret = struct.unpack('4s4s4s4s4s4s4s4s', raw(p)) + ret = b':'.join(ret) return scapy.utils6.in6_ptop(ret) lifaddr = in6_getifaddr() for l in f.readlines(): + l = plain_str(l) d,dp,s,sp,nh,m,rc,us,fl,dev = l.split() fl = int(fl, 16) @@ -460,7 +465,7 @@ class L3PacketSocket(SuperSocket): sdto = (iff, conf.l3types[type(x)]) if sn[3] in conf.l2types: ll = lambda x:conf.l2types[sn[3]]()/x - sx = str(ll(x)) + sx = raw(ll(x)) x.sent_time = time.time() try: self.outs.sendto(sx, sdto) @@ -469,7 +474,7 @@ class L3PacketSocket(SuperSocket): self.outs.send(sx + b"\x00" * (conf.min_pkt_size - len(sx))) elif conf.auto_fragment and msg[0] == 90: for p in x.fragment(): - self.outs.sendto(str(ll(p)), sdto) + self.outs.sendto(raw(ll(p)), sdto) else: raise @@ -535,7 +540,7 @@ class L2Socket(SuperSocket): if isinstance(x, Packet): return SuperSocket.send(self, x / Padding(load=padding)) else: - return SuperSocket.send(self, str(x) + padding) + return SuperSocket.send(self, raw(x) + padding) raise diff --git a/scapy/arch/pcapdnet.py b/scapy/arch/pcapdnet.py index 9193a8a45..b52072c70 100644 --- a/scapy/arch/pcapdnet.py +++ b/scapy/arch/pcapdnet.py @@ -13,6 +13,7 @@ if not sys.platform.startswith("win"): from fcntl import ioctl from scapy.data import * +from scapy.compat import * from scapy.config import conf from scapy.utils import mac2str from scapy.supersocket import SuperSocket @@ -74,13 +75,13 @@ if conf.use_winpcapy: try: p = devs while p: - if p.contents.name.endswith(iff): + if p.contents.name.endswith(iff.guid.encode("ascii")): a = p.contents.addresses while a: if hasattr(socket, 'AF_LINK') and a.contents.addr.contents.sa_family == socket.AF_LINK: ap = a.contents.addr val = cast(ap, POINTER(sockaddr_dl)) - ret = str(val.contents.sdl_data[ val.contents.sdl_nlen : val.contents.sdl_nlen + val.contents.sdl_alen ]) + ret = (val.contents.sdl_data[ val.contents.sdl_nlen : val.contents.sdl_nlen + val.contents.sdl_alen ]).encode("utf8") a = a.contents.next break p = p.contents.next @@ -97,13 +98,13 @@ if conf.use_winpcapy: try: p = devs while p: - if p.contents.name.endswith(iff.guid): + if p.contents.name.endswith(iff.guid.encode("ascii")): a = p.contents.addresses while a: if a.contents.addr.contents.sa_family == socket.AF_INET: ap = a.contents.addr val = cast(ap, POINTER(sockaddr_in)) - ret = "".join(chr(x) for x in val.contents.sin_addr[:4]) + ret = b"".join(chr(x) for x in val.contents.sin_addr[:4]) a = a.contents.next break p = p.contents.next @@ -140,7 +141,7 @@ if conf.use_winpcapy: class _PcapWrapper_pypcap: def __init__(self, device, snaplen, promisc, to_ms): self.errbuf = create_string_buffer(PCAP_ERRBUF_SIZE) - self.iface = create_string_buffer(device) + self.iface = create_string_buffer(device.encode('ascii')) self.pcap = pcap_open_live(self.iface, snaplen, promisc, to_ms, self.errbuf) self.header = POINTER(pcap_pkthdr)() self.pkt_data = POINTER(c_ubyte)() @@ -150,7 +151,7 @@ if conf.use_winpcapy: if not c > 0: return ts = self.header.contents.ts.tv_sec + float(self.header.contents.ts.tv_usec) / 1000000 - pkt = "".join(chr(i) for i in self.pkt_data[:self.header.contents.len]) + pkt = b"".join(chb(i) for i in self.pkt_data[:self.header.contents.len]) return ts, pkt __next__ = next def datalink(self): @@ -161,7 +162,7 @@ if conf.use_winpcapy: return 0 return pcap_get_selectable_fd(self.pcap) def setfilter(self, f): - filter_exp = create_string_buffer(f) + filter_exp = create_string_buffer(f.encode('ascii')) if pcap_compile(self.pcap, byref(self.bpf_program), filter_exp, 0, -1) == -1: log_loading.error("Could not compile filter expression %s" % f) return False @@ -276,7 +277,7 @@ if conf.use_winpcapy: if filter: self.ins.setfilter(filter) def send(self, x): - sx = str(x) + sx = raw(x) if hasattr(x, "sent_time"): x.sent_time = time.time() return self.outs.send(sx) @@ -332,7 +333,7 @@ if conf.use_winpcapy: return def send(self, x): cls = conf.l2types[1] - sx = str(cls()/x) + sx = raw(cls()/x) if hasattr(x, "sent_time"): x.sent_time = time.time() return self.ins.send(sx) @@ -374,7 +375,7 @@ if conf.use_pcap: if c is None: return ts, pkt = c - return ts, str(pkt) + return ts, raw(pkt) __next__ = next open_pcap = lambda *args,**kargs: _PcapWrapper_pypcap(*args,**kargs) elif hasattr(pcap,"pcapObject"): # python-libpcap @@ -603,9 +604,9 @@ if conf.use_pcap and conf.use_dnet: ifs = dnet.ip() self.iflist[iff] = ifs,cls if cls is None: - sx = str(x) + sx = raw(x) else: - sx = str(cls()/x) + sx = raw(cls()/x) x.sent_time = time.time() ifs.send(sx) def recv(self,x=MTU): diff --git a/scapy/arch/windows/__init__.py b/scapy/arch/windows/__init__.py index 154a667fd..1399e2a97 100755 --- a/scapy/arch/windows/__init__.py +++ b/scapy/arch/windows/__init__.py @@ -20,7 +20,7 @@ from scapy.base_classes import Gen, Net, SetGen from scapy.data import MTU, ETHER_BROADCAST, ETH_P_ARP import scapy.modules.six as six -from scapy.modules.six.moves import range, zip +from scapy.modules.six.moves import range, zip, input conf.use_pcap = False conf.use_dnet = False @@ -429,7 +429,7 @@ class NetworkInterfaceDict(UserDict): if not conf.interactive: return False while True: - _confir = raw_input("Do you want to start it ? (yes/no) [y]: ").lower().strip() + _confir = input("Do you want to start it ? (yes/no) [y]: ").lower().strip() if _confir in ["yes", "y", ""]: return True elif _confir in ["no", "n"]: @@ -480,7 +480,7 @@ class NetworkInterfaceDict(UserDict): def dev_from_index(self, if_index): """Return interface name from interface index""" - for devname, iface in self.items(): + for devname, iface in six.iteritems(self): if iface.win_index == str(if_index): return iface if str(if_index) == "1": @@ -491,7 +491,8 @@ class NetworkInterfaceDict(UserDict): def remove_invalid_ifaces(self): """Remove all invalid interfaces""" - for devname, iface in self.items(): + for devname in list(self.keys()): + iface = self.data[devname] if iface.is_invalid(): self.data.pop(devname) @@ -863,6 +864,13 @@ def route_add_loopback(routes=None, ipv6=False, iflist=None): IFACES.pop(devname) # Inject interface IFACES[data['guid']] = adapter + scapy.consts.LOOPBACK_INTERFACE = adapter + if isinstance(conf.iface, NetworkInterface): + if conf.iface.name == LOOPBACK_NAME: + conf.iface = adapter + if isinstance(conf.iface6, NetworkInterface): + if conf.iface6.name == LOOPBACK_NAME: + conf.iface6 = adapter # Build the packed network addresses loop_net = struct.unpack("!I", socket.inet_aton("127.0.0.0"))[0] loop_mask = struct.unpack("!I", socket.inet_aton("255.0.0.0"))[0] diff --git a/scapy/as_resolvers.py b/scapy/as_resolvers.py index e92b3a36b..65f40f6a6 100644 --- a/scapy/as_resolvers.py +++ b/scapy/as_resolvers.py @@ -11,6 +11,7 @@ Resolve Autonomous Systems (AS). from __future__ import absolute_import import socket, errno from scapy.config import conf +from scapy.compat import * class AS_resolver: server = None @@ -26,7 +27,7 @@ class AS_resolver: self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.connect((self.server,self.port)) if self.options: - self.s.send(self.options+"\n") + self.s.send(self.options.encode("utf8")+b"\n") self.s.recv(8192) def _stop(self): self.s.close() @@ -35,17 +36,17 @@ class AS_resolver: asn,desc = None,b"" for l in txt.splitlines(): if not asn and l.startswith(b"origin:"): - asn = l[7:].strip() + asn = l[7:].strip().decode("utf8") if l.startswith(b"descr:"): if desc: desc += r"\n" desc += l[6:].strip() if asn is not None and desc: break - return asn,desc.strip() + return asn, desc.strip().decode("utf8") def _resolve_one(self, ip): - self.s.send("%s\n" % ip) + self.s.send(("%s\n" % ip).encode("utf8")) x = b"" while not (b"%" in x or b"source" in x): x += self.s.recv(8192) @@ -55,7 +56,7 @@ class AS_resolver: self._start() ret = [] for ip in ips: - ip,asn,desc = self._resolve_one(ip) + ip,asn,desc = self._resolve_one(ip.encode("utf8")) if asn is not None: ret.append((ip,asn,desc)) self._stop() @@ -78,7 +79,7 @@ class AS_resolver_cymru(AS_resolver): ASNlist = [] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((self.server,self.port)) - s.send(b"begin\r\n"+b"\r\n".join(ips)+b"\r\nend\r\n") + s.send(b"begin\r\n"+b"\r\n".join(ips.encode("utf8"))+b"\r\nend\r\n") r = b"" while True: l = s.recv(8192) @@ -92,7 +93,7 @@ class AS_resolver_cymru(AS_resolver): asn, ip, desc = [elt.strip() for elt in l.split('|')] if asn == b"NA": continue - asn = b"AS" + str(int(asn)) + asn = b"AS" + bytes(int(asn)) ASNlist.append((ip, asn, desc)) return ASNlist diff --git a/scapy/asn1/asn1.py b/scapy/asn1/asn1.py index 1da212ba1..15ec23a32 100644 --- a/scapy/asn1/asn1.py +++ b/scapy/asn1/asn1.py @@ -198,6 +198,8 @@ class ASN1_Object(six.with_metaclass(ASN1_Object_metaclass)): return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), self.val) def __str__(self): return self.enc(conf.ASN1_default_codec) + def __bytes__(self): + return self.enc(conf.ASN1_default_codec) def strshow(self, lvl=0): return (" "*lvl)+repr(self)+"\n" def show(self, lvl=0): diff --git a/scapy/asn1/ber.py b/scapy/asn1/ber.py index d9326ee8d..f292740bf 100644 --- a/scapy/asn1/ber.py +++ b/scapy/asn1/ber.py @@ -11,6 +11,7 @@ Basic Encoding Rules (BER) for ASN.1 from __future__ import absolute_import from scapy.error import warning +from scapy.compat import * from scapy.utils import binrepr,inet_aton,inet_ntoa from scapy.asn1.asn1 import ASN1_Decoding_Error,ASN1_Encoding_Error,ASN1_BadTag_Decoding_Error,ASN1_Codecs,ASN1_Class_UNIVERSAL,ASN1_Error,ASN1_DECODING_ERROR,ASN1_BADTAG import scapy.modules.six as six @@ -60,15 +61,15 @@ class BER_BadTag_Decoding_Error(BER_Decoding_Error, ASN1_BadTag_Decoding_Error): def BER_len_enc(l, size=0): if l <= 127 and size==0: - return chr(l) + return chb(l) s = b"" while l or size>0: - s = chr(l&0xff)+s + s = chb(l&0xff)+s l >>= 8 size -= 1 if len(s) > 127: raise BER_Exception("BER_len_enc: Length too long (%i) to be encoded [%r]" % (len(s),s)) - return chr(len(s)|0x80)+s + return chb(len(s)|0x80)+s def BER_len_dec(s): l = ord(s[0]) if not l & 0x80: @@ -90,7 +91,7 @@ def BER_num_enc(l, size=1): x[0] |= 0x80 l >>= 7 size -= 1 - return b"".join(chr(k) for k in x) + return b"".join(chb(k) for k in x) def BER_num_dec(s, cls_id=0): if len(s) == 0: raise BER_Decoding_Error("BER_num_dec: got empty string", remaining=s) @@ -132,7 +133,7 @@ def BER_id_dec(s): def BER_id_enc(n): if n < 256: # low-tag-number - return chr(n) + return chb(n) else: # high-tag-number s = BER_num_enc(n) @@ -140,7 +141,7 @@ def BER_id_enc(n): tag &= 0x07 # reset every bit from 8 to 4 tag <<= 5 # move back the info bits on top tag |= 0x1f # pad with 1s every bit from 5 to 1 - return chr(tag) + s[1:] + return chb(tag) + s[1:] # The functions below provide implicit and explicit tagging support. def BER_tagging_dec(s, hidden_tag=None, implicit_tag=None, @@ -156,7 +157,7 @@ def BER_tagging_dec(s, hidden_tag=None, implicit_tag=None, raise BER_Decoding_Error(err_msg, remaining=s) else: real_tag = ber_id - s = chr(hidden_tag) + s + s = chb(hash(hidden_tag)) + s elif explicit_tag is not None: ber_id,s = BER_id_dec(s) if ber_id != explicit_tag: @@ -231,7 +232,7 @@ class BERcodec_Object(six.with_metaclass(BERcodec_metaclass)): if p not in context: t = s if len(t) > 18: - t = t[:15]+"..." + t = t[:15]+b"..." raise BER_Decoding_Error("Unknown prefix [%02x] for [%r]" % (p,t), remaining=s) codec = context[p].get_codec(ASN1_Codecs.BER) return codec.dec(s,context,safe) @@ -257,7 +258,7 @@ class BERcodec_Object(six.with_metaclass(BERcodec_metaclass)): @classmethod def enc(cls, s): - if isinstance(s, basestring): + if isinstance(s, basestring, bytes): return BERcodec_STRING.enc(s) else: return BERcodec_INTEGER.enc(int(s)) @@ -283,9 +284,9 @@ class BERcodec_INTEGER(BERcodec_Object): i >>= 8 if not i: break - s = [chr(c) for c in s] + s = [chb(hash(c)) for c in s] s.append(BER_len_enc(len(s))) - s.append(chr(cls.tag)) + s.append(chb(hash(cls.tag))) s.reverse() return b"".join(s) @classmethod @@ -327,15 +328,15 @@ class BERcodec_BIT_STRING(BERcodec_Object): else: unused_bits = 8 - len(s)%8 s += b"0"*unused_bits - s = b"".join(chr(int(b"".join(x),2)) for x in zip(*[iter(s)]*8)) - s = chr(unused_bits) + s - return chr(cls.tag)+BER_len_enc(len(s))+s + s = b"".join(chb(int(b"".join(x),2)) for x in zip(*[iter(s)]*8)) + s = chb(unused_bits) + s + return chb(hash(cls.tag))+BER_len_enc(len(s))+s class BERcodec_STRING(BERcodec_Object): tag = ASN1_Class_UNIVERSAL.STRING @classmethod def enc(cls,s): - return chr(cls.tag)+BER_len_enc(len(s))+s + return chb(hash(cls.tag))+BER_len_enc(len(s))+s @classmethod def do_dec(cls, s, context=None, safe=False): l,s,t = cls.check_type_check_len(s) @@ -346,7 +347,7 @@ class BERcodec_NULL(BERcodec_INTEGER): @classmethod def enc(cls, i): if i == 0: - return chr(cls.tag)+b"\0" + return chb(hash(cls.tag))+b"\0" else: return super(cls,cls).enc(i) @@ -354,12 +355,13 @@ class BERcodec_OID(BERcodec_Object): tag = ASN1_Class_UNIVERSAL.OID @classmethod def enc(cls, oid): - lst = [int(x) for x in oid.strip(".").split(".")] + oid = raw(oid) + lst = [int(x) for x in oid.strip(b".").split(b".")] if len(lst) >= 2: lst[1] += 40*lst[0] del(lst[0]) s = b"".join(BER_num_enc(k) for k in lst) - return chr(cls.tag)+BER_len_enc(len(s))+s + return chb(hash(cls.tag))+BER_len_enc(len(s))+s @classmethod def do_dec(cls, s, context=None, safe=False): l,s,t = cls.check_type_check_len(s) @@ -370,7 +372,7 @@ class BERcodec_OID(BERcodec_Object): if (len(lst) > 0): lst.insert(0,lst[0]//40) lst[1] %= 40 - return cls.asn1_object(".".join(str(k) for k in lst)), t + return cls.asn1_object(b".".join(str(k).encode('ascii') for k in lst)), t class BERcodec_ENUMERATED(BERcodec_INTEGER): tag = ASN1_Class_UNIVERSAL.ENUMERATED @@ -406,9 +408,9 @@ class BERcodec_SEQUENCE(BERcodec_Object): tag = ASN1_Class_UNIVERSAL.SEQUENCE @classmethod def enc(cls, l): - if not isinstance(l, str): - l = "".join(x.enc(cls.codec) for x in l) - return chr(cls.tag)+BER_len_enc(len(l))+l + if not isinstance(l, bytes): + l = b"".join(x.enc(cls.codec) for x in l) + return chb(hash(cls.tag))+BER_len_enc(len(l))+l @classmethod def do_dec(cls, s, context=None, safe=False): if context is None: @@ -441,7 +443,7 @@ class BERcodec_IPADDRESS(BERcodec_STRING): s = inet_aton(ipaddr_ascii) except Exception: raise BER_Encoding_Error("IPv4 address could not be encoded") - return chr(cls.tag)+BER_len_enc(len(s))+s + return chb(hash(cls.tag))+BER_len_enc(len(s))+s @classmethod def do_dec(cls, s, context=None, safe=False): l,s,t = cls.check_type_check_len(s) @@ -459,6 +461,3 @@ class BERcodec_GAUGE32(BERcodec_INTEGER): class BERcodec_TIME_TICKS(BERcodec_INTEGER): tag = ASN1_Class_UNIVERSAL.TIME_TICKS - - - diff --git a/scapy/asn1/mib.py b/scapy/asn1/mib.py index 3f1e49539..588db8892 100644 --- a/scapy/asn1/mib.py +++ b/scapy/asn1/mib.py @@ -15,6 +15,7 @@ from scapy.dadict import DADict,fixname from scapy.config import conf from scapy.utils import do_graph import scapy.modules.six as six +from scapy.compat import * ################# ## MIB parsing ## @@ -85,7 +86,7 @@ def mib_register(ident, value, the_mib, unresolved): if _mib_re_integer.match(v): resval.append(v) else: - v = fixname(v) + v = fixname(plain_str(v)) if v not in the_mib: not_resolved = 1 if v in the_mib: @@ -121,7 +122,7 @@ def load_mib(filenames): for k in six.iterkeys(conf.mib): mib_register(k, conf.mib[k].split("."), the_mib, unresolved) - if isinstance(filenames, str): + if isinstance(filenames, (str, bytes)): filenames = [filenames] for fnames in filenames: for fname in glob(fnames): diff --git a/scapy/asn1fields.py b/scapy/asn1fields.py index 1b16f05ee..5f1caf40d 100644 --- a/scapy/asn1fields.py +++ b/scapy/asn1fields.py @@ -13,6 +13,7 @@ from scapy.asn1.asn1 import * from scapy.asn1.ber import * from scapy.asn1.mib import * from scapy.volatile import * +from scapy.compat import * from scapy.base_classes import BasePacket from scapy.utils import binrepr from scapy import packet @@ -199,7 +200,7 @@ class ASN1F_BIT_STRING(ASN1F_field): def __init__(self, name, default, default_readable=True, context=None, implicit_tag=None, explicit_tag=None): if default is not None and default_readable: - default = b"".join(binrepr(ord(x)).zfill(8) for x in default) + default = b"".join(binrepr(ord(x)).zfill(8).encode("utf8") for x in default) ASN1F_field.__init__(self, name, default, context=context, implicit_tag=implicit_tag, explicit_tag=explicit_tag) @@ -367,7 +368,7 @@ class ASN1F_SEQUENCE_OF(ASN1F_field): elif val is None: s = b"" else: - s = b"".join(map(str, val)) + s = b"".join(raw(i) for i in val) return self.i2m(pkt, s) def randval(self): @@ -483,9 +484,9 @@ class ASN1F_CHOICE(ASN1F_field): return choice.m2i(pkt, s) def i2m(self, pkt, x): if x is None: - s = "" + s = b"" else: - s = str(x) + s = raw(x) if hash(type(x)) in self.pktchoices: imp, exp = self.pktchoices[hash(type(x))] s = BER_tagging_enc(s, implicit_tag=imp, @@ -530,7 +531,7 @@ class ASN1F_PACKET(ASN1F_field): if x is None: s = b"" else: - s = str(x) + s = raw(x) return BER_tagging_enc(s, implicit_tag=self.implicit_tag, explicit_tag=self.explicit_tag) def randval(self): @@ -561,7 +562,7 @@ class ASN1F_BIT_STRING_ENCAPS(ASN1F_BIT_STRING): if x is None: s = b"" else: - s = str(x) + s = raw(x) s = b"".join(binrepr(ord(x)).zfill(8) for x in s) return ASN1F_BIT_STRING.i2m(self, pkt, s) diff --git a/scapy/automaton.py b/scapy/automaton.py index b6a60764d..9945cd455 100644 --- a/scapy/automaton.py +++ b/scapy/automaton.py @@ -19,6 +19,7 @@ from scapy.plist import PacketList from scapy.data import MTU from scapy.supersocket import SuperSocket from scapy.consts import WINDOWS +from scapy.compat import * import scapy.modules.six as six try: @@ -346,8 +347,8 @@ class _ATMT_supersocket(SuperSocket): def fileno(self): return self.spa.fileno() def send(self, s): - if not isinstance(s, str): - s = str(s) + if not isinstance(s, bytes): + s = bytes(s) return self.spa.send(s) def recv(self, n=MTU): r = self.spa.recv(n) @@ -422,14 +423,14 @@ class Automaton_metaclass(type): for v in six.itervalues(cls.timeout): - v.sort(lambda (t1,f1),(t2,f2): cmp(t1,t2)) + v.sort(key=cmp_to_key(lambda t1_f1,t2_f2: cmp(t1_f1[0],t2_f2[0]))) v.append((None, None)) for v in itertools.chain(six.itervalues(cls.conditions), six.itervalues(cls.recv_conditions), six.itervalues(cls.ioevents)): - v.sort(lambda c1,c2: cmp(c1.atmt_prio,c2.atmt_prio)) + v.sort(key=cmp_to_key(lambda c1,c2: cmp(c1.atmt_prio,c2.atmt_prio))) for condname,actlst in six.iteritems(cls.actions): - actlst.sort(lambda c1,c2: cmp(c1.atmt_cond[condname], c2.atmt_cond[condname])) + actlst.sort(key=cmp_to_key(lambda c1,c2: cmp(c1.atmt_cond[condname], c2.atmt_cond[condname]))) for ioev in cls.iosupersockets: setattr(cls, ioev.atmt_as_supersocket, _ATMT_to_supersocket(ioev.atmt_as_supersocket, ioev.atmt_ioname, cls)) diff --git a/scapy/compat.py b/scapy/compat.py new file mode 100644 index 000000000..630b87a32 --- /dev/null +++ b/scapy/compat.py @@ -0,0 +1,138 @@ +## This file is part of Scapy +## See http://www.secdev.org/projects/scapy for more informations +## Copyright (C) Philippe Biondi +## Copyright (C) Gabriel Potter +## This program is published under a GPLv2 license + +""" +Python 2 and 3 link classes. +""" + +from __future__ import absolute_import +import codecs + +import scapy.modules.six as six + +########### +# Python3 # +########### + +def cmp_to_key(mycmp): + # TODO remove me once all 'key=cmp_to_key(..)' has been fixed in utils6.py, automaton.py + """Convert a cmp= function into a key= function. + To use with sort() + + e.g: def stg_cmp(a, b): + return a == b + list.sort(key=cmp_to_key(stg_cmp)) + """ + class K(object): + def __init__(self, obj, *args): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) < 0 + def __gt__(self, other): + return mycmp(self.obj, other.obj) > 0 + def __eq__(self, other): + return mycmp(self.obj, other.obj) == 0 + def __le__(self, other): + return mycmp(self.obj, other.obj) <= 0 + def __ge__(self, other): + return mycmp(self.obj, other.obj) >= 0 + def __ne__(self, other): + return mycmp(self.obj, other.obj) != 0 + return K + +def cmp(a, b): + """Old Python 2 function""" + return (a > b) - (a < b) + +def orb(x): + """Return ord(x) when necessary. + Python 3 compatible. + + """ + if isinstance(x, (str, bytes)): + return ord(x) + else: + return x + +if six.PY2: + def raw(x): + """Convert a str, a packet to bytes""" + if x is None: + return None + if hasattr(x, "__bytes__"): + return x.__bytes__() + try: + return chr(x) + except (ValueError, TypeError): + return str(x) + + def plain_str(x): + """Convert basic byte objects to str""" + return x + + def chb(x): + """Same than chr() but encode as bytes. + + """ + if isinstance(x, bytes): + return x + else: + if hasattr(x, "__int__") and not isinstance(x, int): + return bytes(chr(int(x))) + return bytes(chr(x)) +else: + def raw(x): + """Convert a str, an int, a list of ints, a packet to bytes""" + try: + return bytes(x) + except TypeError: + return bytes(x, encoding="utf8") + + def plain_str(x): + """Convert basic byte objects to str""" + if isinstance(x, bytes): + return x.decode('utf8') + return x + + def chb(x): + """Same than chr() but encode as bytes. + + """ + if isinstance(x, bytes): + return x + else: + if hasattr(x, "__int__") and not isinstance(x, int): + return bytes(chr(int(x)), encoding="utf8") + return bytes(chr(x), encoding="utf8") + +def bytes_codec(x, codec, force_str=False): + """Hexify a str or a bytes object""" + if six.PY2: + return str(x).encode(codec) + else: + hex_ = codecs.getencoder(codec)(raw(x))[0] + if force_str: + hex_ = hex_.decode('utf8') + return hex_ + +def codec_bytes(x, codec): + """De-hexify a str or a byte object""" + if six.PY2: + return str(x).decode(codec) + else: + return codecs.getdecoder(codec)(x)[0] + +def bytes_hex(x, force_str=False): + """Hexify a str or a bytes object""" + return bytes_codec(x, "hex", force_str) + +def hex_bytes(x): + """De-hexify a str or a byte object""" + return codec_bytes(x, "hex") + +def base64_bytes(x): + """Turn base64 into bytes""" + return codec_bytes(raw(x), "base64") diff --git a/scapy/config.py b/scapy/config.py index 871c182cf..e18e74a2e 100755 --- a/scapy/config.py +++ b/scapy/config.py @@ -335,7 +335,7 @@ def _prompt_changer(attr,val): ## ^A and ^B delimit invisible characters for readline to count right. ## And we need ct.prompt() to do change something or else ^A and ^B will be ## displayed - prompt = b"\001%s\002" % ct.prompt(b"\002"+prompt+b"\001") + prompt = "\001%s\002" % ct.prompt("\002"+prompt+"\001") else: prompt = ct.prompt(prompt) except: diff --git a/scapy/contrib/bgp.uts b/scapy/contrib/bgp.uts index 5ccdf9ff2..f6be42093 100644 --- a/scapy/contrib/bgp.uts +++ b/scapy/contrib/bgp.uts @@ -297,7 +297,7 @@ str(BGPOptParam()) == b'\x02\x00' = BGPOptParam - Instantiation with specific values (1) str(BGPOptParam(param_type = 1)) == b'\x01\x00' -str(BGPOptParam(param_type = 1, param_value = BGPAuthenticationInformation())) == b'\x01\x04' +str(BGPOptParam(param_type = 1, param_value = BGPAuthenticationInformation())) == b'\x01\x00' = BGPOptParam - Instantiation with specific values (2) str(BGPOptParam(param_type = 2)) == b'\x02\x00' diff --git a/scapy/dadict.py b/scapy/dadict.py index 57d5f2501..f45e6e37f 100644 --- a/scapy/dadict.py +++ b/scapy/dadict.py @@ -11,13 +11,14 @@ from __future__ import absolute_import from __future__ import print_function from scapy.error import Scapy_Exception import scapy.modules.six as six +from scapy.compat import * ############################### ## Direct Access dictionary ## ############################### def fixname(x): - if x and x[0] in "0123456789": + if x and str(x[0]) in "0123456789": x = "n_"+x return x.translate("________________________________________________0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______abcdefghijklmnopqrstuvwxyz_____________________________________________________________________________________________________________________________________") @@ -30,7 +31,7 @@ class DADict: self._name=_name self.update(kargs) def fixname(self,val): - return fixname(val) + return fixname(plain_str(val)) def __contains__(self, val): return val in self.__dict__ def __getitem__(self, attr): @@ -90,7 +91,7 @@ class DADict: r += p return r def keys(self): - return list(six.iterkeys(self)) + return list(six.iterkeys(self.__dict__)) def iterkeys(self): return (x for x in self.__dict__ if x and x[0] != "_") def __len__(self): diff --git a/scapy/data.py b/scapy/data.py index e0b2a6e5f..f129cb27c 100644 --- a/scapy/data.py +++ b/scapy/data.py @@ -10,6 +10,7 @@ Global variables and functions for handling external data sets. import os, sys, re, time from scapy.dadict import DADict from scapy.error import log_loading +from scapy.compat import * ############ ## Consts ## @@ -141,7 +142,7 @@ def load_services(filename): class ManufDA(DADict): def fixname(self, val): - return val + return plain_str(val) def _get_manuf_couple(self, mac): oui = ":".join(mac.split(":")[:3]).upper() return self.__dict__.get(oui,(mac,mac)) diff --git a/scapy/fields.py b/scapy/fields.py index ceabf1a99..521d257bb 100644 --- a/scapy/fields.py +++ b/scapy/fields.py @@ -12,6 +12,7 @@ import struct,copy,socket,collections from scapy.config import conf from scapy.volatile import * from scapy.data import * +from scapy.compat import * from scapy.utils import * from scapy.base_classes import BasePacket, Gen, Net, Field_metaclass from scapy.error import warning @@ -209,7 +210,7 @@ class MACField(Field): def m2i(self, pkt, x): return str2mac(x) def any2i(self, pkt, x): - if isinstance(x, str) and len(x) is 6: + if isinstance(x, bytes) and len(x) == 6: x = self.m2i(pkt, x) return x def i2repr(self, pkt, x): @@ -226,7 +227,9 @@ class IPField(Field): def __init__(self, name, default): Field.__init__(self, name, default, "4s") def h2i(self, pkt, x): - if isinstance(x, six.string_types): + if isinstance(x, bytes): + x = plain_str(x) + if isinstance(x, str): try: inet_aton(x) except socket.error: @@ -381,14 +384,14 @@ class StrField(Field): def i2m(self, pkt, x): if x is None: x = b"" - elif not isinstance(x, str): - x=str(x) + elif not isinstance(x, bytes): + x = bytes(x) return x def addfield(self, pkt, s, val): - return s+self.i2m(pkt, val) + return s + self.i2m(pkt, val) def getfield(self, pkt, s): if self.remain == 0: - return b"",self.m2i(pkt, s) + return b"", self.m2i(pkt, s) else: return s[-self.remain:],self.m2i(pkt, s[:-self.remain]) def randval(self): @@ -401,7 +404,9 @@ class PacketField(StrField): StrField.__init__(self, name, default, remain=remain) self.cls = cls def i2m(self, pkt, i): - return str(i) + if i is None: + return b"" + return raw(i) def m2i(self, pkt, m): return self.cls(m) def getfield(self, pkt, s): @@ -455,7 +460,7 @@ class PacketListField(PacketField): if x is None: return None else: - return [p if isinstance(p, six.string_types) else p.copy() for p in x] + return [p if isinstance(p, bytes) else p.copy() for p in x] def getfield(self, pkt, s): c = l = None if self.length_from is not None: @@ -490,7 +495,7 @@ class PacketListField(PacketField): lst.append(p) return remain+ret,lst def addfield(self, pkt, s, val): - return s + b"".join(str(v) for v in val) + return s + b"".join(raw(v) for v in val) class StrFixedLenField(StrField): @@ -540,12 +545,12 @@ class NetBIOSNameField(StrFixedLenField): x = b"" x += b" "*(l) x = x[:l] - x = b"".join(chr(0x41 + ord(b)>>4) + chr(0x41 + ord(b)&0xf) for b in x) + x = b"".join(chb(0x41 + ord(b)>>4) + chb(0x41 + ord(b)&0xf) for b in x) x = b" "+x return x def m2i(self, pkt, x): x = x.strip(b"\x00").strip(" ") - return b"".join(map(lambda x,y: chr((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2])) + return b"".join(map(lambda x,y: chb((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2])) class StrLenField(StrField): __slots__ = ["length_from"] @@ -564,7 +569,7 @@ class XStrField(StrField): def i2repr(self, pkt, x): if not x: return repr(x) - return x.encode("hex") + return to_hex(x) class XStrLenField(StrLenField): """ @@ -574,7 +579,7 @@ class XStrLenField(StrLenField): def i2repr(self, pkt, x): if not x: return repr(x) - return x[:self.length_from(pkt)].encode("hex") + return to_hex(x[:self.length_from(pkt)]) class XStrFixedLenField(StrFixedLenField): """ @@ -584,7 +589,7 @@ class XStrFixedLenField(StrFixedLenField): def i2repr(self, pkt, x): if not x: return repr(x) - return x[:self.length_from(pkt)].encode("hex") + return to_hex(x[:self.length_from(pkt)]) class StrLenFieldUtf16(StrLenField): def h2i(self, pkt, x): @@ -767,11 +772,11 @@ class BitField(Field): w = s[:nb_bytes] # split the substring byte by byte - bytes = struct.unpack('!%dB' % nb_bytes , w) + _bytes = struct.unpack('!%dB' % nb_bytes , w) b = 0 for c in range(nb_bytes): - b |= int(bytes[c]) << (nb_bytes-c-1)*8 + b |= int(_bytes[c]) << (nb_bytes-c-1)*8 # get rid of high order bits b &= (1 << (nb_bytes*8-bn)) - 1 diff --git a/scapy/layers/all.py b/scapy/layers/all.py index 20a991d07..1ee19ab52 100644 --- a/scapy/layers/all.py +++ b/scapy/layers/all.py @@ -23,6 +23,7 @@ for _l in conf.load_layers: try: load_layer(_l, globals_dict=globals(), symb_list=__all__) except Exception as e: + raise log.warning("can't import layer %s: %s" % (_l,e)) del _l diff --git a/scapy/layers/dhcp.py b/scapy/layers/dhcp.py index ab1daad34..c40b0f186 100644 --- a/scapy/layers/dhcp.py +++ b/scapy/layers/dhcp.py @@ -16,6 +16,7 @@ from scapy.packet import * from scapy.fields import * from scapy.ansmachine import * from scapy.data import * +from scapy.compat import * from scapy.layers.inet import UDP,IP from scapy.layers.l2 import Ether from scapy.base_classes import Net @@ -182,6 +183,8 @@ class RandDHCPOptions(RandField): else: op.append((o.name, o.randval()._fix())) return op + def __bytes__(self): + return raw(self.__str__()) class DHCPOptionsField(StrField): @@ -265,17 +268,17 @@ class DHCPOptionsField(StrField): warning("Unknown field option %s" % name) continue - s += chr(onum) - s += chr(len(oval)) + s += chb(onum) + s += chb(len(oval)) s += oval elif (isinstance(o, str) and o in DHCPRevOptions and DHCPRevOptions[o][1] == None): - s += chr(DHCPRevOptions[o][0]) + s += raw(DHCPRevOptions[o][0]) elif isinstance(o, int): - s += chr(o)+b"\0" - elif isinstance(o, str): - s += o + s += chb(o)+b"\0" + elif isinstance(o, (str, bytes)): + s += raw(o) else: warning("Malformed option %s" % o) return s diff --git a/scapy/layers/dhcp6.py b/scapy/layers/dhcp6.py index e87eba4a2..847e7a2fb 100644 --- a/scapy/layers/dhcp6.py +++ b/scapy/layers/dhcp6.py @@ -19,6 +19,7 @@ from scapy.ansmachine import AnsweringMachine from scapy.arch import get_if_raw_hwaddr, in6_getifaddr from scapy.config import conf from scapy.data import EPOCH, ETHER_ANY +from scapy.compat import raw, chb from scapy.error import warning from scapy.fields import BitField, ByteEnumField, ByteField, FieldLenField, \ FlagsField, IntEnumField, IntField, MACField, PacketField, \ @@ -283,7 +284,7 @@ class _DUIDField(PacketField): self.length_from = length_from def i2m(self, pkt, i): - return str(i) + return raw(i) def m2i(self, pkt, x): cls = conf.raw_layer @@ -329,7 +330,7 @@ class _IANAOptField(PacketListField): def i2len(self, pkt, z): if z is None or z == []: return 0 - return sum(len(str(x)) for x in z) + return sum(len(raw(x)) for x in z) def getfield(self, pkt, s): l = self.length_from(pkt) @@ -757,8 +758,7 @@ class DomainNameField(StrLenField): def i2m(self, pkt, x): if not x: return b"" - tmp = b"".join(chr(len(z)) + z for z in x.split('.')) - return tmp + return b"".join(chb(len(z)) + z for z in x.split('.')) class DHCP6OptNISDomain(_DHCP6OptGuessPayload): #RFC3898 name = "DHCP6 Option - NIS Domain Name" @@ -1418,7 +1418,7 @@ DHCPv6_am.parse_options( dns="2001:500::1035", domain="localdomain, local", duid = p[DHCP6OptServerId].duid if not isinstance(duid, type(self.duid)): return False - if str(duid) != str(self.duid): + if raw(duid) != raw(self.duid): return False if (p.msgtype == 5 or # Renew @@ -1483,7 +1483,7 @@ DHCPv6_am.parse_options( dns="2001:500::1035", domain="localdomain, local", duid = p[DHCP6OptServerId].duid if not isinstance(duid, type(self.duid)): return False - if str(duid) != str(self.duid): + if raw(duid) != raw(self.duid): return False if ((DHCP6OptIA_NA in p) or (DHCP6OptIA_TA in p) or diff --git a/scapy/layers/dns.py b/scapy/layers/dns.py index e35fa9d29..98255cc50 100644 --- a/scapy/layers/dns.py +++ b/scapy/layers/dns.py @@ -13,6 +13,7 @@ import socket,struct from scapy.config import conf from scapy.packet import * from scapy.fields import * +from scapy.compat import * from scapy.ansmachine import * from scapy.sendrecv import sr1 from scapy.layers.inet import IP, DestIPField, UDP, TCP @@ -23,11 +24,10 @@ import scapy.modules.six as six from scapy.modules.six.moves import range class DNSStrField(StrField): - def h2i(self, pkt, x): - if x == "": - return "." - return x + if x == "": + return "." + return x def i2m(self, pkt, x): if x == ".": @@ -35,7 +35,7 @@ class DNSStrField(StrField): # Truncate chunks that cannot be encoded (more than 63 bytes..) x = b"".join(chr(len(y)) + y for y in (k[:63] for k in x.split("."))) - if x[-1] != b"\x00": + if ord(x[-1]) != 0: x += b"\x00" return x @@ -43,7 +43,7 @@ class DNSStrField(StrField): n = b"" if ord(s[0]) == 0: - return s[1:], b"." + return s[1:], "." while True: l = ord(s[0]) @@ -53,7 +53,7 @@ class DNSStrField(StrField): if l & 0xc0: raise Scapy_Exception("DNS message can't be compressed at this point!") else: - n += s[:l]+b"." + n += s[:l]+"." s = s[l:] return s, n @@ -123,7 +123,7 @@ class DNSRRField(StrField): def i2m(self, pkt, x): if x is None: return b"" - return str(x) + return raw(x) def decodeRR(self, name, s, p): ret = s[p:p+10] type,cls,ttl,rdlen = struct.unpack("!HHIH", ret) @@ -209,6 +209,7 @@ class RDataField(StrLenField): s += b"\x00" elif pkt.type == 16: # TXT if s: + s = raw(s) ret_s = b"" # The initial string must be splitted into a list of strings # prepended with theirs sizes. diff --git a/scapy/layers/dot11.py b/scapy/layers/dot11.py index 69b827998..a09659684 100644 --- a/scapy/layers/dot11.py +++ b/scapy/layers/dot11.py @@ -13,6 +13,7 @@ from zlib import crc32 from scapy.config import conf, crypto_validator from scapy.data import * +from scapy.compat import * from scapy.packet import * from scapy.fields import * from scapy.ansmachine import * @@ -221,7 +222,7 @@ class Dot11Elt(Packet): StrLenField("info", "", length_from=lambda x:x.len) ] def mysummary(self): if self.ID == 0: - return "SSID=%s"%repr(self.info),[Dot11] + return "SSID=%s"%repr(plain_str(self.info)),[Dot11] else: return "" @@ -292,7 +293,7 @@ class Dot11WEP(Packet): key = conf.wepkey if key: d = Cipher( - algorithms.ARC4(self.iv + key), + algorithms.ARC4(self.iv + key.encode("utf8")), None, default_backend(), ).decryptor() @@ -317,7 +318,7 @@ class Dot11WEP(Packet): else: icv = p[4:8] e = Cipher( - algorithms.ARC4(self.iv + key), + algorithms.ARC4(self.iv + key.encode("utf8")), None, default_backend(), ).encryptor() @@ -328,7 +329,7 @@ class Dot11WEP(Packet): def post_build(self, p, pay): if self.wepdata is None: - p = self.encrypt(p, pay) + p = self.encrypt(p, raw(pay)) return p @@ -408,7 +409,7 @@ iwconfig wlan0 mode managed return 0 ip = pkt.getlayer(IP) tcp = pkt.getlayer(TCP) - pay = str(tcp.payload) + pay = raw(tcp.payload) if not self.ptrn.match(pay): return 0 if self.iptrn.match(pay): @@ -417,7 +418,7 @@ iwconfig wlan0 mode managed def make_reply(self, p): ip = p.getlayer(IP) tcp = p.getlayer(TCP) - pay = str(tcp.payload) + pay = raw(tcp.payload) del(p.payload.payload.payload) p.FCfield="from-DS" p.addr1,p.addr2 = p.addr2,p.addr1 @@ -471,7 +472,7 @@ iwconfig wlan0 mode managed return ip = p.getlayer(IP) tcp = p.getlayer(TCP) - pay = str(tcp.payload) + pay = raw(tcp.payload) if not ptrn.match(pay): return if iptrn.match(pay): diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py index be474e653..5246c9ae3 100644 --- a/scapy/layers/inet.py +++ b/scapy/layers/inet.py @@ -9,7 +9,7 @@ IPv4 (Internet Protocol v4). from __future__ import absolute_import from __future__ import print_function -import os,time,struct,re,socket,new +import os, time, struct, re, socket, types from select import select from collections import defaultdict @@ -17,6 +17,7 @@ from scapy.utils import checksum,inet_aton,inet_ntoa from scapy.base_classes import Gen from scapy.data import * from scapy.layers.l2 import * +from scapy.compat import * from scapy.config import conf from scapy.consts import OPENBSD, WINDOWS from scapy.fields import * @@ -288,7 +289,7 @@ class TCPOptionsField(StrField): def i2m(self, pkt, x): opt = b"" - for oname,oval in x: + for oname, oval in x: if isinstance(oname, str): if oname == "NOP": opt += b"\x01" @@ -313,7 +314,7 @@ class TCPOptionsField(StrField): if not isinstance(oval, str): warning("option [%i] is not string."%onum) continue - opt += chr(onum)+chr(2+len(oval))+oval + opt += chb(onum) + chb(2+len(oval))+ raw(oval) return opt+b"\x00"*(3-((len(opt)+3)%4)) def randval(self): return [] # XXX @@ -380,13 +381,13 @@ class IP(Packet, IPTools): p += b"\0"*((-len(p))%4) # pad IP options if needed if ihl is None: ihl = len(p)//4 - p = chr(((self.version&0xf)<<4) | ihl&0x0f)+p[1:] + p = chb(((self.version&0xf)<<4) | ihl&0x0f)+p[1:] if self.len is None: l = len(p)+len(pay) p = p[:2]+struct.pack("!H", l)+p[4:] if self.chksum is None: ck = checksum(p) - p = p[:10]+chr(ck>>8)+chr(ck&0xff)+p[12:] + p = p[:10]+chb(ck>>8)+chb(ck&0xff)+p[12:] return p+pay def extract_padding(self, s): @@ -459,7 +460,7 @@ class IP(Packet, IPTools): fl = fl.underlayer for p in fl: - s = str(p[fnb].payload) + s = raw(p[fnb].payload) nb = (len(s)+fragsize-1)//fragsize for i in range(nb): q = p.copy() @@ -521,7 +522,7 @@ class TCP(Packet): dataofs = self.dataofs if dataofs is None: dataofs = 5+((len(self.get_field("options").i2m(self,self.options))+3)//4) - p = p[:12]+chr((dataofs << 4) | ord(p[12])&0x0f)+p[13:] + p = p[:12]+chb((dataofs << 4) | ord(p[12])&0x0f)+p[13:] if self.chksum is None: if isinstance(self.underlayer, IP): ck = in4_chksum(socket.IPPROTO_TCP, self.underlayer, p) @@ -689,7 +690,7 @@ class ICMP(Packet): p += pay if self.chksum is None: ck = checksum(p) - p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:] + p = p[:2] + chb(ck>>8) + chb(ck&0xff) + p[4:] return p def hashret(self): @@ -834,7 +835,7 @@ def fragment(pkt, fragsize=1480): fragsize = (fragsize+7)//8*8 lst = [] for p in pkt: - s = str(p[IP].payload) + s = raw(p[IP].payload) nb = (len(s)+fragsize-1)//fragsize for i in range(nb): q = p.copy() @@ -924,7 +925,7 @@ def defrag(plist): defrag.append(p) defrag2=PacketList() for p in defrag: - defrag2.append(p.__class__(str(p))) + defrag2.append(p.__class__(raw(p))) return nofrag,defrag2,missfrag @conf.commands.register @@ -986,7 +987,7 @@ def defragment(plist): defrag.append(p) defrag2=[] for p in defrag: - q = p.__class__(str(p)) + q = p.__class__(raw(p)) q._defrag_pos = p._defrag_pos defrag2.append(q) final += defrag2 @@ -1052,7 +1053,7 @@ def _packetlist_timeskew_graph(self, ip, **kargs): return lines -PacketList.timeskew_graph = new.instancemethod(_packetlist_timeskew_graph, None, PacketList) +PacketList.timeskew_graph = _packetlist_timeskew_graph ### Create a new packet list @@ -1568,7 +1569,7 @@ class TCP_client(Automaton): raise self.ESTABLISHED().action_parameters(pkt) @ATMT.action(incoming_data_received) def receive_data(self,pkt): - data = str(pkt[TCP].payload) + data = raw(pkt[TCP].payload) if data and self.l4[TCP].ack == pkt[TCP].seq: self.l4[TCP].ack += len(data) self.l4[TCP].flags = "A" diff --git a/scapy/layers/inet6.py b/scapy/layers/inet6.py index b325ace3e..5b1577349 100644 --- a/scapy/layers/inet6.py +++ b/scapy/layers/inet6.py @@ -43,6 +43,7 @@ if not hasattr(socket, "IPPROTO_IPIP"): from scapy.config import conf from scapy.base_classes import * from scapy.data import * +from scapy.compat import * from scapy.fields import * from scapy.packet import * from scapy.volatile import * @@ -221,7 +222,7 @@ class IP6Field(Field): x = [Net6(a) for a in x] return x def i2m(self, pkt, x): - return inet_pton(socket.AF_INET6, x) + return inet_pton(socket.AF_INET6, plain_str(x)) def m2i(self, pkt, x): return inet_ntop(socket.AF_INET6, x) def any2i(self, pkt, x): @@ -602,8 +603,8 @@ class IPerror6(IPv6): selfup.dataofs = 0 # Test it and save result - s1 = str(selfup) - s2 = str(otherup) + s1 = raw(selfup) + s2 = raw(otherup) l = min(len(s1), len(s2)) res = s1[:l] == s2[:l] @@ -617,8 +618,8 @@ class IPerror6(IPv6): return res - s1 = str(selfup) - s2 = str(otherup) + s1 = raw(selfup) + s2 = raw(otherup) l = min(len(s1), len(s2)) return s1[:l] == s2[:l] @@ -692,7 +693,7 @@ def in6_chksum(nh, u, p): else: ph6.dst = u.dst ph6.uplen = len(p) - ph6s = str(ph6) + ph6s = raw(ph6) return checksum(ph6s+p) @@ -887,10 +888,10 @@ class _HopByHopOptionsField(PacketListField): d = p.alignment_delta(curpos) curpos += d if d == 1: - s += str(Pad1()) + s += raw(Pad1()) elif d != 0: - s += str(PadN(optdata=b'\x00'*(d-2))) - pstr = str(p) + s += raw(PadN(optdata=b'\x00'*(d-2))) + pstr = raw(p) curpos += len(pstr) s += pstr @@ -901,9 +902,9 @@ class _HopByHopOptionsField(PacketListField): return s d = 8 - d if d == 1: - s += str(Pad1()) + s += raw(Pad1()) elif d != 0: - s += str(PadN(optdata=b'\x00'*(d-2))) + s += raw(PadN(optdata=b'\x00'*(d-2))) return s @@ -1054,7 +1055,7 @@ class IPv6ExtHdrSegmentRouting(_IPv6ExtHdr): #Add the padding extension tmp_pad = b"\x00" * (tmp_mod-2) tlv = IPv6ExtHdrSegmentRoutingTLVPadding(padding=tmp_pad) - pkt += str(tlv) + pkt += raw(tlv) tmp_len = (len(pkt) - 8) // 8 pkt = pkt[:1] + struct.pack("B", tmp_len)+ pkt[2:] @@ -1124,7 +1125,7 @@ def defragment6(packets): if offset != len(fragmentable): warning("Expected an offset of %d. Found %d. Padding with XXXX" % (len(fragmentable), offset)) fragmentable += b"X"*(offset - len(fragmentable)) - fragmentable += str(q.payload) + fragmentable += raw(q.payload) # Regenerate the unfragmentable part. q = res[0] @@ -1133,7 +1134,7 @@ def defragment6(packets): del q[IPv6ExtHdrFragment].underlayer.payload q /= conf.raw_layer(load=fragmentable) - return IPv6(str(q)) + return IPv6(raw(q)) def fragment6(pkt, fragSize): @@ -1156,18 +1157,18 @@ def fragment6(pkt, fragSize): # If the payload is bigger than 65535, a Jumbo payload must be used, as # an IPv6 packet can't be bigger than 65535 bytes. - if len(str(pkt[IPv6ExtHdrFragment])) > 65535: + if len(raw(pkt[IPv6ExtHdrFragment])) > 65535: warning("An IPv6 packet can'be bigger than 65535, please use a Jumbo payload.") return [] - s = str(pkt) # for instantiation to get upper layer checksum right + s = raw(pkt) # for instantiation to get upper layer checksum right if len(s) <= fragSize: return [pkt] # Fragmentable part : fake IPv6 for Fragmentable part length computation fragPart = pkt[IPv6ExtHdrFragment].payload - tmp = str(IPv6(src="::1", dst="::1")/fragPart) + tmp = raw(IPv6(src="::1", dst="::1")/fragPart) fragPartLen = len(tmp) - 40 # basic IPv6 header length fragPartStr = s[-fragPartLen:] @@ -1707,7 +1708,7 @@ class TruncPktLenField(PacketLenField): return s def i2m(self, pkt, x): - s = str(x) + s = raw(x) l = len(s) r = (l + self.cur_shift) % 8 l = l - r @@ -1896,6 +1897,7 @@ class DomainNameListField(StrLenField): return len(self.i2m(pkt, x)) def m2i(self, pkt, x): + x = plain_str(x) res = [] while x: # Get a name until \x00 is reached @@ -1917,12 +1919,12 @@ class DomainNameListField(StrLenField): def i2m(self, pkt, x): def conditionalTrailingDot(z): - if z and z[-1] == '\x00': + if z and z[-1] == b'\x00': return z - return z+'\x00' + return z+b'\x00' # Build the encode names - tmp = [[chr(len(z)) + z for z in y.split('.')] for y in x] - ret_string = "".join(conditionalTrailingDot("".join(x)) for x in tmp) + tmp = [[chb(len(z)) + z for z in y.split('.')] for y in x] + ret_string = b"".join(conditionalTrailingDot(b"".join(x)) for x in tmp) # In padded mode, add some \x00 bytes if self.padded and not len(ret_string) % self.padded_unit == 0: @@ -1988,7 +1990,7 @@ class ICMPv6ND_NS(_ICMPv6NDGuessPayload, _ICMPv6, Packet): return self.sprintf("%name% (tgt: %tgt%)") def hashret(self): - return self.tgt+self.payload.hashret() + return raw(self.tgt)+self.payload.hashret() class ICMPv6ND_NA(_ICMPv6NDGuessPayload, _ICMPv6, Packet): name = "ICMPv6 Neighbor Discovery - Neighbor Advertisement" @@ -2006,7 +2008,7 @@ class ICMPv6ND_NA(_ICMPv6NDGuessPayload, _ICMPv6, Packet): return self.sprintf("%name% (tgt: %tgt%)") def hashret(self): - return self.tgt+self.payload.hashret() + return raw(self.tgt)+self.payload.hashret() def answers(self, other): return isinstance(other, ICMPv6ND_NS) and self.tgt == other.tgt @@ -2156,16 +2158,19 @@ def names2dnsrepr(x): """ if isinstance(x, str): - if x and x[-1] == b'\x00': # stupid heuristic + if x and x[-1] == '\x00': # stupid heuristic + return x.encode("utf8") + x = [x.encode("utf8")] + elif type(x) is bytes: + if x and x[-1] == 0: return x - x = [x] res = [] for n in x: termin = b"\x00" - if n.count('.') == 0: # single-component gets one more + if n.count(b'.') == 0: # single-component gets one more termin += b'\x00' - n = b"".join(chr(len(y)) + y for y in n.split('.')) + termin + n = b"".join(chb(len(y)) + y for y in n.split(b'.')) + termin res.append(n) return b"".join(res) @@ -2231,6 +2236,7 @@ class NIQueryDataField(StrField): return val def i2repr(self, pkt, x): + x = plain_str(x) t,val = x if t == 1: # DNS Name # we don't use dnsrepr2names() to deal with @@ -2848,7 +2854,7 @@ class _MobilityHeader(Packet): cksum = in6_chksum(135, self.underlayer, p) else: cksum = self.cksum - p = p[:4]+struct.pack("!H", cksum)+p[6:] + p = chb(p[:4])+struct.pack("!H", cksum)+chb(p[6:]) return p @@ -2894,7 +2900,7 @@ class _MobilityOptionsField(PacketListField): x = op.payload.load del(op.payload) else: - x = "" + x = b"" return opt def i2m(self, pkt, x): @@ -2913,10 +2919,10 @@ class _MobilityOptionsField(PacketListField): d = p.alignment_delta(curpos) curpos += d if d == 1: - s += str(Pad1()) + s += raw(Pad1()) elif d != 0: - s += str(PadN(optdata=b'\x00'*(d-2))) - pstr = str(p) + s += raw(PadN(optdata=b'\x00'*(d-2))) + pstr = raw(p) curpos += len(pstr) s += pstr @@ -2927,9 +2933,9 @@ class _MobilityOptionsField(PacketListField): return s d = 8 - d if d == 1: - s += str(Pad1()) + s += raw(Pad1()) elif d != 0: - s += str(PadN(optdata=b'\x00'*(d-2))) + s += raw(PadN(optdata=b'\x00'*(d-2))) return s @@ -2968,7 +2974,7 @@ class MIP6MH_HoTI(_MobilityHeader): length_from = lambda pkt: 8*(pkt.len-1)) ] overload_fields = { IPv6: { "nh": 135 } } def hashret(self): - return self.cookie + return bytes(self.cookie) class MIP6MH_CoTI(MIP6MH_HoTI): name = "IPv6 Mobility Header - Care-of Test Init" diff --git a/scapy/layers/ipsec.py b/scapy/layers/ipsec.py index 254f8e170..91cd98ecb 100644 --- a/scapy/layers/ipsec.py +++ b/scapy/layers/ipsec.py @@ -23,7 +23,7 @@ Example of use: >>> p = IP(src='1.1.1.1', dst='2.2.2.2') >>> p /= TCP(sport=45012, dport=80) >>> p /= Raw('testdata') ->>> p = IP(str(p)) +>>> p = IP(raw(p)) >>> p >> >>> @@ -47,6 +47,7 @@ import struct from scapy.config import conf, crypto_validator from scapy.data import IP_PROTOS +from scapy.compat import * from scapy.error import log_loading from scapy.fields import ByteEnumField, ByteField, IntField, PacketField, \ ShortField, StrField, XIntField, XStrField, XStrLenField @@ -532,12 +533,12 @@ class AuthAlgo(object): mac = self.new_mac(key) if pkt.haslayer(ESP): - mac.update(str(pkt[ESP])) + mac.update(raw(pkt[ESP])) pkt[ESP].data += mac.finalize()[:self.icv_size] elif pkt.haslayer(AH): clone = zero_mutable_fields(pkt.copy(), sending=True) - mac.update(str(clone)) + mac.update(raw(clone)) pkt[AH].icv = mac.finalize()[:self.icv_size] return pkt @@ -572,7 +573,7 @@ class AuthAlgo(object): pkt_icv = pkt[AH].icv clone = zero_mutable_fields(pkt.copy(), sending=False) - mac.update(str(clone)) + mac.update(raw(clone)) computed_icv = mac.finalize()[:self.icv_size] # XXX: Cannot use mac.verify because the ICV can be truncated @@ -631,7 +632,7 @@ def split_for_transport(orig_pkt, transport_proto): payload. """ # force resolution of default fields to avoid padding errors - header = orig_pkt.__class__(str(orig_pkt)) + header = orig_pkt.__class__(raw(orig_pkt)) next_hdr = header.payload nh = None @@ -847,7 +848,7 @@ class SecurityAssociation(object): del tunnel.nh del tunnel.plen - pkt = tunnel.__class__(str(tunnel / pkt)) + pkt = tunnel.__class__(raw(tunnel / pkt)) ip_header, nh, payload = split_for_transport(pkt, socket.IPPROTO_ESP) esp.data = payload @@ -919,7 +920,7 @@ class SecurityAssociation(object): if ip_header.version == 4: ip_header.len = len(ip_header) + len(ah) + len(payload) del ip_header.chksum - ip_header = ip_header.__class__(str(ip_header)) + ip_header = ip_header.__class__(raw(ip_header)) else: ip_header.plen = len(ip_header.payload) + len(ah) + len(payload) @@ -984,7 +985,7 @@ class SecurityAssociation(object): ip_header.remove_payload() ip_header.len = len(ip_header) + len(esp.data) # recompute checksum - ip_header = ip_header.__class__(str(ip_header)) + ip_header = ip_header.__class__(raw(ip_header)) else: encrypted.underlayer.nh = esp.nh encrypted.underlayer.remove_payload() @@ -1016,7 +1017,7 @@ class SecurityAssociation(object): ip_header.remove_payload() ip_header.len = len(ip_header) + len(payload) # recompute checksum - ip_header = ip_header.__class__(str(ip_header)) + ip_header = ip_header.__class__(raw(ip_header)) else: ah.underlayer.nh = ah.nh ah.underlayer.remove_payload() diff --git a/scapy/layers/isakmp.py b/scapy/layers/isakmp.py index 0bd3ad3af..c6d0f0af1 100644 --- a/scapy/layers/isakmp.py +++ b/scapy/layers/isakmp.py @@ -11,6 +11,7 @@ from __future__ import absolute_import import struct from scapy.config import conf from scapy.packet import * +from scapy.compat import * from scapy.fields import * from scapy.ansmachine import * from scapy.layers.inet import IP,UDP @@ -113,7 +114,7 @@ class ISAKMPTransformSetField(StrLenField): warning("%r should not be TLV but is too big => using TLV encoding" % typ) n = 0 while val: - s = chr(val&0xff)+s + s = chb(val&0xff)+s val >>= 8 n += 1 val = n @@ -232,7 +233,7 @@ class ISAKMP_payload_Transform(ISAKMP_class): def post_build(self, p, pay): if self.length is None: l = len(p) - p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:] + p = p[:2]+chb((l>>8)&0xff)+chb(l&0xff)+p[4:] p += pay return p diff --git a/scapy/layers/l2.py b/scapy/layers/l2.py index d8f540d77..d11135982 100644 --- a/scapy/layers/l2.py +++ b/scapy/layers/l2.py @@ -15,6 +15,7 @@ from scapy.base_classes import Net from scapy.config import conf from scapy.consts import OPENBSD from scapy.data import * +from scapy.compat import * from scapy.packet import * from scapy.ansmachine import * from scapy.plist import SndRcvList @@ -62,7 +63,7 @@ def getmacbyip(ip, chainCC=0): if isinstance(ip,Net): ip = iter(ip).next() ip = inet_ntoa(inet_aton(ip)) - tmp = [ord(e) for e in inet_aton(ip)] + tmp = [orb(e) for e in inet_aton(ip)] if (tmp[0] & 0xf0) == 0xe0: # mcast @ return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3]) iff,a,gw = conf.route.route(ip) @@ -350,7 +351,7 @@ class GRE(Packet): p += pay if self.chksum_present and self.chksum is None: c = checksum(p) - p = p[:4]+chr((c>>8)&0xff)+chr(c&0xff)+p[6:] + p = p[:4]+chb((c>>8)&0xff)+chb(c&0xff)+p[6:] return p @@ -381,7 +382,7 @@ class GRE_PPTP(GRE): p += pay if self.payload_len is None: pay_len = len(pay) - p = p[:4] + chr((pay_len >> 8) & 0xff) + chr(pay_len & 0xff) + p[6:] + p = p[:4] + chb((pay_len >> 8) & 0xff) + chb(pay_len & 0xff) + p[6:] return p diff --git a/scapy/layers/lltd.py b/scapy/layers/lltd.py index d1c109039..560c8eecd 100644 --- a/scapy/layers/lltd.py +++ b/scapy/layers/lltd.py @@ -24,6 +24,8 @@ from scapy.layers.inet import IPField from scapy.layers.inet6 import IP6Field from scapy.data import ETHER_ANY import scapy.modules.six as six +from scapy.compat import * + # Protocol layers ################## @@ -215,7 +217,7 @@ class LLTDQueryResp(Packet): # unsupported format (14 bits) flags = ord(pkt[0]) & 0xc0 count = len(self.descs_list) - pkt = chr(flags + (count >> 8)) + chr(count % 256) + pkt[2:] + pkt = chb(flags + (count >> 8)) + chb(count % 256) + pkt[2:] return pkt + pay def mysummary(self): @@ -257,7 +259,7 @@ class LLTDQueryLargeTlvResp(Packet): # format (14 bits) flags = ord(pkt[0]) & 0xc0 length = len(self.value) - pkt = chr(flags + (length >> 8)) + chr(length % 256) + pkt[2:] + pkt = chb(flags + (length >> 8)) + chb(length % 256) + pkt[2:] return pkt + pay def mysummary(self): diff --git a/scapy/layers/ntp.py b/scapy/layers/ntp.py index e9374c4ec..d5590fac5 100644 --- a/scapy/layers/ntp.py +++ b/scapy/layers/ntp.py @@ -22,6 +22,7 @@ PacketListField, FieldListField, ConditionalField, PadField) from scapy.layers.inet6 import IP6Field from scapy.layers.inet import UDP from scapy.utils import lhex +from scapy.compat import * from scapy.config import conf import scapy.modules.six as six from scapy.modules.six.moves import range @@ -198,7 +199,7 @@ def _ntp_dispatcher(payload): else: length = len(payload) if length >= _NTP_PACKET_MIN_SIZE: - first_byte = struct.unpack("!B", payload[0])[0] + first_byte = struct.unpack("!B", raw(payload[0]))[0] # Extract NTP mode mode_mask = 0x07 diff --git a/scapy/layers/ppp.py b/scapy/layers/ppp.py index 3aacafea6..5bcc8e2db 100644 --- a/scapy/layers/ppp.py +++ b/scapy/layers/ppp.py @@ -12,6 +12,7 @@ PPP (Point to Point Protocol) import struct from scapy.config import conf from scapy.data import DLT_PPP, DLT_PPP_SERIAL, DLT_PPP_ETHER +from scapy.compat import * from scapy.packet import Packet, bind_layers from scapy.layers.eap import EAP from scapy.layers.l2 import Ether, CookedLinux, GRE_PPTP @@ -207,7 +208,7 @@ class PPP(Packet): fields_desc = [ ShortEnumField("proto", 0x0021, _PPP_proto) ] @classmethod def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and _pkt[0] == b'\xff': + if _pkt and ord(_pkt[0]) == 0xff: cls = HDLC return cls diff --git a/scapy/layers/sctp.py b/scapy/layers/sctp.py index e2b51d380..253a29484 100644 --- a/scapy/layers/sctp.py +++ b/scapy/layers/sctp.py @@ -11,6 +11,7 @@ SCTP (Stream Control Transmission Protocol). from __future__ import absolute_import import struct +from scapy.compat import * from scapy.volatile import RandBin from scapy.config import conf from scapy.packet import * @@ -235,7 +236,7 @@ class SCTP(_SCTPChunkGuessPayload, Packet): def post_build(self, p, pay): p += pay if self.chksum is None: - crc = crc32c(str(p)) + crc = crc32c(raw(p)) p = p[:8]+struct.pack(">I", crc)+p[12:] return p @@ -254,7 +255,7 @@ class ChunkParamField(PacketListField): # dummy class to avoid Raw() after Chunk params class _SCTPChunkParam: def extract_padding(self, s): - return "",s[:] + return b"",s[:] class SCTPChunkParamHearbeatInfo(_SCTPChunkParam, Packet): fields_desc = [ ShortEnumField("type", 1, sctpchunkparamtypes), diff --git a/scapy/layers/tls/cert.py b/scapy/layers/tls/cert.py index e6c4816ec..9f9128837 100644 --- a/scapy/layers/tls/cert.py +++ b/scapy/layers/tls/cert.py @@ -51,6 +51,8 @@ from scapy.layers.tls.crypto.pkcs1 import (pkcs_os2ip, pkcs_i2osp, _get_hash, _EncryptAndVerifyRSA, _DecryptAndSignRSA) +from scapy.compat import * + # Maximum allowed size in bytes for a certificate file, to avoid # loading huge file when importing a cert _MAX_KEY_SIZE = 50*1024 @@ -66,6 +68,7 @@ _MAX_CRL_SIZE = 10*1024*1024 # some are that big def der2pem(der_string, obj="UNKNOWN"): """Convert DER octet string to PEM format (with optional header)""" # Encode a byte string in PEM format. Header advertizes type. + obj = raw(obj) pem_string = b"-----BEGIN %s-----\n" % obj base64_string = base64.b64encode(der_string) chunks = [base64_string[i:i+64] for i in range(0, len(base64_string), 64)] @@ -128,6 +131,7 @@ class _PKIObjMaker(type): if obj_path is None: raise Exception(error_msg) + obj_path = raw(obj_path) if (not b'\x00' in obj_path) and os.path.isfile(obj_path): _size = os.path.getsize(obj_path) @@ -135,25 +139,25 @@ class _PKIObjMaker(type): raise Exception(error_msg) try: f = open(obj_path) - raw = f.read() + _raw = f.read() f.close() except: raise Exception(error_msg) else: - raw = obj_path + _raw = obj_path try: - if b"-----BEGIN" in raw: + if b"-----BEGIN" in _raw: frmt = "PEM" - pem = raw - der_list = split_pem(raw) + pem = _raw + der_list = split_pem(_raw) der = b''.join(map(pem2der, der_list)) else: frmt = "DER" - der = raw + der = _raw pem = "" if pem_marker is not None: - pem = der2pem(raw, pem_marker) + pem = der2pem(_raw, pem_marker) # type identification may be needed for pem_marker # in such case, the pem attribute has to be updated except: @@ -509,7 +513,7 @@ class PrivKeyECDSA(PrivKey): @crypto_validator def import_from_asn1pkt(self, privkey): - self.key = serialization.load_der_private_key(str(privkey), None, + self.key = serialization.load_der_private_key(raw(privkey), None, backend=default_backend()) self.pubkey = self.key.public_key() diff --git a/scapy/layers/tls/crypto/h_mac.py b/scapy/layers/tls/crypto/h_mac.py index c91060628..e36c1b0ab 100644 --- a/scapy/layers/tls/crypto/h_mac.py +++ b/scapy/layers/tls/crypto/h_mac.py @@ -12,7 +12,7 @@ import hmac from scapy.layers.tls.crypto.hash import _tls_hash_algs import scapy.modules.six as six - +from scapy.compat import * _SSLv3_PAD1_MD5 = b"\x36"*48 _SSLv3_PAD1_SHA1 = b"\x36"*40 @@ -57,7 +57,7 @@ class _GenericHMAC(six.with_metaclass(_GenericHMACMetaclass, object)): def digest(self, tbd): if self.key is None: raise HMACError - return hmac.new(self.key, tbd, self.hash_alg.hash_cls).digest() + return hmac.new(raw(self.key), raw(tbd), self.hash_alg.hash_cls).digest() def digest_sslv3(self, tbd): if self.key is None: diff --git a/scapy/layers/tls/crypto/pkcs1.py b/scapy/layers/tls/crypto/pkcs1.py index 870990b80..a3f394527 100644 --- a/scapy/layers/tls/crypto/pkcs1.py +++ b/scapy/layers/tls/crypto/pkcs1.py @@ -12,6 +12,7 @@ Ubuntu or OSX. This is why we reluctantly keep some legacy crypto here. """ from __future__ import absolute_import +from scapy.compat import * from scapy.config import conf, crypto_validator if conf.crypto_valid: @@ -37,7 +38,7 @@ def pkcs_os2ip(s): Input : s octet string to be converted Output: n corresponding nonnegative integer """ - return int(s.encode("hex"), 16) + return int(bytes_hex(s), 16) def pkcs_i2osp(n, sLen): """ @@ -52,7 +53,7 @@ def pkcs_i2osp(n, sLen): #if n >= 256**sLen: # raise Exception("Integer too large for provided sLen %d" % sLen) fmt = "%%0%dx" % (2*sLen) - return (fmt % n).decode("hex") + return hex_bytes(fmt % n) def pkcs_ilen(n): """ @@ -218,4 +219,3 @@ class _DecryptAndSignRSA(object): privExp = self.key.private_numbers().d s = pow(m, privExp, n) return pkcs_i2osp(s, k) - diff --git a/scapy/layers/tls/crypto/prf.py b/scapy/layers/tls/crypto/prf.py index 2895234c7..848278976 100644 --- a/scapy/layers/tls/crypto/prf.py +++ b/scapy/layers/tls/crypto/prf.py @@ -14,6 +14,7 @@ from scapy.utils import strxor from scapy.layers.tls.crypto.hash import _tls_hash_algs from scapy.layers.tls.crypto.h_mac import _tls_hmac_algs from scapy.modules.six.moves import range +from scapy.compat import * ### Data expansion functions @@ -42,7 +43,7 @@ def _tls_P_hash(secret, seed, req_len, hm): a = hm(secret).digest(seed) # A(1) while n > 0: - res += hm(secret).digest(a + seed) + res += hm(secret).digest(a + raw(seed)) a = hm(secret).digest(a) n -= 1 diff --git a/scapy/layers/tls/record.py b/scapy/layers/tls/record.py index 4526b637a..ab9d293c5 100644 --- a/scapy/layers/tls/record.py +++ b/scapy/layers/tls/record.py @@ -17,6 +17,7 @@ import struct from scapy.config import conf from scapy.fields import * +from scapy.compat import * from scapy.packet import * from scapy.layers.inet import TCP from scapy.layers.tls.session import _GenericTLSSessionInheritance @@ -164,10 +165,10 @@ class _TLSMsgListField(PacketListField): cur = p.str_stateful() p.post_build_tls_session_update(cur) else: - cur = str(p) + cur = raw(p) else: pkt.type = 23 - cur = str(p) + cur = raw(p) return cur def addfield(self, pkt, s, val): @@ -735,4 +736,3 @@ class TLSApplicationData(_GenericTLSSessionInheritance): bind_bottom_up(TCP, TLS, {"dport": 443}) bind_bottom_up(TCP, TLS, {"sport": 443}) - diff --git a/scapy/layers/vrrp.py b/scapy/layers/vrrp.py index bd50e45b2..249a00cb8 100644 --- a/scapy/layers/vrrp.py +++ b/scapy/layers/vrrp.py @@ -10,6 +10,7 @@ VRRP (Virtual Router Redundancy Protocol). from scapy.packet import * from scapy.fields import * +from scapy.compat import * from scapy.layers.inet import * from scapy.layers.inet6 import * from scapy.error import warning @@ -35,7 +36,7 @@ class VRRP(Packet): def post_build(self, p, pay): if self.chksum is None: ck = checksum(p) - p = p[:6]+chr(ck>>8)+chr(ck&0xff)+p[8:] + p = p[:6]+chb(ck>>8)+chb(ck&0xff)+p[8:] return p @classmethod diff --git a/scapy/modules/nmap.py b/scapy/modules/nmap.py index 2b4162b65..29650a686 100644 --- a/scapy/modules/nmap.py +++ b/scapy/modules/nmap.py @@ -27,6 +27,7 @@ from scapy.error import warning from scapy.layers.inet import IP, TCP, UDP, ICMP, UDPerror, IPerror from scapy.packet import NoPayload from scapy.sendrecv import sr +from scapy.compat import * import scapy.modules.six as six @@ -64,6 +65,7 @@ None. name = None sig = {} for line in fdesc: + line = plain_str(line) line = line.split('#', 1)[0].strip() if not line: continue diff --git a/scapy/packet.py b/scapy/packet.py index b12967bf5..12ba22c27 100644 --- a/scapy/packet.py +++ b/scapy/packet.py @@ -17,6 +17,7 @@ import subprocess from scapy.fields import StrField, ConditionalField, Emph, PacketListField, BitField, \ MultiEnumField, EnumField, FlagsField from scapy.config import conf +from scapy.compat import * from scapy.base_classes import BasePacket, Gen, SetGen, Packet_metaclass from scapy.volatile import VolatileValue from scapy.utils import import_hexcap,tex_escape,colgen,get_temp_file, \ @@ -36,6 +37,8 @@ class RawVal: self.val = val def __str__(self): return str(self.val) + def __bytes__(self): + return raw(self.val) def __repr__(self): return "" % self.val @@ -175,10 +178,10 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): if t in payload.overload_fields: self.overloaded_fields = payload.overload_fields[t] break - elif isinstance(payload, str): + elif isinstance(payload, bytes): self.payload = conf.raw_layer(load=payload) else: - raise TypeError("payload must be either 'Packet' or 'str', not [%s]" % repr(payload)) + raise TypeError("payload must be either 'Packet' or 'bytes', not [%s]" % repr(payload)) def remove_payload(self): self.payload.remove_underlayer(self) self.payload = NoPayload() @@ -311,6 +314,8 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): repr(self.payload), ct.punct(">")) def __str__(self): + return str(self.build()) + def __bytes__(self): return self.build() def __div__(self, other): if isinstance(other, Packet): @@ -318,13 +323,13 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): cloneB = other.copy() cloneA.add_payload(cloneB) return cloneA - elif isinstance(other, str): + elif isinstance(other, (bytes, str)): return self/conf.raw_layer(load=other) else: return other.__rdiv__(self) __truediv__ = __div__ def __rdiv__(self, other): - if isinstance(other, str): + if isinstance(other, (bytes, str)): return conf.raw_layer(load=other)/self else: raise TypeError @@ -341,7 +346,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): return True __bool__ = __nonzero__ def __len__(self): - return len(self.__str__()) + return len(self.__bytes__()) def copy_field_value(self, fieldname, value): return self.get_field(fieldname).do_copy(value) def copy_fields_dict(self, fields): @@ -367,7 +372,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): for f in self.fields_desc: val = self.getfieldval(f.name) if isinstance(val, RawVal): - sval = str(val) + sval = raw(val) p += sval if field_pos_list is not None: field_pos_list.append( (f.name, sval.encode("string_escape"), len(p), len(sval) ) ) @@ -390,7 +395,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): :return: a string of the packet with the payload """ if not self.explicit: - self = self.__iter__().next() + self = next(iter(self)) pkt = self.self_build() for t in self.post_transforms: pkt = t(pkt) @@ -435,7 +440,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): if isinstance(f, ConditionalField) and not f._evalcond(self): continue p = f.addfield(self, p, self.getfieldval(f.name) ) - if isinstance(p, str): + if isinstance(p, bytes): r = p[len(q):] q = p else: @@ -502,7 +507,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): raise ImportError("PyX and its depedencies must be installed") canvas = pyx.canvas.canvas() if rebuild: - p,t = self.__class__(str(self)).build_ps() + p,t = self.__class__(raw(self)).build_ps() else: p,t = self.build_ps() YTXT=len(t) @@ -598,7 +603,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): last_shift,last_y=0,0.0 while t: - bkcol = backcolor.next() + bkcol = next(backcolor) proto,fields = t.pop() y += 0.5 pt = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % proto.name, [ pyx.text.size.Large]) @@ -608,7 +613,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): canvas.stroke(ptbb.path(),[pyx.color.rgb.black, pyx.deco.filled([bkcol])]) canvas.insert(pt) for fname, fval, fdump in fields: - col = forecolor.next() + col = next(forecolor) ft = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fname.name)) if isinstance(fval, str): if len(fval) > 18: @@ -664,7 +669,8 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): return s def do_dissect(self, s): - raw = s + s = raw(s) + _raw = s self.raw_packet_cache_fields = {} for f in self.fields_desc: if not s: @@ -675,8 +681,8 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): if f.islist or f.holds_packets or f.ismutable: self.raw_packet_cache_fields[f.name] = f.do_copy(fval) self.fields[f.name] = fval - assert(raw.endswith(s)) - self.raw_packet_cache = raw[:-len(s)] if s else raw + assert(_raw.endswith(s)) + self.raw_packet_cache = _raw[:-len(s)] if s else _raw self.explicit = 1 return s @@ -811,7 +817,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): """True if other is an answer from self (self ==> other).""" if isinstance(other, Packet): return other < self - elif isinstance(other, str): + elif isinstance(other, bytes): return 1 else: raise TypeError((self, other)) @@ -819,7 +825,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): """True if self is an answer from other (other ==> self).""" if isinstance(other, Packet): return self.answers(other) - elif isinstance(other, str): + elif isinstance(other, bytes): return 1 else: raise TypeError((self, other)) @@ -915,7 +921,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): if ret is None: if isinstance(lname, Packet_metaclass): lname = lname.__name__ - elif not isinstance(lname, str): + elif not isinstance(lname, bytes): lname = repr(lname) raise IndexError("Layer [%s] not found" % lname) return ret @@ -1022,7 +1028,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)): :param str label_lvl: additional information about the layer fields :return: return a hierarchical view if dump, else print it """ - return self.__class__(str(self)).show(dump, indent, lvl, label_lvl) + return self.__class__(raw(self)).show(dump, indent, lvl, label_lvl) def sprintf(self, fmt, relax=1): """sprintf(format, [relax=1]) -> str @@ -1172,7 +1178,7 @@ A side effect is that, to obtain "{" and "}" characters, you must use def decode_payload_as(self,cls): """Reassembles the payload and decode it using another packet class""" - s = str(self.payload) + s = raw(self.payload) self.payload = cls(s, _internal=1, _underlayer=self) pp = self while pp.underlayer is not None: @@ -1224,6 +1230,8 @@ class NoPayload(Packet): return "" def __str__(self): return "" + def __bytes__(self): + return b"" def __nonzero__(self): return False __bool__ = __nonzero__ @@ -1289,7 +1297,7 @@ class Raw(Packet): fields_desc = [ StrField("load", "") ] def answers(self, other): return 1 -# s = str(other) +# s = raw(other) # t = self.load # l = min(len(s), len(t)) # return s[:l] == t[:l] @@ -1307,7 +1315,7 @@ class Padding(Raw): def self_build(self): return b"" def build_padding(self): - return (self.load if self.raw_packet_cache is None + return (raw(self.load) if self.raw_packet_cache is None else self.raw_packet_cache) + self.payload.build_padding() conf.raw_layer = Raw diff --git a/scapy/pipetool.py b/scapy/pipetool.py index ba4a0f032..889a2f8a0 100644 --- a/scapy/pipetool.py +++ b/scapy/pipetool.py @@ -430,11 +430,11 @@ class RawConsoleSink(Sink): def push(self, msg): if self.newlines: msg += "\n" - os.write(self._write_pipe, str(msg)) + os.write(self._write_pipe, msg.encode("utf8")) def high_push(self, msg): if self.newlines: msg += "\n" - os.write(self._write_pipe, str(msg)) + os.write(self._write_pipe, msg.encode("utf8")) class CLIFeeder(AutoSource): """Send messages from python command line diff --git a/scapy/pton_ntop.py b/scapy/pton_ntop.py index 06e93095d..991ed1632 100644 --- a/scapy/pton_ntop.py +++ b/scapy/pton_ntop.py @@ -13,7 +13,9 @@ without IPv6 support, on Windows for instance. from __future__ import absolute_import import socket import re +import binascii from scapy.modules.six.moves import range +from scapy.compat import * _IP6_ZEROS = re.compile('(?::|^)(0(?::0)+)(?::|$)') _INET6_PTON_EXC = socket.error("illegal IP address string passed to inet_pton") @@ -25,6 +27,7 @@ used when socket.inet_pton is not available. """ joker_pos = None result = b"" + addr = plain_str(addr) if addr == '::': return b'\x00' * 16 if addr.startswith('::'): @@ -54,8 +57,8 @@ used when socket.inet_pton is not available. else: # Each part must be 16bit. Add missing zeroes before decoding. try: - result += part.rjust(4, "0").decode("hex") - except TypeError: + result += hex_bytes(part.rjust(4, "0")) + except (binascii.Error, TypeError): raise _INET6_PTON_EXC # If there's a wildcard, fill up with zeros to reach 128bit (16 bytes) if joker_pos is not None: @@ -77,6 +80,7 @@ _INET_PTON = { def inet_pton(af, addr): """Convert an IP address from text representation into binary form.""" # Use inet_pton if available + addr = plain_str(addr) try: return socket.inet_pton(af, addr) except AttributeError: @@ -96,7 +100,7 @@ used when socket.inet_pton is not available. raise ValueError("invalid length of packed IP address string") # Decode to hex representation - address = ":".join(addr[idx:idx + 2].encode('hex').lstrip('0') or '0' + address = ":".join(bytes_hex(addr[idx:idx + 2], force_str=True).lstrip('0') or '0' for idx in range(0, 16, 2)) try: @@ -121,6 +125,7 @@ _INET_NTOP = { def inet_ntop(af, addr): """Convert an IP address from binary form into text representation.""" # Use inet_ntop if available + addr = raw(addr) try: return socket.inet_ntop(af, addr) except AttributeError: diff --git a/scapy/route.py b/scapy/route.py index c6a973de5..40a730774 100644 --- a/scapy/route.py +++ b/scapy/route.py @@ -162,7 +162,7 @@ class Route: return LOOPBACK_INTERFACE,"0.0.0.0","0.0.0.0" # Choose the more specific route (greatest netmask). # XXX: we don't care about metrics - pathes.sort() + pathes.sort(key=lambda x: x[0]) ret = pathes[-1][1] self.cache[dest] = ret return ret diff --git a/scapy/scapypipes.py b/scapy/scapypipes.py index 4d37f5e1e..1bb077bf2 100644 --- a/scapy/scapypipes.py +++ b/scapy/scapypipes.py @@ -5,9 +5,10 @@ from __future__ import print_function import socket -import Queue +from scapy.modules.six.moves.queue import Queue, Empty from scapy.pipetool import Source,Drain,Sink from scapy.config import conf +from scapy.compat import * from scapy.utils import PcapReader, PcapWriter @@ -121,7 +122,7 @@ class UDPDrain(Drain): from scapy.layers.inet import IP, UDP if IP in msg and msg[IP].proto == 17 and UDP in msg: payload = msg[UDP].payload - self._high_send(str(payload)) + self._high_send(raw(payload)) def high_push(self, msg): from scapy.layers.inet import IP, UDP p = IP(dst=self.ip)/UDP(sport=1234,dport=self.port)/msg @@ -184,7 +185,7 @@ class TCPListenPipe(TCPConnectPipe): def __init__(self, addr="", port=0, name=None): TCPConnectPipe.__init__(self, addr, port, name) self.connected = False - self.q = Queue.Queue() + self.q = Queue() def start(self): self.connected = False self.fd = socket.socket() @@ -209,7 +210,7 @@ class TCPListenPipe(TCPConnectPipe): while True: try: self.fd.send(self.q.get(block=False)) - except Queue.Empty: + except Empty: break @@ -283,9 +284,9 @@ class TriggeredQueueingValve(Drain): def __init__(self, start_state=True, name=None): Drain.__init__(self, name=name) self.opened = start_state - self.q = Queue.Queue() + self.q = Queue() def start(self): - self.q = Queue.Queue() + self.q = Queue() def push(self, msg): if self.opened: self._send(msg) @@ -302,7 +303,7 @@ class TriggeredQueueingValve(Drain): while True: try: low,msg = self.q.get(block=False) - except Queue.Empty: + except Empty: break else: if low: diff --git a/scapy/supersocket.py b/scapy/supersocket.py index 81feec212..599955eeb 100644 --- a/scapy/supersocket.py +++ b/scapy/supersocket.py @@ -12,6 +12,7 @@ import socket,time from scapy.config import conf from scapy.data import * +from scapy.compat import * from scapy.error import warning, log_runtime import scapy.packet from scapy.utils import PcapReader, tcpdump @@ -33,7 +34,7 @@ class SuperSocket(six.with_metaclass(_SuperSocket_metaclass)): self.outs = self.ins self.promisc=None def send(self, x): - sx = str(x) + sx = raw(x) if hasattr(x, "sent_time"): x.sent_time = time.time() return self.outs.send(sx) @@ -104,7 +105,7 @@ class L3RawSocket(SuperSocket): return pkt def send(self, x): try: - sx = str(x) + sx = raw(x) x.sent_time = time.time() self.outs.sendto(sx,(x.dst,0)) except socket.error as msg: diff --git a/scapy/tools/UTscapy.py b/scapy/tools/UTscapy.py index bffcc1ac8..8ede56d97 100755 --- a/scapy/tools/UTscapy.py +++ b/scapy/tools/UTscapy.py @@ -10,7 +10,7 @@ Unit testing infrastructure for Scapy from __future__ import absolute_import from __future__ import print_function import sys, getopt, imp, glob, importlib -import bz2, base64, os.path, time, traceback, zlib, sha +import hashlib, copy, bz2, base64, os.path, time, traceback, zlib from scapy.consts import WINDOWS import scapy.modules.six as six from scapy.modules.six.moves import range @@ -188,10 +188,11 @@ class UnitTest(TestClass): self.crc = None self.expand = 1 def decode(self): - self.test = self.test.decode("utf8", "ignore") - self.output = self.output.decode("utf8", "ignore") - self.comments = self.comments.decode("utf8", "ignore") - self.result = self.result.decode("utf8", "ignore") + if six.PY2: + self.test = self.test.decode("utf8", "ignore") + self.output = self.output.decode("utf8", "ignore") + self.comments = self.comments.decode("utf8", "ignore") + self.result = self.result.decode("utf8", "ignore") def __nonzero__(self): return self.res __bool__ = __nonzero__ @@ -301,12 +302,18 @@ def dump_campaign(test_campaign): print(" %s%s" % (c,k)) #### COMPUTE CAMPAIGN DIGESTS #### +if six.PY2: + def crc32(x): + return "%08X" % (0xffffffff & zlib.crc32(x)) -def crc32(x): - return "%08X" % (0xffffffff & zlib.crc32(x)) + def sha1(x): + return hashlib.sha1(x).hexdigest().upper() +else: + def crc32(x): + return "%08X" % (0xffffffff & zlib.crc32(bytearray(x, "utf8"))) -def sha1(x): - return sha.sha(x).hexdigest().upper() + def sha1(x): + return hashlib.sha1(x.encode("utf8")).hexdigest().upper() def compute_campaign_digests(test_campaign): dc = "" @@ -315,9 +322,9 @@ def compute_campaign_digests(test_campaign): for t in ts: dt = t.test.strip() t.crc = crc32(dt) - dts += b"\0"+dt + dts += "\0"+dt ts.crc = crc32(dts) - dc += b"\0\x01"+dts + dc += "\0\x01"+dts test_campaign.crc = crc32(dc) test_campaign.sha = sha1(open(test_campaign.filename).read()) @@ -801,7 +808,7 @@ def main(argv): UNIQUE = len(TESTFILES) == 1 # Resolve tags and asterix - for prex in PREEXEC_DICT.keys(): + for prex in six.iterkeys(copy.copy(PREEXEC_DICT)): if "*" in prex: pycode = PREEXEC_DICT[prex] del PREEXEC_DICT[prex] diff --git a/scapy/utils.py b/scapy/utils.py index b41dd7c2a..9e81fbe1e 100644 --- a/scapy/utils.py +++ b/scapy/utils.py @@ -24,6 +24,7 @@ warnings.filterwarnings("ignore","tempnam",RuntimeWarning, __name__) from scapy.config import conf from scapy.consts import DARWIN, WINDOWS from scapy.data import MTU +from scapy.compat import * from scapy.error import log_runtime, log_loading, log_interactive, Scapy_Exception, warning from scapy.base_classes import BasePacketList @@ -44,7 +45,7 @@ def sane_color(x): if (j < 32) or (j >= 127): r=r+conf.color_theme.not_printable(".") else: - r=r+i + r=r+chb(i) return r def sane(x): @@ -67,6 +68,10 @@ def lhex(x): else: return x +def to_hex(x): + """Turns string or bytes to hex format""" + return x if isinstance(x, bytes) and not six.PY2 else x.encode("hex") + @conf.commands.register def hexdump(x, dump=False): """ Build a tcpdump like hexadecimal view @@ -76,7 +81,7 @@ def hexdump(x, dump=False): :returns: a String only when dump=True """ s = "" - x = str(x) + x = raw(x) l = len(x) i = 0 while i < l: @@ -114,7 +119,7 @@ def linehexdump(x, onlyasc=0, onlyhex=0, dump=False): :returns: a String only when dump=True """ s = "" - x = str(x) + x = raw(x) l = len(x) if not onlyasc: for i in range(l): @@ -140,8 +145,8 @@ def chexdump(x, dump=False): :param dump: print the view if False :returns: a String only if dump=True """ - x = str(x) - s = str(", ".join("%#04x" % ord(x) for x in x)) + x = raw(x) + s = ", ".join("%#04x" % ord(x) for x in x) if dump: return s else: @@ -343,10 +348,12 @@ def fletcher16_checkbytes(binbuf, offset): def mac2str(mac): - return b"".join(chr(int(x, 16)) for x in mac.split(':')) + return b"".join(chb(int(x, 16)) for x in mac.split(':')) def str2mac(s): - return ("%02x:"*6)[:-1] % tuple(map(ord, s)) + if isinstance(s, str): + return ("%02x:"*6)[:-1] % tuple(map(ord, s)) + return ("%02x:"*6)[:-1] % tuple(s) def randstring(l): """ @@ -365,14 +372,14 @@ def strxor(s1, s2): Returns the binary XOR of the 2 provided strings s1 and s2. s1 and s2 must be of same length. """ - return b"".join(map(lambda x,y:chr(ord(x)^ord(y)), s1, s2)) + return b"".join(map(lambda x,y:chb(orb(x)^orb(y)), s1, s2)) def strand(s1, s2): """ Returns the binary AND of the 2 provided strings s1 and s2. s1 and s2 must be of same length. """ - return b"".join(map(lambda x,y:chr(ord(x)&ord(y)), s1, s2)) + return b"".join(map(lambda x,y:chb(orb(x)&orb(y)), s1, s2)) # Workaround bug 643005 : https://sourceforge.net/tracker/?func=detail&atid=105470&aid=643005&group_id=5470 @@ -555,7 +562,7 @@ def binrepr(val): return bin(val)[2:] def long_converter(s): - return long(s.replace('\n', '').replace(' ', ''), 16) + return int(s.replace('\n', '').replace(' ', ''), 16) ######################### #### Enum management #### @@ -572,8 +579,16 @@ class EnumElement: return getattr(self._value, attr) def __str__(self): return self._key + def __bytes__(self): + return raw(self.__str__()) + def __hash__(self): + return self._value + def __int__(self): + return int(self._value) def __eq__(self, other): return self._value == int(other) + def __neq__(self, other): + return not self.__eq__(other) class Enum_metaclass(type): @@ -626,7 +641,7 @@ def load_object(fname): @conf.commands.register def corrupt_bytes(s, p=0.01, n=None): """Corrupt a given percentage or number of bytes from a string""" - s = array.array("B",str(s)) + s = array.array("B",raw(s)) l = len(s) if n is None: n = max(1,int(l*p)) @@ -637,7 +652,7 @@ def corrupt_bytes(s, p=0.01, n=None): @conf.commands.register def corrupt_bits(s, p=0.01, n=None): """Flip a given percentage or number of bits from a string""" - s = array.array("B",str(s)) + s = array.array("B",raw(s)) l = len(s)*8 if n is None: n = max(1,int(l*p)) @@ -710,6 +725,7 @@ class PcapReader_metaclass(type): try: i.__init__(filename, fdesc, magic) except Scapy_Exception: + raise try: i.f.seek(-4, 1) except: @@ -1149,7 +1165,7 @@ class PcapWriter(RawPcapWriter): return sec = int(packet.time) usec = int(round((packet.time - sec) * (1000000000 if self.nano else 1000000))) - s = str(packet) + s = raw(packet) caplen = len(s) RawPcapWriter._write_packet(self, s, sec, usec, caplen, caplen) @@ -1345,7 +1361,7 @@ def pretty_routes(rtlst, header, sortBy=0): # Append tag rtlst = header + rtlst # Detect column's width - colwidth = [max([len(y) for y in x]) for x in apply(zip, rtlst)] + colwidth = [max([len(y) for y in x]) for x in zip(*rtlst)] # Make text fit in box (if exist) # TODO: find a better and more precise way of doing this. That's currently working but very complicated width = get_terminal_width() @@ -1454,7 +1470,7 @@ def whois(ip_address): query = whois_ip s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("whois.ripe.net", 43)) - s.send(query + b"\r\n") + s.send(query.encode("utf8") + b"\r\n") answer = b"" while True: d = s.recv(4096) diff --git a/scapy/utils6.py b/scapy/utils6.py index 31bdb66c7..42349d567 100644 --- a/scapy/utils6.py +++ b/scapy/utils6.py @@ -18,6 +18,7 @@ from scapy.config import conf import scapy.consts from scapy.data import * from scapy.utils import * +from scapy.compat import * from scapy.pton_ntop import * from scapy.volatile import RandMAC from scapy.error import warning @@ -71,7 +72,8 @@ def construct_source_candidate_set(addr, plen, laddr): elif addr == '::' and plen == 0: cset = (x for x in laddr if x[1] == IPV6_ADDR_GLOBAL) cset = [x[0] for x in cset] - cset.sort(cmp=cset_sort) # Sort with global addresses first + # TODO convert the cmd use into a key + cset.sort(key=cmp_to_key(cset_sort)) # Sort with global addresses first return cset def get_source_addr_from_candidate_set(dst, candidate_set): @@ -151,7 +153,7 @@ def get_source_addr_from_candidate_set(dst, candidate_set): # Should not happen return None - candidate_set.sort(cmp=rfc3484_cmp, reverse=True) + candidate_set.sort(key=cmp_to_key(rfc3484_cmp), reverse=True) return candidate_set[0] @@ -165,11 +167,11 @@ def in6_getAddrType(addr): addrType = 0 # _Assignable_ Global Unicast Address space # is defined in RFC 3513 as those in 2000::/3 - if ((struct.unpack("B", naddr[0])[0] & 0xE0) == 0x20): + if ((struct.unpack("B", raw(naddr[0]))[0] & 0xE0) == 0x20): addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_GLOBAL) if naddr[:2] == b' \x02': # Mark 6to4 @ addrType |= IPV6_ADDR_6TO4 - elif naddr[0] == b'\xff': # multicast + elif ord(naddr[0]) == 0xff: # multicast addrScope = paddr[3] if addrScope == '2': addrType = (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_MULTICAST) @@ -177,7 +179,7 @@ def in6_getAddrType(addr): addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST) else: addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST) - elif ((naddr[0] == b'\xfe') and ((int(paddr[2], 16) & 0xC) == 0x8)): + elif ((ord(naddr[0]) == 0xfe) and ((int(paddr[2], 16) & 0xC) == 0x8)): addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL) elif paddr == "::1": addrType = IPV6_ADDR_LOOPBACK @@ -226,7 +228,7 @@ def in6_ifaceidtomac(ifaceid): # TODO: finish commenting function behavior first = struct.pack("B", ((first & 0xFD) | ulbit)) oui = first + ifaceid[1:3] end = ifaceid[5:] - l = ["%.02x" % struct.unpack('B', x)[0] for x in list(oui + end)] + l = ["%.02x" % struct.unpack('B', raw(x))[0] for x in list(oui + end)] return ":".join(l) def in6_addrtomac(addr): @@ -293,7 +295,7 @@ def in6_getLinkScopedMcastAddr(addr, grpid=None, scope=2): if grpid is None: grpid = b'\x00\x00\x00\x00' else: - if isinstance(grpid, str): + if isinstance(grpid, (bytes, str)): if len(grpid) == 8: try: grpid = int(grpid, 16) & 0xffffffff @@ -366,8 +368,8 @@ def in6_getLocalUniquePrefix(): mac = RandMAC() # construct modified EUI-64 ID eui64 = inet_pton(socket.AF_INET6, '::' + in6_mactoifaceid(mac))[8:] - import sha - globalid = sha.new(tod+eui64).digest()[:5] + import hashlib + globalid = hashlib.sha1(tod+eui64).digest()[:5] return inet_ntop(socket.AF_INET6, b'\xfd' + globalid + b'\x00'*10) def in6_getRandomizedIfaceId(ifaceid, previous=None): @@ -393,15 +395,15 @@ def in6_getRandomizedIfaceId(ifaceid, previous=None): s = b"" if previous is None: - d = b"".join(chr(x) for x in range(256)) + d = b"".join(chb(x) for x in range(256)) for _ in range(8): s += random.choice(d) previous = s s = inet_pton(socket.AF_INET6, "::"+ifaceid)[8:] + previous - import md5 - s = md5.new(s).digest() + import hashlib + s = hashlib.md5(s).digest() s1,s2 = s[:8],s[8:] - s1 = chr(ord(s1[0]) | 0x04) + s1[1:] + s1 = raw(ord(s1[0]) | 0x04) + s1[1:] s1 = inet_ntop(socket.AF_INET6, b"\xff"*8 + s1)[20:] s2 = inet_ntop(socket.AF_INET6, b"\xff"*8 + s2)[20:] return (s1, s2) diff --git a/scapy/volatile.py b/scapy/volatile.py index f4ae84bc3..117e16f5d 100644 --- a/scapy/volatile.py +++ b/scapy/volatile.py @@ -10,6 +10,7 @@ Fields that hold random numbers. from __future__ import absolute_import import random,time,math from scapy.base_classes import Net +from scapy.compat import * from scapy.utils import corrupt_bits,corrupt_bytes from scapy.modules.six.moves import range @@ -82,6 +83,10 @@ class VolatileValue: if attr == "__setstate__": raise AttributeError(attr) return getattr(self._fix(),attr) + def __str__(self): + return str(self._fix()) + def __bytes__(self): + return raw(self._fix()) def _fix(self): return None @@ -101,6 +106,8 @@ class RandNum(RandField): def __int__(self): return int(self._fix()) + def __index__(self): + return int(self) def __str__(self): return str(self._fix()) @@ -240,7 +247,9 @@ class RandTermString(RandString): def __str__(self): return str(self._fix()) - + + def __bytes__(self): + return raw(self._fix()) class RandIP(RandString): @@ -624,6 +633,8 @@ class RandSingString(RandSingularity): def __str__(self): return str(self._fix()) + def __bytes__(self): + return raw(self._fix()) class RandPool(RandField): diff --git a/test/cert.uts b/test/cert.uts index a605b061d..f926312d6 100644 --- a/test/cert.uts +++ b/test/cert.uts @@ -47,10 +47,10 @@ type(y) is PubKeyRSA y.frmt == "DER" = PubKey class : Checking modulus value -x_pubNum.n == y_pubNum.n and x_pubNum.n == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163L +x_pubNum.n == y_pubNum.n and x_pubNum.n == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163 = PubKey class : Checking public exponent value -x_pubNum.e == y_pubNum.e and x_pubNum.e == 65537L +x_pubNum.e == y_pubNum.e and x_pubNum.e == 65537 = PubKey class : Importing PEM-encoded ECDSA public key z = PubKey(""" @@ -65,7 +65,7 @@ type(z) is PubKeyECDSA z.pubkey.curve.name == "secp256k1" = PubKey class : Checking point value -z.pubkey.public_numbers().x == 104748656174769496952370005421566518252704263000192720134585149244759951661467L +z.pubkey.public_numbers().x == 104748656174769496952370005421566518252704263000192720134585149244759951661467 ########### PrivKey class ############################################### @@ -107,15 +107,15 @@ x_pubNum = x.pubkey.public_numbers() type(x) is PrivKeyRSA = PrivKey class : Checking public attributes -assert(x_pubNum.n == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163L) -x_pubNum.e == 65537L +assert(x_pubNum.n == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163) +x_pubNum.e == 65537 = PrivKey class : Checking private attributes -assert(x_privNum.p == 140977881300857803928857666115326329496639762170623218602431133528876162476487960230341078724702018316260690172014674492782486113504117653531825010840338251572887403113276393351318549036549656895326851872473595350667293402676143426484331639796163189182788306480699144107905869179435145810212051656274284113969L) -assert(x_privNum.q == 136413798668820291889092636919077529673097927884427227010121877374504825870002258140616512268521246045642663981036167305976907058413796938050224182519965099316625879807962173794483933183111515251808827349718943344770056106787713032506379905031673992574818291891535689493330517205396872699985860522390496583027L) -assert(x_privNum.dmp1 == 46171616708754015342920807261537213121074749458020000367465429453038710215532257783908950878847126373502288079285334594398328912526548076894076506899568491565992572446455658740752572386903609191774044411412991906964352741123956581870694330173563737928488765282233340389888026245745090096745219902501964298369L) -assert(x_privNum.dmq1 == 58077388505079936284685944662039782610415160654764308528562806086690474868010482729442634318267235411531220690585030443434512729356878742778542733733189895801341155353491318998637269079682889033003797865508917973141494201620317820971253064836562060222814287812344611566640341960495346782352037479526674026269L) -x_privNum.d == 15879630313397508329451198152673380989865598204237760057319927734227125481903063742175442230739018051313441697936698689753842471306305671266572085925009572141819112648211571007521954312641597446020984266846581125287547514750428503480880603089110687015181510081018160579576523796170439894692640171752302225125980423560965987469457505107324833137678663960560798216976668670722016960863268272661588745006387723814962668678285659376534048525020951633874488845649968990679414325096323920666486328886913648207836459784281744709948801682209478580185160477801656666089536527545026197569990716720623647770979759861119273292833L +assert(x_privNum.p == 140977881300857803928857666115326329496639762170623218602431133528876162476487960230341078724702018316260690172014674492782486113504117653531825010840338251572887403113276393351318549036549656895326851872473595350667293402676143426484331639796163189182788306480699144107905869179435145810212051656274284113969) +assert(x_privNum.q == 136413798668820291889092636919077529673097927884427227010121877374504825870002258140616512268521246045642663981036167305976907058413796938050224182519965099316625879807962173794483933183111515251808827349718943344770056106787713032506379905031673992574818291891535689493330517205396872699985860522390496583027) +assert(x_privNum.dmp1 == 46171616708754015342920807261537213121074749458020000367465429453038710215532257783908950878847126373502288079285334594398328912526548076894076506899568491565992572446455658740752572386903609191774044411412991906964352741123956581870694330173563737928488765282233340389888026245745090096745219902501964298369) +assert(x_privNum.dmq1 == 58077388505079936284685944662039782610415160654764308528562806086690474868010482729442634318267235411531220690585030443434512729356878742778542733733189895801341155353491318998637269079682889033003797865508917973141494201620317820971253064836562060222814287812344611566640341960495346782352037479526674026269) +x_privNum.d == 15879630313397508329451198152673380989865598204237760057319927734227125481903063742175442230739018051313441697936698689753842471306305671266572085925009572141819112648211571007521954312641597446020984266846581125287547514750428503480880603089110687015181510081018160579576523796170439894692640171752302225125980423560965987469457505107324833137678663960560798216976668670722016960863268272661588745006387723814962668678285659376534048525020951633874488845649968990679414325096323920666486328886913648207836459784281744709948801682209478580185160477801656666089536527545026197569990716720623647770979759861119273292833 = PrivKey class : Importing PEM-encoded ECDSA private key y = PrivKey(""" @@ -129,10 +129,10 @@ type(y) is PrivKeyECDSA = PrivKey class : Checking public attributes assert(y.key.curve.name == "secp256k1") -y.key.public_key().public_numbers().y == 86290575637772818452062569410092503179882738810918951913926481113065456425840L +y.key.public_key().public_numbers().y == 86290575637772818452062569410092503179882738810918951913926481113065456425840 = PrivKey class : Checking private attributes -y.key.private_numbers().private_value == 90719786431263082134670936670180839782031078050773732489701961692235185651857L +y.key.private_numbers().private_value == 90719786431263082134670936670180839782031078050773732489701961692235185651857 ########### Keys crypto tests ####################################### @@ -218,7 +218,7 @@ x.notAfter == (2026, 3, 30, 7, 38, 59, 0, 89, -1) = Cert class : Checking RSA public key assert(type(x.pubKey) is PubKeyRSA) x_pubNum = x.pubKey.pubkey.public_numbers() -assert(x_pubNum.n == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163L) +assert(x_pubNum.n == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163) x_pubNum.e == 0x10001 = Cert class : Checking extensions @@ -249,7 +249,7 @@ JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv assert(type(y.pubKey) is PubKeyECDSA) pubkey = y.pubKey.pubkey assert(pubkey.curve.name == 'secp384r1') -pubkey.public_numbers().x == 3987178688175281746349180015490646948656137448666005327832107126183726641822596270780616285891030558662603987311874L +pubkey.public_numbers().x == 3987178688175281746349180015490646948656137448666005327832107126183726641822596270780616285891030558662603987311874 = Cert class : Checking ECDSA signature y.signatureValue == b'0d\x020%\xa4\x81E\x02k\x12KutO\xc8#\xe3p\xf2ur\xde|\x89\xf0\xcf\x91ra\x9e^\x10\x92YV\xb9\x83\xc7\x10\xe78\xe9X&6}\xd5\xe44\x869\x020|6S\xf00\xe5bc:\x99\xe2\xb6\xa3;\x9b4\xfa\x1e\xda\x10\x92q^\x91\x13\xa7\xdd\xa4n\x92\xcc2\xd6\xf5!f\xc7/\xea\x96cjeE\x92\x95\x01\xb4' diff --git a/test/regression.uts b/test/regression.uts index c0ed1b311..fab7e9a11 100644 --- a/test/regression.uts +++ b/test/regression.uts @@ -53,7 +53,7 @@ def get_dummy_interface(): data["name"] = "dummy0" data["description"] = "Does not exist" data["win_index"] = -1 - data["guid"] = "{0XX00000-X000-0X0X-X00X-00XXXX000XXX}" + data["guid"] = "{1XX00000-X000-0X0X-X00X-00XXXX000XXX}" data["invalid"] = True return NetworkInterface(data) else: @@ -578,7 +578,7 @@ assert(_ == b'5\x00\x00\x14\x00\x01\x00\x00 \x00\xac\xe7\x7f\x00\x00\x01\x7f\x00 = ISAKMP creation ~ IP UDP ISAKMP -p=IP(src='192.168.8.14',dst='10.0.0.1')/UDP()/ISAKMP()/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal(trans=ISAKMP_payload_Transform(transforms=[('Encryption', 'AES-CBC'), ('Hash', 'MD5'), ('Authentication', 'PSK'), ('GroupDesc', '1536MODPgr'), ('KeyLength', 256), ('LifeType', 'Seconds'), ('LifeDuration', 86400L)])/ISAKMP_payload_Transform(res2=12345,transforms=[('Encryption', '3DES-CBC'), ('Hash', 'SHA'), ('Authentication', 'PSK'), ('GroupDesc', '1024MODPgr'), ('LifeType', 'Seconds'), ('LifeDuration', 86400L)]))) +p=IP(src='192.168.8.14',dst='10.0.0.1')/UDP()/ISAKMP()/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal(trans=ISAKMP_payload_Transform(transforms=[('Encryption', 'AES-CBC'), ('Hash', 'MD5'), ('Authentication', 'PSK'), ('GroupDesc', '1536MODPgr'), ('KeyLength', 256), ('LifeType', 'Seconds'), ('LifeDuration', 86400)])/ISAKMP_payload_Transform(res2=12345,transforms=[('Encryption', '3DES-CBC'), ('Hash', 'SHA'), ('Authentication', 'PSK'), ('GroupDesc', '1024MODPgr'), ('LifeType', 'Seconds'), ('LifeDuration', 86400)]))) p.show() p diff --git a/test/run_tests b/test/run_tests index 52ca07df3..48bc94186 100755 --- a/test/run_tests +++ b/test/run_tests @@ -7,7 +7,7 @@ else fi if [ -z "$*" ] then - PYTHONPATH=$DIR exec $PYTHON ${DIR}/scapy/tools/UTscapy.py -t regression.uts -f html -l -o /tmp/scapy_regression_test_$(date +%Y%m%d-%H%M%S).html + PYTHONPATH=$DIR exec $PYTHON ${DIR}/scapy/tools/UTscapy.py -t regression.uts -f html -K ipv6 -l -o /tmp/scapy_regression_test_$(date +%Y%m%d-%H%M%S).html else PYTHONPATH=$DIR exec $PYTHON ${DIR}/scapy/tools/UTscapy.py "$@" fi