/*
**************************************************************************
*
* Boot-ROM-Code to load an operating system across a TCP/IP network.
*
* Module: getext.c
* Purpose: Get BOOTP vendor extensions file
* Entries: get_ext
*
**************************************************************************
*
* Copyright (C) 1995-2003 Gero Kuhlmann <gero@gkminix.han.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: getext.c,v 1.5 2003/01/25 23:29:41 gkminix Exp $
*
**************************************************************************
*
* We can print error messages within this module as it gets never called
* by a PXE function.
*/
#include <general.h>
#include <kernel/net.h>
#include <kernel/arpa.h>
#include <kernel/romlib.h>
#include <pxe/common.h>
#include "bootp.h"
/*
**************************************************************************
*
* Get vendor extensions file with TFTP.
*/
void get_ext(ftag)
unsigned char *ftag;
{
register unsigned char *cp;
unsigned char *endp;
t_tftp_read_file params;
int i;
/*
* Determine address where to load the extension file. If the END tag
* can't be found we silently return like when no extension file has
* been given.
*/
if ((endp = get_vend(VEND_END)) == NULL)
return;
endp--;
/*
* Setup parameter structure for TFTP transfer.
*/
memset(¶ms, 0, sizeof(params));
if ((i = *ftag) > (sizeof(params.filename) - 1))
i = sizeof(params.filename) - 1;
memcpy(params.filename, ftag + 1, i);
params.server = bootp_bufs[cur_bootp_buf]->bp_siaddr;
params.gateway = n_IP_ANY;
params.buffer = far2long(MK_FP(getds(), endp));
params.bufsize = (unsigned char *)(bootp_bufs[cur_bootp_buf]) +
bootp_sizes[cur_bootp_buf] - endp;
/*
* If the buffer size available is not sufficient for at least a minimal
* extensions file, return as if no extensions file has been specified.
*/
if (params.bufsize < (VM_SIZE + 2))
return;
/*
* Now read the file via TFTP
*/
printf("BOOTP: Loading %s: ", params.filename);
if ((i = tftp_read_file(¶ms)) != PXENV_STATUS_SUCCESS) {
printf("TFTP error %x", i);
goto getext_err;
}
/*
* Check that the file starts with the correct vendor extension. If it
* does, overwrite the signature with all NOPs so that the record
* becomes valid.
*/
cp = endp;
if (params.bufsize < (VM_SIZE + 1) ||
*((unsigned long *)(cp)) != VM_RFC1048) {
printf("Invalid file");
goto getext_err;
}
for (i = 0; i < VM_SIZE; i++)
*(cp++) = VEND_NOP;
/* Finally check that we have an end identifier at all */
(void)get_vend(VEND_NOP);
if (get_vend(VEND_END) == NULL) {
printf("No END tag");
goto getext_err;
}
printf("ok\n");
return;
getext_err:
/* In case of error, restore the original BOOTP record */
*endp = VEND_END;
printf(", ignored\n");
}
syntax highlighted by Code2HTML, v. 0.9.1