13. 커널아이 m2m 모듈 ue의 gateway 및 subnetmask 생성 코드 - netipark/t_lte GitHub Wiki

static void
dhcpi_am_ps_single_ip_calcs(dhcp_am_ps_iface_info * am)
{
  uint32 bits = 1;
  uint32 mask = ~bits;
  uint32 ip;
  uint32 host;
  uint32 network;

  ASSERT(NULL != am);
  ASSERT(DHCP_AM_COOKIE == am->cookie);

  /* Do the calculation in host byte oder */
  ip = dss_ntohl(am->lease.client_ip);

  /*------------------------------------------------------------------------ 
    If LSB is 1, then skip all 1's till 0 to generate netmask.
    For Example:
    IP      = 10.0.0.3        ( 0000 1010 0000 0000 0000 0000 0000 0011 )
    netmask = 255.255.255.248 ( 1111 1111 1111 1111 1111 1111 1111 1000 )
   
    If LSB is 0, then skip all 0's till 1 to genrate netmask.
    For Example:
    IP      = 10.0.0.8        ( 0000 1010 0000 0000 0000 0000 0000 1000 )
    netmask = 255.255.255.240 ( 1111 1111 1111 1111 1111 1111 1111 0000 )
  ------------------------------------------------------------------------*/
  if (bits & ip) 
  {
    while( (bits & ip) )
    {
      bits <<= 1;
      mask <<= 1;
    }
  }
  else
  {
    while( !(bits & ip) )
    {
      bits <<= 1;
      mask <<= 1;
    }
  }

#define DHCP_AM_MIN_MASK ((uint32)(0xfffffffc))
  mask &= DHCP_AM_MIN_MASK;

#if defined(PS_DHCP_IP_ADDR_CLASS_BASED_NETMASK_CALC)
  /*
   * Netmask is calculated on the basis of IP address class.
   * This is because if we choose MIN_MASK the chances of broadcast address
   * coinciding with other addresses, the n/w assigns like - DNS, SIP etc.
   * will increase.
   * Gateway address calculation will be still based on MIN_MASK.
   * This is because if we calculate it based on the calculated netmask value,
   * the value will always be netmask+1 or netmask+2, which increases the
   * chances of this address coinciding with the ip address of another
   * rmnet instance. So we choose MIN_MASK to calculate gateway address.
   * TBD: Not a fool proof solution re-visit in future if needed.
   */

  /* class C address */
  if ( ( ip & 0xE0000000 ) == 0xC0000000 )
  {
    am->netmask  = dss_htonl(0xFFFFFF00);
  }
  else if( ( ip & 0xC0000000 ) == 0x80000000 ) /* class B address */
  {
    am->netmask  = dss_htonl (0xFFFF0000);
  }
  else if( ( ip & 0x80000000 ) == 0x00000000 )   /* class A address */
  {
    am->netmask  = dss_htonl (0xFF000000);
  } 
#elif defined(PS_DHCP_FIXED_NETMASK_255_255_255_255)
  /*
   * IP address class based netmask calculation has few limitations.
   * In Qualnet all the IP addresses are Class A addresses.
   * When a QMI call is made in lab, the netmask will be 255.0.0.0,
   * in that case Windows routes all the packets through QMI interface.
   * In case of Multi-Rmnet calls, all the QMI ip addresses will fall into a
   * single subnet. Then in that case we cannot test the data transfers
   * individually on different PDN's. To overcome these limitations
   * we are fixing the netmask to 255.255.255.255
   * But this may have other limitations like the ones encountered in 
   * field testing.
   * TBD: Not a fool proof solution, more testing is needed.
   */
  am->netmask  = dss_htonl(0xFFFFFFFF);
#else
  am->netmask = dss_htonl (mask);
#endif /* PS_DHCP_IP_ADDR_CLASS_BASED_NETMASK_CALC */

  /*------------------------------------------------------------------------ 
    Generate Server IP by adding 1 to IP address.
    If by adding 1 the host address becomes broadcast address
    then subtract 1 to generate server address.
   
    For Example (Subtract):
    IP      =  10.0.0.10       (0000 1010 0000 0000 0000 0000 0000 1010)
    netmask =  255.255.255.252 (1111 1111 1111 1111 1111 1111 1111 1100)
    Server  =  10.0.0.9        (0000 1010 0000 0000 0000 0000 0000 1001)
   
    For Example (Addition):
    IP      =  10.0.0.11       (0000 1010 0000 0000 0000 0000 0000 1011)
    netmask =  255.255.255.248 (1111 1111 1111 1111 1111 1111 1111 1000)
    Server  =  10.0.0.12       (0000 1010 0000 0000 0000 0000 0000 1100)
  ------------------------------------------------------------------------*/
  if ( (~mask & (ip + 1)) == ~mask )
  {
    host = ~mask & (ip - 1);
  }
  else
  {
    host = ~mask & (ip + 1);
  }

  network = mask & ip;

  /*------------------------------------------------------------------------ 
    Combine Network & Host address to form server address.
  ------------------------------------------------------------------------*/
  ip = network | host;

  am->server_id = dss_htonl(ip);
}