static int handle_index(int s, wificfg_method method, uint32_t content_length, wificfg_content_type content_type, char *buf, size_t len) { if (wificfg_write_string(s, http_success_header) < 0) return -1; if (method != HTTP_METHOD_HEAD) { if (wificfg_write_string_chunk(s, http_index_content[0], buf, len) < 0) return -1; if (wificfg_write_html_title(s, buf, len, "Home") < 0) return -1; if (wificfg_write_string_chunk(s, http_index_content[1], buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, "<dl class=\"dlh\">", buf, len) < 0) return -1; struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); if (getpeername(s, (struct sockaddr *)&addr, &addr_len) == 0) { if (((struct sockaddr *)&addr)->sa_family == AF_INET) { struct sockaddr_in *sa = (struct sockaddr_in *)&addr; if (wificfg_write_string_chunk(s, "<dt>Peer address</dt>", buf, len) < 0) return -1; snprintf(buf, len, "<dd>" IPSTR ", port %u</dd>", IP2STR((ip4_addr_t *)&sa->sin_addr.s_addr), ntohs(sa->sin_port)); if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1; } #if LWIP_IPV6 if (((struct sockaddr *)&addr)->sa_family == AF_INET6) { struct sockaddr_in6 *sa = (struct sockaddr_in6 *)&addr; if (wificfg_write_string_chunk(s, "<dt>Peer address</dt><dd>", buf, len) < 0) return -1; if (inet6_ntoa_r(sa->sin6_addr, buf, len)) { if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1; } snprintf(buf, len, ", port %u</dd>", ntohs(sa->sin6_port)); if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1; } #endif } if (wificfg_write_string_chunk(s, "</dl>", buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_index_content[2], buf, len) < 0) return -1; if (wificfg_write_chunk_end(s) < 0) return -1; } return 0; }
static void tcp_server_task(void *pvParameters) { char rx_buffer[128]; char addr_str[128]; int addr_family; int ip_protocol; while (1) { #ifdef CONFIG_EXAMPLE_IPV4 struct sockaddr_in destAddr; destAddr.sin_addr.s_addr = htonl(INADDR_ANY); destAddr.sin_family = AF_INET; destAddr.sin_port = htons(PORT); addr_family = AF_INET; ip_protocol = IPPROTO_IP; inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1); #else // IPV6 struct sockaddr_in6 destAddr; bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un)); destAddr.sin6_family = AF_INET6; destAddr.sin6_port = htons(PORT); addr_family = AF_INET6; ip_protocol = IPPROTO_IPV6; inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); #endif int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol); if (listen_sock < 0) { ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); break; } ESP_LOGI(TAG, "Socket created"); int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr)); if (err != 0) { ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno); break; } ESP_LOGI(TAG, "Socket binded"); err = listen(listen_sock, 1); if (err != 0) { ESP_LOGE(TAG, "Error occured during listen: errno %d", errno); break; } ESP_LOGI(TAG, "Socket listening"); #ifdef CONFIG_EXAMPLE_IPV6 struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6 #else struct sockaddr_in sourceAddr; #endif uint addrLen = sizeof(sourceAddr); int sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen); if (sock < 0) { ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno); break; } ESP_LOGI(TAG, "Socket accepted"); while (1) { int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0); // Error occured during receiving if (len < 0) { ESP_LOGE(TAG, "recv failed: errno %d", errno); break; } // Connection closed else if (len == 0) { ESP_LOGI(TAG, "Connection closed"); break; } // Data received else { #ifdef CONFIG_EXAMPLE_IPV6 // Get the sender's ip address as string if (sourceAddr.sin6_family == PF_INET) { inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); } else if (sourceAddr.sin6_family == PF_INET6) { inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); } #else inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); #endif rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string ESP_LOGI(TAG, "Received %d bytes from %s:", len, addr_str); ESP_LOGI(TAG, "%s", rx_buffer); int err = send(sock, rx_buffer, len, 0); if (err < 0) { ESP_LOGE(TAG, "Error occured during sending: errno %d", errno); break; } } } if (sock != -1) { ESP_LOGE(TAG, "Shutting down socket and restarting..."); shutdown(sock, 0); close(sock); } } vTaskDelete(NULL); }
static INT __tshellPing6 (INT iArgC, PCHAR *ppcArgV) { struct addrinfo hints; struct addrinfo *phints = LW_NULL; struct in6_addr in6addr; CHAR cInetAddr[INET6_ADDRSTRLEN]; /* IP 地址缓存 */ PCHAR pcNetif = LW_NULL; INT iTimes = 4; INT iDataSize = 32; INT iTimeout = 3000; if (iArgC <= 1) { fprintf(stderr, "argments error!\n"); return (-ERROR_TSHELL_EPARAM); } /* * 分析参数 */ if (iArgC >= 4) { REGISTER INT i; for (i = 2; i < iArgC; i += 2) { if (lib_strcmp(ppcArgV[i], "-n") == 0) { sscanf(ppcArgV[i + 1], "%i", &iTimes); /* 获得次数 */ } else if (lib_strcmp(ppcArgV[i], "-l") == 0) { sscanf(ppcArgV[i + 1], "%i", &iDataSize); /* 获得数据大小 */ if ((iDataSize > (65000 - sizeof(struct icmp_echo_hdr))) || (iDataSize < 1)) { fprintf(stderr, "data size error!\n"); return (-ERROR_TSHELL_EPARAM); } } else if (lib_strcmp(ppcArgV[i], "-w") == 0) { /* 获得 timeout 的值 */ sscanf(ppcArgV[i + 1], "%i", &iTimeout); if ((iTimeout < 1) || (iTimeout > 60000)) { fprintf(stderr, "timeout error!\n"); return (-ERROR_TSHELL_EPARAM); } } else if (lib_strcmp(ppcArgV[i], "-I") == 0) { /* 网络接口名 */ pcNetif = ppcArgV[i + 1]; } else { fprintf(stderr, "argments error!\n"); /* 参数错误 */ return (-ERROR_TSHELL_EPARAM); } } } /* * 解析地址 */ if (!inet6_aton(ppcArgV[1], &in6addr)) { printf("Execute a DNS query...\n"); { ULONG iOptionNoAbort; ULONG iOption; ioctl(STD_IN, FIOGETOPTIONS, &iOption); iOptionNoAbort = (iOption & ~OPT_ABORT); ioctl(STD_IN, FIOSETOPTIONS, iOptionNoAbort); /* 不允许 control-C 操作 */ hints.ai_family = AF_INET6; /* 解析 IPv6 地址 */ getaddrinfo(ppcArgV[1], LW_NULL, &hints, &phints); /* 域名解析 */ ioctl(STD_IN, FIOSETOPTIONS, iOption); /* 回复原来状态 */ } if (phints == LW_NULL) { printf("Pinging request could not find host %s ." "Please check the name and try again.\n\n", ppcArgV[1]); return (-ERROR_TSHELL_EPARAM); } else { if (phints->ai_addr->sa_family == AF_INET6) { /* 获得网络地址 */ in6addr = ((struct sockaddr_in6 *)(phints->ai_addr))->sin6_addr; freeaddrinfo(phints); } else { freeaddrinfo(phints); printf("Ping6 only support AF_INET6 domain!\n"); return (-EAFNOSUPPORT); } printf("Pinging %s [%s]\n\n", ppcArgV[1], inet6_ntoa_r(in6addr, cInetAddr, sizeof(cInetAddr))); } } return (API_INetPing6(&in6addr, iTimes, iDataSize, iTimeout, pcNetif)); }
/********************************************************************************************************* ** 函数名称: API_INetPing6 ** 功能描述: internet ipv6 ping ** 输 入 : pinaddr 目标 ip 地址. ** iTimes 次数 ** iDataSize 数据大小 ** iTimeout 超时时间 ** pcNetif 网络接口名 (NULL 表示自动确定接口) ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT API_INetPing6 (struct in6_addr *pin6addr, INT iTimes, INT iDataSize, INT iTimeout, CPCHAR pcNetif) { CHAR cInetAddr[INET6_ADDRSTRLEN]; /* IP 地址缓存 */ REGISTER INT iSock; INT i; UINT16 usSeqRecv = 0; ULONG ulTime1; ULONG ulTime2; INT iSuc = 0; INT iHLRecv; struct sockaddr_in6 sockaddrin6To; REGISTER ULONG ulTimeMax = 0; REGISTER ULONG ulTimeMin = 0xFFFFFFFF; REGISTER ULONG ulTimeAvr = 0; if ((iDataSize >= (64 * LW_CFG_KB_SIZE)) || (iDataSize < 0)) { /* 0 - 64KB */ _ErrorHandle(EINVAL); return (PX_ERROR); } sockaddrin6To.sin6_len = sizeof(struct sockaddr_in6); sockaddrin6To.sin6_family = AF_INET6; sockaddrin6To.sin6_addr = *pin6addr; iSock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); /* 必须原子运行到 push */ if (iSock < 0) { return (PX_ERROR); } API_ThreadCleanupPush(__inetPing6Cleanup, (PVOID)iSock); /* 加入清除函数 */ setsockopt(iSock, SOL_SOCKET, SO_RCVTIMEO, &iTimeout, sizeof(INT)); connect(iSock, (struct sockaddr *)&sockaddrin6To, sizeof(struct sockaddr_in6)); /* 设定目标 */ printf("Pinging %s\n\n", inet6_ntoa_r(*pin6addr, cInetAddr, sizeof(cInetAddr))); for (i = 0; ;) { if (__inetPing6Send(iSock, pin6addr, iDataSize, pcNetif, &usSeqRecv) < 0) { /* 发送 icmp 数据包 */ fprintf(stderr, "error : %s.\n", lib_strerror(errno)); i++; if (i >= iTimes) { break; } API_TimeSSleep(1); /* 等待 1 S */ continue; } else { i++; /* 发送次数 ++ */ } ulTime1 = API_TimeGet(); if (__inetPing6Recv(iSock, usSeqRecv, &iHLRecv) < 0) { /* 接收 icmp 数据包 */ printf("Request time out.\n"); /* timeout */ if (i >= iTimes) { break; /* ping 结束 */ } } else { ulTime2 = API_TimeGet(); ulTime2 = (ulTime2 >= ulTime1) ? (ulTime2 - ulTime1) : ((__ARCH_ULONG_MAX - ulTime1) + ulTime2 + 1); ulTime2 = ((ulTime2 * 1000) / LW_TICK_HZ); /* 转为毫秒数 */ printf("Reply from %s: bytes=%d time=%ldms hoplim=%d\n", inet6_ntoa_r(*pin6addr, cInetAddr, sizeof(cInetAddr)), iDataSize, ulTime2, iHLRecv); iSuc++; ulTimeAvr += ulTime2; ulTimeMax = (ulTimeMax > ulTime2) ? ulTimeMax : ulTime2; ulTimeMin = (ulTimeMin < ulTime2) ? ulTimeMin : ulTime2; if (i >= iTimes) { break; /* ping 结束 */ } else { API_TimeSSleep(1); /* 等待 1 S */ } } } API_ThreadCleanupPop(LW_TRUE); /* ping 清除 */ /* * 打印总结信息 */ printf("\nPing statistics for %s:\n", inet6_ntoa_r(*pin6addr, cInetAddr, sizeof(cInetAddr))); printf(" Packets: Send = %d, Received = %d, Lost = %d(%d%% loss),\n", iTimes, iSuc, (iTimes - iSuc), (((iTimes - iSuc) * 100) / iTimes)); if (iSuc == 0) { /* 没有一次成功 */ return (PX_ERROR); } ulTimeAvr = ulTimeAvr / iSuc; printf("Approximate round trip times in milli-seconds:\n"); printf(" Minimum = %ldms, Maximum = %ldms, Average = %ldms\r\n\r\n", ulTimeMin, ulTimeMax, ulTimeAvr); return (ERROR_NONE); }