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报文相关推荐

  1. Linux 内核源码分析 IPv6报文接收处理流程

    内核版本 3.4.39 实现一个IPv6报文转发功能的时候,需要对IPv6报文的扩展选项进行处理,还是直接参考下内核的处理比较稳妥,整理了IPv6报文的内核处理流程,如下图:

  2. 如何设置IPv4和IPv6报文的DSCP值——网络测试仪实操

    一.操作说明 在QoS测试中,经常要设置不同优先级的报文,来验证被测设备对于优先级的调度.所以,我们就要了解如何设置IPv6和IPv6报文中的DSCP(大部分使用DSCP值,也会用到TOS值) 这里我 ...

  3. IPv4和IPv6报文格式介绍和对比

    IPv4和IPv6报文介绍和对比 IPv4数据报 IPv4报文详解 IPv6数据报 IPv6报文详解 扩展头部详解 IPv4和IPv6报文详细对比 IPv4数据报 IPv4报文详解 版本Version ...

  4. c语言设置ipv6报文扩展头,IPV6扩展报文头

    IPv6_Exten_Header.pdf 紧跟着IPv6报文头8个基本字段后面的是扩展报头和数据部分. 扩展报头部分并不固定,如果存在,以 紧跟着8个基本字段后面是扩展报头和数据部分.扩展报头部分并 ...

  5. IPv4和IPv6报文详细和区别

    文章目录 IPv4和IPv6报文详细和区别 一.IPv4报文格式 二.IPv6报文格式 三.IPv4报文和IPv6报文区别 IPv4和IPv6报文详细和区别 一.IPv4报文格式 1.Version ...

  6. IPv4 和 IPv6 报文格式详解

    文章目录 1 概述 2 报文格式 2.1 IPv4 2.2 IPv6 2.3 两者区别 3 网工软考真题 1 概述 2 报文格式 2.1 IPv4 中文名 英文名 长度 bit(位) 解释 版本 Ve ...

  7. tcp/ip 协议栈Linux源码分析五 IPv6分片报文重组分析一

    做防火墙模块的时候遇到过IPv6分片报文处理的问题是,当时的问题是netfilter无法基于传输层的端口拦截IPv6分片报文,但是IPv4的分片报文可以.分析了内核源码得知是因为netfilter的连 ...

  8. ip6tables 无法基于端口过滤IPv6 分片报文问题解决

    问题现象:使用ip6tables 添加端口过滤规则,只允许指定端口IPv6报文进来,测试结果显示如果是分片报文,只有第一个分片报文能够收到,后续分片会被丢弃. 内核版本:3.4.39 问题原因: 因为 ...

  9. ++实现 ipv6数据报_IPV6报文格式和IPV4有什么区别?

    前言 RFC2460定义了IPv6数据报格式. 总体结构上,IPv6数据报格式与IPv4数据报格式是一样的,也是由IP报头和数据(在IPv6中称为有效载荷)这两个部分组成的. 但在IPv6数据报数据部 ...

最新文章

  1. leangoo自由配置任务卡片(需求、迭代、bug)自定义字段
  2. Android之如何设置TextView中不同字段的字体颜色
  3. python字符串/列表/字典互相转换
  4. react学习(60)--ant design中getFieldDecorator
  5. 数据结构--------------静态表的希尔排序
  6. web管理 pdo-mysql_PHP重新安装启用PDO扩展和PDO_MySQL扩展
  7. 明天回湖北!今天要开始收拾烂摊子了
  8. Python 分析到底是谁操纵《庆余年》上了热搜?
  9. 嵌入式实时操作系统ucos-ii_「正点原子NANO STM32开发板资料连载」第三十八章 UCOSII 实验 3...
  10. 创建连接数据库(DBLink)
  11. 8.声卡驱动02-自己实现alsa驱动-虚拟声卡-匹配
  12. Spring Cloud与Dubbo优缺点详解
  13. 探讨:Mac真的有必要安装双系统吗
  14. 智能车辆纵向速度跟踪与控制方法研究
  15. AndroidStudio项目配置第三方libray库
  16. 周报8.22-8.28
  17. CCRC信息安全服务资质--软件开发-简单介绍
  18. 磁盘分区方式——MBR与GPT之学习笔记
  19. 自动驾驶常用定位方案
  20. samsung android usb device驱动

热门文章

  1. .Net 4.0 (2)
  2. 各种排序总结(一)直接插入排序
  3. 代码编译delphi条件编译
  4. 两个场景怎样合在一起_Spring AOP应用场景你还不知道?这篇一定要看
  5. 1.4 正则化-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授
  6. usb_get_device_descriptor()
  7. android 8 esp8266,ESP8266 WIFI模块学习之路(8)——自写Android手机APP控制直流电机正反转...
  8. 五天带你学完《计算机网络》·第四天·应用层
  9. 警惕!这7件事情千万不要发生你身上-来自15年程序员的忠告
  10. 一点一点看JDK源码(五)java.util.ArrayList 后篇之forEach