11
11
from decimal import Decimal
12
12
from io import StringIO
13
13
from itertools import zip_longest
14
+ from uuid import UUID
14
15
15
16
import array
16
17
import argparse
@@ -1646,7 +1647,8 @@ class RawPcapNgReader(RawPcapReader):
1646
1647
PacketMetadata = collections .namedtuple ("PacketMetadataNg" , # type: ignore
1647
1648
["linktype" , "tsresol" ,
1648
1649
"tshigh" , "tslow" , "wirelen" ,
1649
- "comment" , "ifname" , "direction" ])
1650
+ "comment" , "ifname" , "direction" ,
1651
+ "process_information" ])
1650
1652
1651
1653
def __init__ (self , filename , fdesc = None , magic = None ): # type: ignore
1652
1654
# type: (str, IO[bytes], bytes) -> None
@@ -1668,8 +1670,10 @@ def __init__(self, filename, fdesc=None, magic=None): # type: ignore
1668
1670
3 : self ._read_block_spb ,
1669
1671
6 : self ._read_block_epb ,
1670
1672
10 : self ._read_block_dsb ,
1673
+ 0x80000001 : self ._read_block_pib ,
1671
1674
}
1672
1675
self .endian = "!" # Will be overwritten by first SHB
1676
+ self .process_information = [] # type: List[Dict[str, Any]]
1673
1677
1674
1678
if magic != b"\x0a \x0d \x0d \x0a " : # PcapNg:
1675
1679
raise Scapy_Exception (
@@ -1868,6 +1872,18 @@ def _read_block_epb(self, block, size):
1868
1872
1869
1873
# Parse options
1870
1874
options = self ._read_options (block [opt_offset :])
1875
+
1876
+ process_information = {}
1877
+ for code , value in options .items ():
1878
+ if code in [0x8001 , 0x8003 ]: # PCAPNG_EPB_PIB_INDEX, PCAPNG_EPB_E_PIB_INDEX
1879
+ proc_index = struct .unpack (self .endian + "I" , value )[0 ]
1880
+ if proc_index < len (self .process_information ):
1881
+ key = "proc" if code == 0x8001 else "eproc"
1882
+ process_information [key ] = self .process_information [proc_index ]
1883
+ else :
1884
+ warning ("PcapNg: EPB invalid process information index "
1885
+ "(%d/%d) !" % (proc_index , len (self .process_information )))
1886
+
1871
1887
comment = options .get (1 , None )
1872
1888
epb_flags_raw = options .get (2 , None )
1873
1889
if epb_flags_raw :
@@ -1884,6 +1900,7 @@ def _read_block_epb(self, block, size):
1884
1900
1885
1901
self ._check_interface_id (intid )
1886
1902
ifname = self .interfaces [intid ][2 ].get ('name' , None )
1903
+
1887
1904
return (block [20 :20 + caplen ][:size ],
1888
1905
RawPcapNgReader .PacketMetadata (linktype = self .interfaces [intid ][0 ], # noqa: E501
1889
1906
tsresol = self .interfaces [intid ][2 ]['tsresol' ], # noqa: E501
@@ -1892,7 +1909,8 @@ def _read_block_epb(self, block, size):
1892
1909
wirelen = wirelen ,
1893
1910
comment = comment ,
1894
1911
ifname = ifname ,
1895
- direction = direction ))
1912
+ direction = direction ,
1913
+ process_information = process_information ))
1896
1914
1897
1915
def _read_block_spb (self , block , size ):
1898
1916
# type: (bytes, int) -> Tuple[bytes, RawPcapNgReader.PacketMetadata]
@@ -1918,7 +1936,8 @@ def _read_block_spb(self, block, size):
1918
1936
wirelen = wirelen ,
1919
1937
comment = None ,
1920
1938
ifname = None ,
1921
- direction = None ))
1939
+ direction = None ,
1940
+ process_information = {}))
1922
1941
1923
1942
def _read_block_pkt (self , block , size ):
1924
1943
# type: (bytes, int) -> Tuple[bytes, RawPcapNgReader.PacketMetadata]
@@ -1941,7 +1960,8 @@ def _read_block_pkt(self, block, size):
1941
1960
wirelen = wirelen ,
1942
1961
comment = None ,
1943
1962
ifname = None ,
1944
- direction = None ))
1963
+ direction = None ,
1964
+ process_information = {}))
1945
1965
1946
1966
def _read_block_dsb (self , block , size ):
1947
1967
# type: (bytes, int) -> None
@@ -1995,6 +2015,35 @@ def _read_block_dsb(self, block, size):
1995
2015
else :
1996
2016
warning ("PcapNg: Unknown DSB secrets type (0x%x)!" , secrets_type )
1997
2017
2018
+ def _read_block_pib (self , block , _ ):
2019
+ # type: (bytes, int) -> None
2020
+ """Apple Process Information Block"""
2021
+
2022
+ # Get the Process ID
2023
+ try :
2024
+ dpeb_pid = struct .unpack (self .endian + "I" , block [:4 ])[0 ]
2025
+ process_information = {"id" : dpeb_pid }
2026
+ block = block [4 :]
2027
+ except struct .error :
2028
+ warning ("PcapNg: DPEB is too small (%d). Cannot get PID!" ,
2029
+ len (block ))
2030
+ raise EOFError
2031
+
2032
+ # Get Options
2033
+ options = self ._read_options (block )
2034
+ for code , value in options .items ():
2035
+ if code == 2 :
2036
+ process_information ["name" ] = value .decode ("ascii" , "backslashreplace" )
2037
+ elif code == 4 :
2038
+ if len (value ) == 16 :
2039
+ process_information ["uuid" ] = str (UUID (bytes = value ))
2040
+ else :
2041
+ warning ("PcapNg: DPEB UUID length is invalid (%d)!" ,
2042
+ len (value ))
2043
+
2044
+ # Store process information
2045
+ self .process_information .append (process_information )
2046
+
1998
2047
1999
2048
class PcapNgReader (RawPcapNgReader , PcapReader ):
2000
2049
@@ -2013,7 +2062,7 @@ def read_packet(self, size=MTU, **kwargs):
2013
2062
rp = super (PcapNgReader , self )._read_packet (size = size )
2014
2063
if rp is None :
2015
2064
raise EOFError
2016
- s , (linktype , tsresol , tshigh , tslow , wirelen , comment , ifname , direction ) = rp
2065
+ s , (linktype , tsresol , tshigh , tslow , wirelen , comment , ifname , direction , process_information ) = rp # noqa: E501
2017
2066
try :
2018
2067
cls = conf .l2types .num2layer [linktype ] # type: Type[Packet]
2019
2068
p = cls (s , ** kwargs ) # type: Packet
@@ -2031,6 +2080,7 @@ def read_packet(self, size=MTU, **kwargs):
2031
2080
p .wirelen = wirelen
2032
2081
p .comment = comment
2033
2082
p .direction = direction
2083
+ p .process_information = process_information .copy ()
2034
2084
if ifname is not None :
2035
2085
p .sniffed_on = ifname .decode ('utf-8' , 'backslashreplace' )
2036
2086
return p
0 commit comments