diff --git a/scapy/arch/__init__.py b/scapy/arch/__init__.py index 949303dd527f07b0da960d553815539e6fa9339d..5bd7d8e80c17b5d2a31b475e5e2ea545c076496c 100644 --- a/scapy/arch/__init__.py +++ b/scapy/arch/__init__.py @@ -15,6 +15,7 @@ from scapy.consts import LINUX, OPENBSD, FREEBSD, NETBSD, DARWIN, \ from scapy.error import * import scapy.config from scapy.pton_ntop import inet_pton +from scapy.data import * def str2mac(s): return ("%02x:"*6)[:-1] % tuple(map(ord, s)) diff --git a/scapy/arch/bpf/core.py b/scapy/arch/bpf/core.py index a8339b2ab620abfe2753018b2ed9d2d4d3cf7429..5d84f233f58305ea30b9409cff1f23b70f587628 100644 --- a/scapy/arch/bpf/core.py +++ b/scapy/arch/bpf/core.py @@ -53,12 +53,14 @@ def get_if_raw_addr(ifname): try: fd = os.popen("%s %s" % (conf.prog.ifconfig, ifname)) except OSError, msg: - raise Scapy_Exception("Failed to execute ifconfig: (%s)" % msg) + warning("Failed to execute ifconfig: (%s)" % msg) + return "\0\0\0\0" # Get IPv4 addresses - addresses = [l for l in fd.readlines() if l.find("netmask") >= 0] + addresses = [l for l in fd if l.find("netmask") >= 0] if not addresses: - raise Scapy_Exception("No IPv4 address found on %s !" % ifname) + warning("No IPv4 address found on %s !" % ifname) + return "\0\0\0\0" # Pack the first address address = addresses[0].split(' ')[1] @@ -78,7 +80,6 @@ def get_if_raw_hwaddr(ifname): try: fd = os.popen("%s %s" % (conf.prog.ifconfig, ifname)) except OSError, msg: - warning("Failed to execute ifconfig: (%s)" % msg) raise Scapy_Exception("Failed to execute ifconfig: (%s)" % msg) # Get MAC addresses diff --git a/scapy/arch/pcapdnet.py b/scapy/arch/pcapdnet.py index 77e18b4720e073196263993b2b00b25cfc164e02..f90fdacb73e218272d3fb0bbdfcda9c627571ca1 100644 --- a/scapy/arch/pcapdnet.py +++ b/scapy/arch/pcapdnet.py @@ -520,7 +520,13 @@ if conf.use_dnet: def get_if_raw_addr(ifname): i = dnet.intf() - return i.get(ifname)["addr"].data + try: + return i.get(ifname)["addr"].data + except OSError: + warning("No MAC address found on %s !" % ifname) + return "\0\0\0\0" + + def get_if_list(): return [i.get("name", None) for i in dnet.intf()] diff --git a/scapy/route.py b/scapy/route.py index a6595d08b98fa9f578a9182e3392064c1893a00a..14e24473e04696bfd43feafe3abf5b8fc24db609 100644 --- a/scapy/route.py +++ b/scapy/route.py @@ -12,6 +12,7 @@ from scapy.consts import LOOPBACK_NAME from scapy.utils import atol,ltoa,itom from scapy.config import conf from scapy.error import Scapy_Exception,warning +from scapy.arch import WINDOWS ############################## ## Routing/Interfaces stuff ## @@ -89,7 +90,10 @@ class Route: for i, route in enumerate(self.routes): net, msk, gw, iface, addr = route - if iface != iff: + if WINDOWS: + if iff.guid != iface.guid: + continue + elif iff != iface: continue if gw == '0.0.0.0': self.routes[i] = (the_net,the_msk,gw,iface,the_addr) @@ -103,8 +107,12 @@ class Route: self.invalidate_cache() new_routes=[] for rt in self.routes: - if rt[3] != iff: - new_routes.append(rt) + if WINDOWS: + if iff.guid == rt[3].guid: + continue + elif iff == rt[3]: + continue + new_routes.append(rt) self.routes=new_routes def ifadd(self, iff, addr): @@ -157,9 +165,15 @@ class Route: def get_if_bcast(self, iff): for net, msk, gw, iface, addr in self.routes: - if (iff == iface and net != 0L): - bcast = atol(addr)|(~msk&0xffffffffL); # FIXME: check error in atol() - return ltoa(bcast); + if net == 0: + continue + if WINDOWS: + if iff.guid != iface.guid: + continue + elif iff != iface: + continue + bcast = atol(addr)|(~msk&0xffffffffL); # FIXME: check error in atol() + return ltoa(bcast) warning("No broadcast address found for iface %s\n" % iff); conf.route=Route() diff --git a/scapy/route6.py b/scapy/route6.py index 4331e467f93d52abeb539cc196d88a385a19090b..58f64c2b45cd2c2df76e7846bb66a12b547881ee 100644 --- a/scapy/route6.py +++ b/scapy/route6.py @@ -105,7 +105,7 @@ class Route6: l = filter(lambda x: in6_ptop(x[0]) == dst and x[1] == plen, self.routes) if gw: gw = in6_ptop(gw) - l = filter(lambda x: in6_ptop(x[0]) == gw, self.routes) + l = [x for x in self.routes if in6_ptop(x[2]) == gw] if len(l) == 0: warning("No matching route found") elif len(l) > 1: diff --git a/scapy/utils.py b/scapy/utils.py index 74fc4c10e5312db47faa3482f19d5513b28106f2..c163cfdc3c8fd21701df23722ccf82801ba862dc 100644 --- a/scapy/utils.py +++ b/scapy/utils.py @@ -124,6 +124,7 @@ def linehexdump(x, onlyasc=0, onlyhex=0, dump=False): else: print s +@conf.commands.register def chexdump(x, dump=False): """ Build a per byte hexadecimal representation @@ -141,7 +142,8 @@ def chexdump(x, dump=False): return s else: print s - + +@conf.commands.register def hexstr(x, onlyasc=0, onlyhex=0): s = [] if not onlyasc: @@ -1066,6 +1068,7 @@ class PcapWriter(RawPcapWriter): re_extract_hexcap = re.compile("^((0x)?[0-9a-fA-F]{2,}[ :\t]{,3}|) *(([0-9a-fA-F]{2} {,2}){,16})") +@conf.commands.register def import_hexcap(): p = "" try: diff --git a/scapy/utils6.py b/scapy/utils6.py index 1298544cb8990f93a021738f80e7760873ff2b94..30ee6ba58ee893a842d45655bb1f4c57a3761b6c 100644 --- a/scapy/utils6.py +++ b/scapy/utils6.py @@ -17,6 +17,7 @@ from scapy.config import conf from scapy.data import * from scapy.utils import * from scapy.pton_ntop import * +from scapy.volatile import RandMAC def construct_source_candidate_set(addr, plen, laddr, loname): @@ -150,42 +151,6 @@ def get_source_addr_from_candidate_set(dst, candidate_set): return candidate_set[0] -def find_ifaddr2(addr, plen, laddr): - dstAddrType = in6_getAddrType(addr) - - if dstAddrType == IPV6_ADDR_UNSPECIFIED: # Shouldn't happen as dst addr - return None - - if dstAddrType == IPV6_ADDR_LOOPBACK: - return None - - tmp = [[]] + map(lambda (x,y,z): (in6_getAddrType(x), x, y, z), laddr) - def filterSameScope(l, t): - if (t[0] & dstAddrType & IPV6_ADDR_SCOPE_MASK) == 0: - l.append(t) - return l - sameScope = reduce(filterSameScope, tmp) - - l = len(sameScope) - if l == 1: # Only one address for our scope - return sameScope[0][1] - - elif l > 1: # Multiple addresses for our scope - stfAddr = filter(lambda x: x[0] & IPV6_ADDR_6TO4, sameScope) - nativeAddr = filter(lambda x: not (x[0] & IPV6_ADDR_6TO4), sameScope) - - if not (dstAddrType & IPV6_ADDR_6TO4): # destination is not 6to4 - if len(nativeAddr) != 0: - return nativeAddr[0][1] - return stfAddr[0][1] - - else: # Destination is 6to4, try to use source 6to4 addr if any - if len(stfAddr) != 0: - return stfAddr[0][1] - return nativeAddr[0][1] - else: - return None - # Think before modify it : for instance, FE::1 does exist and is unicast # there are many others like that. # TODO : integrate Unique Local Addresses @@ -393,10 +358,7 @@ def in6_getLocalUniquePrefix(): i = int(tod) j = int((tod - i)*(2**32)) tod = struct.pack("!II", i,j) - # TODO: Add some check regarding system address gathering - from scapy.arch import get_if_raw_hwaddr - rawmac = get_if_raw_hwaddr(conf.iface6)[1] - mac = ":".join(map(lambda x: "%.02x" % ord(x), list(rawmac))) + mac = RandMAC() # construct modified EUI-64 ID eui64 = inet_pton(socket.AF_INET6, '::' + in6_mactoifaceid(mac))[8:] import sha diff --git a/scapy/volatile.py b/scapy/volatile.py index 116bf8601c7f58d4cde52be0c08372dc08db4ca4..152eb5bf19a2a64ffefcbfef322f3a2bd68bfc75 100644 --- a/scapy/volatile.py +++ b/scapy/volatile.py @@ -97,6 +97,12 @@ class RandNum(RandField): def _fix(self): return random.randrange(self.min, self.max+1) + def __int__(self): + return int(self._fix()) + + def __str__(self): + return str(self._fix()) + class RandNumGamma(RandField): def __init__(self, alpha, beta): self.alpha = alpha @@ -229,6 +235,9 @@ class RandTermString(RandString): self.term = term def _fix(self): return RandString._fix(self)+self.term + + def __str__(self): + return str(self._fix()) @@ -517,6 +526,7 @@ class RandSingNum(RandSingularity): if not mn <= i <= mx: sing.remove(i) self._choice = list(sing) + self._choice.sort() class RandSingByte(RandSingNum): @@ -607,6 +617,9 @@ class RandSingString(RandSingularity): r"\\myserver\share", "foo.exe:", "foo.exe\\", ] + + def __str__(self): + return str(self._fix()) class RandPool(RandField): diff --git a/test/ipsec.uts b/test/ipsec.uts index 7a49e2855b73b007cc65b668c673f830a18fa3bd..9707dce8b4c09a4d851c0abbbd24e4a92a4feed7 100644 --- a/test/ipsec.uts +++ b/test/ipsec.uts @@ -1,5 +1,5 @@ ############################## -% IPSec layer regression tests +% IPsec layer regression tests ############################## ~ crypto diff --git a/test/regression.uts b/test/regression.uts index a2cd5a5bf442397c7a81eef40ad9ffe5ca2f2be7..11052b8440ed4008ba7ee7ad42744a223570d540 100644 --- a/test/regression.uts +++ b/test/regression.uts @@ -34,8 +34,25 @@ get_if_raw_hwaddr(conf.iface) get_if_raw_addr(conf.iface).encode("hex") +def get_dummy_interface(): + """Returns a dummy network interface""" + if WINDOWS: + data = {} + data["name"] = "dummy0" + data["description"] = "Does not exist" + data["win_index"] = -1 + data["guid"] = "{0XX00000-X000-0X0X-X00X-00XXXX000XXX}" + data["invalid"] = True + return NetworkInterface(data) + else: + return "dummy0" + +get_if_raw_addr(get_dummy_interface()) + get_if_list() +get_if_raw_addr6(conf.iface6) + = Test read_routes6() - default output routes6 = read_routes6() @@ -57,7 +74,7 @@ if len(routes6): else: False else: - #Â IPv6 seems disabled. Force a route to ::1 + # IPv6 seems disabled. Force a route to ::1 conf.route6.routes.append(("::1", 128, "::", LOOPBACK_NAME, ["::1"])) True @@ -89,6 +106,47 @@ save_session(fname="scapySession1") = Test load_session load_session(fname="scapySession1") += Test utility functions + +tmpfile = get_temp_file(autoext=".ut") +tmpfile.startswith("/tmp/scapy") +conf.temp_files[0].endswith(".ut") +conf.temp_files.pop() + +get_temp_file(True).startswith("/tmp/scapy") and len(conf.temp_files) == 0 + +sane("A\x00\xFFB") == "A..B" + +linehexdump(Ether(), dump=True) == "FFFFFFFFFFFF0242D077E8129000 .......B.w...." + +chexdump(Ether(), dump=True) == "0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x42, 0xd0, 0x77, 0xe8, 0x12, 0x90, 0x00" + +hexstr("A\x00\xFFB") == "41 00 ff 42 A..B" + +fletcher16_checksum("\x28\x07") == 22319 + +tex_escape("$#_") == "\\$\\#\\_" + +f = colgen(range(3)) +len([f.next() for i in range(2)]) == 2 + +f = incremental_label() +[f.next() for i in range(2)] == ["tag00000", "tag00001"] + +import random +random.seed(0x2807) +corrupt_bytes("ABCDE") == "ABCDW" +sane(corrupt_bytes("ABCDE", n=3)) == "A.8D4" + +corrupt_bits("ABCDE") == "EBCDE" +sane(corrupt_bits("ABCDE", n=3)) == "AF.EE" + += Test utility functions - network related +~ netaccess + +atol("www.secdev.org") == 3642339845 + + ############ ############ + Basic tests @@ -2844,14 +2902,24 @@ if not len(conf.route6.routes): conf.route6.routes.append(("::1", 128, "::", LOOPBACK_NAME, ["::1"])) True += Route6 - Route6.make_route + +r6 = Route6() +r6.make_route("2001:db8::1", dev=LOOPBACK_NAME) == ("2001:db8::1", 128, "::", LOOPBACK_NAME, []) +len_r6 = len(r6.routes) + += Route6 - Route6.add & Route6.delt + +r6.add(dst="2001:db8:cafe:f000::/64", gw="2001:db8:cafe::1", dev="eth0") +print len(r6.routes) == len_r6 + 1 +r6.delt(dst="2001:db8:cafe:f000::/64", gw="2001:db8:cafe::1") +len(r6.routes) == len_r6 -# There are many other to do. # Below is our Homework : here is the mountain ... -########### Net6 Class ############################################## ########### ICMPv6MLQuery Class ##################################### ########### ICMPv6MLReport Class #################################### ########### ICMPv6MLDone Class ###################################### @@ -7219,3 +7287,203 @@ s == 'E\x00\x007\x00\x01\x00\x00@\x11|\xb3\x7f\x00\x00\x01\x7f\x00\x00\x01\x07\x = Radius - dissection p = IP(s) Radius in p and len(p[Radius].attributes) == 1 and p[Radius].attributes[0].value == "scapy" + + +############ +############ ++ Addresses generators + += Net + +n1 = Net("192.168.0.0/31") +[ip for ip in n1] == ["192.168.0.0", "192.168.0.1"] + +n2 = Net("192.168.0.*") +len([ip for ip in n2]) == 256 + +n3 = Net("192.168.0.1-5") +len([ip for ip in n3]) == 5 + +(n1 == n3) == False + +(n3 in n2) == True + += OID + +oid = OID("1.2.3.4.5.6-8") +len([ o for o in oid ]) == 3 + += Net6 + +n1 = Net6("2001:db8::/127") +len([ip for ip in n1]) == 2 + + +############ +############ ++ IPv6 helpers + += in6_getLocalUniquePrefix() + +p = in6_getLocalUniquePrefix() +len(inet_pton(socket.AF_INET6, p)) == 16 and p.startswith("fd") + += Misc addresses manipulation functions + +teredoAddrExtractInfo("2001:0:0a0b:0c0d:0028:f508:f508:08f5") == ("10.11.12.13", 40, "10.247.247.10", 2807) + +in6_iseui64("fe80::bae8:58ff:fed4:e5f6") == True + +in6_isanycast("2001:db8::fdff:ffff:ffff:ff80") == True + +a = inet_pton(socket.AF_INET6, "2001:db8::2807") +in6_xor(a, a) == "\x00" * 16 + +a = inet_pton(socket.AF_INET6, "fe80::bae8:58ff:fed4:e5f6") +r = inet_ntop(socket.AF_INET6, in6_getnsma(a)) +r == "ff02::1:ffd4:e5f6" + +in6_isllsnmaddr(r) == True + +in6_isdocaddr("2001:db8::2807") == True + +in6_isaddrllallnodes("ff02::1") == True + +in6_isaddrllallservers("ff02::2") == True + += in6_getscope() + +in6_getscope("2001:db8::2807") == IPV6_ADDR_GLOBAL +in6_getscope("fec0::2807") == IPV6_ADDR_SITELOCAL +in6_getscope("fe80::2807") == IPV6_ADDR_LINKLOCAL +in6_getscope("ff02::2807") == IPV6_ADDR_LINKLOCAL +in6_getscope("ff0e::2807") == IPV6_ADDR_GLOBAL +in6_getscope("ff05::2807") == IPV6_ADDR_SITELOCAL +in6_getscope("ff01::2807") == IPV6_ADDR_LOOPBACK +in6_getscope("::1") == IPV6_ADDR_LOOPBACK + + +############ +############ ++ Test Route class + += make_route() + +r4 = Route() +tmp_route = r4.make_route(host="10.12.13.14") +(tmp_route[0], tmp_route[1], tmp_route[2]) == (168561934, 4294967295L, '0.0.0.0') + +tmp_route = r4.make_route(net="10.12.13.0/24") +(tmp_route[0], tmp_route[1], tmp_route[2]) == (168561920, 4294967040L, '0.0.0.0') + += add() & delt() + +r4 = Route() +len_r4 = len(r4.routes) +r4.add(net="192.168.1.0/24", gw="1.2.3.4") +len(r4.routes) == len_r4 + 1 +r4.delt(net="192.168.1.0/24", gw="1.2.3.4") +len(r4.routes) == len_r4 + += ifchange() + +r4.add(net="192.168.1.0/24", gw="1.2.3.4", dev=get_dummy_interface()) +r4.ifchange(get_dummy_interface(), "5.6.7.8") +r4.routes[-1][-1] == "5.6.7.8" + += ifdel() + +r4.ifdel(get_dummy_interface()) +len(r4.routes) == len_r4 + += ifadd() & get_if_bcast() + +r4 = Route() +len_r4 = len(r4.routes) + +r4.ifadd(get_dummy_interface(), "1.2.3.4/24") +len(r4.routes) == len_r4 +1 + +r4.get_if_bcast(get_dummy_interface()) == "1.2.3.255" + +r4.ifdel(get_dummy_interface()) +print len(r4.routes), len_r4 +len(r4.routes) == len_r4 + + +############ +############ ++ Random objects + += RandomEnumeration + +re = RandomEnumeration(0, 7, seed=0x2807, forever=False) +[x for x in re] == [3, 4, 2, 5, 1, 6, 0, 7] + += RandIP6 + +random.seed(0x2807) +r6 = RandIP6() +str(r6) == "d279:1205:e445:5a9f:db28:efc9:afd7:f594" + +random.seed(0x2807) +r6 = RandIP6("2001:db8::-") +print r6 == "2001:0db8::9e9c" + +r6 = RandIP6("2001:db8::*") +print r6 == "2001:0db8::9ccb" + += RandMAC + +random.seed(0x2807) +rm = RandMAC() +rm == "d2:12:e4:5a:db:ef" + +rm = RandMAC("00:01:02:03:04:0-7") +rm == "00:01:02:03:04:05" + + += RandOID + +random.seed(0x2807) +ro = RandOID() +ro == "7.222.44.194.276.116.320.6.84.97.31.5.25.20.13.84.104.18" + +ro = RandOID("1.2.3.*") +ro == "1.2.3.41" + +ro = RandOID("1.2.3.0-28") +ro == "1.2.3.11" + += RandRegExp + +random.seed(0x2807) +re = RandRegExp("[g-v]* @? [0-9]{3} . (g|v)") +print re == "vmuvr @ 906 g" + += Corrupted(Bytes|Bits) + +random.seed(0x2807) +cb = CorruptedBytes("ABCDE", p=0.5) +sane(str(cb)) == ".BCD)" + +cb = CorruptedBits("ABCDE", p=0.2) +sane(str(cb)) == "ECk@Y" + += Rand* + +random.seed(0x2807) +rs = RandSingNum(-28, 07) +rs == 3 + +random.seed(0x2807) +rss = RandSingString() +rss == "CON:" + +random.seed(0x2807) +rek = RandEnumKeys({'a': 1, 'b': 2}) +rek == 'b' + +random.seed(0x2807) +rts = RandTermString(4, "scapy") +sane(str(rts)) == "...[scapy"