Sat Mar 10 22:21:50 2012 UTC ()
Add a small disassembler.


(christos)
diff -r1.5 -r1.6 src/usr.sbin/npf/npfctl/Makefile
diff -r0 -r1.1 src/usr.sbin/npf/npfctl/npf_disassemble.c
diff -r1.7 -r1.8 src/usr.sbin/npf/npfctl/npf_ncgen.c
diff -r1.12 -r1.13 src/usr.sbin/npf/npfctl/npfctl.h

cvs diff -r1.5 -r1.6 src/usr.sbin/npf/npfctl/Makefile (expand / switch to unified diff)

--- src/usr.sbin/npf/npfctl/Makefile 2012/01/08 21:34:21 1.5
+++ src/usr.sbin/npf/npfctl/Makefile 2012/03/10 22:21:50 1.6
@@ -1,18 +1,20 @@ @@ -1,18 +1,20 @@
1# $NetBSD: Makefile,v 1.5 2012/01/08 21:34:21 rmind Exp $ 1# $NetBSD: Makefile,v 1.6 2012/03/10 22:21:50 christos Exp $
2 2
3PROG= npfctl 3PROG= npfctl
4MAN= npfctl.8 npf.conf.5 4MAN= npfctl.8 npf.conf.5
5 5
6SRCS= npfctl.c npf_var.c npf_data.c npf_ncgen.c npf_build.c 6SRCS= npfctl.c npf_var.c npf_data.c npf_ncgen.c npf_build.c \
 7 npf_disassemble.c
7 8
8CPPFLAGS+= -I${.CURDIR} 9CPPFLAGS+= -I${.CURDIR}
9SRCS+= npf_scan.l npf_parse.y 10SRCS+= npf_scan.l npf_parse.y
10YHEADER= 1 11YHEADER= 1
 12YFLAGS+= -v
11 13
12LDADD+= -lnpf -lprop -ly 14LDADD+= -lnpf -lprop -lutil -ly
13DPADD+= ${LIBNPF} ${LIBPROP} 15DPADD+= ${LIBNPF} ${LIBPROP} ${LIBUTIL}
14 16
15WARNS?= 4 17WARNS?= 4
16NOLINT= # disabled (note: deliberately) 18NOLINT= # disabled (note: deliberately)
17 19
18.include <bsd.prog.mk> 20.include <bsd.prog.mk>

File Added: src/usr.sbin/npf/npfctl/Attic/npf_disassemble.c
/*	$NetBSD: npf_disassemble.c,v 1.1 2012/03/10 22:21:50 christos Exp $	*/

/*-
 * Copyright (c) 2012 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Christos Zoulas.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_disassemble.c,v 1.1 2012/03/10 22:21:50 christos Exp $");

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <util.h>

#define NPF_OPCODES_STRINGS
#include <net/npf_ncode.h>

#include "npfctl.h"

#define ADVANCE(n, rv) \
	do { \
		if (len < sizeof(*pc) * (n)) { \
			warnx("ran out of bytes"); \
			return rv; \
		} \
		pc += (n); \
		len -= sizeof(*pc) * (n); \
	} while (/*CONSTCOND*/0)

static size_t
npfctl_ncode_get_target(const uint32_t *pc, const uint32_t **t, size_t l)
{
	for (size_t i = 0; i < l; i++)
		if (t[i] == pc)
			return i;
	return ~0;
}

static size_t
npfctl_ncode_add_target(const uint32_t *pc, const uint32_t ***t, size_t *l,
    size_t *m)
{
	size_t q = npfctl_ncode_get_target(pc, *t, *l);

	if (q != (size_t)~0)
		return q;

	if (*l <= *m) {
		*m += 10;
		*t = xrealloc(*t, *m * sizeof(**t));
	}
	q = *l;
	(*t)[(*l)++] = pc;
	return q;
}

static const char *
npfctl_ncode_operand(char *buf, size_t bufsiz, uint8_t op, const uint32_t *st,
    const uint32_t **pcv, size_t *lenv, const uint32_t ***t, size_t *l,
    size_t *m)
{
	const uint32_t *pc = *pcv;
	size_t len = *lenv;
	struct sockaddr_storage ss;

	switch (op) {
	case NPF_OPERAND_NONE:
		abort();

	case NPF_OPERAND_REGISTER:
		if (*pc & ~0x3) {
			warnx("Bad register operand 0x%x at offset %td",
			    *pc, pc - st);
			return NULL;
		}
		snprintf(buf, bufsiz, "R%d", *pc);
		ADVANCE(1, NULL);
		break;
				
	case NPF_OPERAND_KEY:
		snprintf(buf, bufsiz, "key=<0x%x>", *pc);
		ADVANCE(1, NULL);
		break;

	case NPF_OPERAND_VALUE:
		snprintf(buf, bufsiz, "value=<0x%x>", *pc);
		ADVANCE(1, NULL);
		break;

	case NPF_OPERAND_SD:
		if (*pc & ~0x1) {
			warnx("Bad src/dst operand 0x%x at offset %td",
			    *pc, pc - st);
			return NULL;
		}
		snprintf(buf, bufsiz, "%s", *pc == NPF_OPERAND_SD_SRC ?
		    "SRC" : "DST");
		ADVANCE(1, NULL);
		break;

	case NPF_OPERAND_REL_ADDRESS:
		snprintf(buf, bufsiz, "+%zu",
		    npfctl_ncode_add_target(pc + *pc - 1, t, l, m));
		ADVANCE(1, NULL);
		break;

	case NPF_OPERAND_NET_ADDRESS4: {
		struct sockaddr_in *sin = (void *)&ss;
		sin->sin_len = sizeof(*sin);
		sin->sin_family = AF_INET;
		sin->sin_port = 0;
		memcpy(&sin->sin_addr, pc, sizeof(sin->sin_addr));
		sockaddr_snprintf(buf, bufsiz, "%a", (struct sockaddr *)(void *)
		    sin);
		ADVANCE(sizeof(sin->sin_addr) / sizeof(*pc), NULL);
		break;
	}
	case NPF_OPERAND_NET_ADDRESS6: {
		struct sockaddr_in6 *sin6 = (void *)&ss;
		sin6->sin6_len = sizeof(*sin6);
		sin6->sin6_family = AF_INET6;
		sin6->sin6_port = 0;
		memcpy(&sin6->sin6_addr, pc, sizeof(sin6->sin6_addr));
		sockaddr_snprintf(buf, bufsiz, "%a", (struct sockaddr *)(void *)
		    sin6);
		ADVANCE(sizeof(sin6->sin6_addr) / sizeof(*pc), NULL);
		break;
	}
	case NPF_OPERAND_ETHER_TYPE:
		snprintf(buf, bufsiz, "ether=0x%x", *pc);
		ADVANCE(1, NULL);
		break;

	case NPF_OPERAND_SUBNET:
		snprintf(buf, bufsiz, "/%d", *pc);
		ADVANCE(1, NULL);
		break;

	case NPF_OPERAND_LENGTH:
		snprintf(buf, bufsiz, "length=%d", *pc);
		ADVANCE(1, NULL);
		break;

	case NPF_OPERAND_TABLE_ID:
		snprintf(buf, bufsiz, "id=%d", *pc);
		ADVANCE(1, NULL);
		break;

	case NPF_OPERAND_ICMP4_TYPE_CODE:
		snprintf(buf, bufsiz, "icmp=0x%x", *pc);
		ADVANCE(1, NULL);
		break;

	case NPF_OPERAND_TCP_FLAGS_MASK:
		snprintf(buf, bufsiz, "flmask=0x%x", *pc);
		ADVANCE(1, NULL);
		break;

	case NPF_OPERAND_PORT_RANGE:
		snprintf(buf, bufsiz, "%d-%d", (*pc >> 16), *pc & 0xffff);
		ADVANCE(1, NULL);
		break;
	default:
		warnx("invalid operand %d at offset %td", op, pc - st);
		return NULL;
	}

	*pcv = pc;
	*lenv = len;
	return buf;
}

int
npfctl_ncode_disassemble(FILE *fp, const void *v, size_t len)
{
	const uint32_t *pc = v;
	const uint32_t *st = v;
	const struct npf_instruction *ni;
	char buf[256];
	const uint32_t **targ;
	size_t tlen, mlen, target;

	targ = NULL;
	mlen = tlen = 0;
	while (len) {
		/* Get the opcode */
		if (*pc & ~0xff) {
			warnx("bad opcode 0x%x at offset (%td)", *pc,
			    pc - st);
			return -1;
		}
		ni = &npf_instructions[*pc];
		if (ni->name == NULL) {
			warnx("invalid opcode 0x%x at offset (%td)", *pc,
			    pc - st);
			return -1;
		}
		target = npfctl_ncode_get_target(pc, targ, tlen);
		if (target != (size_t)~0)
			printf("%zu:", target);
		fprintf(fp, "\t%s", ni->name);
		ADVANCE(1, -1);
		for (size_t i = 0; i < __arraycount(ni->op); i++) {
			const char *op;
			if (ni->op[i] == NPF_OPERAND_NONE)
				break;
			op = npfctl_ncode_operand(buf, sizeof(buf), ni->op[i],
			    st, &pc, &len, &targ, &tlen, &mlen);
			if (op == NULL)
				return -1;
			fprintf(fp, "%s%s", i == 0 ? " " : ", ", op);
		}
		fprintf(fp, "\n");
	}
	return 0;
}

cvs diff -r1.7 -r1.8 src/usr.sbin/npf/npfctl/Attic/npf_ncgen.c (expand / switch to unified diff)

--- src/usr.sbin/npf/npfctl/Attic/npf_ncgen.c 2012/01/09 01:47:09 1.7
+++ src/usr.sbin/npf/npfctl/Attic/npf_ncgen.c 2012/03/10 22:21:50 1.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npf_ncgen.c,v 1.7 2012/01/09 01:47:09 rmind Exp $ */ 1/* $NetBSD: npf_ncgen.c,v 1.8 2012/03/10 22:21:50 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This material is based upon work partially supported by The 7 * This material is based upon work partially supported by The
8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * N-code generation interface. 33 * N-code generation interface.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__RCSID("$NetBSD: npf_ncgen.c,v 1.7 2012/01/09 01:47:09 rmind Exp $"); 37__RCSID("$NetBSD: npf_ncgen.c,v 1.8 2012/03/10 22:21:50 christos Exp $");
38 38
39#include <stdlib.h> 39#include <stdlib.h>
40#include <stddef.h> 40#include <stddef.h>
41#include <inttypes.h> 41#include <inttypes.h>
42#include <assert.h> 42#include <assert.h>
43#include <err.h> 43#include <err.h>
44 44
45#include "npfctl.h" 45#include "npfctl.h"
46 46
47/* Reduce re-allocations by expanding in 64 byte blocks. */ 47/* Reduce re-allocations by expanding in 64 byte blocks. */
48#define NC_ALLOC_MASK (64 - 1) 48#define NC_ALLOC_MASK (64 - 1)
49#define NC_ALLOC_ROUND(x) (((x) + NC_ALLOC_MASK) & ~NC_ALLOC_MASK) 49#define NC_ALLOC_ROUND(x) (((x) + NC_ALLOC_MASK) & ~NC_ALLOC_MASK)
50 50
@@ -378,20 +378,24 @@ npfctl_gennc_tcpfl(nc_ctx_t *ctx, uint8_ @@ -378,20 +378,24 @@ npfctl_gennc_tcpfl(nc_ctx_t *ctx, uint8_
378 *nc++ = NPF_OPCODE_TCP_FLAGS; 378 *nc++ = NPF_OPCODE_TCP_FLAGS;
379 *nc++ = (tf << 8) | tf_mask; 379 *nc++ = (tf << 8) | tf_mask;
380 380
381 /* Comparison block (2 words). */ 381 /* Comparison block (2 words). */
382 npfctl_ncgen_addjmp(ctx, &nc); 382 npfctl_ncgen_addjmp(ctx, &nc);
383 383
384 /* + 4 words. */ 384 /* + 4 words. */
385 npfctl_ncgen_putptr(ctx, nc); 385 npfctl_ncgen_putptr(ctx, nc);
386} 386}
387 387
388void 388void
389npfctl_ncgen_print(const void *code, size_t len) 389npfctl_ncgen_print(const void *code, size_t len)
390{ 390{
 391#if 0
391 const uint32_t *op = code; 392 const uint32_t *op = code;
392 393
393 while (len) { 394 while (len) {
394 printf("\t> |0x%02x|\n", (u_int)*op++); 395 printf("\t> |0x%02x|\n", (u_int)*op++);
395 len -= sizeof(*op); 396 len -= sizeof(*op);
396 } 397 }
 398#else
 399 npfctl_ncode_disassemble(stdout, code, len);
 400#endif
397} 401}

cvs diff -r1.12 -r1.13 src/usr.sbin/npf/npfctl/npfctl.h (expand / switch to unified diff)

--- src/usr.sbin/npf/npfctl/npfctl.h 2012/02/26 21:50:05 1.12
+++ src/usr.sbin/npf/npfctl/npfctl.h 2012/03/10 22:21:50 1.13
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npfctl.h,v 1.12 2012/02/26 21:50:05 christos Exp $ */ 1/* $NetBSD: npfctl.h,v 1.13 2012/03/10 22:21:50 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -144,15 +144,16 @@ void npfctl_gennc_tcpfl(nc_ctx_t *, uin @@ -144,15 +144,16 @@ void npfctl_gennc_tcpfl(nc_ctx_t *, uin
144#define NPFCTL_BINAT 2 144#define NPFCTL_BINAT 2
145#define NPFCTL_NAT 3 145#define NPFCTL_NAT 3
146 146
147void npfctl_config_init(bool); 147void npfctl_config_init(bool);
148int npfctl_config_send(int); 148int npfctl_config_send(int);
149 149
150void npfctl_build_rproc(const char *, npfvar_t *); 150void npfctl_build_rproc(const char *, npfvar_t *);
151void npfctl_build_group(const char *, int, u_int); 151void npfctl_build_group(const char *, int, u_int);
152void npfctl_build_rule(int, u_int, sa_family_t, 152void npfctl_build_rule(int, u_int, sa_family_t,
153 const opt_proto_t *, const filt_opts_t *, const char *); 153 const opt_proto_t *, const filt_opts_t *, const char *);
154void npfctl_build_nat(int, u_int, const filt_opts_t *, 154void npfctl_build_nat(int, u_int, const filt_opts_t *,
155 npfvar_t *, npfvar_t *); 155 npfvar_t *, npfvar_t *);
156void npfctl_build_table(const char *, u_int, const char *); 156void npfctl_build_table(const char *, u_int, const char *);
 157int npfctl_ncode_disassemble(FILE *, const void *, size_t);
157 158
158#endif 159#endif