/*net data packet transmit tools
* liujx
* 2007-4-1*/#include#include#include#include#include#include#include#include#include#include#defineIN_ETH "eth1"char*dev_a,*dev_b;
pcap_t*pt_a,*pt_b;
pthread_t pid_a, pid_b;
libnet_t*net_a,*net_b;staticcharerrbuf[256];voidsigproc(intsig );void*dev_a_capture(void*);voiddev_a_handle( u_char*devId,conststructpcap_pkthdr*h,constu_char*p );void*dev_b_capture(void*);voiddev_b_handle( u_char*devId,conststructpcap_pkthdr*h,constu_char*p );intmain(intargc,char*argv[] )
{/*regise signal ctrl+c stop capture*/signal( SIGINT, sigproc ) ;/*init libnet*/net_a=libnet_init( LIBNET_LINK,"eth2", errbuf );if( net_a==NULL )
{
fprintf(stderr,"libnet_init fail:%s", errbuf );return;
}
net_b=libnet_init( LIBNET_LINK,"eth1", errbuf );if( net_a==NULL )
{
fprintf(stderr,"libnet_init fail:%s", errbuf );return;
}/*create thread*/intstatus;
printf("create a");
status=pthread_create(&pid_a, NULL, dev_a_capture, NULL );if( status!=0)
{
printf("pthread_create( A ) faile.");gotoend;
}
printf("create b");
status=pthread_create(&pid_b, NULL, dev_b_capture, NULL );if( status!=0)
{
printf("pthread_create( B ) faile.");gotoend;
}
pthread_join( pid_a, NULL );
pthread_join( pid_b, NULL );
end:
pcap_close( pt_a );
pcap_close( pt_b );return0;
}/*single processing function*/voidsigproc(intsig )
{
pthread_cancel( pid_a );
pthread_cancel( pid_b );
pcap_close( pt_a );
pcap_close( pt_b );
libnet_destroy( net_a );
libnet_destroy( net_b );
printf("exit transmit.");
exit(0);
}/*receive eth1's packet and transmit to eth2*/void*dev_a_capture(void*arg)
{
dev_a=pcap_lookupdev( errbuf );if( dev_a==NULL)
{
printf("pcap_lookupdev: %s", errbuf );
exit(0);
}
printf("get dev: '%s'", dev_a );
pt_a=pcap_open_live( dev_a,8000,1,500, errbuf );if( pt_a==NULL )
{
printf("pcap_open_live:%s", errbuf );
exit(0);
}for(;;)
{intret;
ret=pcap_dispatch( pt_a,0, dev_a_handle, NULL);if( ret==-1)
{
pcap_perror( pt_a,"pcap_dispatch err:");
}
}
}voiddev_a_handle( u_char*devId,conststructpcap_pkthdr*hdr,constu_char*packet )
{//printf("%s,capture size :%d ",devId, hdr->caplen );structether_header ehdr;
memcpy(&ehdr, packet,sizeof(structether_header ));/*labpcap can capture all packet ,include self send packet.
* only transmit distination address is 221(eth2 MAC last bytes) or broadcast address,
* 221 is eth2 link host's MAC.*/if( ehdr.ether_shost[ETH_ALEN-1]==221)
{return;
}if( ehdr.ether_dhost[ETH_ALEN-1]==221||ehdr.ether_dhost[ETH_ALEN-1]==255)
{
printf("A src:%d, dst:%d", ehdr.ether_shost[ETH_ALEN-1], ehdr.ether_dhost[ETH_ALEN-1] );intc;
c=libnet_write_link( net_a, (u_char*)packet, hdr->caplen );//printf("A write: %d ", c );}
}/*receive eth2's packet and transmit to eth1.*/void*dev_b_capture(void*arg)
{//dev_b = pcap_lookupdev( errbuf );dev_b="eth2";
pt_b=pcap_open_live( dev_b,8000,1,500, errbuf );if( pt_b==NULL )
{
printf("pcap_open_live:%s", errbuf );
exit(0);
}for(;;)
{intret;
ret=pcap_dispatch( pt_b,0, dev_b_handle, NULL);if( ret==-1)
{
pcap_perror( pt_b,"pcap_dispatch err:");
}
}
}voiddev_b_handle( u_char*devId,conststructpcap_pkthdr*hdr,constu_char*packet )
{//printf("%s,capture size :%d ",devId, hdr->caplen );u_int8_t eth_a[ETH_ALEN];
u_int8_t eth_b[ETH_ALEN];structether_header ehdr;
memcpy(&ehdr, packet,sizeof(structether_header ));/*Only transmit source address is 221(eth2 MAC last bytes)*/if( ehdr.ether_shost[ETH_ALEN-1]==221)
{
printf("B src:%d, dst:%d", ehdr.ether_shost[ETH_ALEN-1], ehdr.ether_dhost[ETH_ALEN-1] );intc;
c=libnet_write_link( net_b, (u_char*)packet, hdr->caplen );//printf("B write: %d ", c );}
}