1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 2010-2011 Gene Cumm - All Rights Reserved
4  *
5  *   Portions from chain.c:
6  *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
7  *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
8  *   Significant portions copyright (C) 2010 Shao Miller
9  *					[partition iteration, GPT, "fs"]
10  *
11  *   This program is free software; you can redistribute it and/or modify
12  *   it under the terms of the GNU General Public License as published by
13  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
14  *   Boston MA 02111-1307, USA; either version 2 of the License, or
15  *   (at your option) any later version; incorporated herein by reference.
16  *
17  * ----------------------------------------------------------------------- */
18 
19 /*
20  * prdhcp.c
21  *
22  * Print the contents of the 3 DHCP packets
23  */
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <consoles.h>
28 #include <console.h>
29 #include <errno.h>
30 #include <string.h>
31 #include <syslinux/config.h>
32 #include <syslinux/loadfile.h>
33 #include <syslinux/bootrm.h>
34 #include <syslinux/video.h>
35 #include <com32.h>
36 #include <stdint.h>
37 #include <syslinux/pxe.h>
38 #include <sys/gpxe.h>
39 #include <unistd.h>
40 #include <getkey.h>
41 
42 #define PRDHCP_DEBUG 0
43 
44 #define dprintf0(f, ...)		((void)0)
45 
46 #ifdef PRDHCP_DEBUG
47 #  define dpressanykey			pressanykey
48 #  define dprintf			printf
49 #  define dprint_pxe_bootp_t		print_pxe_bootp_t
50 #  define dprint_pxe_vendor_blk		print_pxe_vendor_blk
51 #  define dprint_pxe_vendor_raw		print_pxe_vendor_raw
52 #else
53 #  define dpressanykey(void)		((void)0)
54 #  define dprintf(f, ...)		((void)0)
55 #  define dprint_pxe_bootp_t(p, l)	((void)0)
56 #  define dprint_pxe_vendor_blk(p, l)	((void)0)
57 #  define dprint_pxe_vendor_raw(p, l)	((void)0)
58 #endif
59 
60 #define dprintf_opt_cp	dprintf0
61 #define dprintf_opt_inj	dprintf
62 
63 
64 const char app_name_str[] = "prdhcp.c32";
65 
66 
pressanykey(void)67 int pressanykey(void) {
68     int inc;
69 
70     printf("Press any key to continue. ");
71     inc = KEY_NONE;
72     while (inc == KEY_NONE)
73 	inc = get_key(stdin, 6000);
74     puts("");
75     return inc;
76 }
77 
print_pxe_vendor_blk(pxe_bootp_t * p,size_t len)78 void print_pxe_vendor_blk(pxe_bootp_t *p, size_t len)
79 {
80     int i, vlen, oplen, j;
81     uint8_t *d;
82     uint32_t magic;
83     if (!p) {
84 	printf("  packet pointer is null\n");
85 	return;
86     }
87     vlen = len - ((void *)&(p->vendor) - (void *)p);
88     printf("  Vendor Data:    Len=%d", vlen);
89     d = p->vendor.d;
90     /* Print only 256 characters of the vendor/option data */
91     /*
92     print_pxe_vendor_raw(p, (len - vlen) + 256);
93     vlen = 0;
94     */
95     magic = ntohl(*((uint32_t *)d));
96     printf("    Magic: %08X", ntohl(*((uint32_t *)d)));
97     if (magic != VM_RFC1048)	/* Invalid DHCP packet */
98 	vlen = 0;
99     for (i = 4; i < vlen; i++) {
100 	if (d[i])	/* Skip the padding */
101 	    printf("\n    @%03X-%3d", i, d[i]);
102 	if (d[i] == 255)	/* End of list */
103 	    break;
104 	if (d[i]) {
105 	    oplen = d[++i];
106 	    printf(" l=%3d:", oplen);
107 	    for (j = (++i + oplen); i < vlen && i < j; i++) {
108 		printf(" %02X", d[i]);
109 	    }
110 	    i--;
111 	}
112     }
113     printf("\n");
114 }
115 
print_pxe_bootp_t(pxe_bootp_t * p,size_t len)116 void print_pxe_bootp_t(pxe_bootp_t *p, size_t len)
117 {
118     if (!p) {
119 	printf("  packet pointer is null\n");
120 	return;
121     }
122     printf("  op:%02X  hw:%02X  hl:%02X  gh:%02X  id:%08X se:%04X f:%04X"
123 	"  cip:%08X\n", p->opcode, p->Hardware, p->Hardlen, p->Gatehops,
124 	ntohl(p->ident), ntohs(p->seconds), ntohs(p->Flags), ntohl(p->cip));
125     printf("  yip:%08X  sip:%08X  gip:%08X",
126 	ntohl(p->yip), ntohl(p->sip), ntohl(p->gip));
127     printf("  caddr-%02X:%02X:%02X:%02X:%02X:%02X\n", p->CAddr[0],
128 	p->CAddr[1], p->CAddr[2], p->CAddr[3], p->CAddr[4], p->CAddr[5]);
129     printf("  sName: '%s'\n", p->Sname);
130     printf("  bootfile: '%s'\n", p->bootfile);
131     print_pxe_vendor_blk(p, len);
132 }
133 
print_dhcp_pkt_all(void)134 void print_dhcp_pkt_all(void)
135 {
136     pxe_bootp_t *p;
137     size_t len;
138     int i;
139     int ptype[3] = {PXENV_PACKET_TYPE_DHCP_DISCOVER, PXENV_PACKET_TYPE_DHCP_ACK, PXENV_PACKET_TYPE_CACHED_REPLY};
140 
141     for (i = 0; i < 3; i++) {
142 	if (!pxe_get_cached_info(ptype[i],
143 		(void **)&(p), &(len))) {
144 	    dprintf("Got packet #%d/%d\n", (i + 1), ptype[i]);
145 	    print_pxe_bootp_t(p, len);
146 	    pressanykey();
147 	}
148     }
149 }
150 
main(void)151 int main(void)
152 {
153     int rv= -1;
154     const struct syslinux_version *sv;
155 
156     console_ansi_raw();
157     sv = syslinux_version();
158     if (sv->filesystem != SYSLINUX_FS_PXELINUX) {
159 	printf("%s: May only run in PXELINUX\n", app_name_str);
160 	return -2;
161     }
162     print_dhcp_pkt_all();
163     return rv;
164 }
165