开发环境是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);
}