/*
 **************************************************************************
 *
 * 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(&params, 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(&params)) != 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