Shao Miller
2012-Oct-03 02:26 UTC
[syslinux] [PATCH] pxedump.c32: Simple PXE cached packet dumping
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
Shao Miller
2012-Oct-03 02:29 UTC
[syslinux] [PATCH] pxedump.c32: Simple PXE cached packet dumping
Not much to it, but thought I'd offer. Oops... With attachment, this time. - 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 -------------- next part -------------->From c668e24421a344231fc3fba31a26c88e92d03f43 Mon Sep 17 00:00:00 2001From: 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