PCAP 数据包洞察暨 IP 地缘定位系统

import dpkt
import socket
import geoip2.database
import argparse
# 加载GeoIP数据库
# 使用geoip2.database.Reader类来读取本地的GeoLite2-City.mmdb数据库文件,
# 参数指定了数据库文件在本地磁盘的具体路径,这里是 'D:\GeoLite2-City\GeoLite2-City_20241122\GeoLite2-City.mmdb',
# 通过这个对象后续可以查询IP地址对应的地理位置信息。
gi = geoip2.database.Reader(r'D:\GeoLite2-City\GeoLite2-City_20241122\GeoLite2-City.mmdb')
# 定义一个函数,用于根据给定的IP地址获取对应的地理位置信息字符串表示
def retGeoStr(ip):
    try:
        """
        通过之前加载的GeoIP数据库对象gi的city方法,传入IP地址来查询该IP对应的地理位置详细信息。
        返回的rec是一个包含多种地理位置信息的对象,例如城市、国家、地区等相关信息。
        """
        rec = gi.city(ip)
        # 从查询结果对象中获取城市名称,如果存在的话。
        city = rec.city.name
        # 从查询结果对象中获取国家的ISO代码,用于标识国家。
        country = rec.country.iso_code
        if city:
            """
            如果获取到的城市名称不为空,那么地理位置信息字符串就由城市名和国家的ISO代码组成,用逗号和空格隔开,
            例如:"北京, CN",方便直观地展示地理位置。
            """
            geoLoc = city + ', ' + country
        else:
            """
            如果城市名称为空,说明可能没有对应具体城市的信息,那么地理位置信息字符串就只使用国家的ISO代码来表示,
            例如:"CN"。
            """
            geoLoc = country
        return geoLoc
    except Exception as e:
        """
        如果在查询地理位置信息过程中出现任何异常(比如IP地址不存在于数据库中、数据库读取错误等情况),
        则返回'Unregistered'表示该IP地址对应的地理位置未注册(无法获取到相关信息)。
        """
        return 'Unregistered'
# 定义一个函数,用于读取给定的PCAP文件(网络数据包捕获文件)中的数据包信息,并进行相关处理和打印
def printPcap(pcap):
    for (ts, buf) in pcap:
        try:
            """
            使用dpkt库解析以太网数据包。dpkt.ethernet.Ethernet类用于将二进制的数据包缓冲区(buf)解析为以太网数据包对象(eth)。
            """
            eth = dpkt.ethernet.Ethernet(buf)
            # 判断数据包是否为IP数据包,通过比较数据包的类型字段(type)与dpkt.ethernet.ETH_TYPE_IP常量来确定。
            # 如果数据包类型不是IP数据包,则跳过当前数据包,继续处理下一个数据包,因为后续代码主要是针对IP数据包进行处理的。
            if not eth.type == dpkt.ethernet.ETH_TYPE_IP:
                continue  # Skip non-IP packets
            ip = eth.data
            # 将源IP地址从网络字节序转换为点分十进制表示形式,方便打印和查看。
            src = socket.inet_ntoa(ip.src)
            # 将目的IP地址从网络字节序转换为点分十进制表示形式。
            dst = socket.inet_ntoa(ip.dst)
            print('[+] Src:' + src + '--> Dst:' + dst)
            print('[+] Src:' + retGeoStr(src) + '--> Dst:' + retGeoStr(dst))
        except Exception as e:
            """
            如果在解析数据包或者获取地理位置信息等操作过程中出现错误(比如数据包格式不正确、无法查询到地理位置等情况),
            则打印出具体的错误信息,方便排查问题,然后继续处理下一个数据包。
            """
            print(f"Error processing packet: {e}")
def main():
    """
    主函数,用于解析命令行参数,打开指定的PCAP文件,并调用printPcap函数来处理文件中的数据包信息。
    """
    # 创建一个ArgumentParser对象,用于解析命令行参数,并设置相应的描述信息,这里描述了程序的主要功能是处理PCAP文件并打印IP地理位置信息。
    parser = argparse.ArgumentParser(description='Process PCAP file and print IP geolocation.')
    # 添加一个命令行参数选项'-p',指定其目标属性名称为'pcapFile',参数类型为字符串,用于指定PCAP文件名,并添加相应的帮助信息。
    parser.add_argument('-p', dest='pcapFile', type=str, help='specify pcap filename')
    # 解析命令行参数,返回解析后的命名空间对象,其中包含了通过命令行传入的参数值等信息。
    options = parser.parse_args()
    if options.pcapFile is None:
        """
        如果没有通过命令行指定PCAP文件(即'pcapFile'属性为None),则打印出命令行参数帮助信息,提示用户如何正确使用程序,然后退出程序。
        """
        parser.print_help()
        exit(0)
    # 获取通过命令行指定的PCAP文件名。
    pcapFile = options.pcapFile
    try:
        # 以二进制只读模式打开指定的PCAP文件,使用 'with' 语句可以确保文件在使用完后自动关闭,避免资源泄漏。
        with open(pcapFile, 'rb') as f:
            # 使用dpkt.pcap.Reader创建一个PCAP文件读取器对象,用于按顺序读取PCAP文件中的数据包。
            pcap = dpkt.pcap.Reader(f)
            printPcap(pcap)
    except FileNotFoundError:
        """
        如果指定的PCAP文件不存在,打印出相应的错误信息,告知用户文件不存在,然后以错误码1退出程序,表示程序执行出现错误。
        """
        print(f"Error: The file '{pcapFile}' does not exist.")
        exit(1)
    except dpkt.dpkt.NeedData:
        """
        如果打开的文件不符合PCAP文件格式要求,或者文件已损坏等导致dpkt库在读取时提示需要更多数据(dpkt.dpkt.NeedData异常),
        则打印出相应的错误信息,告知用户文件可能存在问题,然后以错误码1退出程序。
        """
        print(f"Error: The file '{pcapFile}' is not a valid pcap file or is corrupted.")
        exit(1)
if __name__ == '__main__':
    main()

运行命令:

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luky!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值