使用pcap库打印数据包详细信息

时间:2013-09-07 20:30:21

标签: c networking

这是一个代码片段,我在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端口的错误号码。请告诉我什么是错的。

2 个答案:

答案 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));