From e2b28c774fe856fa8b483cf016f20adabef8822f Mon Sep 17 00:00:00 2001 From: "Thomas M. Galla" Date: Wed, 4 Mar 2026 16:07:05 +0100 Subject: [PATCH 1/4] Removed superfluous commented out code --- sockdump.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sockdump.py b/sockdump.py index 4ebc85b..de8e86d 100755 --- a/sockdump.py +++ b/sockdump.py @@ -402,7 +402,6 @@ def main(args): else: sys.stdout.flush() # fflush buffer of current stdout sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb') # fdopen as binary - # sys.stdout = sys.stdout.buffer pcap_write_header(args.seg_size, PCAP_LINK_TYPE) else: if args.output != '/dev/stdout': From 790e91af3ce29aef330648df70c0cc4f57f70713 Mon Sep 17 00:00:00 2001 From: "Thomas M. Galla" Date: Thu, 5 Mar 2026 22:51:13 +0100 Subject: [PATCH 2/4] Added first shot on properly displaying of abstract sockets for string and hex(string) otuput --- sockdump.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/sockdump.py b/sockdump.py index de8e86d..5fe8666 100755 --- a/sockdump.py +++ b/sockdump.py @@ -242,7 +242,7 @@ class Packet(ct.Structure): ('len', ct.c_uint), ('flags', ct.c_uint), ('comm', ct.c_char * TASK_COMM_LEN), - ('path', ct.c_char * UNIX_PATH_MAX), + ('path', ct.c_byte * UNIX_PATH_MAX), # using c_byte to properly deal with leading \0 abstract UN*X domain sockets # variable length data ] @@ -270,13 +270,24 @@ def parse_event(event, size): return packet, data +def sanitize_pathname(pathname): + sanitized_pathname = bytearray(pathname) + # abstract UN*X domain socket? + if (sanitized_pathname[0] == 0): + sanitized_pathname[0] = ord('@') + + # split at first string terminator + split_pathname = sanitized_pathname.split(b'\x00', 1) + + return split_pathname[0] if len(split_pathname) > 1 else sanitized_pathname + def print_header(packet, data): ts = time.time() ts = time.strftime('%H:%M:%S', time.localtime(ts)) + '.%03d' % (ts%1 * 1000) print('%s >>> process %s [%d -> %d] path %s len %d(%d)' % ( ts, packet.comm.decode(), packet.pid, packet.peer_pid, - packet.path.decode(), len(data), packet.len)) + sanitize_pathname(packet.path).decode(), len(data), packet.len)) def string_output(cpu, event, size): global flush_after_each_packet From fc79481a671fefb9e79945210e445beccfdf6adf Mon Sep 17 00:00:00 2001 From: "Thomas M. Galla" Date: Fri, 6 Mar 2026 10:35:14 +0100 Subject: [PATCH 3/4] Completed proper displaying of abstract sockets - pcap output --- sockdump.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/sockdump.py b/sockdump.py index 5fe8666..2e32bd8 100755 --- a/sockdump.py +++ b/sockdump.py @@ -242,7 +242,8 @@ class Packet(ct.Structure): ('len', ct.c_uint), ('flags', ct.c_uint), ('comm', ct.c_char * TASK_COMM_LEN), - ('path', ct.c_byte * UNIX_PATH_MAX), # using c_byte to properly deal with leading \0 abstract UN*X domain sockets + # using c_byte here to properly deal with the leading '\0' abstract UN*X domain sockets + ('path', ct.c_byte * UNIX_PATH_MAX), # variable length data ] @@ -270,16 +271,21 @@ def parse_event(event, size): return packet, data -def sanitize_pathname(pathname): +def sanitize_pathname(pathname, replacement=0): + # create modifyable copy sanitized_pathname = bytearray(pathname) - # abstract UN*X domain socket? + + start_idx = 0 + + # abstract UN*X domain socket? => replace leading '\0' with replacement if (sanitized_pathname[0] == 0): - sanitized_pathname[0] = ord('@') + start_idx = 1 if len(sanitized_pathname) > 1 else 0 + sanitized_pathname[0] = replacement - # split at first string terminator - split_pathname = sanitized_pathname.split(b'\x00', 1) + # discard garbage starting with first end-of-string character (excluding the leading one) + eos_idx = sanitized_pathname.find(b'\x00', start_idx) - return split_pathname[0] if len(split_pathname) > 1 else sanitized_pathname + return sanitized_pathname if eos_idx == -1 else sanitized_pathname[:eos_idx] def print_header(packet, data): ts = time.time() @@ -287,7 +293,7 @@ def print_header(packet, data): print('%s >>> process %s [%d -> %d] path %s len %d(%d)' % ( ts, packet.comm.decode(), packet.pid, packet.peer_pid, - sanitize_pathname(packet.path).decode(), len(data), packet.len)) + sanitize_pathname(packet.path, ord('@')).decode(), len(data), packet.len)) def string_output(cpu, event, size): global flush_after_each_packet @@ -357,7 +363,7 @@ def pcap_output(cpu, event, size): ts = time.time() ts_sec = int(ts) ts_usec = int((ts % 1) * 10**6) - header = struct.pack(f'>{UNIX_PATH_MAX + 1}pQQ', packet.path, packet.peer_pid, packet.pid) + header = struct.pack(f'>{UNIX_PATH_MAX + 1}pQQ', sanitize_pathname(packet.path), packet.peer_pid, packet.pid) data = header + data size = len(header) + packet.len From cc2e04d9d25a8df8a52d1dc9a4d951b0cb23e53f Mon Sep 17 00:00:00 2001 From: "Thomas M. Galla" Date: Mon, 16 Mar 2026 16:58:50 +0100 Subject: [PATCH 4/4] Used correct varibale name --- sockdump.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sockdump.py b/sockdump.py index 2e32bd8..81f82b9 100755 --- a/sockdump.py +++ b/sockdump.py @@ -302,7 +302,7 @@ def string_output(cpu, event, size): print_header(packet, data) if packet.flags & SS_PACKET_F_ERR: print('error') - print(str(data.raw, encoding='ascii', errors='ignore'), end='', flush=flush_after_each_event) + print(str(data.raw, encoding='ascii', errors='ignore'), end='', flush=flush_after_each_packet) def ascii(c): if c < 32 or c > 126: