【C语言】Linux平台下解析pcap文件

开发环境是readhat、ubuntu、kali

在wireshark上抓包需要使用 Wireshark/tcpdump/ 且 文件后缀名为.pcap 方式保存

效果如下:

引入俩文件如下。

my_pcap.h
#pragma once
#include <netinet/in.h>

#define PCAP_MAGIC 0xa1b2c3d4

typedef struct pcap_file_header
{
    uint32_t magic;       /* 0xa1b2c3d4 */
    uint16_t version_major;   /* magjor Version 2 */
    uint16_t version_minor;   /* magjor Version 4 */
    uint32_t thiszone;      /* gmt to local correction */
    uint32_t sigfigs;     /* accuracy of timestamps */
    uint32_t snaplen;     /* max length saved portion of each pkt */
    uint32_t linktype;    /* data link type (LINKTYPE_*) */
}* PPCAP_HEADER;
#define PCAP_FILE_HEADER_LEN sizeof(struct pcap_file_header)

typedef struct pcap_pkthdr
{
    uint32_t ts_sec;
    uint32_t ts_usec;
    uint32_t caplen; /* length of portion present */
    uint32_t len;    /* length this packet (off wire) */
}* PPCAP_PK_HEADER;
#define PCAP_PK_LEN sizeof(struct pcap_pkthdr)

typedef struct pcap_each
{
    int pcap_len;
    int pos;
    char* pcap_data;
}* PPCAP_EACH;


PPCAP_EACH create_pcap_each(char* data, int data_len);
int check_pcap(char* data,int data_len);
PPCAP_PK_HEADER get_first_pkg(PPCAP_EACH pcap_each);
PPCAP_PK_HEADER next_pkg(PPCAP_EACH pcap_each);
char* get_pkg_data(PPCAP_PK_HEADER pcap_pk_hdr, int* out_len);

my_pcap.c
#include "my_pcap.h"
#include <stdlib.h>

int check_pcap(char* data,int data_len){
    PPCAP_HEADER pcap_hdr = (PPCAP_HEADER)data; 
    if(pcap_hdr->magic == PCAP_MAGIC){
        return 1;
    }
    return 0;
}

PPCAP_EACH create_pcap_each(char* data, int data_len){
    PPCAP_EACH pe = malloc(sizeof(struct pcap_each));
    pe->pos = 0;
    pe->pcap_data = data;
    pe->pcap_len = data_len;
    return pe;
}

PPCAP_PK_HEADER get_first_pkg(PPCAP_EACH pcap_each){
    pcap_each->pos = PCAP_FILE_HEADER_LEN;
    return (PPCAP_PK_HEADER)(pcap_each->pcap_data + pcap_each->pos);
}

PPCAP_PK_HEADER next_pkg(PPCAP_EACH pcap_each){
    PPCAP_PK_HEADER now_pkg = (PPCAP_PK_HEADER)(pcap_each->pcap_data + pcap_each->pos);
    pcap_each->pos += PCAP_PK_LEN + now_pkg->caplen;
    if(pcap_each->pos >= pcap_each->pcap_len){
        return 0;
    }
    PPCAP_PK_HEADER next_pkg = (PPCAP_PK_HEADER)(pcap_each->pcap_data + pcap_each->pos);
    return next_pkg;
}

char* get_pkg_data(PPCAP_PK_HEADER pcap_pk_hdr, int* out_len){
    *out_len = pcap_pk_hdr->caplen;
    return ((char*)pcap_pk_hdr + PCAP_PK_LEN);
}

然后进行测试,测试代码如下:

int buffer_len = 0;
char* buffer = read_file("/home/kali/Desktop/pcap/your_pack.pcap", &buffer_len);
if(check_pcap(buffer, buffer_len) == 0){
	printf("file not is pcap file \n");
	return;
}
PPCAP_EACH peach = create_pcap_each(buffer, buffer_len);
PPCAP_PK_HEADER pkg = get_first_pkg(peach);
int data_len = 0;
char* data = 0;
for(;pkg != 0; pkg = next_pkg(peach)){
	data = get_pkg_data(pkg, &data_len);
	printf("data_len:%d \n", data_len);
	hexDump(data, data_len);
}
free(peach);
free(buffer);

其中的read_file方法和hexDump方法是需要自己写的。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

char* read_file(char* path,int* out_len){
    int fd = open(path, O_RDONLY);
    struct stat st;
    stat(path, &st);
    *out_len = st.st_size;
    char* buffer = (char*)malloc(st.st_size);
    read(fd, buffer, st.st_size);
    close(fd);
    return buffer;
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void hexDump(void* _buf, int len)
{
    if(len > 99999){
        printf("show len:%d >300 Byte. do not show. \n",len);
        return;
    }
    char* buf = (char*)_buf;
	if (len < 1 || buf == (void*)0) return;
	const char *hexChars = "0123456789ABCDEF";
	int i = 0;
	char c = 0x00;
	char str_print_able[17];
	char str_hex_buffer[16 * 3 + 1];
	for (i = 0; i < (len / 16) * 16; i += 16)
	{
		int j = 0;
		for (j = 0; j < 16; j++)
		{
			c = buf[i + j];
			// hex
			int z = j * 3;
			str_hex_buffer[z++] = hexChars[(c >> 4) & 0x0F];
			str_hex_buffer[z++] = hexChars[c & 0x0F];
			str_hex_buffer[z++] = (j < 10 && !((j + 1) % 8)) ? '_' : ' ';
			// string with space repalced
			if (c < 32 || c == '\0' || c == '\t' || c == '\r' || c == '\n' || c == '\b')
				str_print_able[j] = '.';
			else
				str_print_able[j] = c;
		}
		str_hex_buffer[16 * 3] = 0x00;
		str_print_able[j] = 0x00;
		printf("%04x  %s %s\n", i, str_hex_buffer, str_print_able);
	}
	int leftSize = len % 16;
	if (leftSize < 1) return;
	int j = 0;
	int pos = i;
	for (; i < len; i++)
	{
		c = buf[i];
		// hex
		int z = j * 3;
		str_hex_buffer[z++] = hexChars[(c >> 4) & 0x0F];
		str_hex_buffer[z++] = hexChars[c & 0x0F];
		str_hex_buffer[z++] = ' ';
		// string with space repalced
		if (c < 32 || c == '\0' || c == '\t' || c == '\r' || c == '\n' || c == '\b')
			str_print_able[j] = '.';
		else
			str_print_able[j] = c;
		j++;

	}
	str_hex_buffer[leftSize * 3] = 0x00;
	str_print_able[j] = 0x00;
	for (j = leftSize; j < 16; j++)
	{
		int z = j * 3;
		str_hex_buffer[z++] = ' ';
		str_hex_buffer[z++] = ' ';
		str_hex_buffer[z++] = ' ';
	}
	str_hex_buffer[16 * 3] = 0x00;
	printf("%04x  %s %s\n", pos, str_hex_buffer, str_print_able);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值