views:

335

answers:

1

I'm experimenting with WinPcap 4.1.1 libraries for Windows, but I can't manage to compile even example source provided with the library.

I'm getting these errors:

'PCAP_OPENFLAG_PROMISCUOUS' undeclared (first use in this function)
'PCAP_SRC_IF_STRING' undeclared (first use in this function)

And bunch of warnings:

implicit declaration of function 'localtime_s'
implicit declaration of function 'pcap_findalldevs_ex'
implicit declaration of function 'pcap_open'
implicit declaration of function 'scanf_s'

I Googled up a bit and found that I should add a line #define HAVE_REMOTE (I have no clue what does it do) but it leads in much more errors like this:

undefined reference to 'pcap_open'
undefined reference to 'pcap_findalldevs_ex'
undefined reference to 'localtime_s'

The "pcap.h" seems to be included properly (eclipse does not report any including errors). I have copied the *.lib files into MinGW/lib direcotry and set this path in the Path and Symbols->Library Paths (eclipse project properties)

I have no idea what to try next. Any ideas are welcome. Thanks in advance

Here's the code:

#include "pcap.h"

/* prototype of the packet handler */
void packet_handler(u_char *param, const struct pcap_pkthdr *header,
const u_char *pkt_data);

int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];

       /* Retrieve the device list on the local machine */
       if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
       {
               fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
               exit(1);
       }

       /* Print the list */
       for(d=alldevs; d; d=d->next)
       {
               printf("%d. %s", ++i, d->name);
               if (d->description)
                       printf(" (%s)\n", d->description);
               else
                       printf(" (No description available)\n");
       }

       if(i==0)
       {
               printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
               return -1;
       }

       printf("Enter the interface number (1-%d):",i);
       scanf_s("%d", &inum);

       if(inum < 1 || inum > i)
       {
               printf("\nInterface number out of range.\n");
               /* Free the device list */
               pcap_freealldevs(alldevs);
               return -1;
       }

       /* Jump to the selected adapter */
       for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);

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

       printf("\nlistening on %s...\n", d->description);

       /* At this point, we don't need any more the device list. Free it */
       pcap_freealldevs(alldevs);

       /* 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;

       /*
        * unused variables
        */
       (VOID)(param);
       (VOID)(pkt_data);

       /* 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);

       printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);

}
+1  A: 

You can replace your localtime_s call with:

localtime_r(&local_tv_sec, &ltime);

(Note the swapped arguments.)

Also, replace your scanf_s call with scanf.

localtime_s() and scanf_s() are Microsoft-specific extensions, and are not available in MinGW.

Alok
I get the same error with `localtime_r` but I used `localtime` instead this way `ltime = localtime(` and it works.
Petr Peller
Yeah, looks like `localtime_r` is not available in MinGW. If you're not concerned about thread-safety, then replacing it with an appropriate `localtime` call as you did is fine.
Alok
Also, I am assuming you changed the type of `ltime` to be a pointer.
Alok
Indeed. Thanks for help.
Petr Peller