iptable_raw.c revision 65b4b4e81a5094d52cbe372b887b1779abe53f9b
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
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 = {
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.name = "raw",
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.valid_hooks = RAW_VALID_HOOKS,
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.num_entries = 3,
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.hook_entry = {
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			[NF_IP_PRE_ROUTING] = 0,
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			[NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) },
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.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 */
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	     {
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     .entry = {
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     .target_offset = sizeof(struct ipt_entry),
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     .next_offset = sizeof(struct ipt_standard),
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     },
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     .target = {
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  .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 = {
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						.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
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct ipt_table packet_raw = {
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.name = "raw",
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.valid_hooks =  RAW_VALID_HOOKS,
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.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{
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 'raw' is the very first table. */
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct nf_hook_ops ipt_ops[] = {
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  .hook = ipt_hook,
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  .pf = PF_INET,
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  .hooknum = NF_IP_PRE_ROUTING,
107b43309578477ff3271945d4efb920f558a309b4aPatrick McHardy	  .priority = NF_IP_PRI_RAW,
108b43309578477ff3271945d4efb920f558a309b4aPatrick McHardy	  .owner = THIS_MODULE,
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	},
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  .hook = ipt_hook,
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  .pf = PF_INET,
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  .hooknum = NF_IP_LOCAL_OUT,
114b43309578477ff3271945d4efb920f558a309b4aPatrick McHardy	  .priority = NF_IP_PRI_RAW,
115b43309578477ff3271945d4efb920f558a309b4aPatrick 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 */
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = nf_register_hook(&ipt_ops[0]);
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ret < 0)
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto cleanup_table;
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = nf_register_hook(&ipt_ops[1]);
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ret < 0)
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto cleanup_hook0;
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cleanup_hook0:
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nf_unregister_hook(&ipt_ops[0]);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cleanup_table:
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ipt_unregister_table(&packet_raw);
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14765b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonstatic void __exit iptable_raw_fini(void)
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int i;
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nf_unregister_hook(&ipt_ops[i]);
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ipt_unregister_table(&packet_raw);
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15765b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_init(iptable_raw_init);
15865b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_exit(iptable_raw_fini);
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
160