| /* ----------------------------------------------------------------------- * |
| * |
| * Copyright 2010-2011 Gene Cumm - All Rights Reserved |
| * |
| * Portions from chain.c: |
| * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved |
| * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin |
| * Significant portions copyright (C) 2010 Shao Miller |
| * [partition iteration, GPT, "fs"] |
| * |
| * 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. |
| * |
| * ----------------------------------------------------------------------- */ |
| |
| /* |
| * prdhcp.c |
| * |
| * Print the contents of the 3 DHCP packets |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <consoles.h> |
| #include <console.h> |
| #include <errno.h> |
| #include <string.h> |
| #include <syslinux/config.h> |
| #include <syslinux/loadfile.h> |
| #include <syslinux/bootrm.h> |
| #include <syslinux/video.h> |
| #include <com32.h> |
| #include <stdint.h> |
| #include <syslinux/pxe.h> |
| #include <sys/gpxe.h> |
| #include <unistd.h> |
| #include <getkey.h> |
| |
| #define PRDHCP_DEBUG 0 |
| |
| #define dprintf0(f, ...) ((void)0) |
| |
| #ifdef PRDHCP_DEBUG |
| # define dpressanykey pressanykey |
| # define dprintf printf |
| # define dprint_pxe_bootp_t print_pxe_bootp_t |
| # define dprint_pxe_vendor_blk print_pxe_vendor_blk |
| # define dprint_pxe_vendor_raw print_pxe_vendor_raw |
| #else |
| # define dpressanykey(void) ((void)0) |
| # define dprintf(f, ...) ((void)0) |
| # define dprint_pxe_bootp_t(p, l) ((void)0) |
| # define dprint_pxe_vendor_blk(p, l) ((void)0) |
| # define dprint_pxe_vendor_raw(p, l) ((void)0) |
| #endif |
| |
| #define dprintf_opt_cp dprintf0 |
| #define dprintf_opt_inj dprintf |
| |
| |
| const char app_name_str[] = "prdhcp.c32"; |
| |
| |
| int pressanykey(void) { |
| int inc; |
| |
| printf("Press any key to continue. "); |
| inc = KEY_NONE; |
| while (inc == KEY_NONE) |
| inc = get_key(stdin, 6000); |
| puts(""); |
| return inc; |
| } |
| |
| void print_pxe_vendor_blk(pxe_bootp_t *p, size_t len) |
| { |
| int i, vlen, oplen, j; |
| uint8_t *d; |
| uint32_t magic; |
| if (!p) { |
| printf(" packet pointer is null\n"); |
| return; |
| } |
| vlen = len - ((void *)&(p->vendor) - (void *)p); |
| printf(" Vendor Data: Len=%d", vlen); |
| d = p->vendor.d; |
| /* Print only 256 characters of the vendor/option data */ |
| /* |
| print_pxe_vendor_raw(p, (len - vlen) + 256); |
| vlen = 0; |
| */ |
| magic = ntohl(*((uint32_t *)d)); |
| printf(" Magic: %08X", ntohl(*((uint32_t *)d))); |
| if (magic != VM_RFC1048) /* Invalid DHCP packet */ |
| vlen = 0; |
| for (i = 4; i < vlen; i++) { |
| if (d[i]) /* Skip the padding */ |
| printf("\n @%03X-%3d", i, d[i]); |
| if (d[i] == 255) /* End of list */ |
| break; |
| if (d[i]) { |
| oplen = d[++i]; |
| printf(" l=%3d:", oplen); |
| for (j = (++i + oplen); i < vlen && i < j; i++) { |
| printf(" %02X", d[i]); |
| } |
| i--; |
| } |
| } |
| printf("\n"); |
| } |
| |
| void print_pxe_bootp_t(pxe_bootp_t *p, size_t len) |
| { |
| if (!p) { |
| printf(" packet pointer is null\n"); |
| return; |
| } |
| printf(" op:%02X hw:%02X hl:%02X gh:%02X id:%08X se:%04X f:%04X" |
| " cip:%08X\n", p->opcode, p->Hardware, p->Hardlen, p->Gatehops, |
| ntohl(p->ident), ntohs(p->seconds), ntohs(p->Flags), ntohl(p->cip)); |
| printf(" yip:%08X sip:%08X gip:%08X", |
| ntohl(p->yip), ntohl(p->sip), ntohl(p->gip)); |
| printf(" caddr-%02X:%02X:%02X:%02X:%02X:%02X\n", p->CAddr[0], |
| p->CAddr[1], p->CAddr[2], p->CAddr[3], p->CAddr[4], p->CAddr[5]); |
| printf(" sName: '%s'\n", p->Sname); |
| printf(" bootfile: '%s'\n", p->bootfile); |
| print_pxe_vendor_blk(p, len); |
| } |
| |
| void print_dhcp_pkt_all(void) |
| { |
| pxe_bootp_t *p; |
| size_t len; |
| int i; |
| int ptype[3] = {PXENV_PACKET_TYPE_DHCP_DISCOVER, PXENV_PACKET_TYPE_DHCP_ACK, PXENV_PACKET_TYPE_CACHED_REPLY}; |
| |
| for (i = 0; i < 3; i++) { |
| if (!pxe_get_cached_info(ptype[i], |
| (void **)&(p), &(len))) { |
| dprintf("Got packet #%d/%d\n", (i + 1), ptype[i]); |
| print_pxe_bootp_t(p, len); |
| pressanykey(); |
| } |
| } |
| } |
| |
| int main(void) |
| { |
| int rv= -1; |
| const struct syslinux_version *sv; |
| |
| console_ansi_raw(); |
| sv = syslinux_version(); |
| if (sv->filesystem != SYSLINUX_FS_PXELINUX) { |
| printf("%s: May only run in PXELINUX\n", app_name_str); |
| return -2; |
| } |
| print_dhcp_pkt_all(); |
| return rv; |
| } |