• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"""
7Functions to send and receive packets.
8"""
9
10from __future__ import absolute_import, print_function
11import errno
12import itertools
13import threading
14import os
15from select import select, error as select_error
16import subprocess
17import time
18
19from scapy.consts import DARWIN, FREEBSD, OPENBSD, WINDOWS
20from scapy.data import ETH_P_ALL, MTU
21from scapy.config import conf
22from scapy.packet import Gen
23from scapy.utils import get_temp_file, PcapReader, tcpdump, wrpcap
24from scapy import plist
25from scapy.error import log_runtime, log_interactive
26from scapy.base_classes import SetGen
27from scapy.supersocket import StreamSocket, L3RawSocket, L2ListenTcpdump
28from scapy.modules import six
29from scapy.modules.six.moves import map
30if conf.route is None:
31    # unused import, only to initialize conf.route
32    import scapy.route
33from scapy.supersocket import SuperSocket
34
35#################
36## Debug class ##
37#################
38
39class debug:
40    recv=[]
41    sent=[]
42    match=[]
43
44
45####################
46## Send / Receive ##
47####################
48
49
50def _sndrcv_snd(pks, timeout, inter, verbose, tobesent, stopevent):
51    """Function used in the sending thread of sndrcv()"""
52    try:
53        i = 0
54        if verbose:
55            print("Begin emission:")
56        for p in tobesent:
57            pks.send(p)
58            i += 1
59            time.sleep(inter)
60        if verbose:
61            print("Finished to send %i packets." % i)
62    except SystemExit:
63        pass
64    except KeyboardInterrupt:
65        pass
66    except:
67        log_runtime.info("--- Error sending packets", exc_info=True)
68    if timeout is not None:
69        stopevent.wait(timeout)
70        stopevent.set()
71
72class _BreakException(Exception):
73    """A dummy exception used in _get_pkt() to get out of the infinite
74loop
75
76    """
77    pass
78
79def _sndrcv_rcv(pks, tobesent, stopevent, nbrecv, notans, verbose, chainCC,
80                multi):
81    """Function used to recieve packets and check their hashret"""
82    ans = []
83    hsent = {}
84    for i in tobesent:
85        h = i.hashret()
86        hsent.setdefault(i.hashret(), []).append(i)
87
88    if WINDOWS:
89        def _get_pkt():
90            return pks.recv(MTU)
91    elif conf.use_bpf:
92        from scapy.arch.bpf.supersocket import bpf_select
93        def _get_pkt():
94            if bpf_select([pks]):
95                return pks.recv()
96    elif (conf.use_pcap and not isinstance(pks, (StreamSocket, L3RawSocket, L2ListenTcpdump))) or \
97         (not isinstance(pks, (StreamSocket, L2ListenTcpdump)) and (DARWIN or FREEBSD or OPENBSD)):
98        def _get_pkt():
99            res = pks.nonblock_recv()
100            if res is None:
101                time.sleep(0.05)
102            return res
103    else:
104        def _get_pkt():
105            try:
106                inp, _, _ = select([pks], [], [], 0.05)
107            except (IOError, select_error) as exc:
108                # select.error has no .errno attribute
109                if exc.args[0] != errno.EINTR:
110                    raise
111            else:
112                if inp:
113                    return pks.recv(MTU)
114            if stopevent.is_set():
115                raise _BreakException()
116
117    try:
118        try:
119            while True:
120                r = _get_pkt()
121                if r is None:
122                    if stopevent.is_set():
123                        break
124                    continue
125                ok = False
126                h = r.hashret()
127                if h in hsent:
128                    hlst = hsent[h]
129                    for i, sentpkt in enumerate(hlst):
130                        if r.answers(sentpkt):
131                            ans.append((sentpkt, r))
132                            if verbose > 1:
133                                os.write(1, b"*")
134                            ok = True
135                            if not multi:
136                                del hlst[i]
137                                notans -= 1
138                            else:
139                                if not hasattr(sentpkt, '_answered'):
140                                    notans -= 1
141                                sentpkt._answered = 1
142                            break
143                if notans == 0 and not multi:
144                    break
145                if not ok:
146                    if verbose > 1:
147                        os.write(1, b".")
148                    nbrecv += 1
149                    if conf.debug_match:
150                        debug.recv.append(r)
151        except KeyboardInterrupt:
152            if chainCC:
153                raise
154        except _BreakException:
155            pass
156    finally:
157        stopevent.set()
158    return (hsent, ans, nbrecv, notans)
159
160def sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=False,
161           retry=0, multi=False, rcv_pks=None):
162    """Scapy raw function to send a packet and recieve its answer.
163    WARNING: This is an internal function. Using sr/srp/sr1/srp is
164    more appropriate in many cases.
165
166    pks: SuperSocket instance to send/recieve packets
167    pkt: the packet to send
168    rcv_pks: if set, will be used instead of pks to recieve packets. packets will still
169             be sent through pks
170    nofilter: put 1 to avoid use of BPF filters
171    retry:    if positive, how many times to resend unanswered packets
172              if negative, how many times to retry when no more packets are answered
173    timeout:  how much time to wait after the last packet has been sent
174    verbose:  set verbosity level
175    multi:    whether to accept multiple answers for the same stimulus"""
176    if not isinstance(pkt, Gen):
177        pkt = SetGen(pkt)
178    if verbose is None:
179        verbose = conf.verb
180    debug.recv = plist.PacketList([],"Unanswered")
181    debug.sent = plist.PacketList([],"Sent")
182    debug.match = plist.SndRcvList([])
183    nbrecv = 0
184    ans = []
185    # do it here to fix random fields, so that parent and child have the same
186    tobesent = [p for p in pkt]
187    notans = len(tobesent)
188
189    if retry < 0:
190        retry = -retry
191        autostop = retry
192    else:
193        autostop = 0
194
195    while retry >= 0:
196        if timeout is not None and timeout < 0:
197            timeout = None
198        stopevent = threading.Event()
199
200        thread = threading.Thread(
201            target=_sndrcv_snd,
202            args=(pks, timeout, inter, verbose, tobesent, stopevent),
203        )
204        thread.start()
205
206        hsent, newans, nbrecv, notans = _sndrcv_rcv(
207            (rcv_pks or pks), tobesent, stopevent, nbrecv, notans, verbose, chainCC, multi,
208        )
209        thread.join()
210        ans.extend(newans)
211
212        remain = list(itertools.chain(*six.itervalues(hsent)))
213        if multi:
214            remain = [p for p in remain if not hasattr(p, '_answered')]
215
216        if autostop and len(remain) > 0 and len(remain) != len(tobesent):
217            retry = autostop
218
219        tobesent = remain
220        if len(tobesent) == 0:
221            break
222        retry -= 1
223
224    if conf.debug_match:
225        debug.sent=plist.PacketList(remain[:], "Sent")
226        debug.match=plist.SndRcvList(ans[:])
227
228    # Clean the ans list to delete the field _answered
229    if multi:
230        for snd, _ in ans:
231            if hasattr(snd, '_answered'):
232                del snd._answered
233
234    if verbose:
235        print("\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans))
236    return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
237
238
239def __gen_send(s, x, inter=0, loop=0, count=None, verbose=None, realtime=None, return_packets=False, *args, **kargs):
240    if isinstance(x, str):
241        x = conf.raw_layer(load=x)
242    if not isinstance(x, Gen):
243        x = SetGen(x)
244    if verbose is None:
245        verbose = conf.verb
246    n = 0
247    if count is not None:
248        loop = -count
249    elif not loop:
250        loop = -1
251    if return_packets:
252        sent_packets = plist.PacketList()
253    try:
254        while loop:
255            dt0 = None
256            for p in x:
257                if realtime:
258                    ct = time.time()
259                    if dt0:
260                        st = dt0+p.time-ct
261                        if st > 0:
262                            time.sleep(st)
263                    else:
264                        dt0 = ct-p.time
265                s.send(p)
266                if return_packets:
267                    sent_packets.append(p)
268                n += 1
269                if verbose:
270                    os.write(1,b".")
271                time.sleep(inter)
272            if loop < 0:
273                loop += 1
274    except KeyboardInterrupt:
275        pass
276    s.close()
277    if verbose:
278        print("\nSent %i packets." % n)
279    if return_packets:
280        return sent_packets
281
282@conf.commands.register
283def send(x, inter=0, loop=0, count=None, verbose=None, realtime=None, return_packets=False, socket=None,
284         *args, **kargs):
285    """Send packets at layer 3
286send(packets, [inter=0], [loop=0], [count=None], [verbose=conf.verb], [realtime=None], [return_packets=False],
287     [socket=None]) -> None"""
288    if socket is None:
289        socket = conf.L3socket(*args, **kargs)
290    return __gen_send(socket, x, inter=inter, loop=loop, count=count,verbose=verbose,
291                      realtime=realtime, return_packets=return_packets)
292
293@conf.commands.register
294def sendp(x, inter=0, loop=0, iface=None, iface_hint=None, count=None, verbose=None, realtime=None,
295          return_packets=False, socket=None, *args, **kargs):
296    """Send packets at layer 2
297sendp(packets, [inter=0], [loop=0], [iface=None], [iface_hint=None], [count=None], [verbose=conf.verb],
298      [realtime=None], [return_packets=False], [socket=None]) -> None"""
299    if iface is None and iface_hint is not None and socket is None:
300        iface = conf.route.route(iface_hint)[0]
301    if socket is None:
302        socket = conf.L2socket(iface=iface, *args, **kargs)
303    return __gen_send(socket, x, inter=inter, loop=loop, count=count,
304                      verbose=verbose, realtime=realtime, return_packets=return_packets)
305
306@conf.commands.register
307def sendpfast(x, pps=None, mbps=None, realtime=None, loop=0, file_cache=False, iface=None):
308    """Send packets at layer 2 using tcpreplay for performance
309    pps:  packets per second
310    mpbs: MBits per second
311    realtime: use packet's timestamp, bending time with real-time value
312    loop: number of times to process the packet list
313    file_cache: cache packets in RAM instead of reading from disk at each iteration
314    iface: output interface """
315    if iface is None:
316        iface = conf.iface
317    argv = [conf.prog.tcpreplay, "--intf1=%s" % iface ]
318    if pps is not None:
319        argv.append("--pps=%i" % pps)
320    elif mbps is not None:
321        argv.append("--mbps=%f" % mbps)
322    elif realtime is not None:
323        argv.append("--multiplier=%f" % realtime)
324    else:
325        argv.append("--topspeed")
326
327    if loop:
328        argv.append("--loop=%i" % loop)
329        if file_cache:
330            argv.append("--preload-pcap")
331
332    f = get_temp_file()
333    argv.append(f)
334    wrpcap(f, x)
335    try:
336        subprocess.check_call(argv)
337    except KeyboardInterrupt:
338        log_interactive.info("Interrupted by user")
339    except Exception:
340        if conf.interactive:
341            log_interactive.error("Cannot execute [%s]", argv[0], exc_info=True)
342        else:
343            raise
344    finally:
345        os.unlink(f)
346
347
348
349
350
351@conf.commands.register
352def sr(x, promisc=None, filter=None, iface=None, nofilter=0, *args,**kargs):
353    """Send and receive packets at layer 3
354nofilter: put 1 to avoid use of BPF filters
355retry:    if positive, how many times to resend unanswered packets
356          if negative, how many times to retry when no more packets are answered
357timeout:  how much time to wait after the last packet has been sent
358verbose:  set verbosity level
359multi:    whether to accept multiple answers for the same stimulus
360filter:   provide a BPF filter
361iface:    listen answers only on the given interface"""
362    if "timeout" not in kargs:
363        kargs["timeout"] = -1
364    s = conf.L3socket(promisc=promisc, filter=filter, iface=iface, nofilter=nofilter)
365    result = sndrcv(s, x, *args, **kargs)
366    s.close()
367    return result
368
369@conf.commands.register
370def sr1(x, promisc=None, filter=None, iface=None, nofilter=0, *args,**kargs):
371    """Send packets at layer 3 and return only the first answer
372nofilter: put 1 to avoid use of BPF filters
373retry:    if positive, how many times to resend unanswered packets
374          if negative, how many times to retry when no more packets are answered
375timeout:  how much time to wait after the last packet has been sent
376verbose:  set verbosity level
377multi:    whether to accept multiple answers for the same stimulus
378filter:   provide a BPF filter
379iface:    listen answers only on the given interface"""
380    if "timeout" not in kargs:
381        kargs["timeout"] = -1
382    s=conf.L3socket(promisc=promisc, filter=filter, nofilter=nofilter, iface=iface)
383    ans, _ = sndrcv(s, x, *args, **kargs)
384    s.close()
385    if len(ans) > 0:
386        return ans[0][1]
387    else:
388        return None
389
390@conf.commands.register
391def srp(x, promisc=None, iface=None, iface_hint=None, filter=None, nofilter=0, type=ETH_P_ALL, *args,**kargs):
392    """Send and receive packets at layer 2
393nofilter: put 1 to avoid use of BPF filters
394retry:    if positive, how many times to resend unanswered packets
395          if negative, how many times to retry when no more packets are answered
396timeout:  how much time to wait after the last packet has been sent
397verbose:  set verbosity level
398multi:    whether to accept multiple answers for the same stimulus
399filter:   provide a BPF filter
400iface:    work only on the given interface"""
401    if "timeout" not in kargs:
402        kargs["timeout"] = -1
403    if iface is None and iface_hint is not None:
404        iface = conf.route.route(iface_hint)[0]
405    s = conf.L2socket(promisc=promisc, iface=iface, filter=filter, nofilter=nofilter, type=type)
406    result = sndrcv(s, x, *args, **kargs)
407    s.close()
408    return result
409
410@conf.commands.register
411def srp1(*args,**kargs):
412    """Send and receive packets at layer 2 and return only the first answer
413nofilter: put 1 to avoid use of BPF filters
414retry:    if positive, how many times to resend unanswered packets
415          if negative, how many times to retry when no more packets are answered
416timeout:  how much time to wait after the last packet has been sent
417verbose:  set verbosity level
418multi:    whether to accept multiple answers for the same stimulus
419filter:   provide a BPF filter
420iface:    work only on the given interface"""
421    if "timeout" not in kargs:
422        kargs["timeout"] = -1
423    ans, _ = srp(*args, **kargs)
424    if len(ans) > 0:
425        return ans[0][1]
426    else:
427        return None
428
429# SEND/RECV LOOP METHODS
430
431def __sr_loop(srfunc, pkts, prn=lambda x:x[1].summary(), prnfail=lambda x:x.summary(), inter=1, timeout=None, count=None, verbose=None, store=1, *args, **kargs):
432    n = 0
433    r = 0
434    ct = conf.color_theme
435    if verbose is None:
436        verbose = conf.verb
437    parity = 0
438    ans=[]
439    unans=[]
440    if timeout is None:
441        timeout = min(2*inter, 5)
442    try:
443        while True:
444            parity ^= 1
445            col = [ct.even,ct.odd][parity]
446            if count is not None:
447                if count == 0:
448                    break
449                count -= 1
450            start = time.time()
451            if verbose > 1:
452                print("\rsend...\r", end=' ')
453            res = srfunc(pkts, timeout=timeout, verbose=0, chainCC=True, *args, **kargs)
454            n += len(res[0])+len(res[1])
455            r += len(res[0])
456            if verbose > 1 and prn and len(res[0]) > 0:
457                msg = "RECV %i:" % len(res[0])
458                print("\r"+ct.success(msg), end=' ')
459                for p in res[0]:
460                    print(col(prn(p)))
461                    print(" "*len(msg), end=' ')
462            if verbose > 1 and prnfail and len(res[1]) > 0:
463                msg = "fail %i:" % len(res[1])
464                print("\r"+ct.fail(msg), end=' ')
465                for p in res[1]:
466                    print(col(prnfail(p)))
467                    print(" "*len(msg), end=' ')
468            if verbose > 1 and not (prn or prnfail):
469                print("recv:%i  fail:%i" % tuple(map(len, res[:2])))
470            if store:
471                ans += res[0]
472                unans += res[1]
473            end=time.time()
474            if end-start < inter:
475                time.sleep(inter+start-end)
476    except KeyboardInterrupt:
477        pass
478
479    if verbose and n>0:
480        print(ct.normal("\nSent %i packets, received %i packets. %3.1f%% hits." % (n,r,100.0*r/n)))
481    return plist.SndRcvList(ans),plist.PacketList(unans)
482
483@conf.commands.register
484def srloop(pkts, *args, **kargs):
485    """Send a packet at layer 3 in loop and print the answer each time
486srloop(pkts, [prn], [inter], [count], ...) --> None"""
487    return __sr_loop(sr, pkts, *args, **kargs)
488
489@conf.commands.register
490def srploop(pkts, *args, **kargs):
491    """Send a packet at layer 2 in loop and print the answer each time
492srloop(pkts, [prn], [inter], [count], ...) --> None"""
493    return __sr_loop(srp, pkts, *args, **kargs)
494
495# SEND/RECV FLOOD METHODS
496
497def sndrcvflood(pks, pkt, inter=0, verbose=None, chainCC=False, prn=lambda x: x):
498    if not verbose:
499        verbose = conf.verb
500    if not isinstance(pkt, Gen):
501        pkt = SetGen(pkt)
502    tobesent = [p for p in pkt]
503
504    stopevent = threading.Event()
505    count_packets = six.moves.queue.Queue()
506
507    def send_in_loop(tobesent, stopevent, count_packets=count_packets):
508        """Infinite generator that produces the same packet until stopevent is triggered."""
509        while True:
510            for p in tobesent:
511                if stopevent.is_set():
512                    raise StopIteration()
513                count_packets.put(0)
514                yield p
515
516    infinite_gen = send_in_loop(tobesent, stopevent)
517
518    # We don't use _sndrcv_snd verbose (it messes the logs up as in a thread that ends after recieving)
519    thread = threading.Thread(
520        target=_sndrcv_snd,
521        args=(pks, None, inter, False, infinite_gen, stopevent),
522    )
523    thread.start()
524
525    hsent, ans, nbrecv, notans = _sndrcv_rcv(pks, tobesent, stopevent, 0, len(tobesent), verbose, chainCC, False)
526    thread.join()
527    remain = list(itertools.chain(*six.itervalues(hsent)))
528    # Apply prn
529    ans = [(x, prn(y)) for (x, y) in ans]
530
531    if verbose:
532        print("\nReceived %i packets, got %i answers, remaining %i packets. Sent a total of %i packets." % (nbrecv+len(ans), len(ans), notans, count_packets.qsize()))
533    count_packets.empty()
534    del count_packets
535
536    return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
537
538@conf.commands.register
539def srflood(x, promisc=None, filter=None, iface=None, nofilter=None, *args,**kargs):
540    """Flood and receive packets at layer 3
541prn:      function applied to packets received
542unique:   only consider packets whose print
543nofilter: put 1 to avoid use of BPF filters
544filter:   provide a BPF filter
545iface:    listen answers only on the given interface"""
546    s = conf.L3socket(promisc=promisc, filter=filter, iface=iface, nofilter=nofilter)
547    r=sndrcvflood(s,x,*args,**kargs)
548    s.close()
549    return r
550
551@conf.commands.register
552def sr1flood(x, promisc=None, filter=None, iface=None, nofilter=0, *args,**kargs):
553    """Flood and receive packets at layer 3 and return only the first answer
554prn:      function applied to packets received
555verbose:  set verbosity level
556nofilter: put 1 to avoid use of BPF filters
557filter:   provide a BPF filter
558iface:    listen answers only on the given interface"""
559    s=conf.L3socket(promisc=promisc, filter=filter, nofilter=nofilter, iface=iface)
560    ans, _ = sndrcvflood(s, x, *args, **kargs)
561    s.close()
562    if len(ans) > 0:
563        return ans[0][1]
564    else:
565        return None
566
567@conf.commands.register
568def srpflood(x, promisc=None, filter=None, iface=None, iface_hint=None, nofilter=None, *args,**kargs):
569    """Flood and receive packets at layer 2
570prn:      function applied to packets received
571unique:   only consider packets whose print
572nofilter: put 1 to avoid use of BPF filters
573filter:   provide a BPF filter
574iface:    listen answers only on the given interface"""
575    if iface is None and iface_hint is not None:
576        iface = conf.route.route(iface_hint)[0]
577    s = conf.L2socket(promisc=promisc, filter=filter, iface=iface, nofilter=nofilter)
578    r=sndrcvflood(s,x,*args,**kargs)
579    s.close()
580    return r
581
582@conf.commands.register
583def srp1flood(x, promisc=None, filter=None, iface=None, nofilter=0, *args,**kargs):
584    """Flood and receive packets at layer 2 and return only the first answer
585prn:      function applied to packets received
586verbose:  set verbosity level
587nofilter: put 1 to avoid use of BPF filters
588filter:   provide a BPF filter
589iface:    listen answers only on the given interface"""
590    s=conf.L2socket(promisc=promisc, filter=filter, nofilter=nofilter, iface=iface)
591    ans, _ = sndrcvflood(s, x, *args, **kargs)
592    s.close()
593    if len(ans) > 0:
594        return ans[0][1]
595    else:
596        return None
597
598# SNIFF METHODS
599
600@conf.commands.register
601def sniff(count=0, store=True, offline=None, prn=None, lfilter=None,
602          L2socket=None, timeout=None, opened_socket=None,
603          stop_filter=None, iface=None, *arg, **karg):
604    """
605
606Sniff packets and return a list of packets.
607
608Arguments:
609
610  count: number of packets to capture. 0 means infinity.
611
612  store: whether to store sniffed packets or discard them
613
614  prn: function to apply to each packet. If something is returned, it
615      is displayed.
616
617      Ex: prn = lambda x: x.summary()
618
619  filter: BPF filter to apply.
620
621  lfilter: Python function applied to each packet to determine if
622      further action may be done.
623
624      Ex: lfilter = lambda x: x.haslayer(Padding)
625
626  offline: PCAP file (or list of PCAP files) to read packets from,
627      instead of sniffing them
628
629  timeout: stop sniffing after a given time (default: None).
630
631  L2socket: use the provided L2socket (default: use conf.L2listen).
632
633  opened_socket: provide an object (or a list of objects) ready to use
634      .recv() on.
635
636  stop_filter: Python function applied to each packet to determine if
637      we have to stop the capture after this packet.
638
639      Ex: stop_filter = lambda x: x.haslayer(TCP)
640
641  iface: interface or list of interfaces (default: None for sniffing
642      on all interfaces).
643
644The iface, offline and opened_socket parameters can be either an
645element, a list of elements, or a dict object mapping an element to a
646label (see examples below).
647
648Examples:
649
650  >>> sniff(filter="arp")
651
652  >>> sniff(lfilter=lambda pkt: ARP in pkt)
653
654  >>> sniff(iface="eth0", prn=Packet.summary)
655
656  >>> sniff(iface=["eth0", "mon0"],
657  ...       prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
658  ...                                   pkt.summary()))
659
660  >>> sniff(iface={"eth0": "Ethernet", "mon0": "Wifi"},
661  ...       prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
662  ...                                   pkt.summary()))
663
664    """
665    c = 0
666    sniff_sockets = {}  # socket: label dict
667    if opened_socket is not None:
668        if isinstance(opened_socket, list):
669            sniff_sockets.update((s, "socket%d" % i)
670                                 for i, s in enumerate(opened_socket))
671        elif isinstance(opened_socket, dict):
672            sniff_sockets.update((s, label)
673                                 for s, label in six.iteritems(opened_socket))
674        else:
675            sniff_sockets[opened_socket] = "socket0"
676    if offline is not None:
677        flt = karg.get('filter')
678        if isinstance(offline, list):
679            sniff_sockets.update((PcapReader(
680                fname if flt is None else
681                tcpdump(fname, args=["-w", "-", flt], getfd=True)
682            ), fname) for fname in offline)
683        elif isinstance(offline, dict):
684            sniff_sockets.update((PcapReader(
685                fname if flt is None else
686                tcpdump(fname, args=["-w", "-", flt], getfd=True)
687            ), label) for fname, label in six.iteritems(offline))
688        else:
689            sniff_sockets[PcapReader(
690                offline if flt is None else
691                tcpdump(offline, args=["-w", "-", flt], getfd=True)
692            )] = offline
693    if not sniff_sockets or iface is not None:
694        if L2socket is None:
695            L2socket = conf.L2listen
696        if isinstance(iface, list):
697            sniff_sockets.update(
698                (L2socket(type=ETH_P_ALL, iface=ifname, *arg, **karg), ifname)
699                for ifname in iface
700            )
701        elif isinstance(iface, dict):
702            sniff_sockets.update(
703                (L2socket(type=ETH_P_ALL, iface=ifname, *arg, **karg), iflabel)
704                for ifname, iflabel in six.iteritems(iface)
705            )
706        else:
707            sniff_sockets[L2socket(type=ETH_P_ALL, iface=iface,
708                                   *arg, **karg)] = iface
709    lst = []
710    if timeout is not None:
711        stoptime = time.time()+timeout
712    remain = None
713    read_allowed_exceptions = ()
714    if conf.use_bpf:
715        from scapy.arch.bpf.supersocket import bpf_select
716        def _select(sockets):
717            return bpf_select(sockets, remain)
718    elif WINDOWS:
719        from scapy.arch.pcapdnet import PcapTimeoutElapsed
720        read_allowed_exceptions = (PcapTimeoutElapsed,)
721        def _select(sockets):
722            try:
723                return sockets
724            except PcapTimeoutElapsed:
725                return []
726    else:
727        def _select(sockets):
728            try:
729                return select(sockets, [], [], remain)[0]
730            except select_error as exc:
731                # Catch 'Interrupted system call' errors
732                if exc[0] == errno.EINTR:
733                    return []
734                raise
735    try:
736        while sniff_sockets:
737            if timeout is not None:
738                remain = stoptime-time.time()
739                if remain <= 0:
740                    break
741            ins = _select(sniff_sockets)
742            for s in ins:
743                try:
744                    p = s.recv()
745                except read_allowed_exceptions:
746                    continue
747                if p is None:
748                    del sniff_sockets[s]
749                    break
750                if lfilter and not lfilter(p):
751                    continue
752                p.sniffed_on = sniff_sockets[s]
753                if store:
754                    lst.append(p)
755                c += 1
756                if prn:
757                    r = prn(p)
758                    if r is not None:
759                        print(r)
760                if stop_filter and stop_filter(p):
761                    sniff_sockets = []
762                    break
763                if 0 < count <= c:
764                    sniff_sockets = []
765                    break
766    except KeyboardInterrupt:
767        pass
768    if opened_socket is None:
769        for s in sniff_sockets:
770            s.close()
771    return plist.PacketList(lst,"Sniffed")
772
773
774@conf.commands.register
775def bridge_and_sniff(if1, if2, xfrm12=None, xfrm21=None, prn=None, L2socket=None,
776                     *args, **kargs):
777    """Forward traffic between interfaces if1 and if2, sniff and return
778the exchanged packets.
779
780Arguments:
781
782  if1, if2: the interfaces to use (interface names or opened sockets).
783
784  xfrm12: a function to call when forwarding a packet from if1 to
785      if2. If it returns True, the packet is forwarded as it. If it
786      returns False or None, the packet is discarded. If it returns a
787      packet, this packet is forwarded instead of the original packet
788      one.
789
790  xfrm21: same as xfrm12 for packets forwarded from if2 to if1.
791
792  The other arguments are the same than for the function sniff(),
793      except for offline, opened_socket and iface that are ignored.
794      See help(sniff) for more.
795
796    """
797    for arg in ['opened_socket', 'offline', 'iface']:
798        if arg in kargs:
799            log_runtime.warning("Argument %s cannot be used in "
800                                "bridge_and_sniff() -- ignoring it.", arg)
801            del kargs[arg]
802    def _init_socket(iface, count):
803        if isinstance(iface, SuperSocket):
804            return iface, "iface%d" % count
805        else:
806            return (L2socket or conf.L2socket)(iface=iface), iface
807    sckt1, if1 = _init_socket(if1, 1)
808    sckt2, if2 = _init_socket(if2, 2)
809    peers = {if1: sckt2, if2: sckt1}
810    xfrms = {}
811    if xfrm12 is not None:
812        xfrms[if1] = xfrm12
813    if xfrm21 is not None:
814        xfrms[if2] = xfrm21
815    def prn_send(pkt):
816        try:
817            sendsock = peers[pkt.sniffed_on]
818        except KeyError:
819            return
820        if pkt.sniffed_on in xfrms:
821            try:
822                newpkt = xfrms[pkt.sniffed_on](pkt)
823            except:
824                log_runtime.warning(
825                    'Exception in transformation function for packet [%s] '
826                    'received on %s -- dropping',
827                    pkt.summary(), pkt.sniffed_on, exc_info=True
828                )
829                return
830            else:
831                if newpkt is True:
832                    newpkt = pkt.original
833                elif not newpkt:
834                    return
835        else:
836            newpkt = pkt.original
837        try:
838            sendsock.send(newpkt)
839        except:
840            log_runtime.warning('Cannot forward packet [%s] received on %s',
841                                pkt.summary(), pkt.sniffed_on, exc_info=True)
842    if prn is None:
843        prn = prn_send
844    else:
845        prn_orig = prn
846        def prn(pkt):
847            prn_send(pkt)
848            return prn_orig(pkt)
849
850    return sniff(opened_socket={sckt1: if1, sckt2: if2}, prn=prn,
851                 *args, **kargs)
852
853
854@conf.commands.register
855def tshark(*args,**kargs):
856    """Sniff packets and print them calling pkt.summary(), a bit like text wireshark"""
857    print("Capturing on '" + str(kargs.get('iface') if 'iface' in kargs else conf.iface) + "'")
858    i = [0]  # This should be a nonlocal variable, using a mutable object for Python 2 compatibility
859    def _cb(pkt):
860        print("%5d\t%s" % (i[0], pkt.summary()))
861        i[0] += 1
862    sniff(prn=_cb, store=False, *args, **kargs)
863    print("\n%d packet%s captured" % (i[0], 's' if i[0] > 1 else ''))
864