pcap libnet pthread

来源:百度文库 编辑:神马文学网 时间:2024/04/30 03:09:58
/* net data packet transmit tools
* liujx
* 2007-4-1
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define IN_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;
static char errbuf[256];
void sigproc( int sig );
void* dev_a_capture( void *);
void dev_a_handle( u_char *devId, const struct pcap_pkthdr *h, const u_char *p );
void* dev_b_capture( void *);
void dev_b_handle( u_char *devId, const struct pcap_pkthdr *h, const u_char *p );
int main( int argc, 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 */
int status;
printf("create a ");
status = pthread_create( &pid_a, NULL, dev_a_capture, NULL );
if ( status != 0 )
{
printf( "pthread_create( A ) faile. ");
goto end;
}
printf("create b ");
status = pthread_create( &pid_b, NULL, dev_b_capture, NULL );
if ( status != 0 )
{
printf( "pthread_create( B ) faile. ");
goto end;
}
pthread_join( pid_a, NULL );
pthread_join( pid_b, NULL );
end:
pcap_close( pt_a );
pcap_close( pt_b );
return 0;
}
/* single processing function */
void sigproc( int sig )
{
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(;;)
{
int ret;
ret = pcap_dispatch( pt_a, 0, dev_a_handle, NULL);
if ( ret == -1 )
{
pcap_perror( pt_a, "pcap_dispatch err:");
}
}
}
void dev_a_handle( u_char *devId, const struct pcap_pkthdr *hdr, const u_char *packet )
{
//printf("%s,capture size :%d ",devId, hdr->caplen );
struct ether_header ehdr;
memcpy( &ehdr, packet, sizeof( struct ether_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] );
int c;
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(;;)
{
int ret;
ret = pcap_dispatch( pt_b, 0, dev_b_handle, NULL);
if ( ret == -1 )
{
pcap_perror( pt_b, "pcap_dispatch err:");
}
}
}
void dev_b_handle( u_char *devId, const struct pcap_pkthdr *hdr, const u_char *packet )
{
//printf("%s,capture size :%d ",devId, hdr->caplen );
u_int8_t eth_a[ETH_ALEN];
u_int8_t eth_b[ETH_ALEN];
struct ether_header ehdr;
memcpy( &ehdr, packet, sizeof( struct ether_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] );
int c;
c = libnet_write_link( net_b, (u_char*)packet, hdr->caplen );
//printf("B write: %d ", c );
}
}