Linux Netfilter discussions
 help / color / mirror / Atom feed
From: "Kyoungyong Lee" <leeky@icu.ac.kr>
To: netfilter@lists.netfilter.org
Subject: [help] packet forwarding.. T_T
Date: Tue, 7 Oct 2003 18:57:42 +0900	[thread overview]
Message-ID: <01a801c38cb9$734d73c0$e4836bd2@leeky> (raw)

[-- Attachment #1: Type: text/plain, Size: 3985 bytes --]

Hi,

I have a problem in writing netfilter module.

the purpose of this program is to forward packets which is incoming specified port number to specified destination address(with specified port).

the problem I met is occured when executing "skb2->dst->output(skb2)".
whenever I tested this program, linux box was crashed.

i'll explain the flow of this program.

.- netfilter module receives packet.
.- if this packet is from port 9999, forward it to 210.111.222.111:9999. otherwise, do nothing...

Could you explain your briliant solution?? I hope..

Thanks.


================= Source Code ==========================================
#define __KERNEL__
#define MODULE

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/mm.h>
#include <asm/uaccess.h>
#include <linux/string.h>

#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/inet.h>

#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>

#include <linux/interrupt.h>

#include <net/route.h>
#include <net/sock.h>

struct nf_hook_ops pre_routing_filter;

char *next_node_ip_address = "210.111.222.111";
short DEST_PORT = 9999;

int change_daddr(struct sk_buff **pskb)
{
        ((*pskb)->nh.iph)->daddr = in_aton(next_node_ip_address);
        ((*pskb)->h.th)->dest = htons(DEST_PORT);

        (*pskb)->nfcache |= NFC_ALTERED;

        return 1;
}

static int route_me_harder(struct sk_buff *skb)
{
        struct iphdr *iph = skb->nh.iph;
        struct rtable *rt;
        struct rt_key key = {   dst:iph->daddr,
                                src:iph->saddr,
                                oif:skb->sk ? skb->sk->bound_dev_if : 0,
                                tos:RT_TOS(iph->tos)|RTO_CONN,
#ifdef CONFIG_IP_ROUTE_FWMARK
                                fwmark:skb->nfmark
#endif
        };

        if (ip_route_output_key(&rt, &key) != 0) {
                printk("route_me_harder: No more route.\n");
                return -EINVAL;
        }

        dst_release(skb->dst);
        skb->dst = &rt->u.dst;

        return 0;
}

unsigned int pre_routing_handler(unsigned int hooknum,
                                struct sk_buff **skb,
                                const struct net_device *in,
                                const struct net_device *out)
{
        struct iphdr *iph;
        struct tcphdr *tcph;

        struct sk_buff *skb2 = NULL;

        iph  = (*skb)->nh.iph;
        tcph = (struct tcphdr*)((__u32 *)iph+iph->ihl);

        if(ntohs(tcph->dest) == DEST_PORT)
        {
                skb2 = skb_clone(*skb, GFP_ATOMIC);
                if(change_daddr(&skb2)){
                        if(route_me_harder(skb2) != 0){
                                kfree_skb(skb2);
                        }

                        skb2->dst->output(skb2);

                        return NF_ACCEPT;
                }
        }

        return 0;
}

int init_module(void)
{
        int result;

        /* pre_routing hook */
        pre_routing_filter.list.next = NULL;
        pre_routing_filter.list.prev = NULL;
        pre_routing_filter.hook = (nf_hookfn*)pre_routing_handler;
        pre_routing_filter.pf = PF_INET; /* IPv4 */
        pre_routing_filter.hooknum = NF_IP_PRE_ROUTING;
        pre_routing_filter.priority = NF_IP_PRI_FILTER;

        /* hooks registration */
        result = nf_register_hook(&pre_routing_filter);
        if(result){
                goto hook_failed;
        }

        return 0;

hook_failed:
        return result; /* error registering hooks */
}

void cleanup_module(void)
{
        /* unregister hooks */
        nf_unregister_hook(&pre_routing_filter);
        printk("cleanup_module\n");
}

============== End of Source Code =============================================

[-- Attachment #2: Type: text/html, Size: 10087 bytes --]

                 reply	other threads:[~2003-10-07  9:57 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='01a801c38cb9$734d73c0$e4836bd2@leeky' \
    --to=leeky@icu.ac.kr \
    --cc=netfilter@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox