00001
00002
00003
struct notifier_block;
00004
00005
#include <linux/netfilter_ipv4.h>
00006
#include <linux/ip.h>
00007
#include <net/icmp.h>
00008
#include <linux/if.h>
00009
#include <linux/inetdevice.h>
00010
#include <linux/netdevice.h>
00011
#include <linux/module.h>
00012
#include <asm/uaccess.h>
00013
#include <net/ip.h>
00014
#include <net/route.h>
00015
#include <linux/netfilter_ipv4/compat_firewall.h>
00016
#include <linux/netfilter_ipv4/ip_conntrack.h>
00017
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
00018
00019
00020
00021 EXPORT_NO_SYMBOLS;
00022
00023 static struct firewall_ops *
fwops;
00024
00025
00026
extern unsigned int
00027
do_redirect(
struct sk_buff *skb,
00028
const struct net_device *dev,
00029 u_int16_t redirpt);
00030
00031
extern void
00032
check_for_redirect(
struct sk_buff *skb);
00033
00034
extern void
00035
check_for_unredirect(
struct sk_buff *skb);
00036
00037
00038
extern unsigned int
00039
do_masquerade(
struct sk_buff **pskb,
const struct net_device *dev);
00040
00041
extern unsigned int
00042
check_for_masq_error(
struct sk_buff *pskb);
00043
00044
extern unsigned int
00045
check_for_demasq(
struct sk_buff **pskb);
00046
00047
extern int __init
masq_init(
void);
00048
extern void masq_cleanup(
void);
00049
00050
#ifdef CONFIG_IP_VS
00051
00052
extern unsigned int
00053
check_for_ip_vs_out(
struct sk_buff **skb_p,
int (*okfn)(
struct sk_buff *));
00054
#endif
00055
00056
00057 int register_firewall(
int pf,
struct firewall_ops *fw)
00058 {
00059
if (pf != PF_INET) {
00060 printk(
"Attempt to register non-IP firewall module.\n");
00061
return -EINVAL;
00062 }
00063
if (
fwops) {
00064 printk(
"Attempt to register multiple firewall modules.\n");
00065
return -EBUSY;
00066 }
00067
00068
fwops = fw;
00069
return 0;
00070 }
00071
00072 int unregister_firewall(
int pf,
struct firewall_ops *fw)
00073 {
00074
fwops = NULL;
00075
return 0;
00076 }
00077
00078
static unsigned int
00079 fw_in(
unsigned int hooknum,
00080
struct sk_buff **pskb,
00081
const struct net_device *in,
00082
const struct net_device *out,
00083
int (*okfn)(
struct sk_buff *))
00084 {
00085
int ret = FW_BLOCK;
00086 u_int16_t redirpt;
00087
00088
00089 (*pskb)->nfcache |=
NFC_UNKNOWN |
NFC_ALTERED;
00090
if ((*pskb)->ip_summed ==
CHECKSUM_HW)
00091 (*pskb)->ip_summed =
CHECKSUM_NONE;
00092
00093
00094
00095
if (
skb_cloned(*pskb) && !(*pskb)->sk) {
00096
struct sk_buff *nskb =
skb_copy(*pskb, GFP_ATOMIC);
00097
if (!nskb)
00098
return NF_DROP;
00099
kfree_skb(*pskb);
00100 *pskb = nskb;
00101 }
00102
00103
switch (hooknum) {
00104
case NF_IP_PRE_ROUTING:
00105
if (
fwops->fw_acct_in)
00106
fwops->fw_acct_in(
fwops, PF_INET,
00107 (
struct net_device *)in,
00108 (*pskb)->nh.raw, &redirpt, pskb);
00109
00110
if ((*pskb)->nh.iph->frag_off & htons(
IP_MF|
IP_OFFSET)) {
00111 *pskb =
ip_ct_gather_frags(*pskb);
00112
00113
if (!*pskb)
00114
return NF_STOLEN;
00115 }
00116
00117 ret =
fwops->fw_input(
fwops, PF_INET, (
struct net_device *)in,
00118 (*pskb)->nh.raw, &redirpt, pskb);
00119
break;
00120
00121
case NF_IP_FORWARD:
00122
00123
00124
if ((*pskb)->nfct)
00125 ret = FW_ACCEPT;
00126
else ret =
fwops->fw_forward(
fwops, PF_INET,
00127 (
struct net_device *)out,
00128 (*pskb)->nh.raw, &redirpt, pskb);
00129
break;
00130
00131
case NF_IP_POST_ROUTING:
00132 ret =
fwops->fw_output(
fwops, PF_INET,
00133 (
struct net_device *)out,
00134 (*pskb)->nh.raw, &redirpt, pskb);
00135
if (ret == FW_ACCEPT || ret == FW_SKIP) {
00136
if (
fwops->fw_acct_out)
00137
fwops->fw_acct_out(
fwops, PF_INET,
00138 (
struct net_device *)out,
00139 (*pskb)->nh.raw, &redirpt,
00140 pskb);
00141
00142
00143
if (ip_conntrack_confirm(*pskb) ==
NF_DROP)
00144 ret = FW_BLOCK;
00145 }
00146
break;
00147 }
00148
00149
switch (ret) {
00150
case FW_REJECT: {
00151
00152
00153
00154
00155
00156
struct iphdr *iph = (*pskb)->nh.iph;
00157
00158
if ((*pskb)->dst != NULL
00159 ||
ip_route_input(*pskb, iph->daddr, iph->saddr, iph->tos,
00160 (
struct net_device *)in) == 0)
00161
icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH,
00162 0);
00163
return NF_DROP;
00164 }
00165
00166
case FW_ACCEPT:
00167
case FW_SKIP:
00168
if (hooknum ==
NF_IP_PRE_ROUTING) {
00169
check_for_demasq(pskb);
00170
check_for_redirect(*pskb);
00171 }
else if (hooknum ==
NF_IP_POST_ROUTING) {
00172
check_for_unredirect(*pskb);
00173
00174
if ((*pskb)->nh.iph->protocol ==
IPPROTO_ICMP
00175 && (*pskb)->nfct)
00176
check_for_masq_error(*pskb);
00177 }
00178
return NF_ACCEPT;
00179
00180
case FW_MASQUERADE:
00181
if (hooknum ==
NF_IP_FORWARD) {
00182
#ifdef CONFIG_IP_VS
00183
00184
if (
check_for_ip_vs_out(pskb, okfn) ==
NF_STOLEN)
00185
return NF_STOLEN;
00186
#endif
00187
return do_masquerade(pskb, out);
00188 }
00189
else return NF_ACCEPT;
00190
00191
case FW_REDIRECT:
00192
if (hooknum ==
NF_IP_PRE_ROUTING)
00193
return do_redirect(*pskb, in, redirpt);
00194
else return NF_ACCEPT;
00195
00196
default:
00197
00198
return NF_DROP;
00199 }
00200 }
00201
00202 static unsigned int fw_confirm(
unsigned int hooknum,
00203
struct sk_buff **pskb,
00204
const struct net_device *in,
00205
const struct net_device *out,
00206
int (*okfn)(
struct sk_buff *))
00207 {
00208
return ip_conntrack_confirm(*pskb);
00209 }
00210
00211
extern int ip_fw_ctl(
int optval,
void *m,
unsigned int len);
00212
00213 static int sock_fn(
struct sock *sk,
int optval,
void *user,
unsigned int len)
00214 {
00215
00216
00217
00218
00219
00220
00221
00222
char tmp_fw[200];
00223
if (!capable(CAP_NET_ADMIN))
00224
return -EPERM;
00225
00226
if (len >
sizeof(tmp_fw) || len < 1)
00227
return -EINVAL;
00228
00229
if (copy_from_user(&tmp_fw, user, len))
00230
return -EFAULT;
00231
00232
return -
ip_fw_ctl(optval, &tmp_fw, len);
00233 }
00234
00235
static struct nf_hook_ops
preroute_ops
00236 = { { NULL, NULL },
fw_in, PF_INET,
NF_IP_PRE_ROUTING,
NF_IP_PRI_FILTER };
00237
00238
static struct nf_hook_ops
postroute_ops
00239 = { { NULL, NULL },
fw_in, PF_INET,
NF_IP_POST_ROUTING,
NF_IP_PRI_FILTER };
00240
00241
static struct nf_hook_ops
forward_ops
00242 = { { NULL, NULL },
fw_in, PF_INET,
NF_IP_FORWARD,
NF_IP_PRI_FILTER };
00243
00244
static struct nf_hook_ops
local_in_ops
00245 = { { NULL, NULL },
fw_confirm, PF_INET,
NF_IP_LOCAL_IN,
NF_IP_PRI_LAST - 1 };
00246
00247
static struct nf_sockopt_ops
sock_ops
00248 = { { NULL, NULL }, PF_INET, 64, 64 + 1024 + 1, &
sock_fn, 0, 0, NULL,
00249 0, NULL };
00250
00251
extern int ipfw_init_or_cleanup(
int init);
00252
00253 static int init_or_cleanup(
int init)
00254 {
00255
int ret = 0;
00256
00257
if (!
init)
goto cleanup;
00258
00259 ret =
nf_register_sockopt(&
sock_ops);
00260
00261
if (ret < 0)
00262
goto cleanup_nothing;
00263
00264 ret =
ipfw_init_or_cleanup(1);
00265
if (ret < 0)
00266
goto cleanup_sockopt;
00267
00268 ret =
masq_init();
00269
if (ret < 0)
00270
goto cleanup_ipfw;
00271
00272
nf_register_hook(&
preroute_ops);
00273
nf_register_hook(&
postroute_ops);
00274
nf_register_hook(&
forward_ops);
00275
nf_register_hook(&
local_in_ops);
00276
00277
return ret;
00278
00279 cleanup:
00280
nf_unregister_hook(&
preroute_ops);
00281
nf_unregister_hook(&
postroute_ops);
00282
nf_unregister_hook(&
forward_ops);
00283
nf_unregister_hook(&
local_in_ops);
00284
00285
masq_cleanup();
00286
00287 cleanup_ipfw:
00288
ipfw_init_or_cleanup(0);
00289
00290 cleanup_sockopt:
00291
nf_unregister_sockopt(&
sock_ops);
00292
00293 cleanup_nothing:
00294
return ret;
00295 }
00296
00297 static int __init
init(
void)
00298 {
00299
return init_or_cleanup(1);
00300 }
00301
00302 static void __exit
fini(
void)
00303 {
00304
init_or_cleanup(0);
00305 }
00306
00307
module_init(init);
00308
module_exit(fini);