1
2 /*
3 * Copyright (C) 2012 by Darren Reed.
4 *
5 * See the IPFILTER.LICENCE file for details on licencing.
6 *
7 * $Id$
8 */
9
10 #include <fcntl.h>
11 #include <sys/ioctl.h>
12 #include "ipf.h"
13 #include "netinet/ip_lookup.h"
14 #include "netinet/ip_htable.h"
15
16
17 int
load_hash(iphtable_t * iphp,iphtent_t * list,ioctlfunc_t iocfunc)18 load_hash(iphtable_t *iphp, iphtent_t *list, ioctlfunc_t iocfunc)
19 {
20 iplookupop_t op;
21 iphtable_t iph;
22 iphtent_t *a;
23 size_t size;
24 int n;
25
26 if (pool_open() == -1)
27 return (-1);
28
29 for (n = 0, a = list; a != NULL; a = a->ipe_next)
30 n++;
31
32 bzero((char *)&iph, sizeof(iph));
33 op.iplo_arg = 0;
34 op.iplo_type = IPLT_HASH;
35 op.iplo_unit = iphp->iph_unit;
36 strncpy(op.iplo_name, iphp->iph_name, sizeof(op.iplo_name));
37 if (*op.iplo_name == '\0')
38 op.iplo_arg = IPHASH_ANON;
39 op.iplo_size = sizeof(iph);
40 op.iplo_struct = &iph;
41 iph = *iphp;
42 if (n <= 0)
43 n = 1;
44 if (iphp->iph_size == 0)
45 size = n * 2 - 1;
46 else
47 size = iphp->iph_size;
48 if ((list == NULL) && (size == 1)) {
49 fprintf(stderr,
50 "WARNING: empty hash table %s, recommend setting %s\n",
51 iphp->iph_name, "size to match expected use");
52 }
53 iph.iph_size = size;
54 iph.iph_table = NULL;
55 iph.iph_list = NULL;
56 iph.iph_ref = 0;
57
58 if ((opts & OPT_REMOVE) == 0) {
59 if (pool_ioctl(iocfunc, SIOCLOOKUPADDTABLE, &op))
60 if ((opts & OPT_DONOTHING) == 0) {
61 return (ipf_perror_fd(pool_fd(), iocfunc,
62 "add lookup hash table"));
63 }
64 }
65
66 strncpy(iph.iph_name, op.iplo_name, sizeof(op.iplo_name));
67 strncpy(iphp->iph_name, op.iplo_name, sizeof(op.iplo_name));
68
69 if (opts & OPT_VERBOSE) {
70 iph.iph_table = calloc(size, sizeof(*iph.iph_table));
71 if (iph.iph_table == NULL) {
72 perror("calloc(size, sizeof(*iph.iph_table))");
73 return (-1);
74 }
75 iph.iph_list = list;
76 printhash(&iph, bcopywrap, iph.iph_name, opts, NULL);
77 free(iph.iph_table);
78
79 for (a = list; a != NULL; a = a->ipe_next) {
80 a->ipe_addr.in4_addr = htonl(a->ipe_addr.in4_addr);
81 a->ipe_mask.in4_addr = htonl(a->ipe_mask.in4_addr);
82 }
83 }
84
85 if (opts & OPT_DEBUG)
86 printf("Hash %s:\n", iph.iph_name);
87
88 for (a = list; a != NULL; a = a->ipe_next)
89 load_hashnode(iphp->iph_unit, iph.iph_name, a, 0, iocfunc);
90
91 if ((opts & OPT_REMOVE) != 0) {
92 if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op))
93 if ((opts & OPT_DONOTHING) == 0) {
94 return (ipf_perror_fd(pool_fd(), iocfunc,
95 "delete lookup hash table"));
96 }
97 }
98 return (0);
99 }
100