📄 ipraw.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 implicitly
* accepts the terms of the license.
*
*************************************************************************/
/**************************************************************************
*
* FILENAME VERSION
*
* IPRAW.C 4.4
*
* DESCRIPTION
*
* IPRAW Protocol routines
*
* DATA STRUCTURES
*
*
* FUNCTIONS
*
* IPRaw_Read
* IPRaw_Send
* IPRaw_Append
* IPRaw_Interpret
* IPRaw_Cache_Route
* IPRaw_Make_Port
* IPRaw_Get_PCB
*
*
* DEPENDENCIES
*
* No other file dependencies
*
****************************************************************************/
#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "net/inc/mem_defs.h"
#include "net/inc/rtab.h"
#include "net/inc/ipraw.h"
#include "net/inc/socketd.h"
#include "net/inc/nerrs.h"
#include "net/inc/netevent.h"
#include "net/inc/arp.h"
#include "net/inc/ip.h"
#if (INCLUDE_SNMP == NU_TRUE)
#include SNMP_GLUE
#endif
/* Import external variables */
extern NET_BUFFER_HEADER MEM_Buffer_Freelist;
extern NU_TASK NU_EventsDispatcher_ptr;
extern NU_TASK timer_task_ptr;
#if INCLUDE_IP_RAW
STATUS IPRaw_Append(INT port_index, NET_BUFFER *buf_ptr);
STATUS IPRaw_Cache_Route (struct iport *, UINT32);
struct iport *IPR_Ports[IPR_MAX_PORTS];
/***********************************************************************
*
* FUNCTION
*
* IPRaw_Read
*
* DESCRIPTION
*
* Get the data from the IP buffer and transfer it into your buffer.
* Returns the number of bytes transferred or -1 of none available.
*
* INPUTS
*
* iptr
* buffer
* from
* sockptr
*
* OUTPUTS
*
* INT16:
* Number of bytes copied.
* NU_NO_DATA_TRANSFER
*
*************************************************************************/
INT16 IPRaw_Read (struct iport *iptr, CHAR *buffer, struct addr_struct *from,
struct sock_struct *sockptr)
{
IPLAYER *ip_pkt_ptr;
INT bytes_copied;
NET_BUFFER *buf_ptr;
UNUSED_PARAMETER(iptr);
/* Check to see if there are any packets waiting. */
if(sockptr->s_recvlist.head == NU_NULL)
return (NU_NO_DATA_TRANSFER);
/* Set up a pointer to the packet stored in first buffer in the list */
ip_pkt_ptr = (IPLAYER *) (sockptr->s_recvlist.head->data_ptr);
/* Move the data into the caller's buffer, copy it from the buffer chain. */
/* Get a pointer to the data */
buf_ptr = sockptr->s_recvlist.head;
/* Do the parent buffer first */
NU_BLOCK_COPY(buffer, buf_ptr->data_ptr, (INT)buf_ptr->data_len);
/* Update the bytes copied. */
bytes_copied = (INT)(buf_ptr->data_len);
/* Loop through the chain if needed and copy all buffers. */
while (buf_ptr->next_buffer != NU_NULL)
{
/* Move to the next buffer in the chain */
buf_ptr = buf_ptr->next_buffer;
/* Copy the data */
NU_BLOCK_COPY(buffer + bytes_copied, buf_ptr->data_ptr, (INT)buf_ptr->data_len);
/* Update the bytes copied. */
bytes_copied += (INT)(buf_ptr->data_len);
} /* end while there are buffers in the chain */
/* Get his IP number. */
*(UINT32 *)from->id.is_ip_addrs = LONGSWAP(GET32(ip_pkt_ptr, IP_SRC_OFFSET));
from->port = 0;
/* Update the socket descriptor with foreign address information. */
*(UINT32 *)sockptr->s_foreign_addr.ip_num.is_ip_addrs =
LONGSWAP(GET32(ip_pkt_ptr, IP_SRC_OFFSET));
/* Place this buffer back onto the free list. */
MEM_Buffer_Chain_Free (&sockptr->s_recvlist, &MEM_Buffer_Freelist);
/* Update the number of buffered datagrams. */
sockptr->s_recvpackets--;
return ((INT16)bytes_copied);
} /* IPRaw_Read */
/***********************************************************************
*
* FUNCTION
*
* IPRaw_Send
*
* DESCRIPTION
*
* Send some data out in a IP packet.
*
* Returns 0 on ok send, non-zero for an error
*
* INPUTS
*
* iptr
* buffer
* nbytes
* sock_options
*
* OUTPUTS
*
* INT16
* NU_NO_BUFFERS
* Number of bytes sent.
* -1
*
*************************************************************************/
INT16 IPRaw_Send (struct iport *iptr, UINT8 *buffer, UINT16 nbytes,
UINT16 sock_options)
{
NET_BUFFER *buf_ptr, *work_buf;
STATUS stat;
INT32 bytes_left;
UINT8 *work_ptr;
struct sock_struct *sock_ptr = SCK_Sockets[iptr->ip_socketd];
/* Remove compiler warning. */
UNUSED_PARAMETER(sock_options);
/* Before we do anything else make sure a route to the host is up. */
if ( (stat = IPRaw_Cache_Route (iptr, iptr->ip_faddr)) != NU_SUCCESS)
return ( (INT16) stat );
/* Extract the local IP address to use from the route. */
iptr->ip_laddr = iptr->ip_route.rt_route->rt_device->dev_addr.dev_ip_addr;
/* Don't send more than we have concluded is our maximum. Our maximum
is different here depending on if the IP header is to be generated
by the stack or if it was created by the application. */
if (sock_ptr->s_flags & IP_RAWOUTPUT)
{
/* Check for the max size. The macro IMAXLEN does not include the IP
header so it must be subtracted off the nbytes before the
comparision. */
if ( (nbytes - ( (GET8(buffer, IP_VERSIONANDHDRLEN_OFFSET) & 0xf) << 2) )
> (IMAXLEN) )
return (NU_MSGSIZE);
}
else
{
/* No IP header is supplied so just check the length. */
if (nbytes > IMAXLEN)
nbytes = IMAXLEN;
}
/* Allocate a buffer, or chain of buffers, to place the packet in. The size is
increased by the various protocols header sizes to make room for them.*/
buf_ptr = MEM_Buffer_Chain_Dequeue(&MEM_Buffer_Freelist, (INT32)(nbytes
+ NET_MAX_IP_HEADER_SIZE));
if(buf_ptr == NU_NULL)
{
SNMP_ipOutDiscards_Inc;
return (NU_NO_BUFFERS);
}
buf_ptr->mem_total_data_len = nbytes;
/* Set the deallocation list pointer. */
buf_ptr->mem_dlist = &MEM_Buffer_Freelist;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -