这是一个代码片段,我在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端口的错误号码。请告诉我什么是错的。
答案 0 :(得分:1)
printf(“From:%s \ n”,inet_ntoa(ip-&gt; ip_src)); //网络到ascii printf(“To:%s \ n”,inet_ntoa(ip-&gt; ip_dst));
答案 1 :(得分:0)
我想我明白了。我正在使用你的代码来实际学习libpcap。您必须将ip-&gt; ip_src,dst和mac src,dst传递给inet_ntoa()函数,该函数将ip,mac地址转换为可读字符串。您必须将结构中的ip和mac地址的类型更改为struct in_addr。
struct in_addr ip_src,ip_dst;
和
struct in_addr ether_dest_host, ether_src_host;
打印出来只需用%s调用printf。
printf("\n IP SRC : %s", inet_ntoa(ip->ip_src));