~ubuntu-branches/ubuntu/quantal/xtables-addons/quantal

« back to all changes in this revision

Viewing changes to extensions/ipset-4/ipset_ipportiphash.c

  • Committer: Bazaar Package Importer
  • Author(s): Pierre Chifflier
  • Date: 2011-01-13 14:21:34 UTC
  • mfrom: (1.3.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110113142134-l7au0iehf1q1wq7k
Tags: 1.32-1
* Imported Upstream version 1.32 (Closes: #593521)
  - Build on recent kernels (Closes: #590140)
* Add temporary hack to fix configure with --without-kbuild flag
* Fix clean target

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2008 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
 
2
 *
 
3
 * This program is free software; you can redistribute it and/or modify   
 
4
 * it under the terms of the GNU General Public License as published by   
 
5
 * the Free Software Foundation; either version 2 of the License, or      
 
6
 * (at your option) any later version.                                    
 
7
 *                                                                         
 
8
 * This program is distributed in the hope that it will be useful,        
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of         
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
 
11
 * GNU General Public License for more details.                           
 
12
 *                                                                         
 
13
 * You should have received a copy of the GNU General Public License      
 
14
 * along with this program; if not, write to the Free Software            
 
15
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
16
 */
 
17
 
 
18
#include <limits.h>                     /* UINT_MAX */
 
19
#include <stdio.h>                      /* *printf */
 
20
#include <string.h>                     /* mem*, str* */
 
21
 
 
22
#include "ipset.h"
 
23
 
 
24
#include "ip_set_ipportiphash.h"
 
25
 
 
26
#define OPT_CREATE_HASHSIZE     0x01U
 
27
#define OPT_CREATE_PROBES       0x02U
 
28
#define OPT_CREATE_RESIZE       0x04U
 
29
#define OPT_CREATE_NETWORK      0x08U
 
30
#define OPT_CREATE_FROM         0x10U
 
31
#define OPT_CREATE_TO           0x20U
 
32
 
 
33
/* Initialize the create. */
 
34
static void
 
35
ipportiphash_create_init(void *data)
 
36
{
 
37
        struct ip_set_req_ipportiphash_create *mydata = data;
 
38
 
 
39
        DP("create INIT");
 
40
 
 
41
        /* Default create parameters */ 
 
42
        mydata->hashsize = IP_NF_SET_HASHSIZE;
 
43
        mydata->probes = 8;
 
44
        mydata->resize = 50;
 
45
}
 
46
 
 
47
/* Function which parses command options; returns true if it ate an option */
 
48
static int
 
49
ipportiphash_create_parse(int c, char *argv[] UNUSED, void *data,
 
50
                          unsigned *flags)
 
51
{
 
52
        struct ip_set_req_ipportiphash_create *mydata = data;
 
53
        ip_set_ip_t value;
 
54
 
 
55
        DP("create_parse");
 
56
 
 
57
        switch (c) {
 
58
        case '1':
 
59
 
 
60
                if (string_to_number(optarg, 1, UINT_MAX - 1, &mydata->hashsize))
 
61
                        exit_error(PARAMETER_PROBLEM, "Invalid hashsize `%s' specified", optarg);
 
62
 
 
63
                *flags |= OPT_CREATE_HASHSIZE;
 
64
 
 
65
                DP("--hashsize %u", mydata->hashsize);
 
66
                
 
67
                break;
 
68
 
 
69
        case '2':
 
70
 
 
71
                if (string_to_number(optarg, 1, 65535, &value))
 
72
                        exit_error(PARAMETER_PROBLEM, "Invalid probes `%s' specified", optarg);
 
73
 
 
74
                mydata->probes = value;
 
75
                *flags |= OPT_CREATE_PROBES;
 
76
 
 
77
                DP("--probes %u", mydata->probes);
 
78
                
 
79
                break;
 
80
 
 
81
        case '3':
 
82
 
 
83
                if (string_to_number(optarg, 0, 65535, &value))
 
84
                        exit_error(PARAMETER_PROBLEM, "Invalid resize `%s' specified", optarg);
 
85
 
 
86
                mydata->resize = value;
 
87
                *flags |= OPT_CREATE_RESIZE;
 
88
 
 
89
                DP("--resize %u", mydata->resize);
 
90
                
 
91
                break;
 
92
 
 
93
        case '4':
 
94
                parse_ip(optarg, &mydata->from);
 
95
 
 
96
                *flags |= OPT_CREATE_FROM;
 
97
 
 
98
                DP("--from %x (%s)", mydata->from,
 
99
                   ip_tostring_numeric(mydata->from));
 
100
 
 
101
                break;
 
102
 
 
103
        case '5':
 
104
                parse_ip(optarg, &mydata->to);
 
105
 
 
106
                *flags |= OPT_CREATE_TO;
 
107
 
 
108
                DP("--to %x (%s)", mydata->to,
 
109
                   ip_tostring_numeric(mydata->to));
 
110
 
 
111
                break;
 
112
 
 
113
        case '6':
 
114
                parse_ipandmask(optarg, &mydata->from, &mydata->to);
 
115
 
 
116
                /* Make to the last of from + mask */
 
117
                if (mydata->to)
 
118
                        mydata->to = mydata->from | ~(mydata->to);
 
119
                else {
 
120
                        mydata->from = 0x00000000;
 
121
                        mydata->to = 0xFFFFFFFF;
 
122
                }
 
123
                *flags |= OPT_CREATE_NETWORK;
 
124
 
 
125
                DP("--network from %x (%s)", 
 
126
                   mydata->from, ip_tostring_numeric(mydata->from));
 
127
                DP("--network to %x (%s)", 
 
128
                   mydata->to, ip_tostring_numeric(mydata->to));
 
129
 
 
130
                break;
 
131
 
 
132
        default:
 
133
                return 0;
 
134
        }
 
135
 
 
136
        return 1;
 
137
}
 
138
 
 
139
/* Final check; exit if not ok. */
 
140
static void
 
141
ipportiphash_create_final(void *data, unsigned int flags)
 
142
{
 
143
        struct ip_set_req_ipportiphash_create *mydata = data;
 
144
 
 
145
#ifdef IPSET_DEBUG
 
146
        DP("hashsize %u probes %u resize %u",
 
147
           mydata->hashsize, mydata->probes, mydata->resize);
 
148
#endif
 
149
 
 
150
        if (flags & OPT_CREATE_NETWORK) {
 
151
                /* --network */
 
152
                if ((flags & OPT_CREATE_FROM) || (flags & OPT_CREATE_TO))
 
153
                        exit_error(PARAMETER_PROBLEM,
 
154
                                   "Can't specify --from or --to with --network\n");
 
155
        } else if (flags & (OPT_CREATE_FROM | OPT_CREATE_TO)) {
 
156
                /* --from --to */
 
157
                if (!(flags & OPT_CREATE_FROM) || !(flags & OPT_CREATE_TO))
 
158
                        exit_error(PARAMETER_PROBLEM,
 
159
                                   "Need to specify both --from and --to\n");
 
160
        } else {
 
161
                exit_error(PARAMETER_PROBLEM,
 
162
                           "Need to specify --from and --to, or --network\n");
 
163
 
 
164
        }
 
165
 
 
166
        DP("from : %x to: %x diff: %x", 
 
167
           mydata->from, mydata->to,
 
168
           mydata->to - mydata->from);
 
169
 
 
170
        if (mydata->from > mydata->to)
 
171
                exit_error(PARAMETER_PROBLEM,
 
172
                           "From can't be higher than to.\n");
 
173
 
 
174
        if (mydata->to - mydata->from > MAX_RANGE)
 
175
                exit_error(PARAMETER_PROBLEM,
 
176
                           "Range too large. Max is %d IPs in range\n",
 
177
                           MAX_RANGE+1);
 
178
}
 
179
 
 
180
/* Create commandline options */
 
181
static const struct option create_opts[] = {
 
182
        {.name = "hashsize",    .has_arg = required_argument,   .val = '1'},
 
183
        {.name = "probes",      .has_arg = required_argument,   .val = '2'},
 
184
        {.name = "resize",      .has_arg = required_argument,   .val = '3'},
 
185
        {.name = "from",        .has_arg = required_argument,   .val = '4'},
 
186
        {.name = "to",          .has_arg = required_argument,   .val = '5'},
 
187
        {.name = "network",     .has_arg = required_argument,   .val = '6'},
 
188
        {NULL},
 
189
};
 
190
 
 
191
/* Add, del, test parser */
 
192
static ip_set_ip_t
 
193
ipportiphash_adt_parser(int cmd UNUSED, const char *arg, void *data)
 
194
{
 
195
        struct ip_set_req_ipportiphash *mydata = data;
 
196
        char *saved = ipset_strdup(arg);
 
197
        char *ptr, *tmp = saved;
 
198
 
 
199
        DP("ipportiphash: %p %p", arg, data);
 
200
 
 
201
        if (((ptr = strchr(tmp, ':')) || (ptr = strchr(tmp, '%'))) && ++warn_once == 1)
 
202
                fprintf(stderr, "Warning: please use ',' separator token between ip,port,ip.\n"
 
203
                                "Next release won't support old separator tokens.\n");
 
204
 
 
205
        ptr = strsep(&tmp, ":%,");
 
206
        parse_ip(ptr, &mydata->ip);
 
207
 
 
208
        if (!tmp)
 
209
                exit_error(PARAMETER_PROBLEM,
 
210
                           "IP address, port and IP address must be specified: ip,port,ip");
 
211
 
 
212
        ptr = strsep(&tmp, ":%,");
 
213
        parse_port(ptr, &mydata->port);
 
214
        if (tmp)
 
215
                parse_ip(tmp, &mydata->ip1);
 
216
        else
 
217
                exit_error(PARAMETER_PROBLEM,
 
218
                           "IP address, port and IP address must be specified: ip,port,ip");
 
219
        if (!(mydata->ip || mydata->port || mydata->ip1))
 
220
                exit_error(PARAMETER_PROBLEM,
 
221
                          "Zero valued IP address, port and IP address `%s' specified", arg);
 
222
        ipset_free(saved);
 
223
        return 1;       
 
224
};
 
225
 
 
226
/*
 
227
 * Print and save
 
228
 */
 
229
 
 
230
static void
 
231
ipportiphash_initheader(struct set *set, const void *data)
 
232
{
 
233
        const struct ip_set_req_ipportiphash_create *header = data;
 
234
        struct ip_set_ipportiphash *map = set->settype->header;
 
235
 
 
236
        memset(map, 0, sizeof(struct ip_set_ipportiphash));
 
237
        map->hashsize = header->hashsize;
 
238
        map->probes = header->probes;
 
239
        map->resize = header->resize;
 
240
        map->first_ip = header->from;
 
241
        map->last_ip = header->to;
 
242
}
 
243
 
 
244
static void
 
245
ipportiphash_printheader(struct set *set, unsigned options)
 
246
{
 
247
        struct ip_set_ipportiphash *mysetdata = set->settype->header;
 
248
 
 
249
        printf(" from: %s", ip_tostring(mysetdata->first_ip, options));
 
250
        printf(" to: %s", ip_tostring(mysetdata->last_ip, options));
 
251
        printf(" hashsize: %u", mysetdata->hashsize);
 
252
        printf(" probes: %u", mysetdata->probes);
 
253
        printf(" resize: %u\n", mysetdata->resize);
 
254
}
 
255
 
 
256
static void
 
257
ipportiphash_printips(struct set *set, void *data, u_int32_t len,
 
258
                      unsigned options, char dont_align)
 
259
{
 
260
        struct ip_set_ipportiphash *mysetdata = set->settype->header;
 
261
        size_t offset = 0;
 
262
        struct ipportip *ipptr;
 
263
        ip_set_ip_t ip;
 
264
        uint16_t port;
 
265
 
 
266
        while (offset < len) {
 
267
                ipptr = data + offset;
 
268
                ip = (ipptr->ip>>16) + mysetdata->first_ip;
 
269
                port = (uint16_t) ipptr->ip;
 
270
                printf("%s,%s,", 
 
271
                       ip_tostring(ip, options),
 
272
                       port_tostring(port, options));
 
273
                printf("%s\n", 
 
274
                       ip_tostring(ipptr->ip1, options));
 
275
                offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
 
276
        }
 
277
}
 
278
 
 
279
static void
 
280
ipportiphash_saveheader(struct set *set, unsigned options)
 
281
{
 
282
        struct ip_set_ipportiphash *mysetdata = set->settype->header;
 
283
 
 
284
        printf("-N %s %s --from %s",
 
285
               set->name, set->settype->typename,
 
286
               ip_tostring(mysetdata->first_ip, options));
 
287
        printf(" --to %s",
 
288
               ip_tostring(mysetdata->last_ip, options));
 
289
        printf(" --hashsize %u --probes %u --resize %u\n",
 
290
               mysetdata->hashsize, mysetdata->probes, mysetdata->resize);
 
291
}
 
292
 
 
293
/* Print save for an IP */
 
294
static void
 
295
ipportiphash_saveips(struct set *set, void *data, u_int32_t len,
 
296
                     unsigned options, char dont_align)
 
297
{
 
298
        struct ip_set_ipportiphash *mysetdata = set->settype->header;
 
299
        size_t offset = 0;
 
300
        struct ipportip *ipptr;
 
301
        ip_set_ip_t ip;
 
302
        uint16_t port;
 
303
 
 
304
        while (offset < len) {
 
305
                ipptr = data + offset;
 
306
                ip = (ipptr->ip>>16) + mysetdata->first_ip;
 
307
                port = (uint16_t) ipptr->ip;
 
308
                printf("-A %s %s,%s,", set->name, 
 
309
                       ip_tostring(ip, options),
 
310
                       port_tostring(port, options));
 
311
                printf("%s\n",
 
312
                       ip_tostring(ipptr->ip1, options));
 
313
                offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
 
314
        }
 
315
}
 
316
 
 
317
static void
 
318
ipportiphash_usage(void)
 
319
{
 
320
        printf
 
321
            ("-N set ipportiphash --from IP --to IP\n"
 
322
             "   [--hashsize hashsize] [--probes probes ] [--resize resize]\n"
 
323
             "-N set ipportiphash --network IP/mask\n"
 
324
             "   [--hashsize hashsize] [--probes probes ] [--resize resize]\n"
 
325
             "-A set IP,port,IP\n"
 
326
             "-D set IP,port,IP\n"
 
327
             "-T set IP,port,IP\n");
 
328
}
 
329
 
 
330
static struct settype settype_ipportiphash = {
 
331
        .typename = SETTYPE_NAME,
 
332
        .protocol_version = IP_SET_PROTOCOL_VERSION,
 
333
 
 
334
        /* Create */
 
335
        .create_size = sizeof(struct ip_set_req_ipportiphash_create),
 
336
        .create_init = ipportiphash_create_init,
 
337
        .create_parse = ipportiphash_create_parse,
 
338
        .create_final = ipportiphash_create_final,
 
339
        .create_opts = create_opts,
 
340
 
 
341
        /* Add/del/test */
 
342
        .adt_size = sizeof(struct ip_set_req_ipportiphash),
 
343
        .adt_parser = ipportiphash_adt_parser,
 
344
 
 
345
        /* Printing */
 
346
        .header_size = sizeof(struct ip_set_ipportiphash),
 
347
        .initheader = ipportiphash_initheader,
 
348
        .printheader = ipportiphash_printheader,
 
349
        .printips = ipportiphash_printips,
 
350
        .printips_sorted = ipportiphash_printips,
 
351
        .saveheader = ipportiphash_saveheader,
 
352
        .saveips = ipportiphash_saveips,
 
353
        
 
354
        .usage = ipportiphash_usage,
 
355
};
 
356
 
 
357
CONSTRUCTOR(ipportiphash)
 
358
{
 
359
        settype_register(&settype_ipportiphash);
 
360
 
 
361
}