1#!/usr/bin/env python3
2#
3# Copyright (c) 2021 Intel Corporation
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#    http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import getopt
18import socket
19import sys
20import os.path
21from datetime import datetime
22from scapy.all import *
23
24interface = None
25verbose = True
26port = 4242
27pcap = None
28type = "Ether"
29
30argv = sys.argv[1:]
31
32def usage():
33    print("Listen captured network data from Zephyr and save it " +
34        "optionally to pcap file.\n")
35    print(f"{sys.argv[0]} \\" +
36          "\n\t-i | --interface <network interface>" +
37          "\n\t\tListen this inferface for the data" +
38          "\n\t[-p | --port <UDP port>]" +
39          f"\n\t\tUDP port (default is {port}) where the capture data is received" +
40          "\n\t[-q | --quiet]" +
41          "\n\t\tDo not print packet information" +
42          "\n\t[-t | --type <L2 type of the data>]" +
43          f"\n\t\tScapy L2 type name of the UDP payload, default is {type}" +
44          "\n\t[-w | --write <pcap file name>]" +
45          "\n\t\tWrite the received data to file in PCAP format")
46
47try:
48    opts, args = getopt.getopt(argv,
49                               'hi:p:qt:w:',
50                               ['help', 'interface=', 'port=',
51                                'quiet', 'type=', 'write='])
52except getopt.GetoptError as err:
53    print(err)
54    usage()
55    sys.exit(2)
56
57for o, a in opts:
58    if o in ("-q", "--quiet"):
59        verbose = False
60    elif o in ("-h", "--help"):
61        usage()
62        sys.exit()
63    elif o in ("-i", "--interface"):
64        interface = a
65    elif o in ("-p", "--port"):
66        port = int(a)
67    elif o in ("-t", "--type"):
68        type = a
69    elif o in ("-w", "--write"):
70        pcap = a
71    else:
72        assert False, "unhandled option " + o
73
74if interface == None:
75    print("Network interface not set.\n")
76    usage()
77    sys.exit()
78
79if pcap != None and os.path.exists(pcap):
80    os.remove(pcap)
81
82sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
83sock.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE,
84                interface.encode())
85sock.bind(('', port))
86
87def process_packet(data):
88    packet = eval(type)(data)
89
90    if verbose:
91        now = datetime.utcnow()
92        hdr = now.strftime("%Y%m%dZ%H:%M:%S") + "." + str(now.microsecond)
93        print('[%s] %s' % (hdr, packet.summary()))
94    if pcap != None:
95        wrpcap(pcap, packet, append=True)
96
97while True:
98    data, address = sock.recvfrom(4096)
99    process_packet(data)
100