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 * 23from scapy.layers.can import CAN 24 25interface = None 26verbose = True 27port = 4242 28pcap = None 29type = "Ether" 30cooked = False 31cooked_sllv1 = False 32cooked_sllv2 = False 33 34argv = sys.argv[1:] 35 36def usage(): 37 print("Listen captured network data from Zephyr and save it " + 38 "optionally to pcap file.\n") 39 print(f"{sys.argv[0]} \\" + 40 "\n\t-i | --interface <network interface>" + 41 "\n\t\tListen this inferface for the data" + 42 "\n\t[-p | --port <UDP port>]" + 43 f"\n\t\tUDP port (default is {port}) where the capture data is received" + 44 "\n\t[-q | --quiet]" + 45 "\n\t\tDo not print packet information" + 46 "\n\t[-t | --type <L2 type of the data>]" + 47 f"\n\t\tScapy L2 type name of the UDP payload, default is {type}" + 48 "\n\t[-w | --write <pcap file name>]" + 49 "\n\t\tWrite the received data to file in PCAP format" + 50 "\n\t[-c | --cooked-sllv1]" + 51 "\n\t\tThe payload is Linux cooked mode v1 data" + 52 "\n\t[-C | --cooked-sllv2]" + 53 "\n\t\tThe payload is Linux cooked mode v2 data") 54 55try: 56 opts, args = getopt.getopt(argv, 57 'cChi:p:qt:w:', 58 ['cooked-sllv1', 'cooked-sllv2', 'help', 59 'interface=', 'port=', 60 'quiet', 'type=', 'write=']) 61except getopt.GetoptError as err: 62 print(err) 63 usage() 64 sys.exit(2) 65 66for o, a in opts: 67 if o in ("-q", "--quiet"): 68 verbose = False 69 elif o in ("-h", "--help"): 70 usage() 71 sys.exit() 72 elif o in ("-i", "--interface"): 73 interface = a 74 elif o in ("-p", "--port"): 75 port = int(a) 76 elif o in ("-t", "--type"): 77 type = a 78 elif o in ("-w", "--write"): 79 pcap = a 80 elif o in ("-c", "--cooked-sllv1"): 81 cooked_sllv1 = True 82 cooked = True 83 elif o in ("-C", "--cooked-sllv2"): 84 cooked_sllv2 = True 85 cooked = True 86 else: 87 assert False, "unhandled option " + o 88 89if interface == None: 90 print("Network interface not set.\n") 91 usage() 92 sys.exit() 93 94if pcap != None and os.path.exists(pcap): 95 os.remove(pcap) 96 97sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) 98sock.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, 99 interface.encode()) 100sock.bind(('', port)) 101 102def process_packet(data): 103 packet = eval(type)(data) 104 105 if cooked: 106 if cooked_sllv1: 107 packet = CookedLinux(_pkt = Packet.build(packet)) 108 else: 109 packet = CookedLinuxV2(_pkt = Packet.build(packet)) 110 111 packet.show() 112 113 if verbose: 114 now = datetime.utcnow() 115 hdr = now.strftime("%Y%m%dZ%H:%M:%S") + "." + str(now.microsecond) 116 print('[%s] %s' % (hdr, packet.summary())) 117 if pcap != None: 118 wrpcap(pcap, packet, append=True) 119 120while True: 121 data, address = sock.recvfrom(4096) 122 process_packet(data) 123