Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By SwiCago
#21162 Ok, so I have tried various variations and none seem to work

I used a modified version of this package as suggested (even added some Serial.print)
https://github.com/esp8266/Arduino/tree ... /DNSServer
And also other version of DNS server, like in ethernet package. All seem to reply, but none seem to make the device think it is resolved correctly.

Both webserver and dnsserver seems to work in parallel, but like I said the DNS response is not accepted.

My ino, in case someone wants to have a look
Code: Select all#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>

const char* ssid     = "esp8266";
boolean LEDstate[] = {LOW, false, LOW};
const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 1, 1);

const char* html = "<html><head><style>.bt{display:block;width:250px;height:100px;padding:10px;margin:10px;"
                    "text-align:center;border-radius:5px;color:white;font-weight:bold;font-size:70px;text-decoration:none;} "
                    "body{background:#000;} .r{background:#933;} .g{background:#363;} .y{background:#EE0;height:100px;"
                    "width:100px;border-radius:50px;} .b{background:#000;height:100px;width:100px;border-radius:50px;} "
                    ".a{font-size:35px;} td{vertical-align:middle;}</style>"
                    "</head><body><table><tr><td><div class='TGT0'></div></td><td><a class='bt g' href='/L0?v=1'>ON</a></td>"
                    "<td><a class='bt r' href='/L0?v=0'>OFF</a></td></tr><tr><td><div class='TGT2'></div></td><td>"
                    "<a class='bt g' href='/L2?v=1'>ON</a></td><td><a class='bt r' href='/L2?v=0'>OFF</a></td></tr>"
                    "<tr><td>&nbsp;</td><td><a class='bt g a' href='/ALL?v=1'><br/>ALL ON</a></td><td>"
                    "<a class='bt r a' href='/ALL?v=0'><br/>ALL OFF</a></td></tr></body></html>";

ESP8266WebServer server(80);
DNSServer dnsServer;

void setup() {
  pinMode(0, OUTPUT);
  pinMode(2, OUTPUT);
  digitalWrite(2, LEDstate[0]);
  digitalWrite(2, LEDstate[2]);
  Serial.begin(115200);
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP,apIP,IPAddress(255,255,255,0));
  WiFi.softAP(ssid);//, password);
  Serial.print("\n\r \n\rWorking to connect");

  Serial.println("");
  Serial.print("AP is ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.softAPIP());
  server.on("/", handle_root);
  server.on("/L0", handle_L0);
  server.on("/L2", handle_L2);
  server.on("/ALL", handle_ALL);
  server.begin();
  Serial.println("HTTP server started");
  dnsServer.setTTL(300);
  dnsServer.setErrorReplyCode(DNSReplyCode::ServerFailure);
  dnsServer.start(DNS_PORT, "www.example.com", apIP);
  Serial.println("USP Server started");
}

void loop() {
  server.handleClient();
  dnsServer.processNextRequest();
}

void handle_root() {
  Serial.println("Page served");
  String toSend = html;
  toSend.replace("TGT0", LEDstate[0] ? "y" : "b");
  toSend.replace("TGT2", LEDstate[2] ? "y" : "b");
  server.send(200, "text/html", toSend);
  delay(100);
}

void handle_L0() {
  change_states(0);
  handle_root();
}

void handle_L2() {
  change_states(2);
  handle_root();
}

void handle_ALL() {
  change_states(0);
  change_states(2);
  handle_root();
}

void change_states(int tgt) {
  if (server.hasArg("v")) {
    int state = server.arg("v").toInt() == 1;
    Serial.print("LED");
    Serial.print(tgt);
    Serial.print("=");
    Serial.println(state);
    LEDstate[tgt] = state ? HIGH : LOW;
    digitalWrite(tgt, LEDstate[tgt]);
  }
}



Modified DNSserver.ccp
Code: Select all#include "DNSServer.h"
#include <lwip/def.h>
#include <Arduino.h>

DNSServer::DNSServer()
{
  _ttl = htonl(60);
  _errorReplyCode = DNSReplyCode::NonExistentDomain;
}

bool DNSServer::start(const uint16_t &port, const String &domainName,
                     const IPAddress &resolvedIP)
{
  _port = port;
  _domainName = domainName;
  _resolvedIP[0] = resolvedIP[0];
  _resolvedIP[1] = resolvedIP[1];
  _resolvedIP[2] = resolvedIP[2];
  _resolvedIP[3] = resolvedIP[3];
  downcaseAndRemoveWwwPrefix(_domainName);
  return _udp.begin(_port) == 1;
}

void DNSServer::setErrorReplyCode(const DNSReplyCode &replyCode)
{
  _errorReplyCode = replyCode;
}

void DNSServer::setTTL(const uint32_t &ttl)
{
  _ttl = htonl(ttl);
}

void DNSServer::stop()
{
  _udp.stop();
}

void DNSServer::downcaseAndRemoveWwwPrefix(String &domainName)
{
  domainName.toLowerCase();
  domainName.replace("www.", "");
}

void DNSServer::processNextRequest()
{
  _currentPacketSize = _udp.parsePacket();
  if (_currentPacketSize)
  {
    _buffer = (unsigned char*)malloc(_currentPacketSize * sizeof(char));
    _udp.read(_buffer, _currentPacketSize);
    _dnsHeader = (DNSHeader*) _buffer;

    if (_dnsHeader->QR == DNS_QR_QUERY &&
        _dnsHeader->OPCode == DNS_OPCODE_QUERY &&
        requestIncludesOnlyOneQuestion())// &&
        //getDomainNameWithoutWwwPrefix() == _domainName)
    {
      replyWithIP();
    }
    else if (_dnsHeader->QR == DNS_QR_QUERY)
    {
      replyWithCustomCode();
    }

    free(_buffer);
  }
}

bool DNSServer::requestIncludesOnlyOneQuestion()
{
  return ntohs(_dnsHeader->QDCount) == 1 &&
         _dnsHeader->ANCount == 0 &&
         _dnsHeader->NSCount == 0 &&
         _dnsHeader->ARCount == 0;
}

String DNSServer::getDomainNameWithoutWwwPrefix()
{
  String parsedDomainName = "";
  unsigned char *start = _buffer + 12;
  if (*start == 0)
  {
    return parsedDomainName;
  }
  int pos = 0;
  while(true)
  {
    unsigned char labelLength = *(start + pos);
    for(int i = 0; i < labelLength; i++)
    {
      pos++;
      parsedDomainName += (char)*(start + pos);
    }
    pos++;
    if (*(start + pos) == 0)
    {
      downcaseAndRemoveWwwPrefix(parsedDomainName);
      return parsedDomainName;
    }
    else
    {
      parsedDomainName += ".";
    }
  }
}

void DNSServer::replyWithIP()
{
Serial.print("Replying IP ");
Serial.print(_resolvedIP[0]);
Serial.print(".");
Serial.print(_resolvedIP[1]);
Serial.print(".");
Serial.print(_resolvedIP[2]);
Serial.print(".");
Serial.println(_resolvedIP[3]);
  _dnsHeader->QR = DNS_QR_RESPONSE;
  _dnsHeader->ANCount = _dnsHeader->QDCount;
  _dnsHeader->QDCount = 0;

  _udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
  _udp.write(_buffer, _currentPacketSize);
  _udp.write((unsigned char*)&_ttl, 4);
  // Length of RData is 4 bytes (because, in this case, RData is IPv4)
  _udp.write((uint8_t)0);
  _udp.write((uint8_t)4);
  _udp.write(_resolvedIP, sizeof(_resolvedIP));
  _udp.endPacket();
}

void DNSServer::replyWithCustomCode()
{
  _dnsHeader->QR = DNS_QR_RESPONSE;
  _dnsHeader->RCode = (unsigned char)_errorReplyCode;
  _dnsHeader->QDCount = 0;

  _udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
  _udp.write(_buffer, sizeof(DNSHeader));
  _udp.endPacket();
}

Any suggestions
User avatar
By burkmurray
#21169 Does the example code run for you?

knovoselic posted an update to his DNSServer library a couple of days ago, with a CaptivePortal example sketch:

https://github.com/knovoselic/Arduino/tree/dns_server_improvements/hardware/esp8266com/esp8266/libraries/DNSServer

Make sure to replace the src folder - he's updated the library to accept "*" instead of a domain name, to redirect all traffic.

It's working for me, though with a few quirks: it sometimes trips Apple's CNA, and doesn't support redirection for https URLs. Give it a try.
User avatar
By SwiCago
#21173
burkmurray wrote:Does the example code run for you?

knovoselic posted an update to his DNSServer library a couple of days ago, with a CaptivePortal example sketch:

https://github.com/knovoselic/Arduino/tree/dns_server_improvements/hardware/esp8266com/esp8266/libraries/DNSServer

Make sure to replace the src folder - he's updated the library to accept "*" instead of a domain name, to redirect all traffic.

It's working for me, though with a few quirks: it sometimes trips Apple's CNA, and doesn't support redirection for https URLs. Give it a try.


I literally downloaded it today, but from the original git. Let me try his variation and see


EDIT: Just tried with his source. Even used the example ino and uploaded it. The AP starts. The webserver responds, when accessed directly via IP....but nothing happens when entering any domain. Just does not respond with latest android chrome browser.
User avatar
By burkmurray
#21176 Your code works for me with the URL example.com, using the latest iteration of the library. I had to load the page a couple of times (probably because my browser had it cached), then up popped your green and red menu. It controls the LED on my pin 0 (although backwards - mine is wired HIGH for OFF).

Modifying your code to replace
Code: Select all    dnsServer.start(DNS_PORT, "www.example.com", apIP);

with
Code: Select all    dnsServer.start(DNS_PORT, "*", apIP);


works with any simple URL, but doesn't parse addresses with specific pages, e.g., esp8266.com/test - they're getting redirected, but your server displays:

Code: Select all    Not found: /test


I'm having the same trouble with my sample code, and I was just about to dig into it.

I'm using an iPad and an iPhone to test the connections, and both are working fine. What system/OS are you using to connect to the ESP8266?