Beispiel #1
0
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 */
Beispiel #2
0
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 */
Beispiel #3
0
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 */
Beispiel #4
0
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 */
Beispiel #5
0
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 */
Beispiel #6
0
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 */
Beispiel #7
0
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 */