mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +03:00
Add an LLMNR responder implementation (#2880)
This is a simple implementation of an LLMNR responder for the ESP8266 Arduino package. Only support for advertizing a single hostname is currently implemented. LLMNR is a very similar protocol to MDNS. The primary practical difference is that Windows systems (at least Windows 7 and later; perhaps earlier) support the protocol out-of-the-box, whereas additional software is required to support MDNS. However, Linux support is currently more complex, and MacOS X support appears non-existent.
This commit is contained in:
parent
d2b370b22d
commit
04df3adb54
281
libraries/ESP8266LLMNR/ESP8266LLMNR.cpp
Normal file
281
libraries/ESP8266LLMNR/ESP8266LLMNR.cpp
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
/*
|
||||||
|
* ESP8266 LLMNR responder
|
||||||
|
* Copyright (C) 2017 Stephen Warren <swarren@wwwdotorg.org>
|
||||||
|
*
|
||||||
|
* Based on:
|
||||||
|
* ESP8266 Multicast DNS (port of CC3000 Multicast DNS library)
|
||||||
|
* Version 1.1
|
||||||
|
* Copyright (c) 2013 Tony DiCola (tony@tonydicola.com)
|
||||||
|
* ESP8266 port (c) 2015 Ivan Grokhotkov (ivan@esp8266.com)
|
||||||
|
* MDNS-SD Suport 2015 Hristo Gochkov
|
||||||
|
* Extended MDNS-SD support 2016 Lars Englund (lars.englund@gmail.com)
|
||||||
|
*
|
||||||
|
* License (MIT license):
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* Reference:
|
||||||
|
* https://tools.ietf.org/html/rfc4795 (LLMNR)
|
||||||
|
* https://tools.ietf.org/html/rfc1035 (DNS)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
#include <functional>
|
||||||
|
#include <ESP8266LLMNR.h>
|
||||||
|
#include <WiFiUdp.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <user_interface.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <lwip/udp.h>
|
||||||
|
#include <lwip/igmp.h>
|
||||||
|
#include <include/UdpContext.h>
|
||||||
|
|
||||||
|
//#define LLMNR_DEBUG
|
||||||
|
|
||||||
|
#define BIT(x) (1 << (x))
|
||||||
|
|
||||||
|
#define FLAGS_QR BIT(15)
|
||||||
|
#define FLAGS_OP_SHIFT 11
|
||||||
|
#define FLAGS_OP_MASK 0xf
|
||||||
|
#define FLAGS_C BIT(10)
|
||||||
|
#define FLAGS_TC BIT(9)
|
||||||
|
#define FLAGS_T BIT(8)
|
||||||
|
#define FLAGS_RCODE_SHIFT 0
|
||||||
|
#define FLAGS_RCODE_MASK 0xf
|
||||||
|
|
||||||
|
#define _conn_read16() (((uint16_t)_conn->read() << 8) | _conn->read())
|
||||||
|
#define _conn_read8() _conn->read()
|
||||||
|
#define _conn_readS(b, l) _conn->read((b), (l));
|
||||||
|
|
||||||
|
static const IPAddress LLMNR_MULTICAST_ADDR(224, 0, 0, 252);
|
||||||
|
static const int LLMNR_MULTICAST_TTL = 1;
|
||||||
|
static const int LLMNR_PORT = 5355;
|
||||||
|
|
||||||
|
LLMNRResponder::LLMNRResponder() :
|
||||||
|
_conn(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMNRResponder::~LLMNRResponder() {
|
||||||
|
if (_conn)
|
||||||
|
_conn->unref();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMNRResponder::begin(const char* hostname) {
|
||||||
|
// Max length for a single label in DNS
|
||||||
|
if (strlen(hostname) > 63)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_hostname = hostname;
|
||||||
|
_hostname.toLowerCase();
|
||||||
|
|
||||||
|
_sta_got_ip_handler = WiFi.onStationModeGotIP([this](const WiFiEventStationModeGotIP& event){
|
||||||
|
_restart();
|
||||||
|
});
|
||||||
|
|
||||||
|
_sta_disconnected_handler = WiFi.onStationModeDisconnected([this](const WiFiEventStationModeDisconnected& event) {
|
||||||
|
_restart();
|
||||||
|
});
|
||||||
|
|
||||||
|
return _restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMNRResponder::notify_ap_change() {
|
||||||
|
_restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMNRResponder::_restart() {
|
||||||
|
if (_conn) {
|
||||||
|
_conn->unref();
|
||||||
|
_conn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_addr_t multicast_addr;
|
||||||
|
multicast_addr.addr = (uint32_t)LLMNR_MULTICAST_ADDR;
|
||||||
|
|
||||||
|
if (igmp_joingroup(IP_ADDR_ANY, &multicast_addr) != ERR_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_conn = new UdpContext;
|
||||||
|
_conn->ref();
|
||||||
|
|
||||||
|
if (!_conn->listen(*IP_ADDR_ANY, LLMNR_PORT))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_conn->setMulticastTTL(LLMNR_MULTICAST_TTL);
|
||||||
|
_conn->onRx(std::bind(&LLMNRResponder::_process_packet, this));
|
||||||
|
_conn->connect(multicast_addr, LLMNR_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMNRResponder::_process_packet() {
|
||||||
|
if (!_conn || !_conn->next())
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef LLMNR_DEBUG
|
||||||
|
Serial.println("LLMNR: RX'd packet");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint16_t id = _conn_read16();
|
||||||
|
uint16_t flags = _conn_read16();
|
||||||
|
uint16_t qdcount = _conn_read16();
|
||||||
|
uint16_t ancount = _conn_read16();
|
||||||
|
uint16_t nscount = _conn_read16();
|
||||||
|
uint16_t arcount = _conn_read16();
|
||||||
|
|
||||||
|
#ifdef LLMNR_DEBUG
|
||||||
|
Serial.print("LLMNR: ID=");
|
||||||
|
Serial.println(id, HEX);
|
||||||
|
Serial.print("LLMNR: FLAGS=");
|
||||||
|
Serial.println(flags, HEX);
|
||||||
|
Serial.print("LLMNR: QDCOUNT=");
|
||||||
|
Serial.println(qdcount);
|
||||||
|
Serial.print("LLMNR: ANCOUNT=");
|
||||||
|
Serial.println(ancount);
|
||||||
|
Serial.print("LLMNR: NSCOUNT=");
|
||||||
|
Serial.println(nscount);
|
||||||
|
Serial.print("LLMNR: ARCOUNT=");
|
||||||
|
Serial.println(arcount);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BAD_FLAGS (FLAGS_QR | (FLAGS_OP_MASK << FLAGS_OP_SHIFT) | FLAGS_C)
|
||||||
|
if (flags & BAD_FLAGS) {
|
||||||
|
#ifdef LLMNR_DEBUG
|
||||||
|
Serial.println("Bad flags");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qdcount != 1) {
|
||||||
|
#ifdef LLMNR_DEBUG
|
||||||
|
Serial.println("QDCOUNT != 1");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ancount || nscount || arcount) {
|
||||||
|
#ifdef LLMNR_DEBUG
|
||||||
|
Serial.println("AN/NS/AR-COUNT != 0");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t namelen = _conn_read8();
|
||||||
|
#ifdef LLMNR_DEBUG
|
||||||
|
Serial.print("QNAME len ");
|
||||||
|
Serial.println(namelen);
|
||||||
|
#endif
|
||||||
|
if (namelen != _hostname.length()) {
|
||||||
|
#ifdef LLMNR_DEBUG
|
||||||
|
Serial.println("QNAME len mismatch");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char qname[64];
|
||||||
|
_conn_readS(qname, namelen);
|
||||||
|
_conn_read8();
|
||||||
|
qname[namelen] = '\0';
|
||||||
|
#ifdef LLMNR_DEBUG
|
||||||
|
Serial.print("QNAME ");
|
||||||
|
Serial.println(qname);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (strcmp(_hostname.c_str(), qname)) {
|
||||||
|
#ifdef LLMNR_DEBUG
|
||||||
|
Serial.println("QNAME mismatch");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t qtype = _conn_read16();
|
||||||
|
uint16_t qclass = _conn_read16();
|
||||||
|
|
||||||
|
#ifdef LLMNR_DEBUG
|
||||||
|
Serial.print("QTYPE ");
|
||||||
|
Serial.print(qtype);
|
||||||
|
Serial.print(" QCLASS ");
|
||||||
|
Serial.println(qclass);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool have_rr =
|
||||||
|
(qtype == 1) && /* A */
|
||||||
|
(qclass == 1); /* IN */
|
||||||
|
|
||||||
|
_conn->flush();
|
||||||
|
|
||||||
|
#ifdef LLMNR_DEBUG
|
||||||
|
Serial.println("Match; responding");
|
||||||
|
if (!have_rr)
|
||||||
|
Serial.println("(no matching RRs)");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ip_info remote_ip_info;
|
||||||
|
remote_ip_info.ip.addr = _conn->getRemoteAddress();
|
||||||
|
struct ip_info ip_info;
|
||||||
|
bool match_ap = false;
|
||||||
|
if (wifi_get_opmode() & SOFTAP_MODE) {
|
||||||
|
wifi_get_ip_info(SOFTAP_IF, &ip_info);
|
||||||
|
if (ip_info.ip.addr && ip_addr_netcmp(&remote_ip_info.ip, &ip_info.ip, &ip_info.netmask))
|
||||||
|
match_ap = true;
|
||||||
|
}
|
||||||
|
if (!match_ap)
|
||||||
|
wifi_get_ip_info(STATION_IF, &ip_info);
|
||||||
|
uint32_t ip = ip_info.ip.addr;
|
||||||
|
|
||||||
|
// Header
|
||||||
|
uint8_t header[] = {
|
||||||
|
id >> 8, id & 0xff, // ID
|
||||||
|
FLAGS_QR >> 8, 0, // FLAGS
|
||||||
|
0, 1, // QDCOUNT
|
||||||
|
0, !!have_rr, // ANCOUNT
|
||||||
|
0, 0, // NSCOUNT
|
||||||
|
0, 0, // ARCOUNT
|
||||||
|
};
|
||||||
|
_conn->append(reinterpret_cast<const char*>(header), sizeof(header));
|
||||||
|
// Question
|
||||||
|
_conn->append(reinterpret_cast<const char*>(&namelen), 1);
|
||||||
|
_conn->append(qname, namelen);
|
||||||
|
uint8_t q[] = {
|
||||||
|
0, // Name terminator
|
||||||
|
0, 1, // TYPE (A)
|
||||||
|
0, 1, // CLASS (IN)
|
||||||
|
};
|
||||||
|
_conn->append(reinterpret_cast<const char*>(q), sizeof(q));
|
||||||
|
// Answer, if we have one
|
||||||
|
if (have_rr) {
|
||||||
|
_conn->append(reinterpret_cast<const char*>(&namelen), 1);
|
||||||
|
_conn->append(qname, namelen);
|
||||||
|
uint8_t rr[] = {
|
||||||
|
0, // Name terminator
|
||||||
|
0, 1, // TYPE (A)
|
||||||
|
0, 1, // CLASS (IN)
|
||||||
|
0, 0, 0, 30, // TTL (30 seconds)
|
||||||
|
0, 4, // RDLENGTH
|
||||||
|
ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff, // RDATA
|
||||||
|
};
|
||||||
|
_conn->append(reinterpret_cast<const char*>(rr), sizeof(rr));
|
||||||
|
}
|
||||||
|
_conn->setMulticastInterface(remote_ip_info.ip);
|
||||||
|
_conn->send(&remote_ip_info.ip, _conn->getRemotePort());
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_LLMNR)
|
||||||
|
LLMNRResponder LLMNR;
|
||||||
|
#endif
|
66
libraries/ESP8266LLMNR/ESP8266LLMNR.h
Normal file
66
libraries/ESP8266LLMNR/ESP8266LLMNR.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* ESP8266 LLMNR responder
|
||||||
|
* Copyright (C) 2017 Stephen Warren <swarren@wwwdotorg.org>
|
||||||
|
*
|
||||||
|
* Based on:
|
||||||
|
* ESP8266 Multicast DNS (port of CC3000 Multicast DNS library)
|
||||||
|
* Version 1.1
|
||||||
|
* Copyright (c) 2013 Tony DiCola (tony@tonydicola.com)
|
||||||
|
* ESP8266 port (c) 2015 Ivan Grokhotkov (ivan@esp8266.com)
|
||||||
|
* MDNS-SD Suport 2015 Hristo Gochkov
|
||||||
|
* Extended MDNS-SD support 2016 Lars Englund (lars.englund@gmail.com)
|
||||||
|
*
|
||||||
|
* License (MIT license):
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ESP8266LLMNR_H
|
||||||
|
#define ESP8266LLMNR_H
|
||||||
|
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
|
||||||
|
class UdpContext;
|
||||||
|
|
||||||
|
class LLMNRResponder {
|
||||||
|
public:
|
||||||
|
LLMNRResponder();
|
||||||
|
~LLMNRResponder();
|
||||||
|
|
||||||
|
/* Initialize and start responding to LLMNR requests on all interfaces */
|
||||||
|
bool begin(const char* hostname);
|
||||||
|
|
||||||
|
/* Application should call this whenever AP is configured/disabled */
|
||||||
|
void notify_ap_change();
|
||||||
|
|
||||||
|
private:
|
||||||
|
String _hostname;
|
||||||
|
UdpContext *_conn;
|
||||||
|
WiFiEventHandler _sta_got_ip_handler;
|
||||||
|
WiFiEventHandler _sta_disconnected_handler;
|
||||||
|
|
||||||
|
bool _restart();
|
||||||
|
void _process_packet();
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_LLMNR)
|
||||||
|
extern LLMNRResponder LLMNR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
92
libraries/ESP8266LLMNR/README.md
Normal file
92
libraries/ESP8266LLMNR/README.md
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
ESP8266 LLMNR (Link-Local Multicast Name Resolution)
|
||||||
|
====================================================
|
||||||
|
|
||||||
|
This is a simple implementation of an LLMNR responder the ESP8266 Arduino
|
||||||
|
package. Only support for advertizing a single hostname is currently
|
||||||
|
implemented.
|
||||||
|
|
||||||
|
LLMNR is a very similar protocol to MDNS. The primary practical difference is
|
||||||
|
that Windows systems (at least Windows 7 and later; perhaps earlier) support
|
||||||
|
the protocol out-of-the-box, whereas additional software is required to support
|
||||||
|
MDNS. However, Linux support is currently more complex, and MacOS X support
|
||||||
|
appears non-existent.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
- ESP8266WiFi library
|
||||||
|
- LLMNR support in your operating system/client machines:
|
||||||
|
- For Windows, support is already built in (in Windows 7 at least).
|
||||||
|
- For Linux, the systemd-resolve application supports LLMNR.
|
||||||
|
- For Mac OSX: Unknown; likely not supported.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
1. Install this repository using the instructions in the top-levle README.md
|
||||||
|
file.
|
||||||
|
2. Include the ESP8266LLMNR library in the sketch.
|
||||||
|
3. Call the LLMNR.begin() method in the sketch's setup() function, and provide
|
||||||
|
the hostname to advertize. This should not include any ".local" prefix.
|
||||||
|
4. If ESP8266 AP mode is enabled, disabled, or the WiFi or AP configuration is
|
||||||
|
changed, call LLMNR.notify_ap_change() after the change is made.
|
||||||
|
|
||||||
|
See the included LLMNR + HTTP server sketch for a full example.
|
||||||
|
|
||||||
|
References
|
||||||
|
----------
|
||||||
|
1. https://tools.ietf.org/html/rfc4795 (LLMNR)
|
||||||
|
2. https://tools.ietf.org/html/rfc1035 (DNS)
|
||||||
|
|
||||||
|
Caveats
|
||||||
|
-------
|
||||||
|
1. LLMNR implementations MUST support EDNS0 [RFC2671] and extended RCODE
|
||||||
|
values. It is likely that this implementation does not; I have not read
|
||||||
|
that RFC.
|
||||||
|
2. LLMNR responders MUST support listening for TCP queries. This implementation
|
||||||
|
does not.
|
||||||
|
3. On receiving an LLMNR query, the responder MUST check whether it was sent to
|
||||||
|
an LLMNR multicast addresses defined in Section 2. If it was sent to another
|
||||||
|
multicast address, then the query MUST be silently discarded. This
|
||||||
|
implementation makes no such check; it is hoped that the ESP8266 network
|
||||||
|
stack filters out such packets since the code only joins the relevant
|
||||||
|
multicast group and does not listen for unicast packets. This assumption may
|
||||||
|
be invalid.
|
||||||
|
4. Prior to sending an LLMNR response with the 'T' bit clear, a responder
|
||||||
|
configured with a UNIQUE name MUST verify that there is no other host within
|
||||||
|
the scope of LLMNR query propagation that is authoritative for the same name
|
||||||
|
on that interface. This implementation performs no such verification.
|
||||||
|
5. Prior to verifying that its name is UNIQUE, a responder MUST set the 'T' bit
|
||||||
|
in responses. This implementation does not; it assumes that name is unique
|
||||||
|
and responds with the 'T' bit clear in all cases.
|
||||||
|
6. To verify uniqueness, a responder MUST send an LLMNR query with the 'C' bit
|
||||||
|
clear, over all protocols on which it responds to LLMNR queries (IPv4 and/or
|
||||||
|
IPv6). This implementation does not.
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
Copyright (C) 2017 Stephen Warren <swarren@wwwdotorg.org>
|
||||||
|
|
||||||
|
Based on:
|
||||||
|
ESP8266 Multicast DNS (port of CC3000 Multicast DNS library)
|
||||||
|
Version 1.1
|
||||||
|
Copyright (c) 2013 Tony DiCola (tony@tonydicola.com)
|
||||||
|
ESP8266 port (c) 2015 Ivan Grokhotkov (ivan@esp8266.com)
|
||||||
|
MDNS-SD Suport 2015 Hristo Gochkov
|
||||||
|
Extended MDNS-SD support 2016 Lars Englund (lars.englund@gmail.com)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* ESP8266 LLMNR responder sample
|
||||||
|
* Copyright (C) 2017 Stephen Warren <swarren@wwwdotorg.org>
|
||||||
|
*
|
||||||
|
* Based on:
|
||||||
|
* ESP8266 Multicast DNS (port of CC3000 Multicast DNS library)
|
||||||
|
* Version 1.1
|
||||||
|
* Copyright (c) 2013 Tony DiCola (tony@tonydicola.com)
|
||||||
|
* ESP8266 port (c) 2015 Ivan Grokhotkov (ivan@esp8266.com)
|
||||||
|
* MDNS-SD Suport 2015 Hristo Gochkov
|
||||||
|
* Extended MDNS-SD support 2016 Lars Englund (lars.englund@gmail.com)
|
||||||
|
*
|
||||||
|
* License (MIT license):
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This is an example of an HTTP server that is accessible via http://esp8266/
|
||||||
|
* (or perhaps http://esp8266.local/) thanks to the LLMNR responder.
|
||||||
|
*
|
||||||
|
* Instructions:
|
||||||
|
* - Update WiFi SSID and password as necessary.
|
||||||
|
* - Flash the sketch to the ESP8266 board.
|
||||||
|
* - Windows:
|
||||||
|
* - No additional software is necessary.
|
||||||
|
* - Point your browser to http://esp8266/, you should see a response. In most
|
||||||
|
* cases, it is important that you manually type the "http://" to force the
|
||||||
|
* browser to search for a hostname to connect to, rather than perform a web
|
||||||
|
* search.
|
||||||
|
* - Alternatively, run the following command from the command prompt:
|
||||||
|
* ping esp8266
|
||||||
|
* - Linux:
|
||||||
|
* - To validate LLMNR, install the systemd-resolve utility.
|
||||||
|
* - Execute the following command:
|
||||||
|
* systemd-resolve -4 -p llmnr esp8266
|
||||||
|
* - It may be possible to configure your system to use LLMNR for all name
|
||||||
|
* lookups. However, that is beyond the scope of this description.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESP8266LLMNR.h>
|
||||||
|
#include <ESP8266WebServer.h>
|
||||||
|
#include <WiFiClient.h>
|
||||||
|
|
||||||
|
const char* ssid = "replace_me";
|
||||||
|
const char* password = "replace_me";
|
||||||
|
|
||||||
|
ESP8266WebServer web_server(80);
|
||||||
|
|
||||||
|
void handle_http_not_found() {
|
||||||
|
web_server.send(404, "text/plain", "Not Found");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_http_root() {
|
||||||
|
web_server.send(200, "text/plain", "It works!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup(void) {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
// Connect to WiFi network
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
Serial.println("");
|
||||||
|
|
||||||
|
// Wait for connection
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print("Connected to ");
|
||||||
|
Serial.println(ssid);
|
||||||
|
Serial.print("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
// Start LLMNR responder
|
||||||
|
LLMNR.begin("esp8266");
|
||||||
|
Serial.println("LLMNR responder started");
|
||||||
|
// Start HTTP server
|
||||||
|
web_server.onNotFound(handle_http_not_found);
|
||||||
|
web_server.on("/", handle_http_root);
|
||||||
|
web_server.begin();
|
||||||
|
Serial.println("HTTP server started");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(void) {
|
||||||
|
web_server.handleClient();
|
||||||
|
}
|
23
libraries/ESP8266LLMNR/keywords.txt
Normal file
23
libraries/ESP8266LLMNR/keywords.txt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#######################################
|
||||||
|
# Syntax Coloring Map For Ultrasound
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
ESP8266LLMNR KEYWORD1
|
||||||
|
LLMNRResponder KEYWORD1
|
||||||
|
LLMNR KEYWORD1
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
begin KEYWORD2
|
||||||
|
notify_ap_change KEYWORD2
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Constants (LITERAL1)
|
||||||
|
#######################################
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user