--- /dev/null
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007 H. Peter Anvin - All Rights Reserved
+ * Copyright 2011 Timothy J Gleason <timmgleason_at_gmail.com> - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * dhcp.c
+ *
+ * Adds DHCPINFO functionality to the lua.c32 binary
+ *
+ * gettable() returns a table of the BOOTP message fields returned by
+ * the DHCP server for use in a Lua pxeboot script
+ * See http://tools.ietf.org/html/rfc1542
+ *
+ * lua key value RFC key
+ * -----------------------------------------------------------------------
+ * opcode op message opcode
+ * hardware.type htype Hardware address type
+ * hardware.length hlen Hardware address length
+ * hops hops Used by relay agents
+ * transaction.id xid transaction id
+ * elapsed.seconds secs Secs elapsed since client boot
+ * flags flags DHCP Flags field
+ * client.ip.addr ciaddr client IP addr
+ * your.ip.addr yiaddr 'Your' IP addr. (from server)
+ * server.ip.addr siaddr Boot server IP addr
+ * gateway.ip.addr giaddr Relay agent IP addr
+ * client.mac chaddr Client hardware addr
+ * server.hostname sname Optl. boot server hostname
+ * boot.file file boot file name (ascii path)
+ * magic.cookie cookie Magic cookie
+ *
+ * getoptions() returns a table of the DHCP Options field of the BOOTP
+ * message returned by the DHCP server for use in a Lua pxeboot script.
+ * Many of the options are reurned formatted in as strings in a standard,
+ * recognizable format, such as IP addresses.
+ *
+ * 1, 2, and 4 byte numerical options are returned as integers.
+ *
+ * Other Options with non-standard formats are returned as strings of the
+ * raw binary number that was returned by the DHCP server and must be decoded
+ * in a Lua script
+ *
+ * The Options table returns the Option code as the key except where there
+ * are multiple values returned. In those cases, an extra key increment number
+ * is added to allow individual access to each Option value.
+ *
+ * lua key value value Name
+ * -----------------------------------------------------------------------
+ * 1 Subnet Mask
+ * 6.1 DNS Server [element 1]
+ * 6.2 DNS Server [element 2]
+ * 6.3 DNS Server [element 3]
+ * 209 PXE Configuration File
+ * 21.1 Policy Filter [element 1]
+ * 21.2 Policy Filter [element 2]
+ *
+ * Options that can have a list of values, but contain only one (like Option 6)
+ * will not return with .sub key values.
+ *
+ * Usage:
+ t = dhcp.gettable()
+
+ for k,v in pairs(t) do
+ print(k.." : "..v)
+ end
+ */
+
+#include <stdio.h>
+#include "dhcp.h"
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+#include <syslinux/pxe.h>
+
+#define STR_BUF_SIZE 129 /* Sized to accomdate File field in BOOTP message */
+
+void
+ip_address_list(lua_State *L, uint8_t* value, uint8_t len, uint8_t option )
+{
+ static char op_name[64];
+ static char op_value[255];
+ int loop;
+
+ loop = len/4;
+
+ if ( loop == 1) {
+ sprintf(op_name, "%u", option);
+ lua_pushstring(L, op_name);
+ sprintf(op_value, "%u.%u.%u.%u", value[0], value[1], value[2], value[3]);
+ lua_pushstring(L, op_value);
+ lua_settable(L,-3);
+ } else {
+ for (int done = 0; done < loop; done++){
+ sprintf(op_name, "%u.%d", option, done+1);
+ lua_pushstring(L, op_name);
+ sprintf(op_value, "%u.%u.%u.%u", value[0+(done*4)], value[1+(done*4)], value[2+(done*4)], value[3+(done*4)]);
+ lua_pushstring(L, op_value);
+ lua_settable(L,-3);
+ }
+ }
+
+}
+
+static int dhcp_getoptions(lua_State *L)
+{
+ void* dhcpdata = 0;
+ dhcp_t* dhcp = 0;
+ size_t dhcplen = 0;
+
+ /* Append the DHCP info */
+ if (pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK,
+ &dhcpdata, &dhcplen))
+ {
+ return 0;
+ }
+
+ dhcp = (dhcp_t*)dhcpdata;
+
+ lua_newtable(L);
+
+ int done = 0;
+ uint8_t* ptr = (uint8_t*)&dhcp->options;
+ uint8_t len;
+ uint8_t option;
+ uint8_t* value;
+ static char op_name[64];
+
+ do {
+ option = *ptr++;
+ len = *ptr++;
+ value = ptr;
+ ptr += len;
+ switch (option) {
+// IP Address formatted lists, including singles
+ case 1:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 16:
+ case 21: /* Policy Filters - address/mask */
+ case 28:
+ case 32:
+ case 33: /* Static routes - destination/router */
+ case 41:
+ case 42:
+ case 44:
+ case 45:
+ case 47:
+ case 48:
+ case 49:
+ case 50:
+ case 51:
+ case 54:
+ case 65:
+ case 68:
+ case 69:
+ case 70:
+ case 71:
+ case 72:
+ case 73:
+ case 74:
+ case 75:
+ case 76:
+ ip_address_list(L, value, len, option);
+ break;
+// 4byte options - numerical
+ case 2:
+ case 24:
+ case 35:
+ case 38:
+ case 58:
+ case 59:
+ case 211:
+ sprintf(op_name, "%u", option);
+ lua_pushstring(L, op_name);
+ lua_pushinteger(L, ntohl(*(long*)value));
+ lua_settable(L,-3);
+ break;
+// 2byte options -numerical
+ case 13:
+ case 22:
+ case 26:
+ case 57:
+ sprintf(op_name, "%u", option);
+ lua_pushstring(L, op_name);
+ lua_pushinteger(L, ntohs(*(short*)value));
+ lua_settable(L,-3);
+ break;
+// 1byte options - numerical
+ case 19:
+ case 20:
+ case 23:
+ case 27:
+ case 29:
+ case 30:
+ case 31:
+ case 34:
+ case 36:
+ case 37:
+ case 39:
+ case 46:
+ case 52:
+ case 53:
+ sprintf(op_name, "%u", option);
+ lua_pushstring(L, op_name);
+ lua_pushinteger(L, *value);
+ lua_settable(L,-3);
+ break;
+ case 255:
+ done = 1;
+ break;
+ default:
+ sprintf(op_name, "%u", option);
+ lua_pushstring(L, op_name);
+ lua_pushlstring(L, (const char*)value, len);
+ lua_settable(L,-3);
+ break;
+ }
+
+ } while (!done);
+
+ return 1;
+}
+
+static int dhcp_gettable(lua_State *L)
+{
+ void* dhcpdata = 0;
+ dhcp_t* dhcp = 0;
+ size_t dhcplen = 0;
+ static char dhcp_arg[STR_BUF_SIZE];
+
+ /* Append the DHCP info */
+ if (pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK,
+ &dhcpdata, &dhcplen))
+ {
+ return 0;
+ }
+
+ dhcp = (dhcp_t*)dhcpdata;
+
+
+ lua_newtable(L);
+
+ lua_pushstring(L, "opcode");
+ lua_pushinteger(L, dhcp->op);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "hardware.type");
+ lua_pushinteger(L, dhcp->htype);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "hardware.length");
+ lua_pushinteger(L, dhcp->hlen);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "hops");
+ lua_pushinteger(L, dhcp->hops);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "transaction.id");
+ lua_pushinteger(L, ntohl(dhcp->xid));
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "elapsed.seconds");
+ lua_pushinteger(L, ntohs(dhcp->secs));
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "flags");
+ lua_pushinteger(L, ntohs(dhcp->flags));
+ lua_settable(L,-3);
+
+ sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->ciaddr[0], dhcp->ciaddr[1], dhcp->ciaddr[2], dhcp->ciaddr[3]);
+ lua_pushstring(L, "client.ip.addr");
+ lua_pushstring(L, dhcp_arg);
+ lua_settable(L,-3);
+
+ sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->yiaddr[0], dhcp->yiaddr[1], dhcp->yiaddr[2], dhcp->yiaddr[3]);
+ lua_pushstring(L, "your.ip.addr");
+ lua_pushstring(L, dhcp_arg);
+ lua_settable(L,-3);
+
+ sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->siaddr[0], dhcp->siaddr[1], dhcp->siaddr[2], dhcp->siaddr[3]);
+ lua_pushstring(L, "server.ip.addr");
+ lua_pushstring(L, dhcp_arg);
+ lua_settable(L,-3);
+
+ sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->giaddr[0], dhcp->giaddr[1], dhcp->giaddr[2], dhcp->giaddr[3]);
+ lua_pushstring(L, "gateway.ip.addr");
+ lua_pushstring(L, dhcp_arg);
+ lua_settable(L,-3);
+
+ sprintf(dhcp_arg, "%02X:%02X:%02X:%02X:%02X:%02X",
+ dhcp->chaddr[0], dhcp->chaddr[1], dhcp->chaddr[2],
+ dhcp->chaddr[3], dhcp->chaddr[4], dhcp->chaddr[5]);
+ lua_pushstring(L, "client.mac");
+ lua_pushstring(L, dhcp_arg);
+ lua_settable(L,-3);
+
+ snprintf(dhcp_arg, STR_BUF_SIZE, "%s", dhcp->sname);
+ dhcp_arg[STR_BUF_SIZE-1] = 0; /* Guarantee for lua_pushstring that dhcp_arg is 0 terminated /*/
+ lua_pushstring(L, "server.hostname");
+ lua_pushstring(L, dhcp_arg);
+ lua_settable(L,-3);
+
+ snprintf(dhcp_arg, STR_BUF_SIZE, "%s", dhcp->file);
+ dhcp_arg[STR_BUF_SIZE-1] = 0; /* Guarantee for lua_pushstring that dhcp_arg is 0 terminated /*/
+ lua_pushstring(L, "boot.file");
+ lua_pushstring(L, dhcp_arg);
+ lua_settable(L,-3);
+
+ sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->cookie[0], dhcp->cookie[1], dhcp->cookie[2], dhcp->cookie[3]);
+ lua_pushstring(L, "magic.cookie");
+ lua_pushstring(L, dhcp_arg);
+ lua_settable(L,-3);
+
+ return 1;
+}
+
+static const luaL_reg dhcplib[] = {
+ {"gettable", dhcp_gettable},
+ {"getoptions", dhcp_getoptions},
+ {NULL, NULL}
+};
+
+LUALIB_API int luaopen_dhcp (lua_State *L) {
+ luaL_openlib(L, LUA_DHCPLIBNAME, dhcplib, 0);
+ return 1;
+}
--- /dev/null
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007 H. Peter Anvin - All Rights Reserved
+ * Copyright 2011 Timothy J Gleason <timmgleason_at_gmail.com> - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdint.h>
+
+typedef struct dhcp {
+ uint8_t op; /* message opcode */
+ uint8_t htype; /* Hardware address type */
+ uint8_t hlen; /* Hardware address length */
+ uint8_t hops; /* Used by relay agents */
+ uint32_t xid; /* transaction id */
+ uint16_t secs; /* Secs elapsed since client boot */
+ uint16_t flags; /* DHCP Flags field */
+ uint8_t ciaddr[4]; /* client IP addr */
+ uint8_t yiaddr[4]; /* 'Your' IP addr. (from server) */
+ uint8_t siaddr[4]; /* Boot server IP addr */
+ uint8_t giaddr[4]; /* Relay agent IP addr */
+ uint8_t chaddr[16]; /* Client hardware addr */
+ uint8_t sname[64]; /* Optl. boot server hostname */
+ uint8_t file[128]; /* boot file name (ascii path) */
+ uint8_t cookie[4]; /* Magic cookie */
+ uint8_t options[1020]; /* Options */
+} dhcp_t;
+