2.6.30内核Netfilter的简单例子、六(filterPort)

66 篇文章 0 订阅

这篇文章分析一下如何利用Netfilter过滤指定的端口,如TCP的80端口。

1、源代码:filterPort.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netdevice.h>

MODULE_LICENSE("GPL");

/* This is the structure we shall use to register our function */
static struct nf_hook_ops nfho;

/* IP address we want to drop packets from, in NB order */
static unsigned char *deny_port = "/x00/x50";   /* port 80 */


/* This is the hook function itself */
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;
  struct iphdr *iph;
  struct tcphdr *tcph;

  if(!sb) return NF_ACCEPT;
  iph = ip_hdr(sb);
  if(!iph) return NF_ACCEPT;

  /*Make sure this is a TCP packet first*/
  if(iph->protocol != IPPROTO_TCP)
  {
    return NF_ACCEPT;
  }
  tcph = (struct tcphdr *)(sb->data + iph->ihl * 4);
  //tcph = tcp_hdr(sb);
  //pr_warning("%d.%d.%d.%d:%u/t%d.%d.%d.%d:%u/n",NIPQUAD(iph->saddr),ntohs(tcph->source),NIPQUAD(iph->daddr),ntohs(tcph->dest));
  if(tcph->dest == *(__be16 *)deny_port)
  {
    pr_warning("Dropped packet to prot %d/n",ntohs(tcph->dest) );
    return NF_DROP;
  }

  return NF_ACCEPT;

}
/* Initialisation routine */
int init_module()
{
  /* Fill in our hook structure */
  nfho.hook     = hook_func;         /* Handler function */
  nfho.hooknum  = NF_INET_PRE_ROUTING; /* First hook for IPv4 */
  nfho.pf       = PF_INET;
  nfho.priority = NF_IP_PRI_FIRST;   /* Make our function first */

  nf_register_hook(&nfho);

  pr_info("filterPort install into kernel!/n");
  return 0;
}
/* Cleanup routine */
void cleanup_module()
{
  nf_unregister_hook(&nfho);
  pr_info("filterPort removed from kernel!/n");
}

2、Makefile:

obj-m +=filterPort.o
all:
  make -C /lib/modules/`uname -r`/build M=`pwd`
clean:
  make -C /lib/modules/`uname -r`/build M=`pwd` clean

install:
  /sbin/insmod filterPort.ko
remove:
  /sbin/rmmod filterPort

3、编译:

make

4、安装模块:

make install

5、测试:

在安装该内核模块的机器上打开http服务:

service httpd start

从别的机器访问这台机器的http服务。会发现连接不上,并且/var/log/messages中有如下字样:

 Dropped packet to prot 80

6、卸载模块:

make remove

7、注意:

本来以为和获得IP头部一样,可以这样

tcph = tcp_hdr(sb);

获得TCP的头部,结果头部信息总是不正确。查看 内核源码:

ip_hdr 定义为:return (struct iphdr *) (skb->head + skb->network_header);
tcp_hdr 定以为:return (struct tcphdr *)(skb->head + skb->transport_header);

 

终于明白我在处理这个skb 时,内核还在网络层,还没有处理到传输层,所以transport_header 的值与network_header 相同。

于是老老实实用:

tcph = (struct tcphdr *)(sb->data + iph->ihl * 4);

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值