Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5761923
  • 博文数量: 675
  • 博客积分: 20301
  • 博客等级: 上将
  • 技术积分: 7671
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 16:15
文章分类

全部博文(675)

文章存档

2012年(1)

2011年(20)

2010年(14)

2009年(63)

2008年(118)

2007年(141)

2006年(318)

分类: C/C++

2007-10-21 12:21:51

这位仁兄比较有意思,将电脑做成交换机,但是太浪费了,做成路由器多好,还不影响那台双网卡的机器。

动机是我屋里有两台电脑,但到屋里只有一根外出网线,一台机子有双网卡,我就正好运用我前段学习的libpcap和libnet写了一个数据包转发的小工 具,把双网卡的机子模拟成一个交换机,使另一台机子能通过它访问外网,虽然用其它方法以能实现,但这正好是一个练习上面说的两个工具的好地方,还有以可免 除当双网卡机子不开机时,另一台机子只要直接接上外网的网线就行了,不用频繁的更改IP。

/* net data packet transmit tools
 * liujx
 * 2007-4-1
 
*/
#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<string.h>
#include 
<signal.h>
#include 
<netinet/ip.h>
#include 
<sys/time.h>
#include 
<net/ethernet.h>
#include 
<pthread.h>

#include 
<pcap.h>
#include 
<libnet.h>

#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, 80001500, 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, sizeofstruct 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, 80001500, 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, sizeofstruct 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 );
    }
}


阅读(3679) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~