/*
 **************************************************************************
 *
 * Boot-ROM-Code to load an operating system across a TCP/IP network.
 *
 * Module:  bootpbuf.c
 * Purpose: Handle BOOTP/DHCP buffers
 * Entries: new_bootp_buf, set_bootp_size
 *
 **************************************************************************
 *
 * Copyright (C) 1999-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: bootpbuf.c,v 1.4 2003/01/25 23:29:41 gkminix Exp $
 */


#include <general.h>
#include <kernel/net.h>
#include <kernel/arpa.h>
#include <kernel/romlib.h>
#include "bootp.h"



/*
 **************************************************************************
 * 
 * BOOTP/DHCP buffers. These get allocated dynamically.
 */
#define MAX_BUF_SIZE	(BOOTP_PACKET_NUM * sizeof(struct bootp) + \
								BOOTP_EXT_SIZE)

static int last_buf = -1;			/* ID of last alloc'd buffer */
static unsigned char main_buf[MAX_BUF_SIZE];	/* main buffer */
static unsigned char *main_end = main_buf;	/* end of main buffer */
struct bootp *bootp_bufs[BOOTP_PACKET_NUM];	/* BOOTP buffer pointers */
unsigned int bootp_sizes[BOOTP_PACKET_NUM];	/* BOOTP buffer sizes */
int cur_bootp_buf;				/* ID of current buffer */



/*
 **************************************************************************
 * 
 * Allocate a new BOOTP/DHCP buffer.
 *
 */
int new_bootp_buf(id)
int id;
{
  unsigned int newsize;

  if (bootp_bufs[id] == NULL) {
	newsize = (main_buf + MAX_BUF_SIZE - main_end);
	if (last_buf != -1 || newsize < sizeof(struct bootp))
		return(FALSE);
	bootp_bufs[id] = (struct bootp *)main_end;
	bootp_sizes[id] = newsize;
	main_end += newsize;
	last_buf = id;
  }
  cur_bootp_buf = id;
  return(TRUE);
}



/*
 **************************************************************************
 * 
 * Resize the current BOOTP/DHCP buffer to it's actual size.
 *
 */
void set_bootp_size()
{
  register unsigned char *cp;
  unsigned int newsize;
  unsigned char *curbuf = (unsigned char *)(bootp_bufs[cur_bootp_buf]);

  /* Determine size of buffer */
  newsize = sizeof(struct bootp);
  (void)get_vend(VEND_NOP);
  if ((cp = get_vend(VEND_END)) != NULL) {
	newsize = cp - curbuf;
	if (newsize < sizeof(struct bootp))
		newsize = sizeof(struct bootp);
  }
  bootp_sizes[cur_bootp_buf] = newsize;

  /* If this is the last allocated buffer, we can make space for new buffers */
  if (last_buf == cur_bootp_buf) {
	main_end = curbuf + newsize;
	last_buf = -1;
  }
}



syntax highlighted by Code2HTML, v. 0.9.1