summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ipfilter/netinet/ip_lookup.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/ipfilter/netinet/ip_lookup.c')
-rw-r--r--sys/contrib/ipfilter/netinet/ip_lookup.c178
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;
}
OpenPOWER on IntegriCloud