123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- #include "dns_server.h"
- #include <lwip/sockets.h>
- #include <string.h>
- #include <freertos/FreeRTOS.h>
- #include <freertos/task.h>
- #include <freertos/event_groups.h>
- #include <esp_system.h>
- #include <esp_wifi.h>
- #include <esp_event_loop.h>
- #include <esp_log.h>
- #include <esp_err.h>
- #include <nvs_flash.h>
- #include <lwip/err.h>
- #include <lwip/sockets.h>
- #include <lwip/sys.h>
- #include <lwip/netdb.h>
- #include <lwip/dns.h>
- #include <byteswap.h>
- #include "wifi_manager.h"
- static const char TAG[] = "dns_server";
- static TaskHandle_t task_dns_server = NULL;
- int socket_fd;
- void dns_server_start() {
- xTaskCreate(&dns_server, "dns_server", 3072, NULL, WIFI_MANAGER_TASK_PRIORITY-1, &task_dns_server);
- }
- void dns_server_stop(){
- if(task_dns_server){
- vTaskDelete(task_dns_server);
- close(socket_fd);
- task_dns_server = NULL;
- }
- }
- void dns_server(void *pvParameters) {
- struct sockaddr_in sa, ra;
-
- ip4_addr_t ip_resolved;
- inet_pton(AF_INET, DEFAULT_AP_IP, &ip_resolved);
-
- socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (socket_fd < 0){
- ESP_LOGE(TAG, "Failed to create socket");
- exit(0);
- }
- memset(&sa, 0, sizeof(struct sockaddr_in));
-
- tcpip_adapter_ip_info_t ip;
- tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip);
- ra.sin_family = AF_INET;
- ra.sin_addr.s_addr = ip.ip.addr;
- ra.sin_port = htons(53);
- if (bind(socket_fd, (struct sockaddr *)&ra, sizeof(struct sockaddr_in)) == -1) {
- ESP_LOGE(TAG, "Failed to bind to 53/udp");
- close(socket_fd);
- exit(1);
- }
- struct sockaddr_in client;
- socklen_t client_len;
- client_len = sizeof(client);
- int length;
- uint8_t data[DNS_QUERY_MAX_SIZE];
- uint8_t response[DNS_ANSWER_MAX_SIZE];
- char ip_address[INET_ADDRSTRLEN];
- char *domain;
- int err;
- ESP_LOGI(TAG, "DNS Server listening on 53/udp");
-
- for(;;) {
- memset(data, 0x00, sizeof(data));
- length = recvfrom(socket_fd, data, sizeof(data), 0, (struct sockaddr *)&client, &client_len);
-
- if ( length > 0 && ((length + sizeof(dns_answer_t)-1) < DNS_ANSWER_MAX_SIZE) ) {
- data[length] = '\0';
-
- memcpy(response, data, sizeof(dns_header_t));
- dns_header_t *dns_header = (dns_header_t*)response;
- dns_header->QR = 1;
- dns_header->OPCode = DNS_OPCODE_QUERY;
- dns_header->AA = 1;
- dns_header->RCode = DNS_REPLY_CODE_NO_ERROR;
- dns_header->TC = 0;
- dns_header->RD = 0;
- dns_header->ANCount = dns_header->QDCount;
- dns_header->NSCount = 0x0000;
- dns_header->ARCount = 0x0000;
-
- memcpy(response + sizeof(dns_header_t), data + sizeof(dns_header_t), length - sizeof(dns_header_t));
-
- inet_ntop(AF_INET, &(client.sin_addr), ip_address, INET_ADDRSTRLEN);
- domain = (char*) &data[sizeof(dns_header_t) + 1];
- for(char* c=domain; *c != '\0'; c++){
- if(*c < ' ' || *c > 'z') *c = '.';
- }
- ESP_LOGI(TAG, "Replying to DNS request for %s from %s", domain, ip_address);
-
- dns_answer_t *dns_answer = (dns_answer_t*)&response[length];
- dns_answer->NAME = __bswap_16(0xC00C);
- dns_answer->TYPE = __bswap_16(DNS_ANSWER_TYPE_A);
- dns_answer->CLASS = __bswap_16(DNS_ANSWER_CLASS_IN);
- dns_answer->TTL = (uint32_t)0x00000000;
- dns_answer->RDLENGTH = __bswap_16(0x0004);
- dns_answer->RDATA = ip_resolved.addr;
- err = sendto(socket_fd, response, length+sizeof(dns_answer_t), 0, (struct sockaddr *)&client, client_len);
- if (err < 0) {
- ESP_LOGE(TAG, "UDP sendto failed: %d", err);
- }
- }
- taskYIELD();
- }
- close(socket_fd);
- vTaskDelete ( NULL );
- }
|