发新话题
打印

求教,怎么在linux下实现数据包的拦截?

我没有这方面的资料, 多用一下搜索引擎, 用google能找到不错的资料:

http://www.google.com/search?hl= ... 9C%E7%B4%A2&lr=

http://www.google.com/search?q=p ... -CN&newwindow=1      
Advance Monitor - Linux Monitoring Solution

TOP

我发誓一定要学好E文,省的看不懂外国资料。!!!      

TOP

这是一个朋友给我的代码,他说可以运行的。可是为什么在我机子要编译都通不过呢?
是不是运行之前还要有什么预处理命令?

[php]
/*
* filter.c will display all tcp packet information on the screen
*
* gcc -O2 -I /usr/src/linux-2.4.20-8/include/ -c  filter.c
* insmod filter.o
*
* Author interstar
*
*/

#ifndef __KERNEL__
# define __KERNEL__
#endif
#ifndef MODULE
# define MODULE
#endif

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

MODULE_LICENSE("GPL");

char *inet_ntoa(__u32 ina)
{
    static char buf[4 * sizeof "123"];
    unsigned char *ucp = (unsigned char *)&ina;
    sprintf(buf, "%d.%d.%d.%d",
    ucp[0] & 0xff,
    ucp[1] & 0xff,
    ucp[2] & 0xff,
    ucp[3] & 0xff);
    return buf;
}


static unsigned int local_input (unsigned int hooknum, struct sk_buff **pskb,
        const struct net_device *in, const struct net_device *out,
        int (*okfn) (struct sk_buff *))
{
  struct tcphdr *tcph;
  struct iphdr *iph;
  struct sk_buff *skb = *pskb;
  __u32 odaddr;
  __u32 osaddr;
  __u16 odport;
  __u16 osport;
  printk("Local Input Called!\n");
  printk("Input  Device:%s\n",in->name);
  printk("Output Device:%s\n",out->name);
  if (skb->protocol == htons (ETH_P_IP))
    {
      iph = skb->nh.iph;
      if (iph->protocol == IPPROTO_TCP)
      {
      tcph = (struct tcphdr *)((__u32 *)iph+iph->ihl);
      osaddr = iph->saddr;
      odaddr = iph->daddr;
      odport=ntohs(tcph->dest);
      osport=ntohs(tcph->source);
      printk("From:%-16s  Port:%u\n",inet_ntoa(odaddr),osport);
      printk("To:  %-16s  Port:%u\n",inet_ntoa(osaddr),odport);
      printk("fin:%u,syn:%u,ack:%u\n",tcph->fin,tcph->syn,tcph->ack);
      }
    }
  return NF_ACCEPT;
}

static unsigned int local_output (unsigned int hooknum, struct sk_buff **pskb,
          const struct net_device *in, const struct net_device *out,
          int (*okfn) (struct sk_buff *))
{
  struct tcphdr *tcph;
  struct iphdr *iph;
  struct sk_buff *skb = *pskb;
  __u32 odaddr;
  __u32 osaddr;
  __u16 odport;
  __u16 osport;
  printk("Local Output Called!\n");
  printk("Input  Device:%s\n",in->name);
  printk("Output Device:%s\n",out->name);
  if (skb->protocol == htons (ETH_P_IP))
    {
      iph = skb->nh.iph;
      if (iph->protocol == IPPROTO_TCP)
      {
      tcph = (struct tcphdr *)((__u32 *)iph+iph->ihl);
      osaddr = iph->saddr;
      odaddr = iph->daddr;
      odport=ntohs(tcph->dest);
      osport=ntohs(tcph->source);
      printk("From:%-16s  Port:%u\n",inet_ntoa(odaddr),osport);
      printk("To:  %-16s  Port:%u\n",inet_ntoa(osaddr),odport);
      printk("fin:%u,syn:%u,ack:%u\n",tcph->fin,tcph->syn,tcph->ack);
      }
    }
  return NF_ACCEPT;
}


static unsigned int forward_filter (unsigned int hooknum, struct sk_buff **pskb,
          const struct net_device *in, const struct net_device *out,
          int (*okfn) (struct sk_buff *))
{
  struct tcphdr *tcph;
  struct iphdr *iph;
  struct sk_buff *skb = *pskb;
  __u32 odaddr;
  __u32 osaddr;
  __u16 odport;
  __u16 osport;
  printk("Forword Called!\n");
  printk("Input  Device:%s\n",in->name);
  printk("Output Device:%s\n",out->name);
  if (skb->protocol == htons (ETH_P_IP))
    {
      iph = skb->nh.iph;
      if (iph->protocol == IPPROTO_TCP)
      {
      tcph = (struct tcphdr *)((__u32 *)iph+iph->ihl);
      osaddr = iph->saddr;
      odaddr = iph->daddr;
      odport=ntohs(tcph->dest);
      osport=ntohs(tcph->source);
      printk("From:%-16s  Port:%u\n",inet_ntoa(odaddr),osport);
      printk("To:  %-16s  Port:%u\n",inet_ntoa(osaddr),odport);
      printk("fin:%u,syn:%u,ack:%u\n",tcph->fin,tcph->syn,tcph->ack);
      }
    }
  return NF_ACCEPT;
}

static struct nf_hook_ops input_filter =
  {
    {NULL, NULL},
    local_input,
    AF_INET,
    NF_IP_LOCAL_IN,
    NF_IP_PRI_FILTER - 1
  };

static struct nf_hook_ops output_filter =
  {
    {NULL, NULL},
    local_output,
    AF_INET,
    NF_IP_LOCAL_OUT,
    NF_IP_PRI_FILTER - 1
  };


static struct nf_hook_ops forward =
  {
    {NULL, NULL},
    forward_filter,
    AF_INET,
    NF_IP_FORWARD,
    NF_IP_PRI_FILTER - 1
  };

//packet flow diagram:
//
//-NF_IP_PRE_ROUTING---| ROUTING PLOCY |---NF_IP_FORWARD---NF_IP_POST_ROUTING
//                            |                                |
//                            |                                |      
//                            |                                |
//                      NF_IP_LOCAL_IN                  NF_IP_LOCAL_OUT
//                            |                                |
//                            |__________|PROCESSING|___________|
//
//ip_build_and_send_pkt,ip_queue_xmit ip_build_xmit_slow,ip_build_xmit


int init_module (void)
{
  printk ("Load Netfilter Module \n");
  if (nf_register_hook (&input_filter) || nf_register_hook (&output_filter) || nf_register_hook (&forward))
    return 1;
  else
    return 0;
}

void cleanup_module (void)
{
  nf_unregister_hook (&input_filter);
  nf_unregister_hook (&output_filter);
  nf_unregister_hook (&forward);
  printk ("UnLoad Netfilter Module\n");
  return;
}
[/php]      

TOP

测试过,没有问题; 需要内核源代码, 注意路径:

gcc -O2 -I /usr/src/linux-2.4.20-8/include/ -c  filter.c      
Advance Monitor - Linux Monitoring Solution

TOP

斑竹,内核源代码我好象已经加了。还是不行啊。      

TOP

在什么系统下编译的? 系统版本, 内核, gcc的版本
我在redhat9下通过了, 2.4.28的内核      
Advance Monitor - Linux Monitoring Solution

TOP

斑竹,留个QQ给我吧。或者加17514662      

TOP

很少用QQ了, 有问题在论坛提出来吧.      
Advance Monitor - Linux Monitoring Solution

TOP

#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);
}
你帮我看看,我自己研究了好久,这段代码是没有错的,可是硬是编译通不过!
以前用C编程,总是有个main()函数做入口,现在这样的程序都不知道怎么入手,想编写一个printk函数来设置我要指定的端口号,都不知道放在什么位置。      

TOP

斑竹再现下身咯      

TOP

发新话题