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
|
#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; } }
- Follow-Ups:
- Prev by Date: Re: [Wireshark-dev] File size limits on Linux and building for large file support
- Next by Date: [Wireshark-dev] [PATCH] Make PRES context identifiers conversation aware
- Previous by thread: Re: [Wireshark-dev] File size limits on Linux and building for large file support
- Next by thread: Re: [Wireshark-dev] Developing an application suing pacap in windows which simulates - Network Layer 2 Switch
- Index(es):