Exemplo n.º 1
0
/* Create a socket and connect it to a given address */
pal_socket_t createConnectedSocket(struct addrinfo *address_info)
{
  pal_socket_t sfd;
  struct sockaddr_in sai;
  struct sockaddr_in6 sai6;
  struct sockaddr *sa = NULL;
  sint32_t sa_len = 0;

  /* Zero out the structures */
  memset(&sai, 0, sizeof(struct sockaddr_in));
  memset(&sai6, 0, sizeof(struct sockaddr_in6));

  /* It's an IPv4 address */
  if (address_info->ai_family == AF_INET)
  {
    /* Copy the information into the IPv4-specific structure */
    memcpy(&sai.sin_addr, &(((struct sockaddr_in *)address_info->ai_addr)->sin_addr), sizeof(struct in_addr));
    sai.sin_family = AF_INET;
    sai.sin_port = htons(SERVER_PORT);

    /* Set a generic pointer for the connect() call */
    sa = (struct sockaddr *)&sai;
    sa_len = sizeof(struct sockaddr_in);
  }
  /* It's an IPv6 address */
  else if (address_info->ai_family == AF_INET6)
  {
    /* Copy the information into the IPv6-specific structure */
    memcpy(&(sai6.sin6_addr), &(((struct sockaddr_in6 *)address_info->ai_addr)->sin6_addr), sizeof(struct in6_addr));
    sai6.sin6_family = AF_INET6;
    sai6.sin6_port = htons(SERVER_PORT);
#ifdef SIN6_LEN
    sai6.sin6_len = sizeof(struct sockaddr_in6);
#endif

    /* Set a generic pointer for the connect() call */
    sa = (struct sockaddr *)&sai6;
    sa_len = sizeof(struct sockaddr_in6);
  }
  else {
    return (pal_socket_t)(-1);
  }

  /* Create the socket */
  if ((sfd = pal_socket(address_info->ai_family, address_info->ai_socktype, 0)) == -1)
  {
    return (pal_socket_t)(-1);
  }

  /* And connect it using the generic pointer */
  if (connect(sfd, sa, sa_len) == -1) {
    return (pal_socket_t)(-1);
  }

  return sfd;
}
Exemplo n.º 2
0
// --------------------------------------------------------------------------
// NetTCP6Connect:
//
// Return values:
//    0: success
//   -1: Failed to resolve srvname.
//   -2: Socket error / Failed to connect (TCP only).
//
sint32_t NetTCP6Connect( pal_socket_t *p_sock, char *Host, uint16_t Port ) 
{
  pal_socket_t         sockfd;
  struct sockaddr_in6  serv_addr;
  struct in6_addr      addr;

  if( NULL == NetText2Addr6(Host, &addr) )
  {
    return -1;
  }

  memset(&serv_addr, 0, sizeof(serv_addr)); 
  serv_addr.sin6_family      = AF_INET6;
  serv_addr.sin6_port        = htons(Port);
  serv_addr.sin6_addr = addr;

  /*
   * Open a TCP socket (an Internet 6 stream socket).
   */
  if( (sockfd = pal_socket(AF_INET6, SOCK_STREAM, 0)) < 0 )
  {
    return -2;
  }

  /*
   * Connect to the server.
   */
  if( pal_connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 )
  {
    pal_closesocket( sockfd );
    return -2;
  }
  
  *p_sock = sockfd;
  return 0;
}
Exemplo n.º 3
0
// --------------------------------------------------------------------------
// NetUDPConnect:
//
// Return values:
//    0: success
//   -1: Failed to resolve srvname.
//   -2: Socket error / Failed to connect (TCP only).
//
sint32_t NetUDPConnect(pal_socket_t *p_sock, char *Host, uint16_t Port)
{
  pal_socket_t        sockfd;
  struct sockaddr_in  serv_addr;
  struct in_addr      addr;

  if( NetText2Addr(Host, &addr) == NULL )
  {
    return -1;
  }

  memset(&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sin_family      = AF_INET;
  serv_addr.sin_port        = htons(Port);
  serv_addr.sin_addr.s_addr = addr.s_addr;

  /*
   * Open a UDP socket.
   */
  if( (sockfd = pal_socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
  {
    return -2;
  }

  /*
   * Connect to the server.
   */
  if( pal_connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 )
  {
    pal_closesocket( sockfd );
    return -2;
  }

  *p_sock = sockfd;
  return 0;
}
Exemplo n.º 4
0
// --------------------------------------------------------------------------
// 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;
}