Date: Fri, 13 Oct 2000 09:48:18 +0200 From: Danny Braniss <danny@cs.huji.ac.il> To: Paul Saab <paul@mu.org> Cc: freebsd-hackers@freebsd.org Subject: Re: bootp/diskless/kenv Message-ID: <E13jzZi-0001be-00@sexta.cs.huji.ac.il> In-Reply-To: Your message of Fri, 13 Oct 2000 00:40:00 -0700 .
next in thread | raw e-mail | index | archive | help
In message <20001013003959.A52126@elvis.mu.org>you write:
}Danny Braniss (danny@cs.huji.ac.il) wrote:
}> Im including a modified lib/libstand/bootp.c for evaluation. It has:
}> o- fixes for evaluation of netmask - only if not supplied.
}> o- puts in the environment the dhcp stuff
}> it does not - yet -:
}> do any good check for string overflow.
}> check for environment buffer overflow - haven't found out
}> how to do it yet
}>
}> since kenv can now be used early on the diskless boot process, i think
}> it should be placed in /bin and staticaly linked.
}
}a diff would be a whole lot easier to read.
}
}paul
your wish is my command:
--- bootp.c Tue Sep 26 10:46:15 2000
+++ /vol/fbsd/current/lib/libstand/bootp.c Fri Sep 22 10:04:36 2000
@@ -37,7 +37,7 @@
* SUCH DAMAGE.
*
* @(#) Header: bootp.c,v 1.4 93/09/11 03:13:51 leres Exp (LBL)
- * $FreeBSD: src/lib/libstand/bootp.c,v 1.1.1.1.6.1 2000/09/10 02:52:19 ps
Exp $
+ * $FreeBSD: src/lib/libstand/bootp.c,v 1.3 2000/09/20 18:16:20 ps Exp $
*/
#include <sys/types.h>
@@ -46,14 +46,9 @@
#include <string.h>
-/* #define BOOTP_DEBUGxx */
+#define BOOTP_DEBUGxx
#define SUPPORT_DHCP
-/*#define BOOTP_DEBUG /* danny */
-#if defined(BOOTP_DEBUG) || defined(BOOTP_DEBUGxx)
-int debug=1;
-#endif
-
#include "stand.h"
#include "net.h"
#include "netif.h"
@@ -62,7 +57,7 @@
struct in_addr servip;
-static n_long smask;
+static n_long nmask, smask;
static time_t bot;
@@ -84,8 +79,6 @@
struct in_addr dhcp_serverip;
#endif
-static void setenv_dhcp(u_char *cp, u_int len);
-
/* Fetch required bootp infomation */
void
bootp(sock, flag)
@@ -102,9 +95,8 @@
u_char header[HEADER_SIZE];
struct bootp rbootp;
} rbuf;
- int j;
-#ifdef BOOTP_DEBUGxx
+#ifdef BOOTP_DEBUG
if (debug)
printf("bootp: socket=%d\n", sock);
#endif
@@ -115,7 +107,7 @@
printf("bootp: bad socket. %d\n", sock);
return;
}
-#ifdef BOOTP_DEBUGxx
+#ifdef BOOTP_DEBUG
if (debug)
printf("bootp: d=%lx\n", (long)d);
#endif
@@ -130,52 +122,37 @@
MACPY(d->myea, bp->bp_chaddr);
strncpy(bp->bp_file, bootfile, sizeof(bp->bp_file));
bcopy(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048));
- j = sizeof(vm_rfc1048);
#ifdef SUPPORT_DHCP
- bp->bp_vend[j++] = TAG_DHCP_MSGTYPE;
- bp->bp_vend[j++] = 1;
- bp->bp_vend[j++] = DHCPDISCOVER;
-#if 0
- /*
- * We send an RFC 1533 "Maximum DHCP Message Size" option, saying we
- * can do 1200 bytes. If we don't ISC DHCPD will limit the answer to
- * 64 bytes and root/swap and similar will be dropped.
- */
- bp->bp_vend[j++] = TAG_MAXSIZE;
- bp->bp_vend[j++] = 2;
- bp->bp_vend[j++] = 1200 / 256;
- bp->bp_vend[j++] = 1200 % 256;
-#endif
+ bp->bp_vend[4] = TAG_DHCP_MSGTYPE;
+ bp->bp_vend[5] = 1;
+ bp->bp_vend[6] = DHCPDISCOVER;
+
/*
* If we are booting from PXE, we want to send the string
* 'PXEClient' to the DHCP server so you have the option of
* only responding to PXE aware dhcp requests.
*/
if (flag & BOOTP_PXE) {
- char *classid;
- int len;
- bp->bp_vend[j++] = TAG_CLASSID;
-#if 0
- bp->bp_vend[j++] = 9;
- bcopy("PXEClient", &bp->bp_vend[j], 9);
- j += 9;
+ bp->bp_vend[7] = TAG_CLASSID;
+ bp->bp_vend[8] = 9;
+ bcopy("PXEClient", &bp->bp_vend[9], 9);
+ bp->bp_vend[18] = TAG_END;
+ } else
+ bp->bp_vend[7] = TAG_END;
#else
- classid = "FreeBSDc";
- bp->bp_vend[j++] = len = strlen(classid);
- bcopy(classid, &bp->bp_vend[j], len);
- j += len;
+ bp->bp_vend[4] = TAG_END;
#endif
- }
- expected_dhcpmsgtype = DHCPOFFER;
- dhcp_ok = 0;
-#endif
- bp->bp_vend[j++] = TAG_END;
d->myip.s_addr = INADDR_ANY;
d->myport = htons(IPPORT_BOOTPC);
d->destip.s_addr = INADDR_BROADCAST;
d->destport = htons(IPPORT_BOOTPS);
+#ifdef SUPPORT_DHCP
+ expected_dhcpmsgtype = DHCPOFFER;
+ dhcp_ok = 0;
+#endif
+
if(sendrecv(d,
bootpsend, bp, sizeof(*bp),
bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
@@ -187,39 +164,24 @@
#ifdef SUPPORT_DHCP
if(dhcp_ok) {
u_int32_t leasetime;
- int j;
- j = 6;
- bp->bp_vend[j++] = DHCPREQUEST;
- bp->bp_vend[j++] = TAG_REQ_ADDR;
- bp->bp_vend[j++] = 4;
- bcopy(&rbuf.rbootp.bp_yiaddr, &bp->bp_vend[j], 4);
- j += 4;
- bp->bp_vend[j++] = TAG_SERVERID;
- bp->bp_vend[j++] = 4;
- bcopy(&dhcp_serverip.s_addr, &bp->bp_vend[j], 4);
- j += 4;
- bp->bp_vend[j++] = TAG_LEASETIME;
- bp->bp_vend[j++] = 4;
+ bp->bp_vend[6] = DHCPREQUEST;
+ bp->bp_vend[7] = TAG_REQ_ADDR;
+ bp->bp_vend[8] = 4;
+ bcopy(&rbuf.rbootp.bp_yiaddr, &bp->bp_vend[9], 4);
+ bp->bp_vend[13] = TAG_SERVERID;
+ bp->bp_vend[14] = 4;
+ bcopy(&dhcp_serverip.s_addr, &bp->bp_vend[15], 4);
+ bp->bp_vend[19] = TAG_LEASETIME;
+ bp->bp_vend[20] = 4;
leasetime = htonl(300);
- bcopy(&leasetime, &bp->bp_vend[j], 4);
- j += 4;
+ bcopy(&leasetime, &bp->bp_vend[21], 4);
if (flag & BOOTP_PXE) {
-#if 0
- bp->bp_vend[j++] = TAG_CLASSID;
- bp->bp_vend[j++] = 9;
- bcopy("PXEClient", &bp->bp_vend[j], 9);
- j += 9;
-#else
- char *classid;
- int len;
-
- classid = "FreeBSDc";
- bp->bp_vend[j++] = len = strlen(classid);
- bcopy(classid, &bp->bp_vend[j], len);
- j += len;
-#endif
- }
- bp->bp_vend[j++] = TAG_END;
+ bp->bp_vend[25] = TAG_CLASSID;
+ bp->bp_vend[26] = 9;
+ bcopy("PXEClient", &bp->bp_vend[27], 9);
+ bp->bp_vend[36] = TAG_END;
+ } else
+ bp->bp_vend[25] = TAG_END;
expected_dhcpmsgtype = DHCPACK;
@@ -231,7 +193,7 @@
return;
}
}
-#endif /* SUPPORT_DHCP */
+#endif
myip = d->myip = rbuf.rbootp.bp_yiaddr;
servip = rbuf.rbootp.bp_siaddr;
@@ -239,28 +201,50 @@
bcopy(rbuf.rbootp.bp_file, bootfile, sizeof(bootfile));
bootfile[sizeof(bootfile) - 1] = '\0';
- if(smask == 0) {
- if(IN_CLASSA(ntohl(myip.s_addr)))
- smask = htonl(IN_CLASSA_NET);
- else
- if(IN_CLASSB(ntohl(myip.s_addr)))
- smask = htonl(IN_CLASSB_NET);
- else
- smask = htonl(IN_CLASSC_NET);
+ if (IN_CLASSA(ntohl(myip.s_addr)))
+ nmask = htonl(IN_CLASSA_NET);
+ else if (IN_CLASSB(ntohl(myip.s_addr)))
+ nmask = htonl(IN_CLASSB_NET);
+ else
+ nmask = htonl(IN_CLASSC_NET);
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("'native netmask' is %s\n", intoa(nmask));
+#endif
+
+ /* Check subnet mask against net mask; toss if bogus */
+ if ((nmask & smask) != nmask) {
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("subnet mask (%s) bad\n", intoa(smask));
+#endif
+ smask = 0;
}
+
/* Get subnet (or natural net) mask */
- netmask = smask;
+ netmask = nmask;
+ if (smask)
+ netmask = smask;
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("mask: %s\n", intoa(netmask));
+#endif
+
/* We need a gateway if root is on a different net */
if (!SAMENET(myip, rootip, netmask)) {
#ifdef BOOTP_DEBUG
- if (debug)
- printf("need gateway for root ip\n");
+ if (debug)
+ printf("need gateway for root ip\n");
#endif
}
+
/* Toss gateway if on a different net */
if (!SAMENET(myip, gateip, netmask)) {
- printf("gateway ip (%s) is bad!\n", inet_ntoa(gateip));
- gateip.s_addr = 0;
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("gateway ip (%s) bad\n", inet_ntoa(gateip));
+#endif
+ gateip.s_addr = 0;
}
/* Bump xid so next request will be unique. */
@@ -276,7 +260,7 @@
{
register struct bootp *bp;
-#ifdef BOOTP_DEBUGxx
+#ifdef BOOTP_DEBUG
if (debug)
printf("bootpsend: d=%lx called.\n", (long)d);
#endif
@@ -284,7 +268,7 @@
bp = pkt;
bp->bp_secs = htons((u_short)(getsecs() - bot));
-#ifdef BOOTP_DEBUGxx
+#ifdef BOOTP_DEBUG
if (debug)
printf("bootpsend: calling sendudp\n");
#endif
@@ -302,7 +286,7 @@
register ssize_t n;
register struct bootp *bp;
-#ifdef BOOTP_DEBUGxx
+#ifdef BOOTP_DEBUGx
if (debug)
printf("bootp_recvoffer: called\n");
#endif
@@ -313,7 +297,7 @@
bp = (struct bootp *)pkt;
-#ifdef BOOTP_DEBUGxx
+#ifdef BOOTP_DEBUG
if (debug)
printf("bootprecv: checked. bp = 0x%lx, n = %d\n",
(long)bp, (int)n);
@@ -328,7 +312,7 @@
goto bad;
}
-#ifdef BOOTP_DEBUGxx
+#ifdef BOOTP_DEBUG
if (debug)
printf("bootprecv: got one!\n");
#endif
@@ -360,8 +344,6 @@
register int size;
register u_char tag;
- setenv_dhcp(cp, len);
-
#ifdef BOOTP_DEBUG
if (debug)
printf("vend_rfc1048 bootp info. len=%d\n", len);
@@ -374,45 +356,38 @@
while (cp < ep) {
tag = *cp++;
size = *cp++;
- switch(tag) {
- case 0:
- continue;
- case TAG_END:
- break;
- case TAG_SUBNET_MASK:
- bcopy(cp, &smask, sizeof(smask));
- break;
- case TAG_GATEWAY:
- bcopy(cp, &gateip.s_addr, sizeof(gateip.s_addr));
- break;
- case TAG_SWAPSERVER:
- /* let it override bp_siaddr */
- bcopy(cp, &rootip.s_addr, sizeof(swapip.s_addr));
- break;
- case TAG_ROOTPATH:
- strncpy(rootpath, (char *)cp, sizeof(rootpath));
- rootpath[size] = '\0';
- break;
- case TAG_HOSTNAME:
- strncpy(hostname, (char *)cp, sizeof(hostname));
- hostname[size] = '\0';
- break;
+ if (tag == TAG_END)
+ break;
+
+ if (tag == TAG_SUBNET_MASK) {
+ bcopy(cp, &smask, sizeof(smask));
+ }
+ if (tag == TAG_GATEWAY) {
+ bcopy(cp, &gateip.s_addr, sizeof(gateip.s_addr));
+ }
+ if (tag == TAG_SWAPSERVER) {
+ /* let it override bp_siaddr */
+ bcopy(cp, &rootip.s_addr, sizeof(swapip.s_addr));
+ }
+ if (tag == TAG_ROOTPATH) {
+ strncpy(rootpath, (char *)cp, sizeof(rootpath));
+ rootpath[size] = '\0';
+ }
+ if (tag == TAG_HOSTNAME) {
+ strncpy(hostname, (char *)cp, sizeof(hostname));
+ hostname[size] = '\0';
+ }
#ifdef SUPPORT_DHCP
- case TAG_DHCP_MSGTYPE:
- if(*cp != expected_dhcpmsgtype)
- return(-1);
- dhcp_ok = 1;
- break;
- case TAG_SERVERID:
- bcopy(cp, &dhcp_serverip.s_addr, sizeof(dhcp_serverip.s_addr));
- break;
-#endif
-#ifdef BOOTP_DEBUG
- default:
- if (debug)
- printf("unknown tag:%d size=%d\n", tag, size);
-#endif
+ if (tag == TAG_DHCP_MSGTYPE) {
+ if(*cp != expected_dhcpmsgtype)
+ return(-1);
+ dhcp_ok = 1;
+ }
+ if (tag == TAG_SERVERID) {
+ bcopy(cp, &dhcp_serverip.s_addr,
+ sizeof(dhcp_serverip.s_addr));
}
+#endif
cp += size;
}
return(0);
@@ -425,7 +400,7 @@
{
register struct cmu_vend *vp;
-#ifdef BOOTP_DEBUGxx
+#ifdef BOOTP_DEBUG
if (debug)
printf("vend_cmu bootp info.\n");
#endif
@@ -439,209 +414,3 @@
}
}
#endif
-
-/*
- | DHCP Option names, formats and codes, from RFC1533.
- */
-#define __IP 1
-#define __TXT 2
-#define __8 3
-#define __16 4
-#define __32 5
-#define __VE 6
-
-struct dhcp_opt {
- int tag;
- int fmt;
- char *desc;
-} dhcp_opt[] = {
-#define _DHCP(num, fmt, dsc) {num, fmt, dsc}
- _DHCP(1, __IP, "subnet-mask"),
- _DHCP(2, __32, "time-offset"),
- _DHCP(3, __IP, "routers"),
- _DHCP(4, __IP, "time-servers"),
- _DHCP(5, __IP, "ien116-name-servers"),
- _DHCP(6, __IP, "domain-name-servers"),
- _DHCP(7, __IP, "log-servers"),
- _DHCP(8, __IP, "cookie-servers"),
- _DHCP(9, __IP, "lpr-servers"),
- _DHCP(10, __IP, "impress-servers"),
- _DHCP(11, __IP, "resource-location-servers"),
- _DHCP(12, __TXT, "host-name"),
- _DHCP(13, __16, "boot-size"),
- _DHCP(14, __TXT, "merit-dump"),
- _DHCP(15, __TXT, "domain-name"),
- _DHCP(16, __IP, "swap-server"),
- _DHCP(17, __TXT, "root-path"),
- _DHCP(18, __TXT, "extensions-path"),
- _DHCP(19, __8, "ip-forwarding"),
- _DHCP(20, __8, "non-local-source-routing"),
- _DHCP(21, __IP, "policy-filter"),
- _DHCP(22, __16, "max-dgram-reassembly"),
- _DHCP(23, __8, "default-ip-ttl"),
- _DHCP(24, __32, "path-mtu-aging-timeout"),
- _DHCP(25, __16, "path-mtu-plateau-table"),
- _DHCP(26, __16, "interface-mtu"),
- _DHCP(27, __8, "all-subnets-local"),
- _DHCP(28, __IP, "broadcast-address"),
- _DHCP(29, __8, "perform-mask-discovery"),
- _DHCP(30, __8, "mask-supplier"),
- _DHCP(31, __8, "router-discovery"),
- _DHCP(32, __IP, "router-solicitation-address"),
- _DHCP(33, __IP, "static-routes"),
- _DHCP(34, __8, "trailer-encapsulation"),
- _DHCP(35, __32, "arp-cache-timeout"),
- _DHCP(36, __8, "ieee802-3-encapsulation"),
- _DHCP(37, __8, "default-tcp-ttl"),
- _DHCP(38, __32, "tcp-keepalive-interval"),
- _DHCP(39, __8, "tcp-keepalive-garbage"),
- _DHCP(40, __TXT, "nis-domain"),
- _DHCP(41, __IP, "nis-servers"),
- _DHCP(42, __IP, "ntp-servers"),
- _DHCP(43, __VE, "vendor-encapsulated-options"),
- _DHCP(44, __IP, "netbios-name-servers"),
- _DHCP(45, __IP, "netbios-dd-server"),
- _DHCP(46, __8, "netbios-node-type"),
- _DHCP(47, __TXT, "netbios-scope"),
- _DHCP(48, __IP, "font-servers"),
- _DHCP(49, __IP, "x-display-manager"),
- _DHCP(50, __IP, "dhcp-requested-address"),
- _DHCP(51, __32, "dhcp-lease-time"),
- _DHCP(52, __8, "dhcp-option-overload"),
- _DHCP(53, __8, "dhcp-message-type"),
- _DHCP(54, __IP, "dhcp-server-identifier"),
- _DHCP(55, __8, "dhcp-parameter-request-list"),
- _DHCP(56, __TXT, "dhcp-message"),
- _DHCP(57, __16, "dhcp-max-message-size"),
- _DHCP(58, __32, "dhcp-renewal-time"),
- _DHCP(59, __32, "dhcp-rebinding-time"),
- _DHCP(60, __TXT, "vendor-class-identifier"),
- _DHCP(61, __TXT, "dhcp-client-identifier"),
- _DHCP(64, __TXT, "nisplus-domain"),
- _DHCP(65, __IP, "nisplus-servers"),
- _DHCP(66, __TXT, "tftp-server-name"),
- _DHCP(67, __TXT, "bootfile-name"),
- _DHCP(68, __IP, "mobile-ip-home-agent"),
- _DHCP(69, __IP, "smtp-server"),
- _DHCP(70, __IP, "pop-server"),
- _DHCP(71, __IP, "nntp-server"),
- _DHCP(72, __IP, "www-server"),
- _DHCP(73, __IP, "finger-server"),
- _DHCP(74, __IP, "irc-server"),
- _DHCP(75, __IP, "streettalk-server"),
- _DHCP(76, __IP, "streettalk-directory-assistance-server"),
- _DHCP(77, __TXT, "user-class"),
- _DHCP(85, __IP, "nds-servers"),
- _DHCP(86, __TXT, "nds-tree-name"),
- _DHCP(87, __TXT, "nds-context"),
- _DHCP(210, __TXT, "authenticate"),
- {0}
-};
-
-struct dhcp_opt optdef = _DHCP(0, __TXT, "option-%d");
-
-#undef _DHCP
-
-static void
-setenv_dhcp(u_char *cp, u_int len)
-{
- u_char *ep;
- int size;
- u_char tag;
- char env[128], val[512], *vp, tags[512], *tp;
- struct in_addr in_ip;
-
- ep = cp + len;
- cp += sizeof(vm_rfc1048); /* hopefully this was checked? */
- tp = tags;
-
- while(cp < ep) {
- struct dhcp_opt *op;
-
- tag = *cp++;
- size = *cp++;
- if(tag == TAG_END)
- break;
- if(tag == 0)
- continue;
- for(op = dhcp_opt; op->tag; op++)
- if(op->tag >= tag)
- break;
- if(op->tag != tag)
- op = &optdef;
- vp = val;
- switch(op->fmt) {
- case __VE: /* vendor specific */
- while(size-- > 0) {
- sprintf(vp, "%02x", *cp++);
- vp += 2;
- }
- break;
-
- case __IP: /* ip address */
- while(size > 0) {
-
- if(vp != val)
- *vp++ = ',';
- bcopy(cp, &in_ip.s_addr, sizeof(in_ip.s_addr));
- sprintf(vp, "%s", inet_ntoa(in_ip));
- vp += strlen(vp);
- size -= 4;
- cp += 4;
- }
- break;
-
- case __TXT:
- bcopy(cp, val, size);
- val[size] = 0;
- cp += size;
- break;
- case __8:
- case __16:
- case __32:
- while(size > 0) {
- int n = 0;
-
- if(vp != val)
- *vp++ = ',';
- switch(op->fmt) {
- case __8:
- sprintf(vp, "%02x", cp[0]);
- n = 1;
- break;
- case __16:
- sprintf(vp, "%02x%02x", cp[0], cp[1]);
- n = 2;
- break;
- case __32:
- sprintf(vp, "%02x%02x%02x%02x", cp[0], cp[1], cp[2], cp[3]);
- n = 4;
- break;
- }
- cp += n;
- size -= n;
- vp += strlen(vp);
- }
- break;
- }
- sprintf(tp, "%03d:", tag);
- tp += strlen(tp);
-
- if(op == &optdef)
- sprintf(env, "dhcp.option-%d", tag);
- else
- sprintf(env, "dhcp.%s", op->desc);
-#ifdef BOOTP_DEBUG
- if(debug)
- printf("%s %s\n", env, val);
-#endif
- setenv(env, val, 1);
- }
- if(tp != tags) {
-#ifdef BOOTP_DEBUG
- if(debug)
- printf("%s %s\n", "dhcp.tags", tags);
-#endif
- setenv("dhcp.tags", tags, 1);
- }
-}
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E13jzZi-0001be-00>
