Exemple #1
0
/*
 * Generate a DNS id
 */
static uint16_t
DNSGenerateID(void)
{
    static uint16_t id = 0;
    struct timeval now;

    pal_gettimeofday(&now);

    if (!id)
        id = (uint16_t) (0xffff & (now.tv_sec ^ now.tv_usec ^ pal_getpid()));
    else
        id += 1 + (uint16_t)(now.tv_usec % 263);

    return id;
}
// --------------------------------------------------------------------------
// IEE_init: ICMP Echo Engine initialisation routine.
//
// Parameters:
//   pp_config: Opaque double pointer to a ICMP_ECHO_ENGINE_PARMS structure.
//   eng_mode: The mode of the ICMP Echo Engine.
//   send_interval: Fixed interval, in miliseconds, at which ICMP echo
//     requests will be issued.
//   echo_num: Number of ICMP echo requests to issue(0=infinite).
//   echo_timeout: Number of miliseconds after which an unanswered ICMP
//     echo request will be marked as timed out.
//   echo_timeout_threshold: Number of consecutive timed-out ICMP echo
//     requests to declare a general echo timeout.
//   src: Source address used for sending ICMP echo requests.
//   dst: Destination address at which ICMP echo requests will be sent.
//   family: address family (INET or INET6)
//
// Return values:
//   IEE_SUCCESS on success.
//   IEE_INVALID_PARMS if invalid pp_config.
//
iee_ret_t IEE_init( void** pp_config, iee_mode_t eng_mode,
                   uint32_t send_interval, uint32_t echo_num,
                   uint32_t echo_timeout, uint8_t echo_timeout_threshold,
                   char* src, char* dst, sint32_t af,
                   iee_send_clbk send_clbk, iee_recv_clbk recv_clbk )
{
  PICMP_ECHO_ENGINE_PARMS p_engine = NULL;


  // Verify input parameters.
  if( pp_config == NULL  ||  *pp_config != NULL  ||  dst == NULL )
  {
    // Error: bad input parameters.
    return IEE_INVALID_PARMS;
  }

  // Reserve memory for the engine parameters
  *pp_config = pal_malloc( sizeof(ICMP_ECHO_ENGINE_PARMS) );
  p_engine = (PICMP_ECHO_ENGINE_PARMS)*pp_config;
  if( p_engine == NULL )
  {
    // Error: Not enough memory for structure.
    return IEE_RESOURCE_STARVATION;
  }

  // Initialize engine structure with input parameters.
  memset( p_engine, 0, sizeof(ICMP_ECHO_ENGINE_PARMS) );
  p_engine->send_interval          = send_interval;
  p_engine->echo_num               = echo_num;
  p_engine->echo_timeout           = echo_timeout;    // Not used in ACD
  p_engine->echo_timeout_threshold = echo_timeout_threshold;
  p_engine->eng_mode               = eng_mode;

  // Initialize engine variables.
  p_engine->eng_ongoing       = 1;
  p_engine->count_send        = 0;
  p_engine->count_late        = 0;
  p_engine->count_ontime      = 0;
  p_engine->count_consec_late = 0;
  p_engine->event_list = NULL;

  // Set engine callback functions.
  p_engine->clbk_send = send_clbk;
  p_engine->clbk_recv = recv_clbk;

  // Initialize engine socket variables.
  p_engine->icmp_echo_id = pal_getpid();
  p_engine->icmp_saf = af;
  switch( p_engine->icmp_saf )
  {
  case AF_INET:
    if( pal_inet_pton( AF_INET, src, &p_engine->echo_addr_src.in4.sin_addr ) <= 0 )
    {
      // Bad IPv4 address in 'src'.
      pal_free( p_engine );
      return IEE_INVALID_PARMS;
    }
    p_engine->echo_addr_src.in4.sin_family = AF_INET;

    if( pal_inet_pton( AF_INET, dst, &p_engine->echo_addr_dst.in4.sin_addr ) <= 0 )
    {
      // Bad IPv4 address in 'dst'.
      pal_free( p_engine );
      return IEE_INVALID_PARMS;
    }
    p_engine->echo_addr_dst.in4.sin_family = AF_INET;

    p_engine->icmp_sfd = pal_socket( AF_INET, SOCK_RAW, IPPROTO_ICMP );
    break;

  case AF_INET6:
    if( pal_inet_pton( AF_INET6, src, &p_engine->echo_addr_src.in6.sin6_addr ) <= 0 )
    {
      // Bad IPv6 address in 'src'.
      pal_free( p_engine );
      return IEE_INVALID_PARMS;
    }
    p_engine->echo_addr_src.in6.sin6_family = AF_INET6;

    if( pal_inet_pton( AF_INET6, dst, &p_engine->echo_addr_dst.in6.sin6_addr ) <= 0 )
    {
      // Bad IPv6 address in 'dst'.
      pal_free( p_engine );
      return IEE_INVALID_PARMS;
    }
    p_engine->echo_addr_dst.in6.sin6_family = AF_INET6;

    p_engine->icmp_sfd = pal_socket( AF_INET6, SOCK_RAW, IPPROTO_ICMPV6 );
    break;

  default:
    // ERROR! Bad address family!
    pal_free( p_engine );
    return IEE_INVALID_PARMS;
  }

  // Verify that the socket created is valid.
  if( p_engine->icmp_sfd == -1 )
  {
    // Failed to open a socket descriptor.
    pal_free( p_engine );
    return IEE_GENERAL_ECHO_ERROR;
  }

  return IEE_SUCCESS;
}