/* ************************************************************************** * * 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 * * 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 #include #include #include #include #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"); }