76 lines
2.2 KiB
C++
76 lines
2.2 KiB
C++
#include "dns_server.h"
|
|
#include <freertos/FreeRTOS.h>
|
|
#include <freertos/task.h>
|
|
#include <esp_log.h>
|
|
#include <lwip/sockets.h>
|
|
#include <lwip/netdb.h>
|
|
|
|
#define TAG "DnsServer"
|
|
|
|
DnsServer::DnsServer() {
|
|
}
|
|
|
|
DnsServer::~DnsServer() {
|
|
}
|
|
|
|
void DnsServer::Start(esp_ip4_addr_t gateway) {
|
|
ESP_LOGI(TAG, "Starting DNS server");
|
|
gateway_ = gateway;
|
|
|
|
fd_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
if (fd_ < 0) {
|
|
ESP_LOGE(TAG, "Failed to create socket");
|
|
return;
|
|
}
|
|
|
|
struct sockaddr_in server_addr;
|
|
memset(&server_addr, 0, sizeof(server_addr));
|
|
server_addr.sin_family = AF_INET;
|
|
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
server_addr.sin_port = htons(port_);
|
|
|
|
if (bind(fd_, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
|
|
ESP_LOGE(TAG, "failed to bind port %d", port_);
|
|
close(fd_);
|
|
return;
|
|
}
|
|
|
|
xTaskCreate([](void* arg) {
|
|
DnsServer* dns_server = static_cast<DnsServer*>(arg);
|
|
dns_server->Run();
|
|
}, "DnsServerTask", 4096, this, 5, NULL);
|
|
}
|
|
|
|
void DnsServer::Stop() {
|
|
ESP_LOGI(TAG, "Stopping DNS server");
|
|
}
|
|
|
|
void DnsServer::Run() {
|
|
char buffer[512];
|
|
while (1) {
|
|
struct sockaddr_in client_addr;
|
|
socklen_t client_addr_len = sizeof(client_addr);
|
|
int len = recvfrom(fd_, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &client_addr_len);
|
|
if (len < 0) {
|
|
ESP_LOGE(TAG, "recvfrom failed, errno=%d", errno);
|
|
continue;
|
|
}
|
|
|
|
// Simple DNS response: point all queries to 192.168.4.1
|
|
buffer[2] |= 0x80; // Set response flag
|
|
buffer[3] |= 0x80; // Set Recursion Available
|
|
buffer[7] = 1; // Set answer count to 1
|
|
|
|
// Add answer section
|
|
memcpy(&buffer[len], "\xc0\x0c", 2); // Name pointer
|
|
len += 2;
|
|
memcpy(&buffer[len], "\x00\x01\x00\x01\x00\x00\x00\x1c\x00\x04", 10); // Type, class, TTL, data length
|
|
len += 10;
|
|
memcpy(&buffer[len], &gateway_.addr, 4); // 192.168.4.1
|
|
len += 4;
|
|
ESP_LOGI(TAG, "Sending DNS response to %s", inet_ntoa(gateway_.addr));
|
|
|
|
sendto(fd_, buffer, len, 0, (struct sockaddr *)&client_addr, client_addr_len);
|
|
}
|
|
}
|