aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/ip_fw.c25
-rw-r--r--sys/netinet/ip_fw.h22
2 files changed, 38 insertions, 9 deletions
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index 5543bdf86c57..cf61a8bc20f8 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -12,7 +12,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * $Id: ip_fw.c,v 1.115 1999/07/28 22:27:27 green Exp $
+ * $Id: ip_fw.c,v 1.116 1999/08/01 16:57:15 green Exp $
*/
/*
@@ -626,7 +626,7 @@ again:
/* Check protocol; if wildcard, and no [ug]id, match */
if (f->fw_prot == IPPROTO_IP) {
if (!(f->fw_flg & (IP_FW_F_UID|IP_FW_F_GID)))
- goto got_match;
+ goto rnd_then_got_match;
} else
/* If different, don't match */
if (ip->ip_p != f->fw_prot)
@@ -812,6 +812,10 @@ bogusfrag:
goto dropit;
}
+rnd_then_got_match:
+ if ( ((struct ip_fw_ext *)f)->dont_match_prob &&
+ random() < ((struct ip_fw_ext *)f)->dont_match_prob )
+ continue ;
got_match:
*flow_id = chain ; /* XXX set flow id */
/* Update statistics */
@@ -967,12 +971,14 @@ static int
add_entry(struct ip_fw_head *chainptr, struct ip_fw *frwl)
{
struct ip_fw *ftmp = 0;
+ struct ip_fw_ext *ftmp_ext = 0 ;
struct ip_fw_chain *fwc = 0, *fcp, *fcpl = 0;
u_short nbr = 0;
int s;
fwc = malloc(sizeof *fwc, M_IPFW, M_DONTWAIT);
- ftmp = malloc(sizeof *ftmp, M_IPFW, M_DONTWAIT);
+ ftmp_ext = malloc(sizeof *ftmp_ext, M_IPFW, M_DONTWAIT);
+ ftmp = &ftmp_ext->rule ;
if (!fwc || !ftmp) {
dprintf(("%s malloc said no\n", err_prefix));
if (fwc) free(fwc, M_IPFW);
@@ -980,7 +986,11 @@ add_entry(struct ip_fw_head *chainptr, struct ip_fw *frwl)
return (ENOSPC);
}
- bcopy(frwl, ftmp, sizeof(struct ip_fw));
+ bzero(ftmp_ext, sizeof(*ftmp_ext)); /* play safe! */
+ bcopy(frwl, ftmp, sizeof(*ftmp));
+ if (ftmp->fw_flg & IP_FW_F_RND_MATCH)
+ ftmp_ext->dont_match_prob = (long)(ftmp->pipe_ptr) ;
+
ftmp->fw_in_if.fu_via_if.name[FW_IFNLEN - 1] = '\0';
ftmp->fw_pcnt = 0L;
ftmp->fw_bcnt = 0L;
@@ -1293,9 +1303,8 @@ ip_fw_ctl(struct sockopt *sopt)
{
int error, s;
size_t size;
- char *buf, *bp;
struct ip_fw_chain *fcp;
- struct ip_fw frwl;
+ struct ip_fw frwl, *bp , *buf;
/*
* Disallow sets in really-really secure mode, but still allow
@@ -1320,7 +1329,9 @@ ip_fw_ctl(struct sockopt *sopt)
for (fcp = LIST_FIRST(&ip_fw_chain), bp = buf; fcp;
fcp = LIST_NEXT(fcp, chain)) {
bcopy(fcp->rule, bp, sizeof *fcp->rule);
- bp += sizeof *fcp->rule;
+ (long)bp->pipe_ptr =
+ ((struct ip_fw_ext *)fcp->rule)->dont_match_prob;
+ bp ++ ;
}
error = sooptcopyout(sopt, buf, size);
FREE(buf, M_TEMP);
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 958eb67131d8..6c09388dd3c0 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -11,7 +11,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * $Id: ip_fw.h,v 1.39 1999/07/28 22:22:57 green Exp $
+ * $Id: ip_fw.h,v 1.40 1999/08/01 16:57:16 green Exp $
*/
#ifndef _IP_FW_H
@@ -89,6 +89,22 @@ struct ip_fw {
u_int64_t fw_loghighest; /* highest number packet to log */
};
+/*
+ * extended ipfw structure... some fields in the original struct
+ * can be used to pass parameters up/down, namely pointers
+ * void *pipe_ptr
+ * void *next_rule_ptr
+ * some others can be used to pass parameters down, namely counters etc.
+ * u_int64_t fw_pcnt,fw_bcnt;
+ * long timestamp;
+ */
+
+struct ip_fw_ext { /* extended structure */
+ struct ip_fw rule; /* must be at offset 0 */
+ long dont_match_prob; /* 0x7fffffff means 1.0, always fail */
+ u_int param1; /* unused at the moment */
+};
+
#define IP_FW_GETNSRCP(rule) ((rule)->fw_nports & 0x0f)
#define IP_FW_SETNSRCP(rule, n) do { \
(rule)->fw_nports &= ~0x0f; \
@@ -154,7 +170,9 @@ struct ip_fw_chain {
#define IP_FW_F_GID 0x00400000 /* filter by uid */
-#define IP_FW_F_MASK 0x007FFFFF /* All possible flag bits mask */
+#define IP_FW_F_RND_MATCH 0x00800000 /* probabilistic rule match */
+
+#define IP_FW_F_MASK 0x00FFFFFF /* All possible flag bits mask */
/*
* For backwards compatibility with rules specifying "via iface" but