Skip to content

Commit ecf2fac

Browse files
committed
Improve BPF validation with tcpdump
1 parent b895f72 commit ecf2fac

3 files changed

Lines changed: 22 additions & 12 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ MANIFEST
66
*.egg-info/
77
scapy/VERSION
88
test/*.html
9+
.coverage*
910
.tox
1011
.ipynb_checkpoints
1112
.mypy_cache

scapy/utils.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,20 +1974,19 @@ def tdecode(
19741974
def _guess_linktype_name(value):
19751975
# type: (int) -> str
19761976
"""Guess the DLT name from its value."""
1977-
import scapy.data
1978-
return next( # type: ignore
1979-
k[4:] for k, v in six.iteritems(scapy.data.__dict__)
1980-
if k.startswith("DLT") and v == value
1981-
)
1977+
from scapy.libs.winpcapy import pcap_datalink_val_to_name
1978+
return cast(bytes, pcap_datalink_val_to_name(value)).decode()
19821979

19831980

19841981
def _guess_linktype_value(name):
19851982
# type: (str) -> int
19861983
"""Guess the value of a DLT name."""
1987-
import scapy.data
1988-
if not name.startswith("DLT_"):
1989-
name = "DLT_" + name
1990-
return scapy.data.__dict__[name] # type: ignore
1984+
from scapy.libs.winpcapy import pcap_datalink_name_to_val
1985+
val = cast(int, pcap_datalink_name_to_val(name.encode()))
1986+
if val == -1:
1987+
warning("Unknown linktype: %s. Using EN10MB", name)
1988+
return DLT_EN10MB
1989+
return val
19911990

19921991

19931992
@conf.commands.register
@@ -2103,8 +2102,6 @@ def tcpdump(
21032102
raise ValueError("prog must be a string")
21042103

21052104
if linktype is not None:
2106-
# Tcpdump does not support integers in -y (yet)
2107-
# https://github.com/the-tcpdump-group/tcpdump/issues/758
21082105
if isinstance(linktype, int):
21092106
# Guess name from value
21102107
try:
@@ -2135,8 +2132,12 @@ def tcpdump(
21352132

21362133
if flt is not None:
21372134
# Check the validity of the filter
2135+
if linktype is None and isinstance(pktlist, str):
2136+
# linktype is unknown but required. Read it from file
2137+
with PcapReader(pktlist) as rd:
2138+
linktype = rd.linktype
21382139
from scapy.arch.common import compile_filter
2139-
compile_filter(flt)
2140+
compile_filter(flt, linktype=linktype)
21402141
args.append(flt)
21412142

21422143
stdout = subprocess.PIPE if dump or getfd else None

test/regression.uts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2153,6 +2153,14 @@ assert raw(pkt) in f.getvalue()
21532153
f.close()
21542154
del f, pkt
21552155

2156+
= Check sniff() offline with linktype & 802.11 filter
2157+
~ tcpdump
2158+
2159+
fd = get_temp_file()
2160+
wrpcap(fd, [RadioTap()/Dot11()/Dot11ProbeReq(), RadioTap()/Dot11()])
2161+
lst = sniff(offline=fd, filter="subtype probe-req")
2162+
assert len(lst) == 1
2163+
21562164
= Check tcpdump() command rejects non-string input for prog
21572165

21582166
pkt = Ether()/IP()/ICMP()

0 commit comments

Comments
 (0)