1## This file is part of Scapy
2## See http://www.secdev.org/projects/scapy for more informations
3## Copyright (C) Philippe Biondi <phil@secdev.org>
4## This program is published under a GPLv2 license
5
6"""
7Packet sending and receiving with libdnet and libpcap/WinPcap.
8"""
9
10import time, struct, sys, platform
11import socket
12if not sys.platform.startswith("win"):
13    from fcntl import ioctl
14
15from scapy.data import *
16from scapy.compat import *
17from scapy.config import conf
18from scapy.utils import mac2str
19from scapy.supersocket import SuperSocket
20from scapy.error import Scapy_Exception, log_loading, warning
21from scapy.pton_ntop import inet_ntop
22from scapy.automaton import SelectableObject
23import scapy.arch
24import scapy.consts
25
26if 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
348if 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
497if 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
576if 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