OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [ipv4/] [netfilter/] [ip_nat_amanda.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* Amanda extension for TCP NAT alteration.
2
 * (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca>
3
 * based on a copy of HW's ip_nat_irc.c as well as other modules
4
 *
5
 *      This program is free software; you can redistribute it and/or
6
 *      modify it under the terms of the GNU General Public License
7
 *      as published by the Free Software Foundation; either version
8
 *      2 of the License, or (at your option) any later version.
9
 *
10
 *      Module load syntax:
11
 *      insmod ip_nat_amanda.o
12
 */
13
 
14
#include <linux/kernel.h>
15
#include <linux/module.h>
16
#include <linux/netfilter.h>
17
#include <linux/skbuff.h>
18
#include <linux/ip.h>
19
#include <linux/udp.h>
20
#include <net/tcp.h>
21
#include <net/udp.h>
22
 
23
#include <linux/netfilter_ipv4.h>
24
#include <linux/netfilter_ipv4/ip_nat.h>
25
#include <linux/netfilter_ipv4/ip_nat_helper.h>
26
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
27
#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
28
 
29
 
30
MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
31
MODULE_DESCRIPTION("Amanda NAT helper");
32
MODULE_LICENSE("GPL");
33
 
34
static unsigned int
35
amanda_nat_expected(struct sk_buff **pskb,
36
                    unsigned int hooknum,
37
                    struct ip_conntrack *ct,
38
                    struct ip_nat_info *info)
39
{
40
        struct ip_conntrack *master = master_ct(ct);
41
        struct ip_ct_amanda_expect *exp_amanda_info;
42
        struct ip_nat_multi_range mr;
43
        u_int32_t newip;
44
 
45
        IP_NF_ASSERT(info);
46
        IP_NF_ASSERT(master);
47
        IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
48
 
49
        if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
50
                newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
51
        else
52
                newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
53
 
54
        mr.rangesize = 1;
55
        /* We don't want to manip the per-protocol, just the IPs. */
56
        mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
57
        mr.range[0].min_ip = mr.range[0].max_ip = newip;
58
 
59
        if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
60
                exp_amanda_info = &ct->master->help.exp_amanda_info;
61
                mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
62
                mr.range[0].min = mr.range[0].max
63
                        = ((union ip_conntrack_manip_proto)
64
                                { .udp = { htons(exp_amanda_info->port) } });
65
        }
66
 
67
        return ip_nat_setup_info(ct, &mr, hooknum);
68
}
69
 
70
static int amanda_data_fixup(struct ip_conntrack *ct,
71
                             struct sk_buff **pskb,
72
                             enum ip_conntrack_info ctinfo,
73
                             struct ip_conntrack_expect *exp)
74
{
75
        struct ip_ct_amanda_expect *exp_amanda_info;
76
        struct ip_conntrack_tuple t = exp->tuple;
77
        char buffer[sizeof("65535")];
78
        u_int16_t port;
79
 
80
        /* Alter conntrack's expectations. */
81
        exp_amanda_info = &exp->help.exp_amanda_info;
82
        t.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
83
        for (port = exp_amanda_info->port; port != 0; port++) {
84
                t.dst.u.tcp.port = htons(port);
85
                if (ip_conntrack_change_expect(exp, &t) == 0)
86
                        break;
87
        }
88
        if (port == 0)
89
                return 0;
90
 
91
        sprintf(buffer, "%u", port);
92
        return ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
93
                                        exp_amanda_info->offset,
94
                                        exp_amanda_info->len,
95
                                        buffer, strlen(buffer));
96
}
97
 
98
static unsigned int help(struct ip_conntrack *ct,
99
                         struct ip_conntrack_expect *exp,
100
                         struct ip_nat_info *info,
101
                         enum ip_conntrack_info ctinfo,
102
                         unsigned int hooknum,
103
                         struct sk_buff **pskb)
104
{
105
        int dir = CTINFO2DIR(ctinfo);
106
        int ret = NF_ACCEPT;
107
 
108
        /* Only mangle things once: original direction in POST_ROUTING
109
           and reply direction on PRE_ROUTING. */
110
        if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
111
              || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY)))
112
                return NF_ACCEPT;
113
 
114
        /* if this exectation has a "offset" the packet needs to be mangled */
115
        if (exp->help.exp_amanda_info.offset != 0)
116
                if (!amanda_data_fixup(ct, pskb, ctinfo, exp))
117
                        ret = NF_DROP;
118
        exp->help.exp_amanda_info.offset = 0;
119
 
120
        return ret;
121
}
122
 
123
static struct ip_nat_helper ip_nat_amanda_helper;
124
 
125
static void __exit fini(void)
126
{
127
        ip_nat_helper_unregister(&ip_nat_amanda_helper);
128
}
129
 
130
static int __init init(void)
131
{
132
        struct ip_nat_helper *hlpr = &ip_nat_amanda_helper;
133
 
134
        hlpr->tuple.dst.protonum = IPPROTO_UDP;
135
        hlpr->tuple.src.u.udp.port = htons(10080);
136
        hlpr->mask.src.u.udp.port = 0xFFFF;
137
        hlpr->mask.dst.protonum = 0xFFFF;
138
        hlpr->help = help;
139
        hlpr->flags = 0;
140
        hlpr->me = THIS_MODULE;
141
        hlpr->expect = amanda_nat_expected;
142
        hlpr->name = "amanda";
143
 
144
        return ip_nat_helper_register(hlpr);
145
}
146
 
147
module_init(init);
148
module_exit(fini);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.