dhcp_00.c
来自「umon bootloader source code, support mip」· C语言 代码 · 共 253 行
C
253 行
/* dhcp_00.c:
* This file contains the functions that are called from dhcpboot.c if the
* the default DHCP interaction is to be done by the monitor. Whenever a
* new dhcp_XX.c file is created, this file should be used as the template.
*
* General notice:
* This code is part of a boot-monitor package developed as a generic base
* platform for embedded system designs. As such, it is likely to be
* distributed to various projects beyond the control of the original
* author. Please notify the author of any enhancements made or bugs found
* so that all may benefit from the changes. In addition, notification back
* to the author will allow the new user to pick up changes that may have
* been made by other users after this version of the code was distributed.
*
* Note1: the majority of this code was edited with 4-space tabs.
* Note2: as more and more contributions are accepted, the term "author"
* is becoming a mis-representation of credit.
*
* Original author: Ed Sutter
* Email: esutter@lucent.com
* Phone: 908-582-2351
*/
#include "config.h"
#include "cpuio.h"
#include "ether.h"
#include "tfs.h"
#include "tfsprivate.h"
#include "genlib.h"
#include "endian.h"
#include "stddefs.h"
#if INCLUDE_DHCPBOOT
/* ValidDHCPOffer():
* Target issued the DISCOVER, the incoming packet is the server's
* OFFER reply. If the DHCPOFFRFLTR shell variable is not present, then
* return 1 indicating acceptance of the offer. If the DHCPOFFRFLTR variable
* exists, then use its content to determine if the offer should be accepted...
*
* Shell variable syntax:
*
* DHCP_FIELD_IDENTIFIER,EXPECTED_STRING
*
* where DHCP_FIELD_IDENTIFIER can be...
* BFN bootfile name
* SHN server-host name
* VSO### vendor-specific option number (options encapsulated within
* the Vendor-Specific Information (#43) option)
* SSO### site-specific option number (range 128-254)
*
* For example:
* 1...
* if DHCPOFFRFLTR contains "BFN,abcfile"
* then the offer will only be accepted if the bootfile specified by the
* dhcp server contains the string "abcfile".
* 2...
* if DHCPOFFRFLTR contains "SHN,a_host_name"
* then the offer will only be accepted if the server-hostname specified
* by the dhcp server contains the string "a_host_name".
* 3...
* if DHCPOFFRFLTR contains "VSO18,some_String"
* then the offer will only be accepted if the server returns vendor-
* specific option # 18 and it contains the string "some_String".
*
* Note that "containing the string" means that the string specified in
* the DHCPOFFRFLTR shell variable can be the entire string or a sub-string
* within the server's response.
*/
int
ValidDHCPOffer(struct dhcphdr *dhdr)
{
char *var;
int offeraccepted, badsyntax;
/* If no DHCPOFFRFLTR var, accept the offer... */
var = getenv("DHCPOFFRFLTR");
if (!var)
return(1);
/* Start off by assuming acceptance... */
badsyntax = 0;
offeraccepted = 1;
/* Now process the DHCPOFFRFLTR variable and incoming dhcp data,
* and clear the offeraccepted (or set badsyntax) flag if necessary...
*/
if (!strncmp(var,"BFN,",4)) {
if (!strstr(dhdr->bootfile,var+4))
offeraccepted = 0;
}
else if (!strncmp(var,"SHN,",4)) {
if (!strstr(dhdr->server_hostname,var+4))
offeraccepted = 0;
}
else if ((!strncmp(var,"SSO",3)) || (!strncmp(var,"VSO",3))) {
int optno;
ulong cookie;
char *comma, *optval, *vso;
optno = atoi(var+3);
comma = strchr(var,',');
memcpy((char *)&cookie,(char *)&dhdr->magic_cookie,4);
if (cookie != ecl(STANDARD_MAGIC_COOKIE))
offeraccepted = 0;
else if (!comma)
badsyntax = 1;
else if (var[0] == 'S') {
if ((optno < 128) || (optno > 254))
badsyntax = 1;
else {
optval = DhcpGetOption(optno,(char *)(dhdr+1));
if (!optval)
offeraccepted = 0;
else {
if (!strstr(optval+2,comma+1))
offeraccepted = 0;
}
}
}
else if (var[0] == 'V') {
if ((optno < 0) || (optno > 254))
badsyntax = 1;
else {
vso = DhcpGetOption(DHCPOPT_VENDORSPECIFICINFO,
(char *)(dhdr+1));
if (!vso)
offeraccepted = 0;
else {
optval = DhcpGetOption(optno,vso+2);
if (!optval)
offeraccepted = 0;
else {
if (!strstr(optval+2,comma+1))
offeraccepted = 0;
}
}
}
}
}
else {
badsyntax = 1;
}
if (badsyntax) {
printf("Bad DHCPOFFRFLTR syntax.\n");
offeraccepted = 0;
}
return(offeraccepted);
}
/* DhcpVendorSpecific():
* Process any vendor specific data from the incoming header.
*/
void
DhcpVendorSpecific(struct dhcphdr *dhdr)
{
return; /* Obviously, the default is no processing. */
}
/* printDhcpVSopt():
* Input is the option, the option length and the pointer to the options.
* Print the option.
*/
int
printDhcpVSopt(int vsopt, int vsoptlen, char *options)
{
return(0);
}
/* buildDhcpHdr():
* Called by dhcpboot.c to allow application-specific header stuff to
* be added to header. Return 0 if generic stuff in dhcpboot.c is to be
* used; else return 1 and the calling code will assume this function is
* dealing with it (see dhcpboot.c for basic idea).
*/
int
buildDhcpHdr(struct dhcphdr *dhdr)
{
return(0);
}
/* DhcpBootpLoadVSA():
* Called by DhcpBootpDone to store an ascii-coded-hex copy of the
* vendor-specific-area (BOOTP) or options (DHCP) in the shell variable
* DHCPVSA.
*/
void
DhcpBootpLoadVSA(uchar *vsabin, int vsize)
{
int i;
uchar *cp, *vsaacx;
/* If after the transaction has completed, the RLYAGNT is */
/* set, but GIPADD is not set, copy RLYAGNT to GIPADD... */
if (!getenv("GIPADD") && getenv("RLYAGNT"))
setenv("GIPADD",getenv("RLYAGNT"));
/* Since the VSA (bootp) or options list (DHCP) can be large,
* This code looks for the presence of the DHCPVSA shell variable
* as an indication as to whether or not this data should be stored
* in the DHCPVSA variable...
* If the variable is present, then this code will load the DHCPVSA
* shell variable; else it just returns here.
* Note that it doesn't matter what the content of DHCPVSA is, as
* long as it is present, so just loading it with "TRUE" in monrc
* will be sufficient to tell this logic to load the variable with
* the data.
*/
if (!getenv("DHCPVSA"))
return;
/* If allocation succeeds, then copy BOOTP VendorSpecificArea to the */
/* DHCPVSA shell variable. Copy it as ascii-coded hex */
vsaacx = (uchar *)malloc((vsize*2)+4);
if (vsaacx) {
cp = vsaacx;
for(i=0;i<vsize;i++,cp+=2)
sprintf(cp,"%02x",vsabin[i]);
*cp = 0;
setenv("DHCPVSA",vsaacx);
free(vsaacx);
}
else
printf("DHCPVSA space allocation failed\n");
}
/* DhcpBootpDone():
* Called at the end of the Bootp or Dhcp transaction.
* Input...
* bootp: 1 if BOOTP; else DHCP.
* dhdr: pointer to dhcp or bootp header.
* vsize: size of vendor specific area (for bootp this is fixed at 64,
* but for dhcp it is variable).
*/
void
DhcpBootpDone(int bootp, struct dhcphdr *dhdr, int vsize)
{
if (bootp) {
struct bootphdr *bhdr;
bhdr = (struct bootphdr *)dhdr;
DhcpBootpLoadVSA(bhdr->vsa,vsize);
}
else {
DhcpBootpLoadVSA((uchar *)&dhdr->magic_cookie,vsize);
}
return;
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?