2011-11-24 1 views
1

이 프로그램은 오프라인 덤프 파일에서 패킷을 찾아 디코딩해야합니다. 여기 ntohs() 함수에 문제가 있습니다 (끝 부분에 헤더 설명이 있습니다). 왜 효과가 없습니까? OS win7 x86, VS 2010 express.ntohs() 문제

#include "pcap.h" 

#define SIZE_ETHERNET 14 
#define ETHER_ADDR_LEN 6 
/* 4 bytes IP address */ 
typedef struct ip_address{ 
    u_char byte1; 
    u_char byte2; 
    u_char byte3; 
    u_char byte4; 
}ip_address; 

/* IPv4 header */ 
typedef struct ip_header{ 
    u_char ver_ihl;  // Version (4 bits) + Internet header length (4 bits) 
    u_char tos;   // Type of service 
    u_short tlen;   // Total length 
    u_short identification; // Identification 
    u_short flags_fo;  // Flags (3 bits) + Fragment offset (13 bits) 
    u_char ttl;   // Time to live 
    u_char proto;   // Protocol 
    u_short crc;   // Header checksum 
    ip_address saddr;  // Source address 
    ip_address daddr;  // Destination address 
    u_int op_pad;   // Option + Padding 
}ip_header; 

/* UDP header*/ 
typedef struct udp_header{ 
    u_short sport;   // Source port 
    u_short dport;   // Destination port 
    u_short len;   // Datagram length 
    u_short crc;   // Checksum 
}udp_header; 


typedef struct ethernet_address{ 
    u_char byte1; 
    u_char byte2; 
    u_char byte3; 
    u_char byte4; 
    u_char byte5; 
    u_char byte6; 
}ethernet_address; 

    /* Ethernet header */ 
typedef struct ethernet_header { 
     ethernet_address ether_dhost; /* Destination host address */ 
     ethernet_address ether_shost; /* Source host address */ 
     u_short ether_type; /* IP? ARP? RARP? etc */ 
    }; 

/* TCP header */ 
typedef struct tcp_header { 
     u_short th_sport; /* source port */ 
     u_short th_dport; /* destination port */ 

     u_char th_offx2; /* data offset, rsvd */ 
    #define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) 
     u_char th_flags; 
    #define TH_FIN 0x01 
    #define TH_SYN 0x02 
    #define TH_RST 0x04 
    #define TH_PUSH 0x08 
    #define TH_ACK 0x10 
    #define TH_URG 0x20 
    #define TH_ECE 0x40 
    #define TH_CWR 0x80 
    #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) 
     u_short th_win;  /* window */ 
     u_short th_sum;  /* checksum */ 
     u_short th_urp;  /* urgent pointer */ 
}tcp_header; 

/* prototype of the packet handler */ 
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); 
/* Packet count */ 
int num = 1; 

int main(int argc, char **argv) 
{ 
pcap_t *adhandle; 
char errbuf[PCAP_ERRBUF_SIZE]; 
char source[PCAP_BUF_SIZE]; 
u_int netmask; 
char packet_filter[] = ""; 
struct bpf_program fcode; 

    if(argc != 2){ 

     printf("usage: %s filename", argv[0]); 
     return -1; 

    } 

    /* Create the source string according to the new WinPcap syntax */ 
    if (pcap_createsrcstr(source,   // variable that will keep the source string 
          PCAP_SRC_FILE, // we want to open a file 
          NULL,   // remote host 
          NULL,   // port on the remote host 
          argv[1],  // name of the file we want to open 
          errbuf   // error buffer 
          ) != 0) 
    { 
     fprintf(stderr,"\nError creating a source string\n"); 
     return -1; 
    } 

    /* Open the adapter */ 
    if ((adhandle= pcap_open(source, // name of the device 
          65536,  // portion of the packet to capture. 
             // 65536 grants that the whole packet will be captured on all the MACs. 
          PCAP_OPENFLAG_PROMISCUOUS,   // promiscuous mode 
          1000,  // read timeout 
          NULL,  // remote authentication 
          errbuf  // error buffer 
          )) == NULL) 
    { 
     fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n"); 
     return -1; 
    } 

    /* Check the link layer. We support only Ethernet for simplicity. */ 
    if(pcap_datalink(adhandle) != DLT_EN10MB) 
    { 
     fprintf(stderr,"\nThis program works only on Ethernet networks.\n"); 
     return -1; 
    } 

    /* if(d->addresses != NULL) 
     Retrieve the mask of the first address of the interface 
     netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; 
    else */ 
     /* If the interface is without addresses we suppose to be in a C class network */ 
     netmask=0xffffff; 


    //compile the filter 
    if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0) 
    { 
     fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n"); 
     return -1; 
    } 

    //set the filter 
    if (pcap_setfilter(adhandle, &fcode)<0) 
    { 
     fprintf(stderr,"\nError setting the filter.\n"); 
     return -1; 
    } 

    /* start the capture */ 
    pcap_loop(adhandle, 0, packet_handler, NULL); 

    return 0; 
} 

/* Callback function invoked by libpcap for every incoming packet */ 
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) 
{ 
    struct tm ltime; 
    char timestr[16]; 
    time_t local_tv_sec; 
    u_int ip_len; 
    u_short sport,dport; 
    ip_header *ih; 
    const struct ethernet_header *ethh; /* The ethernet header */ 


    /* 
    * Unused variable 
    */ 
    (VOID)(param); 

    printf("Packet %d\n", num); 
    num++; 

    /* convert the timestamp to readable format */ 
    local_tv_sec = header->ts.tv_sec; 
    localtime_s(&ltime, &local_tv_sec); 
    strftime(timestr, sizeof timestr, "%H:%M:%S", &ltime); 

    /* print timestamp and length of the packet */ 
// printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len); 

    /* retireve the position of the ethernet header */ 
    ethh = (struct ethernet_header*)(pkt_data); 
    /* retireve the position of the ip header */ 
    ih = (ip_header *) (pkt_data + 14); //length of ethernet header 

    /* retireve the position of the udp header */ 
    ip_len = (ih->ver_ihl & 0xf) * 4; 

    /* print ip addresses and ports */ 
    printf("Eth Src: %x:%x:%x:%x:%x:%x >>> Dest: %x:%x:%x:%x:%x:%x\nIP Src: %d.%d.%d.%d >>> Dest: %d.%d.%d.%d\n", 
     ethh->ether_shost.byte1, 
     ethh->ether_shost.byte2, 
     ethh->ether_shost.byte3, 
     ethh->ether_shost.byte4, 
     ethh->ether_shost.byte5, 
     ethh->ether_shost.byte6, 
     ethh->ether_dhost.byte1, 
     ethh->ether_dhost.byte2, 
     ethh->ether_dhost.byte3, 
     ethh->ether_dhost.byte4, 
     ethh->ether_dhost.byte5, 
     ethh->ether_dhost.byte6, 
     ih->saddr.byte1, 
     ih->saddr.byte2, 
     ih->saddr.byte3, 
     ih->saddr.byte4, 
     ih->daddr.byte1, 
     ih->daddr.byte2, 
     ih->daddr.byte3, 
     ih->daddr.byte4 
     ); 
    /* Panage protocols */ 
    if(ih->proto == 0x11) 
     { 
      udp_header *uh; 
      uh = (udp_header *) ((u_char*)ih + ip_len); 
      printf("UDP Src: %d >>> Dest: %d\n", uh->sport,uh->dport); 
     } 
    else if(ih->proto == 0x06) 
     { 
      tcp_header *tcp = NULL; 
       /* convert from network byte order to host byte order */ 
      tcp = (tcp_header *) ((u_char*)ih + ip_len); 
/*HERE*/   sport = ntohs(tcp->th_sport); 
/*HERE*/  dport = ntohs(tcp->th_dport); 
      printf("TCP Src: %d >>> Dest: %d\n", sport,dport); 
     } 
} 

오류 로그 : <arpa/inet.h> 또는 <netinet/in.h> 포함

1>------ Build started: Project: cw1, Configuration: Debug Win32 ------ 
1> cw1.c 
1>cw1.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _packet_handler 
1>C:\Users\Medardas\Desktop\ComputerScience\C.SC251 - CW1\cw1\Debug\cw1.exe : fatal error LNK1120: 1 unresolved externals 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 
+0

너는 네가 무엇을 기대하고있는 것과 다른지를 설명해 주시겠습니까? –

+0

그것은 나에게 네트웍 바이트 아웃풋을 제공한다. 나는 호스트 바이트가 필요하다. 그래서 ntohs는 필요하다.] 그러나 ok는 now – Medardas

답변

1

보십시오. 실패하면 링커 설정을 확인하십시오.

+1

im은 윈도우를 사용한다. wpcap =]을 의미하지만 어쨌든 나는 그것을 알아 냈다. 프로젝트에 winsock2 및 Ws2_32.lib를 포함하는 것을 잊었습니다. – Medardas

0

이것은 링커 오류입니다. documentation of the function을 참조하십시오. 해당 페이지의 맨 아래 (모든 페이지가 동일한 방식으로 배치되어 있음)에 필요한 헤더, lib 및 DLL에 대한 세부 정보를 찾을 수 있습니다. 이 경우 Ws2_32.lib에 링크해야합니다.