zoukankan      html  css  js  c++  java
  • linux下libpcap抓包分析

    一、首先下载libpcap包http://www.tcpdump.org/#latest-release

      然后安装,安装完成后进入安装根目录的tests文件夹,编译运行findalldevstest.c(编译时加上-lpcap),查看是否发现所有网络设备。

    二、下载wireshark观察抓包软件的各种功能

    三、熟悉libpcap工作原理:

    四、了解libpcap抓包基本流程:

    五、编程实现

    未完待续。。。 

    PS:整理了一下libpcap常用的数据类型定义

    • libpcap的类型定义:

    0)、typedef int bpf_int32

    1)、typedef u_int bpf_u_int32

        32bit 的无类型整形;

    2)、typedef pcap pcap_t

        Descriptor of an open capture instance(一个打开的捕获实例的描述符?)这个结构对用户是不透明的。

    3)、typedef pcap_dumper pcap_dumper_t

    libpcap保存文件的描述符。

    4)、typedef pcap_if pcap_if_t

    网卡链表的一个元素;

    5)、typedef pcap_addr pcap_addr_t

    网卡地址的表示;

    6)、typedef void (*pcap_handler)(u_char *args, const struct pcap_pkthdr *header,    const u_char *packet);

        其中agrs是从pcap_dispatch()函数传递过来的第四个形参 ,一般我们自己的包捕捉程序不需要提供它,总是为NULL ;header指向
    pcap_pkthdr结构,该结构位于真正的物理帧前面,用于消除不同链路层支持的差异 ;packet指向所捕获报文的物理帧。

    • libpcap结构体

    Libpcap库函数所必须的数据结构定义主要包含在pcap.h和pcap-int.h两个头文件中

    1)、pcap结构在pcap-int.h头文件中被定义:
     编程时需要涉及到的成员有:int fd; 打开设备的描述符;u_char *buffer; 是指向所捕获到数据的缓冲区指针
    struct pcap
    {
       int fd; /* 文件描述字,实际就是 socket */

        int selectable_fd; /* 在 socket 上,可以使用 select() 和 poll() 等 I/O 复用类型函数 */

        int snapshot; /* 用户期望的捕获数据包最大长度 */

        int linktype; /* 设备类型 */

        int tzoff;         /* 时区位置,实际上没有被使用 */

        int offset;       /* 边界对齐偏移量 */

        int break_loop; /* 强制从读数据包循环中跳出的标志 */

        struct pcap_sf sf; /* 数据包保存到文件的相关配置数据结构 */

        struct pcap_md md; /* 具体描述如下 */

       

        int bufsize; /* 读缓冲区的长度 */

        u_char buffer; /* 读缓冲区指针 */

        u_char *bp;

        int cc;

        u_char *pkt;

        /* 相关抽象操作的函数指针,最终指向特定操作系统的处理函数 */

        int   (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);

        int   (*setfilter_op)(pcap_t *, struct bpf_program *);

        int   (*set_datalink_op)(pcap_t *, int);

        int   (*getnonblock_op)(pcap_t *, char *);

        int   (*setnonblock_op)(pcap_t *, int, char *);

        int   (*stats_op)(pcap_t *, struct pcap_stat *);

        void (*close_op)(pcap_t *);

        /*如果 BPF 过滤代码不能在内核中执行,则将其保存并在用户空间执行 */

        struct bpf_program fcode;

        /* 函数调用出错信息缓冲区 */

        char errbuf[PCAP_ERRBUF_SIZE + 1];

       

        /* 当前设备支持的、可更改的数据链路类型的个数 */

        int dlt_count;

        /* 可更改的数据链路类型号链表,在 linux 下没有使用 */

        int *dlt_list;

        /* 数据包自定义头部,对数据包捕获时间、捕获长度、真实长度进行描述 [pcap.h] */

        struct pcap_pkthdr pcap_header;  

    };

    /* 包含了捕获句柄的接口、状态、过滤信息  [pcap-int.h] */

    struct pcap_md {

    /* 捕获状态结构  [pcap.h] */

    struct pcap_stat stat; 

        int use_bpf; /* 如果为1,则代表使用内核过滤*/

        u_long    TotPkts;

        u_long    TotAccepted; /* 被接收数据包数目 */

        u_long    TotDrops;       /* 被丢弃数据包数目 */

        long TotMissed;      /* 在过滤进行时被接口丢弃的数据包数目 */

        long OrigMissed; /*在过滤进行前被接口丢弃的数据包数目*/

    #ifdef linux

        int   sock_packet; /* 如果为 1,则代表使用 2.0 内核的 SOCK_PACKET 模式 */

        int   timeout;  /* pcap_open_live() 函数超时返回时间*/

        int   clear_promisc; /* 关闭时设置接口为非混杂模式 */

        int   cooked;          /* 使用 SOCK_DGRAM 类型 */

        int   lo_ifindex;      /* 回路设备索引号 */

        char *device;  /* 接口设备名称 */

       

    /* 以混杂模式打开 SOCK_PACKET 类型 socket 的 pcap_t 链表*/

    struct pcap *next;      

    #endif

    };

    (2)bpf_program结构
     
    该结构在pcap_compile()函数中被使用,在bpf.h头文件中定义。

    /* [pcap-bpf.h] */

    struct bpf_program {

    u_int bf_len; /* BPF 代码中谓词判断指令的数目 */

    struct bpf_insn *bf_insns; /* 第一个谓词判断指令 */

    };

       

    /* 谓词判断指令结构 */

    struct bpf_insn {

    u_short    code;

    u_char    jt;

    u_char    jf;

    bpf_int32 k;

    };

     (3)

    /usr/include/net/bpf.h

    /*
    * Structure prepended to each packet.
    */

    内核过滤器每输出一个包,将在输出的数据前加了20字节的数据,这就是 struct bpf_hdr
    struct bpf_hdr
    {
        struct timeval bh_tstamp;   /* time stamp                 */
        bpf_u_int32    bh_caplen;   /* length of captured portion数据长度*/
        bpf_u_int32    bh_datalen;  /* original length of packet 实际包长度 */
        u_short        bh_hdrlen;   /* length of bpf header (this struct
                                       plus alignment padding)    */
    };

    (4)pcap_stat结构
     调用函数 pcap_stats() 可以返回一个该结构
    struct pcap_stat {
            u_int ps_recv; /* number of packets received */
            u_int ps_drop; /* number of packets dropped */
            u_int ps_ifdrop; /* drops by interface XXX not yet supported */
    };

    5)、

    struct pcap_addr:网卡地址描述
    {
    pcap_addr *next;如果非空,指向链表中一个元素的指针;空表示链表中的最后一个元素
    sockaddr  *addr;  指向包含一个地址的sockaddr的结构的指针
    sockaddr *netmask;如果非空,指向包含相对于addr指向的地址的一个网络掩码的结构
    sockaddr *broadaddr;如果非空,指向包含相对于addr指向的地址的一个网络掩码的结构
    sockaddr *dstaddr; 如果非空,指向一个相对于addr指向的源地址的目的地址,如果网络不支持点对点通讯,则为空
    };

    6)、dump文件格式

    首先是Dump文件头

    struct pcap_file_header {
    bpf_u_int32 magic;
    u_short version_major;
    u_short version_minor;
    bpf_int32 thiszone; /* gmt to local correction */
    bpf_u_int32 sigfigs; /* accuracy of timestamps */
    bpf_u_int32 snaplen; /* max length saved portion of each pkt */
    bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */

    };

    然后是每一个包的包头和数据

    pcap_pkthdr结构
     
    /usr/include/pcap.h

    /*
    * Each packet in the dump file is prepended with this generic header.
    * This gets around the problem of different headers for different
    * packet interfaces.
    */
    /* 自定义头部在把数据包保存到文件中也被使用 */

    struct pcap_pkthdr

    {

               struct timeval ts; /* 捕获时间戳 */

               bpf_u_int32 caplen; /* 捕获到数据包的长度 */

               bpf_u_int32 len; /* 数据包的真正长度 */

    }

    /* 单个数据包结构,包含数据包元信息和数据信息 */

    struct singleton [pcap.c]

    {

    struct pcap_pkthdr hdr; /* libpcap 自定义数据包头部 */

    const u_char * pkt; /* 指向捕获到的网络数据 */

    };

    7)、pcap_if (libpcap 自定义的接口信息链表 [pcap.h])

    struct pcap_if

    {

    struct pcap_if *next;

    char *name; /* 接口设备名 */

    char *description; /* 接口描述 */

              

    /*接口的 IP 地址, 地址掩码, 广播地址,目的地址 */

    struct pcap_addr addresses;

    bpf_u_int32 flags;      /* 接口的参数 */

    };

  • 相关阅读:
    windows平台下一款强大的免费代理获取工具
    彻底搞懂Git Rebase
    line-height
    text-indent
    text-decoration
    text-align
    color
    CSS属性汇总
    font
    font-style
  • 原文地址:https://www.cnblogs.com/xumaojun/p/8533142.html
Copyright © 2011-2022 走看看