1/* 2 * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT . 3 * 4 * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 5 */ 6#include <linux/module.h> 7#include <linux/netfilter_ipv4/ip_tables.h> 8#include <net/ip.h> 9 10#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT)) 11 12static struct 13{ 14 struct ipt_replace repl; 15 struct ipt_standard entries[2]; 16 struct ipt_error term; 17} initial_table __initdata = { 18 .repl = { 19 .name = "raw", 20 .valid_hooks = RAW_VALID_HOOKS, 21 .num_entries = 3, 22 .size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error), 23 .hook_entry = { 24 [NF_IP_PRE_ROUTING] = 0, 25 [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) 26 }, 27 .underflow = { 28 [NF_IP_PRE_ROUTING] = 0, 29 [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) 30 }, 31 }, 32 .entries = { 33 IPT_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ 34 IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ 35 }, 36 .term = IPT_ERROR_INIT, /* ERROR */ 37}; 38 39static struct xt_table packet_raw = { 40 .name = "raw", 41 .valid_hooks = RAW_VALID_HOOKS, 42 .lock = RW_LOCK_UNLOCKED, 43 .me = THIS_MODULE, 44 .af = AF_INET, 45}; 46 47/* The work comes in here from netfilter.c. */ 48static unsigned int 49ipt_hook(unsigned int hook, 50 struct sk_buff **pskb, 51 const struct net_device *in, 52 const struct net_device *out, 53 int (*okfn)(struct sk_buff *)) 54{ 55 return ipt_do_table(pskb, hook, in, out, &packet_raw); 56} 57 58static unsigned int 59ipt_local_hook(unsigned int hook, 60 struct sk_buff **pskb, 61 const struct net_device *in, 62 const struct net_device *out, 63 int (*okfn)(struct sk_buff *)) 64{ 65 /* root is playing with raw sockets. */ 66 if ((*pskb)->len < sizeof(struct iphdr) || 67 ip_hdrlen(*pskb) < sizeof(struct iphdr)) { 68 if (net_ratelimit()) 69 printk("iptable_raw: ignoring short SOCK_RAW" 70 "packet.\n"); 71 return NF_ACCEPT; 72 } 73 return ipt_do_table(pskb, hook, in, out, &packet_raw); 74} 75 76/* 'raw' is the very first table. */ 77static struct nf_hook_ops ipt_ops[] = { 78 { 79 .hook = ipt_hook, 80 .pf = PF_INET, 81 .hooknum = NF_IP_PRE_ROUTING, 82 .priority = NF_IP_PRI_RAW, 83 .owner = THIS_MODULE, 84 }, 85 { 86 .hook = ipt_local_hook, 87 .pf = PF_INET, 88 .hooknum = NF_IP_LOCAL_OUT, 89 .priority = NF_IP_PRI_RAW, 90 .owner = THIS_MODULE, 91 }, 92}; 93 94static int __init iptable_raw_init(void) 95{ 96 int ret; 97 98 /* Register table */ 99 ret = ipt_register_table(&packet_raw, &initial_table.repl); 100 if (ret < 0) 101 return ret; 102 103 /* Register hooks */ 104 ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); 105 if (ret < 0) 106 goto cleanup_table; 107 108 return ret; 109 110 cleanup_table: 111 ipt_unregister_table(&packet_raw); 112 return ret; 113} 114 115static void __exit iptable_raw_fini(void) 116{ 117 nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); 118 ipt_unregister_table(&packet_raw); 119} 120 121module_init(iptable_raw_init); 122module_exit(iptable_raw_fini); 123MODULE_LICENSE("GPL"); 124