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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用 netfilter 处理IPv6报文

發布時間:2025/4/5 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用 netfilter 处理IPv6报文 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ????? netfilter對IPv6的處理和IPv4流程類似,只有鉤子函數注冊協議不同,優先級和注冊的鏈都是一樣的。

{.hook=nf_input_hook_v4,.pf=NFPROTO_IPV4, //IPv4協議.hooknum=NF_INET_POST_ROUTING,.priority=0,}, {.hook=nf_input_hook_v6,.pf=NFPROTO_IPV6, //IPv6協議.hooknum=NF_INET_PRE_ROUTING,.priority=NF_IP_PRI_FIRST,},

下面是一個netfilter ipv6小栗子,對本機出去的IPv6 UDP報文做了端口變換處理,介紹一下IPv6地址操作、IPv6報文udp校驗值計算等等。

內核版本: 3.4.39

/** Netfilter IPv6 Demo, NAT* Autor : Mason* Date : 20180731*/#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/socket.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv4.h> #include <linux/in.h> #include <linux/if_ether.h> #include <linux/ip.h> #include <net/ip.h> #include <net/dsfield.h> #include <linux/skbuff.h> #include <linux/inet.h> #include <linux/netdevice.h> #include <net/route.h> #include "nfdemov6.h"/* IPv6輸入報文處理函數 */ static unsigned int nfdemo_input_hook_v6(unsigned int hooknum,struct sk_buff *skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff *)) { /* do something */return NF_ACCEPT; }/* IPv6輸出報文處理函數,這里對IPv6 UDP報文做了源端口變換 */ static unsigned int nfdemo_output_hook_v6(unsigned int hooknum,struct sk_buff *skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff *)) { struct ipv6hdr *iph6;struct udphdr *udph; unsigned int udp_len;/* 獲取IPv6首部指針 */iph6 = ipv6_hdr(skb);if (!iph6)return NF_ACCEPT;/* 過濾 ::/128 空類型地址 */if (ipv6_addr_any(&iph6->saddr) || ipv6_addr_any(&iph6->daddr))return NF_ACCEPT;/* 過濾源地址和目的地址相等的報文 */if (ipv6_addr_equal(&iph6->saddr, &iph6->daddr))return NF_ACCEPT;/* 過濾環回地址報文 ::1/128 */if (ipv6_addr_loopback(&iph6->saddr) || ipv6_addr_loopback(&iph6->daddr)) return NF_ACCEPT;/* 只處理UDP報文 */ if (iph6->nexthdr != NEXTHDR_UDP)return NF_ACCEPT;/* 設置傳輸層首部 */skb_set_transport_header(skb, sizeof(struct ipv6hdr));/* 獲取UDP首部 */udph = udp_hdr(skb);if (!udph )return NF_ACCEPT;/* 更改端口 */ udph->source = htons(6666); /* 重新計算校驗和 * IPv6校驗和計算使用 csum_ipv6_magic() 接口* IPv4校驗和計算使用 csum_tcpudp_magic() 接口*/ udph->check = 0; udp_len = ntohs(udph->len); skb->csum = csum_partial(skb_transport_header(skb), udp_len, 0);udph->check = csum_ipv6_magic(&iph6->saddr, &iph6->daddr, udp_len, IPPROTO_UDP, skb->csum); skb->ip_summed = CHECKSUM_NONE;/* 如果udp首部校驗和為0,替換成CSUM_MANGLED_0 */if (0 == udph->check)udph->check = CSUM_MANGLED_0;/* 替換完成,把報文還給系統協議棧繼續處理 */return NF_ACCEPT; }struct nf_hook_ops nfdemo_hook_ops[] ={{.hook = nfdemo_input_hook_v6, /* 鉤子處理函數 */.pf = NFPROTO_IPV6, /* 協議類型IPv6 */.hooknum = NF_INET_PRE_ROUTING, /* Pre_Routing鏈 */.priority = NF_IP_PRI_FIRST + 20, /* 優先級 */},{.hook = nfdemo_output_hook_v6, /* 鉤子處理函數 */.pf = NFPROTO_IPV6, /* 協議類型IPv6 */.hooknum = NF_INET_PRE_ROUTING, /* Post_Routing鏈 */.priority = NF_IP_PRI_FIRST + 20, /* 優先級 */},{} };/* 模塊入口 */ static int __init nfdemov6_init(void) {printk("nfv6demo init \r\n");/* 注冊 Netfilter 鉤子函數 */nf_register_hooks(nfdemo_hook_ops,ARRAY_SIZE(nfdemo_hook_ops)); return 0; }/* 模塊出口 */ static void __exit nfdemov6_exit(void) {printk("nfv6demo exit \r\n");/* 注銷 Netfilter 鉤子函數 */nf_unregister_hooks(nfdemo_hook_ops,ARRAY_SIZE(nfdemo_hook_ops)); return ; }module_init(nfdemov6_init) module_exit(nfdemov6_exit) MODULE_LICENSE("GPL"); MODULE_AUTHOR("Mason");

代碼在本機編譯、運行通過。

調試遇到一個bug,地址替換直接使用128,IPv6地址 長度為40字節128位,導致直接覆蓋后面內容,悲催

當然啦,聰明的你應該不會出現這樣的錯誤

//正確的做法 memcpy(remote_ip.in6, &iph6->saddr, sizeof(struct in6_addr));//錯誤的做法 memcpy(remote_ip.in6, &iph6->saddr, 128);

有問題歡迎提出來

またね

總結

以上是生活随笔為你收集整理的使用 netfilter 处理IPv6报文的全部內容,希望文章能夠幫你解決所遇到的問題。

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