/************************************************************************ * NAME: fnet_dns_init * * DESCRIPTION: Initializes DNS client service and starts the host * name resolving. ************************************************************************/ int fnet_dns_init( struct fnet_dns_params *params ) { const unsigned long bufsize_option = FNET_DNS_MESSAGE_SIZE; unsigned int total_length; unsigned long host_name_length; struct sockaddr remote_addr; fnet_dns_header_t *header; /* Check input parameters. */ if((params == 0) || (params->dns_server_addr.sa_family == AF_UNSPEC) || fnet_socket_addr_is_unspecified(¶ms->dns_server_addr) || (params->handler == 0) /* Check length of host_name.*/ || ((host_name_length = fnet_strlen(params->host_name)) == 0U) || (host_name_length >= FNET_DNS_MAME_SIZE)) { FNET_DEBUG_DNS(FNET_DNS_ERR_PARAMS); goto ERROR; } /* Check if DNS service is free.*/ if(fnet_dns_if.state != FNET_DNS_STATE_DISABLED) { FNET_DEBUG_DNS(FNET_DNS_ERR_IS_INITIALIZED); goto ERROR; } /* Save input parmeters.*/ fnet_dns_if.handler = params->handler; fnet_dns_if.handler_cookie = params->cookie; fnet_dns_if.addr_family = params->addr_family; fnet_dns_if.addr_number = 0; if(params->addr_family == AF_INET) { fnet_dns_if.dns_type = FNET_HTONS(FNET_DNS_TYPE_A); } else if(params->addr_family == AF_INET6) { fnet_dns_if.dns_type = FNET_HTONS(FNET_DNS_TYPE_AAAA); } else { FNET_DEBUG_DNS(FNET_DNS_ERR_PARAMS); goto ERROR; } fnet_dns_if.iteration = 0U; /* Reset iteration counter.*/ fnet_dns_if.id++; /* Change query ID.*/ /* Create socket */ if((fnet_dns_if.socket_cln = socket(params->dns_server_addr.sa_family, SOCK_DGRAM, 0)) == SOCKET_INVALID) { FNET_DEBUG_DNS(FNET_DNS_ERR_SOCKET_CREATION); goto ERROR; } /* Set socket options */ setsockopt(fnet_dns_if.socket_cln, SOL_SOCKET, SO_RCVBUF, (const char *)&bufsize_option, sizeof(bufsize_option)); setsockopt(fnet_dns_if.socket_cln, SOL_SOCKET, SO_SNDBUF, (const char *)&bufsize_option, sizeof(bufsize_option)); /* Bind/connect to the server.*/ FNET_DEBUG_DNS("Connecting to DNS Server."); fnet_memset_zero(&remote_addr, sizeof(remote_addr)); remote_addr = params->dns_server_addr; if(remote_addr.sa_port == 0U) { remote_addr.sa_port = FNET_CFG_DNS_PORT; } if(connect(fnet_dns_if.socket_cln, &remote_addr, sizeof(remote_addr))== FNET_ERR) { FNET_DEBUG_DNS(FNET_DNS_ERR_SOCKET_CONNECT); goto ERROR_1; } /* ==== Build message. ==== */ fnet_memset_zero(fnet_dns_if.message, sizeof(fnet_dns_if.message)); /* Clear buffer.*/ /* Set header fields: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ID | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR| Opcode |AA|TC|RD|RA| Z | RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QDCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ANCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | NSCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ARCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ */ header = (fnet_dns_header_t *)fnet_dns_if.message; header->id = fnet_dns_if.id; /* Set ID. */ header->flags = FNET_HTONS(FNET_DNS_HEADER_FLAGS_RD); /* Recursion Desired.*/ header->qdcount = FNET_HTONS(1U); /* One Question. */ /* No Answer (ANCOUNT).*/ /* No Authority (NSCOUNT). */ /* No Additional (ARCOUNT). */ total_length = sizeof(fnet_dns_header_t); total_length += fnet_dns_add_question( &fnet_dns_if.message[total_length], fnet_dns_if.dns_type, params->host_name); fnet_dns_if.message_size = (unsigned long)(total_length); /* Register DNS service. */ fnet_dns_if.service_descriptor = fnet_poll_service_register(fnet_dns_state_machine, (void *) &fnet_dns_if); if(fnet_dns_if.service_descriptor == (fnet_poll_desc_t)FNET_ERR) { FNET_DEBUG_DNS(FNET_DNS_ERR_SERVICE); goto ERROR_1; } fnet_dns_if.state = FNET_DNS_STATE_TX; /* => Send request. */ return FNET_OK; ERROR_1: closesocket(fnet_dns_if.socket_cln); ERROR: return FNET_ERR; }
/************************************************************************ * NAME: fnet_telnet_init * * DESCRIPTION: Initialization of the Telnet server. *************************************************************************/ fnet_telnet_desc_t fnet_telnet_init( struct fnet_telnet_params *params ) { struct sockaddr local_addr; struct fnet_telnet_if *telnet_if = 0; /* Socket options. */ const struct linger linger_option ={1, /*l_onoff*/ 4 /*l_linger*/}; const unsigned long bufsize_option = FNET_CFG_TELNET_SOCKET_BUF_SIZE; const int keepalive_option = 1; const int keepcnt_option = FNET_TELNET_TCP_KEEPCNT; const int keepintvl_option = FNET_TELNET_TCP_KEEPINTVL; const int keepidle_option = FNET_TELNET_TCP_KEEPIDLE; int i; if(params == 0 ) { FNET_DEBUG_TELNET("TELNET: Wrong init parameters."); goto ERROR_1; } /* Try to find free Telnet server descriptor. */ #if (FNET_CFG_TELNET_MAX > 1) { int i; for(i=0; i<FNET_CFG_TELNET_MAX; i++) { if(telnet_if_list[i].enabled == FNET_FALSE) { telnet_if = &telnet_if_list[i]; break; } } } #else if(telnet_if_list[0].enabled == FNET_FALSE) telnet_if = &telnet_if_list[0]; #endif /* No free Telnet server descriptor. */ if(telnet_if == 0) { FNET_DEBUG_TELNET("TELNET: No free Telnet Server."); goto ERROR_1; } local_addr = params->address; if(local_addr.sa_port == 0) local_addr.sa_port = FNET_CFG_TELNET_PORT; /* Aply the default port. */ if(local_addr.sa_family == AF_UNSPEC) local_addr.sa_family = AF_SUPPORTED; /* Asign supported families.*/ /* Create listen socket */ if((telnet_if->socket_listen = socket(local_addr.sa_family, SOCK_STREAM, 0)) == SOCKET_INVALID) { FNET_DEBUG_TELNET("TELNET: Socket creation error."); goto ERROR_1; } if(bind(telnet_if->socket_listen, (struct sockaddr *)(&local_addr), sizeof(local_addr)) == SOCKET_ERROR) { FNET_DEBUG_TELNET("TELNET: Socket bind error."); goto ERROR_2; } /* Set socket options. */ if( /* Setup linger option. */ (setsockopt (telnet_if->socket_listen, SOL_SOCKET, SO_LINGER, (char *)&linger_option, sizeof(linger_option)) == SOCKET_ERROR) || /* Set socket buffer size. */ (setsockopt(telnet_if->socket_listen, SOL_SOCKET, SO_RCVBUF, (char *) &bufsize_option, sizeof(bufsize_option))== SOCKET_ERROR) || (setsockopt(telnet_if->socket_listen, SOL_SOCKET, SO_SNDBUF, (char *) &bufsize_option, sizeof(bufsize_option))== SOCKET_ERROR) || /* Enable keepalive_option option. */ (setsockopt (telnet_if->socket_listen, SOL_SOCKET, SO_KEEPALIVE, (char *)&keepalive_option, sizeof(keepalive_option)) == SOCKET_ERROR) || /* Keepalive probe retransmit limit. */ (setsockopt (telnet_if->socket_listen, IPPROTO_TCP, TCP_KEEPCNT, (char *)&keepcnt_option, sizeof(keepcnt_option)) == SOCKET_ERROR) || /* Keepalive retransmit interval.*/ (setsockopt (telnet_if->socket_listen, IPPROTO_TCP, TCP_KEEPINTVL, (char *)&keepintvl_option, sizeof(keepintvl_option)) == SOCKET_ERROR) || /* Time between keepalive probes.*/ (setsockopt (telnet_if->socket_listen, IPPROTO_TCP, TCP_KEEPIDLE, (char *)&keepidle_option, sizeof(keepidle_option)) == SOCKET_ERROR) ) { FNET_DEBUG_TELNET("TELNET: Socket setsockopt() error."); goto ERROR_2; } telnet_if->backlog = FNET_CFG_TELNET_SESSION_MAX; if(listen(telnet_if->socket_listen, telnet_if->backlog) == SOCKET_ERROR) { FNET_DEBUG_TELNET("TELNET: Socket listen error."); goto ERROR_2; } /* Register service. */ telnet_if->service_descriptor = fnet_poll_service_register(fnet_telnet_state_machine, (void *) telnet_if); if(telnet_if->service_descriptor == (fnet_poll_desc_t)FNET_ERR) { FNET_DEBUG_TELNET("TELNET: Service registration error."); goto ERROR_2; } for(i=0; i<FNET_CFG_TELNET_SESSION_MAX; i++) { struct fnet_telnet_session_if *session = &telnet_if->session[i]; /* Reset buffer pointers. Move it to init state. */ session->tx_buffer_head_index = 0; session->rx_buffer_head = session->rx_buffer; session->rx_buffer_tail = session->rx_buffer; session->rx_buffer_end = &session->rx_buffer[FNET_TELNET_RX_BUFFER_SIZE]; /* Setup stream. */ session->stream.id = (long)(session); session->stream.putchar = fnet_telnet_putchar; session->stream.getchar = fnet_telnet_getchar; session->stream.flush = fnet_telnet_flush; /* Init shell. */ session->shell_params.shell = params->shell; session->shell_params.cmd_line_buffer = session->cmd_line_buffer; session->shell_params.cmd_line_buffer_size = sizeof(session->cmd_line_buffer); session->shell_params.stream = &session->stream; session->shell_params.echo = FNET_CFG_TELNET_SHELL_ECHO; session->socket_foreign = SOCKET_INVALID; session->state = FNET_TELNET_STATE_LISTENING; } telnet_if->session_active = FNET_NULL; telnet_if->enabled = FNET_TRUE; return (fnet_telnet_desc_t)telnet_if; ERROR_2: closesocket(telnet_if->socket_listen); ERROR_1: return (fnet_telnet_desc_t)FNET_ERR; }
/************************************************************************ * NAME: fnet_ping_request * * DESCRIPTION: Initializes PING service. ************************************************************************/ fnet_return_t fnet_ping_request( struct fnet_ping_params *params ) { const fnet_size_t bufsize_option = FNET_PING_BUFFER_SIZE; /* Check input parameters. */ if((params == 0) || (params->packet_count == 0u) || (fnet_socket_addr_is_unspecified(¶ms->target_addr))) { FNET_DEBUG_PING(FNET_PING_ERR_PARAMS); goto ERROR; } /* Check if PING service is free.*/ if(fnet_ping_if.state != FNET_PING_STATE_DISABLED) { FNET_DEBUG_PING(FNET_PING_ERR_IS_INITIALIZED); goto ERROR; } /* Save input parmeters.*/ fnet_ping_if.handler = params->handler; fnet_ping_if.handler_cookie = params->cookie; fnet_ping_if.timeout_clk = params->timeout/FNET_TIMER_PERIOD_MS; if(fnet_ping_if.timeout_clk == 0u) { fnet_ping_if.timeout_clk = 1u; } fnet_ping_if.family = params->target_addr.sa_family; fnet_ping_if.packet_count = params->packet_count; fnet_ping_if.pattern = params->pattern; fnet_ping_if.packet_size = params->packet_size; if(fnet_ping_if.packet_size > FNET_CFG_PING_PACKET_MAX) { fnet_ping_if.packet_size = FNET_CFG_PING_PACKET_MAX; } fnet_ping_if.target_addr = params->target_addr; /* Create socket */ if((fnet_ping_if.socket_foreign = fnet_socket(fnet_ping_if.family, SOCK_RAW, (fnet_uint32_t)((params->target_addr.sa_family == AF_INET) ? IPPROTO_ICMP : IPPROTO_ICMPV6))) == FNET_ERR) { FNET_DEBUG_PING(FNET_PING_ERR_SOCKET_CREATION); goto ERROR; } /* Set Socket options. */ #if FNET_CFG_IP4 if(fnet_ping_if.family == AF_INET) { fnet_socket_setopt(fnet_ping_if.socket_foreign, IPPROTO_IP, IP_TTL, (fnet_uint8_t *) ¶ms->ttl, sizeof(params->ttl)); } #endif #if FNET_CFG_IP6 if(fnet_ping_if.family == AF_INET6) { fnet_socket_setopt(fnet_ping_if.socket_foreign, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (fnet_uint8_t *) ¶ms->ttl, sizeof(params->ttl)); } #endif fnet_socket_setopt(fnet_ping_if.socket_foreign, SOL_SOCKET, SO_RCVBUF, &bufsize_option, sizeof(bufsize_option)); fnet_socket_setopt(fnet_ping_if.socket_foreign, SOL_SOCKET, SO_SNDBUF, &bufsize_option, sizeof(bufsize_option)); /* Register PING service. */ fnet_ping_if.service_descriptor = fnet_poll_service_register(fnet_ping_state_machine, (void *) &fnet_ping_if); if(fnet_ping_if.service_descriptor == (fnet_poll_desc_t)FNET_ERR) { FNET_DEBUG_PING(FNET_PING_ERR_SERVICE); goto ERROR_1; } fnet_ping_if.state = FNET_PING_STATE_SENDING_REQUEST; return FNET_OK; ERROR_1: fnet_socket_close(fnet_ping_if.socket_foreign); ERROR: return FNET_ERR; }