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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

發布時間:2023/12/14 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux内核丢弃udp报文,内核udp报文截取、修改和发送 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

近來做一個產品需要在網關上獲取特定UDP端口(假設是1000端口)的報文,并將其轉發給其它設備的1000端口。雖然此類文章網上已經有很多了,但我還是貼上來,這樣自己也做下記錄,大家也多一份參考。

下面只給出了代碼片段,自己慢慢調試。

我們假設網絡拓撲如下所示:

LINUX

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

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

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

pc-1發送udp報文到server的1000端口時,我們將報文拷貝一份并發送給DataSrv的1000端口。

報文的獲取,我們采用netfilter hook. 我們將hook鉤到 NF_IP_LOCAL_IN,優先級別設置成NF_IP_PRI_FIRST。

為什么hook到NF_IP_LOCAL_IN 而不是PERROUTING呢? 這是因為hook到 LOCAL_IN的話,我們就不用去考慮報文的重組了。如下圖:

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

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

為什么優先級別設置成最高了,這樣可以防止udp的穿透。

這里我們不詳細描述netfilter hook如何編寫。下面我們來看獲取到skb(重組好了的)的報文后,我們如何處理。

首先,我們假設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)

//調用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地址改變,需要重新計算udp校驗和

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序號

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

//重新計算ip頭校驗和

ip_send_check(iph);

//重新設置路有入口

dst_release(skb->dst);

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

//清除netfilter信息

nf_reset (skb);

//發送

TEST_XMIT (skb, rt);

return (0);

}

閱讀(893) | 評論(1) | 轉發(0) |

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。