xmcxguo 发表于 2013-06-24 15:34

菜鸟求解救 不同网卡间数据包转发

想实现的功能就是两块网卡之间数据包的互相转发 比如eth0收到的包通过eth1发出去 而eth1收到的包则通过eth0发出去但是实际用ping包测试的时候发现经常会丢包
我是个小菜鸟 求大神解救。。。

源码如下:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <sys/ioctl.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <string.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h> //xin hao xiang tou wen jian
#define MAX 4096

char buf_eth0;
volatile int num0,lenth0;
char buf_eth1;
volatile int num1,lenth1;
sem_t sem0,sem1;

void *recv_eth0(void)
{
int sock_recv0,recv0,bind0,ret;
struct ifreq ifr0;
struct sockaddr_ll ether0;
               /*Creat sock*/
sock_recv0 = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sock_recv0 < 0)
{
printf("Creat eth0 receive socket error\n");
}
else
{
printf("eth0 receive socket created\n");
}
               /*bind sock*/
bzero(&ether0,sizeof(ether0));
strcpy(ifr0.ifr_name,"eth0");
ether0.sll_family = PF_PACKET;
ioctl(sock_recv0,SIOCGIFINDEX,&ifr0);
ether0.sll_ifindex = ifr0.ifr_ifindex;
ether0.sll_protocol = htons(ETH_P_ALL);
bind0 = bind(sock_recv0,(struct sockaddr_ll*)&ether0,sizeof(struct sockaddr_ll));
if(bind0 < 0)
        {
         printf("Bind recv socket failed\n");
printf("%d\n",bind0);
}
else
{
printf("Bind recv sock to eth0 success\n");
      }
ret =0;
while(1)
{
if((MAX-ret) <100)
{
ret = 0;       

}
recv0 = recv(sock_recv0,&buf_eth0,MAX-ret,0);
lenth0 = ret;
num0 = recv0;
ret = ret + recv0;
sem_post(&sem0);
}

return (void*)0;
}

void *send_eth0(void)
{
int sock_send0,send0,bind0,sem;
struct ifreq ifr0;
struct sockaddr_ll ether0;
                  /*Creat sock*/
sock_send0 = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sock_send0 < 0)
{
printf("Creat eth0 send socket error!\n");
}
else
{
printf("eth0 send socket created\n");
}

                  /*Bind sock*/
bzero(&ifr0,sizeof(ifr0));
bzero(&ether0,sizeof(ether0));
strcpy(ifr0.ifr_name,"eth0");
ether0.sll_family = PF_PACKET;
ioctl(sock_send0,SIOCGIFINDEX,&ifr0);
ether0.sll_ifindex = ifr0.ifr_ifindex;
ether0.sll_protocol = htons(ETH_P_ALL);
bind0 = bind(sock_send0,(struct sockaddr_ll*)&ether0,sizeof(struct sockaddr_ll));
if(bind0 < 0)
       {
printf("Bind send socket failed\n");
printf("%d\n",bind0);
}
else
{
printf("Bind send sock to eth0 success\n");
}


while(1)
{

sem_wait(&sem1);

send0 = send(sock_send0,&buf_eth1,num1,0);

}

return (void*)0;
}



void *recv_eth1(void)
{
int sock_recv1,recv1,bind0,ret;
struct ifreq ifr1;
struct sockaddr_ll ether1;
               /*Creat sock*/
sock_recv1 = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sock_recv1 < 0)
{
printf("Creat eth1 receive socket error\n");
}
else
{
printf("eth1 receive socket created\n");
}
               /*bind sock*/
bzero(&ether1,sizeof(ether1));
strcpy(ifr1.ifr_name,"eth1");
ether1.sll_family = PF_PACKET;
ioctl(sock_recv1,SIOCGIFINDEX,&ifr1);
ether1.sll_ifindex = ifr1.ifr_ifindex;
ether1.sll_protocol = htons(ETH_P_ALL);
bind0 = bind(sock_recv1,(struct sockaddr_ll*)&ether1,sizeof(struct sockaddr_ll));
if(bind0 < 0)
        {
         printf("Bind recv socket failed\n");
printf("%d\n",bind0);
}
else
{
printf("Bind recv sock to eth1 success\n");
      }
ret =0;
while(1)
{
if((MAX-ret) <100)
{
ret = 0;       

}
recv1 = recv(sock_recv1,&buf_eth1,MAX-ret,0);
lenth1 = ret;
num1 = recv1;
ret = ret + recv1;
sem_post(&sem1);
}


return (void*)0;
}

void *send_eth1(void)
{
int sock_send1,send1,bind0,sem;
struct ifreq ifr1;
struct sockaddr_ll ether1;
                  /*Creat sock*/
sock_send1 = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sock_send1 < 0)
{
printf("Creat eth1 send socket error!\n");
}
else
{
printf("eth1 send socket created\n");
}

                  /*Bind sock*/
bzero(&ifr1,sizeof(ifr1));
bzero(&ether1,sizeof(ether1));
strcpy(ifr1.ifr_name,"eth1");
ether1.sll_family = PF_PACKET;
ioctl(sock_send1,SIOCGIFINDEX,&ifr1);
ether1.sll_ifindex = ifr1.ifr_ifindex;
ether1.sll_protocol = htons(ETH_P_ALL);
bind0 = bind(sock_send1,(struct sockaddr_ll*)&ether1,sizeof(struct sockaddr_ll));
if(bind0 < 0)
       {
printf("Bind send socket failed\n");
printf("%d\n",bind0);
}
else
{
printf("Bind send sock to eth1 success\n");
}


while(1)
{
sem_wait(&sem0);

send1 = send(sock_send1,&buf_eth0,num0,0);

}

return (void*)0;
}






int main()
{
pthread_t thd0,thd1,thd2,thd3;
int ret;
ret = sem_init(&sem0,0,0);
ret = sem_init(&sem1,0,0);

ret= pthread_create(&thd0,NULL,(void*)recv_eth0,NULL);
if(ret)
{
printf("Creat pthread_eth0 error\n");
exit(0);
}
ret= pthread_create(&thd1,NULL,(void*)send_eth0,NULL);
if(ret)
{
printf("Creat pthread_eth0 error\n");
exit(0);
}
ret= pthread_create(&thd2,NULL,(void*)recv_eth1,NULL);
if(ret)
{
printf("Creat pthread_eth0 error\n");
exit(0);
}
ret= pthread_create(&thd3,NULL,(void*)send_eth1,NULL);
if(ret)
{
printf("Creat pthread_eth0 error\n");
exit(0);
}
while(1);

return 0;
}

卖萌犯法 发表于 2013-06-26 10:49

main函数中的:while(1); 是什么意思?

你是想 while(1) sleep(1);?

xmcxguo 发表于 2013-06-27 10:23

回复 2# 卖萌犯法


    我不是得保持主程序一直运行么?要是主程序退出了线程还能继续存在么?

卖萌犯法 发表于 2013-06-27 10:40

是应当一直运行,但是while(1); 会把CPU资源用尽,如果不 sleep 的话。

xmcxguo 发表于 2013-06-27 13:35

回复 4# 卖萌犯法

你的意思是 如果我这里用了while(1) CPU就会一直被主程序占用 而不运行线程程序么
   

卖萌犯法 发表于 2013-06-27 14:43

会运行其他线程,这个要看系统调度机制
while(1)所在线程会竞争CPU控制权,大部分时间是它在执行,但它却什么都不做
这肯定不是你想要的效果吧

xmcxguo 发表于 2013-06-27 16:15

回复 6# 卖萌犯法

恩 有道理 那我应该怎么做?用pthread_join()么?
   

卖萌犯法 发表于 2013-06-27 20:36

pthread_join()也可以,while(1) sleep(1)也可以,反正最后退出都是因为Ctrl + C 的信号处理
页: [1]
查看完整版本: 菜鸟求解救 不同网卡间数据包转发