blob: abc37be033969a42b5c0de1ed9481aea0c4b63eb [file] [log] [blame]
Martin Devera766113a2003-06-19 12:23:37 +00001/* 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. */
12static void
13help(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
22static struct option opts[] = {
23 { "connbytes", 1, 0, '1' },
24 {0}
25};
26
27/* Initialize the match. */
28static void
29init(struct ipt_entry_match *m, unsigned int *nfcache)
30{
31 /* Can't cache this */
32 *nfcache |= NFC_UNKNOWN;
33}
34
35static void
36parse_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 */
54static int
55parse(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
84static 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. */
91static void
92print(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. */
105static 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
115static
116struct 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
131void _init(void)
132{
133 register_match(&state);
134}