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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * This is the 1999 rewrite of IP Firewalling, aiming for kernel 2.3.x.
3
 *
4
 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
5
 *
6
 * Extended to all five netfilter hooks by Brad Chapman & Harald Welte
7
 */
8
#include <linux/config.h>
9
#include <linux/module.h>
10
#include <linux/netfilter_ipv4/ip_tables.h>
11
#include <linux/netdevice.h>
12
#include <linux/skbuff.h>
13
#include <net/sock.h>
14
#include <net/route.h>
15
#include <linux/ip.h>
16
 
17
#define MANGLE_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | \
18
                            (1 << NF_IP_LOCAL_IN) | \
19
                            (1 << NF_IP_FORWARD) | \
20
                            (1 << NF_IP_LOCAL_OUT) | \
21
                            (1 << NF_IP_POST_ROUTING))
22
 
23
/* Standard entry. */
24
struct ipt_standard
25
{
26
        struct ipt_entry entry;
27
        struct ipt_standard_target target;
28
};
29
 
30
struct ipt_error_target
31
{
32
        struct ipt_entry_target target;
33
        char errorname[IPT_FUNCTION_MAXNAMELEN];
34
};
35
 
36
struct ipt_error
37
{
38
        struct ipt_entry entry;
39
        struct ipt_error_target target;
40
};
41
 
42
/* Ouch - five different hooks? Maybe this should be a config option..... -- BC */
43
static struct
44
{
45
        struct ipt_replace repl;
46
        struct ipt_standard entries[5];
47
        struct ipt_error term;
48
} initial_table __initdata
49
= { { "mangle", MANGLE_VALID_HOOKS, 6,
50
      sizeof(struct ipt_standard) * 5 + sizeof(struct ipt_error),
51
      { [NF_IP_PRE_ROUTING]     0,
52
        [NF_IP_LOCAL_IN]        sizeof(struct ipt_standard),
53
        [NF_IP_FORWARD]         sizeof(struct ipt_standard) * 2,
54
        [NF_IP_LOCAL_OUT]       sizeof(struct ipt_standard) * 3,
55
        [NF_IP_POST_ROUTING]    sizeof(struct ipt_standard) * 4 },
56
      { [NF_IP_PRE_ROUTING]     0,
57
        [NF_IP_LOCAL_IN]        sizeof(struct ipt_standard),
58
        [NF_IP_FORWARD]         sizeof(struct ipt_standard) * 2,
59
        [NF_IP_LOCAL_OUT]       sizeof(struct ipt_standard) * 3,
60
        [NF_IP_POST_ROUTING]    sizeof(struct ipt_standard) * 4 },
61
      0, NULL, { } },
62
    {
63
            /* PRE_ROUTING */
64
            { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
65
                0,
66
                sizeof(struct ipt_entry),
67
                sizeof(struct ipt_standard),
68
                0, { 0, 0 }, { } },
69
              { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
70
                -NF_ACCEPT - 1 } },
71
            /* LOCAL_IN */
72
            { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
73
                0,
74
                sizeof(struct ipt_entry),
75
                sizeof(struct ipt_standard),
76
                0, { 0, 0 }, { } },
77
              { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
78
                -NF_ACCEPT - 1 } },
79
            /* FORWARD */
80
            { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
81
                0,
82
                sizeof(struct ipt_entry),
83
                sizeof(struct ipt_standard),
84
                0, { 0, 0 }, { } },
85
              { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
86
                -NF_ACCEPT - 1 } },
87
            /* LOCAL_OUT */
88
            { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
89
                0,
90
                sizeof(struct ipt_entry),
91
                sizeof(struct ipt_standard),
92
                0, { 0, 0 }, { } },
93
              { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
94
                -NF_ACCEPT - 1 } },
95
            /* POST_ROUTING */
96
            { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
97
                0,
98
                sizeof(struct ipt_entry),
99
                sizeof(struct ipt_standard),
100
                0, { 0, 0 }, { } },
101
              { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
102
                -NF_ACCEPT - 1 } },
103
    },
104
    /* ERROR */
105
    { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
106
        0,
107
        sizeof(struct ipt_entry),
108
        sizeof(struct ipt_error),
109
        0, { 0, 0 }, { } },
110
      { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
111
          { } },
112
        "ERROR"
113
      }
114
    }
115
};
116
 
117
static struct ipt_table packet_mangler
118
= { { NULL, NULL }, "mangle", &initial_table.repl,
119
    MANGLE_VALID_HOOKS, RW_LOCK_UNLOCKED, NULL, THIS_MODULE };
120
 
121
/* The work comes in here from netfilter.c. */
122
static unsigned int
123
ipt_route_hook(unsigned int hook,
124
         struct sk_buff **pskb,
125
         const struct net_device *in,
126
         const struct net_device *out,
127
         int (*okfn)(struct sk_buff *))
128
{
129
        return ipt_do_table(pskb, hook, in, out, &packet_mangler, NULL);
130
}
131
 
132
static unsigned int
133
ipt_local_hook(unsigned int hook,
134
                   struct sk_buff **pskb,
135
                   const struct net_device *in,
136
                   const struct net_device *out,
137
                   int (*okfn)(struct sk_buff *))
138
{
139
        unsigned int ret;
140
        u_int8_t tos;
141
        u_int32_t saddr, daddr;
142
        unsigned long nfmark;
143
 
144
        /* root is playing with raw sockets. */
145
        if ((*pskb)->len < sizeof(struct iphdr)
146
            || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
147
                if (net_ratelimit())
148
                        printk("ipt_hook: happy cracking.\n");
149
                return NF_ACCEPT;
150
        }
151
 
152
        /* Save things which could affect route */
153
        nfmark = (*pskb)->nfmark;
154
        saddr = (*pskb)->nh.iph->saddr;
155
        daddr = (*pskb)->nh.iph->daddr;
156
        tos = (*pskb)->nh.iph->tos;
157
 
158
        ret = ipt_do_table(pskb, hook, in, out, &packet_mangler, NULL);
159
        /* Reroute for ANY change. */
160
        if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE
161
            && ((*pskb)->nh.iph->saddr != saddr
162
                || (*pskb)->nh.iph->daddr != daddr
163
                || (*pskb)->nfmark != nfmark
164
                || (*pskb)->nh.iph->tos != tos))
165
                return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
166
 
167
        return ret;
168
}
169
 
170
static struct nf_hook_ops ipt_ops[]
171
= { { { NULL, NULL }, ipt_route_hook, PF_INET, NF_IP_PRE_ROUTING,
172
        NF_IP_PRI_MANGLE },
173
    { { NULL, NULL }, ipt_route_hook, PF_INET, NF_IP_LOCAL_IN,
174
        NF_IP_PRI_MANGLE },
175
    { { NULL, NULL }, ipt_route_hook, PF_INET, NF_IP_FORWARD,
176
        NF_IP_PRI_MANGLE },
177
    { { NULL, NULL }, ipt_local_hook, PF_INET, NF_IP_LOCAL_OUT,
178
        NF_IP_PRI_MANGLE },
179
    { { NULL, NULL }, ipt_route_hook, PF_INET, NF_IP_POST_ROUTING,
180
        NF_IP_PRI_MANGLE }
181
};
182
 
183
static int __init init(void)
184
{
185
        int ret;
186
 
187
        /* Register table */
188
        ret = ipt_register_table(&packet_mangler);
189
        if (ret < 0)
190
                return ret;
191
 
192
        /* Register hooks */
193
        ret = nf_register_hook(&ipt_ops[0]);
194
        if (ret < 0)
195
                goto cleanup_table;
196
 
197
        ret = nf_register_hook(&ipt_ops[1]);
198
        if (ret < 0)
199
                goto cleanup_hook0;
200
 
201
        ret = nf_register_hook(&ipt_ops[2]);
202
        if (ret < 0)
203
                goto cleanup_hook1;
204
 
205
        ret = nf_register_hook(&ipt_ops[3]);
206
        if (ret < 0)
207
                goto cleanup_hook2;
208
 
209
        ret = nf_register_hook(&ipt_ops[4]);
210
        if (ret < 0)
211
                goto cleanup_hook3;
212
 
213
        return ret;
214
 
215
 cleanup_hook3:
216
        nf_unregister_hook(&ipt_ops[3]);
217
 cleanup_hook2:
218
        nf_unregister_hook(&ipt_ops[2]);
219
 cleanup_hook1:
220
        nf_unregister_hook(&ipt_ops[1]);
221
 cleanup_hook0:
222
        nf_unregister_hook(&ipt_ops[0]);
223
 cleanup_table:
224
        ipt_unregister_table(&packet_mangler);
225
 
226
        return ret;
227
}
228
 
229
static void __exit fini(void)
230
{
231
        unsigned int i;
232
 
233
        for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
234
                nf_unregister_hook(&ipt_ops[i]);
235
 
236
        ipt_unregister_table(&packet_mangler);
237
}
238
 
239
module_init(init);
240
module_exit(fini);
241
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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