[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