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 common to different architectures 8""" 9 10import socket 11from fcntl import ioctl 12import os, struct, ctypes 13from ctypes import POINTER, Structure 14from ctypes import c_uint, c_uint32, c_ushort, c_ubyte 15from scapy.config import conf 16import scapy.modules.six as six 17 18def get_if(iff, cmd): 19 """Ease SIOCGIF* ioctl calls""" 20 21 sck = socket.socket() 22 ifreq = ioctl(sck, cmd, struct.pack("16s16x", iff.encode("utf8"))) 23 sck.close() 24 return ifreq 25 26class bpf_insn(Structure): 27 """"The BPF instruction data structure""" 28 _fields_ = [("code", c_ushort), 29 ("jt", c_ubyte), 30 ("jf", c_ubyte), 31 ("k", c_uint32)] 32 33 34class bpf_program(Structure): 35 """"Structure for BIOCSETF""" 36 _fields_ = [("bf_len", c_uint), 37 ("bf_insns", POINTER(bpf_insn))] 38 39def _legacy_bpf_pointer(tcpdump_lines): 40 """Get old-format BPF Pointer. Deprecated""" 41 X86_64 = os.uname()[4] in ['x86_64', 'aarch64'] 42 size = int(tcpdump_lines[0]) 43 bpf = "" 44 for l in tcpdump_lines[1:]: 45 bpf += struct.pack("HBBI",*map(long,l.split())) 46 47 # Thanks to http://www.netprojects.de/scapy-with-pypy-solved/ for the pypy trick 48 if conf.use_pypy and six.PY2: 49 str_buffer = ctypes.create_string_buffer(bpf) 50 return struct.pack('HL', size, ctypes.addressof(str_buffer)) 51 else: 52 # XXX. Argl! We need to give the kernel a pointer on the BPF, 53 # Python object header seems to be 20 bytes. 36 bytes for x86 64bits arch. 54 if X86_64: 55 return struct.pack("HL", size, id(bpf)+36) 56 else: 57 return struct.pack("HI", size, id(bpf)+20) 58 59def get_bpf_pointer(tcpdump_lines): 60 """Create a BPF Pointer for TCPDump filter""" 61 if conf.use_pypy and six.PY2: 62 return _legacy_bpf_pointer(tcpdump_lines) 63 64 # Allocate BPF instructions 65 size = int(tcpdump_lines[0]) 66 bpf_insn_a = bpf_insn * size 67 bip = bpf_insn_a() 68 69 # Fill the BPF instruction structures with the byte code 70 tcpdump_lines = tcpdump_lines[1:] 71 i = 0 72 for line in tcpdump_lines: 73 values = [int(v) for v in line.split()] 74 bip[i].code = c_ushort(values[0]) 75 bip[i].jt = c_ubyte(values[1]) 76 bip[i].jf = c_ubyte(values[2]) 77 bip[i].k = c_uint(values[3]) 78 i += 1 79 80 # Create the BPF program 81 return bpf_program(size, bip) 82