📄 sockets.c
字号:
NU_NULL, pointer, (UNSIGNED)5000, TM_PRIORITY,
(UNSIGNED)0, NU_PREEMPT, NU_START);
if (status != NU_SUCCESS)
{
/* Switch back to user mode. */
NU_USER_MODE();
return(NU_INVAL);
}
#if (NET_VERSION_COMP >= NET_4_2)
/* Initialize the pointer to the non-cached memory pointer. */
MEM_Non_Cached = mem_pool;
#else
/* Versions of NET prior to NET 4.2 did not make use of a non-cached
memory pool. So just use the System_Memory pool for all memory
allocations. */
MEM_Non_Cached = &System_Memory;
#endif
DEV_Table.dv_head = NU_NULL;
DEV_Table.dv_tail = NU_NULL;
/* Initialize the protocols of the NET stack. */
status = PROT_Net_Init();
//#if 0 // mask the loopback device **********************************************************************************************************************************
#if (INCLUDE_LOOPBACK_DEVICE == NU_TRUE)
/* Did we successfully init the stack? */
if (status == NU_SUCCESS)
{
/* Now that the stack is completely intialized setup the
loopback device. */
loopback_device.dv_name = loopback_device_name;
loopback_device.dv_flags = DV_NOARP;
loopback_device.dv_driver_options = NU_NULL;
loopback_device.dv_init = LDC_Init;
loopback_device.dv_ip_addr[0] = 127;
loopback_device.dv_ip_addr[1] = 0;
loopback_device.dv_ip_addr[2] = 0;
loopback_device.dv_ip_addr[3] = 1;
loopback_device.dv_subnet_mask[0] = 255;
loopback_device.dv_subnet_mask[1] = 000;
loopback_device.dv_subnet_mask[2] = 000;
loopback_device.dv_subnet_mask[3] = 000;
*(UINT32 *)loopback_device.dv_gw = 0x00000000;
loopback_device.dv_hw.ether.dv_irq = NU_NULL;
loopback_device.dv_hw.ether.dv_io_addr = NU_NULL;
loopback_device.dv_hw.ether.dv_shared_addr = NU_NULL;
/* Add the device to the system. */
status = DEV_Init_Devices (&loopback_device, 1);
/* If the device was attached. */
if (status == NU_SUCCESS)
{
/* Now add an ARP entry for this device. This will
be a permanent entry since there is no need to ARP
a loopback device. About the MAC address used: since
what the MAC address is is not important just */
ARP_Cache_Update (IP_ADDR (loopback_device.dv_ip_addr),
(UINT8 *)"\0\0\0\0\0\0",
ARP_PERMANENT);
}
}
#endif //**********************************************************************************************************************************************************************
//#endif
/* Switch back to user mode. */
NU_USER_MODE();
return(status);
} /* NU_Init_Net */
/*************************************************************************
*
* FUNCTION
*
* NU_Socket
*
* DESCRIPTION
*
* This function is responsible for establishing a new socket
* descriptor and defining the type of communication protocol to
* be established. Must be called by both clien and server whether
* connection-oriented or connectionless transfer is established.
*
* INPUTS
*
* family
* type
* protocol
*
* OUTPUTS
*
* NU_SUCCESS
* NU_INVALID_PROTOCOL
* NU_NO_SOCKET_SPACE
* NU_NO_SOCK_MEMORY
*
*************************************************************************/
STATUS NU_Socket (INT16 family, INT16 type, INT16 protocol)
{
STATUS return_status;
NU_SUPERV_USER_VARIABLES
/* possible protocols based on [FAMILY, TYPE] */
INT NU_proto_list[][5] =
{
{NU_PROTO_INVALID, NU_PROTO_INVALID, NU_PROTO_INVALID,
NU_PROTO_INVALID, NU_PROTO_INVALID},
{NU_PROTO_INVALID, NU_PROTO_INVALID, NU_PROTO_INVALID,
NU_PROTO_INVALID, NU_PROTO_INVALID},
{NU_PROTO_TCP, NU_PROTO_UDP, NU_PROTO_ICMP,
NU_PROTO_INVALID, NU_PROTO_INVALID}
};
/* Make sure that family and type are in range. */
if (family < 0 || family > 2 || type < 0 || type > 4)
return (NU_INVALID_PROTOCOL);
/* verify that we support the programmer's choice */
if(!NU_proto_list[family][type])
return(NU_INVALID_PROTOCOL);
/* Switch to supervisor mode. */
NU_SUPERVISOR_MODE();
/* Clean up warnings. This parameter is required for socket compatibility
but we are currently not making any use of it. */
UNUSED_PARAMETER(protocol);
/* Don't let any other users in until we are done. */
NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
/* Create a new socket. */
#if INCLUDE_IP_RAW
if (type == NU_TYPE_RAW)
{
/* Could be many protocols with a Raw socket, so must use */
/* the protocol entered */
return_status = SCK_Create_Socket(protocol);
}
else
#endif
{
return_status = SCK_Create_Socket(NU_proto_list[family][type]);
}
NU_Release_Semaphore(&TCP_Resource);
/* Switch back to user mode. */
NU_USER_MODE();
/* return a SCK_Sockets index or an error status to caller */
return (return_status);
} /* NU_Socket */
/************************************************************************
*
* FUNCTION
*
* SCK_Create_Socket
*
* DESCRIPTION
*
* This function creates a new socket.
*
* INPUTS
*
* protocol
*
* OUTPUTS
*
* A socket descriptor is returned on success.
* NU_NO_SOCKET_SPACE
* NU_NO_SOCK_MEMORY
*
*************************************************************************/
INT SCK_Create_Socket(INT protocol)
{
struct sock_struct *sockptr; /* pointer to current socket */
STATUS status;
INT return_status = NU_NO_SOCKET_SPACE; /* initialized to error status */
INT counter; /* to traverse the socket list */
/* search the socket list to be sure there is room for another connection */
for (counter = 0; counter < NSOCKETS; counter++)
{
if (SCK_Sockets[next_socket_no] == NU_NULL)
{
/* allocate a socket structure */
status = NU_Allocate_Memory(&System_Memory, (VOID **) &sockptr,
(UNSIGNED)sizeof(struct sock_struct),
(UNSIGNED)NU_NO_SUSPEND);
if (status == NU_SUCCESS)
{
sockptr = (struct sock_struct *)TLS_Normalize_Ptr(sockptr);
SCK_Sockets[next_socket_no] = sockptr;
/* Zero out the socket structure */
UTL_Zero(sockptr, sizeof(struct sock_struct));
/* fill only the protocol portion of the socket structure */
sockptr->s_protocol = (UINT16)protocol;
/* Set the intial state to connecting. */
sockptr->s_state = SS_ISCONNECTING;
/* Initialize the socket options. The abiltiy to transmit
broadcast messages is enabled by default. */
sockptr->s_options = SO_BROADCAST;
/* Clear the flags field. The default for UDP is blocking.
This is done for backwards compatability. */
if (protocol == NU_PROTO_UDP)
sockptr->s_flags = SF_BLOCK;
else
sockptr->s_flags = 0;
/* Initially there is no multicast option data. */
sockptr->s_moptions = NU_NULL;
/* No port is yet associated with this socket. */
sockptr->s_port_index = -1;
/* return the SCK_Sockets index */
return_status = next_socket_no;
next_socket_no++;
if (next_socket_no >= NSOCKETS)
next_socket_no = 0;
} /* end status == NU_SUCCESS */
else
{
NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);
/* Tell the user there is no memory. */
return_status = NU_NO_SOCK_MEMORY;
} /* end status != NU_SUCCESS */
/* discontinue after we find an empty space in the socket list */
break;
} /* end SCK_Sockets slot is null */
next_socket_no++;
if (next_socket_no >= NSOCKETS)
next_socket_no = 0;
}
return (return_status);
} /* end SCK_Create_Socket */
/*************************************************************************
*
* FUNCTION
*
* NU_Bind
*
* DESCRIPTION
*
* This function is responsible for assigning a local address
* to a socket.
*
* INPUTS
*
* socketd
* *myaddr
* addrlen
*
* OUTPUTS
*
* Socket descriptor on success.
* NU_INVALID_SOCKET
* NU_INVALID_PARM
* NU_INVALID_ADDRESS
*
*************************************************************************/
STATUS NU_Bind(INT socketd, struct addr_struct *myaddr, INT16 addrlen)
{
NU_SUPERV_USER_VARIABLES
/* Validate the socket number. */
if ((socketd < 0) || (socketd >= NSOCKETS) ||
(SCK_Sockets[socketd] == NU_NULL))
return(NU_INVALID_SOCKET);
/* Validate the address structure pointer. */
if (myaddr == NU_NULL)
return (NU_INVALID_PARM);
/* Switch to supervisor mode. */
NU_SUPERVISOR_MODE();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -