DF-3443 / fw3443.c
/* * fw3443.ko - PoC-only inspector module for DF-3443. * Exposes: * hw.fw3443.addr - kernel address to inspect (writable) * hw.fw3443.dump - 64 bytes of hex at that address (readable) * and prints struct geometry at load. */ #include <sys/param.h> #include <sys/kernel.h> #include <sys/module.h> #include <sys/sysctl.h> #include <sys/systm.h> #include <sys/malloc.h> #include <net/if_var.h> #include <net/altq/altq.h> #include <net/altq/if_altq.h> #include <net/altq/altq_priq.h> static struct sysctl_ctx_list fw_ctx; static struct sysctl_oid *fw_root; static unsigned long fw_addr; static char fw_dump[600]; static int fw_sysctl_dump(SYSCTL_HANDLER_ARGS) { uint64_t v[8]; int i, len; if (fw_addr == 0) return (EINVAL); memcpy(v, (void *)(uintptr_t)fw_addr, sizeof(v)); len = 0; fw_dump[0] = '\0'; for (i = 0; i < 8; i++) { len += ksnprintf(fw_dump + len, sizeof(fw_dump) - len, "%016llx%s", (unsigned long long)v[i], (i == 7) ? "" : " "); } return (sysctl_handle_string(oidp, fw_dump, sizeof(fw_dump), req)); } static int fw_sysctl_addr(SYSCTL_HANDLER_ARGS) { return (sysctl_handle_long(oidp, &fw_addr, 0, req)); } static int fw_modevent(module_t mod, int type, void *data) { switch (type) { case MOD_LOAD: sysctl_ctx_init(&fw_ctx); fw_root = SYSCTL_ADD_NODE(&fw_ctx, SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "fw3443", CTLFLAG_RW, 0, "fw3443 inspector"); if (fw_root == NULL) return (ENOMEM); SYSCTL_ADD_PROC(&fw_ctx, SYSCTL_CHILDREN(fw_root), OID_AUTO, "addr", CTLTYPE_LONG | CTLFLAG_RW, 0, 0, fw_sysctl_addr, "L", "kernel address to inspect"); SYSCTL_ADD_PROC(&fw_ctx, SYSCTL_CHILDREN(fw_root), OID_AUTO, "dump", CTLTYPE_STRING | CTLFLAG_RD, 0, 0, fw_sysctl_dump, "A", "64 bytes at addr, hex"); kprintf("fw3443: sizeof(struct ifnet)=%zu " "offsetof(ifnet.if_snd)=%zu " "offsetof(ifaltq.altq_subq)=%zu " "sizeof(struct ifaltq_subque)=%zu " "offsetof(priq_if.pif_ifq)=%zu " "offsetof(priq_if.pif_classes)=%zu\n", sizeof(struct ifnet), offsetof(struct ifnet, if_snd), offsetof(struct ifaltq, altq_subq), sizeof(struct ifaltq_subque), offsetof(struct priq_if, pif_ifq), offsetof(struct priq_if, pif_classes)); return (0); case MOD_UNLOAD: if (sysctl_ctx_free(&fw_ctx) != 0) return (ENOTEMPTY); return (0); default: return (EOPNOTSUPP); } } static moduledata_t fw3443_mod = { "fw3443", fw_modevent, 0 }; DECLARE_MODULE(fw3443, fw3443_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); |