Error connexion with Ethernet NIC card using winpcap

Error connexion with Ethernet NIC card using winpcap - C++ - Programmation

Marsh Posté le 16-05-2011 à 17:24:27    

Hello,
 
i'am developping an application with Visual C++ 2010 on windows 7, i want to sent packets and receive the same packets using winpcap libraries. i'am working with the same computer and i want to sent to and receive from my Ethernet NIC card.
 
the function pcap_sendpacket() returns success, that means the packet is sent!! ok.
 
the receiver is also working succesfully, but the problem that it does not capture the packet that i send to NIC card.
 
i tried to use Wireshark to capture this packet but it informes me that there are no packet in the NIC card.
 
i think this is because the status of the NIC card which is disconnected.
i thought that sending and receiving from NIC card in the same computer doesn't need to use a serial communication with wires.
 
so how can i solve this problem. can some one help me please :(

Reply

Marsh Posté le 16-05-2011 à 17:24:27   

Reply

Marsh Posté le 16-05-2011 à 17:43:47    

why bother trying to use a network card when all you seem to need is the loopback address ? If you want a "real" network test, you'll have to use separate machines anyways.


Message édité par theshockwave le 16-05-2011 à 17:44:02

---------------
last.fm
Reply

Marsh Posté le 16-05-2011 à 18:34:57    

yes i want to have a real network test but i thought i can do it with the same application (transmission.h and reception.h and main.cpp that calls the functions of these two files)
 
i saw an exemple of application like that. that's why i'm trying to do the same thing. and i'am using the same computer because i need to calculate the latency between transmission and reception so i want to have the opportunity to use the clock tick counter of the CPU as the common time reference.  
 
my frame is with special stucture and headers.  
so what you think? are you sure that i can't do it with the same computer?

Reply

Marsh Posté le 17-05-2011 à 11:58:30    

using this testing protocol, you can't even be sure that the interface you are using itself won't skip the send, thus, hiding the latency.
 
And sincerely, I'm wondering what the point might be in checking the latency of your API calls ... Because this is the only thing you are trying to test here, using an unconnected networking device.


---------------
last.fm
Reply

Marsh Posté le 17-05-2011 à 15:09:04    

i'am doing that for my project graduation in my studies. so i have to check performance of sending packets with this protocol test.  
i used pcap_sendpacket() and that works the way i explained to you earlier.
i'am now trying to use pcap_sendqueue_queue() for sending queue packet but i have a problem:
with this function packets are read from a capture file and after they are put in the queue for transmission.  
but in my case i don't want to have a capture file ,i want to send packets that i build (by hand with functions). so have you an idea?

Reply

Marsh Posté le 17-05-2011 à 15:57:55    

You are only at the second step apparently:
To use winpcap's packet queue you'll have to invoke:
- pcap_sendqueue_alloc - to alloc a queue for raw packets;
- pcap_sendqueue_queue - to add raw packets to the queue (plus a header in pcap format);
- pcap_sendqueue_transmit - to send the queue.
- pcap_sendqueue_destroy - later, to free the queue.
 
So was the queue allocated with a sufficient size to hold all your packets before sending them?
(else, at some point, pcap_sendqueue_queue will return with -1)
if you get pcap_sendqueue_transmit(..., squeue, ...) < squeue->len this means that some packet in the queue were not sent.
 
with pcap_sendqueue_queue (pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
pkt_data is your raw packet, but did you craft a winpcap pkt_header (second argument) for it? you shoud have caplen=len=your raw packet size in it, and whichever timestamp that suits your transmission.
 
A+,


Message édité par gilou le 17-05-2011 à 16:15:28

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 17-05-2011 à 19:42:02    

i use this code to send a queue packet:
 
unsigned char *Frame;
unsigned char *InterfaceName;
pcap_t *HandleInterface;
    char errbuf[PCAP_ERRBUF_SIZE];
    int sync=1;
 unsigned int QueueLength; // this is caplen
    u_int res;
    pcap_send_queue *squeue;
 struct pcap_pkthdr *pktheader=0;  // i had an error indicates that pktheader must be initialized  
    float cpu_time;
    u_int npacks = 0;
 QueueLength=100;        // i set it as 100 bytes (my maximum raw packet size is 50
 
 
    /* Open the output adapter */
    if ( (HandleInterface= pcap_open(Device->name, 1500, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL)
    {
        fprintf(stderr,"\nUnable to open adapter %s.\n", InterfaceName);
    }
 else {cout<<"adapter opened"<<endl;}
 
    /* Allocate a send queue */
    if (!(squeue = pcap_sendqueue_alloc(QueueLength)))
 {
  cout<<"Error Allocation send queue"<<endl;}
 
   
        if (pcap_sendqueue_queue(squeue, pktheader, Frame) == -1)
        {
            printf("Warning: packet buffer too small, not all the packets will be sent.\n" );  
        }
 
    /* Transmit the queue */
     
    cpu_time = (float)clock ();
 
    if ((res = pcap_sendqueue_transmit(HandleInterface, squeue, sync)) < squeue->len)
    {
        printf("An error occurred sending the packets: %s. Only %d bytes were sent\n", pcap_geterr(HandleInterface), res);
    }
     
    cpu_time = (clock() - cpu_time)/CLK_TCK;
     
    printf ("\n\nElapsed time: %5.3f\n", cpu_time);
    printf ("\nTotal packets generated = %d", npacks);
    printf ("\nAverage packets per second = %d", (int)((double)npacks/cpu_time));
    printf ("\n" );
 
    /* free the send queue */
    pcap_sendqueue_destroy(squeue);
 
    pcap_close(HandleInterface);
 
    return 0;
}
 

Reply

Marsh Posté le 17-05-2011 à 19:57:10    

my functions for building the packet and choosing the interface works successfully.
but when i try to send one packet with this code, the debug window stopped after printing "adapter opened" so i think the problem is with the function: pcap_sendqueue_queue(squeue, pktheader, Frame) but i don't understand exactly what is this problem?
 
i don't know how to craft a winpcap pkt_header :(


Message édité par sloumanaw le 17-05-2011 à 19:59:20
Reply

Marsh Posté le 17-05-2011 à 20:14:34    

In the other hand ,i try also to send with pcap_sendpacket() and i have the problem that i explained in my first message. for receiving i use pcap_next_ex().
so have you an idea about the solution Gilou?

Reply

Marsh Posté le 17-05-2011 à 21:09:23    

Citation :

struct pcap_pkthdr *pktheader=0;  // i had an error indicates that pktheader must be initialized  


The pcap_sendqueue_queue(squeue, pktheader, Frame) wont work if you don't create a correct pktheader.

Citation :

i don't know how to craft a winpcap pkt_header

:heink: It is just a struct with 3 fields!

Code :
  1. struct pcap_pkthdr {
  2.      struct timeval ts;  //  ts.tv_sec and ts.tv_usec
  3.      bpf_u_int32 caplen;
  4.      bpf_u_int32 len;   
  5. };


 You have to allocate the structure and  fill in the fields.
I already said that:

Citation :

you shoud have caplen=len=your raw packet size in it, and whichever timestamp that suits your transmission.


pcap_sendqueue_queue(squeue, pktheader, pktdata) return -1 if it fails (usually, because the queue size is too small)
A+,


Message édité par gilou le 17-05-2011 à 21:18:16

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 17-05-2011 à 21:09:23   

Reply

Marsh Posté le 17-05-2011 à 21:56:22    

thanks gilou. i did like this:
 
struct pcap_pkthdr {
         struct timeval ts;  
         bpf_u_int32 caplen;
         bpf_u_int32 len;    
    };
 
 struct pcap_pkthdr *pkt_header;
 pkt_header->ts.tv_usec=1000;
 pkt_header->caplen=FrameSize;
 pkt_header->len=FrameSize;
 
but i had this error:  
error C2664: 'pcap_sendqueue_queue' : impossible de convertir le paramètre 2 de 'const RawPacket::SendQueuePacket::pcap_pkthdr *' en 'const pcap_pkthdr *'
 
i changed the struct to const struct but always the same error.

Reply

Marsh Posté le 17-05-2011 à 23:02:46    

i think this error occurs because im devolopping in C++ langage. im using this struct  in the function "SendQueuPacket" which is in the class "RawPacket".
so how can i solve this problem i have no idea.do some have a solution?

Reply

Marsh Posté le 18-05-2011 à 02:37:54    

sloumanaw a écrit :

thanks gilou. i did like this:
 
struct pcap_pkthdr {
         struct timeval ts;  
         bpf_u_int32 caplen;
         bpf_u_int32 len;    
    };
..................

Why would you do this?
Why aren't you including <pcap.h> in your code?  :ouch:  
If you use a library, it seems logical to use its include files.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-05-2011 à 11:21:38    

yesss  looooll, i included "pcap.h" and i added the struct to my code too, so this error occurs.now it is fixed :)
but when i try to debug,it fails because the program stopped with  "pkt_header" is not initialized!!!
 
i tried to do like that:
 struct pcap_pkthdr *pkt_header;
 pkt_header->ts.tv_usec=1000;
 pkt_header->caplen=FrameSize;
 pkt_header->len=FrameSize;
 
 
 

Message cité 1 fois
Message édité par sloumanaw le 18-05-2011 à 11:23:50
Reply

Marsh Posté le 18-05-2011 à 12:04:23    

sloumanaw a écrit :

yesss  looooll, i included "pcap.h" and i added the struct to my code too, so this error occurs.now it is fixed :)
but when i try to debug,it fails because the program stopped with  "pkt_header" is not initialized!!!
 
i tried to do like that:
 struct pcap_pkthdr *pkt_header;
 pkt_header->ts.tv_usec=1000;
 pkt_header->caplen=FrameSize;
 pkt_header->len=FrameSize;
 
 
 

:heink: pkt_header is not pointing to an allocated structure! If you declare a pointer, you must make it points to something that has been allocated.
pkt_header = (struct pcap_pkthdr *) malloc(sizeof(struct pcap_pkthdr));  
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 19-05-2011 à 00:01:17    

thanks!!! that problem is fixed :)
but still have the problem of the NIC interface that i indicated in my first message. i'am looking for a solution, for the moment i can't find one

Reply

Marsh Posté le 20-05-2011 à 00:13:28    

Citation :



 
un pilote the capture pour windows
 ( capture driver to be associated with the NIC )
  :o  
 
Edit:
real card are not meant to be used with the same machine
, you need to use loopback , you should install it ( a new device )
 
 :hello:


Message édité par __tomjost le 20-05-2011 à 09:50:39
Reply

Marsh Posté le 24-05-2011 à 22:20:57    

hello tomjost, have you a link or the full name of the driver needed?

Reply

Marsh Posté le 24-05-2011 à 22:23:50    

winpcap has two .dll: packet.dll and wpcap.dll ,i think those are responsable for capturing and sending messages to NIC interface.so they do the work of a driver.no?

Reply

Marsh Posté le 24-05-2011 à 22:25:10    

i still have the same problem,i can't receive packets that i send,i think they dropped before reaching NIC interface :(

Reply

Marsh Posté le 24-05-2011 à 23:21:54    

Did you read this? http://wiki.wireshark.org/CaptureSetup/Loopback
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 26-05-2011 à 13:03:39    

i used wireshark, but even wireshark does not receive my packet!!  
i used pcap_sendpacket and after i tried pcap_sendqueue. they return success and it prints "frame sent" but still the same problem i can't receive this frame with my receiver or with wireshark.
i'am working with two computer now.
i tested the connexion between two cards of computers with ping,it works succesfully. so i can't understand where is my problem?
 the frame is reelly sent and dropped before reaching Ethernet card? or it is not send? or what? :(

Reply

Marsh Posté le 26-05-2011 à 16:44:45    

Can't you read the link i gave?

Citation :

If you are trying to capture traffic from a machine to itself, that traffic will not be sent over a real network interface, even if it's being sent to an address on one of the machine's network adapters. This means that you will not see it if you are trying to capture on, for example, the interface device for the adapter to which the destination address is assigned. You will only see it if you capture on the "loopback interface", if there is such an interface and it is possible to capture on it; see the next section for information on the platforms on which you can capture on the "loopback interface".


You need to
1) uninstall winpcap
2) download and install the loopback device
3) reinstall winpcap
and it may now capture packets (there are known bugs nevertheless), provided that the IP in use is not 127.0.0.1
 
Or doesn't it work also (your code) when you try it with two different computers?
A+,


Message édité par gilou le 26-05-2011 à 16:46:58

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-05-2011 à 16:20:40    

1)i uninstalled winpcap
2)i read about "Loopback capture setup", and i installed manually the Microsoft Loopback adapter in Windows XP.  
3)i reinstalled winpcap.
 
i sent one packet to the loopback adapter and i configured my receiver to receive from it.
but nothing is received from the loopback adapter.
i opened wireshark and selected the loopback adapter to capture from it but it prints "no packet".
i tried this in the same computer windows XP.
 
ps: i have two computers:  
1) windows XP and with two Ethernet Cards.
2) windows 7 with one Ethernet Card.
 
so before thinking about the loopback device, i worked with the computer 1,i tried to send ans receive packets between two Ethernet Devices.
and i worked with two computers i send from one to the other using a cross wire.

Reply

Marsh Posté le 27-05-2011 à 16:45:37    

Citation :

windows XP and with two Ethernet Cards.

I would use it with one Ethernet Card first in order to have the minimum of causes for failure. Once it works in that setting, I would try with the two cards configuration. Note, if you remove one card, you will probably need to uninstall/reinstall Winpcap.

 

If it was me, I would try:
1) sending from machine 1 with one Ethernet Cards to machine 2 (this is the most basic situation) [send from machine 1 and capture on machine 2]
When it works
2) sending from machine 1 with one Ethernet Card to itself
When it works
3) sending from machine 1 with two Ethernet Cards to itself

 

If step 1 does not work correctly, it means that something is wrong with your code.
By the way, when you send from a machine to itself, I assume that the sending code and the receiving code are in two distincts threads (or two distinct executables), else, I doubt that it may work. Did you do that?.

 

A+,


Message édité par gilou le 27-05-2011 à 16:46:00

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-05-2011 à 00:52:40    

yes i tried the first step, i sent from machine 1 and capture on machine 2.but this doen't work!!
i have two distinct executables one for transmission and one for reception.i didn't used threads yet.
 
i think that my code is correct because the frame is built correctly and i print it and i check headers before sending.
so i think that there is a problem with winpcap functions or with a parameter in these functions!!
because the receiver work corectly,it can receive other frames but it doesn't receive frames that i sent from my transmitter application so there are two suppositions:
 
1) winpcap functions are correct but the frame can't reach the ethernet card. because after sending frame to Ethernet card A, i started wireshark and i tried to capture from this card A but wireshark prints "no packets". so the frame didn't even reach the device.
2) winpcap functions are not correct and the frame is sent in a wrong way. i will search about the "PCAP_OPENFLAG_PROMISCUOUS" if it is the correct parameter or i have to change it
 
so? what do you think?

Reply

Marsh Posté le 28-05-2011 à 01:33:29    

I think that this line is suspect

Citation :

pcap_open(Device->name, 1500, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf)


Maybe the device name is not the one expected by winpcap.
Did you get the device name using the pcap_findalldevs_ex function?
Here is some sample code for this:

Code :
  1. #include <pcap.h>
  2. int _tmain(int argc, _TCHAR* argv[])
  3. {
  4.     pcap_if_t * allAdapters;
  5.     pcap_if_t * adapter;
  6.     char errorBuffer[ PCAP_ERRBUF_SIZE ];
  7.     // retrieve the adapters from the computer
  8.     if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL,
  9.                 &allAdapters, errorBuffer ) == -1 )
  10.     {
  11.         fprintf( stderr, "Error in pcap_findalldevs_ex function: %s\n",
  12.                  errorBuffer );
  13.         return -1;
  14.     }
  15.     // if there are no adapters, print an error
  16.     if( allAdapters == NULL )
  17.     {
  18.         printf( "\nNo adapters found! Make sure WinPcap is installed.\n" );
  19.         return 0;
  20.     }
  21.     // print the list of adapters along with basic information about an adapter
  22.     int crtAdapter = 0;
  23.     for( adapter = allAdapters; adapter != NULL; adapter = adapter->next)
  24.     {
  25.         printf( "\n%d.%s ", ++crtAdapter, adapter->name );
  26.         printf( "-- %s\n", adapter->description );
  27.     }
  28.     printf( "\n" );
  29.     // free the adapter list
  30.     pcap_freealldevs( allAdapters );
  31.     system( "PAUSE" );
  32.     return 0;
  33. }


 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-05-2011 à 02:02:50    

You may also read this article: How to craft UDP packets and send them with WinPCap
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-05-2011 à 15:20:30    

yes i read this article and i used the same fonctions to send my packets. i used "pcap_findalldevs_ex()".
 
i really can't understand what's the problem exactly!!  
 
i read that winpcap send every type of data,means it doen't matter if the packet is Ethernet data or not,winpcap sends what ever the user wants him to send.
 
i don't know why my packet drops before reaching NIC card :(  

Reply

Marsh Posté le 29-05-2011 à 22:25:09    

have you another idea to inject a packet in NIC card? i can use any solution even without winpcap.
 
i don't have much time i have to give my work to my teacher as soon as possible!!! :(

Reply

Marsh Posté le 29-05-2011 à 23:29:29    

Compile an test the code of this article: How to craft UDP packets and send them with WinPCap
If it works (between machine 1 and 2), this means that something is wrong with your code.
If it does not works, this means that something is wrong with your computers settings or network settings (and that your code may be fine).
I can't say more as I know only a part of your code and I don't know much about your machines.
 
A+,


Message édité par gilou le 29-05-2011 à 23:33:29

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 30-05-2011 à 12:35:59    

hello gilou,
 
 
i solved the problem of the transmitter :)
 
now i send my packet and i capture it with wireshark in the same NIC card. but there is another problem that my receiver capture only frames coming from other networks that have Ethernet structure.
 
the structure or my frame is special, but i think winpcap can send and capture any frame without looking to its structure,unless the user set some filters.
 
so i think that i have a problem with my receiver code now!!
 
 
i discarded all filters in the reception, my receiver code now is :
 
 
/* Retrieve the device list */
    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);
 
        //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):\n",i);
    scanf("%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++);
 
  pcap_handle=pcap_open_live(d->name,20480,1,0,errbuf);
 
 
  printf("\nlistening on %s...\n", d->description);
   
    /* At this point, we don't need any more the device list. Free it */
    pcap_freealldevs(alldevs);
 
 
   while((resR = pcap_next_ex( pcap_handle, &paquet_header, &Paquet))>=0)
        {
            if(resR == 0)
           //* Timeout elapsed
             continue;
 
 
        //* convert the timestamp to readable format
        local_tv_secR = paquet_header->ts.tv_sec;
        localtime_s(&ltimeR, &local_tv_secR);
        strftime( timestrR, sizeof timestrR, "%H:%M:%S", &ltimeR);
       
       
        //* print timestamp and length of the packet
        printf("%s     %.6d     len:%d\n", timestrR, paquet_header->ts.tv_usec, paquet_header->len);
        MAClayer.Reception_Paquet(argument,paquet_header,Paquet);  
     }
   
    if(resR == -1)
    {
        printf("Error reading the packets: %s\n", pcap_geterr(pcap_handle));
        return -1;
    }
 
  pcap_close(pcap_handle);
  return 0;
}
 
i have to implement a code that can be able to receive any frame what ever its structure. so have you a suggestion please
 
 
 
 
 
 
 
 
 
 

Reply

Marsh Posté le 30-05-2011 à 14:11:05    

I don't understand. Are you trying to send a non-ethernet frame through an ethernet card? :heink:
I think that Winpcap works only with frames that are encapsulated within ethernet packets.
If you use something other than ethernet with your NIC, like NetBios or other, you must have a network card driver for it and winpcap must know how to communicate with such a driver (which is doubtful)
A+,


Message édité par gilou le 30-05-2011 à 14:20:33

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 30-05-2011 à 15:04:17    

hi that works!!
 
winpcap send and capture any kind of frame.
thank you so much gilou for your time and your help. i have another work to do now.
i'll be back in case of new complications!! :)  
have a nice day!!

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed