uint32_t SOL_TCP_setsockopt ( uint32_t sock, /* [IN] socket handle */ uint32_t level, /* [IN] protocol level for the option */ uint32_t optname, /* [IN] name of the option */ void *optval, /* [IN] new value for the option */ uint32_t optlen /* [IN] length of the option value, in bytes */ ) { /* Body */ register SOCKET_STRUCT_PTR socket_ptr = (SOCKET_STRUCT_PTR)sock; RTCS_ENTER(SETSOCKOPT, sock); #if RTCSCFG_CHECK_ERRORS if (sock == 0 || sock == RTCS_SOCKET_ERROR) { RTCS_EXIT(SETSOCKOPT, RTCSERR_SOCK_INVALID); } /* Endif */ #endif ((uint32_t *)&socket_ptr->CONNECT_TIMEOUT)[optname-1] = *(uint32_t *)optval; RTCS_EXIT(SETSOCKOPT, RTCS_OK); } /* Endbody */
/*FUNCTION*------------------------------------------------------------- ************************************************************************ * * Function Name : SOCK_DGRAM_bind * Returned Value : error code * * Comments : Binds the local endpoint of a socket. Support IPv6 and IPv4 * ************************************************************************ *END*-----------------------------------------------------------------*/ uint32_t SOCK_DGRAM_bind ( uint32_t sock, /* [IN] socket handle */ const sockaddr *localaddr, /* [IN] local address to which to bind the socket */ uint16_t addrlen /* [IN] length of the address, in bytes */ ) { /* Body */ UDP_PARM parms; uint32_t error; RTCS_ENTER(BIND, sock); error = SOCK_check_valid(sock, localaddr); if (error) { RTCS_EXIT(BIND, error); } error = SOCK_check_addr(localaddr, addrlen); if (error) { RTCS_EXIT(BIND, error); } parms.ucb = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR; parms.udpword = sock; parms.af = localaddr->sa_family; if (localaddr->sa_family == AF_INET) { #if RTCSCFG_ENABLE_IP4 parms.udpport =((sockaddr_in *)localaddr)->sin_port; parms.udpservice = UDP_process; parms.ipaddress =((sockaddr_in *)localaddr)->sin_addr.s_addr; error = RTCSCMD_issue(parms, UDP_bind); #endif } else if (localaddr->sa_family == AF_INET6) { #if RTCSCFG_ENABLE_IP6 parms.udpport = ((sockaddr_in6 *)localaddr)->sin6_port; parms.udpservice = UDP_process6; IN6_ADDR_COPY(&(((sockaddr_in6 *)localaddr)->sin6_addr), &(parms.ipv6address)); parms.if_scope_id = ((sockaddr_in6 *)localaddr)->sin6_scope_id; error = RTCSCMD_issue(parms, UDP_bind6); #endif } if (error) { RTCS_EXIT(BIND, error); } ((SOCKET_STRUCT_PTR)sock)->STATE = SOCKSTATE_DGRAM_BOUND; RTCS_EXIT(BIND, RTCS_OK); } /* Endbody */
/** * @brief Receive data from a datagram socket. * * Provides RTCS with the buffer in which to place data that is incoming on the datagram * socket. Supports IPv6 and IPv4 family. * If a remote endpoint has been specified with connect(), only datagrams from that source * will be received. * When the flags parameter is RTCS_MSG_PEEK, the same datagram is received the next time recv() or * recvfrom() is called. * If addrlen is NULL, the socket address is not written to sourceaddr. If sourceaddr is NULL and the value of * addrlen is not NULL, the result is unspecified. * If the function returns RTCS_ERROR, the application can call RTCS_geterror() to determine the reason * for the error. * This function blocks (unles nonblocking option has been set for the socket) until data is available * or an error or a timeout occurs. * * * @param sock [IN] socket handle. * @param buffer [IN] pointer to a buffer for received data. * @param buflen [IN] size of the buffer in bytes. * @param flags [IN] flags to underlying protocols. One of the following: * RTCS_MSG_PEEK - receives a datagram bug does not consume it. * Zero - ignore. * @param sourceaddr [IN/OUT] * @param addrlen [IN/OUT] * @return number of bytes received (success) * RTCS_ERROR (failure). * @see SOCK_DGRAM_bind * @see RTCS_geterror * @see SOCK_DGRAM_sendto * @code * uint32_t handle; * sockaddr_in remote_sin; * uint32_t count; * char my_buffer[500]; * uint16_t remote_len = sizeof(remote_sin); * ... * count = recvfrom(handle, my_buffer, sizeof(my_buffer), 0, (struct sockaddr *) &remote_sin, &remote_len); * if (count == RTCS_ERROR) * { * printf(“\nrecvfrom() failed with error %lx”, * RTCS_geterror(handle)); * } else { * printf(“\nReceived %ld bytes of data.”, count); * } * @endcode */ static int32_t SOCK_DGRAM_recvfrom ( uint32_t sock, /* [IN] socket handle */ void *buffer, /* [IN] buffer for received data */ uint32_t buflen, /* [IN] length of the buffer, in bytes */ uint32_t flags, /* [IN] flags to underlying protocols */ struct sockaddr *sourceaddr, /* [OUT] address from which data was received */ uint16_t *addrlen /* [IN/OUT] length of the address, in bytes */ ) { UDP_PARM parms = {0}; uint32_t error; struct sockaddr addr_from = {0}; SOCKET_STRUCT_PTR sock_struct_ptr = (SOCKET_STRUCT_PTR)sock; RTCS_ENTER(RECVFROM, sock); if(sock_struct_ptr->STATE == SOCKSTATE_DGRAM_GROUND) { RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_BOUND); RTCS_EXIT2(RECVFROM, RTCSERR_SOCK_NOT_BOUND, RTCS_ERROR); } parms.ucb = sock_struct_ptr->UCB_PTR; parms.udpptr = buffer; parms.udpword = buflen; parms.udpflags = flags; if(addrlen) { /* if addrlen pointer is NULL, nothing is to be written to sourceaddr. parms.saddr_ptr is NULL by default. * if addrlen is a non NULL pointer, UDP code will indicate the remote peer address via *saddr_ptr */ parms.saddr_ptr = &addr_from; } error = RTCSCMD_issue(parms, UDP_receive); if(error) { RTCS_setsockerror(sock, error); RTCS_EXIT2(RECVFROM, error, RTCS_ERROR); } /* write the address from which data was received */ SOCKADDR_return_addr(sock_struct_ptr, sourceaddr, &addr_from, addrlen); RTCS_EXIT2(RECVFROM, RTCS_OK, parms.udpword); }
uint_32 SOL_IP_setsockopt ( uint_32 sock, /* [IN] socket handle */ uint_32 level, /* [IN] protocol level for the option */ uint_32 optname, /* [IN] name of the option */ pointer optval, /* [IN] new value for the option */ uint_32 optlen /* [IN] length of the option value, in bytes */ ) { /* Body */ /* Start CR 1146 */ register SOCKET_STRUCT_PTR socket_ptr = (SOCKET_STRUCT_PTR)sock; uint_32 error; RTCS_ENTER(SETSOCKOPT, sock); #if RTCSCFG_CHECK_ERRORS if (sock == 0 || sock == RTCS_SOCKET_ERROR) { RTCS_EXIT(SETSOCKOPT, RTCSERR_SOCK_INVALID); } /* Endif */ #endif switch (optname) { case RTCS_SO_IP_TX_TTL: if (!optlen) { error = RTCSERR_SOCK_SHORT_OPTION; } else { socket_ptr->LINK_OPTIONS.TX.TTL = *(uchar_ptr)optval; /* Propogate the option to the TCB */ if (socket_ptr->TCB_PTR != NULL) { socket_ptr->TCB_PTR->TX.TTL = socket_ptr->LINK_OPTIONS.TX.TTL; } error = RTCS_OK; } /* Endif */ break; default: error = RTCSERR_SOCK_INVALID_OPTION; } /* Endswitch */ /* End CR 1146 */ RTCS_EXIT(SETSOCKOPT, error); } /* Endbody */
static int32_t SOCK_DGRAM_recv ( uint32_t sock, /* [IN] socket handle */ void *buffer, /* [IN] buffer for received data */ uint32_t buflen, /* [IN] length of the buffer, in bytes */ uint32_t flags /* [IN] flags to underlying protocols */ ) { int32_t len; RTCS_ENTER(RECV, sock); len = SOCK_DGRAM_recvfrom(sock, buffer, buflen, flags, NULL, NULL); RTCS_EXIT2(RECV, (len < 0) ? RTCS_ERROR : RTCS_OK, len); }
static int32_t SOCK_DGRAM_send ( uint32_t sock, /* [IN] socket handle */ void *buffer, /* [IN] data to transmit */ uint32_t buflen, /* [IN] length of the buffer, in bytes */ uint32_t flags /* [IN] flags to underlying protocols */ ) { int32_t len= -1 ; // it will generate error if AF != AF_INET or AF_INET6 RTCS_ENTER(SEND, sock); len = SOCK_DGRAM_sendto(sock, buffer, buflen, flags, NULL, 0); RTCS_EXIT2(SEND, (len < 0) ? RTCS_ERROR : RTCS_OK, len); }
/*FUNCTION*------------------------------------------------------------- * * Function Name : SOCK_DGRAM_getpeername * Returned Value : error code * Comments : Retrieve the address of the peer endpoint of a * connected socket. * *END*-----------------------------------------------------------------*/ static uint32_t SOCK_DGRAM_getpeername ( uint32_t sock, /* [IN] socket handle */ sockaddr *name, /* [OUT] address of peer endpoint */ uint16_t *namelen /* [IN/OUT] length of the address, in bytes */ ) { SOCKET_STRUCT_PTR sock_struct_ptr = (SOCKET_STRUCT_PTR)sock; RTCS_ENTER(GETPEERNAME, sock); if(sock_struct_ptr->STATE != SOCKSTATE_DGRAM_OPEN) { RTCS_EXIT(GETPEERNAME, RTCSERR_SOCK_NOT_CONNECTED); } SOCKADDR_return_addr(sock_struct_ptr, name, &sock_struct_ptr->UCB_PTR->RADDR, namelen); RTCS_EXIT(GETPEERNAME, RTCS_OK); }
/** * @brief Retrieve the address of the local endpoint of a bound socket. * * Retrieve the address of the local endpoint of a bound socket. Support IPv6 and IPv4. * The funciton blocks but the command is immediately serviced and replied to. * This function is called by getsockname(), if sock type is a datagram socket. * * @param sock [IN] socket handle * @param name [OUT] pointer to struct sockaddr, where the address of a local endpoint * will be written to. * @param namelen [IN/OUT] pointer to length of the address, in bytes. On input, the length determines the size of sockaddr structure. On output, the length indicates number of bytes that have been written to name. * * @return RTCS_OK (success) * specific error code (failure). * @see SOCK_DGRAM_bind * @see SOCK_DGRAM_getpeername * @see SOCK_DGRAM_socket * @code * uint32_t handle; * sockaddr_in local_sin; * uint32_t status; * uint16_t namelen; * ... * namelen = sizeof (sockaddr_in); * status = getsockname(handle, (struct sockaddr *)&local_sin, &namelen); * if (status != RTCS_OK) * { * printf(“\nError, getsockname() failed with error code %lx”, status); * } else { * printf(“\nLocal address family is %x”, local_sin.sin_family); * printf(“\nLocal port is %d”, local_sin.sin_port); * printf(“\nLocal IP address is %lx”, local_sin.sin_addr.s_addr); * } * @endcode */ static uint32_t SOCK_DGRAM_getsockname ( uint32_t sock, /* [IN] socket handle */ sockaddr *name, /* [OUT] address of local endpoint */ uint16_t *namelen /* [IN/OUT] length of the address, in bytes */ ) { SOCKET_STRUCT_PTR sock_struct_ptr = (SOCKET_STRUCT_PTR)sock; RTCS_ENTER(GETSOCKNAME, sock); if(sock_struct_ptr->STATE == SOCKSTATE_DGRAM_GROUND) { RTCS_EXIT(GETSOCKNAME, RTCSERR_SOCK_NOT_BOUND); } SOCKADDR_return_addr(sock_struct_ptr, name, &sock_struct_ptr->UCB_PTR->LADDR, namelen); RTCS_EXIT(GETSOCKNAME, RTCS_OK); }
uint32_t SOCK_DGRAM_shutdown ( uint32_t sock, /* [IN] socket handle */ uint32_t how /* [IN] how to terminate the socket */ ) { /* Body */ UDP_PARM parms; uint32_t error; RTCS_ENTER(SHUTDOWN, sock); parms.ucb = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR; error = RTCSCMD_issue(parms, UDP_close); if (error) { RTCS_EXIT(SHUTDOWN, error); } /* Endif */ RTCS_EXIT(SHUTDOWN, RTCS_OK); } /* Endbody */
/*FUNCTION*------------------------------------------------------------- ************************************************************************ * * Function Name : SOCK_DGRAM_bind * Returned Value : error code * * Comments : Binds the local endpoint of a socket. Supports IPv6 and IPv4 * ************************************************************************ *END*-----------------------------------------------------------------*/ static uint32_t SOCK_DGRAM_bind ( uint32_t sock, /* [IN] socket handle */ const sockaddr *localaddr, /* [IN] local address to which to bind the socket */ uint16_t addrlen /* [IN] length of the address, in bytes */ ) { UDP_PARM parms; uint32_t error; sockaddr laddr = {0}; SOCKET_STRUCT_PTR sock_struct_ptr = (SOCKET_STRUCT_PTR)sock; RTCS_ENTER(BIND, sock); if(sock_struct_ptr->STATE != SOCKSTATE_DGRAM_GROUND) { RTCS_EXIT(BIND, RTCSERR_SOCK_IS_BOUND); } parms.ucb = sock_struct_ptr->UCB_PTR; SOCKADDR_copy(localaddr, &laddr); /* from->to */ parms.saddr_ptr = &laddr; parms.udpservice = UDP_process; error = RTCSCMD_issue(parms, UDP_bind); if(error) { RTCS_EXIT(BIND, error); } sock_struct_ptr->STATE = SOCKSTATE_DGRAM_BOUND; RTCS_EXIT(BIND, RTCS_OK); }
/*FUNCTION*------------------------------------------------------------- * * Function Name : SOCK_DGRAM_recvfrom * Returned Value : number of bytes received or RTCS_ERROR * Comments : Receive data from a socket for IPv6 and IPv4 family. * *END*-----------------------------------------------------------------*/ int32_t SOCK_DGRAM_recvfrom ( uint32_t sock, /* [IN] socket handle */ void *buffer, /* [IN] buffer for received data */ uint32_t buflen, /* [IN] length of the buffer, in bytes */ uint32_t flags, /* [IN] flags to underlying protocols */ /*sockaddr_in6 *sourceaddr,*/ struct sockaddr *sourceaddr, /* [OUT] address from which data was received */ uint16_t *addrlen /* [IN/OUT] length of the address, in bytes */ ) { /* Body */ UDP_PARM parms = {0}; uint32_t error; RTCS_ENTER(RECVFROM, sock); #if RTCSCFG_CHECK_ERRORS if (((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_DGRAM_GROUND) { RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_BOUND); RTCS_EXIT2(RECVFROM, RTCSERR_SOCK_NOT_BOUND, RTCS_ERROR); } /* Endif */ #endif parms.ucb = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR; parms.udpptr = buffer; parms.udpword = buflen; parms.udpflags = flags; #if RTCSCFG_ENABLE_IP4 #if RTCSCFG_ENABLE_IP6 if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) { #endif error = RTCSCMD_issue(parms, UDP_receive); if (error) { RTCS_setsockerror(sock, error); RTCS_EXIT2(RECVFROM, error, RTCS_ERROR); } /* Endif */ if (!addrlen) { #if RTCSCFG_CHECK_ADDRSIZE } else if (*addrlen < sizeof(sockaddr_in)) { sockaddr_in fullname; fullname.sin_family = AF_INET; fullname.sin_port = parms.udpport; fullname.sin_addr.s_addr = parms.ipaddress; _mem_copy(&fullname, sourceaddr, *addrlen); *addrlen = sizeof(sockaddr_in); #endif } else { ((sockaddr_in *)sourceaddr)->sin_family = AF_INET; ((sockaddr_in *)sourceaddr)->sin_port = parms.udpport; ((sockaddr_in *)sourceaddr)->sin_addr.s_addr = parms.ipaddress; *addrlen = sizeof(sockaddr_in); } /* Endif */ #if RTCSCFG_ENABLE_IP6 } #endif #endif #if RTCSCFG_ENABLE_IP6 #if RTCSCFG_ENABLE_IP4 else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) { #endif error = RTCSCMD_issue(parms, UDP_receive6); if (error) { RTCS_setsockerror(sock, error); RTCS_EXIT2(RECVFROM, error, RTCS_ERROR); } /* Endif */ /* copy addr structure to output */ if(!addrlen)//if parameter of addrlen is not NULL { #if RTCSCFG_CHECK_ADDRSIZE } else if (*addrlen < sizeof(struct sockaddr_in6)) { struct sockaddr_in6 fullname; fullname.sin6_family = AF_INET6; fullname.sin6_port = parms.udpport; fullname.sin6_scope_id = parms.if_scope_id; IN6_ADDR_COPY(&(parms.ipv6address),&(fullname.sin6_addr)); /*do safe mem copy to avoid overflow*/ _mem_copy(&fullname, sourceaddr, *addrlen); /*return real value of size of addr structure*/ *addrlen = sizeof(struct sockaddr_in6); #endif } else { ((sockaddr_in6 *)sourceaddr)->sin6_family = AF_INET6; ((sockaddr_in6 *)sourceaddr)->sin6_port = parms.udpport; ((sockaddr_in6 *)sourceaddr)->sin6_scope_id = parms.if_scope_id; IN6_ADDR_COPY(&(parms.ipv6address),&(((sockaddr_in6 *)sourceaddr)->sin6_addr)); *addrlen = sizeof(struct sockaddr_in6); } #if RTCSCFG_ENABLE_IP4 } #endif #endif RTCS_EXIT2(RECVFROM, RTCS_OK, parms.udpword); } /* Endbody */
int32_t SOCK_DGRAM_sendto ( uint32_t sock, /* [IN] socket handle */ void *send_buffer, /* [IN] data to transmit */ uint32_t buflen, /* [IN] length of the buffer, in bytes */ uint32_t flags, /* [IN] flags to underlying protocols */ sockaddr *destaddr, /* [IN] address to which to send data */ uint16_t addrlen /* [IN] length of the address, in bytes */ ) { /* Body */ UDP_PARM parms = {0}; uint32_t error = 0; sockaddr addr = {0}; uint16_t len = sizeof(addr); RTCS_ENTER(SENDTO, sock); #if RTCSCFG_CHECK_ADDRSIZE #if RTCSCFG_ENABLE_IP4 #if RTCSCFG_ENABLE_IP6 if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) { #endif if(destaddr && addrlen < sizeof(sockaddr_in)) { RTCS_setsockerror(sock, RTCSERR_SOCK_SHORT_ADDRESS); RTCS_EXIT2(SENDTO, RTCSERR_SOCK_SHORT_ADDRESS, RTCS_ERROR); } /* Endif */ #if RTCSCFG_ENABLE_IP6 } #endif #endif #if RTCSCFG_ENABLE_IP6 #if RTCSCFG_ENABLE_IP4 else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) { #endif if(destaddr && addrlen < sizeof(sockaddr_in6)) { RTCS_setsockerror(sock, RTCSERR_SOCK_SHORT_ADDRESS); RTCS_EXIT2(SENDTO, RTCSERR_SOCK_SHORT_ADDRESS, RTCS_ERROR); } /* Endif */ #if RTCSCFG_ENABLE_IP4 } #endif #endif #endif if(!destaddr) { error = SOCK_DGRAM_getpeername(sock, &addr, &len); if(error) { RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_CONNECTED); RTCS_EXIT2(SENDTO, RTCSERR_SOCK_NOT_CONNECTED, RTCS_ERROR); } /* Endif */ } else { _mem_copy(destaddr, &addr, sizeof(addr)); } /* Endif */ #if RTCSCFG_ENABLE_IP4 #if RTCSCFG_ENABLE_IP6 if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) { #endif if(((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_DGRAM_GROUND) { sockaddr_in localaddr = {0}; localaddr.sin_family = AF_INET; localaddr.sin_port = 0; localaddr.sin_addr.s_addr = INADDR_ANY; error = SOCK_DGRAM_bind(sock,(sockaddr *)&localaddr, sizeof(localaddr)); if(error) { RTCS_setsockerror(sock, error); RTCS_EXIT2(SENDTO, error, RTCS_ERROR); } /* Endif */ } /* Endif */ parms.ipaddress = ((sockaddr_in *)&addr)->sin_addr.s_addr; parms.udpport = ((sockaddr_in *)&addr)->sin_port; #if RTCSCFG_ENABLE_IP6 } #endif #endif #if RTCSCFG_ENABLE_IP6 #if RTCSCFG_ENABLE_IP4 else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) { #endif if(((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_DGRAM_GROUND) { struct sockaddr_in6 localaddr = {0}; localaddr.sin6_family = AF_INET6; localaddr.sin6_port = 0; IN6_ADDR_COPY((in6_addr*)(&(in6addr_any)),&(localaddr.sin6_addr)); error = SOCK_DGRAM_bind(sock, (sockaddr *)&localaddr, sizeof(localaddr)); if (error) { RTCS_setsockerror(sock, error); RTCS_EXIT2(SENDTO, error, RTCS_ERROR); } /* Endif */ } /* Endif */ IN6_ADDR_COPY(&(((sockaddr_in6 *)&addr)->sin6_addr),&(parms.ipv6address)); parms.udpport = ((sockaddr_in6 *)&addr)->sin6_port; parms.if_scope_id =((sockaddr_in6 *)&addr)->sin6_scope_id; #if RTCSCFG_ENABLE_IP4 } #endif #endif parms.ucb = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR; parms.udpptr = send_buffer; parms.udpword = buflen; parms.udpflags = flags; error = RTCSCMD_issue(parms, UDP_send); if(error) { RTCS_setsockerror(sock, error); RTCS_EXIT2(SENDTO, error, RTCS_ERROR); } /* Endif */ RTCS_EXIT2(SENDTO, RTCS_OK, buflen); } /* Endbody */
uint32_t SOCK_DGRAM_getpeername ( uint32_t sock, /* [IN] socket handle */ sockaddr *name, /* [OUT] address of peer endpoint */ uint16_t *namelen /* [IN/OUT] length of the address, in bytes */ ) { /* Body */ RTCS_ENTER(GETPEERNAME, sock); #if RTCSCFG_CHECK_ERRORS if (((SOCKET_STRUCT_PTR)sock)->STATE != SOCKSTATE_DGRAM_OPEN) { RTCS_EXIT(GETPEERNAME, RTCSERR_SOCK_NOT_CONNECTED); } /* Endif */ #endif #if RTCSCFG_ENABLE_IP4 #if RTCSCFG_ENABLE_IP6 if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) { #endif if (!namelen) { #if RTCSCFG_CHECK_ADDRSIZE } else if (*namelen < sizeof(sockaddr_in)) { sockaddr_in fullname; fullname.sin_family = AF_INET; fullname.sin_port = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_PORT; fullname.sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_HOST; _mem_copy(&fullname, name, *namelen); #endif } else { ((sockaddr_in *)name)->sin_family = AF_INET; ((sockaddr_in *)name)->sin_port = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_PORT; ((sockaddr_in *)name)->sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_HOST; *namelen = sizeof(sockaddr_in); } /* Endif */ #if RTCSCFG_ENABLE_IP6 } #endif #endif #if RTCSCFG_ENABLE_IP6 #if RTCSCFG_ENABLE_IP4 else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) { #endif if(!namelen) { #if RTCSCFG_CHECK_ADDRSIZE } else if (*namelen < sizeof(struct sockaddr_in6)) { struct sockaddr_in6 fullname; fullname.sin6_family = AF_INET6; fullname.sin6_port = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_PORT; IN6_ADDR_COPY(&((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_HOST6,&(fullname.sin6_addr)); _mem_copy(&fullname,name, *namelen); #endif } else { ((sockaddr_in6 *)name)->sin6_family = AF_INET6; ((sockaddr_in6 *)name)->sin6_port = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_PORT; IN6_ADDR_COPY(&((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_HOST6,&(((sockaddr_in6 *)name)->sin6_addr)); *namelen = sizeof(sockaddr_in); } /* Endif */ #if RTCSCFG_ENABLE_IP4 } #endif #endif RTCS_EXIT(GETPEERNAME, RTCS_OK); } /* Endbody */
/*FUNCTION*------------------------------------------------------------- ************************************************************************ * * Function Name : SOCK_DGRAM_connect * Returned Value : error code * Comments : Binds the remote endpoint of a socket. Support IPv6 and IPv4. * * 1. If connect succeeds the socket is in OPEN state. * 2. If connect fails, the socket is in BOUND or GROUND state, and the * local IP is the same as it was immediatly after the bind() call. * *********************************************************************** *END*-----------------------------------------------------------------*/ uint32_t SOCK_DGRAM_connect ( uint32_t sock, /* [IN] socket handle */ const struct sockaddr *peeraddr, /* [IN] remote address to which to bind the socket */ uint16_t addrlen /* [IN] length of the address, in bytes */ ) { /* Body */ UDP_PARM parms; uint32_t error = RTCS_OK; uint16_t state = ((SOCKET_STRUCT_PTR)sock)->STATE; RTCS_ENTER(CONNECT, sock); #if RTCSCFG_CHECK_ADDRSIZE #if RTCSCFG_ENABLE_IP4 #if RTCSCFG_ENABLE_IP6 if (peeraddr->sa_family == AF_INET) { #endif if (addrlen < sizeof(sockaddr_in)) { error = RTCSERR_SOCK_SHORT_ADDRESS; } /* Endif */ #if RTCSCFG_ENABLE_IP6 } #endif #endif #if RTCSCFG_ENABLE_IP6 #if RTCSCFG_ENABLE_IP4 else if (peeraddr->sa_family == AF_INET6) { #endif if (addrlen < sizeof(struct sockaddr_in6)) { error = RTCSERR_SOCK_SHORT_ADDRESS; } /* Endif */ #if RTCSCFG_ENABLE_IP4 } #endif #endif #endif #if RTCSCFG_CHECK_ERRORS if(!error) { error = RTCSERR_SOCK_INVALID_AF; #if RTCSCFG_ENABLE_IP4 #if RTCSCFG_ENABLE_IP6 if(peeraddr->sa_family == AF_INET) { #endif error = RTCS_OK; #if RTCSCFG_ENABLE_IP6 } #endif #endif #if RTCSCFG_ENABLE_IP6 #if RTCSCFG_ENABLE_IP4 else if(peeraddr->sa_family == AF_INET6) { #endif error = RTCS_OK; #if RTCSCFG_ENABLE_IP4 } #endif #endif } #endif /* If socket is unbound, bind it SOCK_DGRAM_bind */ if (state == SOCKSTATE_DGRAM_GROUND) { //struct sockaddr_in6 localaddr; struct sockaddr localaddr; if (error) { RTCS_EXIT(CONNECT, error); } /* Endif */ #if RTCSCFG_ENABLE_IP4 #if RTCSCFG_ENABLE_IP6 if (peeraddr->sa_family == AF_INET) { #endif localaddr.sa_family = AF_INET; ((sockaddr_in*)&localaddr)->sin_port = 0; /*Set INADDR_ANY address*/ memset(&(((sockaddr_in*)&localaddr)->sin_addr), 0, sizeof(in_addr)); #if RTCSCFG_ENABLE_IP6 } #endif #endif #if RTCSCFG_ENABLE_IP6 #if RTCSCFG_ENABLE_IP4 else if (peeraddr->sa_family == AF_INET6) { #endif localaddr.sa_family = AF_INET6; ((sockaddr_in6 *)&localaddr)->sin6_port = 0; /* add local scope_id here */ ((sockaddr_in6 *)&localaddr)->sin6_scope_id = 0; /*Set INADDR_ANY address*/ memset(&(((sockaddr_in6 *)&localaddr)->sin6_addr), 0, sizeof(in6_addr)); #if RTCSCFG_ENABLE_IP4 } #endif #endif error = SOCK_DGRAM_bind(sock, &localaddr, sizeof(localaddr)); if (error) { RTCS_EXIT(CONNECT, error); } /* Endif */ } /* Endif */ /** check below for IPv6 ************************************/ /* ** Set socket in BOUND state and proceed normaly. If connect ** fails, leave the socket in BOUND state. If connect ** succeeds, set state to OPEN. */ ((SOCKET_STRUCT_PTR)sock)->STATE = SOCKSTATE_DGRAM_BOUND; #if RTCSCFG_ENABLE_IP4 #if RTCSCFG_ENABLE_IP6 if (peeraddr->sa_family == AF_INET) { #endif parms.ipaddress =((sockaddr_in *)peeraddr)->sin_addr.s_addr; parms.udpport =((sockaddr_in *)peeraddr)->sin_port; parms.ucb =((SOCKET_STRUCT_PTR)sock)->UCB_PTR; parms.udpword = error; error = RTCSCMD_issue(parms, UDP_connect); #if RTCSCFG_ENABLE_IP6 } #endif #endif #if RTCSCFG_ENABLE_IP6 #if RTCSCFG_ENABLE_IP4 else if (peeraddr->sa_family == AF_INET6) { #endif memcpy( &(parms.ipv6address), &(((sockaddr_in6 *)peeraddr)->sin6_addr),sizeof(struct in6_addr)); parms.udpport = ((sockaddr_in6 *)peeraddr)->sin6_port; parms.ucb = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR; parms.udpword = error; /* * choose and add scope_id here. * If peeraddr(target addr) scope_id is NULL we well use local(binded) scope_id */ parms.if_scope_id = ((sockaddr_in6 *)peeraddr)->sin6_scope_id; if(parms.if_scope_id ==0) { parms.if_scope_id = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->IF_SCOPE_ID; } error = RTCSCMD_issue(parms, UDP_connect6); #if RTCSCFG_ENABLE_IP4 } #endif #endif if (error) { RTCS_EXIT(CONNECT, error); } /* Endif */ /* Success */ ((SOCKET_STRUCT_PTR)sock)->STATE = SOCKSTATE_DGRAM_OPEN; RTCS_EXIT(CONNECT, RTCS_OK); } /* Endbody */
static int32_t SOCK_DGRAM_sendto ( uint32_t sock, /* [IN] socket handle */ void *send_buffer, /* [IN] data to transmit */ uint32_t buflen, /* [IN] length of the buffer, in bytes */ uint32_t flags, /* [IN] flags to underlying protocols */ sockaddr *destaddr, /* [IN] address to which to send data */ uint16_t addrlen /* [IN] length of the address, in bytes */ ) { UDP_PARM parms = {0}; uint32_t error = RTCS_OK; sockaddr addr = {0}; uint16_t len = sizeof(addr); SOCKET_STRUCT_PTR sock_struct_ptr = (SOCKET_STRUCT_PTR)sock; RTCS_ENTER(SENDTO, sock); if(!destaddr) /* called from SOCK_DGRAM_send() */ { error = SOCK_DGRAM_getpeername(sock, &addr, &len); if(error) { RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_CONNECTED); RTCS_EXIT2(SENDTO, RTCSERR_SOCK_NOT_CONNECTED, RTCS_ERROR); } destaddr = &addr; } parms.saddr_ptr = destaddr; if(sock_struct_ptr->STATE == SOCKSTATE_DGRAM_GROUND) { sockaddr localaddr = {0}; localaddr.sa_family = sock_struct_ptr->AF; error = SOCK_DGRAM_bind(sock,(sockaddr *)&localaddr, sizeof(localaddr)); if(error) { RTCS_setsockerror(sock, error); RTCS_EXIT2(SENDTO, error, RTCS_ERROR); } } parms.ucb = sock_struct_ptr->UCB_PTR; parms.udpptr = send_buffer; parms.udpword = buflen; parms.udpflags = flags; error = RTCSCMD_issue(parms, UDP_send); if(error) { RTCS_setsockerror(sock, error); RTCS_EXIT2(SENDTO, error, RTCS_ERROR); } RTCS_EXIT2(SENDTO, RTCS_OK, buflen); }
uint_32 SOL_IP_getsockopt ( uint_32 sock, /* [IN] socket handle */ uint_32 level, /* [IN] protocol level for the option */ uint_32 optname, /* [IN] name of the option */ pointer optval, /* [IN] buffer for the current value of the option */ uint_32 _PTR_ optlen /* [IN/OUT] length of the option value, in bytes */ ) { /* Body */ register SOCKET_STRUCT_PTR socket_ptr = (SOCKET_STRUCT_PTR)sock; uint_32 error; RTCS_ENTER(GETSOCKOPT, sock); #if RTCSCFG_CHECK_ERRORS if (sock == 0 || sock == RTCS_SOCKET_ERROR) { RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_INVALID); } /* Endif */ #endif switch (optname) { case RTCS_SO_IP_RX_DEST: if (*optlen < sizeof(_ip_address)) { RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_SHORT_OPTION); } /* Endif */ *(_ip_address _PTR_)optval = socket_ptr->LINK_OPTIONS.RX.DEST; *optlen = sizeof(_ip_address); break; case RTCS_SO_IP_RX_TTL: if (!*optlen) { RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_SHORT_OPTION); } /* Endif */ *(uchar_ptr)optval = socket_ptr->LINK_OPTIONS.RX.TTL; *optlen = sizeof(uchar); break; /* Start CR 1146 */ case RTCS_SO_IP_TX_TTL: if (!*optlen) { RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_SHORT_OPTION); } /* Endif */ *(uchar_ptr)optval = socket_ptr->LINK_OPTIONS.TX.TTL; *optlen = sizeof(uchar); break; /* End CR 1146 */ /* Start CR 9999-7 */ case RTCS_SO_IP_LOCAL_ADDR: if (*optlen < sizeof(_ip_address)) { RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_SHORT_OPTION); } /* Endif */ if ( socket_ptr->TCB_PTR != NULL) { *(_ip_address _PTR_)optval = socket_ptr->TCB_PTR->local_host; } else { *(_ip_address _PTR_)optval = 0; } *optlen = sizeof(_ip_address); break; /* End CR 9999-7 */ case RTCS_SO_IP_RX_TOS: if (!*optlen) { RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_SHORT_OPTION); } /* Endif */ *(uchar_ptr)optval = socket_ptr->LINK_OPTIONS.RX.TOS; *optlen = sizeof(uchar); break; default: error = RTCSERR_SOCK_INVALID_OPTION; } /* Endswitch */ RTCS_EXIT(GETSOCKOPT, RTCS_OK); } /* Endbody */
/*FUNCTION*------------------------------------------------------------- ************************************************************************ * * Function Name : SOCK_DGRAM_connect * Returned Value : error code * Comments : Binds the remote endpoint of a socket. Support IPv6 and IPv4. * * 1. If connect succeeds the socket is in OPEN state. * 2. If connect fails, the socket is in BOUND or GROUND state, and the * local IP is the same as it was immediately after the bind() call. * *********************************************************************** *END*-----------------------------------------------------------------*/ static uint32_t SOCK_DGRAM_connect ( uint32_t sock, /* [IN] socket handle */ const struct sockaddr *peeraddr, /* [IN] remote address to which to bind the socket */ uint16_t addrlen /* [IN] length of the address, in bytes */ ) { UDP_PARM parms = {0}; uint32_t error = RTCS_OK; SOCKET_STRUCT_PTR sock_struct_ptr = (SOCKET_STRUCT_PTR)sock; uint16_t state = sock_struct_ptr->STATE; sockaddr raddr = {0}; RTCS_ENTER(CONNECT, sock); /* If socket is unbound, bind it SOCK_DGRAM_bind */ if(state == SOCKSTATE_DGRAM_GROUND) { /* as we clear sockaddr to zeroes, it means INADDR_ANY, port 0, scope_id 0 */ struct sockaddr localaddr = {0}; localaddr.sa_family = sock_struct_ptr->AF; error = SOCK_DGRAM_bind(sock, &localaddr, sizeof(localaddr)); if (error) { RTCS_EXIT(CONNECT, error); } } /* ** Set socket in BOUND state and proceed normaly. If connect ** fails, leave the socket in BOUND state. If connect ** succeeds, set state to OPEN. */ sock_struct_ptr->STATE = SOCKSTATE_DGRAM_BOUND; parms.ucb = sock_struct_ptr->UCB_PTR; memcpy(&raddr, peeraddr, sizeof(sockaddr)); parms.saddr_ptr = &raddr; #if RTCSCFG_ENABLE_IP6 #if RTCSCFG_ENABLE_IP4 if (peeraddr->sa_family == AF_INET6) { #endif /* * choose and add scope_id here. * If peeraddr(target addr) scope_id is NULL we well use local(binded) scope_id */ if(0 == ((const sockaddr_in6 *)peeraddr)->sin6_scope_id) { ((sockaddr_in6*)&raddr)->sin6_scope_id = ((sockaddr_in6*)(&(sock_struct_ptr->UCB_PTR->LADDR)))->sin6_scope_id; } #if RTCSCFG_ENABLE_IP4 } #endif #endif error = RTCSCMD_issue(parms, UDP_connect); if(error) { RTCS_EXIT(CONNECT, error); } /* Success */ sock_struct_ptr->STATE = SOCKSTATE_DGRAM_OPEN; RTCS_EXIT(CONNECT, RTCS_OK); }