diff options
-rw-r--r-- | com32/lua/src/Makefile | 1 | ||||
-rw-r--r-- | com32/lua/src/dhcp.c | 358 | ||||
-rw-r--r-- | com32/lua/src/dhcp.h | 49 | ||||
-rw-r--r-- | com32/lua/src/linit.c | 1 | ||||
-rw-r--r-- | com32/lua/src/lualib.h | 3 |
5 files changed, 412 insertions, 0 deletions
diff --git a/com32/lua/src/Makefile b/com32/lua/src/Makefile index 14b0e33d..f03f7a7f 100644 --- a/com32/lua/src/Makefile +++ b/com32/lua/src/Makefile @@ -44,6 +44,7 @@ LIBLUA_OBJS += dmi.o LIBLUA_OBJS += cpu.o LIBLUA_OBJS += pci.o LIBLUA_OBJS += vesa.o +LIBLUA_OBJS += dhcp.o CFLAGS += -DLUA_ANSI diff --git a/com32/lua/src/dhcp.c b/com32/lua/src/dhcp.c new file mode 100644 index 00000000..af948131 --- /dev/null +++ b/com32/lua/src/dhcp.c @@ -0,0 +1,358 @@ +/* ----------------------------------------------------------------------- * + * + * 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; +} diff --git a/com32/lua/src/dhcp.h b/com32/lua/src/dhcp.h new file mode 100644 index 00000000..a398cfc1 --- /dev/null +++ b/com32/lua/src/dhcp.h @@ -0,0 +1,49 @@ +/* ----------------------------------------------------------------------- * + * + * 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; + diff --git a/com32/lua/src/linit.c b/com32/lua/src/linit.c index 6c7f63e4..6e978736 100644 --- a/com32/lua/src/linit.c +++ b/com32/lua/src/linit.c @@ -33,6 +33,7 @@ static const luaL_Reg lualibs[] = { {LUA_PCILIBNAME, luaopen_pci}, {LUA_SYSLINUXLIBNAME, luaopen_syslinux}, {LUA_VESALIBNAME, luaopen_vesa}, + {LUA_DHCPLIBNAME, luaopen_dhcp}, #endif {NULL, NULL} }; diff --git a/com32/lua/src/lualib.h b/com32/lua/src/lualib.h index 0ae6ba75..40d1bf29 100644 --- a/com32/lua/src/lualib.h +++ b/com32/lua/src/lualib.h @@ -54,6 +54,9 @@ LUALIB_API int (luaopen_vesa) (lua_State *L); #define LUA_CPULIBNAME "cpu" LUALIB_API int (luaopen_cpu) (lua_State *L); + +#define LUA_DHCPLIBNAME "dhcp" +LUALIB_API int (luaopen_dhcp) (lua_State *L); #endif /* open all previous libraries */ |