static void DNS_init_unwind ( DNS_CONTROL_STRUCT *control_ptr, uint32_t sock ) { /* Body */ RTCS_setcfg(DNS, NULL); if (sock) shutdown(sock, 0); if (control_ptr) { if (control_ptr->CNAME_PARTID) RTCS_part_destroy(control_ptr->CNAME_PARTID); if (control_ptr->RR_LIST_PARTID) RTCS_part_destroy(control_ptr->RR_LIST_PARTID); if (control_ptr->NAME_RR_PARTID) RTCS_part_destroy(control_ptr->NAME_RR_PARTID); if (control_ptr->INT_QUERY_PARTID) RTCS_part_destroy(control_ptr->INT_QUERY_PARTID); if (control_ptr->ADDR_RR_PARTID) RTCS_part_destroy(control_ptr->ADDR_RR_PARTID); _mem_free(control_ptr); } return; } /* Endbody */
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 */
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 */
static uint_32 NAT_init_internal2 ( NAT_PARM_PTR parm_ptr /* [IN] Initialization parameters */ ) { /* Body */ NAT_CFG_STRUCT_PTR nat_cfg_ptr = RTCS_getcfg(NAT); uint_32 error; /* ** Make sure the netmask is valid. We use the fact that ** (x & x+1) == 0 <=> x = 2^n-1. */ if (~parm_ptr->IP_MASK & (~parm_ptr->IP_MASK + 1)) { return RTCSERR_INVALID_PARAMETER; } /* Endif */ /* Make sure other parameters have been supplied */ if (!parm_ptr->IP_PRV) { return RTCSERR_INVALID_PARAMETER; } /* Endif */ /* ** If the configuration structure has already been allocated, ** just add another private network and return */ if (nat_cfg_ptr) { error = NAT_add_private_network(&nat_cfg_ptr->PRIVATE_NETWORKS, parm_ptr->IP_PRV, parm_ptr->IP_MASK); if (error == RTCS_OK) { nat_cfg_ptr->NAT_EXEC = NAT_apply; } return error; } /* Endif */ // First time through the initialization, // Allocate the NAT configuration structure nat_cfg_ptr = _mem_alloc_system_zero(sizeof(NAT_CFG_STRUCT)); if (nat_cfg_ptr == NULL) { return RTCSERR_OUT_OF_MEMORY; } /* Endif */ /* Record the private network information */ error = NAT_add_private_network(&nat_cfg_ptr->PRIVATE_NETWORKS, parm_ptr->IP_PRV, parm_ptr->IP_MASK); if (error == RTCS_OK) { nat_cfg_ptr->NAT_EXEC = NAT_apply; nat_cfg_ptr->INITIAL_PRV_NET = parm_ptr->IP_PRV; nat_cfg_ptr->INITIAL_PRV_MASK = parm_ptr->IP_MASK; nat_cfg_ptr->TCP_TOUT.PRIVATE = &nat_cfg_ptr->TCP_HEAD; nat_cfg_ptr->UDP_TOUT.PRIVATE = &nat_cfg_ptr->UDP_HEAD; nat_cfg_ptr->FIN_TOUT.PRIVATE = &nat_cfg_ptr->FIN_HEAD; nat_cfg_ptr->ICMP_TOUT.PRIVATE = &nat_cfg_ptr->ICMP_HEAD; /* Initialize radix trees */ IPRADIX_init(&nat_cfg_ptr->ROOT_IN); IPRADIX_init(&nat_cfg_ptr->ROOT_OUT); /* Initialize timeout functions */ nat_cfg_ptr->UDP_TOUT.EVENT = NAT_expire; nat_cfg_ptr->TCP_TOUT.EVENT = NAT_expire; nat_cfg_ptr->FIN_TOUT.EVENT = NAT_expire; nat_cfg_ptr->ICMP_TOUT.EVENT = NAT_expire; nat_cfg_ptr->TIMEOUT_TCP = NAT_DEFAULT_TIMEOUT_TCP; nat_cfg_ptr->TIMEOUT_UDP = NAT_DEFAULT_TIMEOUT_UDP; nat_cfg_ptr->TIMEOUT_FIN = NAT_DEFAULT_TIMEOUT_FIN; nat_cfg_ptr->TIMEOUT_ICMP = NAT_DEFAULT_TIMEOUT_ICMP; /* Initialize last used port numbers */ nat_cfg_ptr->TCP_PORT = NAT_DEFAULT_PORT_MIN; nat_cfg_ptr->UDP_PORT = NAT_DEFAULT_PORT_MIN; nat_cfg_ptr->ICMP_ID = NAT_DEFAULT_PORT_MIN; nat_cfg_ptr->PORT_MAX = NAT_DEFAULT_PORT_MAX; nat_cfg_ptr->PORT_MIN = NAT_DEFAULT_PORT_MIN; /* Inititalize ALGs */ error = NAT_init_algs(nat_cfg_ptr); } /* Allocate partitions */ if (error == RTCS_OK) { nat_cfg_ptr->SESSION_PART = RTCS_part_create(sizeof(NAT_SESSION_STRUCT), NAT_SESSION_INITIAL_COUNT, NAT_SESSION_GROW_COUNT, NAT_SESSION_MAX, NULL, NULL); if (nat_cfg_ptr->SESSION_PART == NULL) { error = RTCSERR_OUT_OF_MEMORY; } /* Endif */ } /* Endif */ if (error == RTCS_OK) { nat_cfg_ptr->RADIX_IN = RTCS_part_create(sizeof(IPRADIX_NODE), NAT_SESSION_INITIAL_COUNT, NAT_SESSION_GROW_COUNT, NAT_SESSION_MAX, NULL, NULL); if (nat_cfg_ptr->RADIX_IN == NULL) { error = RTCSERR_OUT_OF_MEMORY; } /* Endif */ } /* Endif */ if (error == RTCS_OK) { nat_cfg_ptr->RADIX_OUT = RTCS_part_create(sizeof(IPRADIX_NODE), NAT_SESSION_INITIAL_COUNT, NAT_SESSION_GROW_COUNT, NAT_SESSION_MAX, NULL, NULL); if (nat_cfg_ptr->RADIX_OUT == NULL) { error = RTCSERR_OUT_OF_MEMORY; } /* Endif */ } /* Endif */ if (error == RTCS_OK) { // Initialize queue of DNAT Rules _queue_init( &nat_cfg_ptr->RULE_QUEUE, 0 ); RTCS_setcfg(NAT, nat_cfg_ptr); } else { if (nat_cfg_ptr != NULL) { if (nat_cfg_ptr->RADIX_IN != NULL) RTCS_part_destroy(nat_cfg_ptr->RADIX_IN); if (nat_cfg_ptr->RADIX_OUT != NULL) RTCS_part_destroy(nat_cfg_ptr->RADIX_OUT); if (nat_cfg_ptr->SESSION_PART != NULL) RTCS_part_destroy(nat_cfg_ptr->SESSION_PART); _mem_free(nat_cfg_ptr); } } /* Endif */ return error; } /* Endbody */
uint32_t DNS_init ( void ) { /* Body */ DNS_CONTROL_STRUCT *control_ptr = RTCS_getcfg(DNS); uint32_t temp_socket = 0; int32_t error; if (control_ptr != NULL) { return RTCS_OK; } /* ** Please note, if this is modified to use a value other than ** DNS_MAX_UDP_MESSAGE_SIZE, the recvfrom() in the DNS_Resolver_task ** will need to be modified as well, as they rely on this constant. */ control_ptr = RTCS_mem_alloc_system_zero(sizeof(DNS_CONTROL_STRUCT)+DNS_MAX_UDP_MESSAGE_SIZE); if (control_ptr == NULL) { return RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY; } /* Endif */ _mem_set_type(control_ptr, MEM_TYPE_DNS_CONTROL_STRUCT); RTCS_setcfg(DNS, control_ptr); temp_socket = socket(PF_INET, SOCK_DGRAM, 0); if (temp_socket == RTCS_HANDLE_ERROR) { DNS_init_unwind(control_ptr, temp_socket); return RTCSERR_DNS_UNABLE_TO_OPEN_SOCKET; } /* Endif */ error = RTCS_detachsock(temp_socket); if (error != RTCS_OK) { DNS_init_unwind(control_ptr, temp_socket); return error; } /* Endif */ control_ptr->INT_QUERY_PARTID = RTCS_part_create( sizeof(DNS_INTERNAL_QUERY_STRUCT), DNSALLOC_SIZE, DNSALLOC_SIZE, 0, NULL, NULL); if (control_ptr->INT_QUERY_PARTID == 0) { DNS_init_unwind(control_ptr, temp_socket); return RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION; } /* Endif */ control_ptr->ADDR_RR_PARTID = RTCS_part_create( sizeof(DNS_ADDR_RECORD_STRUCT), DNSALLOC_SIZE, DNSALLOC_SIZE, 0, NULL, NULL); if (control_ptr->ADDR_RR_PARTID == 0) { DNS_init_unwind(control_ptr, temp_socket); return RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION; } /* Endif */ control_ptr->NAME_RR_PARTID = RTCS_part_create( sizeof(DNS_NAME_RECORD_STRUCT), DNSALLOC_SIZE, DNSALLOC_SIZE, 0, NULL, NULL); if (control_ptr->NAME_RR_PARTID == 0) { DNS_init_unwind(control_ptr, temp_socket); return RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION; } /* Endif */ control_ptr->RR_LIST_PARTID = RTCS_part_create( sizeof(DNS_RR_LIST_STRUCT), DNSALLOC_SIZE, DNSALLOC_SIZE, 0, NULL, NULL); if (control_ptr->RR_LIST_PARTID == 0) { DNS_init_unwind(control_ptr, temp_socket); return RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION; } /* Endif */ control_ptr->CNAME_PARTID = RTCS_part_create( sizeof(DNS_CNAME_STRUCT), DNSALLOC_SIZE, DNSALLOC_SIZE, 0, NULL, NULL); if (control_ptr->CNAME_PARTID == 0) { DNS_init_unwind(control_ptr, temp_socket); return RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION; } /* Endif */ control_ptr->ROOT_SLIST_PTR = DNS_A_Root_server; control_ptr->LOCAL_SLIST_PTR = DNS_First_Local_server; control_ptr->NS_BUFFER = NULL; control_ptr->RES_BUFFER = (unsigned char *)(control_ptr + 1); control_ptr->RES_SOCKET = temp_socket; control_ptr->UPDATING = FALSE; error = RTCS_mutex_init(&control_ptr->CACHE_MUTEX); if (error != RTCS_OK) { DNS_init_unwind(control_ptr, temp_socket); return error; } /* Endif */ error = RTCS_mutex_init(&control_ptr->SLIST_MUTEX); if (error != RTCS_OK) { DNS_init_unwind(control_ptr, temp_socket); return error; } /* Endif */ error = RTCS_task_create("DNS Resolver", _RTCSTASK_priority, _RTCSTASK_stacksize + 500 * sizeof(uint32_t), DNS_Resolver_task, control_ptr); if (error) { DNS_init_unwind(control_ptr, temp_socket); return error; } /* Endif */ return RTCS_OK; } /* Endbody */
void TCPIP_task ( void *dummy, void *creator ) { /* Body */ TCPIP_CFG_STRUCT TCPIP_cfg; RTCS_DATA_PTR RTCS_data_ptr; uint32_t i; TCPIP_MESSAGE_PTR tcpip_msg; uint32_t timeout = 1, timebefore, timeafter, timedelta; uint32_t status; /* Return status */ _queue_id tcpip_qid; RTCSLOG_FNE2(RTCSLOG_FN_TCPIP_task, creator); RTCS_data_ptr = RTCS_get_data(); RTCS_setcfg(TCPIP, &TCPIP_cfg); TCPIP_cfg.status = RTCS_OK; tcpip_qid = RTCS_msgq_open(TCPIP_QUEUE, 0); if (tcpip_qid == 0) { RTCS_task_exit(creator, RTCSERR_OPEN_QUEUE_FAILED); } /* Endif */ RTCS_data_ptr->TCPIP_TASKID = RTCS_task_getid(); /* ** Initialize the Time Service */ TCP_tick = TCPIP_fake_tick; TCPIP_Event_init(); timebefore = RTCS_time_get(); /* ** Allocate a block of PCBs */ status = RTCSPCB_init(); if (status != RTCS_OK) { RTCS_task_exit(creator, status); } /* Endif */ IF_FREE = NULL; /* ** Initialize the protocols */ #if RTCSCFG_ENABLE_IP4 /********************************************* * Initialize IPv4 **********************************************/ status = IP_init(); if (status) { RTCS_task_exit(creator, status); } #if RTCSCFG_ENABLE_ICMP status = ICMP_init(); if (status) { RTCS_task_exit(creator, status); } #endif /* RTCSCFG_ENABLE_ICMP */ ARP_init(); BOOT_init(); #endif /* RTCSCFG_ENABLE_IP4 */ #if RTCSCFG_ENABLE_IP6 /********************************************* * Initialize IPv6 **********************************************/ status = IP6_init(); if (status) { RTCS_task_exit(creator, status); } /* Init ICMP6. */ status = ICMP6_init(); //TBD Add it to RTCS6_protocol_table if (status) { RTCS_task_exit(creator, status); } #endif /* RTCSCFG_ENABLE_IP6*/ #if (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4) || (RTCSCFG_ENABLE_IP6_REASSEMBLY && RTCSCFG_ENABLE_IP6) /* Initialize the reassembler */ status = IP_reasm_init(); if (status) { RTCS_task_exit(creator, status); } #endif /* Add loopback interface.*/ status = IPLOCAL_init (); if (status) { RTCS_task_exit(creator, status); }; for (i = 0; RTCS_protocol_table[i]; i++) { status = (*RTCS_protocol_table[i])(); if (status) { RTCS_task_exit(creator, status); } /* Endif */ } /* Endfor */ _RTCS_initialized= TRUE; RTCS_task_resume_creator(creator, RTCS_OK); while (1) { TCPIP_EVENT_PTR queue = TCPIP_Event_head; tcpip_msg = (TCPIP_MESSAGE_PTR)RTCS_msgq_receive(tcpip_qid, timeout, RTCS_data_ptr->TCPIP_msg_pool); if (tcpip_msg) { if (NULL != tcpip_msg->COMMAND) { tcpip_msg->COMMAND(tcpip_msg->DATA); } RTCS_msg_free(tcpip_msg); } timeout = TCP_tick(); timeafter = RTCS_time_get(); /* If head changed set time delta to zero to prevent immidiate event */ if (queue == TCPIP_Event_head) { timedelta = RTCS_timer_get_interval(timebefore, timeafter); } else { timedelta = 0; } timebefore = timeafter; timedelta = TCPIP_Event_time(timedelta); if (timedelta != 0) { if ((timedelta < timeout) || (timeout == 0)) { timeout = timedelta; } } } } /* Endbody */
uint_32 RTCS_create ( void ) { /* Body */ RTCS_DATA_PTR RTCS_data_ptr; SOCKET_CONFIG_STRUCT_PTR socket_cfg_ptr; uint_32 error; /* ** Check and see if this is the first time we have initialized, */ if (RTCS_get_data() != NULL) { return RTCSERR_INITIALIZED; } // RTCS_data_ptr = RTCS_mem_alloc_system_zero(sizeof(RTCS_DATA)); if (RTCS_data_ptr == NULL) { error = RTCSERR_OUT_OF_MEMORY; } else { _mem_set_type(RTCS_data_ptr, MEM_TYPE_RTCS_DATA); RTCS_set_data(RTCS_data_ptr); /* ** Initialize socket state */ socket_cfg_ptr = RTCS_mem_alloc_system_zero(sizeof(SOCKET_CONFIG_STRUCT)); if (socket_cfg_ptr == NULL) { error = RTCSERR_OUT_OF_MEMORY; } else { _mem_set_type(socket_cfg_ptr, MEM_TYPE_SOCKET_CONFIG_STRUCT); socket_cfg_ptr->INITIALIZED = TRUE; socket_cfg_ptr->SOCKET_HEAD = NULL; socket_cfg_ptr->SOCKET_TAIL = NULL; RTCS_mutex_init(&socket_cfg_ptr->SOCK_MUTEX); RTCS_setcfg(SOCKET, socket_cfg_ptr); /* ** Initialize global data */ _IP_forward = FALSE; _TCP_bypass_rx = FALSE; _TCP_bypass_tx = FALSE; RTCS_data_ptr->VERSION = RTCS_VERSION; #if RTCSCFG_LOG_SOCKET_API||RTCSCFG_LOG_PCB RTCS_data_ptr->RTCS_LOG_PROTCOUNT = RTCSLOG_PROT_MAX; RTCSLOG_disable(RTCS_LOGCTRL_ALL); #endif RTCS_data_ptr->TCPIP_qid = RTCS_msgq_get_id(0,TCPIP_QUEUE); /* ** Create a pool of buffers for use in communicating to the TCP/IP task. */ RTCS_data_ptr->TCPIP_msg_pool = RTCS_msgpool_create(sizeof(TCPIP_MESSAGE), _RTCS_msgpool_init, _RTCS_msgpool_grow, _RTCS_msgpool_max); if (RTCS_data_ptr->TCPIP_msg_pool == MSGPOOL_NULL_POOL_ID) { RTCS_log_error( ERROR_TCPIP, RTCSERR_CREATE_POOL_FAILED, 0, 0, 0); error = RTCSERR_CREATE_POOL_FAILED; } else { /* ** Create the socket partition */ RTCS_data_ptr->RTCS_socket_partition = RTCS_part_create(sizeof(SOCKET_STRUCT), _RTCS_socket_part_init, _RTCS_socket_part_grow, _RTCS_socket_part_max, NULL, NULL); if (RTCS_data_ptr->RTCS_socket_partition == 0) { RTCS_log_error(ERROR_RTCS, RTCSERR_CREATE_PARTITION_FAILED, 0, 0, 0); error = RTCSERR_CREATE_PARTITION_FAILED; } else { /* ** Create TCPIP task */ error = RTCS_task_create("TCP/IP", _RTCSTASK_priority, _RTCSTASK_stacksize, TCPIP_task, NULL); if (error) { RTCS_part_destroy(RTCS_data_ptr->RTCS_socket_partition); } } if (error) { RTCS_msgpool_destroy( RTCS_data_ptr->TCPIP_msg_pool ); } } if (error) { RTCS_setcfg(SOCKET, NULL); _mem_free(socket_cfg_ptr); } } if (error) { RTCS_set_data(NULL); _mem_free(RTCS_data_ptr); } } return error; } /* Endbody */