blob: 14a393483b5fdcc6347a1276e70df9696a2e7b8d [file] [log] [blame]
Greg Hartman76d05dc2016-11-23 15:51:27 -08001/* ----------------------------------------------------------------------- *
2 *
3 * Copyright 2007 H. Peter Anvin - All Rights Reserved
4 * Copyright 2011 Timothy J Gleason <timmgleason_at_gmail.com> - All Rights Reserved
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following
13 * conditions:
14 *
15 * The above copyright notice and this permission notice shall
16 * be included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * ----------------------------------------------------------------------- */
28
29/*
30 * dhcp.c
31 *
32 * Adds DHCPINFO functionality to the lua.c32 binary
33 *
34 * gettable() returns a table of the BOOTP message fields returned by
35 * the DHCP server for use in a Lua pxeboot script
36 * See http://tools.ietf.org/html/rfc1542
37 *
38 * lua key value RFC key
39 * -----------------------------------------------------------------------
40 * opcode op message opcode
41 * hardware.type htype Hardware address type
42 * hardware.length hlen Hardware address length
43 * hops hops Used by relay agents
44 * transaction.id xid transaction id
45 * elapsed.seconds secs Secs elapsed since client boot
46 * flags flags DHCP Flags field
47 * client.ip.addr ciaddr client IP addr
48 * your.ip.addr yiaddr 'Your' IP addr. (from server)
49 * server.ip.addr siaddr Boot server IP addr
50 * gateway.ip.addr giaddr Relay agent IP addr
51 * client.mac chaddr Client hardware addr
52 * server.hostname sname Optl. boot server hostname
53 * boot.file file boot file name (ascii path)
54 * magic.cookie cookie Magic cookie
55 *
56 * getoptions() returns a table of the DHCP Options field of the BOOTP
57 * message returned by the DHCP server for use in a Lua pxeboot script.
58 * Many of the options are reurned formatted in as strings in a standard,
59 * recognizable format, such as IP addresses.
60 *
61 * 1, 2, and 4 byte numerical options are returned as integers.
62 *
63 * Other Options with non-standard formats are returned as strings of the
64 * raw binary number that was returned by the DHCP server and must be decoded
65 * in a Lua script
66 *
67 * The Options table returns the Option code as the key except where there
68 * are multiple values returned. In those cases, an extra key increment number
69 * is added to allow individual access to each Option value.
70 *
71 * lua key value value Name
72 * -----------------------------------------------------------------------
73 * 1 Subnet Mask
74 * 6.1 DNS Server [element 1]
75 * 6.2 DNS Server [element 2]
76 * 6.3 DNS Server [element 3]
77 * 209 PXE Configuration File
78 * 21.1 Policy Filter [element 1]
79 * 21.2 Policy Filter [element 2]
80 *
81 * Options that can have a list of values, but contain only one (like Option 6)
82 * will not return with .sub key values.
83 *
84 * Usage:
85 t = dhcp.gettable()
86
87 for k,v in pairs(t) do
88 print(k.." : "..v)
89 end
90 */
91
92#include <stdio.h>
93#include "dhcp.h"
94#include "lua.h"
95#include "lauxlib.h"
96#include "lualib.h"
97#include <syslinux/pxe.h>
98
99#define STR_BUF_SIZE 129 /* Sized to accomdate File field in BOOTP message */
100
101void
102ip_address_list(lua_State *L, uint8_t* value, uint8_t len, uint8_t option )
103{
104 static char op_name[64];
105 static char op_value[255];
106 int loop;
107
108 loop = len/4;
109
110 if ( loop == 1) {
111 sprintf(op_name, "%u", option);
112 lua_pushstring(L, op_name);
113 sprintf(op_value, "%u.%u.%u.%u", value[0], value[1], value[2], value[3]);
114 lua_pushstring(L, op_value);
115 lua_settable(L,-3);
116 } else {
117 for (int done = 0; done < loop; done++){
118 sprintf(op_name, "%u.%d", option, done+1);
119 lua_pushstring(L, op_name);
120 sprintf(op_value, "%u.%u.%u.%u", value[0+(done*4)], value[1+(done*4)], value[2+(done*4)], value[3+(done*4)]);
121 lua_pushstring(L, op_value);
122 lua_settable(L,-3);
123 }
124 }
125
126}
127
128static int dhcp_getoptions(lua_State *L)
129{
130 void* dhcpdata = 0;
131 dhcp_t* dhcp = 0;
132 size_t dhcplen = 0;
133
134 /* Append the DHCP info */
135 if (pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK,
136 &dhcpdata, &dhcplen))
137 {
138 return 0;
139 }
140
141 dhcp = (dhcp_t*)dhcpdata;
142
143 lua_newtable(L);
144
145 int done = 0;
146 uint8_t* ptr = (uint8_t*)&dhcp->options;
147 uint8_t len;
148 uint8_t option;
149 uint8_t* value;
150 static char op_name[64];
151
152 do {
153 option = *ptr++;
154 len = *ptr++;
155 value = ptr;
156 ptr += len;
157 switch (option) {
158// IP Address formatted lists, including singles
159 case 1:
160 case 3:
161 case 4:
162 case 5:
163 case 6:
164 case 7:
165 case 8:
166 case 9:
167 case 10:
168 case 11:
169 case 16:
170 case 21: /* Policy Filters - address/mask */
171 case 28:
172 case 32:
173 case 33: /* Static routes - destination/router */
174 case 41:
175 case 42:
176 case 44:
177 case 45:
178 case 47:
179 case 48:
180 case 49:
181 case 50:
182 case 51:
183 case 54:
184 case 65:
185 case 68:
186 case 69:
187 case 70:
188 case 71:
189 case 72:
190 case 73:
191 case 74:
192 case 75:
193 case 76:
194 ip_address_list(L, value, len, option);
195 break;
196// 4byte options - numerical
197 case 2:
198 case 24:
199 case 35:
200 case 38:
201 case 58:
202 case 59:
203 case 211:
204 sprintf(op_name, "%u", option);
205 lua_pushstring(L, op_name);
206 lua_pushinteger(L, ntohl(*(long*)value));
207 lua_settable(L,-3);
208 break;
209// 2byte options -numerical
210 case 13:
211 case 22:
212 case 26:
213 case 57:
214 sprintf(op_name, "%u", option);
215 lua_pushstring(L, op_name);
216 lua_pushinteger(L, ntohs(*(short*)value));
217 lua_settable(L,-3);
218 break;
219// 1byte options - numerical
220 case 19:
221 case 20:
222 case 23:
223 case 27:
224 case 29:
225 case 30:
226 case 31:
227 case 34:
228 case 36:
229 case 37:
230 case 39:
231 case 46:
232 case 52:
233 case 53:
234 sprintf(op_name, "%u", option);
235 lua_pushstring(L, op_name);
236 lua_pushinteger(L, *value);
237 lua_settable(L,-3);
238 break;
239 case 255:
240 done = 1;
241 break;
242 default:
243 sprintf(op_name, "%u", option);
244 lua_pushstring(L, op_name);
245 lua_pushlstring(L, (const char*)value, len);
246 lua_settable(L,-3);
247 break;
248 }
249
250 } while (!done);
251
252 return 1;
253}
254
255static int dhcp_gettable(lua_State *L)
256{
257 void* dhcpdata = 0;
258 dhcp_t* dhcp = 0;
259 size_t dhcplen = 0;
260 static char dhcp_arg[STR_BUF_SIZE];
261
262 /* Append the DHCP info */
263 if (pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK,
264 &dhcpdata, &dhcplen))
265 {
266 return 0;
267 }
268
269 dhcp = (dhcp_t*)dhcpdata;
270
271
272 lua_newtable(L);
273
274 lua_pushstring(L, "opcode");
275 lua_pushinteger(L, dhcp->op);
276 lua_settable(L,-3);
277
278 lua_pushstring(L, "hardware.type");
279 lua_pushinteger(L, dhcp->htype);
280 lua_settable(L,-3);
281
282 lua_pushstring(L, "hardware.length");
283 lua_pushinteger(L, dhcp->hlen);
284 lua_settable(L,-3);
285
286 lua_pushstring(L, "hops");
287 lua_pushinteger(L, dhcp->hops);
288 lua_settable(L,-3);
289
290 lua_pushstring(L, "transaction.id");
291 lua_pushinteger(L, ntohl(dhcp->xid));
292 lua_settable(L,-3);
293
294 lua_pushstring(L, "elapsed.seconds");
295 lua_pushinteger(L, ntohs(dhcp->secs));
296 lua_settable(L,-3);
297
298 lua_pushstring(L, "flags");
299 lua_pushinteger(L, ntohs(dhcp->flags));
300 lua_settable(L,-3);
301
302 sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->ciaddr[0], dhcp->ciaddr[1], dhcp->ciaddr[2], dhcp->ciaddr[3]);
303 lua_pushstring(L, "client.ip.addr");
304 lua_pushstring(L, dhcp_arg);
305 lua_settable(L,-3);
306
307 sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->yiaddr[0], dhcp->yiaddr[1], dhcp->yiaddr[2], dhcp->yiaddr[3]);
308 lua_pushstring(L, "your.ip.addr");
309 lua_pushstring(L, dhcp_arg);
310 lua_settable(L,-3);
311
312 sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->siaddr[0], dhcp->siaddr[1], dhcp->siaddr[2], dhcp->siaddr[3]);
313 lua_pushstring(L, "server.ip.addr");
314 lua_pushstring(L, dhcp_arg);
315 lua_settable(L,-3);
316
317 sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->giaddr[0], dhcp->giaddr[1], dhcp->giaddr[2], dhcp->giaddr[3]);
318 lua_pushstring(L, "gateway.ip.addr");
319 lua_pushstring(L, dhcp_arg);
320 lua_settable(L,-3);
321
322 sprintf(dhcp_arg, "%02X:%02X:%02X:%02X:%02X:%02X",
323 dhcp->chaddr[0], dhcp->chaddr[1], dhcp->chaddr[2],
324 dhcp->chaddr[3], dhcp->chaddr[4], dhcp->chaddr[5]);
325 lua_pushstring(L, "client.mac");
326 lua_pushstring(L, dhcp_arg);
327 lua_settable(L,-3);
328
329 snprintf(dhcp_arg, STR_BUF_SIZE, "%s", dhcp->sname);
330 dhcp_arg[STR_BUF_SIZE-1] = 0; /* Guarantee for lua_pushstring that dhcp_arg is 0 terminated /*/
331 lua_pushstring(L, "server.hostname");
332 lua_pushstring(L, dhcp_arg);
333 lua_settable(L,-3);
334
335 snprintf(dhcp_arg, STR_BUF_SIZE, "%s", dhcp->file);
336 dhcp_arg[STR_BUF_SIZE-1] = 0; /* Guarantee for lua_pushstring that dhcp_arg is 0 terminated /*/
337 lua_pushstring(L, "boot.file");
338 lua_pushstring(L, dhcp_arg);
339 lua_settable(L,-3);
340
341 sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->cookie[0], dhcp->cookie[1], dhcp->cookie[2], dhcp->cookie[3]);
342 lua_pushstring(L, "magic.cookie");
343 lua_pushstring(L, dhcp_arg);
344 lua_settable(L,-3);
345
346 return 1;
347}
348
349static const luaL_Reg dhcplib[] = {
350 {"gettable", dhcp_gettable},
351 {"getoptions", dhcp_getoptions},
352 {NULL, NULL}
353};
354
355LUALIB_API int luaopen_dhcp (lua_State *L) {
356 luaL_newlib(L, dhcplib);
357 return 1;
358}