Exemple #1
0
static char *
parse_nbuf_chain(struct mbuf *m)
{
	ifnet_t *dummy_ifp = npf_test_addif(IFNAME_TEST, false, false);
	char *s = kmem_zalloc(MBUF_CHAIN_LEN + 1, KM_SLEEP);
	nbuf_t nbuf;
	void *nptr;
	int n;

	nbuf_init(npf_getkernctx(), &nbuf, m, dummy_ifp);

	nptr = nbuf_advance(&nbuf, (random() % 16) + 1, (random() % 16) + 1);
	mbuf_consistency_check(&nbuf);
	assert(nptr != NULL);
	nbuf_reset(&nbuf);

	for (n = 0; ; ) {
		char d[4 + 1];

		nptr = nbuf_ensure_contig(&nbuf, sizeof(uint32_t));
		if (nptr == NULL) {
			break;
		}
		mbuf_consistency_check(&nbuf);
		memcpy(&d, nptr, sizeof(uint32_t));

		d[sizeof(d) - 1] = '\0';
		strcat(s, d);

		if (n + sizeof(uint32_t) == MBUF_CHAIN_LEN) {
			assert(nbuf_advance(&nbuf, sizeof(uint32_t) - 1, 0));
			assert(!nbuf_advance(&nbuf, 1, 0));
			break;
		}
		if (!nbuf_advance(&nbuf, sizeof(uint32_t), 0)) {
			break;
		}
		n += sizeof(uint32_t);
	}
	mbuf_consistency_check(&nbuf);
	return s;
}
Exemple #2
0
static int
test_bpf_code(void *code, size_t size)
{
	ifnet_t *dummy_ifp = npf_test_addif(IFNAME_TEST, false, false);
	npf_cache_t npc = { .npc_info = 0 };
	bpf_args_t bc_args;
	struct mbuf *m;
	nbuf_t nbuf;
	int ret, jret;
	void *jcode;

	/* Layer 3 (IP + TCP). */
	m = fill_packet(IPPROTO_TCP);
	nbuf_init(&nbuf, m, dummy_ifp);
	npf_cache_all(&npc, &nbuf);

	memset(&bc_args, 0, sizeof(bpf_args_t));
	bc_args.pkt = m;
	bc_args.wirelen = m_length(m);
	bc_args.arg = &npc;

	ret = npf_bpf_filter(&bc_args, code, NULL);

	/* JIT-compiled code. */
	jcode = npf_bpf_compile(code, size);
	if (jcode) {
		jret = npf_bpf_filter(&bc_args, NULL, jcode);
		assert(ret == jret);
		bpf_jit_freecode(jcode);
	} else if (lverbose) {
		printf("JIT-compilation failed\n");
	}
	m_freem(m);

	return ret;
}

static uint32_t
npf_bpfcop_run(u_int reg)
{
	struct bpf_insn insns_npf_bpfcop[] = {
		BPF_STMT(BPF_MISC+BPF_COP, NPF_COP_L3),
		BPF_STMT(BPF_LD+BPF_W+BPF_MEM, reg),
		BPF_STMT(BPF_RET+BPF_A, 0),
	};
	return test_bpf_code(&insns_npf_bpfcop, sizeof(insns_npf_bpfcop));
}

static bool
npf_bpfcop_test(void)
{
	bool fail = false;

	/* A <- IP version (4 or 6) */
	struct bpf_insn insns_ipver[] = {
		BPF_STMT(BPF_MISC+BPF_COP, NPF_COP_L3),
		BPF_STMT(BPF_RET+BPF_A, 0),
	};
	fail |= (test_bpf_code(&insns_ipver, sizeof(insns_ipver)) != IPVERSION);

	/* BPF_MW_IPVERI <- IP version */
	fail |= (npf_bpfcop_run(BPF_MW_IPVER) != IPVERSION);

	/* BPF_MW_L4OFF <- L4 header offset */
	fail |= (npf_bpfcop_run(BPF_MW_L4OFF) != sizeof(struct ip));

	/* BPF_MW_L4PROTO <- L4 protocol */
	fail |= (npf_bpfcop_run(BPF_MW_L4PROTO) != IPPROTO_TCP);

	return fail;
}