这是我在 pcap 教程的帮助下获得的代码片段。我使用预构建的 pcap 文件(扩展名 .pcap)来解析和打印地址。我正在尝试打印 mac 地址、ip 地址、tcp 端口。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pcap.h> //library for parsing pcap files
/ethernet headers are always 14 bytes
//IP flags
#define IP_RSRV_FLG 0x8000 // IP's reserved fragment flag
#define IP_DNT_FRAG 0x4000 // flag for not fragmenting
#define IP_MRE_FRAG 0x2000 // Flag for more fragmenting
#define IP_MASK 0x1fff //mask for fragmenting.
//TCP flags
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
/***************************************
*
* Structs to represent headers
*
***************************************/
struct ethernet_h{
u_char ether_dest_host[ETHER_ADDR_LEN]; //the destination host address
u_char ether_src_host[ETHER_ADDR_LEN]; //the source host address
u_short ether_type; //to check if its ip etc
};
struct ip_h{
unsigned char ip_vhl; //assuming its ipv4 and header length more than 2
unsigned char service; //type of service
unsigned short total_len; //total length
unsigned short identification; // identification
u_short ip_off; //offset field
u_char ttl; // time to live value
u_char ip_protocol; // the protocol
u_short sum; //the checksum
unsigned long ip_src;
unsigned long ip_dst;
#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip) (((ip)->ip_vhl) >> 4)
};
struct tcp_h{
u_short src_port; /* source port */
u_short dst_port; /* destination port */
};
int main(int argc, char * argv[]){
pcap_t *pcap;
char errbuf [PCAP_ERRBUF_SIZE];
const unsigned char *packet;
struct pcap_pkthdr header;
int i;
/*Header Structs*/
const struct ethernet_h *ethernet;
const struct ip_h *ip;
const struct tcp_h *tcp;
/* check if the correct number of parameters are passed */
if ( argc != 2 )
{
printf("\n\t\t Incorrect number of arguments provided");
printf("\n\t\t Command format <<packet_headers.c>> <<capture1.pcap>>");
}
/*check if the correct file for trace is passed */
/*if ( ! (strcmp(argv[1],"capture1.pcap")) )
{
printf("\n\t\t Please provide the correct pcap trace file. ");
exit(2);
}*/
/*opening trace file*/
if ((pcap = pcap_open_offline(argv[1],errbuf)) == NULL){
fprintf(stderr, "cant read file %s : %s\n",
argv[0],errbuf);
exit(1);
}
/* reading packets */
for (i = 0; (packet = pcap_next(pcap,&header)) != NULL; i++){
printf("-------- Packet %d ------------\n",i);
printf(" Size: %d bytes",header.len);
/*ethernet map */
ethernet = (struct ethernet_h*) (packet);
printf("\n MAC src: %s", ethernet->ether_src_host);
printf("\n MAC dest: %s", ethernet->ether_dest_host);
ip = (struct ip_h*) (packet + sizeof(struct ethernet_h));
printf("\n IP src: %lu", ip->ip_src);
printf("\n IP dest: %lu",ip->ip_dst);
tcp = (struct tcp_h*) (packet + sizeof(struct ethernet_h) + sizeof(struct ip_h));
printf("\n Src port ; %d", ntohs(tcp->src_port));
printf("\n Dst port ; %d", ntohs(tcp->dst_port));
printf("\n");
}
}
但这并没有给出正确的输出。我知道类型转换/转换值存在一些问题,但无法解决问题。我得到了 IP 地址的垃圾值,以及 tcp 端口的错误编号。请让我知道出了什么问题。