[syslinux] [PATCH] pxedump.c32: Simple PXE cached packet dumping
Shao Miller
sha0.miller at gmail.com
Tue Oct 2 19:26:16 PDT 2012
Not much to it, but thought I'd offer. - Shao
From c668e24421a344231fc3fba31a26c88e92d03f43 Mon Sep 17 00:00:00 2001
From: Shao Miller <sha0.miller at gmail.com>
Date: Tue, 2 Oct 2012 22:02:04 -0400
Subject: [PATCH] pxedump.c32: Simple PXE cached packet dumping
Usage: pxedump.c32 --cached
Mostly useful with a serial connection, to capture the lengthy output
Signed-off-by: Shao Miller <sha0.miller at gmail.com>
---
com32/modules/Makefile | 2 +-
com32/modules/pxedump.c | 241
++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 242 insertions(+), 1 deletion(-)
create mode 100644 com32/modules/pxedump.c
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index d8861c4..53bae4f 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -24,7 +24,7 @@ MODULES = config.c32 ethersel.c32 dmitest.c32
cpuidtest.c32 \
meminfo.c32 sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 \
kbdmap.c32 cmd.c32 vpdtest.c32 host.c32 ls.c32 gpxecmd.c32 \
ifcpu.c32 cpuid.c32 cat.c32 pwd.c32 ifplop.c32 zzjson.c32 \
- whichsys.c32 pxechn.c32
+ whichsys.c32 pxechn.c32 pxedump.c32
TESTFILES =
diff --git a/com32/modules/pxedump.c b/com32/modules/pxedump.c
new file mode 100644
index 0000000..478eba8
--- /dev/null
+++ b/com32/modules/pxedump.c
@@ -0,0 +1,241 @@
+/*
------------------------------------------------------------------------- *
+ *
+ * Copyright 2012 Shao Miller - All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ *
------------------------------------------------------------------------- */
+
+/*
+ * pxedump.c
+ *
+ * A comboot32 module for use with Syslinux' PXELINUX.
+ * Dump PXE cached packets. Mostly useful with a serial connection
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <consoles.h>
+#include <syslinux/pxe.h>
+
+#define countof(arr) (sizeof (arr) / sizeof *(arr))
+#define cached_pkt_count 3
+#define ipaddr_str_template "AAA.BBB.CCC.DDD"
+
+struct ipaddr_str;
+struct cached_pkt;
+struct cached_pkts;
+
+static int get_cached_pkts(struct cached_pkts * cached_pkts);
+static int dump_cached_pkts(struct cached_pkts * cached_pkts);
+static void free_cached_pkts(struct cached_pkts * cached_pkts);
+static void dump_cached_pkt(struct cached_pkt * cached_pkt);
+static int mk_ipaddr(struct ipaddr_str * str, in_addr_t addr);
+static void hexdump(const void * memory, size_t bytes);
+
+struct ipaddr_str {
+ char v[countof(ipaddr_str_template)];
+ };
+
+struct cached_pkt {
+ void * buffer;
+ size_t len;
+ };
+
+struct cached_pkts {
+ struct cached_pkt pkt[cached_pkt_count];
+ };
+
+static const struct ipaddr_str new_ipaddr_str = { ipaddr_str_template };
+static const struct cached_pkt new_cached_pkt = { 0 };
+static const struct cached_pkts new_cached_pkts = { { { 0 } } };
+
+int main(int argc, char ** argv) {
+ struct cached_pkts cached_pkts;
+
+ console_ansi_raw();
+
+ /* Only --cached supported for now */
+ if (argc != 2 || strcmp(argv[1], "--cached")) {
+ printf(
+ "Usage: pxedump.c32 --cached\n"
+ "You might want a serial connection.\n"
+ );
+ return EXIT_FAILURE;
+ }
+
+ get_cached_pkts(&cached_pkts);
+ dump_cached_pkts(&cached_pkts);
+ free_cached_pkts(&cached_pkts);
+
+ return EXIT_SUCCESS;
+ }
+
+/*
+ * Caller is responsible for cached_pkts != NULL.
+ * This function initializes *cached_pkts and allocates memory
+ * for the cached packets, which must be freed with a call to
+ * free_cached_pkts()
+ */
+static int get_cached_pkts(struct cached_pkts * cached_pkts) {
+ unsigned int i;
+ int rc;
+
+ *cached_pkts = new_cached_pkts;
+ for (i = 0; i < countof(cached_pkts->pkt); ++i) {
+ /* One-based index for PXE call */
+ rc = pxe_get_cached_info(
+ i + 1,
+ &cached_pkts->pkt[i].buffer,
+ &cached_pkts->pkt[i].len
+ );
+ if (rc) {
+ printf("Error %d fetching cached packet #%u\n", rc, i + 1);
+ cached_pkts->pkt[i] = new_cached_pkt;
+ continue;
+ }
+ }
+
+ return EXIT_SUCCESS;
+ }
+
+/*
+ * Caller is responsible for cached_pkts != NULL and for
+ * initializing *cached_pkts (no garbage pointers, please)
+ */
+static int dump_cached_pkts(struct cached_pkts * cached_pkts) {
+ unsigned int i;
+
+ for (i = 0; i < countof(cached_pkts->pkt); ++i) {
+ /* Display a one-based index */
+ printf("Packet #%u\n", i + 1);
+ if (cached_pkts->pkt[i].buffer) {
+ hexdump(cached_pkts->pkt[i].buffer, cached_pkts->pkt[i].len);
+ dump_cached_pkt(cached_pkts->pkt + i);
+ } else {
+ printf("No packet available.\n");
+ }
+ }
+
+ return EXIT_SUCCESS;
+ }
+
+/*
+ * Caller is responsible for cached_pkts != NULL and for
+ * initializing *cached_pkts (no garbge pointers, please).
+ * This function leaves *cached_pkts suitably re-initialized
+ * for future use
+ */
+static void free_cached_pkts(struct cached_pkts * cached_pkts) {
+ unsigned int i;
+
+ for (i = 0; i < countof(cached_pkts->pkt); ++i) {
+ free(cached_pkts->pkt[i].buffer);
+ }
+ *cached_pkts = new_cached_pkts;
+ }
+
+/*
+ * Caller is responsible for cached_pkt != NULL and for
+ * initializing *cached_pkt (no garbge pointers, please)
+ */
+static void dump_cached_pkt(struct cached_pkt * cached_pkt) {
+ pxe_bootp_t * pkt;
+ struct ipaddr_str cip;
+ struct ipaddr_str yip;
+ struct ipaddr_str sip;
+ struct ipaddr_str gip;
+
+ pkt = cached_pkt->buffer;
+ mk_ipaddr(&cip, pkt->cip),
+ mk_ipaddr(&yip, pkt->yip),
+ mk_ipaddr(&sip, pkt->sip),
+ mk_ipaddr(&gip, pkt->gip),
+ printf(
+ "opcode: %u Hardware: %u Hardlen: %u Gatehops: %u ident: %08x\n"
+ "seconds: %u Flags: %u cip: %s yip: %s\n"
+ "sip: %s gip: %s\n"
+ "Sname: %.64s\n"
+ "bootfile: %.128s\n",
+ pkt->opcode,
+ pkt->Hardware,
+ pkt->Hardlen,
+ pkt->Gatehops,
+ pkt->ident,
+ pkt->seconds,
+ pkt->Flags,
+ cip.v,
+ yip.v,
+ sip.v,
+ gip.v,
+ pkt->Sname,
+ pkt->bootfile
+ );
+ }
+
+/* Caller is responsible for ipaddr_str != NULL */
+static int mk_ipaddr(struct ipaddr_str * ipaddr_str, in_addr_t addr) {
+ sprintf(
+ ipaddr_str->v,
+ "%u.%u.%u.%u",
+ addr & 0xFF,
+ addr >> 8 & 0xFF,
+ addr >> 16 & 0xFF,
+ addr >> 24 & 0xFF
+ );
+ return EXIT_SUCCESS;
+ }
+
+/* Caller is responsible for memory != NULL */
+static void hexdump(const void * memory, size_t bytes) {
+ const unsigned int columns = 16;
+ const unsigned char * p;
+ const unsigned char * q;
+ unsigned int i;
+
+ p = memory;
+ while (bytes) {
+ q = p;
+ /* Print a row, starting with the address */
+ printf("%08X: ", (size_t) p);
+
+ /* Display the hex view */
+ for (i = 0; i < columns && bytes; ++i) {
+ printf("%02X ", *p);
+ ++p;
+ --bytes;
+ }
+
+ /* Reset the count of bytes for the ASCII view */
+ bytes += i;
+
+ /* Pad the hex view */
+ while (i < columns) {
+ printf("XX ");
+ ++i;
+ }
+
+ /* Display the ASCII view */
+ printf("| ");
+ p = q;
+ for (i = 0; i < columns && bytes; ++i) {
+ printf("%c", isprint(*p) && !isspace(*p) ? *p : ' ');
+ ++p;
+ --bytes;
+ }
+
+ /* Pad the ASCII view */
+ while (i < columns) {
+ printf(" ");
+ ++i;
+ }
+ printf(" |\n");
+ }
+ }
--
1.7.11.4
More information about the Syslinux
mailing list