- make each element of a variable hold a type

- change get_type to take an index, so we can get the individual types of
  each element (since primitive elements can be in lists)
- make port_range primitive
- add a routine to convert a variable of primitives to a variable containing
- only port ranges.
This commit is contained in:
christos 2012-02-26 21:50:05 +00:00
parent 2d942d9d58
commit 394473e707
6 changed files with 106 additions and 25 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_build.c,v 1.5 2012/02/20 00:18:19 rmind Exp $ */
/* $NetBSD: npf_build.c,v 1.6 2012/02/26 21:50:05 christos Exp $ */
/*-
* Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_build.c,v 1.5 2012/02/20 00:18:19 rmind Exp $");
__RCSID("$NetBSD: npf_build.c,v 1.6 2012/02/26 21:50:05 christos Exp $");
#include <sys/types.h>
#include <sys/ioctl.h>
@ -161,7 +161,7 @@ npfctl_build_fam(nc_ctx_t *nc, sa_family_t family,
static void
npfctl_build_vars(nc_ctx_t *nc, sa_family_t family, npfvar_t *vars, int opts)
{
const int type = npfvar_get_type(vars);
const int type = npfvar_get_type(vars, 0);
size_t i;
npfctl_ncgen_group(nc);
@ -335,7 +335,7 @@ npfctl_build_rpcall(nl_rproc_t *rp, const char *name, npfvar_t *args)
return;
}
const int type = npfvar_get_type(arg->ma_opts);
const int type = npfvar_get_type(arg->ma_opts, 0);
if (type != -1 && type != NPFVAR_NUM) {
yyerror("option '%s' is not numeric", aval);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_data.c,v 1.10 2012/01/08 21:34:21 rmind Exp $ */
/* $NetBSD: npf_data.c,v 1.11 2012/02/26 21:50:05 christos Exp $ */
/*-
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_data.c,v 1.10 2012/01/08 21:34:21 rmind Exp $");
__RCSID("$NetBSD: npf_data.c,v 1.11 2012/02/26 21:50:05 christos Exp $");
#include <sys/types.h>
#include <sys/null.h>
@ -231,6 +231,45 @@ out:
return NULL;
}
npfvar_t *
npfctl_parse_port_range_variable(const char *v)
{
npfvar_t *vp = npfvar_lookup(v);
in_port_t p;
port_range_t *pr;
size_t count = npfvar_get_count(vp);
npfvar_t *pvp = npfvar_create(".port_range");
for (size_t i = 0; i < count; i++) {
int type = npfvar_get_type(vp, i);
void *data = npfvar_get_data(vp, type, i);
switch (type) {
case NPFVAR_IDENTIFIER:
case NPFVAR_STRING:
p = npfctl_portno(data);
npfvar_add_elements(pvp, npfctl_parse_port_range(p, p));
break;
case NPFVAR_PORT_RANGE:
pr = data;
npfvar_add_element(pvp, NPFVAR_PORT_RANGE, pr,
sizeof(*pr));
break;
case NPFVAR_NUM:
p = *(unsigned long *)data;
npfvar_add_elements(pvp, npfctl_parse_port_range(p, p));
break;
default:
yyerror("wrong variable '%s' type '%s' for port range",
v, npfvar_type(type));
goto out;
}
}
return pvp;
out:
npfvar_destroy(pvp);
return NULL;
}
npfvar_t *
npfctl_parse_iface(const char *ifname)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_parse.y,v 1.4 2012/02/26 21:14:50 rmind Exp $ */
/* $NetBSD: npf_parse.y,v 1.5 2012/02/26 21:50:05 christos Exp $ */
/*-
* Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@ -213,6 +213,11 @@ list_elem
npfvar_add_element(vp, NPFVAR_STRING, $1, strlen($1) + 1);
npfvar_add_elements(cvar, vp);
}
| NUM MINUS NUM
{
npfvar_t *vp = npfctl_parse_port_range($1, $3);
npfvar_add_elements(cvar, vp);
}
| NUM
{
npfvar_t *vp = npfvar_create(".num");
@ -569,7 +574,7 @@ addr_or_iface
| VAR_ID
{
npfvar_t *vp = npfvar_lookup($1);
const int type = npfvar_get_type(vp);
const int type = npfvar_get_type(vp, 0);
switch (type) {
case NPFVAR_VAR_ID:
@ -606,6 +611,9 @@ port_range
{
$$ = npfctl_parse_port_range($2, $4);
}
| PORT VAR_ID {
$$ = npfctl_parse_port_range_variable($2);
}
|
{
$$ = NULL;
@ -683,7 +691,7 @@ ifindex
| VAR_ID
{
npfvar_t *vp = npfvar_lookup($1);
const int type = npfvar_get_type(vp);
const int type = npfvar_get_type(vp, 0);
switch (type) {
case NPFVAR_VAR_ID:

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_var.c,v 1.3 2012/01/15 00:49:48 rmind Exp $ */
/* $NetBSD: npf_var.c,v 1.4 2012/02/26 21:50:05 christos Exp $ */
/*-
* Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_var.c,v 1.3 2012/01/15 00:49:48 rmind Exp $");
__RCSID("$NetBSD: npf_var.c,v 1.4 2012/02/26 21:50:05 christos Exp $");
#include <stdlib.h>
#include <string.h>
@ -41,6 +41,7 @@ __RCSID("$NetBSD: npf_var.c,v 1.3 2012/01/15 00:49:48 rmind Exp $");
typedef struct npf_element {
void * e_data;
int e_type;
struct npf_element *e_next;
} npf_element_t;
@ -105,6 +106,7 @@ npfvar_add_element(npfvar_t *vp, int type, const void *data, size_t len)
vp->v_count++;
el = zalloc(sizeof(*el));
el->e_data = zalloc(len);
el->e_type = type;
memcpy(el->e_data, data, len);
/* Preserve order of insertion. */
@ -181,12 +183,6 @@ npfvar_get_count(const npfvar_t *vp)
return vp ? vp->v_count : 0;
}
int
npfvar_get_type(const npfvar_t *vp)
{
return vp ? vp->v_type : -1;
}
static void *
npfvar_get_data1(const npfvar_t *vp, int type, size_t idx, size_t level)
{
@ -224,6 +220,43 @@ npfvar_get_data1(const npfvar_t *vp, int type, size_t idx, size_t level)
return el->e_data;
}
static int
npfvar_get_type1(const npfvar_t *vp, size_t idx, size_t level)
{
npf_element_t *el;
if (level >= var_num) {
yyerror("variable loop for '%s'", vp->v_key);
return -1;
}
if (vp == NULL)
return -1;
if (vp->v_count <= idx) {
yyerror("variable '%s' has only %zu elements, requested %zu",
vp->v_key, vp->v_count, idx);
return -1;
}
el = vp->v_elements;
while (idx--) {
el = el->e_next;
}
if (vp->v_type == NPFVAR_VAR_ID) {
npfvar_t *rvp = npfvar_lookup(el->e_data);
return npfvar_get_type1(rvp, 0, level + 1);
}
return el->e_type;
}
int
npfvar_get_type(const npfvar_t *vp, size_t idx)
{
return npfvar_get_type1(vp, idx, 0);
}
void *
npfvar_get_data(const npfvar_t *vp, int type, size_t idx)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_var.h,v 1.1 2012/01/08 21:34:21 rmind Exp $ */
/* $NetBSD: npf_var.h,v 1.2 2012/02/26 21:50:05 christos Exp $ */
/*-
* Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@ -36,14 +36,14 @@
#define NPFVAR_IDENTIFIER 1
#define NPFVAR_VAR_ID 2
#define NPFVAR_NUM 3
#define NPFVAR_PORT_RANGE 4
/* Note: primitive types are equivalent. */
#define NPFVAR_PRIM NPFVAR_NUM
#define NPFVAR_TYPE(x) (((x) & ~NPFVAR_PRIM) ? (x) : 0)
#define NPFVAR_PRIM NPFVAR_PORT_RANGE
#define NPFVAR_TYPE(x) (((x) > NPFVAR_PRIM) ? (x) : 0)
#define NPFVAR_TABLE 4
#define NPFVAR_FAM 5
#define NPFVAR_PORT_RANGE 6
#define NPFVAR_TABLE 5
#define NPFVAR_FAM 6
#define NPFVAR_TCPFLAG 7
#define NPFVAR_ICMP 8
#define NPFVAR_PROC_OP 9
@ -69,7 +69,7 @@ void npfvar_destroy(npfvar_t *);
char * npfvar_expand_string(const npfvar_t *);
size_t npfvar_get_count(const npfvar_t *);
int npfvar_get_type(const npfvar_t *);
int npfvar_get_type(const npfvar_t *, size_t);
void * npfvar_get_data(const npfvar_t *, int, size_t);
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: npfctl.h,v 1.11 2012/02/05 00:37:13 rmind Exp $ */
/* $NetBSD: npfctl.h,v 1.12 2012/02/26 21:50:05 christos Exp $ */
/*-
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@ -103,6 +103,7 @@ npfvar_t * npfctl_parse_icmpcode(const char *);
npfvar_t * npfctl_parse_icmp(uint8_t, uint8_t);
npfvar_t * npfctl_parse_iface(const char *);
npfvar_t * npfctl_parse_port_range(in_port_t, in_port_t);
npfvar_t * npfctl_parse_port_range_variable(const char *);
npfvar_t * npfctl_parse_fam_addr_mask(const char *, const char *,
unsigned long *);
fam_addr_mask_t *npfctl_parse_cidr(char *);