/* 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; }
// -------------------------------------------------------------------------- // 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; }
// -------------------------------------------------------------------------- // 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; }
// -------------------------------------------------------------------------- // 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; }