linux/net/ipv4/netfilter/iptable_raw.c
<<
>>
Prefs
   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_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
  11
  12static const struct
  13{
  14        struct ipt_replace repl;
  15        struct ipt_standard entries[2];
  16        struct ipt_error term;
  17} initial_table __net_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_INET_PRE_ROUTING] = 0,
  25                        [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard)
  26                },
  27                .underflow = {
  28                        [NF_INET_PRE_ROUTING] = 0,
  29                        [NF_INET_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 const struct xt_table packet_raw = {
  40        .name = "raw",
  41        .valid_hooks =  RAW_VALID_HOOKS,
  42        .me = THIS_MODULE,
  43        .af = NFPROTO_IPV4,
  44};
  45
  46/* The work comes in here from netfilter.c. */
  47static unsigned int
  48ipt_hook(unsigned int hook,
  49         struct sk_buff *skb,
  50         const struct net_device *in,
  51         const struct net_device *out,
  52         int (*okfn)(struct sk_buff *))
  53{
  54        return ipt_do_table(skb, hook, in, out,
  55                            dev_net(in)->ipv4.iptable_raw);
  56}
  57
  58static unsigned int
  59ipt_local_hook(unsigned int hook,
  60               struct sk_buff *skb,
  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 (skb->len < sizeof(struct iphdr) ||
  67            ip_hdrlen(skb) < sizeof(struct iphdr))
  68                return NF_ACCEPT;
  69        return ipt_do_table(skb, hook, in, out,
  70                            dev_net(out)->ipv4.iptable_raw);
  71}
  72
  73/* 'raw' is the very first table. */
  74static struct nf_hook_ops ipt_ops[] __read_mostly = {
  75        {
  76                .hook = ipt_hook,
  77                .pf = NFPROTO_IPV4,
  78                .hooknum = NF_INET_PRE_ROUTING,
  79                .priority = NF_IP_PRI_RAW,
  80                .owner = THIS_MODULE,
  81        },
  82        {
  83                .hook = ipt_local_hook,
  84                .pf = NFPROTO_IPV4,
  85                .hooknum = NF_INET_LOCAL_OUT,
  86                .priority = NF_IP_PRI_RAW,
  87                .owner = THIS_MODULE,
  88        },
  89};
  90
  91static int __net_init iptable_raw_net_init(struct net *net)
  92{
  93        /* Register table */
  94        net->ipv4.iptable_raw =
  95                ipt_register_table(net, &packet_raw, &initial_table.repl);
  96        if (IS_ERR(net->ipv4.iptable_raw))
  97                return PTR_ERR(net->ipv4.iptable_raw);
  98        return 0;
  99}
 100
 101static void __net_exit iptable_raw_net_exit(struct net *net)
 102{
 103        ipt_unregister_table(net->ipv4.iptable_raw);
 104}
 105
 106static struct pernet_operations iptable_raw_net_ops = {
 107        .init = iptable_raw_net_init,
 108        .exit = iptable_raw_net_exit,
 109};
 110
 111static int __init iptable_raw_init(void)
 112{
 113        int ret;
 114
 115        ret = register_pernet_subsys(&iptable_raw_net_ops);
 116        if (ret < 0)
 117                return ret;
 118
 119        /* Register hooks */
 120        ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
 121        if (ret < 0)
 122                goto cleanup_table;
 123
 124        return ret;
 125
 126 cleanup_table:
 127        unregister_pernet_subsys(&iptable_raw_net_ops);
 128        return ret;
 129}
 130
 131static void __exit iptable_raw_fini(void)
 132{
 133        nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
 134        unregister_pernet_subsys(&iptable_raw_net_ops);
 135}
 136
 137module_init(iptable_raw_init);
 138module_exit(iptable_raw_fini);
 139MODULE_LICENSE("GPL");
 140