linux 网卡数据转发,linux下自己写的网卡数据转发程序

static struct nf_hook_ops udp_comp_ops =

{

.hook = udp_hook,

.pf = PF_INET,

.hooknum = 0,

.priority =  -1,

};

先使用nf_register_hook注册一个hook函数:

nf_register_hook(&udp_comp_ops );

static unsigned intudp_hook(unsigned int hook,

struct sk_buff *pskb,

const struct net_device *in,

const struct net_device *out,

int (*okfn)(struct sk_buff *))

{

struct iphdr *iph =ip_hdr(pskb);

struct udphdr *udph =(struct udphdr *)(pskb->data+iph->ihl*4);

struct ethhdr *mach = eth_hdr(pskb);

if(iph->protocol != IPPROTO_UDP)  //只转发udp数据

return NF_ACCEPT;

int skb_alloc =0 ;

if (0==memcmp(mach->h_dest,g_local_inside.mac,ETH_ALEN))  //通过目的地址判断数据来源

{

iph->saddr =g_local_outside.addr;    //修改源ip

memcpy(mach->h_source, g_local_outside.mac, ETH_ALEN);//修改源mac地址

memcpy(mach->h_dest, g_outside_net.mac, ETH_ALEN);//修改目的mac地址

struct net_device* pDev = get_other_dev(pskb->dev);  //变换dev为另外一块网卡

if (NULL==pDev)

{

printk("<0>""recv sip,get_other_dev error\n");

return NF_ACCEPT;

}

pskb->dev = pDev;

int chg_len = 0;                ....................    //数据修改

if (chg_len > 0)

{

if(skb_tailroom(pskb) < chg_len) //如果保留数据比增加的长度小,则分配新的sk_buff

{

struct sk_buff * nskb = skb_copy_expand(pskb, skb_headroom(pskb), skb_tailroom(pskb)+64,GFP_ATOMIC);

if(!nskb)

{

printk("<0>""low memory....\n");

return NF_ACCEPT;

}

skb_alloc =1;  //设置分配标志

pskb = nskb;

iph =ip_hdr(pskb);

udph =(struct udphdr *)(pskb->data+iph->ihl*4);

}

}

//修改头部长度,重新计算校验和

iph->tot_len = htons(htons(iph->tot_len)+chg_len);

udph->len = htons(htons(udph->len)+chg_len);

udph->check = 0;

udph->check = csum_tcpudp_magic(iph->saddr,

iph->daddr,

htons(udph->len), IPPROTO_UDP,

csum_partial((char *)udph, htons(udph->len), 0));

iph->check = 0;

iph->check = ip_fast_csum((unsigned char *)iph,iph->ihl);

//修改skb->data指针,使其指向MAC头部,并且增加skb->len

skb_push(pskb , ETH_HLEN);

//直接调用该函数,将数据包从网卡上发送出去

if (0!=dev_queue_xmit(pskb))

{

printk("<0>""recv sip,trans error\n");

}

if (skb_alloc>0)             //这里关键,如果是分配的要返回NF_DROP

return NF_DROP;

else

return NF_STOLEN;

}

return NF_ACCEPT; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值