CAIDA数据集(pcap文件)提取IP或五元组

##pcap文件格式
pcap数据包格式
其中IP头为IPv4头(20字节)或IPv6头(40字节)
在wireshark中打开可看到16进制的数依次表示以太网帧头+IP头+TCP头(TCP协议)
示例
##CAIDA数据格式

需要注意的是,CAIDA数据集给出的报文不含以太网帧头
CAIDA数据集格式

//CAIDA数据集pcap文件不含以太网帧头
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include <stdint.h>
#include<netinet/in.h>
// #include<pcap.h>

typedef int32_t bpf_int32;
typedef u_int32_t bpf_u_int32;
typedef u_int16_t u_short;
typedef u_int32_t u_int32;
typedef u_int16_t u_int16;
typedef u_int8_t u_int8;

//pcap文件头结构体
struct pcap_file_header
{
    bpf_u_int32 magic;       /* 0xa1b2c3d4 */
    u_short version_major;   /* magjor Version 2 */
    u_short version_minor;   /* magjor Version 4 */
    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_*) */
};

//时间戳
struct time_val
{
    int tv_sec;         /* seconds 含义同 time_t 对象的值 */
    int tv_usec;        /* and microseconds */
};

//pcap数据包头结构体
struct pcap_pkthdr
{
    struct time_val ts;  /* time stamp */
    bpf_u_int32 caplen; /* 当前数据区的长度,即抓取到的数据帧长度 */
    bpf_u_int32 len;    /* 离线数据长度:网络中实际数据帧的长度,一般不大于caplen,多数情况下和Caplen数值相等*/
};

//数据帧头
typedef struct FramHeader_t
{ //Pcap捕获的数据帧头
    u_int8 DstMAC[6]; //目的MAC地址
    u_int8 SrcMAC[6]; //源MAC地址
    u_short FrameType;    //帧类型
} FramHeader_t;

//IP数据报头(ipv4)
typedef struct IPHeader_t
{ //IP数据报头
    u_int8 Ver_HLen;       //版本+报头长度
    u_int8 TOS;            //服务类型
    u_int16 TotalLen;       //总长度
    u_int16 ID; //标识
    u_int16 Flag_Segment;   //标志+片偏移
    u_int8 TTL;            //生存周期
    u_int8 Protocol;       //协议类型
    u_int16 Checksum;       //头部校验和
    u_int32 SrcIP; //源IP地址
    u_int32 DstIP; //目的IP地址
} IPHeader_t; 

//TCP数据报头
typedef struct TCPHeader_t
{ //TCP数据报头
    u_int16 SrcPort;//源端口
    u_int16 DstPort;//目的端口
    u_int32 SeqNO;//序号
    u_int32 AckNO; //确认号
    u_int8 HeaderLen; //数据报头的长度(4 bit) + 保留(4 bit)
    u_int8 Flags; //标识TCP不同的控制消息
    u_int16 Window; //窗口大小
    u_int16 Checksum; //校验和
    u_int16 UrgentPointer;  //紧急指针
}TCPHeader_t;

//UDP数据
typedef struct UDPHeader_s
{
    u_int16_t SrcPort;     // 源端口号16bit
    u_int16_t DstPort;    // 目的端口号16bit
    u_int16_t len;        // 数据包长度16bit
    u_int16_t checkSum;   // 校验和16bit
}UDPHeader_t;

typedef struct Quintet
{
	u_int32 SrcIP; //源IP地址
	u_int32 DstIP; //目的IP地址
	// u_int16_t SrcPort;     // 源端口号16bit
	// u_int16_t DstPort;    // 目的端口号16bit
	// u_int8 Protocol;       //协议类型
}Quintet_t;

int main()
{
    struct pcap_pkthdr *pkt_header = NULL;
    FramHeader_t *eth_header = NULL;
    IPHeader_t *ip_header = NULL;
    TCPHeader_t *tcp_header = NULL;
    UDPHeader_t *udp_header = NULL;
    Quintet_t *quintet = NULL;
    //char buf[BUFSIZE];

    //初始化
    pkt_header  = (struct pcap_pkthdr *)malloc(sizeof(struct pcap_pkthdr));
    eth_header = (FramHeader_t *)malloc(sizeof(FramHeader_t));
    ip_header = (IPHeader_t *)malloc(sizeof(IPHeader_t));
    tcp_header = (TCPHeader_t *)malloc(sizeof(TCPHeader_t));
    udp_header = (UDPHeader_t *)malloc(sizeof(UDPHeader_t));
    quintet = (Quintet_t *)malloc(sizeof(Quintet_t));
    //memset(buf, 0, sizeof(buf));

	FILE* pFile = fopen( "/media/longshao/1b112d00-4494-4075-a27e-d7ea7d1e97c4/data/equinix-chicago.dirA.20160121-125911.UTC.anon.pcap", "r");
    // FILE* pFile = fopen("./2.pcap","r");
    if( pFile == 0)
    {
        printf( "打开pcap文件失败\n");
        return 0;
    }

    FILE *output = fopen("/media/longshao/1b112d00-4494-4075-a27e-d7ea7d1e97c4/data/output.dat","wb");
    // FILE *output = fopen("./2.dat","wb");
    if( output == 0)
    {
    	printf( "打开dat文件失败\n");
        return 0;
    }

    //开始读数据包
    printf("开始读数据包\n");
    long int pkt_offset;	//用来文件偏移
    pkt_offset = 24;       //pcap文件头结构 24个字节
    int i = 0;
    int j =0;
    int k = 0;
    int l = 0;
    u_short ftype = 0;
    u_int8 ip_ver =0;
    while(fseek(pFile, pkt_offset, SEEK_SET) == 0) //遍历数据包
    {
        i++;
        memset(pkt_header, 0, sizeof(struct pcap_pkthdr));
        memset(quintet,0,sizeof(struct Quintet));
        //pcap_pkt_header 16 byte
        if(fread(pkt_header, 16, 1, pFile) != 1) //读pcap数据包头结构
        {
            printf("%d: can not read pkt_header\n", i);
            break;
        }

        pkt_offset += 16 + pkt_header->caplen;   //下一个数据包的偏移值
        //IP数据报头 20字节 不考虑>20字节
        memset(ip_header, 0, sizeof(IPHeader_t));
        if(fread(ip_header, sizeof(IPHeader_t), 1, pFile) != 1)
        {
            printf("%d: can not read ip_header\n", i);
            break;
        }
        /**ipv4的ip头前4位为版本号:4,ipv6的为6**/
        ip_ver = (ip_header->Ver_HLen>>4)&(0b00001111);
        if (ip_ver == 4)     //ipv4
        {
            j++;
            quintet->SrcIP = ip_header->SrcIP;
            quintet->DstIP = ip_header->DstIP;
            fwrite(quintet,8,1,output);
        }
        else if (ip_ver == 6) //ipv6
        {
            k++;
        }
        else
        {
            l++;
        }
    } // end while
    fclose(pFile);
    fclose(output);
    printf("Finish!\n");
    printf("ipv4 pkts: %d\n""ipv6 pkts: %d\n",j,k);
    printf("non-IP pkts: %d\n",l);
    return 0;
}



  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值