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