mirror of
https://github.com/xcat2/xNBA.git
synced 2024-11-25 19:08:35 +00:00
885 lines
26 KiB
Plaintext
885 lines
26 KiB
Plaintext
From daniel@insu.com Thu Apr 27 14:14:55 2000
|
|
Sender: root@iNsu.COM
|
|
Message-ID: <39075669.FAEB20F2@insu.com>
|
|
Date: Wed, 26 Apr 2000 16:49:45 -0400
|
|
From: Daniel Shane <daniel@insu.com>
|
|
X-Mailer: Mozilla 4.72 [en] (X11; U; Linux 2.2.14-5.0 i686)
|
|
X-Accept-Language: en
|
|
MIME-Version: 1.0
|
|
Subject: Re: New feature added to etherboot
|
|
References: <20000425170804.6677127D8A@Goffman.iNsu.COM>
|
|
Content-Type: multipart/mixed;
|
|
boundary="------------4734FDA0BF2F2FBDF8EB8DF6"
|
|
|
|
This is a multi-part message in MIME format.
|
|
--------------4734FDA0BF2F2FBDF8EB8DF6
|
|
Content-Type: text/plain; charset=us-ascii
|
|
Content-Transfer-Encoding: 7bit
|
|
|
|
Ok, here is a diff for etherboot 4.6.0 that adds identifiers.
|
|
|
|
To test this you need to use a class in the dhcpd.conf file and
|
|
also send back a string in option 208.
|
|
|
|
These identifiers prevent a client from booting from other DHCP
|
|
servers when you have more than 1 in your network.
|
|
|
|
In will also prevent any client, except the valid ones, to use this
|
|
DHCP server.
|
|
|
|
Here is a subset of my dhcpd.conf :
|
|
|
|
option iNdiskless-state code 208 = text;
|
|
|
|
class "iNdiskless-boot" {
|
|
match if substring(option iNdiskless-state,0,4) = "BOOT";
|
|
}
|
|
class "iNdiskless-setup" {
|
|
match if substring(option iNdiskless-state,0,5) = "SETUP";
|
|
}
|
|
|
|
subnet 10.4.1.0 netmask 255.255.255.0 {
|
|
pool {
|
|
allow members of "iNdiskless-boot";
|
|
deny unknown clients;
|
|
range 10.4.1.2 10.4.1.200;
|
|
next-server 10.4.1.1;
|
|
|
|
# Identify ourselves to the etherboot/DHCP client
|
|
option iNdiskless-state "BOOT";
|
|
|
|
host labo01 {
|
|
hardware ethernet 00:80:c8:ec:04:1b;
|
|
}
|
|
host labo02 {
|
|
hardware ethernet 00:4f:4c:04:45:d6;
|
|
}
|
|
host labo03 {
|
|
hardware ethernet 00:50:ba:c8:db:d6;
|
|
}
|
|
}
|
|
pool {
|
|
allow members of "iNdiskless-setup";
|
|
range 10.4.1.201 10.4.1.254;
|
|
option iNdiskless-state "SETUP";
|
|
|
|
# send another kernel to setup the diskless workstation
|
|
}
|
|
}
|
|
|
|
Daniel Shane.
|
|
--------------4734FDA0BF2F2FBDF8EB8DF6
|
|
Content-Type: text/plain; charset=us-ascii;
|
|
name="main.c.diff"
|
|
Content-Transfer-Encoding: 7bit
|
|
Content-Disposition: inline;
|
|
filename="main.c.diff"
|
|
|
|
--- etherboot-4.6.0/src/main.c Tue Apr 25 08:30:01 2000
|
|
+++ etherboot-4.5.6-new/src/main.c Wed Apr 26 16:17:09 2000
|
|
@@ -42,6 +42,23 @@ char *motd[RFC1533_VENDOR_NUMOFMOTD];
|
|
#ifdef IMAGE_FREEBSD
|
|
int freebsd_howto = 0;
|
|
#endif
|
|
+
|
|
+#ifdef SERVER_IDENT
|
|
+#ifdef DEFAULT_SERVER_IDENT
|
|
+char server_ident[9] = DEFAULT_SERVER_IDENT;
|
|
+#else
|
|
+char server_ident[9] = {};
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+#ifdef CLIENT_IDENT
|
|
+#ifdef DEFAULT_CLIENT_IDENT
|
|
+char client_ident[9] = DEFAULT_CLIENT_IDENT;
|
|
+#else
|
|
+char client_ident[9] = {};
|
|
+#endif
|
|
+#endif
|
|
+
|
|
int vendorext_isvalid;
|
|
char config_buffer[TFTP_MAX_PACKET+1]; /* +1 for null byte */
|
|
unsigned long netmask;
|
|
@@ -63,61 +80,85 @@ char rfc1533_cookie[5] = { RFC1533_CO
|
|
char rfc1533_cookie[] = { RFC1533_COOKIE};
|
|
char rfc1533_end[]={RFC1533_END };
|
|
static const char dhcpdiscover[]={
|
|
- RFC2132_MSG_TYPE,1,DHCPDISCOVER,
|
|
- RFC2132_MAX_SIZE,2,2,64,
|
|
- RFC2132_PARAM_LIST,4,RFC1533_NETMASK,RFC1533_GATEWAY,
|
|
- RFC1533_HOSTNAME,RFC1533_EXTENSIONPATH
|
|
- };
|
|
-static const char dhcprequest []={
|
|
- RFC2132_MSG_TYPE,1,DHCPREQUEST,
|
|
- RFC2132_SRV_ID,4,0,0,0,0,
|
|
- RFC2132_REQ_ADDR,4,0,0,0,0,
|
|
- RFC2132_MAX_SIZE,2,2,64,
|
|
- /* request parameters */
|
|
- RFC2132_PARAM_LIST,
|
|
-#ifdef IMAGE_FREEBSD
|
|
- /* 4 standard + 4 vendortags + 8 motd + 16 menu items */
|
|
- 4 + 4 + 8 + 16,
|
|
+ RFC2132_MSG_TYPE,1,DHCPDISCOVER,
|
|
+ RFC2132_MAX_SIZE,2,2,64,
|
|
+#ifdef CLIENT_IDENT
|
|
+ RFC1533_VENDOR_CLIENT_IDENT,8,0,0,0,0,0,0,0,0,
|
|
+#endif
|
|
+ RFC2132_PARAM_LIST,
|
|
+#ifdef SERVER_IDENT
|
|
+ 5,
|
|
#else
|
|
- /* 4 standard + 3 vendortags + 8 motd + 16 menu items */
|
|
- 4 + 3 + 8 + 16,
|
|
+ 4,
|
|
#endif
|
|
- /* Standard parameters */
|
|
- RFC1533_NETMASK, RFC1533_GATEWAY,
|
|
- RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH,
|
|
- /* Etherboot vendortags */
|
|
- RFC1533_VENDOR_MAGIC,
|
|
+#ifdef SERVER_IDENT
|
|
+ RFC1533_VENDOR_SERVER_IDENT,
|
|
+#endif
|
|
+ RFC1533_NETMASK,
|
|
+ RFC1533_GATEWAY,
|
|
+ RFC1533_HOSTNAME,
|
|
+ RFC1533_EXTENSIONPATH
|
|
+};
|
|
+static const char dhcprequest []={
|
|
+ RFC2132_MSG_TYPE,1,DHCPREQUEST,
|
|
+ RFC2132_SRV_ID,4,0,0,0,0,
|
|
+ RFC2132_REQ_ADDR,4,0,0,0,0,
|
|
+#ifdef CLIENT_IDENT
|
|
+ RFC1533_VENDOR_CLIENT_IDENT,8,0,0,0,0,0,0,0,0,
|
|
+#endif
|
|
+ RFC2132_MAX_SIZE,2,2,64,
|
|
+ /* request parameters */
|
|
+ RFC2132_PARAM_LIST,
|
|
+ /* 4 standard + 3 vendortags + 8 motd + 16 menu items */
|
|
+ 4 +
|
|
+ 3 +
|
|
+#ifdef IMAGE_FREEBSD
|
|
+ 1 + /* One more vendortags for VENDOR_HOWTO */
|
|
+#endif
|
|
+#ifdef SERVER_IDENT
|
|
+ 1 + /* One more vendortags for VENDOR_SERVER_IDENT */
|
|
+#endif
|
|
+ 8 +
|
|
+ 16,
|
|
+ /* Standard parameters */
|
|
+ RFC1533_NETMASK, RFC1533_GATEWAY,
|
|
+ RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH,
|
|
+ /* Etherboot vendortags */
|
|
+ RFC1533_VENDOR_MAGIC,
|
|
#ifdef IMAGE_FREEBSD
|
|
- RFC1533_VENDOR_HOWTO,
|
|
+ RFC1533_VENDOR_HOWTO,
|
|
#endif
|
|
- RFC1533_VENDOR_MNUOPTS, RFC1533_VENDOR_SELECTION,
|
|
- /* 8 MOTD entries */
|
|
- RFC1533_VENDOR_MOTD,
|
|
- RFC1533_VENDOR_MOTD+1,
|
|
- RFC1533_VENDOR_MOTD+2,
|
|
- RFC1533_VENDOR_MOTD+3,
|
|
- RFC1533_VENDOR_MOTD+4,
|
|
- RFC1533_VENDOR_MOTD+5,
|
|
- RFC1533_VENDOR_MOTD+6,
|
|
- RFC1533_VENDOR_MOTD+7,
|
|
- /* 16 image entries */
|
|
- RFC1533_VENDOR_IMG,
|
|
- RFC1533_VENDOR_IMG+1,
|
|
- RFC1533_VENDOR_IMG+2,
|
|
- RFC1533_VENDOR_IMG+3,
|
|
- RFC1533_VENDOR_IMG+4,
|
|
- RFC1533_VENDOR_IMG+5,
|
|
- RFC1533_VENDOR_IMG+6,
|
|
- RFC1533_VENDOR_IMG+7,
|
|
- RFC1533_VENDOR_IMG+8,
|
|
- RFC1533_VENDOR_IMG+9,
|
|
- RFC1533_VENDOR_IMG+10,
|
|
- RFC1533_VENDOR_IMG+11,
|
|
- RFC1533_VENDOR_IMG+12,
|
|
- RFC1533_VENDOR_IMG+13,
|
|
- RFC1533_VENDOR_IMG+14,
|
|
- RFC1533_VENDOR_IMG+15,
|
|
- };
|
|
+#ifdef SERVER_IDENT
|
|
+ RFC1533_VENDOR_SERVER_IDENT,
|
|
+#endif
|
|
+ RFC1533_VENDOR_MNUOPTS, RFC1533_VENDOR_SELECTION,
|
|
+ /* 8 MOTD entries */
|
|
+ RFC1533_VENDOR_MOTD,
|
|
+ RFC1533_VENDOR_MOTD+1,
|
|
+ RFC1533_VENDOR_MOTD+2,
|
|
+ RFC1533_VENDOR_MOTD+3,
|
|
+ RFC1533_VENDOR_MOTD+4,
|
|
+ RFC1533_VENDOR_MOTD+5,
|
|
+ RFC1533_VENDOR_MOTD+6,
|
|
+ RFC1533_VENDOR_MOTD+7,
|
|
+ /* 16 image entries */
|
|
+ RFC1533_VENDOR_IMG,
|
|
+ RFC1533_VENDOR_IMG+1,
|
|
+ RFC1533_VENDOR_IMG+2,
|
|
+ RFC1533_VENDOR_IMG+3,
|
|
+ RFC1533_VENDOR_IMG+4,
|
|
+ RFC1533_VENDOR_IMG+5,
|
|
+ RFC1533_VENDOR_IMG+6,
|
|
+ RFC1533_VENDOR_IMG+7,
|
|
+ RFC1533_VENDOR_IMG+8,
|
|
+ RFC1533_VENDOR_IMG+9,
|
|
+ RFC1533_VENDOR_IMG+10,
|
|
+ RFC1533_VENDOR_IMG+11,
|
|
+ RFC1533_VENDOR_IMG+12,
|
|
+ RFC1533_VENDOR_IMG+13,
|
|
+ RFC1533_VENDOR_IMG+14,
|
|
+ RFC1533_VENDOR_IMG+15,
|
|
+};
|
|
|
|
#endif /* NO_DHCP_SUPPORT */
|
|
static const char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
|
@@ -176,6 +217,55 @@ done:
|
|
break;
|
|
}
|
|
#endif
|
|
+
|
|
+#ifdef SHIFTED_IDENT_INPUT
|
|
+ if (getshift() & 3)
|
|
+ {
|
|
+#endif
|
|
+
|
|
+#ifdef CLIENT_IDENT
|
|
+# ifdef ASK_CLIENT_IDENT
|
|
+ {
|
|
+ char tmp_ident[9] = {};
|
|
+# ifdef DEFAULT_CLIENT_IDENT
|
|
+ printf("Enter the client identifier (8 char max.) default [%s] : ",client_ident);
|
|
+# else
|
|
+ printf("Enter the client identifier (8 char max.) : ");
|
|
+# endif
|
|
+ getstr(tmp_ident,8);
|
|
+ if (strlen(tmp_ident) != 0)
|
|
+ memcpy(client_ident,tmp_ident,8);
|
|
+ else
|
|
+ printf("%s",client_ident);
|
|
+ putchar('\n');
|
|
+ }
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+#ifdef SERVER_IDENT
|
|
+# ifdef ASK_SERVER_IDENT
|
|
+ {
|
|
+ char tmp_ident[9] = {};
|
|
+# ifdef DEFAULT_SERVER_IDENT
|
|
+ printf("Enter the server identifier (8 char max.) default [%s] : ",server_ident);
|
|
+# else
|
|
+ printf("Enter the server identifier (8 char max.) : ");
|
|
+# endif
|
|
+ getstr(tmp_ident,8);
|
|
+ if (strlen(tmp_ident) != 0)
|
|
+ memcpy(server_ident,tmp_ident,8);
|
|
+ else
|
|
+ printf("%s",server_ident);
|
|
+ putchar('\n');
|
|
+ }
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+#ifdef SHIFTED_IDENT_INPUT
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ print_config();
|
|
#if (TRY_FLOPPY_FIRST > 0) && defined(FLOPPY)
|
|
disk_init();
|
|
printf("Trying floppy");
|
|
@@ -188,7 +278,7 @@ done:
|
|
}
|
|
printf("no floppy\n");
|
|
#endif /* TRY_FLOPPY_FIRST && FLOPPY */
|
|
- print_config();
|
|
+ print_config();
|
|
gateA20_set();
|
|
#ifdef EMERGENCYDISKBOOT
|
|
if (!eth_probe()) {
|
|
@@ -663,6 +753,8 @@ BOOTP - Get my IP address and load infor
|
|
int bootp()
|
|
{
|
|
int retry;
|
|
+ int offset = 0;
|
|
+
|
|
#ifndef NO_DHCP_SUPPORT
|
|
int retry1;
|
|
#endif /* NO_DHCP_SUPPORT */
|
|
@@ -680,11 +772,18 @@ int bootp()
|
|
bp.bp_xid = xid = starttime = currticks();
|
|
memcpy(bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
|
|
#ifdef NO_DHCP_SUPPORT
|
|
- memcpy(bp.bp_vend, rfc1533_cookie, 5); /* request RFC-style options */
|
|
+ memcpy(bp.bp_vend+offset, rfc1533_cookie, 5); /* request RFC-style options */
|
|
+ offset += sizeof rfc1533_cookie;
|
|
#else
|
|
- memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie); /* request RFC-style options */
|
|
- memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcpdiscover, sizeof dhcpdiscover);
|
|
- memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcpdiscover, rfc1533_end, sizeof rfc1533_end);
|
|
+ memcpy(bp.bp_vend+offset, rfc1533_cookie, sizeof rfc1533_cookie); /* request RFC-style options */
|
|
+ offset += sizeof rfc1533_cookie;
|
|
+ memcpy(bp.bp_vend+offset, dhcpdiscover, sizeof dhcpdiscover);
|
|
+ offset += sizeof dhcpdiscover;
|
|
+#ifdef CLIENT_IDENT
|
|
+ memcpy(bp.bp_vend+13, client_ident, strlen(client_ident));
|
|
+#endif
|
|
+ memcpy(bp.bp_vend+offset, rfc1533_end, sizeof rfc1533_end);
|
|
+ offset += sizeof rfc1533_end;
|
|
#endif /* NO_DHCP_SUPPORT */
|
|
|
|
for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {
|
|
@@ -715,19 +814,22 @@ int bootp()
|
|
#else
|
|
if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT)){
|
|
if (dhcp_reply==DHCPOFFER){
|
|
- dhcp_reply=0;
|
|
- memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
|
|
- memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcprequest, sizeof dhcprequest);
|
|
- memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcprequest, rfc1533_end, sizeof rfc1533_end);
|
|
- memcpy(bp.bp_vend+9, &dhcp_server, sizeof(in_addr));
|
|
- memcpy(bp.bp_vend+15, &dhcp_addr, sizeof(in_addr));
|
|
- for (retry1 = 0; retry1 < MAX_BOOTP_RETRIES;) {
|
|
- udp_transmit(IP_BROADCAST, 0, BOOTP_SERVER,
|
|
- sizeof(struct bootp_t), &bp);
|
|
dhcp_reply=0;
|
|
- if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))
|
|
- if (dhcp_reply==DHCPACK)
|
|
- return(1);
|
|
+ memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
|
|
+ memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcprequest, sizeof dhcprequest);
|
|
+ memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcprequest, rfc1533_end, sizeof rfc1533_end);
|
|
+ memcpy(bp.bp_vend+9, &dhcp_server, sizeof(in_addr));
|
|
+ memcpy(bp.bp_vend+15, &dhcp_addr, sizeof(in_addr));
|
|
+#ifdef CLIENT_IDENT
|
|
+ memcpy(bp.bp_vend+21, client_ident, strlen(client_ident));
|
|
+#endif
|
|
+ for (retry1 = 0; retry1 < MAX_BOOTP_RETRIES;) {
|
|
+ udp_transmit(IP_BROADCAST, 0, BOOTP_SERVER,
|
|
+ sizeof(struct bootp_t), &bp);
|
|
+ dhcp_reply=0;
|
|
+ if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))
|
|
+ if (dhcp_reply==DHCPACK)
|
|
+ return(1);
|
|
rfc951_sleep(++retry1);
|
|
}
|
|
} else
|
|
@@ -750,6 +852,7 @@ AWAIT_REPLY - Wait until we get a respon
|
|
**************************************************************************/
|
|
int await_reply(int type, int ival, void *ptr, int timeout)
|
|
{
|
|
+ int result;
|
|
unsigned long time;
|
|
struct iphdr *ip;
|
|
struct udphdr *udp;
|
|
@@ -757,6 +860,7 @@ int await_reply(int type, int ival, void
|
|
struct bootp_t *bootpreply;
|
|
struct rpc_t *rpc;
|
|
unsigned short ptype;
|
|
+ unsigned int min_packetlen;
|
|
|
|
unsigned int protohdrlen = ETHER_HDR_SIZE + sizeof(struct iphdr) +
|
|
sizeof(struct udphdr);
|
|
@@ -766,35 +870,35 @@ int await_reply(int type, int ival, void
|
|
* needs a negligible amount of time. */
|
|
for (;;) {
|
|
if (eth_poll()) { /* We have something! */
|
|
- /* Check for ARP - No IP hdr */
|
|
+ /* Check for ARP - No IP hdr */
|
|
if (nic.packetlen >= ETHER_HDR_SIZE) {
|
|
ptype = ((unsigned short) nic.packet[12]) << 8
|
|
| ((unsigned short) nic.packet[13]);
|
|
} else continue; /* what else could we do with it? */
|
|
if ((nic.packetlen >= ETHER_HDR_SIZE +
|
|
- sizeof(struct arprequest)) &&
|
|
- (ptype == ARP) ) {
|
|
+ sizeof(struct arprequest)) &&
|
|
+ (ptype == ARP) ) {
|
|
unsigned long tmp;
|
|
-
|
|
+
|
|
arpreply = (struct arprequest *)
|
|
&nic.packet[ETHER_HDR_SIZE];
|
|
if ((arpreply->opcode == ntohs(ARP_REPLY)) &&
|
|
- !memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) &&
|
|
- (type == AWAIT_ARP)) {
|
|
+ !memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) &&
|
|
+ (type == AWAIT_ARP)) {
|
|
memcpy(arptable[ival].node, arpreply->shwaddr, ETHER_ADDR_SIZE);
|
|
return(1);
|
|
}
|
|
memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
|
|
if ((arpreply->opcode == ntohs(ARP_REQUEST)) &&
|
|
- (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
|
|
+ (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
|
|
arpreply->opcode = htons(ARP_REPLY);
|
|
memcpy(arpreply->tipaddr, arpreply->sipaddr, sizeof(in_addr));
|
|
memcpy(arpreply->thwaddr, arpreply->shwaddr, ETHER_ADDR_SIZE);
|
|
memcpy(arpreply->sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
|
|
memcpy(arpreply->shwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
|
|
eth_transmit(arpreply->thwaddr, ARP,
|
|
- sizeof(struct arprequest),
|
|
- arpreply);
|
|
+ sizeof(struct arprequest),
|
|
+ arpreply);
|
|
#ifdef MDEBUG
|
|
memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
|
|
printf("Sent ARP reply to: %I\n",tmp);
|
|
@@ -802,20 +906,20 @@ int await_reply(int type, int ival, void
|
|
}
|
|
continue;
|
|
}
|
|
-
|
|
+
|
|
if (type == AWAIT_QDRAIN) {
|
|
continue;
|
|
}
|
|
-
|
|
- /* Check for RARP - No IP hdr */
|
|
+
|
|
+ /* Check for RARP - No IP hdr */
|
|
if ((type == AWAIT_RARP) &&
|
|
- (nic.packetlen >= ETHER_HDR_SIZE +
|
|
- sizeof(struct arprequest)) &&
|
|
- (ptype == RARP)) {
|
|
+ (nic.packetlen >= ETHER_HDR_SIZE +
|
|
+ sizeof(struct arprequest)) &&
|
|
+ (ptype == RARP)) {
|
|
arpreply = (struct arprequest *)
|
|
&nic.packet[ETHER_HDR_SIZE];
|
|
if ((arpreply->opcode == ntohs(RARP_REPLY)) &&
|
|
- !memcmp(arpreply->thwaddr, ptr, ETHER_ADDR_SIZE)) {
|
|
+ !memcmp(arpreply->thwaddr, ptr, ETHER_ADDR_SIZE)) {
|
|
memcpy(arptable[ARP_SERVER].node, arpreply->shwaddr, ETHER_ADDR_SIZE);
|
|
memcpy(& arptable[ARP_SERVER].ipaddr, arpreply->sipaddr, sizeof(in_addr));
|
|
memcpy(& arptable[ARP_CLIENT].ipaddr, arpreply->tipaddr, sizeof(in_addr));
|
|
@@ -823,64 +927,72 @@ int await_reply(int type, int ival, void
|
|
}
|
|
continue;
|
|
}
|
|
-
|
|
- /* Anything else has IP header */
|
|
+
|
|
+ /* Anything else has IP header */
|
|
if ((nic.packetlen < protohdrlen) ||
|
|
- (ptype != IP) ) continue;
|
|
+ (ptype != IP) ) continue;
|
|
ip = (struct iphdr *)&nic.packet[ETHER_HDR_SIZE];
|
|
if ((ip->verhdrlen != 0x45) ||
|
|
- ipchksum((unsigned short *)ip, sizeof(struct iphdr)) ||
|
|
- (ip->protocol != IP_UDP)) continue;
|
|
+ ipchksum((unsigned short *)ip, sizeof(struct iphdr)) ||
|
|
+ (ip->protocol != IP_UDP)) continue;
|
|
udp = (struct udphdr *)&nic.packet[ETHER_HDR_SIZE +
|
|
- sizeof(struct iphdr)];
|
|
-
|
|
- /* BOOTP ? */
|
|
+ sizeof(struct iphdr)];
|
|
+
|
|
+ /* BOOTP ? */
|
|
bootpreply = (struct bootp_t *)&nic.packet[ETHER_HDR_SIZE];
|
|
- if ((type == AWAIT_BOOTP) &&
|
|
- (nic.packetlen >= (ETHER_HDR_SIZE +
|
|
-#ifdef NO_DHCP_SUPPORT
|
|
- sizeof(struct bootp_t))) &&
|
|
+#ifdef NO_DHCP_SUPPORT
|
|
+ min_packetlen = ETHER_HDR_SIZE + sizeof(struct bootp_t);
|
|
#else
|
|
- sizeof(struct bootp_t))-DHCP_OPT_LEN) &&
|
|
-#endif /* NO_DHCP_SUPPORT */
|
|
- (ntohs(udp->dest) == BOOTP_CLIENT) &&
|
|
- (bootpreply->bp_op == BOOTP_REPLY) &&
|
|
- (bootpreply->bp_xid == xid)) {
|
|
- arptable[ARP_CLIENT].ipaddr.s_addr =
|
|
- bootpreply->bp_yiaddr.s_addr;
|
|
+ min_packetlen = ETHER_HDR_SIZE + sizeof(struct bootp_t) - DHCP_OPT_LEN;
|
|
+#endif
|
|
+ if (
|
|
+ (type == AWAIT_BOOTP) &&
|
|
+ (nic.packetlen >= min_packetlen) &&
|
|
+ (ntohs(udp->dest) == BOOTP_CLIENT) &&
|
|
+ (bootpreply->bp_op == BOOTP_REPLY) &&
|
|
+ (bootpreply->bp_xid == xid)
|
|
+ ) {
|
|
+ arptable[ARP_CLIENT].ipaddr.s_addr = bootpreply->bp_yiaddr.s_addr;
|
|
#ifndef NO_DHCP_SUPPORT
|
|
dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;
|
|
#endif /* NO_DHCP_SUPPORT */
|
|
netmask = default_netmask();
|
|
- arptable[ARP_SERVER].ipaddr.s_addr =
|
|
- bootpreply->bp_siaddr.s_addr;
|
|
+ arptable[ARP_SERVER].ipaddr.s_addr = bootpreply->bp_siaddr.s_addr;
|
|
memset(arptable[ARP_SERVER].node, 0, ETHER_ADDR_SIZE); /* Kill arp */
|
|
- arptable[ARP_GATEWAY].ipaddr.s_addr =
|
|
- bootpreply->bp_giaddr.s_addr;
|
|
+ arptable[ARP_GATEWAY].ipaddr.s_addr = bootpreply->bp_giaddr.s_addr;
|
|
memset(arptable[ARP_GATEWAY].node, 0, ETHER_ADDR_SIZE); /* Kill arp */
|
|
if (bootpreply->bp_file[0]) {
|
|
memcpy(kernel_buf, bootpreply->bp_file, 128);
|
|
kernel = kernel_buf;
|
|
}
|
|
memcpy((char *)BOOTP_DATA_ADDR, (char *)bootpreply, sizeof(struct bootpd_t));
|
|
- decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend,
|
|
-#ifdef NO_DHCP_SUPPORT
|
|
- 0, BOOTP_VENDOR_LEN +
|
|
- MAX_BOOTP_EXTLEN, 1);
|
|
-#else
|
|
- 0, DHCP_OPT_LEN, 1);
|
|
-#endif /* NO_DHCP_SUPPORT */
|
|
- return(1);
|
|
+#ifdef NO_DHCP_SUPPORT
|
|
+ if (decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend,
|
|
+ 0, BOOTP_VENDOR_LEN +
|
|
+ MAX_BOOTP_EXTLEN, 1)) {
|
|
+ return(1);
|
|
+ }
|
|
+ else {
|
|
+ continue;
|
|
+ }
|
|
+#else
|
|
+ if (decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend,
|
|
+ 0, DHCP_OPT_LEN, 1)) {
|
|
+ return(1);
|
|
+ }
|
|
+ else {
|
|
+ continue;
|
|
+ }
|
|
}
|
|
-
|
|
+#endif /* NO_DHCP_SUPPORT */
|
|
#ifdef DOWNLOAD_PROTO_TFTP
|
|
- /* TFTP ? */
|
|
+ /* TFTP ? */
|
|
if ((type == AWAIT_TFTP) &&
|
|
- (ntohs(udp->dest) == ival)) return(1);
|
|
+ (ntohs(udp->dest) == ival)) return(1);
|
|
#endif /* DOWNLOAD_PROTO_TFTP */
|
|
-
|
|
+
|
|
#ifdef DOWNLOAD_PROTO_NFS
|
|
- /* RPC ? */
|
|
+ /* RPC ? */
|
|
rpc = (struct rpc_t *)&nic.packet[ETHER_HDR_SIZE];
|
|
if ((type == AWAIT_RPC) &&
|
|
(ntohs(udp->dest) == ival) &&
|
|
@@ -889,19 +1001,19 @@ int await_reply(int type, int ival, void
|
|
return (1);
|
|
}
|
|
#endif /* DOWNLOAD_PROTO_NFS */
|
|
-
|
|
+
|
|
} else {
|
|
- /* Check for abort key only if the Rx queue is empty -
|
|
- * as long as we have something to process, don't
|
|
- * assume that something failed. It is unlikely that
|
|
- * we have no processing time left between packets. */
|
|
+ /* Check for abort key only if the Rx queue is empty -
|
|
+ * as long as we have something to process, don't
|
|
+ * assume that something failed. It is unlikely that
|
|
+ * we have no processing time left between packets. */
|
|
if (iskey() && (getchar() == ESC))
|
|
#ifdef EMERGENCYDISKBOOT
|
|
exit(0);
|
|
#else
|
|
- longjmp(jmp_bootmenu,1);
|
|
+ longjmp(jmp_bootmenu,1);
|
|
#endif
|
|
- /* Do the timeout after at least a full queue walk. */
|
|
+ /* Do the timeout after at least a full queue walk. */
|
|
if ((timeout == 0) || (currticks() > time)) {
|
|
break;
|
|
}
|
|
@@ -914,13 +1026,15 @@ int await_reply(int type, int ival, void
|
|
DECODE_RFC1533 - Decodes RFC1533 header
|
|
**************************************************************************/
|
|
int decode_rfc1533(p, block, len, eof)
|
|
- register unsigned char *p;
|
|
- int block, len, eof;
|
|
+ register unsigned char *p;
|
|
+ int block, len, eof;
|
|
{
|
|
static unsigned char *extdata = NULL, *extend = NULL;
|
|
unsigned char *extpath = NULL;
|
|
unsigned char *endp;
|
|
-
|
|
+#ifdef SERVER_IDENT
|
|
+ char rcvd_server_ident[9] = {};
|
|
+#endif
|
|
if (block == 0) {
|
|
#ifdef IMAGE_MENU
|
|
memset(imagelist, 0, sizeof(imagelist));
|
|
@@ -1002,11 +1116,16 @@ int decode_rfc1533(p, block, len, eof)
|
|
}
|
|
#endif
|
|
#ifdef MOTD
|
|
- else if (c >= RFC1533_VENDOR_MOTD &&
|
|
+ else if (c >= RFC1533_VENDOR_MOTD &&
|
|
c < RFC1533_VENDOR_MOTD +
|
|
RFC1533_VENDOR_NUMOFMOTD)
|
|
motd[c - RFC1533_VENDOR_MOTD] = p;
|
|
#endif
|
|
+#ifdef SERVER_IDENT
|
|
+ else if (c == RFC1533_VENDOR_SERVER_IDENT) {
|
|
+ memcpy(rcvd_server_ident,p+2,TAG_LEN(p));
|
|
+ }
|
|
+#endif
|
|
else {
|
|
#if 0
|
|
unsigned char *q;
|
|
@@ -1018,6 +1137,30 @@ int decode_rfc1533(p, block, len, eof)
|
|
}
|
|
p += TAG_LEN(p) + 2;
|
|
}
|
|
+#if defined(SERVER_IDENT) && defined(DBG_IDENT)
|
|
+ if (strcasecmp(rcvd_server_ident,server_ident)) {
|
|
+ char ip[16];
|
|
+
|
|
+ inet_ntoa(dhcp_server,ip);
|
|
+ printf("[%s]: Option %d (%s), invalid response. Wanted (%s).\n",
|
|
+ ip,
|
|
+ RFC1533_VENDOR_SERVER_IDENT,
|
|
+ rcvd_server_ident,
|
|
+ server_ident);
|
|
+ strcpy(rcvd_server_ident,"");
|
|
+ return(0);
|
|
+ }
|
|
+ else {
|
|
+ char ip[16];
|
|
+
|
|
+ inet_ntoa(dhcp_server,ip);
|
|
+ printf("[%s]: Option %d (%s), valid response.\n",
|
|
+ ip,
|
|
+ RFC1533_VENDOR_SERVER_IDENT,
|
|
+ rcvd_server_ident);
|
|
+ strcpy(rcvd_server_ident,"");
|
|
+ }
|
|
+#endif
|
|
extdata = extend = endp;
|
|
if (block == 0 && extpath != NULL) {
|
|
char fname[64];
|
|
@@ -1103,3 +1246,4 @@ void cleanup(void)
|
|
* c-basic-offset: 8
|
|
* End:
|
|
*/
|
|
+
|
|
|
|
--------------4734FDA0BF2F2FBDF8EB8DF6
|
|
Content-Type: text/plain; charset=us-ascii;
|
|
name="misc.c.diff"
|
|
Content-Transfer-Encoding: 7bit
|
|
Content-Disposition: inline;
|
|
filename="misc.c.diff"
|
|
|
|
--- etherboot-4.6.0/src/misc.c Tue Apr 25 08:30:25 2000
|
|
+++ etherboot-4.5.6-new/src/misc.c Wed Apr 26 16:26:38 2000
|
|
@@ -140,9 +140,11 @@ void printf(const char *fmt, ...)
|
|
|
|
#ifdef IMAGE_MENU
|
|
/**************************************************************************
|
|
-INET_ATON - Convert an ascii x.x.x.x to binary form
|
|
+INET_NTOA - Convert an ascii x.x.x.x to binary form
|
|
**************************************************************************/
|
|
-int inet_aton(char *p, in_addr *i)
|
|
+int inet_aton(p, i)
|
|
+ char *p;
|
|
+ in_addr *i;
|
|
{
|
|
unsigned long ip = 0;
|
|
int val;
|
|
@@ -165,7 +167,19 @@ int inet_aton(char *p, in_addr *i)
|
|
|
|
#endif /* IMAGE_MENU */
|
|
|
|
-int getdec(char **ptr)
|
|
+#if defined(CLIENT_IDENT) || defined (SERVER_IDENT)
|
|
+/**************************************************************************
|
|
+INET_NTOA - Convert a binary form to an ascii x.x.x.x form
|
|
+**************************************************************************/
|
|
+char *inet_ntoa(in_addr i, char *p)
|
|
+{
|
|
+ sprintf(p,"%d.%d.%d.%d",i.s_addr>>24,i.s_addr<<8>>24,i.s_addr<<16>>24,i.s_addr<<24>>24);
|
|
+ return p;
|
|
+}
|
|
+#endif
|
|
+
|
|
+int getdec(ptr)
|
|
+ char **ptr;
|
|
{
|
|
char *p = *ptr;
|
|
int ret=0;
|
|
@@ -308,6 +322,45 @@ iskey(void)
|
|
return 0;
|
|
}
|
|
#endif /* ETHERBOOT32 */
|
|
+
|
|
+/**************************************************************************
|
|
+GETSTR - Read a string of size bytes from the keyboard
|
|
+(without echoing the final return)
|
|
+**************************************************************************/
|
|
+void getstr(char *s, int size)
|
|
+{
|
|
+ int i=0;
|
|
+ char c;
|
|
+
|
|
+ while(1) {
|
|
+ c = getc();
|
|
+
|
|
+
|
|
+ if (c == 13)
|
|
+ {
|
|
+ s[i]='\0';
|
|
+ break;
|
|
+ }
|
|
+ else if (
|
|
+ ((c >= 'a') && (c <='z')) ||
|
|
+ ((c >= 'A') && (c <='Z')) ||
|
|
+ ((c >= '0') && (c <='9'))
|
|
+ ) {
|
|
+ if (i==8) {
|
|
+ putchar(8);
|
|
+ putchar(s[i-1]=c);
|
|
+ }
|
|
+ else
|
|
+ putchar(s[i++]=c);
|
|
+ }
|
|
+ else if ( c == 8 ) {
|
|
+ if (i != 0) {
|
|
+ --i;
|
|
+ s[i]='\0';
|
|
+ putchar(8);
|
|
+ putchar(32);
|
|
+ putchar(8);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
|
|
/*
|
|
* Local variables:
|
|
|
|
--------------4734FDA0BF2F2FBDF8EB8DF6
|
|
Content-Type: text/plain; charset=us-ascii;
|
|
name="Config.diff"
|
|
Content-Transfer-Encoding: 7bit
|
|
Content-Disposition: inline;
|
|
filename="Config.diff"
|
|
|
|
--- etherboot-4.6.0/src/Config Tue Apr 25 08:30:57 2000
|
|
+++ etherboot-4.5.6-new/src/Config Wed Apr 26 15:55:57 2000
|
|
@@ -59,6 +59,27 @@
|
|
# may no longer be appropriate. You might need to set
|
|
# MAX_ARP_RETRIES, MAX_BOOTP_RETRIES, MAX_TFTP_RETRIES
|
|
# and MAX_RPC_RETRIES to a larger value.
|
|
+# -DDEFAULT_CLIENT_IDENT
|
|
+# The default client identifier that is sent to the
|
|
+# DHCP server to identify itself.
|
|
+# -DDEFAULT_SERVER_IDENT
|
|
+# The expected response that the client will wait
|
|
+# for when a DHCP server responds to the the initial
|
|
+# client discovery.
|
|
+# -DASK_CLIENT_IDENT
|
|
+# -DASK_SERVER_IDENT
|
|
+# If these are set, the boot process will include
|
|
+# a question period where you can manualy specify
|
|
+# the client and/or server identifiers.
|
|
+# -DSHIFTED_IDENT_INPUT
|
|
+# If this is set then the boot process will only
|
|
+# ask for the identifiers if one of the shift keys
|
|
+# is pressed. Else it will send the default identifiers
|
|
+# automatically
|
|
+# -DDBG_IDENT
|
|
+# This will give show all the DHCP responses with
|
|
+# their identifiers.
|
|
+#
|
|
#
|
|
# Etherboot/32 only options:
|
|
# -DAOUT_IMAGE - Add a.out kernel boot support (generic)
|
|
@@ -147,6 +168,14 @@ CFLAGS32+= -DASK_BOOT=3 -DANS_DEFAULT=AN
|
|
|
|
# Change download protocol to NFS. Only available for Etherboot/32 for now.
|
|
# CFLAGS32+= -DDOWNLOAD_PROTO_NFS
|
|
+
|
|
+# If you have more than one DHCP server you might want to
|
|
+# enable these to be able to sort out which one you want to
|
|
+# respond to.
|
|
+CFLAGS32+= -DDEFAULT_CLIENT_IDENT=\"BOOT\" -DDEFAULT_SERVER_IDENT=\"BOOT\"
|
|
+CFLAGS32+= -DASK_CLIENT_IDENT -DASK_SERVER_IDENT
|
|
+CFLAGS32+= -DSHIFTED_IDENT_INPUT
|
|
+CFLAGS32+= -DDBG_IDENT
|
|
|
|
# These flags affect the loader that is prepended to the Etherboot image
|
|
LCONFIG+= -DMOVEROM
|
|
|
|
--------------4734FDA0BF2F2FBDF8EB8DF6
|
|
Content-Type: text/plain; charset=us-ascii;
|
|
name="etherboot.h.diff"
|
|
Content-Transfer-Encoding: 7bit
|
|
Content-Disposition: inline;
|
|
filename="etherboot.h.diff"
|
|
|
|
--- etherboot-4.6.0/src/etherboot.h Tue Apr 25 08:30:55 2000
|
|
+++ etherboot-4.5.6-new/src/etherboot.h Wed Apr 26 16:07:16 2000
|
|
@@ -8,6 +8,14 @@ Author: Martin Renters
|
|
|
|
#include "osdep.h"
|
|
|
|
+#if (! defined(NO_DHCP_SUPPORT)) && (defined(ASK_CLIENT_IDENT) || defined(DEFAULT_CLIENT_IDENT))
|
|
+# define CLIENT_IDENT
|
|
+#endif
|
|
+
|
|
+#if (! defined(NO_DHCP_SUPPORT)) && (defined(ASK_SERVER_IDENT) || defined(DEFAULT_SERVER_IDENT))
|
|
+# define SERVER_IDENT
|
|
+#endif
|
|
+
|
|
/* These could be customised for different languages perhaps */
|
|
#define ASK_PROMPT "Boot from (N)etwork or from (L)ocal? "
|
|
#define ANS_NETWORK 'N'
|
|
@@ -224,6 +232,12 @@ Author: Martin Renters
|
|
#ifdef IMAGE_FREEBSD
|
|
#define RFC1533_VENDOR_HOWTO 132
|
|
#endif
|
|
+#ifdef CLIENT_IDENT
|
|
+#define RFC1533_VENDOR_CLIENT_IDENT 208
|
|
+#endif
|
|
+#ifdef SERVER_IDENT
|
|
+#define RFC1533_VENDOR_SERVER_IDENT 208
|
|
+#endif
|
|
#define RFC1533_VENDOR_MNUOPTS 160
|
|
#define RFC1533_VENDOR_SELECTION 176
|
|
#define RFC1533_VENDOR_MOTD 184
|
|
@@ -477,11 +491,13 @@ extern int getdec P((char **));
|
|
extern void printf P((const char *, ...));
|
|
extern char *sprintf P((char *, const char *, ...));
|
|
extern int inet_aton P((char *p, in_addr *i));
|
|
+extern char *inet_ntoa P((in_addr i, char *p));
|
|
extern void gateA20_set P((void));
|
|
extern void gateA20_unset P((void));
|
|
extern void putchar P((int));
|
|
extern int getchar P((void));
|
|
extern int iskey P((void));
|
|
+extern void getstr P((char *s, int size));
|
|
|
|
/* start*.S */
|
|
extern int getc P((void));
|
|
@@ -528,8 +544,10 @@ extern int hostnamelen;
|
|
extern unsigned long netmask;
|
|
extern int jmp_bootmenu[10];
|
|
extern struct arptable_t arptable[MAX_ARP];
|
|
-#ifdef IMAGE_MENU
|
|
+#ifdef MOTD
|
|
extern char *motd[RFC1533_VENDOR_NUMOFMOTD];
|
|
+#endif
|
|
+#ifdef IMAGE_MENU
|
|
extern int menutmo,menudefault;
|
|
extern unsigned char *defparams;
|
|
extern int defparams_max;
|
|
|
|
--------------4734FDA0BF2F2FBDF8EB8DF6--
|
|
|