Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/scapy/arch/common.py: 31%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# SPDX-License-Identifier: GPL-2.0-only
2# This file is part of Scapy
3# See https://scapy.net/ for more information
4# Copyright (C) Philippe Biondi <phil@secdev.org>
6"""
7Functions common to different architectures
8"""
10import ctypes
11import re
12import socket
14from scapy.config import conf
15from scapy.data import MTU, ARPHRD_TO_DLT, DLT_RAW_ALT, DLT_RAW
16from scapy.error import Scapy_Exception, warning
17from scapy.interfaces import network_name, resolve_iface, NetworkInterface
18from scapy.libs.structures import bpf_program
19from scapy.pton_ntop import inet_pton
20from scapy.utils import decode_locale_str
22# Type imports
23import scapy
24from typing import (
25 List,
26 Optional,
27 Union,
28)
30# From if.h
31_iff_flags = [
32 "UP",
33 "BROADCAST",
34 "DEBUG",
35 "LOOPBACK",
36 "POINTTOPOINT",
37 "NOTRAILERS",
38 "RUNNING",
39 "NOARP",
40 "PROMISC",
41 "ALLMULTI",
42 "MASTER",
43 "SLAVE",
44 "MULTICAST",
45 "PORTSEL",
46 "AUTOMEDIA",
47 "DYNAMIC",
48 "LOWER_UP",
49 "DORMANT",
50 "ECHO"
51]
54def get_if_raw_addr(iff):
55 # type: (Union[NetworkInterface, str]) -> bytes
56 """Return the raw IPv4 address of interface"""
57 iff = resolve_iface(iff)
58 if not iff.ip:
59 return b"\x00" * 4
60 return inet_pton(socket.AF_INET, iff.ip)
63# BPF HANDLERS
66def compile_filter(filter_exp, # type: str
67 iface=None, # type: Optional[Union[str, 'scapy.interfaces.NetworkInterface']] # noqa: E501
68 linktype=None, # type: Optional[int]
69 promisc=False # type: bool
70 ):
71 # type: (...) -> bpf_program
72 """Asks libpcap to parse the filter, then build the matching
73 BPF bytecode.
75 :param iface: if provided, use the interface to compile
76 :param linktype: if provided, use the linktype to compile
77 """
78 try:
79 from scapy.libs.winpcapy import (
80 PCAP_ERRBUF_SIZE,
81 pcap_open_live,
82 pcap_open_dead,
83 pcap_compile,
84 pcap_geterr,
85 pcap_close
86 )
87 except OSError:
88 raise ImportError(
89 "libpcap is not available. Cannot compile filter !"
90 )
91 from ctypes import create_string_buffer
92 bpf = bpf_program()
93 bpf_filter = create_string_buffer(filter_exp.encode("utf8"))
94 if not linktype:
95 # Try to guess linktype to avoid root
96 if not iface:
97 if not conf.iface:
98 raise Scapy_Exception(
99 "Please provide an interface or linktype!"
100 )
101 iface = conf.iface
102 # Try to guess linktype to avoid requiring root
103 try:
104 arphd = resolve_iface(iface).type
105 linktype = ARPHRD_TO_DLT.get(arphd)
106 except Exception:
107 # Failed to use linktype: use the interface
108 pass
109 if linktype is not None:
110 # Some conversion aliases (e.g. linktype_to_dlt in libpcap)
111 if linktype == DLT_RAW_ALT:
112 linktype = DLT_RAW
113 # Use a "dead" capture handle (no interface / no root required) so that,
114 # on failure, the libpcap error message can be retrieved with pcap_geterr
115 pcap = pcap_open_dead(linktype, MTU)
116 elif iface:
117 err = create_string_buffer(PCAP_ERRBUF_SIZE)
118 iface_b = create_string_buffer(network_name(iface).encode("utf8"))
119 pcap = pcap_open_live(
120 iface_b, MTU, promisc, 0, err
121 )
122 error = decode_locale_str(bytearray(err).strip(b"\x00"))
123 if error:
124 raise OSError(error)
125 else:
126 raise Scapy_Exception("Please provide an interface or linktype!")
127 ret = pcap_compile(
128 pcap, ctypes.byref(bpf), bpf_filter, 1, -1
129 )
130 if ret == -1:
131 # Retrieve the underlying libpcap error message: it explains why the
132 # filter is invalid or incompatible with the link-layer type
133 errstr = decode_locale_str(
134 bytearray(pcap_geterr(pcap)).strip(b"\x00")
135 )
136 pcap_close(pcap)
137 raise Scapy_Exception(
138 "Failed to compile filter expression %r (%s)" % (filter_exp, errstr)
139 )
140 pcap_close(pcap)
141 return bpf
144def free_filter(bp: bpf_program) -> None:
145 """
146 Free a bpf_program created with compile_filter
147 """
148 from scapy.libs.winpcapy import pcap_freecode
149 pcap_freecode(ctypes.byref(bp))
152#######
153# DNS #
154#######
156def read_nameservers() -> List[str]:
157 """Return the nameservers configured by the OS
158 """
159 try:
160 with open('/etc/resolv.conf', 'r') as fd:
161 return re.findall(r"nameserver\s+([^\s]+)", fd.read())
162 except FileNotFoundError:
163 warning("Could not retrieve the OS's nameserver !")
164 return []