diff options
Diffstat (limited to 'sys/contrib/ipfilter/netinet/ip_lookup.c')
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_lookup.c | 178 |
1 files changed, 151 insertions, 27 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_lookup.c b/sys/contrib/ipfilter/netinet/ip_lookup.c index 3c7eb5f..12b1f4a 100644 --- a/sys/contrib/ipfilter/netinet/ip_lookup.c +++ b/sys/contrib/ipfilter/netinet/ip_lookup.c @@ -34,9 +34,6 @@ struct file; #endif #include <sys/socket.h> #if (defined(__osf__) || defined(AIX) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) -# ifdef __osf__ -# include <net/radix.h> -# endif # include "radix_ipf_local.h" # define _RADIX_H_ #endif @@ -61,7 +58,7 @@ struct file; /* END OF INCLUDES */ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.35.2.8 2005/11/13 15:35:45 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.35.2.15 2007/05/26 13:05:13 darrenr Exp $"; #endif #ifdef IPFILTER_LOOKUP @@ -129,10 +126,11 @@ void ip_lookup_unload() /* involves just calling another function to handle the specifics of each */ /* command. */ /* ------------------------------------------------------------------------ */ -int ip_lookup_ioctl(data, cmd, mode) +int ip_lookup_ioctl(data, cmd, mode, uid, ctx) caddr_t data; ioctlcmd_t cmd; -int mode; +int mode, uid; +void *ctx; { int err; SPL_INT(s); @@ -182,6 +180,10 @@ int mode; RWLOCK_EXIT(&ip_poolrw); break; + case SIOCLOOKUPITER : + err = ip_lookup_iterate(data, uid, ctx); + break; + default : err = EINVAL; break; @@ -210,8 +212,13 @@ caddr_t data; ip_pool_t *p; int err; - err = 0; - BCOPYIN(data, &op, sizeof(op)); + err = BCOPYIN(data, &op, sizeof(op)); + if (err != 0) + return EFAULT; + + if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) + return EINVAL; + op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; switch (op.iplo_type) @@ -283,6 +290,9 @@ caddr_t data; err = 0; BCOPYIN(data, &op, sizeof(op)); + if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) + return EINVAL; + op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; switch (op.iplo_type) @@ -341,8 +351,12 @@ caddr_t data; iplookupop_t op; int err; - err = 0; - BCOPYIN(data, &op, sizeof(op)); + err = BCOPYIN(data, &op, sizeof(op)); + if (err != 0) + return EFAULT; + + if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) + return EINVAL; op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; @@ -371,8 +385,10 @@ caddr_t data; * For anonymous pools, copy back the operation struct because in the * case of success it will contain the new table's name. */ - if ((err == 0) && ((op.iplo_arg & IPOOL_ANON) != 0)) { - BCOPYOUT(&op, data, sizeof(op)); + if ((err == 0) && ((op.iplo_arg & LOOKUP_ANON) != 0)) { + err = BCOPYOUT(&op, data, sizeof(op)); + if (err != 0) + err = EFAULT; } return err; @@ -393,11 +409,14 @@ caddr_t data; iplookupop_t op; int err; - BCOPYIN(data, &op, sizeof(op)); - op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; + err = BCOPYIN(data, &op, sizeof(op)); + if (err != 0) + return EFAULT; - if (op.iplo_arg & IPLT_ANON) - op.iplo_arg &= IPLT_ANON; + if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) + return EINVAL; + + op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; /* * create a new pool - fail if one already exists with @@ -406,11 +425,11 @@ caddr_t data; switch (op.iplo_type) { case IPLT_POOL : - err = ip_pool_destroy(&op); + err = ip_pool_destroy(op.iplo_unit, op.iplo_name); break; case IPLT_HASH : - err = fr_removehtable(&op); + err = fr_removehtable(op.iplo_unit, op.iplo_name); break; default : @@ -434,8 +453,12 @@ caddr_t data; iplookupop_t op; int err; - err = 0; - BCOPYIN(data, &op, sizeof(op)); + err = BCOPYIN(data, &op, sizeof(op)); + if (err != 0) + return EFAULT; + + if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) + return EINVAL; switch (op.iplo_type) { @@ -469,15 +492,16 @@ caddr_t data; int err, unit, num, type; iplookupflush_t flush; - err = 0; - BCOPYIN(data, &flush, sizeof(flush)); - - flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0'; + err = BCOPYIN(data, &flush, sizeof(flush)); + if (err != 0) + return EFAULT; unit = flush.iplf_unit; if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) return EINVAL; + flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0'; + type = flush.iplf_type; err = EINVAL; num = 0; @@ -494,12 +518,23 @@ caddr_t data; if (err == 0) { flush.iplf_count = num; - err = COPYOUT(&flush, data, sizeof(flush)); + err = BCOPYOUT(&flush, data, sizeof(flush)); + if (err != 0) + err = EFAULT; } return err; } +/* ------------------------------------------------------------------------ */ +/* Function: ip_lookup_delref */ +/* Returns: void */ +/* Parameters: type(I) - table type to operate on */ +/* ptr(I) - pointer to object to remove reference for */ +/* */ +/* This function organises calling the correct deref function for a given */ +/* type of object being passed into it. */ +/* ------------------------------------------------------------------------ */ void ip_lookup_deref(type, ptr) int type; void *ptr; @@ -522,13 +557,102 @@ void *ptr; } +/* ------------------------------------------------------------------------ */ +/* Function: ip_lookup_iterate */ +/* Returns: int - 0 = success, else error */ +/* Parameters: data(I) - pointer to data from ioctl call */ +/* */ +/* Decodes ioctl request to step through either hash tables or pools. */ +/* ------------------------------------------------------------------------ */ +int ip_lookup_iterate(data, uid, ctx) +void *data; +int uid; +void *ctx; +{ + ipflookupiter_t iter; + ipftoken_t *token; + int err; + SPL_INT(s); + + err = fr_inobj(data, &iter, IPFOBJ_LOOKUPITER); + if (err != 0) + return err; + + if (iter.ili_unit < 0 || iter.ili_unit > IPL_LOGMAX) + return EINVAL; + + if (iter.ili_ival != IPFGENITER_LOOKUP) + return EINVAL; + + SPL_SCHED(s); + token = ipf_findtoken(iter.ili_key, uid, ctx); + if (token == NULL) { + RWLOCK_EXIT(&ipf_tokens); + SPL_X(s); + return ESRCH; + } + + switch (iter.ili_type) + { + case IPLT_POOL : + err = ip_pool_getnext(token, &iter); + break; + case IPLT_HASH : + err = fr_htable_getnext(token, &iter); + break; + default : + err = EINVAL; + break; + } + RWLOCK_EXIT(&ipf_tokens); + SPL_X(s); + + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: iplookup_iterderef */ +/* Returns: int - 0 = success, else error */ +/* Parameters: data(I) - pointer to data from ioctl call */ +/* */ +/* Decodes ioctl request to remove a particular hash table or pool and */ +/* calls the relevant function to do the cleanup. */ +/* ------------------------------------------------------------------------ */ +void ip_lookup_iterderef(type, data) +u_32_t type; +void *data; +{ + iplookupiterkey_t key; + + key.ilik_key = type; + + if (key.ilik_unstr.ilik_ival != IPFGENITER_LOOKUP) + return; + + switch (key.ilik_unstr.ilik_type) + { + case IPLT_HASH : + fr_htable_iterderef((u_int)key.ilik_unstr.ilik_otype, + (int)key.ilik_unstr.ilik_unit, data); + break; + case IPLT_POOL : + ip_pool_iterderef((u_int)key.ilik_unstr.ilik_otype, + (int)key.ilik_unstr.ilik_unit, data); + break; + } +} + + + #else /* IPFILTER_LOOKUP */ /*ARGSUSED*/ -int ip_lookup_ioctl(data, cmd, mode) +int ip_lookup_ioctl(data, cmd, mode, uid, ctx) caddr_t data; ioctlcmd_t cmd; -int mode; +int mode, uid; +void *ctx; { return EIO; } |