/* ** Function used to init session structure ** ** IN: ** FTPSRV_SESSION_STRUCT* session - session structure pointer ** FTPSRV_STRUCT *server - pointer to server structure (needed for session parameters) ** const int sock - socket handle used for communication with client ** ** OUT: ** none ** ** Return Value: ** none */ static void ftpsrv_ses_init(FTPSRV_STRUCT *server, FTPSRV_SESSION_STRUCT *session, const int sock) { if (server && session) { /* Some buffer of arbitrary size so we can get filesystem pointer */ char dev_name[16] = {0}; /* Init session structure */ session->control_sock = sock; session->connected = TRUE; session->auth_tbl = server->params.auth_table; session->root_dir = (char*) server->params.root_dir; session->cur_dir = RTCS_mem_alloc_zero(sizeof("\\")); session->cur_dir[0] = '\\'; session->start_time = RTCS_time_get(); _io_get_dev_for_path(dev_name, NULL, 16, session->root_dir, NULL); session->fs_ptr = _io_get_fs_by_name(dev_name); session->msg_queue = RTCS_mem_alloc_zero(sizeof(LWMSGQ_STRUCT) + FTPSRV_NUM_MESSAGES*sizeof(FTPSRV_TRANSFER_MSG)*sizeof(_mqx_max_type)); if (session->msg_queue != NULL) { _lwmsgq_init(session->msg_queue, FTPSRV_NUM_MESSAGES, sizeof(FTPSRV_TRANSFER_MSG)/sizeof(_mqx_max_type)); } } }
uint32_t IGMP_init ( void ) { /* Body */ uint32_t error; IGMP_CFG_STRUCT_PTR IGMP_cfg_ptr; /* alloc and init the configuration block */ IGMP_cfg_ptr = RTCS_mem_alloc_zero(sizeof(IGMP_CFG_STRUCT)); if (!IGMP_cfg_ptr) { return RTCSERR_IGMP_CFG; } /* Endif */ /* register the configuration block */ RTCS_setcfg(IGMP, IGMP_cfg_ptr); /* register the igmp protocol in the ip layer */ IP_open(IPPROTO_IGMP, IGMP_service, NULL, &error); if (error != RTCS_OK) { return RTCSERR_IGMP_CFG; } /* Endif */ /* ** When IGMP_init() is called, the only registered interface is the ** loopback interface, so we don't need to join the all-hosts group ** on any interface here. */ return error; } /* Endbody */
uint32_t RIP_init (void) { /* Body */ RIP_CFG_STRUCT_PTR cfg = RTCS_getcfg(RIP); uint32_t err; if (RTCS_getcfg(RIP)) return RTCS_OK; /* allocate the memory */ cfg = RTCS_mem_alloc_zero(sizeof(*cfg)); if (!cfg) return RTCSERR_OUT_OF_MEMORY; /* bind the udp port */ err = UDP_openbind_internal(IPPORT_RIP, RIP_service, &cfg->UCB); if (err){ _mem_free(cfg); return err; } RTCS_setcfg(RIP, cfg); ROUTE_register(&RIP_routefn); /* Start the retransmission timer to start sending immediately */ cfg->TIMER_PERIODIC.TIME = 0; cfg->TIMER_PERIODIC.EVENT = RIP_expire_periodic; cfg->TIMER_PERIODIC.PRIVATE = NULL; TCPIP_Event_add(&cfg->TIMER_PERIODIC); /* probe all the interfaces now to build the route table faster */ err = RIP_send_req(); return RTCS_OK; } /* Endbody */
void TFTPSRV_task ( void *dummy, void *creator ) { /* Body */ TFTPSRV_STATE_STRUCT_PTR tftpsrv_ptr; sockaddr_in laddr; uint32_t i, numtrans, timeout; uint32_t error; tftpsrv_ptr = RTCS_mem_alloc_zero(sizeof(TFTPSRV_STATE_STRUCT)); if (tftpsrv_ptr == NULL) { RTCS_task_exit(creator, RTCSERR_OUT_OF_MEMORY); } /* Endif */ TFTPSRV_task_id = RTCS_task_getid(); #ifdef __MQX__ /* Set up exit handler and context so that we can clean up if the TFTP Server is terminated */ _task_set_environment( _task_get_id(), (void *) tftpsrv_ptr ); _task_set_exit_handler( _task_get_id(), TFTPSRV_Exit_handler ); #endif tftpsrv_ptr->SRV_SOCK = socket(PF_INET, SOCK_DGRAM, 0); if (tftpsrv_ptr->SRV_SOCK == RTCS_SOCKET_ERROR) { RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS); } /* Endif */ laddr.sin_family = AF_INET; laddr.sin_port = IPPORT_TFTP; laddr.sin_addr.s_addr = INADDR_ANY; error = bind(tftpsrv_ptr->SRV_SOCK, (const sockaddr *)&laddr, sizeof(laddr)); if (error != RTCS_OK) { RTCS_task_exit(creator, error); } /* Endif */ RTCS_task_resume_creator(creator, RTCS_OK); for (;;) { timeout = TFTPSRV_service_timer(tftpsrv_ptr); numtrans = tftpsrv_ptr->NUM_TRANSACTIONS; error = RTCS_selectset(&tftpsrv_ptr->SRV_SOCK, numtrans+1, timeout); if ((error == RTCS_OK) || (error == RTCS_SOCKET_ERROR)) { continue; } /* Endif */ if (error == tftpsrv_ptr->SRV_SOCK) { /* New request, service it */ TFTPSRV_service_request(tftpsrv_ptr); } else { for (i = 0; i < numtrans; i++) { if (error == tftpsrv_ptr->SOCKETS[i]) { TFTPSRV_service_transaction(tftpsrv_ptr, tftpsrv_ptr->TRANS_PTRS[i]); break; } /* Endif */ } /* Endfor */ } /* Endif */ } /* Endfor */ } /* Endbody */
/* ** Function for session allocation ** ** IN: ** FTPSRV_STRUCT *server - pointer to server structure (needed for session parameters). ** ** OUT: ** none ** ** Return Value: ** FTPSRV_SESSION_STRUCT* - pointer to allocated session. Non-zero if allocation was OK, NULL otherwise */ static FTPSRV_SESSION_STRUCT* ftpsrv_ses_alloc(FTPSRV_STRUCT *server) { FTPSRV_SESSION_STRUCT *session = NULL; if (server) { session = RTCS_mem_alloc_zero(sizeof(FTPSRV_SESSION_STRUCT)); if (session) { session->buffer = RTCS_mem_alloc_zero(sizeof(char)*FTPSRV_BUF_SIZE); } } if (session && (session->buffer == NULL)) { _mem_free(session); session = NULL; } return session; }
/*FUNCTION*------------------------------------------------------------------- * * Function Name : ftpsrv_get_full_path * Returned Value : char* full path of file (root directory + server root + path from parameter) * Comments : This function is used for translating relative path to absolute path * which is required for file operations in MFS. Returned string is allocated dynamically. * * Usage: * *END*---------------------------------------------------------------------*/ char* ftpsrv_get_full_path(FTPSRV_SESSION_STRUCT* session, char* path, uint32_t *wrong_path) { uint32_t path_length = strlen(path); uint32_t root_length = strlen(session->root_dir); uint32_t cur_dir_length; char* new_path; uint32_t index = 0; /* ** If first character in the path is backslash, then the path is absolute in FTP root ** and current directory is not to be added to full path. */ cur_dir_length = (path[0] != '\\') ? strlen(session->cur_dir) : 0; new_path = RTCS_mem_alloc_zero(path_length+root_length+cur_dir_length+2); /* +1 because of backslash and +1 for terminator */ if (new_path == NULL) { return(new_path); } memmove(new_path, session->root_dir, root_length); index += root_length; if (cur_dir_length) { memmove(new_path+index, session->cur_dir, cur_dir_length); index += cur_dir_length; if (new_path[index-1] != '\\') { new_path[index++] = '\\'; } } memmove(new_path+index, path, path_length); /* Resolve directory changing sequences. */ rtcs_path_normalize(new_path); path_length = strlen(new_path); *wrong_path = FALSE; /* If there is not root directory in result, signalize error. */ if ((path_length < root_length) || (new_path[root_length] != '\\') || strncmp(new_path, session->root_dir, root_length) != 0) { _mem_free(new_path); new_path = NULL; *wrong_path = TRUE; } return(new_path); }
char* ftpsrv_get_relative_path(FTPSRV_SESSION_STRUCT* session, char* abs_path) { uint32_t root_length = strlen(session->root_dir); uint32_t new_length = strlen(abs_path) - root_length; char* rel_path; rel_path = RTCS_mem_alloc_zero(new_length+1); if (rel_path != NULL) { _mem_copy(abs_path+root_length, rel_path, new_length); } return(rel_path); }
int32_t ftpsrv_user(FTPSRV_SESSION_STRUCT* session) { char* temp; uint32_t length; int32_t retval = FTPSRV_ERROR; FTPSRV_AUTH_STRUCT* input = &session->auth_input; if (session->cmd_arg == NULL) { session->message = (char*) ftpsrvmsg_badsyntax; return(FTPSRV_ERROR); } length = strlen(session->cmd_arg) + 1; if ((input->uid) && (strlen(input->uid) >= length)) { temp = input->uid; } else { if (input->uid != NULL) { _mem_free(input->uid); input->uid = NULL; } temp = RTCS_mem_alloc_zero(sizeof(char)*length); } if (temp != NULL) { _mem_copy(session->cmd_arg, temp, length - 1); input->uid = temp; session->message = (char*) ftpsrvmsg_need_password; session->auth_state = FTPSRV_USER; retval = FTPSRV_OK; } if (retval != FTPSRV_OK) { session->message = (char*) ftpsrvmsg_no_memory; } return(retval); }
bool SOCK_Add_owner ( SOCKET_STRUCT_PTR socket_ptr, _rtcs_taskid task_ptr ) { /* Body */ #if RTCSCFG_SOCKET_OWNERSHIP SOCKET_OWNER_STRUCT_PTR owner_ptr, new_owner_ptr; uint32_t i; void **saved_ptr = NULL; owner_ptr = &socket_ptr->OWNERS; while (owner_ptr != NULL) { for (i=0;i<SOCKET_NUMOWNERS;i++) { if (owner_ptr->TASK[i] == task_ptr) { /* already here, just return */ return TRUE; } else if ((owner_ptr->TASK[i] == 0) && (saved_ptr == NULL)) { saved_ptr = &owner_ptr->TASK[i]; } /* Endif */ } /* Endfor */ owner_ptr = owner_ptr->NEXT; } /* Endwhile */ if (saved_ptr != NULL) { *saved_ptr = task_ptr; } else { new_owner_ptr = RTCS_mem_alloc_zero(sizeof(SOCKET_OWNER_STRUCT)); if (new_owner_ptr == NULL) { return FALSE; } /* Endif */ _mem_set_type(new_owner_ptr, MEM_TYPE_SOCKET_OWNER_STRUCT); new_owner_ptr->TASK[0] = task_ptr; owner_ptr->NEXT = new_owner_ptr; } /* Endif */ return TRUE; #else return TRUE; #endif } /* Endbody */
uint32_t ICMP_init ( void ) { /* Body */ ICMP_CFG_STRUCT_PTR icmp_cfg_ptr; uint32_t status = RTCS_OK; /* return code */ icmp_cfg_ptr = RTCS_mem_alloc_zero(sizeof(ICMP_CFG_STRUCT)); if (icmp_cfg_ptr == NULL) { return RTCSERR_OUT_OF_MEMORY; } _mem_set_type(icmp_cfg_ptr, MEM_TYPE_ICMP_CFG_STRUCT); RTCS_setcfg(ICMP, icmp_cfg_ptr); IP_open(IPPROTO_ICMP, ICMP_service, NULL, &status); return status; } /* Endbody */
_mqx_int _io_socket_open ( MQX_FILE_PTR fd_ptr, char _PTR_ open_name_ptr, char _PTR_ flags_ptr ) { /* Body */ IO_SOCKET_PTR io_ptr; io_ptr = RTCS_mem_alloc_zero(sizeof(*io_ptr)); if (io_ptr == NULL) { return MQX_OUT_OF_MEMORY; } /* Endif */ _mem_set_type(io_ptr, MEM_TYPE_IO_SOCKET); fd_ptr->DEV_DATA_PTR = io_ptr; io_ptr->SOCKET = (uint_32)flags_ptr; return MQX_OK; } /* Endbody */
HOSTENT_STRUCT *DNS_query_resolver_task ( unsigned char *name, uint16_t query_type ) { /* Body */ DNS_MESSAGE_HEADER_STRUCT *message_head_ptr; DNS_MESSAGE_TAIL_STRUCT *message_tail_ptr; HOSTENT_STRUCT *host_ptr = NULL; sockaddr_in addr; uint32_t local_sock; uint32_t qname_size; uint32_t buffer_size; uint16_t rlen; int32_t temp_size; int32_t error; unsigned char *temp_ptr; unsigned char *qname_ptr; unsigned char *buffer_ptr; /* ** If the size of this buffer is changed, also change the buffer size ** in the recvfrom() call near the bottom of this function */ buffer_ptr = RTCS_mem_alloc_zero( DNS_MAX_UDP_MESSAGE_SIZE ); if ( buffer_ptr == NULL ) { RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY, 0, 0, 0); return( NULL ); }/* Endif */ _mem_set_type(buffer_ptr, MEM_TYPE_DNS_UDP_MESSAGE); qname_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT ); if ( query_type == DNS_A ) { error = DNS_is_dotted_domain_name( name, qname_ptr ); if ( error == RTCSERR_DNS_INVALID_NAME || error == RTCSERR_DNS_INVALID_LOCAL_NAME ) { _mem_free(buffer_ptr); return( NULL ); }/* Endif */ } else { if ( query_type == DNS_PTR ) { error = DNS_insert_IP_query( name, qname_ptr ); if ( error == RTCSERR_DNS_INVALID_IP_ADDR ) { _mem_free(buffer_ptr); return( NULL ); }/* Endif */ } else { _mem_free(buffer_ptr); return( NULL ); } /* Endif */ } /* Endif */ local_sock = socket(AF_INET, SOCK_DGRAM, 0); if ( local_sock == RTCS_HANDLE_ERROR ) { RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_OPEN_SOCKET, 0, 0, 0); _mem_free(buffer_ptr); return( NULL ); }/* Endif */ /* Local address */ addr.sin_family = AF_INET; addr.sin_port = 0; addr.sin_addr.s_addr = INADDR_ANY; error = bind(local_sock, &addr, sizeof(addr)); if (error != RTCS_OK) { RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_BIND_SOCKET, 0, 0, 0); _mem_free(buffer_ptr); return( NULL ); } /* Endif */ /* set up buffer for sending query. */ message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT *)buffer_ptr; mqx_htons(message_head_ptr->ID, 0); mqx_htons(message_head_ptr->CONTROL, DNS_STANDARD_QUERY); mqx_htons(message_head_ptr->QDCOUNT, DNS_SINGLE_QUERY); mqx_htons(message_head_ptr->NSCOUNT, 0); mqx_htons(message_head_ptr->ARCOUNT, 0); mqx_htons(message_head_ptr->ANCOUNT, 0); qname_size = strlen((char *)qname_ptr ); /* Need to include the last '\0' character as well */ qname_size++; temp_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT ) + qname_size; message_tail_ptr = (DNS_MESSAGE_TAIL_STRUCT *)temp_ptr; mqx_htons(message_tail_ptr->QTYPE, query_type); mqx_htons(message_tail_ptr->QCLASS, DNS_IN); buffer_size = sizeof(DNS_MESSAGE_HEADER_STRUCT) + qname_size + sizeof(DNS_MESSAGE_TAIL_STRUCT); /* Remote address, DNS_Resolver currently uses port 1024 */ addr.sin_port = DNS_RESOLVER_PORT; addr.sin_addr.s_addr = DNS_RESOLVER_IP_ADDR; rlen = sizeof(addr); /* Send the buffer to the resolver for making a query */ error = sendto(local_sock, buffer_ptr, buffer_size, 0, &addr, rlen); if (error == RTCS_ERROR) { shutdown(local_sock, FLAG_ABORT_CONNECTION); RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_SEND_QUERY, 0, 0, 0); _mem_free(buffer_ptr); return( NULL ); }/* Endif */ /* Get the response from the resolver, if none received, return NULL */ error = (uint32_t)RTCS_selectset( &local_sock, 1, DNS_QUERY_TIMEOUT ); if ( !error || error == RTCS_ERROR ) { shutdown(local_sock, FLAG_ABORT_CONNECTION); RTCS_log_error(ERROR_DNS, RTCSERR_DNS_NO_RESPONSE_FROM_RESOLVER, 0, 0, 0); _mem_free(buffer_ptr); return( NULL ); } /* Endif */ temp_size = recvfrom(local_sock, buffer_ptr, DNS_MAX_UDP_MESSAGE_SIZE, 0, &addr, &rlen); if ( temp_size == RTCS_ERROR ) { shutdown(local_sock, FLAG_ABORT_CONNECTION); RTCS_log_error(ERROR_DNS, RTCSERR_DNS_PACKET_RECEPTION_ERROR, 0, 0, 0); _mem_free(buffer_ptr); return( NULL ); }/* Endif */ host_ptr = DNS_parse_UDP_response(buffer_ptr, name, query_type); shutdown(local_sock, FLAG_ABORT_CONNECTION); _mem_free(buffer_ptr); return( host_ptr ); } /* Endbody */
bool_t pmap_init ( void ) { /* Body */ int_32 sock; sockaddr_in laddr; SVCXPRT_PTR xprt; PMAPLIST_PTR pml; /* create and bind a UDP socket */ sock = socket(PF_INET, SOCK_DGRAM, 0); if (sock == (int_32)RTCS_SOCKET_ERROR) { fprintf(stderr, "portmap: error creating UDP socket\n"); return FALSE; } /* Endif */ _mem_zero(&laddr, sizeof(laddr)); laddr.sin_family = AF_INET; laddr.sin_port = PMAPPORT; laddr.sin_addr.s_addr = 0; if (bind(sock, &laddr, sizeof(laddr)) != RTCS_OK) { fprintf(stderr, "portmap: error binding UDP socket, rec=%08X\n", RTCS_geterror(sock)); return FALSE; } /* Endif */ /* create a UDP transport*/ xprt = svcudp_create(sock); if (xprt == NULL) { fprintf(stderr, "portmap: error creating UDP transport, rec=%08X\n", RTCS_geterror(sock)); return FALSE; } /* Endif */ /* create an entry for the UDP transport */ pml = (PMAPLIST_PTR)RTCS_mem_alloc_zero(sizeof(PMAPLIST)); if (pml == NULL) { fprintf(stderr, "portmap: error creating UDP entry, can't alloc memory\n"); return FALSE; } /* Endif */ pml->pml_map.pm_prog = PMAPPROG; pml->pml_map.pm_vers = PMAPVERS; pml->pml_map.pm_prot = IPPROTO_UDP; pml->pml_map.pm_port = PMAPPORT; pml->pml_next = pml_head; pml_head = pml; /* create, bind and connect a TCP socket */ sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == (int_32)RTCS_SOCKET_ERROR) { fprintf(stderr, "portmap: error creating TCP socket\n"); return FALSE; } /* Endif */ _mem_zero(&laddr, sizeof(laddr)); laddr.sin_family = AF_INET; laddr.sin_port = PMAPPORT; laddr.sin_addr.s_addr = 0; if (bind(sock, &laddr, sizeof(laddr)) != RTCS_OK) { fprintf(stderr, "portmap: error binding TCP socket, rec=%08X\n", RTCS_geterror(sock)); return FALSE; } /* Endif */ if (listen(sock, 0) != RTCS_OK) { fprintf(stderr, "portmap: error on socket listen, rec=%08X\n", RTCS_geterror(sock)); return FALSE; } /* Endif */ /* create a TCP transport*/ xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); if (xprt == NULL) { fprintf(stderr, "portmap: error creating TCP transport, rec=%08X\n", RTCS_geterror(sock)); return FALSE; } /* Endif */ /* create an entry for the TCP transport */ pml = (PMAPLIST_PTR)RTCS_mem_alloc_zero(sizeof(PMAPLIST)); if (pml == NULL) { fprintf(stderr, "portmap: error creating TCP entry, task error=%08X\n", _task_get_error()); return FALSE; } /* Endif */ pml->pml_map.pm_prog = PMAPPROG; pml->pml_map.pm_vers = PMAPVERS; pml->pml_map.pm_prot = IPPROTO_TCP; pml->pml_map.pm_port = PMAPPORT; pml->pml_next = pml_head; pml_head = pml; /* register program */ if (!svc_register(NULL, PMAPPROG, PMAPVERS, pmap_service, 0)) { fprintf(stderr, "portmap: error registering service\n"); return FALSE; } /* Endif */ return TRUE; } /* Endbody */
/* ** Internal function for server parameters initialization ** ** IN: ** FTPSRV_STRUCT* server - server structure pointer ** ** FTPSRV_PARAM_STRUCT* params - pointer to user parameters if there are any ** OUT: ** none ** ** Return Value: ** uint32_t error code. FTPSRV_OK if everything went right, positive number otherwise */ static uint32_t ftpsrv_set_params(FTPSRV_STRUCT *server, FTPSRV_PARAM_STRUCT *params) { char* temp; server->params.port = IPPORT_FTP; #if RTCSCFG_ENABLE_IP4 server->params.ipv4_address.s_addr = FTPSRVCFG_DEF_ADDR; server->params.af |= AF_INET; #endif #if RTCSCFG_ENABLE_IP6 server->params.ipv6_address = in6addr_any; server->params.ipv6_scope_id = 0; server->params.af |= AF_INET6; #endif server->params.max_ses = FTPSRVCFG_DEF_SES_CNT; server->params.root_dir = "mfs:"; server->params.server_prio = FTPSRVCFG_DEF_SERVER_PRIO; server->params.auth_table = NULL; server->params.use_nagle = 0; /* If there is parameters structure copy nonzero values to server */ if (params != NULL) { if (params->port) server->params.port = params->port; #if RTCSCFG_ENABLE_IP4 if (params->ipv4_address.s_addr != 0) server->params.ipv4_address = params->ipv4_address; #endif #if RTCSCFG_ENABLE_IP6 if (params->ipv6_address.s6_addr != NULL) server->params.ipv6_address = params->ipv6_address; if (params->ipv6_scope_id) server->params.ipv6_scope_id = params->ipv6_scope_id; #endif if (params->af) server->params.af = params->af; if (params->max_ses) server->params.max_ses = params->max_ses; if (params->root_dir) { server->params.root_dir = params->root_dir; } else { return(FTPSRV_ERROR); } if (params->server_prio) server->params.server_prio = params->server_prio; if (params->auth_table) server->params.auth_table = params->auth_table; if (params->use_nagle) server->params.use_nagle = params->use_nagle; } /* Allocate space for string parameters and copy them. */ temp = RTCS_mem_alloc_zero(strlen(server->params.root_dir)+1); if (temp == NULL) { return(FTPSRV_ERROR); } _mem_copy(server->params.root_dir, temp, strlen(server->params.root_dir)); server->params.root_dir = temp; return(FTPSRV_OK); }
HOSTENT_STRUCT *DNS_parse_UDP_response ( unsigned char *buffer_ptr, unsigned char *name_ptr, uint16_t query_type ) { /* Body */ DNS_MESSAGE_HEADER_STRUCT *message_head_ptr = NULL; DNS_RESPONSE_RR_MIDDLE_STRUCT *answer_middle; INTERNAL_HOSTENT_STRUCT *host_ptr = &RTCS_HOST; unsigned char *answer_ptr; unsigned char *answer_tail; unsigned char *temp_ptr; uint16_t response_length, answer_type, name_size, number_of_answers, num_queries; uint32_t i, name_index = 0; uint32_t j = 0; uint32_t k = 0; uint32_t buffer_size; uint32_t *addr_ptr; bool unknown_answer_type = FALSE; message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT *)buffer_ptr; buffer_size = sizeof(DNS_MESSAGE_HEADER_STRUCT); temp_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT ); /* Zero the global HOSTENT_STRUCT */ _mem_zero((char *)host_ptr, sizeof(INTERNAL_HOSTENT_STRUCT)); /* Get the number of queries. */ num_queries = mqx_ntohs(message_head_ptr->QDCOUNT); for (i = 0; i < num_queries; i++) { name_size = 0; while( (mqx_ntohc(temp_ptr) != '\0') && name_size < DNS_MAX_CHARS_IN_NAME ) { name_size = name_size + mqx_ntohc(temp_ptr) + 1; temp_ptr = temp_ptr + mqx_ntohc(temp_ptr) + 1; } /* Endwhile */ /* To include the terminating NULL char */ name_size++; buffer_size += (name_size + sizeof(DNS_MESSAGE_TAIL_STRUCT)); temp_ptr += (1 + sizeof(DNS_MESSAGE_TAIL_STRUCT)); } /* Endfor */ number_of_answers = mqx_ntohs(message_head_ptr->ANCOUNT); if (number_of_answers > DNS_MAX_NAMES ) { number_of_answers = DNS_MAX_NAMES; } /* Endif */ host_ptr->HOSTENT.h_aliases = &host_ptr->ALIASES[0]; host_ptr->HOSTENT.h_addr_list = (char **)&host_ptr->ADDRESSES[0]; host_ptr->ADDRESSES[0] = NULL; host_ptr->HOSTENT.h_name = NULL; host_ptr->HOSTENT.h_length = sizeof( _ip_address ); for (i = 0; (i < number_of_answers) && (j < DNS_MAX_ADDRS) && (k < DNS_MAX_NAMES); i++ ) { answer_ptr = temp_ptr; name_size = 0; while( (mqx_ntohc(temp_ptr) != '\0') && name_size < DNS_MAX_CHARS_IN_NAME && !(mqx_ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK)) { name_size += mqx_ntohc(temp_ptr); temp_ptr += mqx_ntohc(temp_ptr) + 1; } /* Endwhile */ if ( mqx_ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK ) { temp_ptr++; }/* Endif */ temp_ptr++; answer_middle = (DNS_RESPONSE_RR_MIDDLE_STRUCT *)temp_ptr; response_length = mqx_ntohs(answer_middle->RDLENGTH); answer_type = mqx_ntohs(answer_middle->TYPE); temp_ptr += sizeof(DNS_RESPONSE_RR_MIDDLE_STRUCT); answer_tail = temp_ptr; temp_ptr += response_length; switch ( answer_type ) { case DNS_A: if ( host_ptr->HOSTENT.h_name == NULL ) { host_ptr->HOSTENT.h_name = (char *)DNS_parse_answer_name_to_dotted_form( buffer_ptr, answer_ptr, name_index ); name_index++; } /* Endif */ RTCS_HOST_ADDRS[j] = mqx_ntohl((unsigned char *)answer_tail); /* ** j is used in case BOTH CNAME and A data is received. If CNAME ** answer is first, will write into wrong address space if using ** i. */ host_ptr->ADDRESSES[j] = &RTCS_HOST_ADDRS[j]; j++; /* ** This is to assure that the first IP address used is the first ** one that was given */ host_ptr->IP_address = *host_ptr->ADDRESSES[0]; break; case DNS_PTR: if (query_type == DNS_PTR) { if (host_ptr->HOSTENT.h_name != NULL) { host_ptr->ALIASES[k] = host_ptr->HOSTENT.h_name; k++; } /* Endif */ host_ptr->HOSTENT.h_name = (char *)DNS_parse_answer_name_to_dotted_form( buffer_ptr, answer_tail, name_index ); name_index++; addr_ptr = RTCS_mem_alloc_zero( sizeof( _ip_address )); if ( addr_ptr == NULL ) { RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY, 0, 0, 0); return( NULL ); }/* Endif */ *addr_ptr = *((_ip_address *)name_ptr); host_ptr->ADDRESSES[j] = addr_ptr; j++; host_ptr->IP_address = *host_ptr->ADDRESSES[0]; } else { host_ptr->ALIASES[k] = (char *) DNS_parse_answer_name_to_dotted_form( buffer_ptr, answer_tail, name_index ); name_index++; k++; } /* Endif */ break; case DNS_CNAME: /* the k is used for ALIASES as the j is used for ADDRESSES */ host_ptr->ALIASES[k] = (char *) DNS_parse_answer_name_to_dotted_form( buffer_ptr, answer_tail, name_index ); name_index++; k++; break; default: unknown_answer_type = TRUE; } /* Endswitch */ if ( unknown_answer_type == TRUE ) { break; }/* Endif */ host_ptr->ADDRESSES[j] = NULL; host_ptr->ALIASES[k] = NULL; host_ptr->HOSTENT.h_addrtype = mqx_ntohs(answer_middle->CLASS); } /* Endfor */ if ( number_of_answers == 0 ) { return( NULL ); } /* Endif */ return( &RTCS_HOST.HOSTENT ); } /* Endbody */
HOSTENT_STRUCT_PTR RTCS_gethostbyname ( char_ptr name ) { /* Body */ INTERNAL_HOSTENT_STRUCT_PTR host_ptr; uint_32 i; boolean name_found; boolean dotted_decimal; uint_32 num_aliases = 0; uint_32 host_index = 0; uint_32 temp; /* allocate memory for HOSTENT_STRUCT */ host_ptr = RTCS_mem_alloc_zero(sizeof(INTERNAL_HOSTENT_STRUCT)); if ( host_ptr == NULL ) { return(NULL); }/* Endif */ _mem_set_type(host_ptr, MEM_TYPE_HOSTENT_STRUCT); host_ptr->HOSTENT.h_aliases = &host_ptr->ALIASES[0]; host_ptr->HOSTENT.h_addr_list = (char_ptr _PTR_)&host_ptr->ADDRESSES[0]; /* assign address type and length */ host_ptr->HOSTENT.h_addrtype = AF_INET; host_ptr->HOSTENT.h_length = 4; /* IP addresses only used - 4 bytes */ /* check to see if name is written in dotted decimal IP format */ dotted_decimal = RTCS_get_dotted_address (name, &temp); if ( dotted_decimal == TRUE ) { /* assign the hostent struct from the dotted decimal IP name */ host_ptr->HOSTENT.h_name = name; host_ptr->ALIASES[num_aliases] = NULL; host_ptr->IP_address = temp; host_ptr->ADDRESSES[0] = &host_ptr->IP_address; host_ptr->ADDRESSES[1] = NULL; name_found = TRUE; } else { name_found = FALSE; /* search for the name in the hosts structure */ while ( ((RTCS_Hosts_list[host_index]).ip_address != 0) && !name_found) { /*end of list hasn't been reached*/ /* check the aliases for the name */ i=0; while ( ((RTCS_Hosts_list[host_index]).aliases[i] != NULL) && !name_found) { if ( strcmp((RTCS_Hosts_list[host_index]).aliases[i],name) == 0 ) { name_found = TRUE; }/* Endif */ ++i; } /* Endwhile */ /* check the name field for the name */ if ( strcmp((RTCS_Hosts_list[host_index]).host_name, name) == 0) { name_found = TRUE; } /* Endif */ if (name_found == TRUE ) { /* host name was found */ host_ptr->HOSTENT.h_name = (RTCS_Hosts_list[host_index]).host_name; /* assign alias list */ while ( (num_aliases < MAX_HOST_ALIASES) && (RTCS_Hosts_list[host_index]).aliases[num_aliases] != NULL) { host_ptr->ALIASES[num_aliases] = (RTCS_Hosts_list[host_index]).aliases[num_aliases]; ++num_aliases; } /* Endwhile */ host_ptr->ALIASES[num_aliases] = NULL; /* assign addresses (in our case only one IP address is allowed) */ host_ptr->ADDRESSES[0] = (uint_32_ptr)&((RTCS_Hosts_list[host_index]).ip_address); host_ptr->ADDRESSES[1] = NULL; } /* Endif */ ++host_index; } /* Endwhile */ }/* Endif */ if ( !name_found ) { _mem_free(host_ptr); return( NULL ); }/* Endif */ return( &host_ptr->HOSTENT ); }/* EndBody */
/* * Allocate server structure, init sockets, etc. */ FTPSRV_STRUCT* ftpsrv_create_server(FTPSRV_PARAM_STRUCT* params) { FTPSRV_STRUCT *server = NULL; uint32_t error; uint32_t error4 = FTPSRV_OK; uint32_t error6 = FTPSRV_OK; if ((server = _mem_alloc_system_zero(sizeof(FTPSRV_STRUCT))) == NULL) { return(NULL); } _mem_set_type(server, MEM_TYPE_FTPSRV_STRUCT); error = _lwsem_create(&server->tid_sem, 1); if (error != MQX_OK) { goto EXIT; } error = ftpsrv_set_params(server, params); if (error != FTPSRV_OK) { goto EXIT; } /* Allocate space for session pointers */ server->session = RTCS_mem_alloc_zero(sizeof(FTPSRV_SESSION_STRUCT*) * server->params.max_ses); if (server->session == NULL) { goto EXIT; } /* Allocate space for session task IDs */ server->ses_tid = RTCS_mem_alloc_zero(sizeof(_rtcs_taskid) * server->params.max_ses); if (server->ses_tid == NULL) { goto EXIT; } /* Init sockets. */ if (params->af & AF_INET) { /* Setup IPv4 server socket */ error4 = ftpsrv_init_socket(server, AF_INET); } if (params->af & AF_INET6) { /* Setup IPv6 server socket */ error6 = ftpsrv_init_socket(server, AF_INET6); } if ((error4 != FTPSRV_OK) || (error6 != FTPSRV_OK)) { ftpsrv_destroy_server(server); return(NULL); } server->run = 1; return(server); EXIT: ftpsrv_destroy_server(server); return(NULL); }
void TFTPSRV_service_request ( TFTPSRV_STATE_STRUCT_PTR tftpsrv_ptr /* [IN/OUT] The TFTP Server state */ ) { /* Body */ TFTP_TRANS_STRUCT_PTR trans_ptr; sockaddr_in sockaddr_t; int32_t pkt_len, i; uint32_t error; char *filename, *filemode; uint16_t sockaddrlen, pkt_op; /* receive the datagram */ sockaddrlen = sizeof(sockaddr_t); pkt_len = recvfrom(tftpsrv_ptr->SRV_SOCK, tftpsrv_ptr->BUFFER, TFTP_MAX_MESSAGE_SIZE, 0, (sockaddr *)&sockaddr_t, &sockaddrlen); if (pkt_len == RTCS_ERROR) { return; } /* Endif */ /* limit the number of concurrent transactions */ if (tftpsrv_ptr->NUM_TRANSACTIONS >= TFTPSRV_MAX_TRANSACTIONS) { TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_busy, sockaddr_t); return; } /* Endif */ /* parse the request; extract op, filename and filemode */ i = 2; filename = (char *)tftpsrv_ptr->BUFFER + i; for (; i<pkt_len; i++) { if (tftpsrv_ptr->BUFFER[i] == '\0') break; } /* Endfor */ i++; filemode = (char *)tftpsrv_ptr->BUFFER + i; for (; i<pkt_len; i++) { if (tftpsrv_ptr->BUFFER[i] == '\0') break; } /* Endfor */ if (i >= pkt_len) { TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_op, sockaddr_t); return; } /* Endif */ pkt_op = mqx_ntohs(tftpsrv_ptr->BUFFER); /* allocate state for the new transaction */ trans_ptr = RTCS_mem_alloc_zero(sizeof(TFTP_TRANS_STRUCT)); if (trans_ptr == NULL) { TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t); return; } /* Endif */ _mem_set_type(trans_ptr, MEM_TYPE_TFTP_TRANS_STRUCT); /* validate the requested operation */ switch (pkt_op) { case TFTPOP_RRQ: trans_ptr->RECV_OP = TFTPOP_ACK; trans_ptr->SEND_OP = TFTPOP_DATA; break; case TFTPOP_WRQ: trans_ptr->RECV_OP = TFTPOP_DATA; trans_ptr->SEND_OP = TFTPOP_ACK; break; default: TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_op, sockaddr_t); _mem_free(trans_ptr); return; } /* Endswitch */ /* open the requested file */ error = TFTPSRV_open_device(pkt_op, filename, filemode, &trans_ptr->TRANS_FILE_PTR); if (error) { switch (error) { case RTCS_EACCES: TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_accvio, sockaddr_t); break; case RTCS_ENOENT: TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_nofile, sockaddr_t); break; case RTCS_EEXIST: TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_exists, sockaddr_t); break; default: TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t); break; } /* Endswitch */ _mem_free(trans_ptr); return; } /* Endif */ /* create a socket for the new transaction */ trans_ptr->SOCK = socket(PF_INET, SOCK_DGRAM, 0); if (trans_ptr->SOCK == RTCS_SOCKET_ERROR) { TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t); RTCS_io_close(trans_ptr->TRANS_FILE_PTR); _mem_free(trans_ptr); return; } /* Endif */ trans_ptr->ADDR.sin_family = sockaddr_t.sin_family; trans_ptr->ADDR.sin_port = sockaddr_t.sin_port; trans_ptr->ADDR.sin_addr.s_addr = sockaddr_t.sin_addr.s_addr; sockaddr_t.sin_family = AF_INET; sockaddr_t.sin_port = 0; sockaddr_t.sin_addr.s_addr = INADDR_ANY; error = bind(trans_ptr->SOCK, (const sockaddr *)&sockaddr_t, sizeof(sockaddr_t)); if (error != RTCS_OK) { TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t); shutdown(trans_ptr->SOCK, 0); RTCS_io_close(trans_ptr->TRANS_FILE_PTR); _mem_free(trans_ptr); return; } /* Endif */ /* build the first packet */ trans_ptr->BLOCK = 0; switch (trans_ptr->SEND_OP) { case TFTPOP_DATA: TFTPSRV_build_DATA(trans_ptr); break; case TFTPOP_ACK: TFTPSRV_build_ACK(trans_ptr); trans_ptr->EXIT = FALSE; break; } /* Endswitch */ if (trans_ptr->SEND_SIZE < sizeof(TFTP_HEADER)) { TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t); shutdown(trans_ptr->SOCK, 0); RTCS_io_close(trans_ptr->TRANS_FILE_PTR); _mem_free(trans_ptr); return; } /* Endif */ /* send the first packet */ TFTPSRV_timer_start(tftpsrv_ptr, trans_ptr, TFTP_timeout_init(&trans_ptr->XMIT_TIMER)); TFTPSRV_send(trans_ptr); tftpsrv_ptr->SOCKETS[tftpsrv_ptr->NUM_TRANSACTIONS] = trans_ptr->SOCK; tftpsrv_ptr->TRANS_PTRS[tftpsrv_ptr->NUM_TRANSACTIONS] = trans_ptr; tftpsrv_ptr->NUM_TRANSACTIONS++; } /* Endbody */
static void pmap_service ( SVCREQ_PTR req, /* [IN] - RPC request */ SVCXPRT_PTR xprt /* [IN] - transport handle */ ) { /* Body */ PMAP arg; uint_32 res; PMAPLIST_PTR pml; PMAPLIST_PTR _PTR_ p; switch (req->rq_proc) { case PMAPPROC_NULL: svc_sendreply(xprt, xdr_void, NULL); break; case PMAPPROC_SET: if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (caddr_t)&arg)) { svcerr_decode(xprt); } else { /* ** Scan list for existing (prog,vers,prot) entry. */ res = FALSE; for (p = &pml_head; *p != NULL; p = &(*p)->pml_next) { if (((*p)->pml_map.pm_prog == arg.pm_prog) && ((*p)->pml_map.pm_vers == arg.pm_vers) && ((*p)->pml_map.pm_prot == arg.pm_prot)) { /* ** Found -- if the port matches, there's no work to be done. ** If the port doesn't match, we can't satisfy the request. ** Either way, we exit the loop and *p is non-NULL. */ if ((*p)->pml_map.pm_port == arg.pm_port) { res = TRUE; } /* Endif */ break; } /* Endif */ } /* Endfor */ /* ** If there was no entry for (prog,vers,prot), create one ** at end of list. */ if (*p == NULL) { pml = (PMAPLIST_PTR)RTCS_mem_alloc_zero(sizeof(PMAPLIST)); if (pml != NULL) { pml->pml_map = arg; pml->pml_next = NULL; *p = pml; res = TRUE; } /* Endif */ } /* Endif */ /* ** Reply to client */ svc_sendreply(xprt, (xdrproc_t)xdr_uint_32, (pointer)&res); } /* Endif */ break; case PMAPPROC_UNSET: if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (caddr_t)&arg)) { svcerr_decode(xprt); } else { /* ** Scan list for all (prog,vers) entries. */ res = FALSE; for (p = &pml_head; *p != NULL;) { if (((*p)->pml_map.pm_prog == arg.pm_prog) && ((*p)->pml_map.pm_vers == arg.pm_vers)) { /* ** Found -- unlink and free it. */ res = TRUE; pml = *p; *p = pml->pml_next; _mem_free(pml); } else { p = &(*p)->pml_next; } /* Endif */ } /* Endfor */ /* ** Reply to client */ svc_sendreply(xprt, (xdrproc_t)xdr_uint_32, (pointer)&res); } /* Endif */ break; case PMAPPROC_GETPORT: if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (caddr_t)&arg)) { svcerr_decode(xprt); } else { /* ** Scan list for (prog,prot) entries. */ res = 0; for (pml = pml_head; pml != NULL; pml = pml->pml_next) { if ((pml->pml_map.pm_prog == arg.pm_prog) && (pml->pml_map.pm_prot == arg.pm_prot)) { /* ** Found -- get the port, even if the version doesn't match. */ res = pml->pml_map.pm_port; if (pml->pml_map.pm_vers == arg.pm_vers) { break; } /* Endif */ } /* Endif */ } /* Endfor */ /* ** Reply to client */ svc_sendreply(xprt, (xdrproc_t)xdr_uint_32, (pointer)&res); } /* Endif */ break; case PMAPPROC_DUMP: if (!svc_getargs(xprt, xdr_void, (caddr_t)NULL)) { svcerr_decode(xprt); } else { svc_sendreply(xprt, (xdrproc_t)xdr_pmaplist, (pointer)&pml_head); } /* Endif */ break; default: svcerr_noproc(xprt); break; } /* Endswitch */ } /* Endbody */
int32_t ftpsrv_list(FTPSRV_SESSION_STRUCT* session) { int32_t length; char* path; void* dir_ptr; uint32_t sock; char* dir_param; char* full_path; char* temp; uint32_t path_length; uint32_t wrong_path; if (session->cmd_arg == NULL) { path = ""; } else { rtcs_url_decode(session->cmd_arg); path = rtcs_path_strip_delimiters(session->cmd_arg); } /* Translate relative path to absolute. */ full_path = ftpsrv_get_full_path(session, path, &wrong_path); if (full_path == NULL) { if (wrong_path) { session->message = (char*) ftpsrvmsg_no_file; } else { session->message = (char*) ftpsrvmsg_no_memory; } return(FTPSRV_ERROR); } path_length = strlen(full_path); /* Allocate space for path + appendix, copy full path and add appendix to it. */ /* This is required because MFS cannot list directories, only files. */ temp = RTCS_mem_alloc_zero(path_length+sizeof(FTPSRV_PATH_APPENDIX)); _mem_copy(full_path, temp, path_length); _mem_copy(FTPSRV_PATH_APPENDIX, temp+path_length, sizeof(FTPSRV_PATH_APPENDIX)-1); _mem_free(full_path); full_path = temp; /* Open directory. Unix format for LIST command, simple file list for NLIST. */ if (!strcmp(session->command, "LIST")) { /* Unix */ dir_param = "u*"; } else { /* File list */ dir_param = "f*"; } /* Open directory, get list, cleanup and return. */ dir_ptr = _io_mfs_dir_open(session->fs_ptr, full_path, dir_param); if (dir_ptr == NULL) { session->message = (char*) ftpsrvmsg_no_file; return(FTPSRV_ERROR); } /* Send initialization message */ ftpsrv_send_msg(session, ftpsrvmsg_opening_datacon); /* Open data connection */ sock = ftpsrv_open_data_connection(session); if (sock == RTCS_SOCKET_ERROR) { session->message = (char*) ftpsrvmsg_locerr; _mem_free(full_path); _io_mfs_dir_close(dir_ptr); return(FTPSRV_ERROR); } /* Send data (directory listing). */ while ((length = _io_mfs_dir_read(dir_ptr, session->buffer, FTPSRV_BUF_SIZE)) > 0) { /* If we are in root do not list "one level up" nor "current dir" link */ if ((strstr(session->buffer, " .. ") || strstr(session->buffer, " . ")) && !strcmp(session->cur_dir, "\\")) { _mem_zero(session->buffer, length); } else { if (send(sock, session->buffer, length, 0) != length) { ftpsrv_send_msg(session, ftpsrvmsg_writefail); break; } } } /* Cleanup */ closesocket(sock); _io_mfs_dir_close(dir_ptr); _mem_free(full_path); session->message = (char*) ftpsrvmsg_trans_complete; return FTPSRV_OK; }