DF-3439 / krules.c
/* * krules.c - walk fw3_ctx[cpu]->rules and dump raw ip_fw rule bytes via kvm * verifies exactly what ip_fw3_chk walks on each CPU. */ #include <sys/param.h> #include <sys/types.h> #include <fcntl.h> #include <kvm.h> #include <stdio.h> #include <stdlib.h> #include <string.h> struct insn { uint8_t opcode; uint8_t len; uint16_t arg1; uint8_t module; uint8_t arg3; uint16_t arg2; }; struct ipfwhdr { unsigned long next; unsigned long next_rule; uint16_t act_ofs; uint16_t cmd_len; uint16_t rulenum; uint8_t set; uint8_t flags; uint64_t pcnt; uint64_t bcnt; uint32_t timestamp; unsigned long sibling; }; static kvm_t *kd; static int rd(unsigned long addr, void *buf, size_t len) { return kvm_read(kd, addr, buf, len) == (ssize_t)len ? 0 : -1; } int main(int argc, char **argv) { struct nlist nl[2]; unsigned long ctxs[64]; unsigned long ctx; struct ipfwhdr h; struct insn in; int cpu, ncpu = (argc > 1) ? atoi(argv[1]) : 1; memset(nl, 0, sizeof(nl)); nl[0].n_name = "fw3_ctx"; kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL); if (!kd) { fprintf(stderr, "kvm: %s\n", kvm_geterr(kd)); return 1; } if (kvm_nlist(kd, nl) < 0 || !nl[0].n_value) { fprintf(stderr, "nlist: %s\n", kvm_geterr(kd)); return 1; } if (rd(nl[0].n_value, ctxs, sizeof(ctxs))) { fprintf(stderr, "read fw3_ctx: %s\n", kvm_geterr(kd)); return 1; } for (cpu = 0; cpu < ncpu; cpu++) { unsigned long rule; int n; ctx = ctxs[cpu]; if (!ctx) { printf("cpu%d: no ctx\n", cpu); continue; } if (rd(ctx, &rule, sizeof(rule))) { printf("cpu%d: ctx read fail\n", cpu); continue; } printf("cpu%d rules @ 0x%lx:\n", cpu, rule); for (n = 0; rule && n < 20; n++, rule = h.next) { int i; if (rd(rule, &h, sizeof(h))) { printf(" read fail 0x%lx\n", rule); break; } printf(" rule 0x%lx num=%u set=%u act_ofs=%u cmd_len=%u " "pcnt=%llu next=0x%lx next_rule=0x%lx\n", rule, h.rulenum, h.set, h.act_ofs, h.cmd_len, (unsigned long long)h.pcnt, h.next, h.next_rule); for (i = 0; i < h.cmd_len; i += 2) { if (rd(rule + 56 + i * 4, &in, sizeof(in))) break; printf(" insn%d: opcode=%u len=%u arg1=%u " "module=%u arg3=%u arg2=%u\n", i / 2, in.opcode, in.len, in.arg1, in.module, in.arg3, in.arg2); } } } return 0; } |