📄 bootp.c
字号:
/****************************************************************************/
/* */
/* CopyrIght (c) 1993 - 1996 Accelerated Technology, Inc. */
/* */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the subject */
/* matter of this material. All manufacturing, reproduction, use and sales */
/* rights pertaining to this subject matter are governed by the license */
/* agreement. The recipient of this software implicity accepts the terms */
/* of the license. */
/* */
/****************************************************************************/
/****************************************************************************/
/* */
/* FILENAME VERSION */
/* */
/* Bootp 3.2 */
/* */
/* DESCRIPTION */
/* */
/* This file will contain all the bootp routines. */
/* */
/* AUTHOR */
/* */
/* Craig L. Meredith, Accelerated Technology Inc. */
/* */
/* DATA STRUCTURES */
/* */
/* global compenent data stuctures defined in this file */
/* */
/* FUNCTIONS */
/* */
/* bootp_init */
/* parse_bootpacket */
/* bootp */
/* BOOTP_Rand */
/* */
/* DEPENDENCIES */
/* */
/* No other file dependencies */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Craig L. Meredith 04/10/93 Initial version. */
/* Maiqi Qian 12/06/96 Fixed the time wrap around (spr0229) */
/* Maiqi Qian 12/12/96 Added a buffer for receiving reply. */
/* */
/****************************************************************************/
#include "protocol.h"
#include "socketd.h"
#include "bootp.h"
#include "hostform.h"
#include "externs.h"
#include "data.h"
#ifdef PLUS
#include "nucleus.h"
#else
#include "nu_defs.h"
#include "nu_extr.h"
#endif
#include "tcp_errs.h"
#include "target.h"
#include "tcp.h"
#if SNMP_INCLUDED
#include "snmp_g.h"
#endif
/*
* Bootp routines : from the Clarkson 2.2 version of NCSA Telnet.
* Thanks to Brad Clements for implementing this!
*
* bootp routines - These routines are based on the stanford/clarkson
* bootp code. Originally developed at Stanford University.
*
* Bootp is a UDP based protocol that determines the clients IP address and
* gateway information etc.
*/
static ulint bootp_xid;
/* Local functions */
static struct uport *bootp_init (struct bootp *, int16 *, uint8 *);
static int16 parse_in_bp (struct bootp *bp, uint8 *file_name);
static void bootp_cleanup(int16);
static INT BOOTP_Rand(VOID);
/****************************************************************************/
/* FUNCTION */
/* */
/* NU_Bootp */
/* */
/* DESCRIPTION */
/* */
/* This routine will do the main processing of bootp lookup request calls, */
/* send a bootp request packet, and set up the UDP listen port. Will also */
/* handle the retries. */
/* */
/* AUTHOR */
/* */
/* Craig L. Meredith, Accelerated Technology Inc. */
/* */
/* CALLED BY */
/* */
/* No functions call this function */
/* */
/* CALLS */
/* */
/* netsetip */
/* bootp_init */
/* neturead */
/* netulisten */
/* BOOTP_Rand */
/* demux */
/* comparen */
/* parse_bootpacket */
/* */
/* INPUTS */
/* */
/* No inputs to the function */
/* */
/* OUTPUTS */
/* */
/* sint : Returns status flag of 0 if ok, else -1 for fail. */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Craig L. Meredith 04/10/93 Initial version. */
/* */
/****************************************************************************/
int16 NU_Bootp (uint8 *file_name)
{
sint bootp_try;
uint16 delay, delay_mask = 3;
int16 bytes_sent;
#ifdef PLUS
UNSIGNED timeout;
#else
int16 timeout;
#endif
uchar in_buf[1500], out_buf[1500];
int16 port_num = 0;
struct addr_struct addr;
struct sock_struct socket;
struct bootp *in_bp;
struct bootp *out_bp;
struct uport *uprt;
/* Make sure our IP is initialized to all zeros. This ensures that
* when we send the bootp request the bootp server is informed that
* we don't know our own IP number.
*/
netsetip ((uchar *)nullip);
/* set up the in_bp pointer. */
in_bp = (struct bootp *)in_buf;
out_bp = (struct bootp *)out_buf;
/* Initialize bootp */
uprt = bootp_init (out_bp, &port_num, file_name);
/* Clear out any data that might be in the udp port. */
while (neturead (uprt, (char *)in_buf, &addr, &socket) != NU_NO_DATA_TRANSFER)
; /* should only go around once */
/* Set up the socket options options to enable broadcast packets. */
socket.so_options = SO_BROADCAST;
for (bootp_try = 0; bootp_try < BOOTP_RETRIES; bootp_try++)
{
/* Make sure we are listening on the bootp client port. */
netulisten (IPPORT_BOOTPC);
/* Send the bootp request. */
bytes_sent = netusend(uprt, out_buf,
(sint)sizeof(struct bootp), socket.so_options);
/* Was the whole packet sent. */
if (bytes_sent != (int16)sizeof(struct bootp))
{ /* do some error processing */
bootp_cleanup(port_num);
return (-1);
}
/* Randomize the delay. Helps reduce the chances of flodding the
* network if many diskless stations boot at the same time.
*/
delay = (delay_mask & BOOTP_Rand()) + 1;
/* Calculate a timeout value based on the number of ticks per second */
timeout = n_clicks() + (delay * TICKSPERSEC);
/* Check, until a timeout occurs, to see if a response has arrived. */
while (INT32_CMP(timeout, n_clicks()) >= 0)
{
/* Allow other tasks to run while waiting for a response. */
NU_Sleep(TICKSPERSEC >> 2);
/* Grab the response. */
if (neturead (uprt, (char *)in_buf, &addr, &socket) > 0)
{
delay = 0;
break;
}
}
/* Did a timeout occure? */
if(delay)
{
/* A timeout occured. Has the maximum timeout value been reached
* yet? If not, increase the length of the mask by one bit.
*/
if (delay_mask < MAX_BOOTP_TIMEOUT)
delay_mask = delay_mask | (delay_mask + 1);
/* Update the amount of time the bootp client has been running. */
out_bp->bp_secs += delay;
/* Try again. */
continue;
}
/* Is this a reply to our request. */
if (((in_bp->bp_xid) == bootp_xid) &&
((in_bp->bp_op) == BOOTREPLY) &&
comparen (in_bp->bp_chaddr, nnmyaddr, sizeof(nnmyaddr)))
{
/* Parse the reply, returning success if everything goes okay. */
if (parse_in_bp (in_bp, file_name))
{
bootp_cleanup(port_num);
return (-1);
}
bootp_cleanup(port_num);
return (NU_SUCCESS);
}
} /* end for loop */
/* If we got this for then we never received a reply.
* Return an error code. */
bootp_cleanup(port_num);
return(-1);
} /* end bootp routine */
/****************************************************************************/
/* FUNCTION */
/* */
/* bootp_init */
/* */
/* DESCRIPTION */
/* */
/* This routine will handle the initing of the bootp packet. */
/* */
/* AUTHOR */
/* */
/* Craig L. Meredith, Accelerated Technology Inc. */
/* */
/* CALLED BY */
/* */
/* No functions call this function */
/* */
/* CALLS */
/* */
/* memset */
/* memcpy */
/* */
/* INPUTS */
/* */
/* No inputs to the function */
/* */
/* OUTPUTS */
/* */
/* No outputs from this function */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Craig L. Meredith 04/10/93 Initial version. */
/* */
/****************************************************************************/
static struct uport *bootp_init (struct bootp *out_bp, int16 *port_num,
uint8 *file_name)
{
struct uport *uprt;
INT i;
CHAR *temp;
/* get a unique transaction ID */
bootp_xid = n_clicks();
/* Initialize the entire packet to zeros. This puts all fields into
* their default state. */
for (i = 0; i < sizeof(struct bootp); i++, *temp++ = 0);
/* This is a bootp request. */
out_bp->bp_op = BOOTREQUEST;
/* Initialize the hardware dependencies */
out_bp->bp_htype = HARDWARE_TYPE;
out_bp->bp_hlen = DADDLEN;
/* Initialize the unique ID. */
out_bp->bp_xid = bootp_xid;
/* The number of seconds the bootp client has been running. */
out_bp->bp_secs = 1;
/* Fill in the clients hardware address. The server will use this
* to look up the correct ip address. */
memcpy((void *)out_bp->bp_chaddr, nnmyaddr, sizeof(nnmyaddr));
/* Initialize the server's ip address to the broadcast address.
* The server will fill in his correct address. */
memcpy((void *)out_bp->bp_siaddr.is_ip_addrs,
broadip, sizeof(broadip));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -