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