📄 udp.c
字号:
return (stat);
}
/* If the send went ok, then return the number of bytes sent. */
return(nbytes);
} /* UDP_Send */
/*************************************************************************
*
* FUNCTION
*
* UDP_Cache_Route
*
* DESCRIPTION
*
* Cache a route for a UDP socket.
*
* INPUTS
*
* *uprt
* ip_addr
*
* OUPUTS
*
* NU_SUCCESS
* NU_HOST_UNREACHABLE
*
*************************************************************************/
STATUS UDP_Cache_Route (UDP_PORT *uprt, UINT32 ip_addr)
{
RTAB_ROUTE *ro;
UINT32 search_addr = ip_addr;
/* Point to the cached route */
ro = &uprt->up_route;
/* 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)
{
/* default bcast route? */
if ( (uprt->up_socketd >= 0) &&
(SCK_Sockets[uprt->up_socketd]->s_bcast_if) )
/* Set the search addr */
search_addr = SCK_Sockets[uprt->up_socketd]->
s_bcast_if->dev_addr.dev_net;
else
{
/* Use the primary interface, skip the loopback */
if ( (DEV_Table.dv_head->dev_type == DVT_LOOP) &&
(DEV_Table.dv_head->dev_next != NU_NULL) )
search_addr = DEV_Table.dv_head->dev_next->dev_addr.dev_net;
else
search_addr = DEV_Table.dv_head->dev_addr.dev_net;
}
/* Free the cached route. The default IF for sending a
bcast packet may have change. */
if (ro->rt_route)
{
RTAB_Free(ro->rt_route);
ro->rt_route = NU_NULL;
}
}
/* If this is a multicast address then check for a default route. */
else if (IP_MULTICAST_ADDR(search_addr))
{
/* default mcast route? */
if ( (uprt->up_socketd >= 0) &&
(SCK_Sockets[uprt->up_socketd]->s_moptions) &&
(SCK_Sockets[uprt->up_socketd]->s_moptions->ipo_device) )
{
/* Set the search addr */
search_addr = SCK_Sockets[uprt->up_socketd]->
s_moptions->ipo_device->dev_addr.dev_net;
/* Is there a cached route? */
if (ro->rt_route)
{
/* Check the IF used by the cached route. If it is different
than the set default IF free it so a new route can be found. */
if (SCK_Sockets[uprt->up_socketd]->s_moptions->ipo_device !=
ro->rt_route->rt_device)
{
RTAB_Free(ro->rt_route);
ro->rt_route = NU_NULL;
}
}
}
}
/* 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 no route was found and this is a multicast address then
just use the primary interface. */
if ( (!ro->rt_route) && (IP_MULTICAST_ADDR(search_addr)) )
{
if ( (DEV_Table.dv_head->dev_type == DVT_LOOP) &&
(DEV_Table.dv_head->dev_next != NU_NULL) )
ro->rt_ip_dest.sck_addr = DEV_Table.dv_head->dev_next->dev_addr.
dev_net_brdcast;
else
ro->rt_ip_dest.sck_addr = DEV_Table.dv_head->dev_addr.
dev_net_brdcast;
IP_Find_Route(ro);
}
/* If it was the limited broadcast address (255.255.255.255) or a
multicast address 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);
} /* UDP_Cache_Route */
/*************************************************************************
*
* FUNCTION
*
* UDP_Port_Cleanup
*
* DESCRIPTION
*
* This function frees any resources associate with a UDP port when
* that port is closed.
*
* INPUTS
*
* uport_index The index of the port that is closing.
*
* OUTPUTS
*
* NU_SUCCESS
*
*************************************************************************/
STATUS UDP_Port_Cleanup(INT uport_index)
{
/* Clear this port list entry. */
NU_Deallocate_Memory((VOID *) UDP_Ports[uport_index]);
/* Indicate that this port is no longer used. */
UDP_Ports[uport_index] = NU_NULL;
return (NU_SUCCESS);
} /* UDP_Port_Cleanup */
/*************************************************************************
*
* FUNCTION
*
* UDP_Make_Port
*
* DESCRIPTION
*
* This is the intialization for UDP based communication. When a
* port needs to be created, this routine is called to do as much
* pre-initialization as possible to save overhead during operation.
*
* This structure is created upon open of a port, either listening
* or wanting to send.
*
* INPUTS
*
* myport
* socketd
*
* OUTPUTS
*
* INT16
*
*************************************************************************/
INT16 UDP_Make_Port (UINT16 myport, INT socketd)
{
INT16 i, retval;
UDP_PORT *p;
STATUS status;
VOID *return_ptr; /* pointer to memory block */
#if (INCLUDE_SNMP == NU_TRUE)
struct sock_struct *sockptr;
sockptr = SCK_Sockets[socketd];
#endif
/* Check to see if there are any available ports. */
for ( i = 0; (UDP_Ports[i] != NU_NULL) && (i < UDP_MAX_PORTS); i++);
/* If an unused UDP port was not found return an error. */
if (i >= UDP_MAX_PORTS)
{
NERRS_Log_Error ( NERR_RECOVERABLE, __FILE__, __LINE__);
retval = -1;
}
else
{
status = NU_Allocate_Memory(&System_Memory, (VOID **) &return_ptr,
(UNSIGNED)sizeof(struct uport),
(UNSIGNED)NU_NO_SUSPEND);
/* check status of memory allocation */
if (status == NU_SUCCESS)
{
return_ptr = (UINT16 *)TLS_Normalize_Ptr(return_ptr);
p = (UDP_PORT *)return_ptr;
}
else
{
/* ERROR memory allocation error. */
NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);
return (-1); /* out of room for ports */
} /* end if */
UDP_Ports[i] = p;
retval = i;
/* Clear the UDP port structure. */
UTL_Zero((CHAR *)p, sizeof(*p));
/* If my port number has not been specified then find a unique one
for me. */
if (myport == 0)
/* Build a local port number. Needs to be unique and greater than
2048. */
myport = UTL_Get_Unique_Port_Number();
p->up_lport = myport; /* save for incoming comparison */
/* The socket with which this port is associated is unkown at this time. */
p->up_socketd = socketd;
p->up_route.rt_route = NU_NULL;
#if (INCLUDE_SNMP == NU_TRUE)
/* Update the UDP Listen Table. */
SNMP_udpListenTableUpdate(SNMP_ADD, sockptr->s_local_addr.ip_num.is_ip_addrs,
(UNSIGNED)myport);
#endif
}
return (retval);
} /* end UDP_Make_Port() */
#endif /* INCLUDE_UDP == NU_TRUE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -