/* $NetBSD: bootp.c,v 1.14 1998/02/16 11:10:54 drochner Exp $ */
/*
* Copyright (c) 1992 Regents of the University of California.
* All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) Header: bootp.c,v 1.4 93/09/11 03:13:51 leres Exp (LBL)
*/
__FBSDID("$FreeBSD$");
#include <netinet/in_systm.h>
#include <string.h>
#define BOOTP_DEBUGxx
#define SUPPORT_DHCP
/* set DHCP_ENV to one of the values above to export dhcp options to kenv */
#include "stand.h"
#include "net.h"
#include "netif.h"
#include "bootp.h"
#ifdef BOOTP_VEND_CMU
#endif
/* Local forwards */
#ifdef BOOTP_VEND_CMU
#endif
#ifdef DHCP_ENV /* export the dhcp response to kenv */
struct dhcp_opt;
#else
#define setenv_(a, b, c)
#endif
#ifdef SUPPORT_DHCP
#endif
/* Fetch required bootp infomation */
void
int sock;
int flag;
{
struct iodesc *d;
struct {
} wbuf;
struct {
} rbuf;
#ifdef BOOTP_DEBUG
if (debug)
#endif
if (!bot)
if (!(d = socktodesc(sock))) {
return;
}
#ifdef BOOTP_DEBUG
if (debug)
printf("bootp: d=%lx\n", (long)d);
#endif
#ifdef SUPPORT_DHCP
/*
* 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.
*/
} else
#else
#endif
#ifdef SUPPORT_DHCP
dhcp_ok = 0;
#endif
if(sendrecv(d,
== -1) {
printf("bootp: no reply\n");
return;
}
#ifdef SUPPORT_DHCP
if(dhcp_ok) {
} else
if(sendrecv(d,
== -1) {
printf("DHCPREQUEST failed\n");
return;
}
}
#endif
else
#ifdef BOOTP_DEBUG
if (debug)
#endif
/* Check subnet mask against net mask; toss if bogus */
#ifdef BOOTP_DEBUG
if (debug)
#endif
smask = 0;
}
/* Get subnet (or natural net) mask */
if (smask)
#ifdef BOOTP_DEBUG
if (debug)
#endif
/* We need a gateway if root is on a different net */
#ifdef BOOTP_DEBUG
if (debug)
printf("need gateway for root ip\n");
#endif
}
/* Toss gateway if on a different net */
#ifdef BOOTP_DEBUG
if (debug)
#endif
}
/* Bump xid so next request will be unique. */
++d->xid;
}
/* Transmit a bootp request */
static ssize_t
struct iodesc *d;
void *pkt;
{
#ifdef BOOTP_DEBUG
if (debug)
printf("bootpsend: d=%lx called.\n", (long)d);
#endif
#ifdef BOOTP_DEBUG
if (debug)
printf("bootpsend: calling sendudp\n");
#endif
}
static ssize_t
struct iodesc *d;
void *pkt;
{
ssize_t n;
#ifdef BOOTP_DEBUGx
if (debug)
printf("bootp_recvoffer: called\n");
#endif
goto bad;
#ifdef BOOTP_DEBUG
if (debug)
printf("bootprecv: checked. bp = 0x%lx, n = %d\n",
(long)bp, (int)n);
#endif
#ifdef BOOTP_DEBUG
if (debug) {
printf("bootprecv: expected xid 0x%lx, got 0x%x\n",
}
#endif
goto bad;
}
#ifdef BOOTP_DEBUG
if (debug)
printf("bootprecv: got one!\n");
#endif
/* Suck out vendor info */
goto bad;
}
#ifdef BOOTP_VEND_CMU
#endif
else
return(n);
bad:
errno = 0;
return (-1);
}
static int
{
int size;
const char *val;
#ifdef BOOTP_DEBUG
if (debug)
#endif
/* Step over magic cookie */
cp += sizeof(int);
break;
if (tag == TAG_SUBNET_MASK) {
}
if (tag == TAG_GATEWAY) {
}
if (tag == TAG_SWAPSERVER) {
/* let it override bp_siaddr */
}
if (tag == TAG_ROOTPATH) {
}
if (tag == TAG_HOSTNAME) {
}
#ifdef SUPPORT_DHCP
if (tag == TAG_DHCP_MSGTYPE) {
if(*cp != expected_dhcpmsgtype)
return(-1);
dhcp_ok = 1;
}
if (tag == TAG_SERVERID) {
sizeof(dhcp_serverip.s_addr));
}
#endif
}
return(0);
}
#ifdef BOOTP_VEND_CMU
static void
{
#ifdef BOOTP_DEBUG
if (debug)
printf("vend_cmu bootp info.\n");
#endif
}
}
}
#endif
#ifdef DHCP_ENV
/*
* Parse DHCP options and store them into kenv variables.
* Original code from Danny Braniss, modifications by Luigi Rizzo.
*
* The parser is driven by tables which specify the type and name of
* each dhcp option and how it appears in kenv.
* The first entry in the list contains the prefix used to set the kenv
* name (including the . if needed), the last entry must have a 0 tag.
* Entries do not need to be sorted though it helps for readability.
*
* Certain vendor-specific tables can be enabled according to DHCP_ENV.
* Set it to 0 if you don't want any.
*/
};
struct dhcp_opt {
const char *desc;
};
{0, 0, "FreeBSD"}, /* prefix */
{0, 0, "pxe"}, /* prefix */
#else /* default (empty) table */
{0, 0, "dhcp.vendor."}, /* prefix */
#endif
{0, __TXT, "%soption-%d"}
};
/* DHCP Option names, formats and codes, from RFC2132. */
{0, 0, "dhcp."}, // prefix
/* use the following entries for arbitrary variables */
{0, __TXT, "%soption-%d"}
};
/*
* parse a dhcp response, set environment variables translating options
* names and values according to the tables above. Also set dhcp.tags
* to the list of selected tags.
*/
static void
{
break;
if (tag == 0)
continue;
;
/* if not found we end up on the default entry */
/*
* Copy data into the buffer. libstand does not have snprintf so we
* need to be careful with sprintf(). With strings, the source is
* always <256 char so shorter than the buffer so we are safe; with
* other arguments, the longest string is inet_ntoa which is 16 bytes
* so we make sure to have always enough room in the string before
* trying an sprint.
*/
*vp = '\0';
case __NONE:
break; /* should not happen */
case __VE: /* recurse, vendor specific */
break;
case __IP: /* ip address */
}
break;
case __BYTES: /* opaque byte string */
}
break;
case __TXT:
break;
case __32:
case __16:
case __8: /* op->fmt is also the length of each field */
uint32_t v;
else
v = cp[0];
}
break;
case __INDIR: /* name=value */
case __ILIST: /* name=value;name=value... */
/* skip leading whitespace */
endv++;
if (!vp)
break;
*vp++ = 0;
*s++ = '\0';
vp = s; /* prepare for next round */
}
}
}
if (buf[0]) {
else
/*
* Do not replace existing values in the environment, so that
* locally-obtained values can override server-provided values.
*/
}
}
}
}
#endif /* additional dhcp */