/* undind IP6 address on device */ static int32_t Shell_ipconfig_unbind6 (uint32_t enet_device, uint32_t index, int32_t argc, char *argv[]) { uint32_t error; IPCFG6_UNBIND_ADDR_DATA ip6_data; struct addrinfo hints; // used for getaddrinfo() struct addrinfo * addrinfo_res; // used for getaddrinfo() /* Here we need validate IP address and detect it family */ memset(&hints,0,sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_NUMERICHOST; if (getaddrinfo ( argv[index+1], NULL, &hints, &addrinfo_res) != 0) { printf("GETADDRINFO error\n"); return(SHELL_EXIT_ERROR); // we can return right here and do not need free freeaddrinfo(addrinfo_res) } if(addrinfo_res->ai_family == AF_INET6) { IN6_ADDR_COPY(&((struct sockaddr_in6 *)((*addrinfo_res).ai_addr))->sin6_addr,&ip6_data.ip_addr); freeaddrinfo(addrinfo_res); error = ipcfg6_unbind_addr ( enet_device, &ip6_data); if (error != 0) { printf ("Error during unbind %08x!\n", error); return SHELL_EXIT_ERROR; } printf ("Unbind successful.\n"); return SHELL_EXIT_SUCCESS; } printf ("Unbind unsuccessful. Unexpected inet family\n"); return SHELL_EXIT_SUCCESS; }
/*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 */
/*! Send a SOCKS request to the request pipe in order to get * added to the SOCKS queue with socks_enqueue() * @param addr IPv6 address to be requested * @param perm 1 if connection should kept opened inifitely after successful request, 0 else. */ void socks_queue(struct in6_addr addr, int perm) { SocksQueue_t *squeue, sq; for (squeue = socks_queue_; squeue; squeue = squeue->next) if (IN6_ARE_ADDR_EQUAL(&squeue->addr, &addr)) break; if (!squeue) { log_debug("queueing new SOCKS connection request"); memset(&sq, 0, sizeof(sq)); IN6_ADDR_COPY(&sq.addr, &addr); sq.perm = perm; log_debug("signalling connector"); socks_pipe_request(&sq); } else log_debug("connection already exists, not queueing SOCKS connection"); }
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 */
/*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 */
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 */
static int32_t Shell_ipconfig_staticip (uint32_t enet_device, uint32_t index, int32_t argc, char *argv[]) { uint32_t error; #if RTCSCFG_ENABLE_IP4 IPCFG_IP_ADDRESS_DATA ip_data; #endif #if RTCSCFG_ENABLE_IP6 /*IPv6 adds*/ struct addrinfo hints; // used for getaddrinfo() struct addrinfo * addrinfo_res; // used for getaddrinfo() IPCFG6_BIND_ADDR_DATA ip6_bind_data; // structure for bind interface in6_addr ip6; #endif /* Here we need validate IP address and detect it family */ /* Dont forget destroy addrinfo_res by freeaddrinfo(addrinfo_res) */ #if RTCSCFG_ENABLE_IP6 memset(&hints,0,sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_NUMERICHOST; if (getaddrinfo ( argv[index+1], NULL, &hints, &addrinfo_res) != 0) { printf("GETADDRINFO error\n"); return(SHELL_EXIT_ERROR); // we can return right here and do not need free freeaddrinfo(addrinfo_res) } if(addrinfo_res->ai_family == AF_INET6) { IN6_ADDR_COPY(&((struct sockaddr_in6 *)((*addrinfo_res).ai_addr))->sin6_addr,&ip6_bind_data.ip_addr); ip6_bind_data.ip_addr_type = IP6_ADDR_TYPE_MANUAL; freeaddrinfo(addrinfo_res); error = ipcfg6_bind_addr (enet_device, &ip6_bind_data); if (error != RTCS_OK) { printf("\nIPCFG Bind IP6(1) is failed, error = %X\n", error); return SHELL_EXIT_ERROR; } printf ("IP6 bind successful.\n"); return SHELL_EXIT_SUCCESS; } #if RTCSCFG_ENABLE_IP4 else if(addrinfo_res->ai_family == AF_INET) { freeaddrinfo(addrinfo_res); #endif #endif //RTCSCFG_ENABLE_IP6 #if RTCSCFG_ENABLE_IP4 if (argc > ++index) { if (! Shell_parse_ip_address (argv[index], &ip_data.ip)) { printf ("Error in static ip command, invalid ip address!\n"); return SHELL_EXIT_ERROR; } } else { printf ("Error in static ip command, missing ip address parameter!\n"); return SHELL_EXIT_ERROR; } if (argc > ++index) { if (! Shell_parse_ip_address (argv[index], &ip_data.mask)) { printf ("Error in static ip command, invalid mask!\n"); return SHELL_EXIT_ERROR; } } else { printf ("Error in static ip command, missing mask parameter!\n"); return SHELL_EXIT_ERROR; } #if RTCSCFG_ENABLE_GATEWAYS if (argc > ++index) { if (! Shell_parse_ip_address (argv[index], &ip_data.gateway)) { printf ("Error in static ip command, invalid gateway!\n"); return SHELL_EXIT_ERROR; } } #endif error = ipcfg_bind_staticip (enet_device, &ip_data); if (error != 0) { printf ("Error during static ip bind %08x!\n", error); return SHELL_EXIT_ERROR; } printf ("Static IP4 bind successful.\n"); return SHELL_EXIT_SUCCESS; #endif #if RTCSCFG_ENABLE_IP6 #if RTCSCFG_ENABLE_IP4 }//end if family #endif printf ("Static bind unsuccessful. Unknown family detected.\n"); return SHELL_EXIT_ERROR; #endif }