load_hash.c revision 255332
1145519Sdarrenr/* $FreeBSD: head/contrib/ipfilter/lib/load_hash.c 255332 2013-09-06 23:11:19Z cy $ */ 2145510Sdarrenr 3145510Sdarrenr/* 4255332Scy * Copyright (C) 2012 by Darren Reed. 5145510Sdarrenr * 6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 7145510Sdarrenr * 8255332Scy * $Id$ 9145510Sdarrenr */ 10145510Sdarrenr 11145510Sdarrenr#include <fcntl.h> 12145510Sdarrenr#include <sys/ioctl.h> 13145510Sdarrenr#include "ipf.h" 14145510Sdarrenr#include "netinet/ip_lookup.h" 15145510Sdarrenr#include "netinet/ip_htable.h" 16145510Sdarrenr 17145510Sdarrenr 18255332Scyint 19255332Scyload_hash(iphp, list, iocfunc) 20255332Scy iphtable_t *iphp; 21255332Scy iphtent_t *list; 22255332Scy ioctlfunc_t iocfunc; 23145510Sdarrenr{ 24145510Sdarrenr iplookupop_t op; 25145510Sdarrenr iphtable_t iph; 26145510Sdarrenr iphtent_t *a; 27145510Sdarrenr size_t size; 28145510Sdarrenr int n; 29145510Sdarrenr 30255332Scy if (pool_open() == -1) 31145510Sdarrenr return -1; 32145510Sdarrenr 33145510Sdarrenr for (n = 0, a = list; a != NULL; a = a->ipe_next) 34145510Sdarrenr n++; 35145510Sdarrenr 36255332Scy bzero((char *)&iph, sizeof(iph)); 37145510Sdarrenr op.iplo_arg = 0; 38145510Sdarrenr op.iplo_type = IPLT_HASH; 39145510Sdarrenr op.iplo_unit = iphp->iph_unit; 40145510Sdarrenr strncpy(op.iplo_name, iphp->iph_name, sizeof(op.iplo_name)); 41145510Sdarrenr if (*op.iplo_name == '\0') 42145510Sdarrenr op.iplo_arg = IPHASH_ANON; 43145510Sdarrenr op.iplo_size = sizeof(iph); 44145510Sdarrenr op.iplo_struct = &iph; 45255332Scy iph = *iphp; 46145510Sdarrenr if (n <= 0) 47145510Sdarrenr n = 1; 48145510Sdarrenr if (iphp->iph_size == 0) 49145510Sdarrenr size = n * 2 - 1; 50145510Sdarrenr else 51145510Sdarrenr size = iphp->iph_size; 52145510Sdarrenr if ((list == NULL) && (size == 1)) { 53145510Sdarrenr fprintf(stderr, 54145510Sdarrenr "WARNING: empty hash table %s, recommend setting %s\n", 55145510Sdarrenr iphp->iph_name, "size to match expected use"); 56145510Sdarrenr } 57145510Sdarrenr iph.iph_size = size; 58145510Sdarrenr iph.iph_table = NULL; 59170268Sdarrenr iph.iph_list = NULL; 60145510Sdarrenr iph.iph_ref = 0; 61145510Sdarrenr 62145510Sdarrenr if ((opts & OPT_REMOVE) == 0) { 63255332Scy if (pool_ioctl(iocfunc, SIOCLOOKUPADDTABLE, &op)) 64145510Sdarrenr if ((opts & OPT_DONOTHING) == 0) { 65255332Scy return ipf_perror_fd(pool_fd(), iocfunc, 66255332Scy "add lookup hash table"); 67145510Sdarrenr } 68145510Sdarrenr } 69145510Sdarrenr 70153881Sguido strncpy(iph.iph_name, op.iplo_name, sizeof(op.iplo_name)); 71153881Sguido strncpy(iphp->iph_name, op.iplo_name, sizeof(op.iplo_name)); 72145510Sdarrenr 73145510Sdarrenr if (opts & OPT_VERBOSE) { 74145510Sdarrenr iph.iph_table = calloc(size, sizeof(*iph.iph_table)); 75145510Sdarrenr if (iph.iph_table == NULL) { 76145510Sdarrenr perror("calloc(size, sizeof(*iph.iph_table))"); 77145510Sdarrenr return -1; 78145510Sdarrenr } 79170268Sdarrenr iph.iph_list = list; 80255332Scy printhash(&iph, bcopywrap, iph.iph_name, opts, NULL); 81145510Sdarrenr free(iph.iph_table); 82145510Sdarrenr 83145510Sdarrenr for (a = list; a != NULL; a = a->ipe_next) { 84145510Sdarrenr a->ipe_addr.in4_addr = htonl(a->ipe_addr.in4_addr); 85145510Sdarrenr a->ipe_mask.in4_addr = htonl(a->ipe_mask.in4_addr); 86145510Sdarrenr } 87145510Sdarrenr } 88145510Sdarrenr 89145510Sdarrenr if (opts & OPT_DEBUG) 90145510Sdarrenr printf("Hash %s:\n", iph.iph_name); 91145510Sdarrenr 92145510Sdarrenr for (a = list; a != NULL; a = a->ipe_next) 93255332Scy load_hashnode(iphp->iph_unit, iph.iph_name, a, 0, iocfunc); 94145510Sdarrenr 95145510Sdarrenr if ((opts & OPT_REMOVE) != 0) { 96255332Scy if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op)) 97145510Sdarrenr if ((opts & OPT_DONOTHING) == 0) { 98255332Scy return ipf_perror_fd(pool_fd(), iocfunc, 99255332Scy "delete lookup hash table"); 100145510Sdarrenr } 101145510Sdarrenr } 102145510Sdarrenr return 0; 103145510Sdarrenr} 104