Part One: PCAP File Format
I. Basic Format:
File Header | Packet Header | Datagram | Packet Header | DatagramâŠ
II. File Header:
File header structure
struct pcap_file_header
{
DWORD magic;
DWORD version_major;
DWORD version_minor;
DWORD thiszone;
DWORD sigfigs;
DWORD snaplen;
DWORD linktype;
}
Description:
1. Magic Number: a 32-bit value, this has the value hex a1b2c3d4.
2. Major Version Number: a 16-bit value, default is 0x2.
3. Minor Version Number: a 16-bit value, default is 0x04.
4. Time Zone: a 32-bit field not actually used, so it can be set to 0.
5. Timestamp Accuracy: a 32-bit field not actually used, so it can be set to 0.
6. Maximum Packet Length: a 32-bit field indicating the maximum length of captured packets. Set to 65535 to capture all packets, or set to 64 to capture the first 64 bytes.
7. Link Layer Type: a 32-bit field determining the type of link-layer header in the packets in the capture file.
Below is a table of data values and their corresponding link-layer types:
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
III. Packet Data Header:
struct pcap_pkthdr
{
struct tim ts;
DWORD caplen;
DWORD len;
}
struct tim
{
DWORD GMTtime;
DWORD microTime
}
Explanation:
1. Timestamp:
A UNIX-format time-in-seconds value when the packet was captured, the number of seconds since January 1, 1970, 00:00:00 GMT;
The number of microseconds since that second when the packet was captured;
2. Packet Length: a 32-bit value indicating the number of bytes of captured packet data;
3. Actual Packet Length: the real length of the captured packet, which might be greater than the previous number if not saving the entire packet.
IV. Packet Data:
This is the actual content of the Packet (usually the link layer data frame). The length is Caplen, and itâs followed by the next Packet in the current PCAP file. The file contains no defined gap strings or starting points for captured packets, which must be determined from the first Packet. The format here aligns with standard network protocol formats found in any network textbook.
V. Example Analysis
In the diagram, the initial green section is the 24-byte Pcap Header, followed by the 16-byte red section for the first messageâs Pcap Header. Similarly, the second message has its 16-byte red Pcap Header. The two blue sections depict the complete content of two messages starting from the link layer. Actual network packets on the data link layer start with 7 synch bytes, one start byte, and end with four CRC bytes, which are excluded in PCAP files since theyâre irrelevant for protocol analysis.
Using Wireshark to open a PCAP packet reveals all fields of each message, categorized and collapsed by protocol layer. The first layer shows FrameXXX, summarizing essential information and describing protocol relations. Further layers represent corresponding protocol fields, as shown below:
Part Two: PCAP File Analysis
Xplico is a tool for extracting IP traffic data from PCAP files, capable of parsing each email (POP, IMAP, SMTP protocols), all HTTP content, VoIP calls (SIP), etc.
2. C Language Implementation of PCAP File Analysis
Implementation Steps:
1) Use Wireshark to capture data in test.pcap file
2) Program: Analyze PCAP file header -> Analyze PCAP pkt header -> Analyze frame header -> Analyze IP header -> Analyze TCP header -> Analyze HTTP information
#include
#include
#include
#include<netinet/in.h>
#include
#define BUFSIZE 10240
#define STRSIZE 1024
typedef long bpf_int32;
typedef unsigned long bpf_u_int32;
typedef unsigned short u_short;
typedef unsigned long u_int32;
typedef unsigned short u_int16;
typedef unsigned char u_int8;
//PCAP file header structure
struct pcap_file_header
{
bpf_u_int32 magic; /* 0xa1b2c3d4 */
u_short version_major; /* major Version 2 */
u_short version_minor; /* minor Version 4 */
bpf_int32 thiszone; /* GMT to local correction */
bpf_u_int32 sigfigs; /* accuracy of timestamps */
bpf_u_int32 snaplen; /* max length of saved portion of each pkt */
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
};
//Timestamp
struct time_val
{
long tv_sec; /* seconds, same as time_t object value */
long tv_usec; /* microseconds */
};
//PCAP packet header structure
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) */
};
//Data frame header
typedef struct FramHeader_t
{ //Captured data frame header
u_int8 DstMAC[6]; //Destination MAC address
u_int8 SrcMAC[6]; //Source MAC address
u_short FrameType; //Frame type
} FramHeader_t;
//IP datagram header
typedef struct IPHeader_t
{ //IP datagram header
u_int8 Ver_HLen; //Version + header length
u_int8 TOS; //Type of service
u_int16 TotalLen; //Total length
u_int16 ID; //Identification
u_int16 Flag_Segment; //Flags + fragment offset
u_int8 TTL; //Time to live
u_int8 Protocol; //Protocol type
u_int16 Checksum; //Header checksum
u_int32 SrcIP; //Source IP address
u_int32 DstIP; //Destination IP address
} IPHeader_t;
//TCP datagram header
typedef struct TCPHeader_t
{ //TCP datagram header
u_int16 SrcPort; //Source port
u_int16 DstPort; //Destination port
u_int32 SeqNO; //Sequence number
u_int32 AckNO; //Acknowledgment number
u_int8 HeaderLen; //Header length (4 bits) + Reserved (4 bits)
u_int8 Flags; //Flags indicating different TCP control messages
u_int16 Window; //Window size
u_int16 Checksum; //Checksum
u_int16 UrgentPointer; //Urgent pointer
} TCPHeader_t;
//
void match_http(FILE *fp, char *head_str, char *tail_str, char *buf, int total_len); //Function to find HTTP information
//
int main()
{
struct pcap_file_header *file_header;
struct pcap_pkthdr *ptk_header;
IPHeader_t *ip_header;
TCPHeader_t *tcp_header;
FILE *fp, *output;
int pkt_offset, i=0;
int ip_len, http_len, ip_proto;
int src_port, dst_port, tcp_flags;
char buf[BUFSIZE], my_time[STRSIZE];
char src_ip[STRSIZE], dst_ip[STRSIZE];
char host[STRSIZE], uri[BUFSIZE];
//Initialization
file_header = (struct pcap_file_header *)malloc(sizeof(struct pcap_file_header));
ptk_header = (struct pcap_pkthdr *)malloc(sizeof(struct pcap_pkthdr));
ip_header = (IPHeader_t *)malloc(sizeof(IPHeader_t));
tcp_header = (TCPHeader_t *)malloc(sizeof(TCPHeader_t));
memset(buf, 0, sizeof(buf));
//
if((fp = fopen(âtest.pcapâ,ârâ)) == NULL)
{
printf(âerror: cannot open pcap file\nâ);
exit(0);
}
if((output = fopen(âoutput.txtâ,âw+â)) == NULL)
{
printf(âerror: cannot open output file\nâ);
exit(0);
}
//Start reading packets
pkt_offset = 24; //PCAP file header is 24 bytes
while(fseek(fp, pkt_offset, SEEK_SET) == 0) //Iterate packets
{
i++;
//PCAP packet header 16 bytes
if(fread(ptk_header, 16, 1, fp) != 1) //Read PCAP packet header
{
printf(â\nread end of pcap file\nâ);
break;
}
pkt_offset += 16 + ptk_header->caplen; //Offset for next packet
strftime(my_time, sizeof(my_time), â%Y-%m-%d %Tâ, localtime(&(ptk_header->ts.tv_sec))); //Get time
// printf(â%d: %s\nâ, i, my_time);
//Data frame header 14 bytes
fseek(fp, 14, SEEK_CUR); //Skip data frame header
//IP datagram header 20 bytes
if(fread(ip_header, sizeof(IPHeader_t), 1, fp) != 1)
{
printf(â%d: cannot read ip_header\nâ, i);
break;
}
inet_ntop(AF_INET, (void *)&(ip_header->SrcIP), src_ip, 16);
inet_ntop(AF_INET, (void *)&(ip_header->DstIP), dst_ip, 16);
ip_proto = ip_header->Protocol;
ip_len = ip_header->TotalLen; //Total length of IP datagram
// printf(â%d: src=%s\nâ, i, src_ip);
if(ip_proto != 0x06) //Check if TCP protocol
{
continue;
}
//TCP header 20 bytes
if(fread(tcp_header, sizeof(TCPHeader_t), 1, fp) != 1)
{
printf(â%d: cannot read ip_header\nâ, i);
break;
}
src_port = ntohs(tcp_header->SrcPort);
dst_port = ntohs(tcp_header->DstPort);
tcp_flags = tcp_header->Flags;
// printf(â%d: src=%x\nâ, i, tcp_flags);
if(tcp_flags == 0x18) // (PSH, ACK) after successful 3-way handshake
{
if(dst_port == 80) // HTTP GET request
{
http_len = ip_len â 40; //HTTP message length
match_http(fp, âHost: â, â\r\nâ, host, http_len); //Find host value
match_http(fp, âGET â, âHTTPâ, uri, http_len); //Find uri value
sprintf(buf, â%d: %s src=%s:%d dst=%s:%d %s%s\r\nâ, i, my_time, src_ip, src_port, dst_ip, dst_port, host, uri);
//printf(â%sâ, buf);
if(fwrite(buf, strlen(buf), 1, output) != 1)
{
printf(âoutput file cannot writeâ);
break;
}
}
}
} // end while
fclose(fp);
fclose(output);
return 0;
}
//Find HTTP Information
void match_http(FILE *fp, char *head_str, char *tail_str, char *buf, int total_len)
{
int i;
int http_offset;
int head_len, tail_len, val_len;
char head_tmp[STRSIZE], tail_tmp[STRSIZE];
//Initialize
memset(head_tmp, 0, sizeof(head_tmp));
memset(tail_tmp, 0, sizeof(tail_tmp));
head_len = strlen(head_str);
tail_len = strlen(tail_str);
//Find head_str
http_offset = ftell(fp); //Record HTTP message initial file offset
while((head_tmp[0] = fgetc(fp)) != EOF) //Byte-by-byte traversal
{
if((ftell(fp) â http_offset) > total_len) //Traversal complete
{
sprintf(buf, âcannot find %s \r\nâ, head_str);
exit(0);
}
if(head_tmp[0] == *head_str) //Match first character
{
for(i=1; i<head_len; i++) //Match other characters of head_str
{
head_tmp[i]=fgetc(fp);
if(head_tmp[i] != *(head_str+i))
break;
}
if(i == head_len) //Matching head_str successfully, stop traversal
break;
}
}
// printf(âhead_tmp=%s \nâ, head_tmp);
//Find tail_str
val_len = 0;
while((tail_tmp[0] = fgetc(fp)) != EOF) //Traversal
{
if((ftell(fp) â http_offset) > total_len) //Traversal complete
{
sprintf(buf, âcannot find %s \r\nâ, tail_str);
exit(0);
}
buf[val_len++] = tail_tmp[0]; //Store value in buf until finding tail_str
if(tail_tmp[0] == *tail_str) //Match first character
{
for(i=1; i<tail_len; i++) //Match other characters of tail_str
{
tail_tmp[i]=fgetc(fp);
if(tail_tmp[i] != *(tail_str+i))
break;
}
if(i == tail_len) //Matching tail_str successfully, stop traversal
{
buf[val_len-1] = 0; //Remove one surplus character
break;
}
}
}
// printf(âval=%s\nâ, buf);
fseek(fp, http_offset, SEEK_SET); //Reset file pointer to initial offset
}
Published by Full-Stack Programmer, please indicate the source: https://javaforall.cn/168390.html Original link: https://javaforall.cn