Hello All,

 

I am trying to write an application using pcap in windows which acts like a
Network Layer 2 switch. This is what I am doing.

 

 



 

1.       PC A has 1 LAN card

2.       PC B has 2 LAN cards 

3.       PC C has 1 LAN card

 

I Connect PC A to PC B over LAN 1 and connect PC C and PC B over LAN 2. LAN
cards in PC B are NOT bridged. So when I send data from PC A to PC C, it
will not reach the destination.

 

Application that I wrote does the following:

 

Let's assume PC A is connected to LAN card 1 in PC B and PC C is connected
to LAN card 2 in PC B.

 

When PC A sends data intended for PC C, application running on PC B, using
PCAP api's receives the Data link layer data at the application layer
through LAN card 1 and forwards the same without modifying to PC C through
LAN card 2 using pcap api's and vice versa. I could verify that data sent by
PC A is received by LAN card 1 by observing the contents of the packet
received in the application. Api used to transmit the same packet over LAN
card 2 return success but when I ran ethereal on PC C to capture all packets
received I don't see the packet that was forwarded by PC B. I used pcap
library in PC B and ethereal in PC C in promiscuous mode.

 

Am I missing something???????

 

I have also attached the source code. Please take a look and let me know if
I missed something.

Thanks & Regards

Shakthi


E-Mail : [EMAIL PROTECTED]



 

 <skype:t.shakthi.pradeep?call> 

 

<<image001.gif>>

#include "include/pcap.h"


void PacketReceiver_A(unsigned char *, const struct pcap_pkthdr *, const 
unsigned char *);
void PacketReceiver_B(unsigned char *, const struct pcap_pkthdr *, const 
unsigned char *);
int OpenAndRegisterCallBackWithInterfaceA(struct PcapInfo *);
int OpenAndRegisterCallBackWithInterfaceB(struct PcapInfo *);
pcap_if_t *SelectInterface(pcap_if_t *,int );
void DexExit(pcap_if_t *);

struct PcapInfo
{
        pcap_if_t *alldevs;
        pcap_if_t *d;
}pcapinfoA,pcapinfoB;

pcap_t *adhandleA,*adhandleB;

void DexExit(pcap_if_t *alldevs)
{
        getch();
        /* At this point, we don't need any more the device list. Free it */
        pcap_freealldevs(alldevs);
        exit(0);
}

main()
{
        pcap_if_t *alldevs;
        pcap_if_t *d, *dA, *dB;
        int inum;
        int i=0;
        pcap_t *adhandleA,*adhandleB;
        char errbuf[PCAP_ERRBUF_SIZE];
        HANDLE InterfaceA,InterfaceB;
        int InterfaceAStatus,InterfaceBStatus;
        
        /* Retrieve the device list */
        if(pcap_findalldevs(&alldevs, errbuf) == -1)
        {
                fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
                DexExit(alldevs);
        }
        
        /* Print the list */
        for(d=alldevs; d; d=d->next)
        {
                printf("%d. %s", ++i, d->name);
                if (d->description)
                        printf(" (%s)\n\n", d->description);
                else
                        printf(" (No description available)\n");
        }
        
        if(i==0)
        {
                printf("\nNo interfaces found! Make sure WinPcap is 
installed.\n");
                DexExit(alldevs);
        }

        /* Select Interface A */
        dA = SelectInterface(alldevs,i);

        if(dA == -1)
        {
                printf("Selected Wrong Interface\n");
                DexExit(alldevs);
        }
        
        /* Select Interface B */
        dB = SelectInterface(alldevs,i);
        if(dB == -1)
        {
                printf("Selected Wrong Interface\n");
                DexExit(alldevs);
        }

        /* check if both selected interfaces are same */
        if(dA == dB)
        {
                printf("Selected Same Interface\nPlease select different 
Interfaces\n");
                DexExit(alldevs);
        }

        /* Create threadto Hadle Interface A */
    
        pcapinfoA.alldevs = alldevs;
        pcapinfoA.d = dA;

        InterfaceAStatus = CreateThread( 
        NULL,              // default security attributes
        0,                 // use default stack size  
        (void *)OpenAndRegisterCallBackWithInterfaceA,        // thread 
function 
        &pcapinfoA,             // argument to thread function 
        0,                 // use default creation flags 
        &InterfaceA);   // returns the thread identifier 

        if(InterfaceAStatus)
        {
                printf("Interface A Handler started.\n");
        }
        else
        {
                printf("Interface A Handler start failed\n");
                DexExit(alldevs);
        }

        /* Create threadto Hadle Interface A */
    
        pcapinfoB.alldevs = alldevs;
        pcapinfoB.d = dB;

        InterfaceBStatus = CreateThread( 
        NULL,              // default security attributes
        0,                 // use default stack size  
        (void *)OpenAndRegisterCallBackWithInterfaceB,        // thread 
function 
        &pcapinfoB,             // argument to thread function 
        0,                 // use default creation flags 
        &InterfaceB);   // returns the thread identifier 

        if(InterfaceAStatus)
        {
                printf("Interface B Handler started.\n");
        }
        else
        {
                printf("Interface B Handler start failed\n");
                DexExit(alldevs);
        }


        //WaitForSingleObject(InterfaceA,INFINITE);
        //WaitForSingleObject(InterfaceB,INFINITE);

        while(1) Sleep(1);
        
        return 0;
}

pcap_if_t *SelectInterface(pcap_if_t *alldevs,int numinterfaces)
{
        int inum=-1;
        pcap_if_t *d;
        /* Request to select interface */
        printf("Enter the interface number A (1-%d):",numinterfaces);
        scanf("%d", &inum);
        
        if(inum < 1 || inum > numinterfaces)
        {
                printf("\nInterface number out of range.\n");
                /* Free the device list */
                pcap_freealldevs(alldevs);
                return -1;
        }

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

        return d;
}

int OpenAndRegisterCallBackWithInterfaceA(struct PcapInfo *InterfaceInfoA)
{
        int inum;
        int i=0;
        char errbuf[PCAP_ERRBUF_SIZE];


        
        /* Open the device A*/
        /* Open the adapter A*/
        if ((adhandleA= pcap_open_live(InterfaceInfoA->d->name, // name of the 
device
                                                         65536,                 
// portion of the packet to capture. 
                                                                                
        // 65536 grants that the whole packet will be captured on all the MACs.
                                                         1,                     
        // promiscuous mode (nonzero means promiscuous)
                                                         1000,                  
// read timeout
                                                         errbuf                 
// error buffer
                                                         )) == NULL)
        {
                fprintf(stderr,"\nUnable to open the adapter. %s is not 
supported by WinPcap\n", InterfaceInfoA->d->name);
                /* Free the device list */
                pcap_freealldevs(InterfaceInfoA->alldevs);
                return -1;
        }
        
        printf("\nlistening on %s...\n\n", InterfaceInfoA->d->description);
        

        /* start the capture */
        pcap_loop(adhandleA, 0, PacketReceiver_A, NULL);
        
        pcap_close(adhandleA);
        return 0;

}


int OpenAndRegisterCallBackWithInterfaceB(struct PcapInfo *InterfaceInfoB)
{
        int inum;
        int i=0;
        char errbuf[PCAP_ERRBUF_SIZE];


        
        /* Open the device B*/
        /* Open the adapter B*/
        if ((adhandleB= pcap_open_live(InterfaceInfoB->d->name, // name of the 
device
                                                         65536,                 
// portion of the packet to capture. 
                                                                                
        // 65536 grants that the whole packet will be captured on all the MACs.
                                                         1,                     
        // promiscuous mode (nonzero means promiscuous)
                                                         1000,                  
// read timeout
                                                         errbuf                 
// error buffer
                                                         )) == NULL)
        {
                fprintf(stderr,"\nUnable to open the adapter. %s is not 
supported by WinPcap\n", InterfaceInfoB->d->name);
                /* Free the device list */
                pcap_freealldevs(InterfaceInfoB->alldevs);
                return -1;
        }
        
        printf("\nlistening on %s...\n\n", InterfaceInfoB->d->description);
        
        /* start the capture */
        pcap_loop(adhandleB, 0, PacketReceiver_B, NULL);
        
        pcap_close(adhandleB);
        return 0;

}


/* Callback function invoked by libpcap for every incoming packet on Interface 
A*/
void PacketReceiver_A(unsigned char *param, const struct pcap_pkthdr *header, 
const unsigned char *pkt_data)
{
        printf("Interface A : len:%d\n",header->len);

        /* Forward the packet on Interface B */
        if (pcap_sendpacket(adhandleB,  // Adapter
                pkt_data,                               // buffer with the 
packet
                header->len                             // size
                ) != 0)
        {
                fprintf(stderr,"\nError sending the packet to Interface B: \n", 
pcap_geterr(adhandleA));
                return 3;
        }
}

/* Callback function invoked by libpcap for every incoming packet on Interface 
A*/
void PacketReceiver_B(unsigned char *param, const struct pcap_pkthdr *header, 
const unsigned char *pkt_data)
{
        printf("Interface B : len:%d\n",header->len);

        /* Forward the packet on Interface B */
        if (pcap_sendpacket(adhandleA,  // Adapter
                pkt_data,                               // buffer with the 
packet
                header->len                             // size
                ) != 0)
        {
                fprintf(stderr,"\nError sending the packet to Interface A: \n", 
pcap_geterr(adhandleB));
                return 3;
        }
}


_______________________________________________
Wireshark-dev mailing list
Wireshark-dev@wireshark.org
http://www.wireshark.org/mailman/listinfo/wireshark-dev

Reply via email to