日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

linux内核丢弃udp报文,内核udp报文截取、修改和发送

發(fā)布時(shí)間:2023/12/14 linux 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux内核丢弃udp报文,内核udp报文截取、修改和发送 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

近來(lái)做一個(gè)產(chǎn)品需要在網(wǎng)關(guān)上獲取特定UDP端口(假設(shè)是1000端口)的報(bào)文,并將其轉(zhuǎn)發(fā)給其它設(shè)備的1000端口。雖然此類文章網(wǎng)上已經(jīng)有很多了,但我還是貼上來(lái),這樣自己也做下記錄,大家也多一份參考。

下面只給出了代碼片段,自己慢慢調(diào)試。

我們假設(shè)網(wǎng)絡(luò)拓?fù)淙缦滤?#xff1a;

LINUX

--------- --------- ---------

| PC-1 |-------| Server | -------| DataSrv |

--------- --------- ---------

pc-1發(fā)送udp報(bào)文到server的1000端口時(shí),我們將報(bào)文拷貝一份并發(fā)送給DataSrv的1000端口。

報(bào)文的獲取,我們采用netfilter hook. 我們將hook鉤到 NF_IP_LOCAL_IN,優(yōu)先級(jí)別設(shè)置成NF_IP_PRI_FIRST。

為什么hook到NF_IP_LOCAL_IN 而不是PERROUTING呢? 這是因?yàn)閔ook到 LOCAL_IN的話,我們就不用去考慮報(bào)文的重組了。如下圖:

ip_rcv ------> ip_local_deliver ----------> netfilter

|-----------ip_defrag-------^

為什么優(yōu)先級(jí)別設(shè)置成最高了,這樣可以防止udp的穿透。

這里我們不詳細(xì)描述netfilter hook如何編寫(xiě)。下面我們來(lái)看獲取到skb(重組好了的)的報(bào)文后,我們?nèi)绾翁幚怼?/p>

首先,我們假設(shè)DataSrv的ip地址為 192.168.1.254/24;Server的ip地址為 192.168.1.253/24。

#define TEST_XMIT(skb, rt) \

NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, (skb), NULL, \

(rt)->u.dst.dev, dst_output);

#define IP_PARTS_NATIVE(n) \

(unsigned int)((n)&0xFF), \

(unsigned int)((n)>>8)&0xFF, \

(unsigned int)((n)>>16)&0xFF, \

(unsigned int)((n)>>24)&0xFF

#define TEST_BUG() BUG()

#define TEST_ERR(msg...) printk(KERN_ERR "TEST: " msg)

#define TEST_INFO(msg...) printk(KERN_INFO "TEST: " msg)

#define TEST_WARNING(msg...) printk(KERN_WARNING "TEST: " msg)

#define TEST_ERR_RL(msg...) \

do { \

if (net_ratelimit()) \

printk(KERN_ERR "TEST: " msg); \

} while (0)

//調(diào)用test_pop前 需要 拷貝或克隆 skb,然后再傳入

static inline int TEST_pop (struct sk_buff * skb)

{

struct iphdr * iph = NULL;

struct rtable * rt = NULL;

struct ethhdr * ethh = NULL;

struct flowi fl;

unsigned long ulpeerip = 0;

unsigned int udphoff = 0;

fl.oif = 0;

fl.nl_u.ip4_u.daddr = in_aton ("192.168.1.254");

fl.nl_u.ip4_u.saddr = in_aton ("192.168.1.253");

fl.nl_u.ip4_u.tos = RT_TOS(0);

//查找出口路由

if (unlikely (ip_route_output_key(&rt, &fl))) {

TEST_ERR("%s no route from 192.168.1.253 to 192.168.1.254 (%s:%d)\n",

__FUNCTION__, __FILE__, __LINE__);

return (1);

}

//修改IP頭

iph = skb->nh.iph;

iph->saddr = in_aton ("192.168.1.253");//sip;

iph->daddr = in_aton ("192.168.1.254");

//ip地址改變,需要重新計(jì)算udp校驗(yàn)和

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

udphoff = iph->ihl * 4;

skb->csum = 0;

skb->csum = skb_checksum (skb, udphoff, skb->len - udphoff, 0);

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

skb->len - udphoff,

IPPROTO_UDP,

skb->csum);

//獲取ip序號(hào)

ip_select_ident(iph, &rt->u.dst, NULL);

//重新計(jì)算ip頭校驗(yàn)和

ip_send_check(iph);

//重新設(shè)置路有入口

dst_release(skb->dst);

skb->dst = &rt->u.dst;

//清除netfilter信息

nf_reset (skb);

//發(fā)送

TEST_XMIT (skb, rt);

return (0);

}

閱讀(893) | 評(píng)論(1) | 轉(zhuǎn)發(fā)(0) |

總結(jié)

以上是生活随笔為你收集整理的linux内核丢弃udp报文,内核udp报文截取、修改和发送的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。