-->
Page 1 of 1

Offline html page *Auto redirect*

PostPosted: Tue May 16, 2017 3:30 am
by KINGSNAKE
"So I am new to the esp8266 and to programming so if my question seems stupid u know why"

And with that out of the way lets get down to it..

So i want to make the esp8266 into a WiFi network that redirects any traffic to a offline web page. I know it is possible to host a web page from the esp8266 but you have to specifically type in the gateway IP to view it. My question is .... Can i make it automatically redirect people to the web page ?.

Re: Offline html page *Auto redirect*

PostPosted: Tue May 16, 2017 11:58 am
by rudy
It is not a stupid question. From what I have seen it actually is difficult to do if you expect that to happen with any connecting device. (Apple, Windows, Android)

Do a search to Captive Portal.

Also search for .local

viewtopic.php?f=32&t=14807

viewtopic.php?p=61820

Re: Offline html page *Auto redirect*

PostPosted: Tue May 16, 2017 7:55 pm
by KINGSNAKE
rudy wrote:It is not a stupid question. From what I have seen it actually is difficult to do if you expect that to happen with any connecting device. (Apple, Windows, Android)

Do a search to Captive Portal.

Also search for .local

viewtopic.php?f=32&t=14807

viewtopic.php?p=61820


******************************************************************************

Thanks for the Response :D . I have tried using captive portal before with some success. however it will only redirect if i type in something like google.com but if i just type google it wont redirect even though when uo type in google it goes to google.com/google ????? here is the code im using to test








#include "./DNSServer.h"
#include <lwip/def.h>
#include <Arduino.h>

#define DEBUG
#define DEBUG_OUTPUT Serial

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() &&
(_domainName == "*" || 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 += "www";
}
}
}

void DNSServer::replyWithIP()
{
_dnsHeader->QR = DNS_QR_RESPONSE;
_dnsHeader->ANCount = _dnsHeader->QDCount;
_dnsHeader->QDCount = _dnsHeader->QDCount;
//_dnsHeader->RA = 1;

_udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
_udp.write(_buffer, _currentPacketSize);

_udp.write((uint8_t)192); // answer name is a pointer
_udp.write((uint8_t)12); // pointer to offset at 0x00c

_udp.write((uint8_t)0); // 0x0001 answer is type A query (host address)
_udp.write((uint8_t)1);

_udp.write((uint8_t)0); //0x0001 answer is class IN (internet address)
_udp.write((uint8_t)1);

_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();



#ifdef DEBUG
DEBUG_OUTPUT.print("DNS responds: ");
DEBUG_OUTPUT.print(_resolvedIP[0]);
DEBUG_OUTPUT.print(".");
DEBUG_OUTPUT.print(_resolvedIP[1]);
DEBUG_OUTPUT.print(".");
DEBUG_OUTPUT.print(_resolvedIP[2]);
DEBUG_OUTPUT.print(".");
DEBUG_OUTPUT.print(_resolvedIP[3]);
DEBUG_OUTPUT.print(" for ");
DEBUG_OUTPUT.println(getDomainNameWithoutWwwPrefix());
#endif
}

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();
}