当前位置:  技术问答>linux和unix

关于网卡转发问题的程序

    来源: 互联网  发布时间:2016-05-08

    本文导语:        我要利用linux内核里的Netfilter框架实现网卡转发,就是数据从一个网口eth1进,从另一网口eth2发出去,是自己写,不用网桥实现。       首先,我将两个网卡设为混沌模式(使用指令 ifconfig  eth1/eth2  prom...

      我要利用linux内核里的Netfilter框架实现网卡转发,就是数据从一个网口eth1进,从另一网口eth2发出去,是自己写,不用网桥实现。
      首先,我将两个网卡设为混沌模式(使用指令 ifconfig  eth1/eth2  promics后, 运行ifconfig这条指令,eth1/eth2 有promisc这个属性,不知道这算不算设置起,如何测试),然后运行了两个自己写的转发模块。连接eth2网口的主机ping 另一台间接与eth1连接的主机,arp请求转发出去eth2->eth1,但arp应答包到达eth1口(不知道eth1是否接收),没有转发到eth2。我的转发程序如下:

//转发arp包
#ifndef MODULE
#define MODULE
#endif
#ifndef __KERNEL__
#define __KERNEL__
#endif

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

static unsigned int watch_arp(unsigned int hooknum,
struct sk_buff **skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct sk_buff *sb = *skb;
struct sk_buff *sb_new = NULL;
unsigned int  result=NF_STOLEN;         
unsigned long long t1, t2;
int n=1;

__asm__ volatile ("rdtsc":"=A"(t1));

switch (sb->dev->type) 
{
case ARPHRD_PPP:                                               
return result;
case ARPHRD_LOOPBACK:
case ARPHRD_ETHER:
{
int i;
printk("phisical address isn");
for (i=0; imac.raw[i]);

            printk("protocol is %xn",ntohs (sb->protocol));


            sb_new = skb_clone(sb, GFP_ATOMIC);


     printk("this packet comes from %sn ", sb->dev->name);
            printk("this new packet comes from %sn", sb_new->dev->name);

     if (!strncmp(sb_new->dev->name, "eth0", 4))
     return NF_ACCEPT;

    else if(!strncmp(sb_new->dev->name, "eth1", 4))                                                                                                                                                                                                                                              
{
      sb_new->dev = dev_get_by_name("eth2");
printk("Now, go by %sn",sb_new->dev->name);
}
else 
{     
sb_new->dev = dev_get_by_name("eth1");
              printk("Now, go by %sn",sb_new->dev->name);
}
         break;
     }
}
sb_new->pkt_type = PACKET_OUTGOING;
printk("the priority of this packet is %dn", ntohs(sb_new->priority));
       skb_push(sb_new,ETH_HLEN);
n = dev_queue_xmit(sb_new);

if (n dev);

__asm__ volatile ("rdtsc":"=A"(t2));
printk("elapsed: %llun", t2 - t1);
return result;
}

int init_module()
{
printk("ok, starting...n");

arp_hook.hook     = watch_arp;
arp_hook.pf       = NF_ARP;
arp_hook.priority = NF_IP_PRI_FIRST;
arp_hook.hooknum  = NF_ARP_IN;

nf_register_hook(&arp_hook);

printk("ok, starting...n");

return 0;
}

void cleanup_module()
{
nf_unregister_hook(&arp_hook);
}

//转发ip包
#ifndef MODULE
#define MODULE
#endif
#ifndef __KERNEL__
#define __KERNEL__
#endif

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

struct nf_hook_ops ip_hook;
// struct nf_hook_ops arp_hook;

static unsigned int watch_ip(unsigned int hooknum,
struct sk_buff **skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct sk_buff *sb = *skb;
struct sk_buff *sb_new = NULL;
unsigned int  result=NF_STOLEN;           
unsigned long long t1, t2;
    int n=1;

__asm__ volatile ("rdtsc":"=A"(t1));

switch (sb->dev->type)
{
case ARPHRD_PPP:               
return result;
case ARPHRD_LOOPBACK:
case ARPHRD_ETHER:
{
int i;
printk("phisical address isn");
for (i=0; imac.raw[i]);
                
printk("protocol is %xn", ntohs(sb->protocol)); 

                printk("this packet comes from %sn", sb->dev->name);
              //  printk("this new packet comes from %sn", sb_new->dev->name);

                if (!strncmp(sb->dev->name, "eth0", 4))
return NF_ACCEPT;
                    
            else if (!strncmp(sb->dev->name, "eth1", 4))
{
sb_new = skb_clone(sb,GFP_ATOMIC);
sb_new->dev = dev_get_by_name("eth2");

printk("Now, go by %sn ",sb_new->dev->name);
}
else 
{
sb_new = skb_clone(sb,GFP_ATOMIC);
sb_new->dev = dev_get_by_name("eth1");
             
printk("Now, go by %sn",sb_new->dev->name);
}
break;
}
}

sb_new->pkt_type = PACKET_OUTGOING;
printk("priority of this packet is %dn ", ntohs(sb_new->priority));

    skb_push(sb_new,ETH_HLEN);
n = dev_queue_xmit(sb_new);

if (n dev);

__asm__ volatile ("rdtsc":"=A"(t2));
printk("elapsed: %llun", t2 - t1);

return result;
}


int init_module()
{
printk("ok, starting...n");
ip_hook.hook     = watch_ip;
ip_hook.pf       = PF_INET;
ip_hook.priority = NF_IP_PRI_FIRST;
ip_hook.hooknum  = NF_IP_PRE_ROUTING;

/* arp_hook.hook     = watch_arp;
arp_hook.pf       = NF_ARP;
arp_hook.priority = NF_IP_PRI_FIRST;
arp_hook.hooknum  = NF_ARP_IN;*/

nf_register_hook(&ip_hook);
/* nf_register_hook(&arp_hook);*/

printk("ok, starting...n");

return 0;
}

void cleanup_module()
{
nf_unregister_hook(&ip_hook);
/* nf_unregister_hook(&arp_hook);*/
}

我不知道dev_put是否需要用,请个位大侠帮我看看问题出在哪?


|
我看了一下你的源程序,想问一下,你返回NF_STOLEN却没看到对原来的skb做什么处理,这样内存没问题吗

|
dev_put 用的是对的, 在每一次dev_get_by_name 引用net_device 完毕后, 都需要调用 dev_put

|
看了一下, 基本思路是对的, 不过在处理ARP方面我觉得应该是有问题的, 就算ARP能成功回复, 但再以后的IP数据层可能会遇到一些问题。
建议你在转发的时候从那个口出去的,源MAC应该为这个口的MAC地址。
不知道你要实现这个功能的目的, 是透明桥?eth1 and eth2是否有IP地址?

    
 
 

您可能感兴趣的文章:

  • linux下多网卡机器中,如何通过指定网卡来接受数据? iis7站长之家
  • 双网卡转发问题
  • RedHat 9.0系统,安装双网卡,如何设置可以实现在两个网段间转发数据包?
  • linux转发数据,局域网A(eth1)的数据是如何发送到另一个网卡eth0所在的网络上的,只需要设置FORWARD的ACCEPT吗?
  • linux下如何自定义IPV4包?并把它转发到指定网卡上
  • netfilter如何实现双网卡间数据包转发
  • 走虚拟网卡内核程序和走物理网卡应用程序结合问题
  • 用程序如何判断主板上是双网卡还是单网卡呢?
  • 关于两个网卡的网卡驱动程序编写的问题?
  • 各位老大,你们是从哪些方面改进网卡驱动程序的效率,欧现在写了一个lan91c嵌入式网卡的驱动,需要帮助
  • 我的网卡在redhat7.3下不能自动驱动,但我有for linux的驱动程序,请问如何才能驱动我的网卡,我是菜菜,请详细说明,谢谢!
  • 谁会在DOS下面安装网卡驱动程序?
  • 用户程序怎样才能得到网卡的收发数据流量?
  • 网卡external loopback测试程序
  • help !关于网卡驱动程序的问题?
  • 已写好一个网卡驱动,如何编个程序测试?
  • 编一个程序,检测Linux系统下机器网卡的状态(只要检测网络线是否被拔掉?)
  • LINUX下如何调用网卡驱动程序?
  • 网卡流量监控程序 vnStat
  • 网卡驱动程序
  • 怎样在SCO UNIX中安装网卡驱动程序?
  • C程序如何区分当前有效网卡是eth0,还是eth1?
  • 大家好!要在linux下开发一个网卡设备驱动程序,是怎样的一个过程?盼请指点
  • linu下如何才能100%的证明网卡驱动程序是安好了。
  • 网卡驱动程序往外发送数据包的问题
  • 求网卡RealTek8029在Solaris8的驱动程序!!!!!!
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 无线网卡工作模式介绍以及如何设置工作模式
  • 4块网卡,如何绑定成看上去只有逻辑上的2个网卡,达到一种物理上的网卡备份效果?
  • linux/Centos下查看和修改网卡Mac地址(ifconfig命令)
  • 为什么内部网卡可以启动?另一块网卡不能自启动?
  • centos6网络配置及网卡设置相关命令及配置文件
  • 怎么配置网卡,是不是红帽linux9要装网卡驱动啊
  • 最新CentOS 7中文正式版64位下载、安装及CentOS网卡IP配置(ifconfig)(图文)
  • 我在安装netware 操作系统时, 在选择网卡型号时, 找不到我的网卡的型号, 请问怎样办?
  • SCO Unix5下如何装网卡?如何一块网卡配两个IP
  • sco unix5.0.7的网卡驱动那里有,网卡是8139
  • linux下多网卡机器中,如何通过指定网卡来接受数据?
  • 双网卡搭建网桥后,怎样确定数据包是从那个网卡进来的?(LINUX)
  • LINUX中装了三个网卡,三个网卡都是同个IP段,如何让他们不能互相访问?
  • DHCPD服务开启不了,系统提示:我要声明某个网卡(因为我有两块网卡),不知道怎么搞
  • 求redhat9 下 x5dpa-GG的网卡驱动,装好机器后认不出网卡
  • 网卡刚开机时好的,但Redhat9起来后,网卡的屁股就不闪了,需要多次挺拔网线才行
  • 如何手动调整网卡的half duplex & full duplex ?如何手动调整网卡的10/100M速度?
  • 偶的网卡不能被识别,NFORCE2集成的网卡,
  • Red hat 9.0 无法识别USB移动硬盘, 无法识别网卡和无线网卡,请问如何安装驱动?
  • 请问 如何在 solaris 下装 网卡驱动(网卡不能被识别)
  • 装了redhat2003最新版,耕升nf2的主板,能够认识网卡,可是不能激活网卡,不知为什么?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3