Socket_Kernel_Module 09

本文提供了多个Netfilter应用实例,包括丢弃所有数据包、基于源接口及IP地址过滤数据包等,展示了如何通过编写模块化代码实现精细的网络流量控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.4简单示例:

以下提供的是一个示例代码,该示例代码简单的注册了一个丢弃所有到达的数据包的函数。该代码同时展示了Netfilter的返回值如何被解析。

/*
* 安装一个丢弃所有到达的数据包的Netfilter hook函数的示例代码
*/

#define __KERNEL__
#define MODULE

#include <linux/module.h>;
#include <linux/kernel.h>;
#include <linux/netfilter.h>;
#include <linux/netfilter_ipv4.h>;

/* 用于注册我们的函数的数据结构 */
static struct nf_hook_ops nfho;

/* 注册的hook函数的实现 */
unsigned int hook_func(unsigned int hooknum,
                       struct sk_buff **skb,
                       const struct net_device *in,
                       const struct net_device *out,
                       int (*okfn)(struct sk_buff *))
{
    return NF_DROP;           /* 丢弃所有的数据包 */
}

/* 初始化程序 */
int init_module()
{
    /* 填充我们的hook数据结构 */
    nfho.hook = hook_func;         /* 处理函数 */
    nfho.hooknum = NF_IP_PRE_ROUTING; /* 使用IPv4的第一个hook */
    nfho.pf       = PF_INET;
    nfho.priority = NF_IP_PRI_FIRST;   /* 让我们的函数首先执行 */

    nf_register_hook(&nfho);

    return 0;
}

/* 清除程序 */
void cleanup_module()
{
    nf_unregister_hook(&nfho);

 

MODULE_LICENSE("GPL"); //表示采用的开放协议

module_init(init_module);     //
module_exit(cleanup_module);   //

 

4.5基于源接口的数据包过滤

后面这些代码摘自LWFW

使用相应的net_device数据结构的name这个成员,通过比对接口名字,就可以根据数据包的源接口和目的接口来选择是否丢弃它

*
* 安装一个丢弃所有进入我们指定接口的数据包的Netfilter hook函数的示例代码
*/

#define __KERNEL__
#define MODULE
#include <linux/module.h>;
#include <linux/kernel.h>;
#include <linux/netdevice.h>;
#include <linux/netfilter.h>;
#include <linux/netfilter_ipv4.h>;
/* 用于注册我们的函数的数据结构 */
static struct nf_hook_ops nfho;

/* 我们丢弃的数据包来自的接口的名字 */
static char *drop_if = "lo";

/* 注册的hook函数的实现 */
unsigned int hook_func(unsigned int hooknum,
                       struct sk_buff **skb,
                       const struct net_device *in,
                       const struct net_device *out,
                       int (*okfn)(struct sk_buff *))
{
    if (strcmp(in->name, drop_if) == 0) {               //入接口名称
        printk("Dropped packet on %s.../n", drop_if);
        return NF_DROP;
    } else {
        return NF_ACCEPT;
    }
}

/* 初始化程序 */
int init_module()
{
    /* 填充我们的hook数据结构 */
    nfho.hook     = hook_func;         /* 处理函数 */
    nfho.hooknum = NF_IP_PRE_ROUTING; /* 使用IPv4的第一个hook */
    nfho.pf       = PF_INET;
    nfho.priority = NF_IP_PRI_FIRST;   /* 让我们的函数首先执行 */

    nf_register_hook(&nfho);
  
    return 0;
}
  
/* 清除程序 */
void cleanup_module()
{
    nf_unregister_hook(&nfho);
}

 

MODULE_LICENSE("GPL"); //表示采用的开放协议

module_init(init_module);     //

module_exit(cleanup_module);   // 

 

4.6 基于地址进行过滤

基于数据包的源或目的IP地址进行过滤同样简单

unsigned char *deny_ip = "/x7f/x00/x00/x01"; /* 127.0.0.1 */
static int check_ip_packet(struct sk_buff *skb)
{
    /* We don't want any NULL pointers in the chain to
      * the IP header. */
    if (!skb )return NF_ACCEPT;
    if (!(skb->;nh.iph)) return NF_ACCEPT;
         
    if (skb->nh.iph->saddr == *(unsigned int *)deny_ip) {
        return NF_DROP;
    }

    return NF_ACCEPT;
}

 

如果数据包的源地址与我们设定的丢弃数据包的地址匹配,那么该数据包将被丢弃。

为了使这个函数能按预期的方式工作,deny_ip的值应当以网络字节序(Big-endian,与Intel相反)存放

 

4.7基于数据包源地址的过滤

 

/* 安装丢弃所有来自指定IP地址的数据包的Netfilter hook的示例代码 */

#define __KERNEL__
#define MODULE

#include <linux/module.h>;
#include <linux/kernel.h>;
#include <linux/skbuff.h>;
#include <linux/ip.h>;                  /* For IP header */
#include <linux/netfilter.h>;
#include <linux/netfilter_ipv4.h>;

/* 用于注册我们的函数的数据结构 */
static struct nf_hook_ops nfho;

/* 我们要丢弃的数据包来自的地址,网络字节序 */
static unsigned char *drop_ip = "/x7f/x00/x00/x01";

/* 注册的hook函数的实现 */
unsigned int hook_func(unsigned int hooknum,
                       struct sk_buff **skb,
                       const struct net_device *in,
                       const struct net_device *out,
                       int (*okfn)(struct sk_buff *))
{
    struct sk_buff *sb = *skb;
   
    if (sb->nh.iph->saddr == *(unsigned int *)drop_ip) {
        printk("Dropped packet from... %d.%d.%d.%d/n",
                              *drop_ip, *(drop_ip + 1),*(drop_ip + 2), *(drop_ip + 3));
        return NF_DROP;
    } else {
        return NF_ACCEPT;
    }
}

 

 

/* 初始化程序 */
int init_module()
{
    /* 填充我们的hook数据结构 */
    nfho.hook       = hook_func;         /* 处理函数 */
    nfho.hooknum = NF_IP_PRE_ROUTING; /* 使用IPv4的第一个hook */
    nfho.pf       = PF_INET;
    nfho.priority = NF_IP_PRI_FIRST;   /* 让我们的函数首先执行 */

    nf_register_hook(&nfho);

    return 0;
}

/* 清除程序 */
void cleanup_module()
{
    nf_unregister_hook(&nfho);
}

 

4.8基于TCP端口进行过滤

 

unsigned char *deny_port = "/x00/x19";   /* port 25 deny_port必须是网络字节序 */
static int check_tcp_packet(struct sk_buff *skb)
{
    struct tcphdr *thead;

    /* We don't want any NULL pointers in the chain
     * to the IP header. */
    if (!skb ) return NF_ACCEPT;
    if (!(skb->;nh.iph)) return NF_ACCEPT;

    /* Be sure this is a TCP packet first */
    if (skb->;nh.iph->;protocol != IPPROTO_TCP) {
        return NF_ACCEPT;
    }

    thead = (struct tcphdr *)(skb->;data +
                             (skb->;nh.iph->;ihl * 4));

    /* Now check the destination port */
    if ((thead->;dest) == *(unsigned short *)deny_port) {
        return NF_DROP;
    }
    return NF_ACCEPT;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值