Home | History | Annotate | Download | only in arch
      1 ## This file is part of Scapy
      2 ## See http://www.secdev.org/projects/scapy for more informations
      3 ## Copyright (C) Philippe Biondi <phil (at] secdev.org>
      4 ## This program is published under a GPLv2 license
      5 
      6 """
      7 Packet sending and receiving with libdnet and libpcap/WinPcap.
      8 """
      9 
     10 import time, struct, sys, platform
     11 import socket
     12 if not sys.platform.startswith("win"):
     13     from fcntl import ioctl
     14 
     15 from scapy.data import *
     16 from scapy.compat import *
     17 from scapy.config import conf
     18 from scapy.utils import mac2str
     19 from scapy.supersocket import SuperSocket
     20 from scapy.error import Scapy_Exception, log_loading, warning
     21 from scapy.pton_ntop import inet_ntop
     22 from scapy.automaton import SelectableObject
     23 import scapy.arch
     24 import scapy.consts
     25 
     26 if conf.use_winpcapy:
     27   NPCAP_PATH = os.environ["WINDIR"] + "\\System32\\Npcap"
     28   #  Part of the code from https://github.com/phaethon/scapy translated to python2.X
     29   try:
     30       from scapy.modules.winpcapy import *
     31       def winpcapy_get_if_list():
     32           err = create_string_buffer(PCAP_ERRBUF_SIZE)
     33           devs = POINTER(pcap_if_t)()
     34           ret = []
     35           if pcap_findalldevs(byref(devs), err) < 0:
     36               return ret
     37           try:
     38               p = devs
     39               while p:
     40                   ret.append(plain_str(p.contents.name))
     41                   p = p.contents.next
     42               return ret
     43           except:
     44               raise
     45           finally:
     46               pcap_freealldevs(devs)
     47       # Detect Pcap version
     48       version = pcap_lib_version()
     49       if b"winpcap" in version.lower():
     50           if os.path.exists(NPCAP_PATH + "\\wpcap.dll"):
     51               warning("Winpcap is installed over Npcap. Will use Winpcap (see 'Winpcap/Npcap conflicts' in scapy's docs)", onlyOnce=True)
     52           elif platform.release() != "XP":
     53               warning("WinPcap is now deprecated (not maintened). Please use Npcap instead", onlyOnce=True)
     54       elif b"npcap" in version.lower():
     55           conf.use_npcap = True
     56           LOOPBACK_NAME = scapy.consts.LOOPBACK_NAME = "Npcap Loopback Adapter"
     57   except OSError as e:
     58       def winpcapy_get_if_list():
     59           return []
     60       conf.use_winpcapy = False
     61       if conf.interactive:
     62           log_loading.warning("wpcap.dll is not installed. You won't be able to send/recieve packets. Visit the scapy's doc to install it")
     63 
     64   # From BSD net/bpf.h
     65   #BIOCIMMEDIATE=0x80044270
     66   BIOCIMMEDIATE=-2147204496
     67 
     68   class PcapTimeoutElapsed(Scapy_Exception):
     69       pass
     70 
     71   def get_if_raw_addr(iff):
     72     """Returns the raw ip address corresponding to the NetworkInterface."""
     73     if conf.cache_ipaddrs:
     74         return conf.cache_ipaddrs.get(iff.pcap_name, None)
     75     err = create_string_buffer(PCAP_ERRBUF_SIZE)
     76     devs = POINTER(pcap_if_t)()
     77 
     78     if pcap_findalldevs(byref(devs), err) < 0:
     79       return None
     80     try:
     81       p = devs
     82       while p:
     83           a = p.contents.addresses
     84           while a:
     85             if a.contents.addr.contents.sa_family == socket.AF_INET:
     86               ap = a.contents.addr
     87               val = cast(ap, POINTER(sockaddr_in))
     88               if_raw_addr = b"".join(chb(x) for x in val.contents.sin_addr[:4])
     89               if if_raw_addr != b'\x00\x00\x00\x00':
     90                   conf.cache_ipaddrs[plain_str(p.contents.name)] = if_raw_addr
     91             a = a.contents.next
     92           p = p.contents.next
     93       return conf.cache_ipaddrs.get(iff.pcap_name, None)
     94     finally:
     95       pcap_freealldevs(devs)
     96   if conf.use_winpcapy:
     97       def get_if_list():
     98           """Returns all pcap names"""
     99           if conf.cache_iflist:
    100               return conf.cache_iflist
    101           iflist = winpcapy_get_if_list()
    102           conf.cache_iflist = iflist
    103           return iflist
    104   else:
    105     get_if_list = winpcapy_get_if_list
    106 
    107   def in6_getifaddr_raw():
    108     """Returns all available IPv6 on the computer, read from winpcap."""
    109     err = create_string_buffer(PCAP_ERRBUF_SIZE)
    110     devs = POINTER(pcap_if_t)()
    111     ret = []
    112     if pcap_findalldevs(byref(devs), err) < 0:
    113       return ret
    114     try:
    115       p = devs
    116       ret = []
    117       while p:
    118         a = p.contents.addresses
    119         while a:
    120           if a.contents.addr.contents.sa_family == socket.AF_INET6:
    121             ap = a.contents.addr
    122             val = cast(ap, POINTER(sockaddr_in6))
    123             addr = inet_ntop(socket.AF_INET6, b"".join(chb(x) for x in val.contents.sin6_addr[:]))
    124             scope = scapy.utils6.in6_getscope(addr)
    125             ret.append((addr, scope, plain_str(p.contents.name)))
    126           a = a.contents.next
    127         p = p.contents.next
    128       return ret
    129     finally:
    130       pcap_freealldevs(devs)
    131 
    132   from ctypes import POINTER, byref, create_string_buffer
    133   class _PcapWrapper_pypcap:
    134       """Wrapper for the WinPcap calls"""
    135       def __init__(self, device, snaplen, promisc, to_ms):
    136           self.errbuf = create_string_buffer(PCAP_ERRBUF_SIZE)
    137           self.iface = create_string_buffer(device.encode("utf8"))
    138           self.pcap = pcap_open_live(self.iface, snaplen, promisc, to_ms, self.errbuf)
    139           self.header = POINTER(pcap_pkthdr)()
    140           self.pkt_data = POINTER(c_ubyte)()
    141           self.bpf_program = bpf_program()
    142       def next(self):
    143           c = pcap_next_ex(self.pcap, byref(self.header), byref(self.pkt_data))
    144           if not c > 0:
    145               return
    146           ts = self.header.contents.ts.tv_sec + float(self.header.contents.ts.tv_usec) / 1000000
    147           pkt = b"".join(chb(i) for i in self.pkt_data[:self.header.contents.len])
    148           return ts, pkt
    149       __next__ = next
    150       def datalink(self):
    151           return pcap_datalink(self.pcap)
    152       def fileno(self):
    153           if sys.platform.startswith("win"):
    154             log_loading.error("Cannot get selectable PCAP fd on Windows")
    155             return 0
    156           return pcap_get_selectable_fd(self.pcap) 
    157       def setfilter(self, f):
    158           filter_exp = create_string_buffer(f.encode("utf8"))
    159           if pcap_compile(self.pcap, byref(self.bpf_program), filter_exp, 0, -1) == -1:
    160             log_loading.error("Could not compile filter expression %s", f)
    161             return False
    162           else:
    163             if pcap_setfilter(self.pcap, byref(self.bpf_program)) == -1:
    164               log_loading.error("Could not install filter %s", f)
    165               return False
    166           return True
    167       def setnonblock(self, i):
    168           pcap_setnonblock(self.pcap, i, self.errbuf)
    169       def send(self, x):
    170           pcap_sendpacket(self.pcap, x, len(x))
    171       def close(self):
    172           pcap_close(self.pcap)
    173   open_pcap = lambda *args,**kargs: _PcapWrapper_pypcap(*args,**kargs)
    174   class PcapTimeoutElapsed(Scapy_Exception):
    175       pass
    176 
    177   class L2pcapListenSocket(SuperSocket, SelectableObject):
    178       desc = "read packets at layer 2 using libpcap"
    179       def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None):
    180           self.type = type
    181           self.outs = None
    182           self.iface = iface
    183           if iface is None:
    184               iface = conf.iface
    185           if promisc is None:
    186               promisc = conf.sniff_promisc
    187           self.promisc = promisc
    188           self.ins = open_pcap(iface, 1600, self.promisc, 100)
    189           try:
    190               ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
    191           except:
    192               pass
    193           if type == ETH_P_ALL: # Do not apply any filter if Ethernet type is given
    194               if conf.except_filter:
    195                   if filter:
    196                       filter = "(%s) and not (%s)" % (filter, conf.except_filter)
    197                   else:
    198                       filter = "not (%s)" % conf.except_filter
    199               if filter:
    200                   self.ins.setfilter(filter)
    201   
    202       def close(self):
    203           self.ins.close()
    204 
    205       def check_recv(self):
    206           return True
    207           
    208       def recv(self, x=MTU):
    209           ll = self.ins.datalink()
    210           if ll in conf.l2types:
    211               cls = conf.l2types[ll]
    212           else:
    213               cls = conf.default_l2
    214               warning("Unable to guess datalink type (interface=%s linktype=%i). Using %s", self.iface, ll, cls.name)
    215 
    216           pkt = None
    217           while pkt is None:
    218               pkt = self.ins.next()
    219               if pkt is not None:
    220                   ts,pkt = pkt
    221               if scapy.arch.WINDOWS and pkt is None:
    222                   raise PcapTimeoutElapsed
    223           try:
    224               pkt = cls(pkt)
    225           except KeyboardInterrupt:
    226               raise
    227           except:
    228               if conf.debug_dissector:
    229                   raise
    230               pkt = conf.raw_layer(pkt)
    231           pkt.time = ts
    232           return pkt
    233   
    234       def send(self, x):
    235           raise Scapy_Exception("Can't send anything with L2pcapListenSocket")
    236   
    237 
    238   conf.L2listen = L2pcapListenSocket
    239   class L2pcapSocket(SuperSocket, SelectableObject):
    240       desc = "read/write packets at layer 2 using only libpcap"
    241       def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None, nofilter=0):
    242           if iface is None:
    243               iface = conf.iface
    244           self.iface = iface
    245           if promisc is None:
    246               promisc = 0
    247           self.promisc = promisc
    248           self.ins = open_pcap(iface, 1600, self.promisc, 100)
    249           # We need to have a different interface open because of an
    250           # access violation in Npcap that occurs in multi-threading
    251           # (see https://github.com/nmap/nmap/issues/982)
    252           self.outs = open_pcap(iface, 1600, self.promisc, 100)
    253           try:
    254               ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
    255           except:
    256               pass
    257           if nofilter:
    258               if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
    259                   filter = "ether proto %i" % type
    260               else:
    261                   filter = None
    262           else:
    263               if conf.except_filter:
    264                   if filter:
    265                       filter = "(%s) and not (%s)" % (filter, conf.except_filter)
    266                   else:
    267                       filter = "not (%s)" % conf.except_filter
    268               if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
    269                   if filter:
    270                       filter = "(ether proto %i) and (%s)" % (type,filter)
    271                   else:
    272                       filter = "ether proto %i" % type
    273           if filter:
    274               self.ins.setfilter(filter)
    275       def send(self, x):
    276           sx = raw(x)
    277           if hasattr(x, "sent_time"):
    278               x.sent_time = time.time()
    279           return self.outs.send(sx)
    280 
    281       def check_recv(self):
    282           return True
    283 
    284       def recv(self,x=MTU):
    285           ll = self.ins.datalink()
    286           if ll in conf.l2types:
    287               cls = conf.l2types[ll]
    288           else:
    289               cls = conf.default_l2
    290               warning("Unable to guess datalink type (interface=%s linktype=%i). Using %s", self.iface, ll, cls.name)
    291   
    292           pkt = self.ins.next()
    293           if pkt is not None:
    294               ts,pkt = pkt
    295           if pkt is None:
    296               return
    297           
    298           try:
    299               pkt = cls(pkt)
    300           except KeyboardInterrupt:
    301               raise
    302           except:
    303               if conf.debug_dissector:
    304                   raise
    305               pkt = conf.raw_layer(pkt)
    306           pkt.time = ts
    307           return pkt
    308   
    309       def nonblock_recv(self):
    310           self.ins.setnonblock(1)
    311           p = self.recv(MTU)
    312           self.ins.setnonblock(0)
    313           return p
    314   
    315       def close(self):
    316           if not self.closed:
    317               if hasattr(self, "ins"):
    318                   self.ins.close()
    319               if hasattr(self, "outs"):
    320                   self.outs.close()
    321           self.closed = True
    322 
    323   class L3pcapSocket(L2pcapSocket):
    324       desc = "read/write packets at layer 3 using only libpcap"
    325       #def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
    326       #    L2pcapSocket.__init__(self, iface, type, filter, nofilter)
    327       def recv(self, x = MTU):
    328           r = L2pcapSocket.recv(self, x) 
    329           if r:
    330             return r.payload
    331           else:
    332             return
    333       def send(self, x):
    334           # Makes send detects when it should add Loopback(), Dot11... instead of Ether()
    335           ll = self.ins.datalink()
    336           if ll in conf.l2types:
    337               cls = conf.l2types[ll]
    338           else:
    339               cls = conf.default_l2
    340               warning("Unable to guess datalink type (interface=%s linktype=%i). Using %s", self.iface, ll, cls.name)
    341           sx = raw(cls()/x)
    342           if hasattr(x, "sent_time"):
    343               x.sent_time = time.time()
    344           return self.ins.send(sx)
    345   conf.L2socket=L2pcapSocket
    346   conf.L3socket=L3pcapSocket
    347     
    348 if conf.use_pcap:
    349     try:
    350         import pcap
    351     except ImportError as e:
    352         try:
    353             import pcapy as pcap
    354         except ImportError as e2:
    355             if conf.interactive:
    356                 log_loading.error("Unable to import pcap module: %s/%s", e, e2)
    357                 conf.use_pcap = False
    358             else:
    359                 raise
    360     if conf.use_pcap:
    361         
    362         # From BSD net/bpf.h
    363         #BIOCIMMEDIATE=0x80044270
    364         BIOCIMMEDIATE=-2147204496
    365 
    366         if hasattr(pcap,"pcap"): # python-pypcap
    367             class _PcapWrapper_pypcap:
    368                 def __init__(self, device, snaplen, promisc, to_ms):
    369                     try:
    370                         self.pcap = pcap.pcap(device, snaplen, promisc, immediate=1, timeout_ms=to_ms)
    371                     except TypeError:
    372                         # Older pypcap versions do not support the timeout_ms argument
    373                         self.pcap = pcap.pcap(device, snaplen, promisc, immediate=1)                    
    374                 def __getattr__(self, attr):
    375                     return getattr(self.pcap, attr)
    376                 def __del__(self):
    377                     warning("__del__: don't know how to close the file descriptor. Bugs ahead ! Please report this bug.")
    378                 def next(self):
    379                     c = self.pcap.next()
    380                     if c is None:
    381                         return
    382                     ts, pkt = c
    383                     return ts, raw(pkt)
    384                 __next__ = next
    385             open_pcap = lambda *args,**kargs: _PcapWrapper_pypcap(*args,**kargs)
    386         elif hasattr(pcap,"pcapObject"): # python-libpcap
    387             class _PcapWrapper_libpcap:
    388                 def __init__(self, *args, **kargs):
    389                     self.pcap = pcap.pcapObject()
    390                     self.pcap.open_live(*args, **kargs)
    391                 def setfilter(self, filter):
    392                     self.pcap.setfilter(filter, 0, 0)
    393                 def next(self):
    394                     c = self.pcap.next()
    395                     if c is None:
    396                         return
    397                     l,pkt,ts = c 
    398                     return ts,pkt
    399                 __next__ = next
    400                 def __getattr__(self, attr):
    401                     return getattr(self.pcap, attr)
    402                 def __del__(self):
    403                     os.close(self.pcap.fileno())
    404             open_pcap = lambda *args,**kargs: _PcapWrapper_libpcap(*args,**kargs)
    405         elif hasattr(pcap,"open_live"): # python-pcapy
    406             class _PcapWrapper_pcapy:
    407                 def __init__(self, *args, **kargs):
    408                     self.pcap = pcap.open_live(*args, **kargs)
    409                 def next(self):
    410                     try:
    411                         c = self.pcap.next()
    412                     except pcap.PcapError:
    413                         return None
    414                     else:
    415                         h,p = c
    416                         if h is None:
    417                             return
    418                         s,us = h.getts()
    419                         return (s+0.000001*us), p
    420                 __next__ = next
    421                 def fileno(self):
    422                     raise RuntimeError("%s has no fileno. Please report this bug." %
    423                                        self.__class__.__name__)
    424                 def __getattr__(self, attr):
    425                     return getattr(self.pcap, attr)
    426                 def __del__(self):
    427                     try:
    428                         self.pcap.close()
    429                     except AttributeError:
    430                         warning("__del__: don't know how to close the file "
    431                                 "descriptor. Bugs ahead! Please update pcapy!")
    432             open_pcap = lambda *args,**kargs: _PcapWrapper_pcapy(*args,**kargs)
    433 
    434         
    435         class PcapTimeoutElapsed(Scapy_Exception):
    436             pass
    437     
    438         class L2pcapListenSocket(SuperSocket):
    439             desc = "read packets at layer 2 using libpcap"
    440             def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None):
    441                 self.type = type
    442                 self.outs = None
    443                 self.iface = iface
    444                 if iface is None:
    445                     iface = conf.iface
    446                 if promisc is None:
    447                     promisc = conf.sniff_promisc
    448                 self.promisc = promisc
    449                 self.ins = open_pcap(iface, 1600, self.promisc, 100)
    450                 try:
    451                     ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
    452                 except:
    453                     pass
    454                 if type == ETH_P_ALL: # Do not apply any filter if Ethernet type is given
    455                     if conf.except_filter:
    456                         if filter:
    457                             filter = "(%s) and not (%s)" % (filter, conf.except_filter)
    458                         else:
    459                             filter = "not (%s)" % conf.except_filter
    460                     if filter:
    461                         self.ins.setfilter(filter)
    462         
    463             def close(self):
    464                 del(self.ins)
    465                 
    466             def recv(self, x=MTU):
    467                 ll = self.ins.datalink()
    468                 if ll in conf.l2types:
    469                     cls = conf.l2types[ll]
    470                 else:
    471                     cls = conf.default_l2
    472                     warning("Unable to guess datalink type (interface=%s linktype=%i). Using %s", self.iface, ll, cls.name)
    473         
    474                 pkt = self.ins.next()
    475                 if scapy.arch.WINDOWS and pkt is None:
    476                         raise PcapTimeoutElapsed
    477                 if pkt is not None:
    478                     ts,pkt = pkt
    479                     try:
    480                         pkt = cls(pkt)
    481                     except KeyboardInterrupt:
    482                         raise
    483                     except:
    484                         if conf.debug_dissector:
    485                             raise
    486                         pkt = conf.raw_layer(pkt)
    487                     pkt.time = ts
    488                 return pkt
    489         
    490             def send(self, x):
    491                 raise Scapy_Exception("Can't send anything with L2pcapListenSocket")
    492         
    493     
    494         conf.L2listen = L2pcapListenSocket
    495 
    496 
    497 if conf.use_dnet:
    498     try:
    499         try:
    500             # First try to import dnet
    501             import dnet
    502         except ImportError:
    503             # Then, try to import dumbnet as dnet
    504             import dumbnet as dnet
    505     except ImportError as e:
    506         if conf.interactive:
    507             log_loading.error("Unable to import dnet module: %s", e)
    508             conf.use_dnet = False
    509             def get_if_raw_hwaddr(iff):
    510                 "dummy"
    511                 return (0,b"\0\0\0\0\0\0")
    512             def get_if_raw_addr(iff):
    513                 "dummy"
    514                 return b"\0\0\0\0"
    515             def get_if_list():
    516                 "dummy"
    517                 return []
    518         else:
    519             raise
    520     else:
    521         def get_if_raw_hwaddr(iff):
    522             """Return a tuple containing the link type and the raw hardware
    523                address corresponding to the interface 'iff'"""
    524 
    525             if iff == scapy.arch.LOOPBACK_NAME:
    526                 return (ARPHDR_LOOPBACK, b'\x00'*6)
    527 
    528             # Retrieve interface information
    529             try:
    530                 l = dnet.intf().get(iff)
    531                 link_addr = l["link_addr"]
    532             except:
    533                 raise Scapy_Exception("Error in attempting to get hw address"
    534                                       " for interface [%s]" % iff)
    535 
    536             if hasattr(link_addr, "type"):
    537                 # Legacy dnet module
    538                 return link_addr.type, link_addr.data
    539 
    540             else:
    541                 # dumbnet module
    542                 mac = mac2str(str(link_addr))
    543 
    544                 # Adjust the link type
    545                 if l["type"] == 6:  # INTF_TYPE_ETH from dnet
    546                     return (ARPHDR_ETHER, mac)
    547 
    548                 return (l["type"], mac)
    549 
    550         def get_if_raw_addr(ifname):
    551             i = dnet.intf()
    552             try:
    553                 return i.get(ifname)["addr"].data
    554             except (OSError, KeyError):
    555                 warning("No MAC address found on %s !" % ifname)
    556                 return b"\0\0\0\0"
    557 
    558 
    559         def get_if_list():
    560             return [i.get("name", None) for i in dnet.intf()]
    561 
    562 
    563         def get_working_if():
    564             """Returns the first interface than can be used with dnet"""
    565 
    566             if_iter = iter(dnet.intf())
    567 
    568             try:
    569                 intf = next(if_iter)
    570             except StopIteration:
    571                 return scapy.consts.LOOPBACK_NAME
    572 
    573             return intf.get("name", scapy.consts.LOOPBACK_NAME)
    574 
    575 
    576 if conf.use_pcap and conf.use_dnet:
    577     class L3dnetSocket(SuperSocket):
    578         desc = "read/write packets at layer 3 using libdnet and libpcap"
    579         def __init__(self, type = ETH_P_ALL, promisc=None, filter=None, iface=None, nofilter=0):
    580             self.iflist = {}
    581             self.intf = dnet.intf()
    582             if iface is None:
    583                 iface = conf.iface
    584             self.iface = iface
    585             if promisc is None:
    586                 promisc = 0
    587             self.promisc = promisc
    588             self.ins = open_pcap(iface, 1600, self.promisc, 100)
    589             try:
    590                 ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
    591             except:
    592                 pass
    593             if nofilter:
    594                 if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
    595                     filter = "ether proto %i" % type
    596                 else:
    597                     filter = None
    598             else:
    599                 if conf.except_filter:
    600                     if filter:
    601                         filter = "(%s) and not (%s)" % (filter, conf.except_filter)
    602                     else:
    603                         filter = "not (%s)" % conf.except_filter
    604                 if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
    605                     if filter:
    606                         filter = "(ether proto %i) and (%s)" % (type,filter)
    607                     else:
    608                         filter = "ether proto %i" % type
    609             if filter:
    610                 self.ins.setfilter(filter)
    611         def send(self, x):
    612             iff,a,gw  = x.route()
    613             if iff is None:
    614                 iff = conf.iface
    615             ifs,cls = self.iflist.get(iff,(None,None))
    616             if ifs is None:
    617                 iftype = self.intf.get(iff)["type"]
    618                 if iftype == dnet.INTF_TYPE_ETH:
    619                     try:
    620                         cls = conf.l2types[1]
    621                     except KeyError:
    622                         warning("Unable to find Ethernet class. Using nothing")
    623                     ifs = dnet.eth(iff)
    624                 else:
    625                     ifs = dnet.ip()
    626                 self.iflist[iff] = ifs,cls
    627             if cls is None:
    628                 sx = raw(x)
    629             else:
    630                 sx = raw(cls()/x)
    631             x.sent_time = time.time()
    632             ifs.send(sx)
    633         def recv(self,x=MTU):
    634             ll = self.ins.datalink()
    635             if ll in conf.l2types:
    636                 cls = conf.l2types[ll]
    637             else:
    638                 cls = conf.default_l2
    639                 warning("Unable to guess datalink type (interface=%s linktype=%i). Using %s", self.iface, ll, cls.name)
    640     
    641             pkt = self.ins.next()
    642             if pkt is not None:
    643                 ts,pkt = pkt
    644             if pkt is None:
    645                 return
    646     
    647             try:
    648                 pkt = cls(pkt)
    649             except KeyboardInterrupt:
    650                 raise
    651             except:
    652                 if conf.debug_dissector:
    653                     raise
    654                 pkt = conf.raw_layer(pkt)
    655             pkt.time = ts
    656             return pkt.payload
    657     
    658         def nonblock_recv(self):
    659             self.ins.setnonblock(1)
    660             p = self.recv()
    661             self.ins.setnonblock(0)
    662             return p
    663     
    664         def close(self):
    665             if not self.closed:
    666                 if hasattr(self, "ins"):
    667                     del(self.ins)
    668                 if hasattr(self, "outs"):
    669                     del(self.outs)
    670             self.closed = True
    671     
    672     class L2dnetSocket(SuperSocket):
    673         desc = "read/write packets at layer 2 using libdnet and libpcap"
    674         def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None, nofilter=0):
    675             if iface is None:
    676                 iface = conf.iface
    677             self.iface = iface
    678             if promisc is None:
    679                 promisc = 0
    680             self.promisc = promisc
    681             self.ins = open_pcap(iface, 1600, self.promisc, 100)
    682             try:
    683                 ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
    684             except:
    685                 pass
    686             if nofilter:
    687                 if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
    688                     filter = "ether proto %i" % type
    689                 else:
    690                     filter = None
    691             else:
    692                 if conf.except_filter:
    693                     if filter:
    694                         filter = "(%s) and not (%s)" % (filter, conf.except_filter)
    695                     else:
    696                         filter = "not (%s)" % conf.except_filter
    697                 if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
    698                     if filter:
    699                         filter = "(ether proto %i) and (%s)" % (type,filter)
    700                     else:
    701                         filter = "ether proto %i" % type
    702             if filter:
    703                 self.ins.setfilter(filter)
    704             self.outs = dnet.eth(iface)
    705         def recv(self,x=MTU):
    706             ll = self.ins.datalink()
    707             if ll in conf.l2types:
    708                 cls = conf.l2types[ll]
    709             else:
    710                 cls = conf.default_l2
    711                 warning("Unable to guess datalink type (interface=%s linktype=%i). Using %s", self.iface, ll, cls.name)
    712     
    713             pkt = self.ins.next()
    714             if pkt is not None:
    715                 ts,pkt = pkt
    716             if pkt is None:
    717                 return
    718             
    719             try:
    720                 pkt = cls(pkt)
    721             except KeyboardInterrupt:
    722                 raise
    723             except:
    724                 if conf.debug_dissector:
    725                     raise
    726                 pkt = conf.raw_layer(pkt)
    727             pkt.time = ts
    728             return pkt
    729     
    730         def nonblock_recv(self):
    731             self.ins.setnonblock(1)
    732             p = self.recv(MTU)
    733             self.ins.setnonblock(0)
    734             return p
    735     
    736         def close(self):
    737             if not self.closed:
    738                 if hasattr(self, "ins"):
    739                     del(self.ins)
    740                 if hasattr(self, "outs"):
    741                     del(self.outs)
    742             self.closed = True
    743 
    744     conf.L3socket=L3dnetSocket
    745     conf.L2socket=L2dnetSocket
    746 
    747         
    748     
    749