aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Aleaxander <Aleaxander@gmail.com>2009-08-05 18:58:37 +0800
committerLiu Aleaxander <Aleaxander@gmail.com>2009-08-05 18:58:37 +0800
commit824fd668b821ea48ff5309853a60da7791836ec7 (patch)
tree6dc487bc8e5e32ede3a0b1eb8bf2865fbdd8e593
parentac317a87826518afad5e2492c4cd81db5cb72650 (diff)
downloadpxelinux-824fd668b821ea48ff5309853a60da7791836ec7.tar.gz
pxelinux-824fd668b821ea48ff5309853a60da7791836ec7.tar.xz
pxelinux-824fd668b821ea48ff5309853a60da7791836ec7.zip
Core:PXELINUX: code clean -- 7HEADcore32
break the pxe.c with a new one file, dhcp_option.c, which contains the dhcp options parsing functions
-rw-r--r--core/dhcp_option.c259
-rw-r--r--core/include/pxe.h213
-rw-r--r--core/pxe.c476
3 files changed, 473 insertions, 475 deletions
diff --git a/core/dhcp_option.c b/core/dhcp_option.c
new file mode 100644
index 00000000..f9ff4f22
--- /dev/null
+++ b/core/dhcp_option.c
@@ -0,0 +1,259 @@
+#include <stdio.h>
+#include <string.h>
+#include <core.h>
+#include <pxe.h>
+#include <sys/cpu.h>
+
+void subnet_mask(void *data, int opt_len)
+{
+ if (opt_len != 4)
+ return;
+ Netmask = *(uint32_t *)data;
+}
+
+void router(void *data, int opt_len)
+{
+ if (opt_len != 4)
+ return;
+ Gateway = *(uint32_t *)data;
+}
+
+void dns_servers(void *data, int opt_len)
+{
+ int num = opt_len >> 2;
+ int i;
+
+ if (num > DNS_MAX_SERVERS)
+ num = DNS_MAX_SERVERS;
+
+ for (i = 0; i < num; i++) {
+ DNSServers[i] = *(uint32_t *)data;
+ data += 4;
+ }
+
+ /* NOT SURE FOR NOW */
+ LastDNSServer = OFFS_WRT(&DNSServers[num - 1], 0);
+}
+
+void local_domain(void *data, int opt_len)
+{
+ com32sys_t regs;
+ char *p = (char *)data + opt_len;
+ char end = *p;
+
+ memset(&regs, 0, sizeof regs);
+ *p = '\0'; /* Zero-terminate option */
+ regs.esi.w[0] = OFFS_WRT(data, 0);
+ regs.edi.w[0] = OFFS_WRT(LocalDomain, 0);
+ call16(dns_mangle, &regs, NULL);
+ *p = end; /* Resotre ending byte */
+}
+
+void vendor_encaps(void *data, int opt_len)
+{
+ /* Only recongnize PXELINUX options */
+ parse_dhcp_options(data, opt_len, 208);
+}
+
+void option_overload(void *data, int opt_len)
+{
+ if (opt_len != 1)
+ return;
+ OverLoad = *(uint8_t *)data;
+}
+
+
+void server(void *data, int opt_len)
+{
+ uint32_t ip;
+
+ if (opt_len != 4)
+ return;
+
+ if (ServerIP)
+ return;
+
+ ip = *(uint32_t *)data;
+ if (ip_ok(ip))
+ ServerIP = ip;
+}
+
+void client_identifier(void *data, int opt_len)
+{
+ if (opt_len > MAC_MAX || opt_len < 2 ||
+ MACLen != (opt_len >> 8) ||
+ *(uint8_t *)data != MACType)
+ return;
+
+ opt_len --;
+ MACLen = opt_len & 0xff;
+ memcpy(MAC, data+1, opt_len);
+ MAC[opt_len] = 0;
+}
+
+void bootfile_name(void *data, int opt_len)
+{
+ strncpy(BootFile, data, opt_len);
+ BootFile[opt_len] = 0;
+}
+
+void uuid_client_identifier(void *data, int opt_len)
+{
+ int type = *(uint8_t *)data;
+ if (opt_len != 17 ||
+ (type | HaveUUID))
+ return;
+
+ HaveUUID = 1;
+ UUIDType = type;
+ memcpy(UUID, data+1, 16);
+ UUID[16] = 0;
+}
+
+void pxelinux_configfile(void *data, int opt_len)
+{
+ DHCPMagic |= 2;
+ strncpy(ConfigName, data, opt_len);
+ ConfigName[opt_len] = 0;
+}
+
+void pxelinux_pathprefix(void *data,int opt_len)
+{
+ DHCPMagic |= 4;
+ strncpy(PathPrefix, data, opt_len);
+ PathPrefix[opt_len] = 0;
+}
+
+void pxelinux_reboottime(void *data, int opt_len)
+{
+ if ((opt_len && 0xff) != 4)
+ return ;
+
+ RebootTime = ntohl(*(uint32_t *)data);
+ DHCPMagic |= 8; /* Got reboot time */
+}
+
+
+struct dhcp_options {
+ int opt_num;
+ void (*fun) (void *, int);
+};
+
+struct dhcp_options dhcp_opts[] = {
+ {1, subnet_mask},
+ {3, router},
+ {6, dns_servers},
+ {15, local_domain},
+ {43, vendor_encaps},
+ {52, option_overload},
+ {54, server},
+ {61, client_identifier},
+ {67, bootfile_name},
+ {97, uuid_client_identifier},
+ {209, pxelinux_configfile},
+ {210, pxelinux_pathprefix},
+ {211, pxelinux_reboottime}
+};
+
+/*
+ * Parse a sequence of DHCP options, pointed to by _option_;
+ * -- some DHCP servers leave option fields unterminated
+ * in violation of the spec.
+ *
+ * filter contains the minimum value for the option to recognize
+ * -- this is used to restrict parsing to PXELINUX-specific options only.
+ */
+void parse_dhcp_options(void *option, int size, int filter)
+{
+ uint8_t opt_num;
+ uint8_t opt_len;
+ uint8_t opt_filter = filter == 208 ? 208 : 0;
+ int opt_entries = sizeof(dhcp_opts) / sizeof(dhcp_opts[0]);
+ int i = 0;
+ char *p = option;
+ struct dhcp_options *opt;
+
+ if (opt_filter)
+ printf("***NOTE!:*** we hit a pxelinux-specific options\n");
+
+ while (size --) {
+ opt_num = *p++;
+
+ if (!size)
+ break;
+ if (opt_num == 0)
+ continue;
+ if (opt_num == 0xff)
+ break;
+
+ /* Anything else will have a lenght filed */
+ opt_len = *p++; /* c <- option lenght */
+ size = size - opt_len - 1;
+ if (size < 0)
+ break;
+ if (opt_num < opt_filter) { /* Is the option value valid */
+ option += opt_len; /* Try next */
+ continue;
+ }
+
+ opt = dhcp_opts;
+ for (i = 0; i < opt_entries; i++) {
+ if (opt_num == opt->opt_num) {
+ opt->fun(p, opt_len);
+ break;
+ }
+ opt ++;
+ }
+
+ /* parse next */
+ p += opt_len;
+ }
+}
+
+/*
+ *
+ ;
+ ; parse_dhcp
+ ;
+ ; Parse a DHCP packet. This includes dealing with "overloaded"
+ ; option fields (see RFC 2132, section 9.3)
+ ;
+ ; This should fill in the following global variables, if the
+ ; information is present:
+ ;
+ ; MyIP - client IP address
+ ; ServerIP - boot server IP address
+ ; Netmask - network mask
+ ; Gateway - default gateway router IP
+ ; BootFile - boot file name
+ ; DNSServers - DNS server IPs
+ ; LocalDomain - Local domain name
+ ; MACLen, MAC - Client identifier, if MACLen == 0
+ ;
+ ; This assumes the DHCP packet is in "trackbuf".
+ ;
+*/
+void parse_dhcp(int pkt_len)
+{
+ struct bootp_t *dhcp = (struct bootp_t *)trackbuf;
+ int opt_len;
+
+ OverLoad = 0;
+ if (ip_ok(dhcp->yip))
+ MyIP = dhcp->yip;
+
+ if (ip_ok(dhcp->sip))
+ ServerIP = dhcp->sip;
+
+ opt_len = (char *)dhcp + pkt_len - (char *)&dhcp->options;
+ if (opt_len && (dhcp->option_magic == BOOTP_OPTION_MAGIC))
+ parse_dhcp_options(&dhcp->options, opt_len, 0);
+
+ if (OverLoad & 1)
+ parse_dhcp_options(&dhcp->bootfile, 128, 0);
+ else if (dhcp->bootfile[0])
+ strcpy(BootFile, dhcp->bootfile);
+
+ if (OverLoad & 2)
+ parse_dhcp_options(dhcp->sname, 64, 0);
+}
diff --git a/core/include/pxe.h b/core/include/pxe.h
index 7f30f9a6..b9c71dfb 100644
--- a/core/include/pxe.h
+++ b/core/include/pxe.h
@@ -154,4 +154,217 @@
#define PXENV_STATUS_LOADER_UNDI_START 0xca
#define PXENV_STATUS_LOADER_BC_START 0xcb
+
+
+
+/*
+ * some other defines
+ */
+#define PKTBUF_SIZE (65536 / MAX_OPEN)
+
+#define TFTP_BLOCKSIZE_LG2 9
+#define TFTP_BLOCKSIZE (1 << TFTP_BLOCKSIZE_LG2)
+#define PKTBUF_SEG 0x4000
+#define DNS_MAX_SERVERS 4
+
+#define is_digit(c) (((c) >= '0') && ((c) <= '9'))
+#define htons(x) ( ( ((x) & 0xff) << 8) + ( ((x) &0xff00) >> 8) )
+#define ntohs(x) htons(x)
+#define htonl(x) ( ( ((x) & 0xff) << 24) + ( ((x) & 0xff00) << 8 ) + \
+ ( ((x) & 0xff0000) >> 8 ) + ( ((x) & 0xff000000) >> 24) )
+#define ntohl(x) htonl(x)
+
+/*
+ * TFTP operation codes
+ */
+#define TFTP_RRQ htons(1) // Read rest
+#define TFTP_WRQ htons(2) // Write rest
+#define TFTP_DATA htons(3) // Data packet
+#define TFTP_ACK htons(4) // ACK packet
+#define TFTP_ERROR htons(5) // ERROR packet
+#define TFTP_OACK htons(6) // OACK packet
+
+/*
+ * TFTP error codes
+ */
+#define TFTP_EUNDEF htons(0) // Unspecified error
+#define TFTP_ENOTFOUND htons(1) // File not found
+#define TFTP_EACCESS htons(2) // Access violation
+#define TFTP_ENOSPACE htons(3) // Disk full
+#define TFTP_EBADOP htons(4) // Invalid TFTP operation
+#define TFTP_EBADID htons(5) // Unknown transfer
+#define TFTP_EEXISTS htons(6) // File exists
+#define TFTP_ENOUSER htons(7) // No such user
+#define TFTP_EOPTNEG htons(8) // Option negotiation failure
+
+#define BOOTP_OPTION_MAGIC htonl(0x63825363)
+
+
+/*
+ * structures
+ */
+struct bootp_t {
+ uint8_t opcode; /* BOOTP/DHCP "opcode" */
+ uint8_t hardware; /* ARP hreadware type */
+ uint8_t hardlen; /* Hardware address length */
+ uint8_t gatehops; /* Used by forwarders */
+ uint32_t ident; /* Transaction ID */
+ uint16_t seconds; /* Seconds elapsed */
+ uint16_t flags; /* Broadcast flags */
+ uint32_t cip; /* Cient IP */
+ uint32_t yip; /* "Your" IP */
+ uint32_t sip; /* Next Server IP */
+ uint32_t gip; /* Relay agent IP */
+ uint8_t macaddr[16]; /* Client MAC address */
+ uint8_t sname[64]; /* Server name (optional) */
+ char bootfile[128]; /* Boot file name */
+ uint32_t option_magic; /* Vendor option magic cookie */
+ uint8_t options[1260]; /* Vendor options */
+} __attribute__ ((packed));
+
+struct open_file_t {
+ uint16_t tftp_localport; /* Local port number (0=not in us)*/
+ uint16_t tftp_remoteport; /* Remote port number */
+ uint32_t tftp_remoteip; /* Remote IP address */
+ uint32_t tftp_filepos; /* bytes downloaded (includeing buffer) */
+ uint32_t tftp_filesize; /* Total file size(*) */
+ uint32_t tftp_blksize; /* Block size for this connection(*) */
+ uint16_t tftp_bytesleft; /* Unclaimed data bytes */
+ uint16_t tftp_lastpkt; /* Sequence number of last packet (NBO) */
+ uint16_t tftp_dataptr; /* Pointer to available data */
+ uint8_t tftp_goteof; /* 1 if the EOF packet received */
+ uint8_t tftp_unused[3]; /* Currently unused */
+ uint16_t tftp_pktbuf; /* Packet buffer offset */
+} __attribute__ ((packed));
+extern char Files[];
+
+struct pxe_udp_write_pkt {
+ uint16_t status;
+ uint32_t sip;
+ uint32_t gip;
+ uint16_t lport;
+ uint16_t rport;
+ uint16_t buffersize;
+ uint16_t buffer[2];
+} __attribute__ ((packed));
+
+struct pxe_udp_read_pkt {
+ uint16_t status;
+ uint32_t sip;
+ uint32_t dip;
+ uint16_t rport;
+ uint16_t lport;
+ uint16_t buffersize;
+ uint16_t buffer[2];
+} __attribute__ ((packed));
+
+struct pxe_bootp_query_pkt {
+ uint16_t status;
+ uint16_t packettype;
+ uint16_t buffersize;
+ uint16_t buffer[2];
+ uint16_t bufferlimit;
+} __attribute__ ((packed));
+
+struct pxe_udp_open_pkt {
+ uint16_t status;
+ uint32_t sip;
+} __attribute__ ((packed));
+
+struct gpxe_file_api_check {
+ uint16_t status;
+ uint16_t size;
+ uint32_t magic;
+ uint32_t provider;
+ uint32_t apimask;
+ uint32_t flags;
+} __attribute__ ((packed));
+
+struct gpxe_file_open {
+ uint16_t status;
+ uint16_t filehandle;
+ uint16_t filename[2];
+ uint32_t reserved;
+} __attribute__ ((packed));
+
+struct gpxe_get_file_size {
+ uint16_t status;
+ uint16_t filehandle;
+ uint32_t filesize;
+} __attribute__ ((packed));
+
+struct gpxe_file_read {
+ uint16_t status;
+ uint16_t filehandle;
+ uint16_t buffersize;
+ uint16_t buffer[2];
+} __attribute__ ((packed));
+
+/*
+ * externs
+ */
+extern uint32_t ServerIP;
+extern uint32_t MyIP;
+extern uint32_t Netmask;
+extern uint32_t Gateway;
+extern uint32_t ServerPort;
+
+#define MAC_MAX 32
+extern char MACStr[]; /* MAC address as a string */
+extern char MAC[]; /* Actual MAC address */
+extern char BOOTIFStr[]; /* Space for "BOOTIF=" */
+extern uint8_t MACLen; /* MAC address len */
+extern uint8_t MACType; /* MAC address type */
+
+
+extern uint8_t DHCPMagic;
+extern uint8_t OverLoad;
+extern uint32_t RebootTime;
+
+
+/* TFTP ACK packet */
+extern uint16_t ack_packet_buf[];
+
+extern void kaboom(void);
+extern void dns_mangle(void);
+extern char trackbuf[];
+extern char BootFile[];
+extern char PathPrefix[];
+extern char CurrentDirName[];
+extern char LocalDomain[];
+
+extern char packet_buf[];
+
+extern char IPOption[];
+extern char DotQuadBuf[];
+
+
+extern uint32_t DNSServers[];
+extern uint16_t LastDNSServer;
+
+extern char ConfigName[];
+
+extern uint16_t RealBaseMem;
+extern uint16_t APIVer;
+extern far_ptr_t PXEEntry;
+
+extern far_ptr_t InitStack;
+
+extern int HaveUUID;
+extern uint8_t UUIDType;
+extern char UUID[];
+
+extern volatile uint16_t BIOS_timer;
+
+
+/*
+ * functions
+ */
+int ip_ok(uint32_t);
+void parse_dhcp(int);
+void parse_dhcp_options(void *, int, int);
+
+
+
+
#endif /* pxe.h */
diff --git a/core/pxe.c b/core/pxe.c
index 67079aec..86450d40 100644
--- a/core/pxe.c
+++ b/core/pxe.c
@@ -8,199 +8,12 @@
#define MAX_OPEN (1 << MAX_OPEN_LG2)
#define FILENAME_MAX_LG2 7
#define FILENAME_MAX (1 << FILENAME_MAX_LG2)
-#define PKTBUF_SIZE (65536 / MAX_OPEN)
-
-#define TFTP_BLOCKSIZE_LG2 9
-#define TFTP_BLOCKSIZE (1 << TFTP_BLOCKSIZE_LG2)
-
-
-#define PKTBUF_SEG 0x4000
-
-#define DNS_MAX_SERVERS 4
#define MAX(a,b) (a > b ? a : b)
#define GPXE 1
#define USE_PXE_PROVIDED_STACK 0
-#define is_digit(c) (((c) >= '0') && ((c) <= '9'))
-#define htons(x) ( ( ((x) & 0xff) << 8) + ( ((x) &0xff00) >> 8) )
-#define ntohs(x) htons(x)
-#define htonl(x) ( ( ((x) & 0xff) << 24) + ( ((x) & 0xff00) << 8 ) + \
- ( ((x) & 0xff0000) >> 8 ) + ( ((x) & 0xff000000) >> 24) )
-#define ntohl(x) htonl(x)
-
-/*
- * TFTP operation codes
- */
-#define TFTP_RRQ htons(1) // Read rest
-#define TFTP_WRQ htons(2) // Write rest
-#define TFTP_DATA htons(3) // Data packet
-#define TFTP_ACK htons(4) // ACK packet
-#define TFTP_ERROR htons(5) // ERROR packet
-#define TFTP_OACK htons(6) // OACK packet
-
-/*
- * TFTP error codes
- */
-#define TFTP_EUNDEF htons(0) // Unspecified error
-#define TFTP_ENOTFOUND htons(1) // File not found
-#define TFTP_EACCESS htons(2) // Access violation
-#define TFTP_ENOSPACE htons(3) // Disk full
-#define TFTP_EBADOP htons(4) // Invalid TFTP operation
-#define TFTP_EBADID htons(5) // Unknown transfer
-#define TFTP_EEXISTS htons(6) // File exists
-#define TFTP_ENOUSER htons(7) // No such user
-#define TFTP_EOPTNEG htons(8) // Option negotiation failure
-
-#define BOOTP_OPTION_MAGIC htonl(0x63825363)
-
-struct bootp_t {
- uint8_t opcode; /* BOOTP/DHCP "opcode" */
- uint8_t hardware; /* ARP hreadware type */
- uint8_t hardlen; /* Hardware address length */
- uint8_t gatehops; /* Used by forwarders */
- uint32_t ident; /* Transaction ID */
- uint16_t seconds; /* Seconds elapsed */
- uint16_t flags; /* Broadcast flags */
- uint32_t cip; /* Cient IP */
- uint32_t yip; /* "Your" IP */
- uint32_t sip; /* Next Server IP */
- uint32_t gip; /* Relay agent IP */
- uint8_t macaddr[16]; /* Client MAC address */
- uint8_t sname[64]; /* Server name (optional) */
- char bootfile[128]; /* Boot file name */
- uint32_t option_magic; /* Vendor option magic cookie */
- uint8_t options[1260]; /* Vendor options */
-} __attribute__ ((packed));
-
-struct open_file_t {
- uint16_t tftp_localport; /* Local port number (0=not in us)*/
- uint16_t tftp_remoteport; /* Remote port number */
- uint32_t tftp_remoteip; /* Remote IP address */
- uint32_t tftp_filepos; /* bytes downloaded (includeing buffer) */
- uint32_t tftp_filesize; /* Total file size(*) */
- uint32_t tftp_blksize; /* Block size for this connection(*) */
- uint16_t tftp_bytesleft; /* Unclaimed data bytes */
- uint16_t tftp_lastpkt; /* Sequence number of last packet (NBO) */
- uint16_t tftp_dataptr; /* Pointer to available data */
- uint8_t tftp_goteof; /* 1 if the EOF packet received */
- uint8_t tftp_unused[3]; /* Currently unused */
- uint16_t tftp_pktbuf; /* Packet buffer offset */
-} __attribute__ ((packed));
-extern char Files[];
-
-struct pxe_udp_write_pkt {
- uint16_t status;
- uint32_t sip;
- uint32_t gip;
- uint16_t lport;
- uint16_t rport;
- uint16_t buffersize;
- uint16_t buffer[2];
-} __attribute__ ((packed));
-extern char pxe_udp_write_pkt[];
-
-struct pxe_udp_read_pkt {
- uint16_t status;
- uint32_t sip;
- uint32_t dip;
- uint16_t rport;
- uint16_t lport;
- uint16_t buffersize;
- uint16_t buffer[2];
-} __attribute__ ((packed));
-extern char pxe_udp_read_pkt[];
-
-struct pxe_bootp_query_pkt {
- uint16_t status;
- uint16_t packettype;
- uint16_t buffersize;
- uint16_t buffer[2];
- uint16_t bufferlimit;
-} __attribute__ ((packed));
-extern char pxe_bootp_query_pkt[];
-
-struct pxe_udp_open_pkt {
- uint16_t status;
- uint32_t sip;
-} __attribute__ ((packed));
-extern char pxe_udp_open_pkt[];
-
-struct gpxe_file_api_check {
- uint16_t status;
- uint16_t size;
- uint32_t magic;
- uint32_t provider;
- uint32_t apimask;
- uint32_t flags;
-} __attribute__ ((packed));
-extern char gpxe_file_api_check[];
-
-struct gpxe_file_open {
- uint16_t status;
- uint16_t filehandle;
- uint16_t filename[2];
- uint32_t reserved;
-} __attribute__ ((packed));
-extern char gpxe_file_open[];
-
-struct gpxe_get_file_size {
- uint16_t status;
- uint16_t filehandle;
- uint32_t filesize;
-} __attribute__ ((packed));
-extern char gpxe_get_file_size[];
-
-struct gpxe_file_read {
- uint16_t status;
- uint16_t filehandle;
- uint16_t buffersize;
- uint16_t buffer[2];
-} __attribute__ ((packed));
-extern char gpxe_file_read[];
-
-extern uint32_t ServerIP;
-extern uint32_t MyIP;
-extern uint32_t Netmask;
-extern uint32_t Gateway;
-extern uint32_t ServerPort;
-
-#define MAC_MAX 32
-extern char MACStr[]; /* MAC address as a string */
-extern char MAC[]; /* Actual MAC address */
-extern char BOOTIFStr[]; /* Space for "BOOTIF=" */
-extern uint8_t MACLen; /* MAC address len */
-extern uint8_t MACType; /* MAC address type */
-
-
-extern uint8_t DHCPMagic;
-extern uint8_t OverLoad;
-extern uint32_t RebootTime;
-
-
-/* TFTP ACK packet */
-extern uint16_t ack_packet_buf[];
-
-extern void kaboom(void);
-extern char trackbuf[];
-extern char BootFile[];
-extern char PathPrefix[];
-extern char CurrentDirName[];
-extern char LocalDomain[];
-
-extern char packet_buf[];
-
-extern char IPOption[];
-extern char DotQuadBuf[];
-
-
-extern uint32_t DNSServers[];
-extern uint16_t LastDNSServer;
-
-extern void dhcp_option_list(void);
-extern void dhcp_option_list_end(void);
-
char *err_nopxe = "No !PXE or PXENV+ API found; we're dead...\n";
char *err_pxefailed = "PXE API call failed, error ";
char *err_udpinit = "Failed to initialize UDP stack\n";
@@ -216,37 +29,17 @@ int has_gpxe;
int HaveUUID = 0;
uint8_t UUIDType;
uint8_t uuid_dashes[] = {4, 2, 2, 2, 6, 0};
-extern char UUID[];
-extern char ConfigName[FILENAME_MAX];
-com32sys_t temp;
-
-extern uint16_t RealBaseMem;
-extern uint16_t APIVer;
-extern far_ptr_t PXEEntry;
uint16_t StructPtr[2];
-extern far_ptr_t InitStack;
-
-struct stack {
- uint32_t esp;
- uint16_t ss;
-} __attribute__ ((packed));
-extern char BaseStack[];
-struct stack *stack = (struct stack *)BaseStack;
-
-extern volatile uint16_t BIOS_timer;
static const uint8_t TimeoutTable[] = {
2, 2, 3, 3, 4, 5, 6, 7, 9, 10, 12, 15, 18, 21, 26, 31, 37, 44, 53, 64, 77,
92, 110, 132, 159, 191, 229, 255, 255, 255, 255, 0
};
-
-
char *mode = "octet";
char *tsize_str = "tsize";
-/* We should include the final null here */
-int tsize_len = 6;
+int tsize_len = 6; /* We should include the final null here */
char *blksize_str = "blksize";
int blksize_len = 8;
@@ -254,17 +47,6 @@ int blksize_len = 8;
char *asciidec = "1408";
-
-inline void pusha(com32sys_t *regs)
-{
- memcpy(&temp, regs, sizeof temp);
-}
-
-inline void popa(com32sys_t *regs)
-{
- memcpy(regs, &temp, sizeof temp);
-}
-
/*
* parse the ip_str and return the ip address with *res.
* return the the string address after the ip string
@@ -919,263 +701,7 @@ void get_prefix(void)
-void subnet_mask(void *data, int opt_len)
-{
- if (opt_len != 4)
- return;
- Netmask = *(uint32_t *)data;
-}
-
-void router(void *data, int opt_len)
-{
- if (opt_len != 4)
- return;
- Gateway = *(uint32_t *)data;
-}
-
-void dns_servers(void *data, int opt_len)
-{
- int num = opt_len >> 2;
- int i;
-
- if (num > DNS_MAX_SERVERS)
- num = DNS_MAX_SERVERS;
-
- for (i = 0; i < num; i++) {
- DNSServers[i] = *(uint32_t *)data;
- data += 4;
- }
-
- /* NOT SURE FOR NOW */
- LastDNSServer = OFFS_WRT(&DNSServers[num - 1], 0);
-}
-
-void local_domain(void *data, int opt_len)
-{
- extern void dns_mangle(void);
- com32sys_t regs;
- char *p = (char *)data + opt_len;
- char end = *p;
-
- memset(&regs, 0, sizeof regs);
- *p = '\0'; /* Zero-terminate option */
- regs.esi.w[0] = OFFS_WRT(data, 0);
- regs.edi.w[0] = OFFS_WRT(LocalDomain, 0);
- call16(dns_mangle, &regs, NULL);
- *p = end; /* Resotre ending byte */
-}
-
-void vendor_encaps(void *data, int opt_len)
-{
- extern void parse_dhcp_options(void *, int, int);
-
- /* Only recongnize PXELINUX options */
- parse_dhcp_options(data, opt_len, 208);
-}
-
-void option_overload(void *data, int opt_len)
-{
- if (opt_len != 1)
- return;
- OverLoad = *(uint8_t *)data;
-}
-
-
-void server(void *data, int opt_len)
-{
- uint32_t ip;
-
- if (opt_len != 4)
- return;
-
- if (ServerIP)
- return;
-
- ip = *(uint32_t *)data;
- if (ip_ok(ip))
- ServerIP = ip;
-}
-
-void client_identifier(void *data, int opt_len)
-{
- if (opt_len > MAC_MAX || opt_len < 2 ||
- MACLen != (opt_len >> 8) ||
- *(uint8_t *)data != MACType)
- return;
-
- opt_len --;
- MACLen = opt_len & 0xff;
- memcpy(MAC, data+1, opt_len);
- MAC[opt_len] = 0;
-}
-
-void bootfile_name(void *data, int opt_len)
-{
- strncpy(BootFile, data, opt_len);
- BootFile[opt_len] = 0;
-}
-
-void uuid_client_identifier(void *data, int opt_len)
-{
- int type = *(uint8_t *)data;
- if (opt_len != 17 ||
- (type | HaveUUID))
- return;
-
- HaveUUID = 1;
- UUIDType = type;
- memcpy(UUID, data+1, 16);
- UUID[16] = 0;
-}
-
-void pxelinux_configfile(void *data, int opt_len)
-{
- DHCPMagic |= 2;
- strncpy(ConfigName, data, opt_len);
- ConfigName[opt_len] = 0;
-}
-
-void pxelinux_pathprefix(void *data,int opt_len)
-{
- DHCPMagic |= 4;
- strncpy(PathPrefix, data, opt_len);
- PathPrefix[opt_len] = 0;
-}
-
-void pxelinux_reboottime(void *data, int opt_len)
-{
- if ((opt_len && 0xff) != 4)
- return ;
-
- RebootTime = ntohl(*(uint32_t *)data);
- DHCPMagic |= 8; /* Got reboot time */
-}
-
-
-struct dhcp_options {
- int opt_num;
- void (*fun) (void *, int);
-};
-
-struct dhcp_options dhcp_opts[] = {
- {1, subnet_mask},
- {3, router},
- {6, dns_servers},
- {15, local_domain},
- {43, vendor_encaps},
- {52, option_overload},
- {54, server},
- {61, client_identifier},
- {67, bootfile_name},
- {97, uuid_client_identifier},
- {209, pxelinux_configfile},
- {210, pxelinux_pathprefix},
- {211, pxelinux_reboottime}
-};
-
-/*
- * Parse a sequence of DHCP options, pointed to by _option_;
- * -- some DHCP servers leave option fields unterminated
- * in violation of the spec.
- *
- * filter contains the minimum value for the option to recognize
- * -- this is used to restrict parsing to PXELINUX-specific options only.
- */
-void parse_dhcp_options(void *option, int size, int filter)
-{
- uint8_t opt_num;
- uint8_t opt_len;
- uint8_t opt_filter = filter == 208 ? 208 : 0;
- int opt_entries = sizeof(dhcp_opts) / sizeof(dhcp_opts[0]);
- int i = 0;
- char *p = option;
- struct dhcp_options *opt;
-
- if (opt_filter)
- printf("***NOTE!:*** we hit a pxelinux-specific options\n");
-
- while (size --) {
- opt_num = *p++;
-
- if (!size)
- break;
- if (opt_num == 0)
- continue;
- if (opt_num == 0xff)
- break;
-
- /* Anything else will have a lenght filed */
- opt_len = *p++; /* c <- option lenght */
- size = size - opt_len - 1;
- if (size < 0)
- break;
- if (opt_num < opt_filter) { /* Is the option value valid */
- option += opt_len; /* Try next */
- continue;
- }
-
- opt = dhcp_opts;
- for (i = 0; i < opt_entries; i++) {
- if (opt_num == opt->opt_num) {
- opt->fun(p, opt_len);
- break;
- }
- opt ++;
- }
-
- /* parse next */
- p += opt_len;
- }
-}
-
-/*
- *
- ;
- ; parse_dhcp
- ;
- ; Parse a DHCP packet. This includes dealing with "overloaded"
- ; option fields (see RFC 2132, section 9.3)
- ;
- ; This should fill in the following global variables, if the
- ; information is present:
- ;
- ; MyIP - client IP address
- ; ServerIP - boot server IP address
- ; Netmask - network mask
- ; Gateway - default gateway router IP
- ; BootFile - boot file name
- ; DNSServers - DNS server IPs
- ; LocalDomain - Local domain name
- ; MACLen, MAC - Client identifier, if MACLen == 0
- ;
- ; This assumes the DHCP packet is in "trackbuf" and the length
- ; of the packet in in CX on entry.
- ;
-*/
-void parse_dhcp(int pkt_len)
-{
- struct bootp_t *dhcp = (struct bootp_t *)trackbuf;
- int opt_len;
-
- OverLoad = 0;
- if (ip_ok(dhcp->yip))
- MyIP = dhcp->yip;
-
- if (ip_ok(dhcp->sip))
- ServerIP = dhcp->sip;
-
- opt_len = (char *)dhcp + pkt_len - (char *)&dhcp->options;
- if (opt_len && (dhcp->option_magic == BOOTP_OPTION_MAGIC))
- parse_dhcp_options(&dhcp->options, opt_len, 0);
- if (OverLoad & 1)
- parse_dhcp_options(&dhcp->bootfile, 128, 0);
- else if (dhcp->bootfile[0])
- strcpy(BootFile, dhcp->bootfile);
-
- if (OverLoad & 2)
- parse_dhcp_options(dhcp->sname, 64, 0);
-}
#if GPXE
/*