源码

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re
import sys
import json

def parse_line(line):
    '''
    解析一行数据,返回一个字典,包含源IP、源端口、目的IP、目的端口
    输入:
        1.1.1.1.8888 > 123.123.123.123.123
    输出:
        {'src_ip': '1.1.1.1', 'src_port': 8888, 'dst_ip': '123.123.123.123', 'dst_port': 123}
    '''
    line = line.strip()

    # IPv4 pattern: 支持完整IPv4地址
    ipv4_pattern = r'(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'

    # IPv6 pattern: 支持完整IPv6地址和压缩形式(使用::)
    hex_4 = r'[0-9a-fA-F]{1,4}'
    ipv6_full = r'(?:{0}:){{7}}{0}'.format(hex_4)  # 完整格式 8段
    ipv6_compressed = r'(?:(?:{0}:){{0,6}}{0})?::(?:(?:{0}:){{0,6}}{0})?'.format(hex_4)  # 压缩格式
    ipv6_pattern = r'(?:{0}|{1})'.format(ipv6_full, ipv6_compressed)

    # 端口号pattern: 1-65535
    port_pattern = r'(?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3})'

    pattern = r'''
        (?P<src_ip>(?:{0}|{1}))\.?(?P<src_port>{2}) # 源IP和源端口
        \s*>\s*
        (?P<dst_ip>(?:{0}|{1}))\.?(?P<dst_port>{2}) # 目的IP和目的端口
    '''.format(ipv4_pattern, ipv6_pattern, port_pattern)

    regex = re.compile(pattern, re.VERBOSE) # 使用re.VERBOSE标志以忽略正则表达式中的空白和注释
    line = line.strip() # 去除行尾的换行符
    match = regex.search(line) # 使用正则表达式进行匹配
    if match:
        src_ip = match.group('src_ip')
        dst_ip = match.group('dst_ip')  
        src_port = int(match.group('src_port'))
        dst_port = int(match.group('dst_port'))
        return {'src_ip': src_ip, 'src_port': src_port, 'dst_ip': dst_ip, 'dst_port': dst_port}
    else:
        return None

if __name__ == "__main__":
    # 从标准输入读取数据
    # tcpdump -i en0 -nn -c 10 | python3 parse.py
    while True:
        line = sys.stdin.readline()
        if not line:
            break
        result = parse_line(line)
        if result:
            print(json.dumps(result))

使用

tcpdump -i en0 -nn -c 10 2>/dev/null | python3 parse.py
python3 parse.py <<(tcpdump -i en0 -nn -c 10 2>/dev/null)
{"src_ip": "192.168.111.103", "src_port": 548, "dst_ip": "192.168.111.100", "dst_port": 56364}
{"src_ip": "192.168.111.103", "src_port": 548, "dst_ip": "192.168.111.100", "dst_port": 56364}
{"src_ip": "192.168.111.103", "src_port": 548, "dst_ip": "192.168.111.100", "dst_port": 56364}
{"src_ip": "192.168.111.103", "src_port": 548, "dst_ip": "192.168.111.100", "dst_port": 56364}
{"src_ip": "192.168.111.103", "src_port": 548, "dst_ip": "192.168.111.100", "dst_port": 56364}
{"src_ip": "192.168.111.103", "src_port": 548, "dst_ip": "192.168.111.100", "dst_port": 56364}
{"src_ip": "192.168.111.103", "src_port": 548, "dst_ip": "192.168.111.100", "dst_port": 56364}
{"src_ip": "192.168.111.103", "src_port": 548, "dst_ip": "192.168.111.100", "dst_port": 56364}
{"src_ip": "192.168.111.103", "src_port": 548, "dst_ip": "192.168.111.100", "dst_port": 56364}
{"src_ip": "192.168.111.103", "src_port": 548, "dst_ip": "192.168.111.100", "dst_port": 56364}