uint_32 DHCPSRV_ippool_add ( _ip_address ipstart, uint_32 ipnum, DHCPSRV_DATA_STRUCT_PTR params, uchar_ptr optptr, uint_32 optlen ) { /* Body */ DHCPSRV_OPTIONS_STRUCT_PTR options; DHCPSRV_ADDR_STRUCT_PTR addr; uchar_ptr moreoptions = NULL; options = RTCS_mem_alloc_system(sizeof(DHCPSRV_OPTIONS_STRUCT) + optlen); if (!options) { return RTCSERR_OUT_OF_MEMORY; } /* Endif */ _mem_set_type(options, MEM_TYPE_DHCPSRV_OPTIONS_STRUCT); moreoptions = (uchar_ptr)(options+1); _mem_copy(optptr, moreoptions, optlen); options->COUNT = 0; options->SERVERID = params->SERVERID; options->LEASE = params->LEASE; options->MASK = params->MASK; options->OPTION_PTR = moreoptions; options->OPTION_LEN = optlen; options->SADDR = params->SADDR; _mem_copy(params->SNAME, options->SNAME, sizeof(options->SNAME) - 1); options->SNAME[sizeof(options->SNAME) - 1] = '\0'; _mem_copy(params->FILE, options->FILE, sizeof(options->FILE) - 1); options->FILE[sizeof(options->FILE) - 1] = '\0'; RTCS_mutex_lock(&DHCPSRV_cfg->IPLIST_SEM); for (; ipnum; ipnum--, ipstart++) { addr = RTCS_mem_alloc_system(sizeof(DHCPSRV_ADDR_STRUCT)); if (!addr) { if (options->COUNT == 0) { _mem_free(options); } /* Endif */ RTCS_mutex_unlock(&DHCPSRV_cfg->IPLIST_SEM); return RTCSERR_OUT_OF_MEMORY; } /* Endif */ _mem_set_type(options, MEM_TYPE_DHCPSRV_ADDR_STRUCT); addr->CLIENTID_LEN = 0; addr->CLIENTID_PTR = NULL; addr->IP_ADDR = ipstart; addr->OPTIONS = options; options->COUNT++; DHCPSRV_lease_start(&DHCPSRV_cfg->IP_AVAIL, addr, 0); } /* Endfor */ RTCS_mutex_unlock(&DHCPSRV_cfg->IPLIST_SEM); return RTCS_OK; } /* Endbody */
void SOCK_Free_sock_struct ( SOCKET_STRUCT_PTR socket_ptr ) { /* Body */ SOCKET_CONFIG_STRUCT_PTR socket_cfg_ptr = RTCS_getcfg(SOCKET); #if RTCSCFG_SOCKET_OWNERSHIP //FSL AB SOCKET_OWNER_STRUCT_PTR owner_ptr; SOCKET_OWNER_STRUCT_PTR free_ptr; #endif socket_ptr->VALID = 0; #if RTCSCFG_SOCKET_OWNERSHIP owner_ptr = socket_ptr->OWNERS.NEXT; while (owner_ptr != NULL) { free_ptr = owner_ptr; owner_ptr = owner_ptr->NEXT; _mem_free(free_ptr); } /* Endwhile */ #endif RTCS_mutex_lock(&socket_cfg_ptr->SOCK_MUTEX); /* ** Fix up the head/next pointer of our predecessor. */ if ( socket_ptr->PREV == NULL ) { socket_cfg_ptr->SOCKET_HEAD = socket_ptr->NEXT; } else { (socket_ptr->PREV)->NEXT = socket_ptr->NEXT; } /* Endif */ /* ** Fix up the tail/prev pointer of our successor. */ if ( socket_ptr->NEXT == NULL ) { socket_cfg_ptr->SOCKET_TAIL = socket_ptr->PREV; } else { (socket_ptr->NEXT)->PREV = socket_ptr->PREV; } /* Endif */ /* ** Release the socket structure memory. */ RTCS_part_free(socket_ptr); socket_cfg_ptr->CURRENT_SOCKETS--; RTCS_mutex_unlock(&socket_cfg_ptr->SOCK_MUTEX); } /* Endbody */
static uint_32 DHCPSRV_set_config_flag_off ( uint_32 flags /* [IN] flags to govern behaviour of dhcp server */ ) { /* Body */ RTCS_mutex_lock(&DHCPSRV_cfg->IPLIST_SEM); DHCPSRV_cfg->FLAGS &= !flags; RTCS_mutex_unlock(&DHCPSRV_cfg->IPLIST_SEM); return RTCS_OK; } /* Endbody */
static void DHCPSRV_service_request ( DHCPSRV_STATE_STRUCT_PTR state ) { /* Body */ uchar_ptr inp, cid_ptr, sid_ptr, lease_ptr; uint_32 inlen, cid_len; _ip_address serverid = 0; uint_32 lease = 0; DHCPSRV_ADDR_STRUCT_PTR addr; DHCPSRV_ADDR_STRUCT_PTR _PTR_ addrp; /* Start CR 1599 */ boolean reply=FALSE; /* End CR 1599 */ inp = state->RCV_BUFFER + sizeof(DHCP_HEADER) + 4; inlen = state->RCV_BUFFER_LEN - sizeof(DHCP_HEADER) - 4; /* Get the client ID; use CHADDR if none */ cid_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_CLIENTID); if (cid_ptr) { cid_ptr++; cid_len = ntohc(cid_ptr); cid_ptr++; } else { DHCP_HEADER_PTR pkt_ptr = (DHCP_HEADER_PTR)state->RCV_BUFFER; cid_ptr = pkt_ptr->CHADDR; cid_len = ntohc(pkt_ptr->HLEN); if (cid_len > sizeof(pkt_ptr->CHADDR)) { cid_len = sizeof(pkt_ptr->CHADDR); } /* Endif */ } /* Endif */ /* Get the server ID */ sid_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_SERVERID); if (sid_ptr && ntohc(sid_ptr+1) == DHCPSIZE_SERVERID) { sid_ptr += 2; serverid = ntohl(sid_ptr); } else { sid_ptr = NULL; } /* Endif */ /* Get the requested lease */ lease_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_LEASE); if (lease_ptr && ntohc(lease_ptr+1) == DHCPSIZE_LEASE) { lease_ptr += 2; lease = ntohl(lease_ptr); } else { lease_ptr = NULL; } /* Endif */ addrp = NULL; RTCS_mutex_lock(&state->IPLIST_SEM); if (!addrp) { addrp = DHCPSRV_find_clientid(&state->IP_LEASED, cid_ptr, cid_len, NULL); } /* Endif */ if (!addrp && sid_ptr) { addrp = DHCPSRV_find_clientid(&state->IP_OFFERED, cid_ptr, cid_len, NULL); } /* Endif */ /* Start CR 2089 */ /* check whether any available address was previously offered/leased to the client */ if (!addrp) { addrp = DHCPSRV_find_clientid(&state->IP_AVAIL, cid_ptr, cid_len, NULL); } /* Endif */ /* End CR 2089 */ if (addrp) { if (sid_ptr && serverid != (*addrp)->OPTIONS->SERVERID) { reply = FALSE; addr = DHCPSRV_lease_stop(addrp); DHCPSRV_lease_start(&state->IP_AVAIL, addr, 0); } else if (lease_ptr && lease > (*addrp)->OPTIONS->LEASE) { DHCPSRV_write_header(state, NULL, 0, DHCPTYPE_DHCPNAK); DHCPSRV_write_end(state); reply = TRUE; } else { if (!lease_ptr) { lease = (*addrp)->OFFER; } /* Endif */ DHCPSRV_write_header (state, *addrp, lease, DHCPTYPE_DHCPACK); DHCPSRV_write_options(state, *addrp); DHCPSRV_write_end (state); reply = TRUE; addr = DHCPSRV_lease_stop(addrp); DHCPSRV_lease_start(&state->IP_LEASED, addr, lease); } /* Endif */ } /* Endif */ RTCS_mutex_unlock(&state->IPLIST_SEM); if (reply) { DHCPSRV_send(state); } /* Endif */ } /* Endbody */
static void DHCPSRV_service_discover ( DHCPSRV_STATE_STRUCT_PTR state ) { /* Body */ uchar_ptr inp, cid_ptr, opt_ptr; uint_32 inlen, cid_len; DHCPSRV_ADDR_STRUCT_PTR addr; DHCPSRV_ADDR_STRUCT_PTR _PTR_ addrp; uint_32 time, lease; boolean leased, avail, newcid; inp = state->RCV_BUFFER + sizeof(DHCP_HEADER) + 4; inlen = state->RCV_BUFFER_LEN - sizeof(DHCP_HEADER) - 4; /* Get the client ID; use CHADDR if none */ cid_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_CLIENTID); if (cid_ptr) { cid_ptr++; cid_len = ntohc(cid_ptr); cid_ptr++; } else { DHCP_HEADER_PTR pkt_ptr = (DHCP_HEADER_PTR)state->RCV_BUFFER; cid_ptr = pkt_ptr->CHADDR; cid_len = ntohc(pkt_ptr->HLEN); if (cid_len > sizeof(pkt_ptr->CHADDR)) { cid_len = sizeof(pkt_ptr->CHADDR); } /* Endif */ } /* Endif */ addrp = NULL; RTCS_mutex_lock(&state->IPLIST_SEM); /* First check whether the client already has a lease */ if (!addrp) { addrp = DHCPSRV_find_clientid(&state->IP_LEASED, cid_ptr, cid_len, &time); leased = TRUE; avail = FALSE; newcid = FALSE; } /* Endif */ /* Next check whether the client has been offered a lease */ if (!addrp) { addrp = DHCPSRV_find_clientid(&state->IP_OFFERED, cid_ptr, cid_len, &time); leased = FALSE; avail = FALSE; newcid = FALSE; } /* Endif */ /* Next check whether any available address was previously offered/leased to the client */ if (!addrp) { addrp = DHCPSRV_find_clientid(&state->IP_AVAIL, cid_ptr, cid_len, NULL); leased = FALSE; avail = TRUE; newcid = FALSE; } /* Endif */ /* Next check whether the client's requested address is available */ if (!addrp) { _ip_address reqaddr; opt_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_ADDRESS); if (opt_ptr && ntohc(opt_ptr+1) == DHCPSIZE_ADDRESS) { reqaddr = ntohl(opt_ptr+2); } else { DHCP_HEADER_PTR pkt_ptr = (DHCP_HEADER_PTR)state->RCV_BUFFER; reqaddr = ntohl(pkt_ptr->CIADDR); } /* Endif */ addrp = DHCPSRV_find_addr(&state->IP_AVAIL, reqaddr); leased = FALSE; avail = TRUE; newcid = TRUE; } /* Endif */ /* Finally, offer the first available address */ if (!addrp) { if (state->IP_AVAIL) { addrp = &state->IP_AVAIL; } /* Endif */ leased = FALSE; avail = TRUE; newcid = TRUE; } /* Endif */ if (newcid && addrp) { addrp = DHCPSRV_update_clientid(addrp, cid_ptr, cid_len); } /* Endif */ if (addrp) { /* Determine length of offer */ opt_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_LEASE); if (opt_ptr && ntohc(opt_ptr+1) == DHCPSIZE_LEASE) { lease = ntohl(opt_ptr+2); if (lease > (*addrp)->OPTIONS->LEASE) { lease = (*addrp)->OPTIONS->LEASE; } /* Endif */ } else if (leased) { lease = time; } else { lease = (*addrp)->OPTIONS->LEASE; } /* Endif */ (*addrp)->OFFER = lease; DHCPSRV_write_header (state, *addrp, lease, DHCPTYPE_DHCPOFFER); DHCPSRV_write_options(state, *addrp); DHCPSRV_write_end (state); /* Start CR 1547 */ /* probe the address to see if it is already taken (if so configured) */ if (addrp && DHCPSRV_cfg->FLAGS & DHCPSVR_FLAG_DO_PROBE) { uint_32 timeout = 50; /* miliseconds */ uint_32 error; /* note: this will hang the dhserver application while we await the probe result */ error = RTCS_ping((*addrp)->IP_ADDR, &timeout, 0xFACE); if (error == RTCS_OK) { /* bad news: someone answered this ping, we can't use this address */ addr = DHCPSRV_lease_stop(addrp); DHCPSRV_lease_start(&state->IP_TAKEN, addr, DHCPTIME_OFFER); avail = FALSE; /* nak this discover, client will send us another */ DHCPSRV_write_header(state, NULL, 0, DHCPTYPE_DHCPNAK); DHCPSRV_write_end(state); } } /* End CR 1547 */ /* Reserve the offer for at least DHCPTIME_OFFER */ if (avail) { addr = DHCPSRV_lease_stop(addrp); DHCPSRV_lease_start(&state->IP_OFFERED, addr, DHCPTIME_OFFER); } else if (time < DHCPTIME_OFFER) { DHCPSRV_lease_extend(addrp, DHCPTIME_OFFER - time); } /* Endif */ } else { DHCPSRV_write_header(state, NULL, 0, DHCPTYPE_DHCPNAK); DHCPSRV_write_end(state); } /* Endif */ RTCS_mutex_unlock(&state->IPLIST_SEM); DHCPSRV_send(state); } /* Endbody */
static uint_32 DHCPSRV_expire ( DHCPSRV_STATE_STRUCT_PTR state ) { /* Body */ DHCPSRV_ADDR_STRUCT_PTR addr; TIME_STRUCT time; uint_32 elapsed; RTCS_mutex_lock(&state->IPLIST_SEM); _time_get(&time); /* Expire offers */ elapsed = time.SECONDS - state->TIME; while (state->IP_OFFERED) { if (state->IP_OFFERED->EXPIRE > elapsed) { state->IP_OFFERED->EXPIRE -= elapsed; break; } /* Endif */ addr = state->IP_OFFERED; state->IP_OFFERED = addr->NEXT; elapsed -= addr->EXPIRE; DHCPSRV_lease_start(&state->IP_AVAIL, addr, 0); } /* Endwhile */ /* Expire leases */ elapsed = time.SECONDS - state->TIME; while (state->IP_LEASED && state->IP_LEASED->EXPIRE < DHCP_LEASE_INFINITE) { if (state->IP_LEASED->EXPIRE > elapsed) { state->IP_LEASED->EXPIRE -= elapsed; break; } /* Endif */ addr = state->IP_LEASED; state->IP_LEASED = addr->NEXT; elapsed -= addr->EXPIRE; DHCPSRV_lease_start(&state->IP_AVAIL, addr, 0); } /* Endwhile */ /* Start CR 1547 */ /* Expire takens */ elapsed = time.SECONDS - state->TIME; while (state->IP_TAKEN && state->IP_TAKEN->EXPIRE < DHCP_LEASE_INFINITE) { if (state->IP_TAKEN->EXPIRE > elapsed) { state->IP_TAKEN->EXPIRE -= elapsed; break; } /* Endif */ addr = state->IP_TAKEN; state->IP_TAKEN = addr->NEXT; elapsed -= addr->EXPIRE; DHCPSRV_lease_start(&state->IP_AVAIL, addr, 0); } /* Endwhile */ /* End CR 1547 */ /* Calculate time to next expiry */ elapsed = DHCP_LEASE_INFINITE; if (state->IP_OFFERED && state->IP_OFFERED->EXPIRE < elapsed) { elapsed = state->IP_OFFERED->EXPIRE; } /* Endif */ if (state->IP_LEASED && state->IP_LEASED->EXPIRE < elapsed) { elapsed = state->IP_LEASED->EXPIRE; } /* Endif */ if (elapsed == DHCP_LEASE_INFINITE) { elapsed = 0; } /* Endif */ state->TIME = time.SECONDS; RTCS_mutex_unlock(&state->IPLIST_SEM); return elapsed; } /* Endbody */
SOCKET_STRUCT_PTR SOCK_Get_sock_struct ( RTCS_SOCKET_CALL_STRUCT_PTR type, _rtcs_taskid owner ) { /* Body */ RTCS_DATA_PTR RTCS_data_ptr; SOCKET_CONFIG_STRUCT_PTR socket_cfg_ptr; SOCKET_STRUCT_PTR socket_ptr; RTCS_data_ptr = RTCS_get_data(); socket_cfg_ptr = RTCS_data_ptr->SOCKET_CFG; socket_ptr = RTCS_part_alloc_zero(RTCS_data_ptr->RTCS_socket_partition); if ( socket_ptr != NULL ) { RTCS_mutex_lock(&socket_cfg_ptr->SOCK_MUTEX); socket_cfg_ptr->CURRENT_SOCKETS++; #if RTCSCFG_SOCKET_OWNERSHIP SOCK_Add_owner(socket_ptr, owner); #endif /* ** link in this socket into the linked list of active sockets */ if ( socket_cfg_ptr->SOCKET_HEAD != NULL ) { ((SOCKET_STRUCT_PTR)socket_cfg_ptr->SOCKET_TAIL)->NEXT = (void *)socket_ptr; socket_ptr->PREV = (SOCKET_STRUCT_PTR)socket_cfg_ptr->SOCKET_TAIL; } else { socket_cfg_ptr->SOCKET_HEAD = (void *)socket_ptr; socket_ptr->PREV = NULL; } /* Endif */ socket_ptr->NEXT = NULL; socket_cfg_ptr->SOCKET_TAIL = (void *)socket_ptr; RTCS_mutex_unlock(&socket_cfg_ptr->SOCK_MUTEX); socket_ptr->VALID = SOCKET_VALID; /* ** set the default socket options */ socket_ptr->CONNECT_TIMEOUT = DEFAULT_CONNECT_TIMEOUT; socket_ptr->RETRANSMISSION_TIMEOUT = DEFAULT_RETRANSMISSION_TIMEOUT; socket_ptr->SEND_TIMEOUT = DEFAULT_SEND_TIMEOUT; socket_ptr->RECEIVE_TIMEOUT = DEFAULT_RECEIVE_TIMEOUT; socket_ptr->RECEIVE_PUSH = DEFAULT_PUSH; socket_ptr->SEND_NOWAIT = DEFAULT_SEND_NOWAIT; socket_ptr->SEND_WAIT = DEFAULT_SEND_WAIT; socket_ptr->SEND_PUSH = DEFAULT_PUSH; socket_ptr->RECEIVE_NOWAIT = DEFAULT_RECEIVE_NOWAIT; socket_ptr->CHECKSUM_BYPASS = DEFAULT_CHECKSUM_BYPASS; socket_ptr->ACTIVE = DEFAULT_ACTIVE; socket_ptr->TBSIZE = DEFAULT_TBSIZE; socket_ptr->RBSIZE = DEFAULT_RBSIZE; socket_ptr->MAXRTO = DEFAULT_MAXRTO; socket_ptr->MAXRCV_WND = DEFAULT_MAXRCV_WND; socket_ptr->KEEPALIVE = DEFAULT_KEEPALIVE; socket_ptr->NOWAIT = DEFAULT_NOWAIT; socket_ptr->NO_NAGLE_ALGORITHM = DEFAULT_NO_NAGLE_ALGORITHM; socket_ptr->NOSWRBUF = DEFAULT_NOSWRBUF; socket_ptr->CALL_BACK = DEFAULT_CALL_BACK; socket_ptr->TYPE_MIRROR = (uint32_t)type; socket_ptr->APPLICATION_CALLBACK = DEFAULT_CALLBACK; socket_ptr->TIMEWAIT_TIMEOUT = DEFAULT_TIMEWAIT_TIMEOUT; socket_ptr->DELAY_ACK = DEFAULT_DELAY_ACK; #if RTCSCFG_ENABLE_IP6 socket_ptr->LINK_OPTIONS.TX.HOP_LIMIT_MULTICAST = DEFAULT_IP6_MULTICAST_HOPS; #endif socket_ptr->PROTOCOL = type; } /* Endif */ return(socket_ptr); } /* Endbody */