我是靠谱客的博主 踏实耳机,最近开发中收集的这篇文章主要介绍c语言解析pcap文件,打印出每个数据包的五元组信息并输出到txt。,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

使用C语言,解析pcap文件,要求能够打印出每个数据包的五元组信息,并将五元组信息写入文件5_tuple.txt中。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<netinet/in.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;
char tempSrcIp[256];//存储转化后的字符地址。
char tempDstIp[256];
//pacp文件头结构体
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; /* length of portion present */
    bpf_u_int32 len;    /* length this packet (off wire) */
};

//IP数据报头 20字节
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/UDP数据
typedef struct TCPUDPHeader_t
{
    u_int16_t SrcPort;     // 源端口号16bit
    u_int16_t DstPort;    // 目的端口号16bit
   
}TCPUDPHeader_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 *ptk_header = NULL;//设置将要读取的pcap包的包头
    IPHeader_t *ip_header = NULL;
    TCPUDPHeader_t *tcpudp_header = NULL;
    Quintet_t *quintet = NULL;
    //初始化,分配内存
    ptk_header  = (struct pcap_pkthdr *)malloc(256);
    ip_header = (IPHeader_t *)malloc(sizeof(IPHeader_t));
    tcpudp_header = (TCPUDPHeader_t *)malloc(sizeof(TCPUDPHeader_t));
    quintet = (Quintet_t *)malloc(sizeof(Quintet_t));
    //memset(buf, 0, sizeof(buf));

	FILE* pFile = fopen( "data.pcap", "r");
    if( pFile == 0)
    {
        printf( "打开pcap文件失败");
        return 0;
    }

    FILE *output = fopen("./5_tuple.txt","w+");
    if( output == 0)
    {
    	printf( "打开txt文件失败");
        return 0;
    }

    //开始读数据包------------
    long int pkt_offset;	//用来文件偏移
    pkt_offset = 24;       //pcap文件头结构 24个字节
    int i = 0;
	fprintf(output,"index    sip               dip           sport     dport      protocoln");
    while(1) //遍历数据包,结构:pcap文件头24B,数据包头16B(包括caplen),数据包内容中包括数据帧头14B,IP数据报头20B(源地址和目的地址),UDP/TCP数据包内容。
    {
        i++;
		fseek(pFile, pkt_offset, SEEK_SET);//移动pfile文件指针位置,跳过pcap文件头
		//对要存储的变量地址的内容进行初始化。
        memset(ptk_header, 0, sizeof(struct pcap_pkthdr));
        memset(quintet,0,sizeof(struct Quintet));	
        //读pcap数据包头结构,16个字节
        if(fread(ptk_header, 16, 1, pFile) != 1) 
        {
            printf("%d: can not read ptk_headern", i);
            break;
        }
        pkt_offset += 16 + ptk_header->caplen;   //下一个数据包的开始位置为此数据包的起始位置+数据包头(16B)+数据长度caplen
		printf("caplen:%dn",ptk_header->caplen);
        //数据帧头 14字为ethnet协议大小,跳过。
        fseek(pFile,14, SEEK_CUR);
        //IP数据报头 20字节
        memset(ip_header, 0, sizeof(IPHeader_t));
        if(fread(ip_header, sizeof(IPHeader_t), 1, pFile) != 1)
        {
            printf("%d: can not read ip_headern", i);
            break;
        }
        quintet->SrcIP = ip_header->SrcIP;
        quintet->DstIP = ip_header->DstIP;
        quintet->Protocol = ip_header->Protocol;
		
        memset(tcpudp_header,0,sizeof(TCPUDPHeader_t));
		//TCP/UDP头 20字节,端口字段是一样的
        if(fread(tcpudp_header, sizeof(TCPUDPHeader_t), 1, pFile) != 1)
            {
                printf("%d: can not read tcpudp_headern", i);
                break;
            }
        quintet->SrcPort = tcpudp_header->SrcPort;
        quintet->DstPort = tcpudp_header->DstPort;
		//将数值转化为ip地址
		//printf("???%dn",&ip_header->SrcIP);
		inet_ntop(AF_INET,&(ip_header->SrcIP),tempSrcIp,sizeof(tempSrcIp));
        inet_ntop(AF_INET, &(ip_header->DstIP),tempDstIp,sizeof(tempDstIp));

		//将数值转换为端口号
      quintet->SrcPort = ntohs(quintet->SrcPort);
      quintet->DstPort = ntohs(quintet->DstPort);
	  //输出到txt文件
	fprintf(output,"%d    %s     %s      %d     %d      %dn",i,tempSrcIp,tempDstIp,quintet->SrcPort,quintet->DstPort,quintet->Protocol);

    } 
    fclose(pFile);
    fclose(output);
    return 0;
}

最后

以上就是踏实耳机为你收集整理的c语言解析pcap文件,打印出每个数据包的五元组信息并输出到txt。的全部内容,希望文章能够帮你解决c语言解析pcap文件,打印出每个数据包的五元组信息并输出到txt。所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部