iptables-1.2.9-2.3.1.src.rpm
[iptables.git] / extensions / libipt_connbytes.c
1 /* Shared library add-on to iptables to add byte tracking support. */
2 #include <stdio.h>
3 #include <netdb.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <getopt.h>
7 #include <iptables.h>
8 #include <linux/netfilter_ipv4/ip_conntrack.h>
9 #include <linux/netfilter_ipv4/ipt_connbytes.h>
10
11 /* Function which prints out usage message. */
12 static void
13 help(void)
14 {
15         printf(
16 "connbytes v%s options:\n"
17 " [!] --connbytes from:[to]\n"
18 "                               Transfered byte range to match\n"
19 "\n", IPTABLES_VERSION);
20 }
21
22 static struct option opts[] = {
23         { "connbytes", 1, 0, '1' },
24         {0}
25 };
26
27 /* Initialize the match. */
28 static void
29 init(struct ipt_entry_match *m, unsigned int *nfcache)
30 {
31         /* Can't cache this */
32         *nfcache |= NFC_UNKNOWN;
33 }
34
35 static void
36 parse_range(const char *arg, struct ipt_connbytes_info *si)
37 {
38         char *colon,*p;
39
40         si->from = strtol(arg,&colon,10);
41         if (*colon != ':') 
42                 exit_error(PARAMETER_PROBLEM, "Bad range `%s'", arg);
43         si->to = strtol(colon+1,&p,10);
44         if (p == colon+1) {
45                 /* second number omited */
46                 si->to = 0xffffffff;
47         }
48         if (si->from > si->to)
49                 exit_error(PARAMETER_PROBLEM, "%lu should be less than %lu", si->from,si->to);
50 }
51
52 /* Function which parses command options; returns true if it
53    ate an option */
54 static int
55 parse(int c, char **argv, int invert, unsigned int *flags,
56       const struct ipt_entry *entry,
57       unsigned int *nfcache,
58       struct ipt_entry_match **match)
59 {
60         struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)(*match)->data;
61         int i;
62
63         switch (c) {
64         case '1':
65                 if (check_inverse(optarg, &invert, optind, 0))
66                         optind++;
67
68                 parse_range(argv[optind-1], sinfo);
69                 if (invert) {
70                         i = sinfo->from;
71                         sinfo->from = sinfo->to;
72                         sinfo->to = i;
73                 }
74                 *flags = 1;
75                 break;
76
77         default:
78                 return 0;
79         }
80
81         return 1;
82 }
83
84 static void final_check(unsigned int flags)
85 {
86         if (!flags)
87                 exit_error(PARAMETER_PROBLEM, "You must specify `--connbytes'");
88 }
89
90 /* Prints out the matchinfo. */
91 static void
92 print(const struct ipt_ip *ip,
93       const struct ipt_entry_match *match,
94       int numeric)
95 {
96         struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)match->data;
97
98         if (sinfo->from > sinfo->to) 
99                 printf("connbytes ! %lu:%lu",sinfo->to,sinfo->from);
100         else
101                 printf("connbytes %lu:%lu",sinfo->from,sinfo->to);
102 }
103
104 /* Saves the matchinfo in parsable form to stdout. */
105 static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
106 {
107         struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)match->data;
108
109         if (sinfo->from > sinfo->to) 
110                 printf("! --connbytes %lu:%lu",sinfo->to,sinfo->from);
111         else
112                 printf("--connbytes %lu:%lu",sinfo->from,sinfo->to);
113 }
114
115 static
116 struct iptables_match state
117 = { NULL,
118     "connbytes",
119     IPTABLES_VERSION,
120     IPT_ALIGN(sizeof(struct ipt_connbytes_info)),
121     IPT_ALIGN(sizeof(struct ipt_connbytes_info)),
122     &help,
123     &init,
124     &parse,
125     &final_check,
126     &print,
127     &save,
128     opts
129 };
130
131 void _init(void)
132 {
133         register_match(&state);
134 }