summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ipfilter/netinet/ip_scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/ipfilter/netinet/ip_scan.c')
-rw-r--r--sys/contrib/ipfilter/netinet/ip_scan.c220
1 files changed, 122 insertions, 98 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_scan.c b/sys/contrib/ipfilter/netinet/ip_scan.c
index 54acb2a..5b7c77e 100644
--- a/sys/contrib/ipfilter/netinet/ip_scan.c
+++ b/sys/contrib/ipfilter/netinet/ip_scan.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1995-2001 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -58,17 +58,17 @@ struct file;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_scan.c,v 2.40.2.10 2007/06/02 21:22:28 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id$";
#endif
#ifdef IPFILTER_SCAN /* endif at bottom of file */
-ipscan_t *ipsc_list = NULL,
- *ipsc_tail = NULL;
-ipscanstat_t ipsc_stat;
+ipscan_t *ipf_scan_list = NULL,
+ *ipf_scan_tail = NULL;
+ipscanstat_t ipf_scan_stat;
# ifdef USE_MUTEXES
-ipfrwlock_t ipsc_rwlock;
+ipfrwlock_t ipf_scan_rwlock;
# endif
# ifndef isalpha
@@ -77,42 +77,47 @@ ipfrwlock_t ipsc_rwlock;
# endif
-int ipsc_add __P((caddr_t));
-int ipsc_delete __P((caddr_t));
-struct ipscan *ipsc_lookup __P((char *));
-int ipsc_matchstr __P((sinfo_t *, char *, int));
-int ipsc_matchisc __P((ipscan_t *, ipstate_t *, int, int, int *));
-int ipsc_match __P((ipstate_t *));
+int ipf_scan_add __P((caddr_t));
+int ipf_scan_remove __P((caddr_t));
+struct ipscan *ipf_scan_lookup __P((char *));
+int ipf_scan_matchstr __P((sinfo_t *, char *, int));
+int ipf_scan_matchisc __P((ipscan_t *, ipstate_t *, int, int, int *));
+int ipf_scan_match __P((ipstate_t *));
-static int ipsc_inited = 0;
+static int ipf_scan_inited = 0;
-int ipsc_init()
+int
+ipf_scan_init()
{
- RWLOCK_INIT(&ipsc_rwlock, "ip scan rwlock");
- ipsc_inited = 1;
+ RWLOCK_INIT(&ipf_scan_rwlock, "ip scan rwlock");
+ ipf_scan_inited = 1;
return 0;
}
-void fr_scanunload()
+void
+ipf_scan_unload(ipf_main_softc_t *arg)
{
- if (ipsc_inited == 1) {
- RW_DESTROY(&ipsc_rwlock);
- ipsc_inited = 0;
+ if (ipf_scan_inited == 1) {
+ RW_DESTROY(&ipf_scan_rwlock);
+ ipf_scan_inited = 0;
}
}
-int ipsc_add(data)
-caddr_t data;
+int
+ipf_scan_add(data)
+ caddr_t data;
{
ipscan_t *i, *isc;
int err;
KMALLOC(isc, ipscan_t *);
- if (!isc)
+ if (!isc) {
+ ipf_interror = 90001;
return ENOMEM;
+ }
err = copyinptr(data, isc, sizeof(*isc));
if (err) {
@@ -120,23 +125,24 @@ caddr_t data;
return err;
}
- WRITE_ENTER(&ipsc_rwlock);
+ WRITE_ENTER(&ipf_scan_rwlock);
- i = ipsc_lookup(isc->ipsc_tag);
- if (i) {
- RWLOCK_EXIT(&ipsc_rwlock);
+ i = ipf_scan_lookup(isc->ipsc_tag);
+ if (i != NULL) {
+ RWLOCK_EXIT(&ipf_scan_rwlock);
KFREE(isc);
+ ipf_interror = 90002;
return EEXIST;
}
- if (ipsc_tail) {
- ipsc_tail->ipsc_next = isc;
- isc->ipsc_pnext = &ipsc_tail->ipsc_next;
- ipsc_tail = isc;
+ if (ipf_scan_tail) {
+ ipf_scan_tail->ipsc_next = isc;
+ isc->ipsc_pnext = &ipf_scan_tail->ipsc_next;
+ ipf_scan_tail = isc;
} else {
- ipsc_list = isc;
- ipsc_tail = isc;
- isc->ipsc_pnext = &ipsc_list;
+ ipf_scan_list = isc;
+ ipf_scan_tail = isc;
+ isc->ipsc_pnext = &ipf_scan_list;
}
isc->ipsc_next = NULL;
@@ -145,14 +151,15 @@ caddr_t data;
isc->ipsc_sref = 0;
isc->ipsc_active = 0;
- ipsc_stat.iscs_entries++;
- RWLOCK_EXIT(&ipsc_rwlock);
+ ipf_scan_stat.iscs_entries++;
+ RWLOCK_EXIT(&ipf_scan_rwlock);
return 0;
}
-int ipsc_delete(data)
-caddr_t data;
+int
+ipf_scan_remove(data)
+ caddr_t data;
{
ipscan_t isc, *i;
int err;
@@ -161,14 +168,15 @@ caddr_t data;
if (err)
return err;
- WRITE_ENTER(&ipsc_rwlock);
+ WRITE_ENTER(&ipf_scan_rwlock);
- i = ipsc_lookup(isc.ipsc_tag);
+ i = ipf_scan_lookup(isc.ipsc_tag);
if (i == NULL)
err = ENOENT;
else {
if (i->ipsc_fref) {
- RWLOCK_EXIT(&ipsc_rwlock);
+ RWLOCK_EXIT(&ipf_scan_rwlock);
+ ipf_interror = 90003;
return EBUSY;
}
@@ -176,61 +184,66 @@ caddr_t data;
if (i->ipsc_next)
i->ipsc_next->ipsc_pnext = i->ipsc_pnext;
else {
- if (i->ipsc_pnext == &ipsc_list)
- ipsc_tail = NULL;
+ if (i->ipsc_pnext == &ipf_scan_list)
+ ipf_scan_tail = NULL;
else
- ipsc_tail = *(*i->ipsc_pnext)->ipsc_pnext;
+ ipf_scan_tail = *(*i->ipsc_pnext)->ipsc_pnext;
}
- ipsc_stat.iscs_entries--;
+ ipf_scan_stat.iscs_entries--;
KFREE(i);
}
- RWLOCK_EXIT(&ipsc_rwlock);
+ RWLOCK_EXIT(&ipf_scan_rwlock);
return err;
}
-struct ipscan *ipsc_lookup(tag)
-char *tag;
+struct ipscan *
+ipf_scan_lookup(tag)
+ char *tag;
{
ipscan_t *i;
- for (i = ipsc_list; i; i = i->ipsc_next)
+ for (i = ipf_scan_list; i; i = i->ipsc_next)
if (!strcmp(i->ipsc_tag, tag))
return i;
return NULL;
}
-int ipsc_attachfr(fr)
-struct frentry *fr;
+int
+ipf_scan_attachfr(fr)
+ struct frentry *fr;
{
ipscan_t *i;
- if (fr->fr_isctag[0]) {
- READ_ENTER(&ipsc_rwlock);
- i = ipsc_lookup(fr->fr_isctag);
+ if (fr->fr_isctag != -1) {
+ READ_ENTER(&ipf_scan_rwlock);
+ i = ipf_scan_lookup(fr->fr_isctag + fr->fr_names);
if (i != NULL) {
ATOMIC_INC32(i->ipsc_fref);
}
- RWLOCK_EXIT(&ipsc_rwlock);
- if (i == NULL)
+ RWLOCK_EXIT(&ipf_scan_rwlock);
+ if (i == NULL) {
+ ipf_interror = 90004;
return ENOENT;
+ }
fr->fr_isc = i;
}
return 0;
}
-int ipsc_attachis(is)
-struct ipstate *is;
+int
+ipf_scan_attachis(is)
+ struct ipstate *is;
{
frentry_t *fr;
ipscan_t *i;
- READ_ENTER(&ipsc_rwlock);
+ READ_ENTER(&ipf_scan_rwlock);
fr = is->is_rule;
- if (fr) {
+ if (fr != NULL) {
i = fr->fr_isc;
if ((i != NULL) && (i != (ipscan_t *)-1)) {
is->is_isc = i;
@@ -245,13 +258,14 @@ struct ipstate *is;
is->is_flags |= IS_SC_MATCHS;
}
}
- RWLOCK_EXIT(&ipsc_rwlock);
+ RWLOCK_EXIT(&ipf_scan_rwlock);
return 0;
}
-int ipsc_detachfr(fr)
-struct frentry *fr;
+int
+ipf_scan_detachfr(fr)
+ struct frentry *fr;
{
ipscan_t *i;
@@ -263,18 +277,19 @@ struct frentry *fr;
}
-int ipsc_detachis(is)
-struct ipstate *is;
+int
+ipf_scan_detachis(is)
+ struct ipstate *is;
{
ipscan_t *i;
- READ_ENTER(&ipsc_rwlock);
+ READ_ENTER(&ipf_scan_rwlock);
if ((i = is->is_isc) && (i != (ipscan_t *)-1)) {
ATOMIC_DEC32(i->ipsc_sref);
is->is_isc = NULL;
is->is_flags &= ~(IS_SC_CLIENT|IS_SC_SERVER);
}
- RWLOCK_EXIT(&ipsc_rwlock);
+ RWLOCK_EXIT(&ipf_scan_rwlock);
return 0;
}
@@ -282,10 +297,11 @@ struct ipstate *is;
/*
* 'string' compare for scanning
*/
-int ipsc_matchstr(sp, str, n)
-sinfo_t *sp;
-char *str;
-int n;
+int
+ipf_scan_matchstr(sp, str, n)
+ sinfo_t *sp;
+ char *str;
+ int n;
{
char *s, *t, *up;
int i = n;
@@ -316,10 +332,11 @@ int n;
* Returns 3 if both server and client match, 2 if just server,
* 1 if just client
*/
-int ipsc_matchisc(isc, is, cl, sl, maxm)
-ipscan_t *isc;
-ipstate_t *is;
-int cl, sl, maxm[2];
+int
+ipf_scan_matchisc(isc, is, cl, sl, maxm)
+ ipscan_t *isc;
+ ipstate_t *is;
+ int cl, sl, maxm[2];
{
int i, j, k, n, ret = 0, flags;
@@ -348,7 +365,8 @@ int cl, sl, maxm[2];
i = 0;
n = MIN(cl, isc->ipsc_clen);
if ((n > 0) && (!maxm || (n >= maxm[1]))) {
- if (!ipsc_matchstr(&isc->ipsc_cl, is->is_sbuf[0], n)) {
+ if (!ipf_scan_matchstr(&isc->ipsc_cl,
+ is->is_sbuf[0], n)) {
i++;
ret |= 1;
if (n > j)
@@ -364,7 +382,8 @@ int cl, sl, maxm[2];
i = 0;
n = MIN(cl, isc->ipsc_slen);
if ((n > 0) && (!maxm || (n >= maxm[1]))) {
- if (!ipsc_matchstr(&isc->ipsc_sl, is->is_sbuf[1], n)) {
+ if (!ipf_scan_matchstr(&isc->ipsc_sl,
+ is->is_sbuf[1], n)) {
i++;
ret |= 2;
if (n > k)
@@ -381,8 +400,9 @@ int cl, sl, maxm[2];
}
-int ipsc_match(is)
-ipstate_t *is;
+int
+ipf_scan_match(is)
+ ipstate_t *is;
{
int i, j, k, n, cl, sl, maxm[2];
ipscan_t *isc, *lm;
@@ -399,7 +419,7 @@ ipstate_t *is;
/*
* Known object to scan for.
*/
- i = ipsc_matchisc(isc, is, cl, sl, NULL);
+ i = ipf_scan_matchisc(isc, is, cl, sl, NULL);
if (i & 1) {
is->is_flags |= IS_SC_MATCHC;
is->is_flags &= ~IS_SC_CLIENT;
@@ -415,8 +435,8 @@ ipstate_t *is;
lm = NULL;
maxm[0] = 0;
maxm[1] = 0;
- for (k = 0, isc = ipsc_list; isc; isc = isc->ipsc_next) {
- i = ipsc_matchisc(isc, is, cl, sl, maxm);
+ for (k = 0, isc = ipf_scan_list; isc; isc = isc->ipsc_next) {
+ i = ipf_scan_matchisc(isc, is, cl, sl, maxm);
if (i) {
/*
* We only want to remember the best match
@@ -475,7 +495,7 @@ ipstate_t *is;
j = ISC_A_NONE;
if ((is->is_flags & IS_SC_MATCHALL) == IS_SC_MATCHALL) {
j = isc->ipsc_action;
- ipsc_stat.iscs_acted++;
+ ipf_scan_stat.iscs_acted++;
} else if ((is->is_isc != NULL) &&
((is->is_flags & IS_SC_MATCHALL) != IS_SC_MATCHALL) &&
!(is->is_flags & (IS_SC_CLIENT|IS_SC_SERVER))) {
@@ -483,7 +503,7 @@ ipstate_t *is;
* Matching failed...
*/
j = isc->ipsc_else;
- ipsc_stat.iscs_else++;
+ ipf_scan_stat.iscs_else++;
}
switch (j)
@@ -508,9 +528,10 @@ ipstate_t *is;
/*
* check if a packet matches what we're scanning for
*/
-int ipsc_packet(fin, is)
-fr_info_t *fin;
-ipstate_t *is;
+int
+ipf_scan_packet(fin, is)
+ fr_info_t *fin;
+ ipstate_t *is;
{
int i, j, rv, dlen, off, thoff;
u_32_t seq, s0;
@@ -552,7 +573,7 @@ ipstate_t *is;
if (j == 0)
return 1;
- (void) ipsc_match(is);
+ (void) ipf_scan_match(is);
#if 0
/*
* There is the potential here for plain text passwords to get
@@ -567,11 +588,12 @@ ipstate_t *is;
}
-int fr_scan_ioctl(data, cmd, mode, uid, ctx)
-caddr_t data;
-ioctlcmd_t cmd;
-int mode, uid;
-void *ctx;
+int
+ipf_scan_ioctl(data, cmd, mode, uid, ctx)
+ caddr_t data;
+ ioctlcmd_t cmd;
+ int mode, uid;
+ void *ctx;
{
ipscanstat_t ipscs;
int err = 0;
@@ -579,17 +601,19 @@ void *ctx;
switch (cmd)
{
case SIOCADSCA :
- err = ipsc_add(data);
+ err = ipf_scan_add(data);
break;
case SIOCRMSCA :
- err = ipsc_delete(data);
+ err = ipf_scan_remove(data);
break;
case SIOCGSCST :
- bcopy((char *)&ipsc_stat, (char *)&ipscs, sizeof(ipscs));
- ipscs.iscs_list = ipsc_list;
+ bcopy((char *)&ipf_scan_stat, (char *)&ipscs, sizeof(ipscs));
+ ipscs.iscs_list = ipf_scan_list;
err = BCOPYOUT(&ipscs, data, sizeof(ipscs));
- if (err != 0)
+ if (err != 0) {
+ ipf_interror = 90005;
err = EFAULT;
+ }
break;
default :
err = EINVAL;
OpenPOWER on IntegriCloud