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 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