📄 ipraw.c
字号:
* Add a received packet to a sockets receive list.
*
* INPUTS
*
* port_index
* buf_ptr
*
* OUTPUTS
*
* NU_SUCCESS
*
*************************************************************************/
STATUS IPRaw_Append(INT port_index, NET_BUFFER *buf_ptr)
{
struct iport *iptr = IPR_Ports[port_index];
struct sock_struct *sockptr = SCK_Sockets[iptr->ip_socketd];
/* Place the datagram onto this ports datagram list. */
MEM_Buffer_Enqueue(&sockptr->s_recvlist, buf_ptr);
/* Update the number of buffered datagrams. */
sockptr->s_recvpackets++;
/* If there is a task pending data on the port, then set an event to
resume that task. */
if(sockptr->s_RXTask)
{
TLS_Put_Event (IPDATA, iptr->ip_socketd);
}
return (NU_SUCCESS);
} /* IPRaw_Append */
/***********************************************************************
*
* FUNCTION
*
* IPRaw_Cache_Route
*
* DESCRIPTION
*
* Cache a route for an IP socket.
*
* INPUTS
*
* iprt
* ip_addr
*
* OUTPUTS
*
* NU_SUCCESS
* NU_HOST_UNREACHABLE
*
*************************************************************************/
STATUS IPRaw_Cache_Route (struct iport *iprt, UINT32 ip_addr)
{
RTAB_ROUTE *ro;
UINT32 search_addr = ip_addr;
/* If the destination is the limited broadcast address, update it to the
broadcast address for the primary network interface. This is for the
purposes of route discovery below. */
if (search_addr == IP_ADDR_BROADCAST)
search_addr = DEV_Table.dv_head->dev_addr.dev_net_brdcast;
ro = &iprt->ip_route;
/* If there is already a route cached but the destination IP addresses
don't match then free the route. This comparison is done to the real
IP address not the search address, they will only be different when a
route for the limited broadcast address is desired. */
if (ro->rt_route && ((ro->rt_ip_dest.sck_addr != ip_addr) ||
((!(ro->rt_route->rt_device->dev_flags & DV_RUNNING)) &&
(!(ro->rt_route->rt_device->dev_flags & DV_UP)))))
{
RTAB_Free(ro->rt_route);
ro->rt_route = NU_NULL;
}
/* If there is no cached route then try to find one. */
if ( ro->rt_route == NU_NULL )
{
ro->rt_ip_dest.sck_addr = search_addr;
ro->rt_ip_dest.sck_family = SK_FAM_IP;
IP_Find_Route(ro);
}
/* If it was the limited broadcast address (255.255.255.255) that a
route was desired for then the route address will be wrong. Go ahead
and update it for all cases.
*/
ro->rt_ip_dest.sck_addr = ip_addr;
if (ro->rt_route)
{
return NU_SUCCESS;
}
else
return (NU_HOST_UNREACHABLE);
} /* IPRaw_Cache_Route */
/***********************************************************************
*
* FUNCTION
*
* IPRaw_Make_Port
*
* DESCRIPTION
*
* This is the intialization for IP Raw based communication. When an IP
* PCB needs to be created, this routine is called to do as much pre-
* initialization as possible to save overhead during operation.
*
*
* INPUTS
*
* socketd
*
* OUTPUTS
*
* INT16
*
*************************************************************************/
INT16 IPRaw_Make_Port (INT socketd)
{
INT16 i, retval = -1;
STATUS status;
UINT16 *return_ptr; /* pointer to memory block */
struct iport *p;
struct sock_struct *sockptr;
sockptr = SCK_Sockets[socketd];
p = NU_NULL;
for (i = 0; IPR_Ports[i] != NU_NULL; i++)
{
if (i >= IPR_MAX_PORTS)
{
NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);
return (-1); /* out of room for ports */
} /* end if */
} /* end for */
if (p == NU_NULL)
{
/* added during ATI mods - 10/1/92, bgh */
status = NU_Allocate_Memory(&System_Memory, (VOID **) &return_ptr,
(UNSIGNED)sizeof(struct iport),
(UNSIGNED)NU_NO_SUSPEND);
/* check status of memory allocation */
if (status == NU_SUCCESS)
{
return_ptr = (UINT16 *)TLS_Normalize_Ptr(return_ptr);
p = (struct iport *)return_ptr;
}
else
{
/* ERROR memory allocation error.\r\n */
NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);
return (-1); /* out of room for ports */
} /* end if */
IPR_Ports[i] = p;
retval = i;
} /* end if */
/* Clear the RawIP port structure. */
UTL_Zero((char *)p, sizeof(*p));
sockptr->s_recvpackets = 0;
sockptr->s_recvlist.head = NU_NULL;
sockptr->s_recvlist.tail = NU_NULL;
/* The socket with which this port is associated is unknown at this time. */
p->ip_socketd = socketd;
p->ip_route.rt_route = NU_NULL;
return (retval);
} /* end IPRaw_Make_Port */
/***********************************************************************
*
* FUNCTION
*
* IPRaw_Get_PCB
*
* DESCRIPTION
*
* This function is responsible for returning a TCP_Ports entry number
* to a caller based on a match with the port information sent in the
* socket descriptor.
*
* INPUTS
*
* socketd
* socket_desc
*
* OUTPUTS
*
* INT16 Port list entry.
*
*************************************************************************/
INT16 IPRaw_Get_PCB(INT socketd, struct sock_struct *socket_desc)
{
INT16 pnum = NU_IGNORE_VALUE; /* TCP_Ports entry number initialized */
INT16 index;
struct iport *iprt;
for (index=0; index < IPR_MAX_PORTS; index++)
{
iprt = IPR_Ports[index];
if ( iprt != NU_NULL &&
(iprt->ip_protocol == (UINT16)socket_desc->s_protocol) &&
(iprt->ip_socketd == socketd))
{
pnum=index;
break;
} /* end if */
} /* end for */
/* return a TCP_Ports entry number to the caller */
return(pnum);
} /* IPRaw_Get_PCB */
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -