zoukankan      html  css  js  c++  java
  • 【wireshark】抓包和文件格式支持

    1. 抓包

    捕获从网络适配器提取包,并将其保存到硬盘上.

    访问底层网络适配器需要提升的权限,因此和底层网卡抓包的功能被封装在dumpcap中,这是Wireshark中唯一需要特权执行的程序,代码的其他部分(包括解析器,用户界面等等)只需要普通用户权限。

    为了隐藏所有底层的机器依赖性,使用了libpcap/WinPcap库.这此库提供了从多种不同的网络接口 类型(Ethernet, Token Ring,...)上捕获包的通用接口.

    2. 文件格式

    Wireshark可以读写libpcap格式的捕获文件,这是它的默认文件格式,被用于其他很多网络捕获工具, 如tcpdump.另外,Wireshark还可以读写其他网络捕获工具使用的多种不同的文件格式.wiretap库, 和Wireshark一起开发,提供了读写所有这些文件格式的通用接口.如果你需要添加其他的捕获文件格式,应从此处着手.

    pcap文件的封装格式如下图所示。magic number的值对于以主机字节序写入的文件来说是0x1a2b3c4d。

    两个重要struct见/wiretap/libpcap.h。

    /* "libpcap" file header (minus magic number). */
    struct pcap_hdr {
        unsigned short  version_major;
        unsigned short  version_minor;
        int thiszone;
        unsigned int    sigfigs;
        unsigned int    snaplen;
        unsigned int    network;
    };
    
    /* "libpcap" record header. */
    struct pcaprec_hdr {
        unsigned int    ts_sec;
        unsigned int    ts_usec;
        unsigned int    incl_len;
        unsigned int    orig_len;
    };

    3. 报文解析

    当Wireshark从文件中载入包时,会解析每一个包.Wireshark尝试探测包类型并尽可能地取得更多的包信息.然而此时,只需要显示在报文列表窗格(packet list pane)的信息.

    当用户在包列表窗格中选择特定的包时,它会被重新解析一次.此时,Wireshark尝试取得每条信息并显示在报文细节窗格(packet detail pane)中.

    Wireshark支持多种文件格式,这是由wiretap目录下代码来实现的。简单来说,在fire_access.c里有一个open_info结构体数组open_info_base,它的一部分如下:

    static struct open_info open_info_base[] = {
        { "Pcap",                        OPEN_INFO_MAGIC,     libpcap_open,             "pcap",     NULL, NULL },
        { "PcapNG",                      OPEN_INFO_MAGIC,     pcapng_open,              "pcapng",   NULL, NULL },
        { "NgSniffer",                   OPEN_INFO_MAGIC,     ngsniffer_open,           NULL,       NULL, NULL },
        { "Snoop",                       OPEN_INFO_MAGIC,     snoop_open,               NULL,       NULL, NULL },
        { "IP Trace",                    OPEN_INFO_MAGIC,     iptrace_open,             NULL,       NULL, NULL },
        { "Netmon",                      OPEN_INFO_MAGIC,     netmon_open,              NULL,       NULL, NULL },
        { "Netxray",                     OPEN_INFO_MAGIC,     netxray_open,             NULL,       NULL, NULL },
        { "Radcom",                      OPEN_INFO_MAGIC,     radcom_open,              NULL,       NULL, NULL },
        { "Nettl",                       OPEN_INFO_MAGIC,     nettl_open,               NULL,       NULL, NULL },
        { "Visual",                      OPEN_INFO_MAGIC,     visual_open,              NULL,       NULL, NULL },
        { "5 Views",                     OPEN_INFO_MAGIC,     _5views_open,             NULL,       NULL, NULL },
        { "Network Instruments",         OPEN_INFO_MAGIC,     network_instruments_open, NULL,       NULL, NULL },
        { "Peek Tagged",                 OPEN_INFO_MAGIC,     peektagged_open,          NULL,       NULL, NULL },
        { "DBS Etherwatch",              OPEN_INFO_MAGIC,     dbs_etherwatch_open,      NULL,       NULL, NULL },
        { "K12",                         OPEN_INFO_MAGIC,     k12_open,                 NULL,       NULL, NULL },
        { "Catapult DCT 2000",           OPEN_INFO_MAGIC,     catapult_dct2000_open,    NULL,       NULL, NULL },
        { "Aethra",                      OPEN_INFO_MAGIC,     aethra_open,              NULL,       NULL, NULL },
        { "BTSNOOP",                     OPEN_INFO_MAGIC,     btsnoop_open,             "log",      NULL, NULL },
        { "EYESDN",                      OPEN_INFO_MAGIC,     eyesdn_open,              NULL,       NULL, NULL },
        { "TNEF",                        OPEN_INFO_MAGIC,     tnef_open,                NULL,       NULL, NULL },
        { "MIME Files with Magic Bytes", OPEN_INFO_MAGIC,     mime_file_open,           NULL,       NULL, NULL },
        { "Lanalyzer",                   OPEN_INFO_HEURISTIC, lanalyzer_open,           "tr1",      NULL, NULL },
        ...
    };

    在file_access.c中的init_open_routines函数中,它被赋值给全局变量open_routines。

    在file_access.c中的wtap_open_offline函数中,会遍历此数组,直到其中的打开函数可以打开给定的文件。

    switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
    case -1:
        /* I/O error - give up */
        wtap_close(wth);
        return NULL;
    
    case 0:
        /* No I/O error, but not that type of file */
        break;
    
    case 1:
        /* We found the file type */
        goto success;
    }

    4. 参考

    Wireshark开发指南第6章"How wireshark works"

  • 相关阅读:
    sql2slack alash3al 开源的又个轻量级工具
    pgspider fetchq 扩展docker镜像
    godns 集成coredns 的demo
    godns 简单dnsmasq 的dns 替换方案
    aviary.sh 一个基于bash的分布式配置管理工具
    使用coredns 的template plugin实现一个xip 服务
    nginx 代理 coredns dns 服务
    基于nginx proxy dns server
    几个不错的geodns server
    spring boot rest api 最好添加servlet.context-path
  • 原文地址:https://www.cnblogs.com/zzqcn/p/4823229.html
Copyright © 2011-2022 走看看