I have this code that works fine when it's defined altogether, but if I move a portion of the code to its own function, I get an OSError: [Errno 22] Invalid argument
.
from ctypes import create_string_buffer, addressof
from struct import pack, unpack
import socket
SHOW_ERROR: bool = True
def bpf_jump(code, k, jt, jf):
return pack('HBBI', code, jt, jf, k)
def bpf_stmt(code, k):
return bpf_jump(code, k, 0, 0)
# Instruction classes
BPF_LD = 0x00
BPF_JMP = 0x05
BPF_RET = 0x06
# ld/ldx fields
BPF_H = 0x08
BPF_B = 0x10
BPF_ABS = 0x20
# alu/jmp fields
BPF_JEQ = 0x10
BPF_K = 0x00
# As defined in asm/socket.h
SO_ATTACH_FILTER = 26
# Ordering of the filters is backwards of what would be intuitive for
# performance reasons: the check that is most likely to fail is first.
filters_list = [
# Must be UDP (check protocol field at byte offset 23)
bpf_stmt(BPF_LD | BPF_B | BPF_ABS, 23),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 0x11, 0, 3),
# Must be IPv4 (check ethertype field at byte offset 12)
bpf_stmt(BPF_LD | BPF_H | BPF_ABS, 12),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 0x0800, 0, 1),
bpf_stmt(BPF_RET | BPF_K, 0x0FFFFFFF), # pass
bpf_stmt(BPF_RET | BPF_K, 0), # reject
]
str_buf = None
def create_filters_struct() -> bytes:
filters = b''.join(filters_list)
str_buf = create_string_buffer(filters)
mem_addr_of_filters = addressof(str_buf)
fprog = pack('HL', len(filters_list), mem_addr_of_filters)
return fprog
if SHOW_ERROR is False:
filters = b''.join(filters_list)
b = create_string_buffer(filters)
mem_addr_of_filters = addressof(b)
fprog = pack('HL', len(filters_list), mem_addr_of_filters)
else:
fprog = create_filters_struct()
net_if = "eth0"
sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003))
sock.setsockopt(socket.SOL_SOCKET,
SO_ATTACH_FILTER,
fprog)
Here is the error traceback:
Traceback (most recent call last):
File "error_demo.py", line 68, in <module>
fprog)
OSError: [Errno 22] Invalid argument
How can I fix this?