source: bootcd/isolinux/syslinux-6.03/com32/lua/src/dhcp.c @ 26ffad7

Last change on this file since 26ffad7 was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 9.7 KB
Line 
1/* ----------------------------------------------------------------------- *
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}
Note: See TracBrowser for help on using the repository browser.