简体   繁体   中英

printing packet details using pcap library

Here is a code snippet im having with some help from the pcap tutorials. Im using a prebuilt pcap file (extension .pcap) for parsing and printing the addresses. Im trying to print mac addresses, ip addresses, tcp ports.

#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");

}

}

BUt this isnt giving the correct output. I know there is some problem with typecasting/converting values but can't figure out the issue. i get garbage values for IP addresses, and incorrect nos for tcp ports. please let me know whats wrong.

printf("From: %s\\n", inet_ntoa(ip->ip_src)); // network to ascii printf(" To: %s\\n", inet_ntoa(ip->ip_dst));

I think I figured it out. I was using your code to learn libpcap actually. You have to pass ip->ip_src, dst and mac src, dst to the inet_ntoa() function, which converts ip, mac addresses to readable strings. You have to change the types of the ip and mac addresses in your structs to struct in_addr.

struct in_addr ip_src,ip_dst;

and

struct in_addr ether_dest_host, ether_src_host;

to print them out just call printf with %s.

printf("\n IP SRC : %s", inet_ntoa(ip->ip_src));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM