Skip to content

Commit a18382f

Browse files
author
Eric Marchand
committed
Report the interface ID used to capture pcapng files
* On pcapng files, you can have several capture interfaces. We report this information to be able to use it on another classes
1 parent 0648c0d commit a18382f

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

scapy/packet.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ class Packet(
101101
"direction", "sniffed_on",
102102
# handle snaplen Vs real length
103103
"wirelen",
104+
"intid",
104105
"comment",
105106
"process_information"
106107
]
@@ -177,6 +178,7 @@ def __init__(self,
177178
self.raw_packet_cache = None # type: Optional[bytes]
178179
self.raw_packet_cache_fields = None # type: Optional[Dict[str, Any]] # noqa: E501
179180
self.wirelen = None # type: Optional[int]
181+
self.intid = None
180182
self.direction = None # type: Optional[int]
181183
self.sniffed_on = None # type: Optional[_GlobInterfaceType]
182184
self.comment = None # type: Optional[bytes]
@@ -232,6 +234,7 @@ def __reduce__(self):
232234
self.direction,
233235
self.sniffed_on,
234236
self.wirelen,
237+
self.intid,
235238
self.comment
236239
))
237240

@@ -258,7 +261,6 @@ def init_fields(self, for_dissect_only=False):
258261
"""
259262
Initialize each fields of the fields_desc dict
260263
"""
261-
262264
if self.class_dont_cache.get(self.__class__, False):
263265
self.do_init_fields(self.fields_desc)
264266
else:
@@ -431,6 +433,7 @@ def copy(self) -> Self:
431433
self.raw_packet_cache_fields
432434
)
433435
clone.wirelen = self.wirelen
436+
clone.intid = self.intid
434437
clone.post_transforms = self.post_transforms[:]
435438
clone.payload = self.payload.copy()
436439
clone.payload.add_underlayer(clone)
@@ -500,6 +503,7 @@ def setfieldval(self, attr, val):
500503
self.raw_packet_cache = None
501504
self.raw_packet_cache_fields = None
502505
self.wirelen = None
506+
self.intid = None
503507
elif attr == "payload":
504508
self.remove_payload()
505509
self.add_payload(val)
@@ -524,6 +528,7 @@ def delfieldval(self, attr):
524528
self.raw_packet_cache = None
525529
self.raw_packet_cache_fields = None
526530
self.wirelen = None
531+
self.intid = None
527532
elif attr in self.default_fields:
528533
pass
529534
elif attr == "payload":
@@ -694,6 +699,8 @@ def self_build(self):
694699
# type: () -> bytes
695700
"""
696701
Create the default layer regarding fields_desc dict
702+
703+
:param field_pos_list:
697704
"""
698705
if self.raw_packet_cache is not None and \
699706
self.raw_packet_cache_fields is not None:
@@ -703,6 +710,7 @@ def self_build(self):
703710
self.raw_packet_cache = None
704711
self.raw_packet_cache_fields = None
705712
self.wirelen = None
713+
self.intid = None
706714
break
707715
if self.raw_packet_cache is not None:
708716
return self.raw_packet_cache
@@ -1145,6 +1153,7 @@ def clone_with(self, payload=None, **kargs):
11451153
self.raw_packet_cache_fields
11461154
)
11471155
pkt.wirelen = self.wirelen
1156+
pkt.intid = self.intid
11481157
pkt.comment = self.comment
11491158
pkt.sniffed_on = self.sniffed_on
11501159
pkt.direction = self.direction
@@ -2006,7 +2015,7 @@ def mysummary(self):
20062015
class Padding(Raw):
20072016
name = "Padding"
20082017

2009-
def self_build(self):
2018+
def self_build(self, field_pos_list=None):
20102019
# type: (Optional[Any]) -> bytes
20112020
return b""
20122021

scapy/utils.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -1647,7 +1647,7 @@ class RawPcapNgReader(RawPcapReader):
16471647
PacketMetadata = collections.namedtuple("PacketMetadataNg", # type: ignore
16481648
["linktype", "tsresol",
16491649
"tshigh", "tslow", "wirelen",
1650-
"comment", "ifname", "direction",
1650+
"comment","ifname","intid", "direction",
16511651
"process_information"])
16521652

16531653
def __init__(self, filename, fdesc=None, magic=None): # type: ignore
@@ -1656,6 +1656,7 @@ def __init__(self, filename, fdesc=None, magic=None): # type: ignore
16561656
self.f = fdesc
16571657
# A list of (linktype, snaplen, tsresol); will be populated by IDBs.
16581658
self.interfaces = [] # type: List[Tuple[int, int, Dict[str, Any]]]
1659+
self.interface_names = []
16591660
self.default_options = {
16601661
"tsresol": 1000000
16611662
}
@@ -1781,7 +1782,7 @@ def _read_block_shb(self):
17811782
def _read_packet(self, size=MTU): # type: ignore
17821783
# type: (int) -> Tuple[bytes, RawPcapNgReader.PacketMetadata]
17831784
"""Read blocks until it reaches either EOF or a packet, and
1784-
returns None or (packet, (linktype, sec, usec, wirelen)),
1785+
returns None or (packet, (linktype, sec, usec, wirelen,intid)),
17851786
where packet is a string.
17861787
17871788
"""
@@ -1800,7 +1801,7 @@ def _read_options(self, options):
18001801
warning("PcapNg: options header is too small "
18011802
"%d !" % len(options))
18021803
raise EOFError
1803-
if code != 0 and 4 + length <= len(options):
1804+
if code != 0 and 4 + length < len(options):
18041805
opts[code] = options[4:4 + length]
18051806
if code == 0:
18061807
if length != 0:
@@ -1860,6 +1861,7 @@ def _read_block_epb(self, block, size):
18601861
self.endian + "5I",
18611862
block[:20],
18621863
)
1864+
ifname = self.interface_names[intid] if intid < len(self.interface_names) else None
18631865
except struct.error:
18641866
warning("PcapNg: EPB is too small %d/20 !" % len(block))
18651867
raise EOFError
@@ -1914,6 +1916,7 @@ def _read_block_epb(self, block, size):
19141916
wirelen=wirelen,
19151917
comment=comment,
19161918
ifname=ifname,
1919+
intid=intid,
19171920
direction=direction,
19181921
process_information=process_information))
19191922

@@ -1952,6 +1955,7 @@ def _read_block_pkt(self, block, size):
19521955
self.endian + "HH4I",
19531956
block[:20],
19541957
)
1958+
ifname = self.interface_names[intid] if intid < len(self.interface_names) else None
19551959
except struct.error:
19561960
warning("PcapNg: PKT is too small %d/20 !" % len(block))
19571961
raise EOFError
@@ -2067,7 +2071,7 @@ def read_packet(self, size=MTU, **kwargs):
20672071
rp = super(PcapNgReader, self)._read_packet(size=size)
20682072
if rp is None:
20692073
raise EOFError
2070-
s, (linktype, tsresol, tshigh, tslow, wirelen, comment, ifname, direction, process_information) = rp # noqa: E501
2074+
s, (linktype, tsresol, tshigh, tslow, wirelen, comment, ifname, intid, direction, process_information) = rp # noqa: E501
20712075
try:
20722076
cls = conf.l2types.num2layer[linktype] # type: Type[Packet]
20732077
p = cls(s, **kwargs) # type: Packet
@@ -2088,6 +2092,7 @@ def read_packet(self, size=MTU, **kwargs):
20882092
p.process_information = process_information.copy()
20892093
if ifname is not None:
20902094
p.sniffed_on = ifname.decode('utf-8', 'backslashreplace')
2095+
p.intid = intid
20912096
return p
20922097

20932098
def recv(self, size: int = MTU, **kwargs: Any) -> 'Packet': # type: ignore
@@ -2210,7 +2215,7 @@ def write_packet(self,
22102215
comment=comment,
22112216
ifname=ifname,
22122217
direction=direction,
2213-
linktype=linktype
2218+
linktype=linktype,
22142219
)
22152220

22162221

@@ -2640,6 +2645,7 @@ def _write_packet(self, # type: ignore
26402645
if wirelen is None:
26412646
wirelen = caplen
26422647

2648+
26432649
ifid = self.interfaces2id.get(ifname, None)
26442650
if ifid is None:
26452651
ifid = max(self.interfaces2id.values()) + 1

0 commit comments

Comments
 (0)