使用libnet, libpcap模拟一个交换机
来源:互联网 发布:linux crontab 服务 编辑:程序博客网 时间:2024/05/17 10:05
动机是我屋里有两台电脑,但到屋里只有一根外出网线,一台机子有双网卡,我就正好运用我前段学习的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, 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 );
}
}
* 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, 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 );
}
}
- 使用libnet, libpcap模拟一个交换机
- libnet libpcap libnids libicmp介绍与使用
- 何谓libnet、libpcap
- libnids libpcap libnet 安装
- 使用libnet与libpcap构造TCP/IP协议软件
- 使用libnet与libpcap构造TCP/IP协议软件
- 使用libnet与libpcap构造TCP/IP协议软件
- 使用libnet与libpcap构造TCP/IP协议软件
- 使用libnet与libpcap构造TCP/IP协议软件
- 使用libnet与libpcap构造TCP/IP协议软件
- ubuntu 安装 libpcap、libnet、libnids
- libnet使用
- Linux下libpcap+libnet的编译
- libnet入门,libpcap,libnids,libicmp~~网络开发~~~
- tcpdump libnet libpcap 介绍及编译
- libnet和pcap模拟ARP
- 三个源码包libnet、libnids、libpcap学习TCP/IP
- ubuntu下安装libnet、libpcap、libnids等环境
- The Tao of Programming
- 什么是工厂模式
- 4.2
- 什么是设计模式
- 深入了解路由器
- 使用libnet, libpcap模拟一个交换机
- Delphi第三方控件大比拼
- 交换机漏洞全面了解
- 两个梦,都是难以实现的吗?(转载)
- Linux系统上架设VSFTP服务器实例解析
- 如何应对面试的“十大必考题”?
- Linux操作系统下的多进程编程详细解析
- D-Day +14 of .NET 发现自己对.NET有点感觉了,没想到这么快就接到活了,财大后勤服务网
- JavaScript 运算符和表达式