• 自主创建tcpdump/wireshark pcap文件


     

     pcap文件格式是bpf保存原始数据包的格式,很多软件都在使用,比如tcpdump、wireshark等等,了解pcap格式可以加深对原始数据包的了解,自己也可以手工构造任意的数据包进行测试。

     
    pcap文件的格式为:
      文件头    24字节
      数据包头 + 数据包  数据包头为16字节,后面紧跟数据包
      数据包头 + 数据包  ……
     
    pcap.h里定义了文件头的格式

    [cpp] view plaincopy
     
    1. struct pcap_file_header {  
    2.         bpf_u_int32 magic;  
    3.         u_short version_major;  
    4.         u_short version_minor;  
    5.         bpf_int32 thiszone;     /* gmt to local correction */  
    6.         bpf_u_int32 sigfigs;    /* accuracy of timestamps */  
    7.         bpf_u_int32 snaplen;    /* max length saved portion of each pkt */  
    8.         bpf_u_int32 linktype;   /* data link type (LINKTYPE_*) */  
    9. };  

    看一下各字段的含义:
    magic:   4字节 pcap文件标识 目前为“d4 c3 b2 a1”
    major:   2字节 主版本号     #define PCAP_VERSION_MAJOR 2
    minor:   2字节 次版本号     #define PCAP_VERSION_MINOR 4
    thiszone:4字节 时区修正     并未使用,目前全为0
    sigfigs: 4字节 精确时间戳   并未使用,目前全为0
    snaplen: 4字节 抓包最大长度 如果要抓全,设为0x0000ffff(65535),
                   tcpdump -s 0就是设置这个参数,缺省为68字节
    linktype:4字节 链路类型    一般都是1:ethernet
    常用链路类型:
          0           BSD loopback devices, except for later OpenBSD
           1           Ethernet, and Linux loopback devices
           6           802.5 Token Ring
           7           ARCnet
           8           SLIP
           9           PPP
           10          FDDI
           100         LLC/SNAP-encapsulated ATM
           101         "raw IP", with no link
           102         BSD/OS SLIP
           103         BSD/OS PPP
           104         Cisco HDLC
           105         802.11
           108         later OpenBSD loopback devices (with the AF_value in network byte order)
           113         special Linux "cooked" capture
           114         LocalTalk

    =======================================================================================
    |    magic    |major  | minor |   thiszone  |   sigfigs   |   snaplen   |  linktype  
    | d4 c3 b2 a1 | 02 00 | 04 00 | 00 00 00 00 | 00 00 00 00 | ff ff 00 00 | 01 00 00 00
    =======================================================================================
     
     
    数据包头的格式

    [cpp] view plaincopy
     
    1. struct pcap_pkthdr {  
    2.         struct timeval ts;      /* time stamp */  
    3.         bpf_u_int32 caplen;     /* length of portion present */  
    4.         bpf_u_int32 len;        /* length this packet (off wire) */  
    5. };  
    6. struct timeval {  
    7.         long            tv_sec;         /* seconds (XXX should be time_t) */  
    8.         suseconds_t     tv_usec;        /* and microseconds */  
    9. };  

    ts:    8字节 抓包时间 4字节表示秒数,4字节表示微秒数
    caplen:4字节 保存下来的包长度(最多是snaplen,比如68字节)
    len:   4字节 数据包的真实长度,如果文件中保存的不是完整数据包,可能比caplen大

    了解了pcap文件格式,就可以自己手工构造任意数据包了,可以以录好的包为基础,

    构建pcap文件示例:

    含有两套构建方法, 因起先不知道可以通过pcap_open_dead & pcap_dump_open 构建文件头, 所以开始是自己创建一个文件并写入文件头.

    [cpp] view plaincopy
     
    1. #include <stdio.h>  
    2. #include <stdlib.h>  
    3. #include <string.h>  
    4. #include <unistd.h>  
    5. #include <stdint.h>  
    6. #include <errno.h>  
    7. #include <pcap.h>  
    8. #include "common.h"  
    9.   
    10.   
    11. #define TCPDUMP_MAGIC       0xa1b2c3d4  
    12. #ifndef PCAP_VERSION_MAJOR  
    13. #define PCAP_VERSION_MAJOR 2  
    14. #define   
    15. #define PCAP_VERSION_MINOR   
    16. #define PCAP_VERSION_MINOR 4  
    17. #endif  
    18.   
    19.   
    20. #define LINKTYPE_NULL       DLT_NULL  
    21. #define LINKTYPE_ETHERNET   DLT_EN10MB  /* also for 100Mb and up */  
    22. #define LINKTYPE_EXP_ETHERNET   DLT_EN3MB   /* 3Mb experimental Ethernet */  
    23. #define LINKTYPE_AX25       DLT_AX25  
    24. #define LINKTYPE_PRONET     DLT_PRONET  
    25. #define LINKTYPE_CHAOS      DLT_CHAOS  
    26. #define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */  
    27. #define LINKTYPE_ARCNET     DLT_ARCNET  /* BSD-style headers */  
    28. #define LINKTYPE_SLIP       DLT_SLIP  
    29. #define LINKTYPE_PPP        DLT_PPP  
    30. #define LINKTYPE_FDDI       DLT_FDDI  
    31.   
    32.   
    33. static int  
    34. pcap_write_header(FILE *fp, int linktype, int thiszone, int snaplen)  
    35. {  
    36.     struct pcap_file_header hdr;  
    37.   
    38.     hdr.magic = TCPDUMP_MAGIC;  
    39.     hdr.version_major = PCAP_VERSION_MAJOR;  
    40.     hdr.version_minor = PCAP_VERSION_MINOR;  
    41.   
    42.     hdr.thiszone = thiszone;  
    43.     hdr.snaplen = snaplen;  
    44.     hdr.sigfigs = 0;  
    45.     hdr.linktype = linktype;  
    46.   
    47.     if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)  
    48.         return (-1);  
    49.   
    50.     return (0);  
    51. }  
    52.   
    53. #define FILE_SAVE "pcap_write.pcap"  
    54.   
    55. uint8_t l2_data[] = {  
    56. 0x00, 0x0c, 0x29, 0x99, 0xfc, 0xa6, 0x00, 0x0c, 0x29, 0xd7, 0xc1, 0xf2, 0x08, 0x00, 0x45, 0x00,  
    57. 0x00, 0x46, 0x87, 0x8a, 0x00, 0x00, 0x40, 0x11, 0x6e, 0xa5, 0xc0, 0xa8, 0x01, 0x31, 0xc0, 0xa8,  
    58. 0x01, 0xf6, 0x7e, 0x75, 0x00, 0x35, 0x00, 0x32, 0x89, 0x42, 0x0a, 0x5d, 0x00, 0x00, 0x00, 0x01,  
    59. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x6e, 0x73, 0x31, 0x05, 0x67, 0x75, 0x61, 0x72, 0x64,  
    60. 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00,  
    61. 0x80, 0x00, 0x00, 0x00  
    62. };  
    63. int main(int argc, char **argv)  
    64. {  
    65.   
    66. #if 0  
    67.     FILE *fp = NULL;  
    68.     struct pcap_pkthdr h;  
    69.     fp = fopen(FILE_SAVE, "wb");  
    70.     if (!fp){  
    71.         fprintf(stderr, "fopen %s for write failed. errno=%d desc=%s ",   
    72.             FILE_SAVE, errno, strerror(errno));  
    73.         return 1;  
    74.     }  
    75.   
    76.     pcap_write_header(fp, LINKTYPE_ETHERNET, 0x0, 0x0000ffff);  
    77.     gettimeofday(&h.ts, NULL);  
    78.     h.caplen = sizeof(l2_data);  
    79.     h.len    = sizeof(l2_data);  
    80.   
    81.     pcap_dump((uint8_t *)fp, &h, l2_data);  
    82.     fflush(fp);  
    83.     fclose(fp);   
    84. #else  
    85.     pcap_t *p = NULL;     
    86.     pcap_dumper_t *fp = NULL;  
    87.     struct pcap_pkthdr h;  
    88.       
    89.     p = pcap_open_dead(LINKTYPE_ETHERNET, 0x0000ffff);  
    90.     if (NULL == p){  
    91.         fprintf(stderr, "pcap_open_dead failed. ");  
    92.         return 1;  
    93.     }  
    94.     fp = pcap_dump_open(p, FILE_SAVE);  
    95.     if (NULL == fp){  
    96.         fprintf(stderr, "pcap_dump_open failed. ");  
    97.         return 1;  
    98.     }  
    99.     gettimeofday(&h.ts, NULL);  
    100.     h.caplen = sizeof(l2_data);  
    101.     h.len    = sizeof(l2_data);  
    102.   
    103.     pcap_dump((uint8_t *)fp, &h, l2_data);    
    104.     pcap_dump_close(fp);  
    105. #endif  
    106.   
    107.     return 0;  
    108. }  

    编译 & 链接

    # gcc pcap_write.c -o pcap_write -lpcap

  • 相关阅读:
    从 datetime2 数据类型到 datetime 数据类型的转换产生一个超出范围的值
    EF增删改查操作
    将String转化成Stream,将Stream转换成String, C# Stream 和 byte[] 之间的转换(文件流的应用)
    解决远程主机关闭了连接错误(正在中止线程)
    手动爆库详细流程以及语句解析
    asp.net 中将汉字转换成拼音
    jdk1.6下使用sardine和jackrabbit-webdav的问题
    模式匹配-BF算法
    git项目创建
    main thread starting…
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/4067234.html
Copyright © 2020-2023  润新知