📄 bootp.c
字号:
memcpy(buf_ptr->data_ptr , work_buffer, (INT)current_size);
/* Set the Data Length to the Size of bytes copied. */
buf_ptr->data_len = current_size;
/* Set the Total data length to the Number of bytes in a Bootp Packet. */
buf_ptr->mem_total_data_len = nbytes;
/* Increment Bootp Buffer to be at the number of bytes copied. */
work_buffer = work_buffer + current_size;
/* Check to make sure there is data to store in the mem_packet */
while ((total_size) && (next_buf != NU_NULL))
{
if (total_size > NET_MAX_BUFFER_SIZE)
{
current_size = NET_MAX_BUFFER_SIZE;
}
else
{
current_size = total_size;
}
total_size = total_size - current_size;
/* Copy the remaining data in the chaining packets */
memcpy(next_buf->mem_packet,work_buffer,(INT)current_size);
/* Set the Data pointer to the remainder of the packets. */
next_buf->data_ptr = next_buf->mem_packet;
next_buf->next = NU_NULL;
next_buf->data_len = current_size;
work_buffer = work_buffer + current_size;
if (next_buf->next_buffer != NU_NULL)
{
next_buf = next_buf->next_buffer;
}
}
/* Increment the Packet data pointer to the UDP layer */
buf_ptr->data_ptr -= sizeof(UDPLAYER);
/* Copy the udp_pkt into the parent_packet. */
memcpy(buf_ptr->data_ptr,(UINT8 *)udp_pkt,sizeof(UDPLAYER));
/* Increment the total data length */
buf_ptr->mem_total_data_len += sizeof(UDPLAYER);
/* Increment the data length of this packet. */
buf_ptr->data_len += sizeof(UDPLAYER);
/* Calculate UDP Checksum */
tcp_chk.source = 0x0;
tcp_chk.dest = 0xFFFFFFFFUL;
tcp_chk.z = 0;
tcp_chk.proto = IP_UDP_PROT;
tcp_chk.tcplen = INTSWAP((UINT16)buf_ptr->mem_total_data_len);
PUT16(udp_pkt, UDP_CHECK_OFFSET, TLS_TCP_Check( (UINT16 *)&tcp_chk, buf_ptr) );
/* If a checksum of zero is computed it should be replaced with 0xffff. */
if (GET16(udp_pkt, UDP_CHECK_OFFSET) == 0)
PUT16(udp_pkt, UDP_CHECK_OFFSET, 0xFFFF);
/* Set up the IP header */
PUT8(ip_ptr, IP_VERSIONANDHDRLEN_OFFSET, (UINT8) (((hlen >> 2)) | (IP_VERSION << 4)) );
/* Set the IP header to no fragments. */
PUT16(ip_ptr, IP_FRAGS_OFFSET, 0);
/* Set the IP packet ID. */
PUT16(ip_ptr, IP_IDENT_OFFSET, 0);
/* Set the type of service. */
PUT8(ip_ptr, IP_SERVICE_OFFSET, 0);
/* Set the total length( data and IP header) for this packet. */
length = nbytes +(UINT16)sizeof(UDPLAYER);
PUT16(ip_ptr, IP_TLEN_OFFSET, (INT16)(length + hlen) );
/* Set the time to live. */
PUT8(ip_ptr, IP_TTL_OFFSET, IP_TIME_TO_LIVE);
/* Set the protocol. */
PUT8(ip_ptr, IP_PROTOCOL_OFFSET, IP_UDP_PROT);
/* We are doing a broadcast, so we do not need this fields. */
PUT32(ip_ptr, IP_SRC_OFFSET, 0);
PUT32(ip_ptr, IP_DEST_OFFSET, IP_ADDR_BROADCAST);
/* Compute the IP checksum. */
PUT16(ip_ptr, IP_CHECK_OFFSET, 0);
PUT16(ip_ptr, IP_CHECK_OFFSET, TLS_IP_Check((UINT16 *)ip_ptr, (UINT16)(hlen >> 1)) );
/* Set the buffer pointer to the IP Layer. */
buf_ptr->data_ptr -= sizeof(IPLAYER);
/* Add the IPLAYER to the total data length */
buf_ptr->mem_total_data_len += sizeof(IPLAYER);
temp_total_data_len = buf_ptr->mem_total_data_len;
/* Set the data length of the current packet. */
buf_ptr->data_len += sizeof(IPLAYER);
temp_data_len = buf_ptr->data_len;
/* Copy the IP header into the parent packet of the buffer chain. */
memcpy(buf_ptr->data_ptr,(UINT8 *)ip_ptr,sizeof(IPLAYER));
/* Set initial Delay for Processing packets. */
delay= (UINT16) ((delay_mask & UTL_Rand()) + 1);
/* Innitialize the ethernet header. */
ether_header = (UINT8 *)sa.sck_data;
PUT_STRING(ether_header, ETHER_DEST_OFFSET, NET_Ether_Broadaddr, DADDLEN);
PUT_STRING(ether_header, ETHER_ME_OFFSET, bp_ptr->bp_mac_addr, DADDLEN);
PUT16(ether_header, ETHER_TYPE_OFFSET, INTSWAP(EIP));
sa.sck_family = SK_FAM_UNSPEC;
sa.sck_len = sizeof(sa);
/* Transmit the packet */
for (i = 0; i < BOOTP_RETRIES; i++)
{
/* Grab the semaphore because we are about to change the interface
that the BOOTP request will be sent over. */
NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
/* The device will not send packets until an IP address is attached.
Temporarily trick it into thinking an IP address is attached so this
request can be sent. Then set it back. */
flags = int_face->dev_flags;
int_face->dev_flags |= (DV_UP | DV_RUNNING);
/* Send the packet. */
status = (*(int_face->dev_output)) (buf_ptr, int_face,
(SCK_SOCKADDR_IP *)&sa, NU_NULL);
int_face->dev_flags = flags;
NU_Release_Semaphore(&TCP_Resource);
if (status != NU_SUCCESS)
{
NERRS_Log_Error(NERR_FATAL, __FILE__,__LINE__);
retval = NU_BOOTP_SEND_FAILED;
break;
}
/* Look at each packet on the buffer list to see if it is my reply */
found = BOOTP_Process_Packets(socketd, bp_ptr, delay);
if (found == NU_TRUE)
break; /* Found the Packet. */
delay_mask++;
delay = (UINT16) ((delay_mask & UTL_Rand()) + 1);
/* Get the the packet off the Trasmitted list and retrasnmit again. */
MEM_Buffer_Remove (&BOOTP_List, buf_ptr);
buf_ptr->data_ptr = buf_ptr->mem_parent_packet + NET_ETHER_HEADER_OFFSET_SIZE;
buf_ptr->data_len = temp_data_len;
buf_ptr->mem_total_data_len = temp_total_data_len;
} /* End For Loop */
/* Have we errored out? */
if (retval == NU_NULL)
{
/* We did not error out. Did we get a response? */
if (found == NU_TRUE)
{
status = DEV_Attach_IP_To_Device( dv_name, bp_ptr->bp_yiaddr,
bp_ptr->bp_net_mask);
if (status != NU_SUCCESS)
{
NERRS_Log_Error(NERR_FATAL, __FILE__, __LINE__);
retval = NU_BOOTP_ATTACH_IP_FAILED;
}
else
retval = NU_SUCCESS;
}
else
retval = found;
} /* end if we errored out */
/* Cleanup */
NU_Close_Socket(socketd);
/* Free this buffer by pulling it off of the bootp list and
putting it onto the free list. */
MEM_Buffer_Remove (&BOOTP_List, buf_ptr);
MEM_One_Buffer_Chain_Free (buf_ptr, &MEM_Buffer_Freelist);
NU_Deallocate_Memory(buffer);
/* Switch back to user mode. */
NU_USER_MODE();
return (retval);
} /* NU_Bootp */
/**************************************************************************
* FUNCTION
*
* BOOTP_init
*
* DESCRIPTION
*
* This routine will handle the initing of the bootp packet.
*
* INPUTS
*
* pkt Packet to be transmitted.
* out_bp The structure that contains global data.
*
* OUTPUTS
*
* len The length of the BOOTP Request packet.
*
****************************************************************************/
static UINT16 BOOTP_init (BOOTPLAYER *pkt, BOOTP_STRUCT *out_bp)
{
/* Initially, there are no buffers on the BOOTP_List. */
BOOTP_List.head = NU_NULL;
BOOTP_List.tail = NU_NULL;
/* get a unique transaction ID */
bootp_xid = NU_Retrieve_Clock();
/* Set the Packet to all 0's */
memset(pkt, 0, sizeof(BOOTPLAYER) );
/* This is a bootp request. */
pkt->bp_op = BOOTREQUEST;
/* Initialize the hardware dependencies */
pkt->bp_htype = HARDWARE_TYPE;
pkt->bp_hlen = DADDLEN; /* Hardware Address 1 octet */
/* Initialize the unique ID. */
pkt->bp_xid = bootp_xid;
/* The number of seconds the bootp client has been running. */
pkt->bp_secs = 1;
memcpy(pkt->bp_chaddr, out_bp->bp_mac_addr,DADDLEN);
/* Initialize the server's ip address to the broadcast address.
* The server will fill in his correct address. */
memcpy(pkt->bp_siaddr.is_ip_addrs, IP_Brd_Cast, IP_ADDR_LEN);
return (sizeof(*pkt));
} /* BOOTP_init */
/**************************************************************************
* FUNCTION
*
* BOOTP_Process_Packets
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -