iptables-1.3.2-20050720
[iptables.git] / extensions / libipt_NETLINK.c
1 /* Provides a NETLINK target, identical to that of the ipchains -o flag */
2 /* AUTHOR: Gianni Tedesco <gianni@ecsc.co.uk> */
3 #include <stdio.h>
4 #include <netdb.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <syslog.h>
8 #include <getopt.h>
9 #include <iptables.h>
10 #include <linux/netfilter_ipv4/ip_tables.h>
11 #include <linux/netfilter_ipv4/ipt_NETLINK.h>
12
13 static void help(void)
14 {
15         printf("NETLINK v%s options:\n"
16                 " --nldrop              Drop the packet too\n"
17                 " --nlmark <number>     Mark the packet\n"
18                 " --nlsize <bytes>      Limit packet size\n",
19                IPTABLES_VERSION);
20 }
21
22 static struct option opts[] = {
23         {"nldrop", 0, 0, 'd'},
24         {"nlmark", 1, 0, 'm'},
25         {"nlsize", 1, 0, 's'},
26         {0}
27 };
28
29 static void init(struct ipt_entry_target *t, unsigned int *nfcache)
30 {
31         struct ipt_nldata *nld = (struct ipt_nldata *) t->data;
32         
33         nld->flags=0;
34         
35 }
36
37 /* Parse command options */
38 static int parse(int c, char **argv, int invert, unsigned int *flags,
39                  const struct ipt_entry *entry,
40                  struct ipt_entry_target **target)
41 {
42         struct ipt_nldata *nld=(struct ipt_nldata *)(*target)->data;
43
44         switch (c) {
45                 case 'd':
46                         if (MASK(*flags, USE_DROP))
47                                 exit_error(PARAMETER_PROBLEM,
48                                 "Can't specify --nldrop twice");
49
50                         if ( check_inverse(optarg, &invert, NULL, 0) ) {
51                                 MASK_UNSET(nld->flags, USE_DROP);
52                         } else {
53                                 MASK_SET(nld->flags, USE_DROP);
54                         }
55
56                         MASK_SET(*flags, USE_DROP);                     
57
58                         break;
59                 case 'm':
60                         if (MASK(*flags, USE_MARK))
61                                 exit_error(PARAMETER_PROBLEM,
62                                 "Can't specify --nlmark twice");
63
64                         if (check_inverse(optarg, &invert, NULL, 0)) {
65                                 MASK_UNSET(nld->flags, USE_MARK);
66                         }else{
67                                 MASK_SET(nld->flags, USE_MARK);
68                                 nld->mark=atoi(optarg);
69                         }
70
71                         MASK_SET(*flags, USE_MARK);
72                         break;
73                 case 's':
74                         if (MASK(*flags, USE_SIZE))
75                                 exit_error(PARAMETER_PROBLEM,
76                                 "Can't specify --nlsize twice");
77
78                         if ( atoi(optarg) <= 0 )
79                                 exit_error(PARAMETER_PROBLEM,
80                                 "--nlsize must be larger than zero");
81                         
82
83                         if (check_inverse(optarg, &invert, NULL, 0)) {
84                                 MASK_UNSET(nld->flags, USE_SIZE);
85                         }else{
86                                 MASK_SET(nld->flags, USE_SIZE);
87                                 nld->size=atoi(optarg);
88                         }
89                         MASK_SET(*flags, USE_SIZE);
90                         break;
91
92                 default:
93                         return 0;
94         }
95         return 1;
96 }
97
98 static void final_check(unsigned int flags)
99 {
100         /* ?? */
101 }
102
103 /* Saves the union ipt_targinfo in parsable form to stdout. */
104 static void save(const struct ipt_ip *ip,
105                  const struct ipt_entry_target *target)
106 {
107         const struct ipt_nldata *nld
108             = (const struct ipt_nldata *) target->data;
109
110         if ( MASK(nld->flags, USE_DROP) )
111                 printf("--nldrop ");
112
113         if ( MASK(nld->flags, USE_MARK) )
114                 printf("--nlmark %i ", nld->mark);
115
116         if ( MASK(nld->flags, USE_SIZE) )
117                 printf("--nlsize %i ", nld->size);              
118 }
119
120 /* Prints out the targinfo. */
121 static void
122 print(const struct ipt_ip *ip,
123       const struct ipt_entry_target *target, int numeric)
124 {
125         const struct ipt_nldata *nld
126             = (const struct ipt_nldata *) target->data;
127
128         if ( MASK(nld->flags, USE_DROP) )
129                 printf("nldrop ");
130
131         if ( MASK(nld->flags, USE_MARK) )
132                 printf("nlmark %i ", nld->mark);
133
134         if ( MASK(nld->flags, USE_SIZE) )
135                 printf("nlsize %i ", nld->size);
136 }
137
138 static struct iptables_target netlink = {
139         .next           = NULL,
140         .name           = "NETLINK",
141         .version        = IPTABLES_VERSION,
142         .size           = IPT_ALIGN(sizeof(struct ipt_nldata)),
143         .userspacesize  = IPT_ALIGN(sizeof(struct ipt_nldata)),
144         .help           = &help,
145         .init           = &init,
146         .parse          = &parse,
147         .final_check    = &final_check,
148         .print          = &print,
149         .save           = &save,
150         .extra_opts     = opts
151 };
152
153 void _init(void)
154 {
155         register_target(&netlink);
156 }
157