📄 bootp.c
字号:
/**************************************************************************
*
* CopyrIght (c) 1993 - 2001 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 4.4
*
* DESCRIPTION
*
* This file will contain all the BOOTP routines.
*
* DATA STRUCTURES
*
* None.
*
* FUNCTIONS
*
* NU_Bootp Processes BOOTP function.
* BOOTP_init Initializes the BOOTP Request
* Packet.
* BOOTP_Process_Packet Processes the BOOTP Reply Packet.
*
* DEPENDENCIES
*
* BOOTP.H Holds the defines necessary for
* BOOTp to function properly.
*
****************************************************************************/
#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "net/inc/rtab.h"
#include "net/inc/udp.h"
#include "net/inc/mem_defs.h"
#include "net/inc/ip.h"
#include "net/inc/bootp.h"
#include "net/inc/nerrs.h"
#if (INCLUDE_BOOTP == NU_TRUE)
static UINT32 bootp_xid;
/* Local functions */
static UINT16 BOOTP_init (BOOTPLAYER *pkt, BOOTP_STRUCT *out_bp);
STATUS BOOTP_Process_Packets(INT socketd, BOOTP_STRUCT *bp, UINT16 timeout);
extern INT16 NU_rand(VOID);
/* This list is used to hold on to the BOOTP request that will be sent. By using
this list the need to build the request each time it is transmitted is
avoided. Instead the request is built once and then reused if
retransmissions are necessary. */
NET_BUFFER_HEADER BOOTP_List;
#define IOSIZE 1500 /* in/out buffer size */
/**************************************************************************
* FUNCTION
*
* NU_Bootp
*
* DESCRIPTION
*
* This routine will do the main processing of bootp lookup request
* calls. The function will build the entire packet from the mac layer
* to the BOOTP layer. It will send a bootp request packet, and process
* the BOOTP REPLY that is sent from the BOOTP Server.
* The code will also handle retries.
*
* INPUTS
*
* dv_name Pointer to Devices name.
* bp_ptr Pointer to BOOTP structure.
*
* OUTPUTS
*
* NU_SUCCESS Call was successful.
* NU_INVALID_PARM Invalid parameter.
* NU_BOOTP_INIT_FAILED General init failure.
* NU_NO_BUFFERS No buffers available for packet.
* NU_BOOTP_ATTACH_IP_FAILED Could not attach IP to device.
* NU_BOOTP_SEND_FAILED Could not send bootp packet.
*
****************************************************************************/
STATUS NU_Bootp ( CHAR *dv_name, BOOTP_STRUCT *bp_ptr)
{
UINT16 delay, delay_mask = 3;
INT i;
STATUS ret;
BOOTPLAYER *bootp_ptr;
IPLAYER *ip_ptr;
UDPLAYER *udp_pkt;
NET_BUFFER *buf_ptr;
NET_BUFFER *next_buf;
struct pseudotcp tcp_chk;
STATUS retval = 0;
DV_DEVICE_ENTRY *int_face;
INT socketd;
UINT8 HUGE *work_buffer;
UINT8 *buffer;
struct addr_struct clientaddr;
UINT16 nbytes;
STATUS status;
INT16 hlen = sizeof (IPLAYER);
INT length;
INT32 total_size, current_size;
STATUS found = 0;
INT32 flags;
SCK_SOCKADDR sa;
INT32 temp_data_len,temp_total_data_len;
UINT8 *ether_header;
NU_SUPERV_USER_VARIABLES
/* Validate parameters. */
if ((dv_name == NU_NULL) || (bp_ptr == NU_NULL))
return (NU_INVALID_PARM);
/* Create a socket and bind to it, so that we can receive packets. */
socketd = NU_Socket(NU_FAMILY_IP, NU_TYPE_DGRAM, NU_NONE);
if ( socketd < 0 )
{
NERRS_Log_Error (NERR_FATAL, __FILE__, __LINE__);
return (NU_BOOTP_INIT_FAILED);
}
/* build local address and port to bind to. */
clientaddr.family = NU_FAMILY_IP;
clientaddr.port = IPPORT_BOOTPC;
clientaddr.id.is_ip_addrs[0] = (UINT8) 0;
clientaddr.id.is_ip_addrs[1] = (UINT8) 0;
clientaddr.id.is_ip_addrs[2] = (UINT8) 0;
clientaddr.id.is_ip_addrs[3] = (UINT8) 0;
clientaddr.name = "ATI";
/* Allocate memory for the buffer space */
status = NU_Allocate_Memory(&System_Memory,(VOID **) &buffer,sizeof(BOOTPLAYER), NU_NO_SUSPEND);
if (status != NU_SUCCESS)
return (NU_BOOTP_INIT_FAILED);
/* Get a pointer to the buffer to work with. We do not want to
do anything with the original buffer pointer. It must be left
alone so that deallocation with work correctly. */
work_buffer = buffer;
/* Switch to supervisor mode. */
NU_SUPERVISOR_MODE();
ret = NU_Bind(socketd, &clientaddr, 0);
if ( ret != socketd )
{
NERRS_Log_Error (NERR_FATAL, __FILE__, __LINE__);
/* Free the buffer space since the bind failed. */
NU_Deallocate_Memory(buffer);
NU_Close_Socket(socketd);
/* Switch back to user mode. */
NU_USER_MODE();
return (NU_BOOTP_INIT_FAILED);
}
UTL_Zero(bp_ptr->bp_mac_addr, sizeof(bp_ptr->bp_mac_addr));
UTL_Zero(bp_ptr->bp_siaddr,sizeof(bp_ptr->bp_siaddr));
UTL_Zero(bp_ptr->bp_giaddr,sizeof(bp_ptr->bp_giaddr));
UTL_Zero(bp_ptr->bp_sname,sizeof(bp_ptr->bp_sname));
UTL_Zero(bp_ptr->bp_file,sizeof(bp_ptr->bp_file));
/* Get the device by name to be used on BOOTP for this iteration. */
int_face = DEV_Get_Dev_By_Name(dv_name);
if (int_face->dev_mtu < BOOTP_MAX_HEADER_SIZE)
{
/* Free the buffer space since the devices MTU is too small
to do BOOTP over. */
NU_Deallocate_Memory(buffer);
/* Switch back to user mode. */
NU_USER_MODE();
return (NU_BOOTP_INIT_FAILED);
}
/* copy the hardware address from the device structure */
memcpy(bp_ptr->bp_mac_addr, int_face->dev_mac_addr, DADDLEN);
/* make sure that the MAC address is a good. */
if ( memcmp(bp_ptr->bp_mac_addr, "\0\0\0\0\0\0", 6) == 0)
{
/* Free the buffer space since the MAC address is bad. */
NU_Deallocate_Memory(buffer);
/* Switch back to user mode. */
NU_USER_MODE();
return (NU_BOOTP_INIT_FAILED);
}
buf_ptr = MEM_Buffer_Chain_Dequeue(&MEM_Buffer_Freelist, BOOTP_MAX_HEADER_SIZE);
if (buf_ptr == NU_NULL)
{
/* Free the buffer space since there are no buffers to send
the BOOTP packet with. */
NU_Deallocate_Memory(buffer);
/* Switch back to user mode. */
NU_USER_MODE();
return (NU_NO_BUFFERS);
}
buf_ptr->mem_dlist = &BOOTP_List;
UTL_Zero(buf_ptr->mem_parent_packet, sizeof(NET_PARENT_BUFFER_SIZE));
if (buf_ptr->next_buffer != NU_NULL)
{
next_buf = buf_ptr->next_buffer;
UTL_Zero(next_buf->mem_packet, sizeof(NET_MAX_BUFFER_SIZE));
}
else
next_buf = NU_NULL;
/* Set up pointers to each of the headers that make up a BOOTP Packet. */
bootp_ptr = (BOOTPLAYER *)(buf_ptr->mem_parent_packet + (BOOTP_MAX_HEADER_SIZE - (sizeof(BOOTPLAYER))));
udp_pkt = (UDPLAYER *) (((CHAR *)bootp_ptr) - sizeof(UDPLAYER));
ip_ptr = (IPLAYER *) (((CHAR *)udp_pkt) - sizeof(IPLAYER));
/* Build the BOOTP Request Packet */
nbytes = BOOTP_init((BOOTPLAYER *)work_buffer, bp_ptr);
/* Initialize the local and foreign port numbers */
PUT16(udp_pkt, UDP_SRC_OFFSET, IPPORT_BOOTPC);
PUT16(udp_pkt, UDP_DEST_OFFSET, IPPORT_BOOTPS);
/* Set up the UDP Header */
PUT16(udp_pkt, UDP_LENGTH_OFFSET, (UINT16)(nbytes + sizeof(UDPLAYER)) );
PUT16(udp_pkt, UDP_CHECK_OFFSET, 0);
buf_ptr->data_ptr = buf_ptr->mem_parent_packet + NET_MAX_UDP_HEADER_SIZE;
total_size = nbytes;
/* Chain the Bootp Request Packet */
if (total_size > NET_PARENT_BUFFER_SIZE)
{
current_size = NET_PARENT_BUFFER_SIZE - sizeof(IPLAYER) - NET_ETHER_HEADER_OFFSET_SIZE;
total_size = total_size - current_size;
}
else
{
current_size = total_size;
}
/* Copy Bootp Packet into first Buffer */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -