iptable_raw.c revision e905a9edab7f4f14f9213b52234e4a346c690911
1e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/netfilter_ipv4/ip_tables.h>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ipt_replace repl;
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ipt_standard entries[2];
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ipt_error term;
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} initial_table __initdata = {
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.repl = {
18e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki		.name = "raw",
19e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki		.valid_hooks = RAW_VALID_HOOKS,
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.num_entries = 3,
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
22e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki		.hook_entry = {
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			[NF_IP_PRE_ROUTING] = 0,
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			[NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) },
25e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki		.underflow = {
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			[NF_IP_PRE_ROUTING] = 0,
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			[NF_IP_LOCAL_OUT]  = sizeof(struct ipt_standard) },
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	},
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.entries = {
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	     /* PRE_ROUTING */
31e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki	     {
32e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki		     .entry = {
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     .target_offset = sizeof(struct ipt_entry),
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     .next_offset = sizeof(struct ipt_standard),
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     },
36e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki		     .target = {
37e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki			  .target = {
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  .u = {
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					  .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  },
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  },
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  .verdict = -NF_ACCEPT - 1,
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     },
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	     },
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	     /* LOCAL_OUT */
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	     {
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     .entry = {
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     .target_offset = sizeof(struct ipt_entry),
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     .next_offset = sizeof(struct ipt_standard),
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     },
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     .target = {
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     .target = {
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				     .u = {
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					     .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				     },
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     },
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     .verdict = -NF_ACCEPT - 1,
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     },
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	     },
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	},
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* ERROR */
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.term = {
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.entry = {
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			.target_offset = sizeof(struct ipt_entry),
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			.next_offset = sizeof(struct ipt_error),
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		},
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.target = {
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			.target = {
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				.u = {
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					.user = {
72e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki						.target_size = IPT_ALIGN(sizeof(struct ipt_error_target)),
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						.name = IPT_ERROR_TARGET,
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					},
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				},
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			},
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			.errorname = "ERROR",
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		},
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
82e60a13e030867078f3c9fef8dca6cd8a5b883478Jan Engelhardtstatic struct xt_table packet_raw = {
83e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki	.name = "raw",
84e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki	.valid_hooks =  RAW_VALID_HOOKS,
85e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki	.lock = RW_LOCK_UNLOCKED,
862e4e6a17af35be359cc8f1c924f8f198fbd478ccHarald Welte	.me = THIS_MODULE,
872e4e6a17af35be359cc8f1c924f8f198fbd478ccHarald Welte	.af = AF_INET,
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The work comes in here from netfilter.c. */
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsipt_hook(unsigned int hook,
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 struct sk_buff **pskb,
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 const struct net_device *in,
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 const struct net_device *out,
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 int (*okfn)(struct sk_buff *))
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
98fe1cb10873b44cf89082465823ee6d4d4ac63ad7Patrick McHardy	return ipt_do_table(pskb, hook, in, out, &packet_raw);
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 'raw' is the very first table. */
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct nf_hook_ops ipt_ops[] = {
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
104964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy		.hook = ipt_hook,
105964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy		.pf = PF_INET,
106964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy		.hooknum = NF_IP_PRE_ROUTING,
107964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy		.priority = NF_IP_PRI_RAW,
108964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy		.owner = THIS_MODULE,
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	},
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
111964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy		.hook = ipt_hook,
112964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy		.pf = PF_INET,
113964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy		.hooknum = NF_IP_LOCAL_OUT,
114964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy		.priority = NF_IP_PRI_RAW,
115964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy		.owner = THIS_MODULE,
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	},
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11965b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonstatic int __init iptable_raw_init(void)
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Register table */
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = ipt_register_table(&packet_raw, &initial_table.repl);
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ret < 0)
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ret;
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Register hooks */
129964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy	ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ret < 0)
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto cleanup_table;
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cleanup_table:
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ipt_unregister_table(&packet_raw);
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14065b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonstatic void __exit iptable_raw_fini(void)
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
142964ddaa10de8f3aeed12bc2a30726514ff309e64Patrick McHardy	nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ipt_unregister_table(&packet_raw);
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14665b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_init(iptable_raw_init);
14765b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_exit(iptable_raw_fini);
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
149