2

这是我在 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 端口的错误编号。请让我知道出了什么问题。

4

2 回答 2

1

printf("来自:%s\n", inet_ntoa(ip->ip_src)); // 网络到 ascii printf("To: %s\n", inet_ntoa(ip->ip_dst));

于 2014-01-20T19:34:09.820 回答
0

我想我想通了。我实际上是在使用您的代码来学习 libpcap。您必须将 ip->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));
于 2014-08-11T07:58:41.070 回答