]> git.ipfire.org Git - thirdparty/ipset.git/blob - lib/data.c
ipset 7.19 released
[thirdparty/ipset.git] / lib / data.c
1 /* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@netfilter.org)
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 version 2 as
5 * published by the Free Software Foundation.
6 */
7 #include <assert.h> /* assert */
8 #include <arpa/inet.h> /* ntoh* */
9 #include <net/ethernet.h> /* ETH_ALEN */
10 #include <net/if.h> /* IFNAMSIZ */
11 #include <stdlib.h> /* malloc, free */
12 #include <string.h> /* memset */
13
14 #include <libipset/linux_ip_set.h> /* IPSET_MAXNAMELEN */
15 #include <libipset/debug.h> /* D() */
16 #include <libipset/types.h> /* struct ipset_type */
17 #include <libipset/utils.h> /* inXcpy */
18 #include <libipset/data.h> /* prototypes */
19
20 /* Internal data structure to hold
21 * a) input data entered by the user or
22 * b) data received from kernel
23 *
24 * We always store the data in host order, *except* IP addresses.
25 */
26
27 struct ipset_data {
28 /* Option bits: which fields are set */
29 uint64_t bits;
30 /* Option bits: which options are ignored */
31 uint64_t ignored;
32 /* Setname */
33 char setname[IPSET_MAXNAMELEN];
34 /* Set type */
35 const struct ipset_type *type;
36 /* Common CADT options */
37 uint8_t cidr;
38 uint8_t family;
39 uint32_t flags; /* command level flags */
40 uint32_t cadt_flags; /* data level flags */
41 uint32_t timeout;
42 union nf_inet_addr ip;
43 union nf_inet_addr ip_to;
44 uint32_t mark;
45 uint16_t port;
46 uint16_t port_to;
47 uint16_t index;
48 union {
49 /* RENAME/SWAP */
50 char setname2[IPSET_MAXNAMELEN];
51 /* CREATE/LIST/SAVE */
52 struct {
53 uint8_t bucketsize;
54 uint8_t resize;
55 uint8_t netmask;
56 union nf_inet_addr bitmask;
57 uint32_t hashsize;
58 uint32_t maxelem;
59 uint32_t markmask;
60 uint32_t initval;
61 uint32_t size;
62 /* Filled out by kernel */
63 uint32_t references;
64 uint32_t elements;
65 uint32_t memsize;
66 char typename[IPSET_MAXNAMELEN];
67 uint8_t revision_min;
68 uint8_t revision;
69 } create;
70 /* ADT/LIST/SAVE */
71 struct {
72 union nf_inet_addr ip2;
73 union nf_inet_addr ip2_to;
74 uint8_t cidr2;
75 uint8_t proto;
76 char ether[ETH_ALEN];
77 char name[IPSET_MAXNAMELEN];
78 char nameref[IPSET_MAXNAMELEN];
79 char iface[IFNAMSIZ];
80 uint64_t packets;
81 uint64_t bytes;
82 char comment[IPSET_MAX_COMMENT_SIZE+1];
83 uint64_t skbmark;
84 uint32_t skbprio;
85 uint16_t skbqueue;
86 } adt;
87 };
88 };
89
90 static void
91 copy_addr(uint8_t family, union nf_inet_addr *ip, const void *value)
92 {
93 if (family == NFPROTO_IPV4)
94 in4cpy(&ip->in, value);
95 else
96 in6cpy(&ip->in6, value);
97 }
98
99 /**
100 * ipset_strlcpy - copy the string from src to dst
101 * @dst: the target string buffer
102 * @src: the source string buffer
103 * @len: the length of bytes to copy, including the terminating null byte.
104 *
105 * Copy the string from src to destination, but at most len bytes are
106 * copied. The target is unconditionally terminated by the null byte.
107 */
108 void
109 ipset_strlcpy(char *dst, const char *src, size_t len)
110 {
111 assert(dst);
112 assert(src);
113
114 strncpy(dst, src, len);
115 dst[len - 1] = '\0';
116 }
117
118 /**
119 * ipset_strlcat - concatenate the string from src to the end of dst
120 * @dst: the target string buffer
121 * @src: the source string buffer
122 * @len: the length of bytes to concat, including the terminating null byte.
123 *
124 * Cooncatenate the string in src to destination, but at most len bytes are
125 * copied. The target is unconditionally terminated by the null byte.
126 */
127 void
128 ipset_strlcat(char *dst, const char *src, size_t len)
129 {
130 assert(dst);
131 assert(src);
132
133 strncat(dst, src, len);
134 dst[len - 1] = '\0';
135 }
136
137 /**
138 * ipset_data_flags_test - test option bits in the data blob
139 * @data: data blob
140 * @flags: the option flags to test
141 *
142 * Returns true if the options are already set in the data blob.
143 */
144 bool
145 ipset_data_flags_test(const struct ipset_data *data, uint64_t flags)
146 {
147 assert(data);
148 return !!(data->bits & flags);
149 }
150
151 /**
152 * ipset_data_flags_set - set option bits in the data blob
153 * @data: data blob
154 * @flags: the option flags to set
155 *
156 * The function sets the flags in the data blob so that
157 * the corresponding fields are regarded as if filled with proper data.
158 */
159 void
160 ipset_data_flags_set(struct ipset_data *data, uint64_t flags)
161 {
162 assert(data);
163 data->bits |= flags;
164 }
165
166 /**
167 * ipset_data_flags_unset - unset option bits in the data blob
168 * @data: data blob
169 * @flags: the option flags to unset
170 *
171 * The function unsets the flags in the data blob.
172 * This is the quick way to clear specific fields.
173 */
174 void
175 ipset_data_flags_unset(struct ipset_data *data, uint64_t flags)
176 {
177 assert(data);
178 data->bits &= ~flags;
179 }
180
181 #define flag_type_attr(data, opt, flag) \
182 do { \
183 data->flags |= flag; \
184 opt = IPSET_OPT_FLAGS; \
185 } while (0)
186
187 #define cadt_flag_type_attr(data, opt, flag) \
188 do { \
189 data->cadt_flags |= flag; \
190 opt = IPSET_OPT_CADT_FLAGS; \
191 } while (0)
192
193 /**
194 * ipset_data_ignored - test and set ignored bits in the data blob
195 * @data: data blob
196 * @flags: the option flag to be ignored
197 *
198 * Returns true if the option was already ignored.
199 */
200 bool
201 ipset_data_ignored(struct ipset_data *data, enum ipset_opt opt)
202 {
203 bool ignored;
204 assert(data);
205
206 ignored = data->ignored & IPSET_FLAG(opt);
207 data->ignored |= IPSET_FLAG(opt);
208
209 return ignored;
210 }
211
212 /**
213 * ipset_data_test_ignored - test ignored bits in the data blob
214 * @data: data blob
215 * @flags: the option flag to be tested
216 *
217 * Returns true if the option is ignored.
218 */
219 bool
220 ipset_data_test_ignored(struct ipset_data *data, enum ipset_opt opt)
221 {
222 assert(data);
223
224 return data->ignored & IPSET_FLAG(opt);
225 }
226
227 /**
228 * ipset_data_set - put data into the data blob
229 * @data: data blob
230 * @opt: the option kind of the data
231 * @value: the value of the data
232 *
233 * Put a given kind of data into the data blob and mark the
234 * option kind as already set in the blob.
235 *
236 * Returns 0 on success or a negative error code.
237 */
238 int
239 ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value)
240 {
241 assert(data);
242 assert(opt != IPSET_OPT_NONE);
243 assert(value);
244
245 switch (opt) {
246 /* Common ones */
247 case IPSET_SETNAME:
248 ipset_strlcpy(data->setname, value, IPSET_MAXNAMELEN);
249 break;
250 case IPSET_OPT_TYPE:
251 data->type = value;
252 break;
253 case IPSET_OPT_FAMILY:
254 data->family = *(const uint8_t *) value;
255 data->ignored &= ~IPSET_FLAG(IPSET_OPT_FAMILY);
256 D("family set to %u", data->family);
257 break;
258 /* CADT options */
259 case IPSET_OPT_IP:
260 if (!(data->family == NFPROTO_IPV4 ||
261 data->family == NFPROTO_IPV6))
262 return -1;
263 copy_addr(data->family, &data->ip, value);
264 break;
265 case IPSET_OPT_IP_TO:
266 if (!(data->family == NFPROTO_IPV4 ||
267 data->family == NFPROTO_IPV6))
268 return -1;
269 copy_addr(data->family, &data->ip_to, value);
270 break;
271 case IPSET_OPT_CIDR:
272 data->cidr = *(const uint8_t *) value;
273 break;
274 case IPSET_OPT_MARK:
275 data->mark = *(const uint32_t *) value;
276 break;
277 case IPSET_OPT_PORT:
278 data->port = *(const uint16_t *) value;
279 break;
280 case IPSET_OPT_PORT_TO:
281 data->port_to = *(const uint16_t *) value;
282 break;
283 case IPSET_OPT_TIMEOUT:
284 data->timeout = *(const uint32_t *) value;
285 break;
286 case IPSET_OPT_INDEX:
287 data->index = *(const uint16_t *) value;
288 break;
289 /* Create-specific options */
290 case IPSET_OPT_INITVAL:
291 data->create.initval = *(const uint32_t *) value;
292 break;
293 case IPSET_OPT_HASHSIZE:
294 data->create.hashsize = *(const uint32_t *) value;
295 break;
296 case IPSET_OPT_MAXELEM:
297 data->create.maxelem = *(const uint32_t *) value;
298 break;
299 case IPSET_OPT_MARKMASK:
300 data->create.markmask = *(const uint32_t *) value;
301 break;
302 case IPSET_OPT_NETMASK:
303 data->create.netmask = *(const uint8_t *) value;
304 break;
305 case IPSET_OPT_BITMASK:
306 if (!(data->family == NFPROTO_IPV4 ||
307 data->family == NFPROTO_IPV6))
308 return -1;
309 copy_addr(data->family, &data->create.bitmask, value);
310 break;
311 case IPSET_OPT_BUCKETSIZE:
312 data->create.bucketsize = *(const uint8_t *) value;
313 break;
314 case IPSET_OPT_RESIZE:
315 data->create.resize = *(const uint8_t *) value;
316 break;
317 case IPSET_OPT_SIZE:
318 data->create.size = *(const uint32_t *) value;
319 break;
320 case IPSET_OPT_COUNTERS:
321 cadt_flag_type_attr(data, opt, IPSET_FLAG_WITH_COUNTERS);
322 break;
323 case IPSET_OPT_CREATE_COMMENT:
324 cadt_flag_type_attr(data, opt, IPSET_FLAG_WITH_COMMENT);
325 break;
326 case IPSET_OPT_FORCEADD:
327 cadt_flag_type_attr(data, opt, IPSET_FLAG_WITH_FORCEADD);
328 break;
329 case IPSET_OPT_SKBINFO:
330 cadt_flag_type_attr(data, opt, IPSET_FLAG_WITH_SKBINFO);
331 break;
332 /* Create-specific options, filled out by the kernel */
333 case IPSET_OPT_ELEMENTS:
334 data->create.elements = *(const uint32_t *) value;
335 break;
336 case IPSET_OPT_REFERENCES:
337 data->create.references = *(const uint32_t *) value;
338 break;
339 case IPSET_OPT_MEMSIZE:
340 data->create.memsize = *(const uint32_t *) value;
341 break;
342 /* Create-specific options, type */
343 case IPSET_OPT_TYPENAME:
344 ipset_strlcpy(data->create.typename, value,
345 IPSET_MAXNAMELEN);
346 break;
347 case IPSET_OPT_REVISION:
348 data->create.revision = *(const uint8_t *) value;
349 break;
350 case IPSET_OPT_REVISION_MIN:
351 data->create.revision_min = *(const uint8_t *) value;
352 break;
353 /* ADT-specific options */
354 case IPSET_OPT_ETHER:
355 memcpy(data->adt.ether, value, ETH_ALEN);
356 break;
357 case IPSET_OPT_NAME:
358 ipset_strlcpy(data->adt.name, value, IPSET_MAXNAMELEN);
359 break;
360 case IPSET_OPT_NAMEREF:
361 ipset_strlcpy(data->adt.nameref, value, IPSET_MAXNAMELEN);
362 break;
363 case IPSET_OPT_IP2:
364 if (!(data->family == NFPROTO_IPV4 ||
365 data->family == NFPROTO_IPV6))
366 return -1;
367 copy_addr(data->family, &data->adt.ip2, value);
368 break;
369 case IPSET_OPT_IP2_TO:
370 if (!(data->family == NFPROTO_IPV4 ||
371 data->family == NFPROTO_IPV6))
372 return -1;
373 copy_addr(data->family, &data->adt.ip2_to, value);
374 break;
375 case IPSET_OPT_CIDR2:
376 data->adt.cidr2 = *(const uint8_t *) value;
377 break;
378 case IPSET_OPT_PROTO:
379 data->adt.proto = *(const uint8_t *) value;
380 break;
381 case IPSET_OPT_IFACE:
382 ipset_strlcpy(data->adt.iface, value, IFNAMSIZ);
383 break;
384 case IPSET_OPT_PACKETS:
385 data->adt.packets = *(const uint64_t *) value;
386 break;
387 case IPSET_OPT_BYTES:
388 data->adt.bytes = *(const uint64_t *) value;
389 break;
390 case IPSET_OPT_ADT_COMMENT:
391 ipset_strlcpy(data->adt.comment, value,
392 IPSET_MAX_COMMENT_SIZE + 1);
393 break;
394 case IPSET_OPT_SKBMARK:
395 data->adt.skbmark = *(const uint64_t *) value;
396 break;
397 case IPSET_OPT_SKBPRIO:
398 data->adt.skbprio = *(const uint32_t *) value;
399 break;
400 case IPSET_OPT_SKBQUEUE:
401 data->adt.skbqueue = *(const uint16_t *) value;
402 break;
403 /* Swap/rename */
404 case IPSET_OPT_SETNAME2:
405 ipset_strlcpy(data->setname2, value, IPSET_MAXNAMELEN);
406 break;
407 /* flags */
408 case IPSET_OPT_EXIST:
409 flag_type_attr(data, opt, IPSET_FLAG_EXIST);
410 break;
411 case IPSET_OPT_BEFORE:
412 cadt_flag_type_attr(data, opt, IPSET_FLAG_BEFORE);
413 break;
414 case IPSET_OPT_PHYSDEV:
415 cadt_flag_type_attr(data, opt, IPSET_FLAG_PHYSDEV);
416 break;
417 case IPSET_OPT_NOMATCH:
418 cadt_flag_type_attr(data, opt, IPSET_FLAG_NOMATCH);
419 break;
420 case IPSET_OPT_IFACE_WILDCARD:
421 cadt_flag_type_attr(data, opt, IPSET_FLAG_IFACE_WILDCARD);
422 break;
423 case IPSET_OPT_FLAGS:
424 data->flags = *(const uint32_t *)value;
425 break;
426 case IPSET_OPT_CADT_FLAGS:
427 data->cadt_flags = *(const uint32_t *)value;
428 if (data->cadt_flags & IPSET_FLAG_BEFORE)
429 ipset_data_flags_set(data,
430 IPSET_FLAG(IPSET_OPT_BEFORE));
431 if (data->cadt_flags & IPSET_FLAG_PHYSDEV)
432 ipset_data_flags_set(data,
433 IPSET_FLAG(IPSET_OPT_PHYSDEV));
434 if (data->cadt_flags & IPSET_FLAG_NOMATCH)
435 ipset_data_flags_set(data,
436 IPSET_FLAG(IPSET_OPT_NOMATCH));
437 if (data->cadt_flags & IPSET_FLAG_WITH_COUNTERS)
438 ipset_data_flags_set(data,
439 IPSET_FLAG(IPSET_OPT_COUNTERS));
440 if (data->cadt_flags & IPSET_FLAG_WITH_COMMENT)
441 ipset_data_flags_set(data,
442 IPSET_FLAG(IPSET_OPT_CREATE_COMMENT));
443 if (data->cadt_flags & IPSET_FLAG_WITH_SKBINFO)
444 ipset_data_flags_set(data,
445 IPSET_FLAG(IPSET_OPT_SKBINFO));
446 if (data->cadt_flags & IPSET_FLAG_IFACE_WILDCARD)
447 ipset_data_flags_set(data,
448 IPSET_FLAG(IPSET_OPT_IFACE_WILDCARD));
449 break;
450 default:
451 return -1;
452 };
453
454 ipset_data_flags_set(data, IPSET_FLAG(opt));
455 return 0;
456 }
457
458 /**
459 * ipset_data_get - get data from the data blob
460 * @data: data blob
461 * @opt: option kind of the requested data
462 *
463 * Returns the pointer to the requested kind of data from the data blob
464 * if it is set. If the option kind is not set or is an unknown type,
465 * NULL is returned.
466 */
467 const void *
468 ipset_data_get(const struct ipset_data *data, enum ipset_opt opt)
469 {
470 assert(data);
471 assert(opt != IPSET_OPT_NONE);
472
473 if (!(opt == IPSET_OPT_TYPENAME || ipset_data_test(data, opt)))
474 return NULL;
475
476 switch (opt) {
477 /* Common ones */
478 case IPSET_SETNAME:
479 return data->setname;
480 case IPSET_OPT_TYPE:
481 return data->type;
482 case IPSET_OPT_TYPENAME:
483 if (ipset_data_test(data, IPSET_OPT_TYPE))
484 return data->type->name;
485 else if (ipset_data_test(data, IPSET_OPT_TYPENAME))
486 return data->create.typename;
487 return NULL;
488 case IPSET_OPT_FAMILY:
489 return &data->family;
490 /* CADT options */
491 case IPSET_OPT_IP:
492 return &data->ip;
493 case IPSET_OPT_IP_TO:
494 return &data->ip_to;
495 case IPSET_OPT_CIDR:
496 return &data->cidr;
497 case IPSET_OPT_MARK:
498 return &data->mark;
499 case IPSET_OPT_PORT:
500 return &data->port;
501 case IPSET_OPT_PORT_TO:
502 return &data->port_to;
503 case IPSET_OPT_TIMEOUT:
504 return &data->timeout;
505 case IPSET_OPT_INDEX:
506 return &data->index;
507 /* Create-specific options */
508 case IPSET_OPT_INITVAL:
509 return &data->create.initval;
510 case IPSET_OPT_HASHSIZE:
511 return &data->create.hashsize;
512 case IPSET_OPT_MAXELEM:
513 return &data->create.maxelem;
514 case IPSET_OPT_MARKMASK:
515 return &data->create.markmask;
516 case IPSET_OPT_NETMASK:
517 return &data->create.netmask;
518 case IPSET_OPT_BITMASK:
519 return &data->create.bitmask;
520 case IPSET_OPT_BUCKETSIZE:
521 return &data->create.bucketsize;
522 case IPSET_OPT_RESIZE:
523 return &data->create.resize;
524 case IPSET_OPT_SIZE:
525 return &data->create.size;
526 /* Create-specific options, filled out by the kernel */
527 case IPSET_OPT_ELEMENTS:
528 return &data->create.elements;
529 case IPSET_OPT_REFERENCES:
530 return &data->create.references;
531 case IPSET_OPT_MEMSIZE:
532 return &data->create.memsize;
533 /* Create-specific options, TYPE */
534 case IPSET_OPT_REVISION:
535 return &data->create.revision;
536 case IPSET_OPT_REVISION_MIN:
537 return &data->create.revision_min;
538 /* ADT-specific options */
539 case IPSET_OPT_ETHER:
540 return data->adt.ether;
541 case IPSET_OPT_NAME:
542 return data->adt.name;
543 case IPSET_OPT_NAMEREF:
544 return data->adt.nameref;
545 case IPSET_OPT_IP2:
546 return &data->adt.ip2;
547 case IPSET_OPT_IP2_TO:
548 return &data->adt.ip2_to;
549 case IPSET_OPT_CIDR2:
550 return &data->adt.cidr2;
551 case IPSET_OPT_PROTO:
552 return &data->adt.proto;
553 case IPSET_OPT_IFACE:
554 return &data->adt.iface;
555 case IPSET_OPT_PACKETS:
556 return &data->adt.packets;
557 case IPSET_OPT_BYTES:
558 return &data->adt.bytes;
559 case IPSET_OPT_ADT_COMMENT:
560 return &data->adt.comment;
561 case IPSET_OPT_SKBMARK:
562 return &data->adt.skbmark;
563 case IPSET_OPT_SKBPRIO:
564 return &data->adt.skbprio;
565 case IPSET_OPT_SKBQUEUE:
566 return &data->adt.skbqueue;
567 /* Swap/rename */
568 case IPSET_OPT_SETNAME2:
569 return data->setname2;
570 /* flags */
571 case IPSET_OPT_FLAGS:
572 case IPSET_OPT_EXIST:
573 return &data->flags;
574 case IPSET_OPT_CADT_FLAGS:
575 case IPSET_OPT_BEFORE:
576 case IPSET_OPT_PHYSDEV:
577 case IPSET_OPT_NOMATCH:
578 case IPSET_OPT_COUNTERS:
579 case IPSET_OPT_CREATE_COMMENT:
580 case IPSET_OPT_FORCEADD:
581 case IPSET_OPT_SKBINFO:
582 case IPSET_OPT_IFACE_WILDCARD:
583 return &data->cadt_flags;
584 default:
585 return NULL;
586 }
587 }
588
589 /**
590 * ipset_data_sizeof - calculates the size of the data type
591 * @opt: option kind of the data
592 * @family: INET family
593 *
594 * Returns the size required to store the given data type.
595 */
596 size_t
597 ipset_data_sizeof(enum ipset_opt opt, uint8_t family)
598 {
599 assert(opt != IPSET_OPT_NONE);
600
601 switch (opt) {
602 case IPSET_OPT_IP:
603 case IPSET_OPT_IP_TO:
604 case IPSET_OPT_IP2:
605 case IPSET_OPT_IP2_TO:
606 case IPSET_OPT_BITMASK:
607 return family == NFPROTO_IPV4 ? sizeof(uint32_t)
608 : sizeof(struct in6_addr);
609 case IPSET_OPT_MARK:
610 return sizeof(uint32_t);
611 case IPSET_OPT_PORT:
612 case IPSET_OPT_PORT_TO:
613 case IPSET_OPT_SKBQUEUE:
614 case IPSET_OPT_INDEX:
615 return sizeof(uint16_t);
616 case IPSET_SETNAME:
617 case IPSET_OPT_NAME:
618 case IPSET_OPT_NAMEREF:
619 return IPSET_MAXNAMELEN;
620 case IPSET_OPT_TIMEOUT:
621 case IPSET_OPT_INITVAL:
622 case IPSET_OPT_HASHSIZE:
623 case IPSET_OPT_MAXELEM:
624 case IPSET_OPT_MARKMASK:
625 case IPSET_OPT_SIZE:
626 case IPSET_OPT_ELEMENTS:
627 case IPSET_OPT_REFERENCES:
628 case IPSET_OPT_MEMSIZE:
629 case IPSET_OPT_SKBPRIO:
630 return sizeof(uint32_t);
631 case IPSET_OPT_PACKETS:
632 case IPSET_OPT_BYTES:
633 case IPSET_OPT_SKBMARK:
634 return sizeof(uint64_t);
635 case IPSET_OPT_CIDR:
636 case IPSET_OPT_CIDR2:
637 case IPSET_OPT_NETMASK:
638 case IPSET_OPT_BUCKETSIZE:
639 case IPSET_OPT_RESIZE:
640 case IPSET_OPT_PROTO:
641 return sizeof(uint8_t);
642 case IPSET_OPT_ETHER:
643 return ETH_ALEN;
644 /* Flags doesn't counted once :-( */
645 case IPSET_OPT_BEFORE:
646 case IPSET_OPT_PHYSDEV:
647 case IPSET_OPT_NOMATCH:
648 case IPSET_OPT_COUNTERS:
649 case IPSET_OPT_FORCEADD:
650 case IPSET_OPT_IFACE_WILDCARD:
651 return sizeof(uint32_t);
652 case IPSET_OPT_ADT_COMMENT:
653 return IPSET_MAX_COMMENT_SIZE + 1;
654 default:
655 return 0;
656 };
657 }
658
659 /**
660 * ipset_setname - return the name of the set from the data blob
661 * @data: data blob
662 *
663 * Return the name of the set from the data blob or NULL if the
664 * name not set yet.
665 */
666 const char *
667 ipset_data_setname(const struct ipset_data *data)
668 {
669 assert(data);
670 return ipset_data_test(data, IPSET_SETNAME) ? data->setname : NULL;
671 }
672
673 /**
674 * ipset_family - return the INET family of the set from the data blob
675 * @data: data blob
676 *
677 * Return the INET family supported by the set from the data blob.
678 * If the family is not set yet, NFPROTO_UNSPEC is returned.
679 */
680 uint8_t
681 ipset_data_family(const struct ipset_data *data)
682 {
683 assert(data);
684 return ipset_data_test(data, IPSET_OPT_FAMILY)
685 ? data->family : NFPROTO_UNSPEC;
686 }
687
688 /**
689 * ipset_data_cidr - return the value of IPSET_OPT_CIDR
690 * @data: data blob
691 *
692 * Return the value of IPSET_OPT_CIDR stored in the data blob.
693 * If it is not set, then the returned value corresponds to
694 * the default one according to the family type or zero.
695 */
696 uint8_t
697 ipset_data_cidr(const struct ipset_data *data)
698 {
699 assert(data);
700 return ipset_data_test(data, IPSET_OPT_CIDR) ? data->cidr :
701 data->family == NFPROTO_IPV4 ? 32 :
702 data->family == NFPROTO_IPV6 ? 128 : 0;
703 }
704
705 /**
706 * ipset_flags - return which fields are set in the data blob
707 * @data: data blob
708 *
709 * Returns the value of the bit field which elements are set.
710 */
711 uint64_t
712 ipset_data_flags(const struct ipset_data *data)
713 {
714 assert(data);
715 return data->bits;
716 }
717
718 /**
719 * ipset_data_reset - reset the data blob to unset
720 * @data: data blob
721 *
722 * Resets the data blob to the unset state for every field.
723 */
724 void
725 ipset_data_reset(struct ipset_data *data)
726 {
727 assert(data);
728 memset(data, 0, sizeof(*data));
729 }
730
731 /**
732 * ipset_data_init - create a new data blob
733 *
734 * Return the new data blob initialized to empty. In case of
735 * an error, NULL is retured.
736 */
737 struct ipset_data *
738 ipset_data_init(void)
739 {
740 return calloc(1, sizeof(struct ipset_data));
741 }
742
743 /**
744 * ipset_data_fini - release a data blob created by ipset_data_init
745 *
746 * Release the data blob created by ipset_data_init previously.
747 */
748 void
749 ipset_data_fini(struct ipset_data *data)
750 {
751 assert(data);
752 free(data);
753 }