forked from esp8266/Arduino
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathIPv6.ino
187 lines (145 loc) · 4.68 KB
/
IPv6.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
arduino IPv6 example
released to public domain
output is like:
SDK:2.2.1(cfd48f3)/Core:2.4.2-141-g4f97603/lwIP:IPv6+STABLE-2_1_0_RC1/glue:arduino-2.4.2-30-ga53619c/BearSSL:6d1cefc
dns0=10.43.1.254
Try me at these addresses:
(with 'telnet <addr> or 'nc -u <addr> 23')
IF='st'(0) IPv6=0 local=0 hostname='ipv6test' addr= 10.43.1.244 / mask:255.255.255.0 / gw:10.43.1.254
IF='st'(0) IPv6=1 local=1 hostname='ipv6test' addr= fe80::1afe:34ff:fed1:cec7
IF='st'(0) IPV6=1 local=0 hostname='ipv6test' addr= 2xxx:xxxx:xxxx:xxxx:1afe:34ff:fed1:cec7
resolving www.google.com: 216.58.205.100
resolving ipv6.google.com: 2a00:1450:4002:808::200e
*/
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <PolledTimeout.h>
#include <AddrList.h>
#include <lwip/dns.h>
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#endif
#define FQDN F("www.google.com") // with both IPv4 & IPv6 addresses
#define FQDN6 F("ipv6.google.com") // does not resolve in IPv4
#define STATUSDELAY_MS 10000
#define TCP_PORT 23
#define UDP_PORT 23
WiFiServer statusServer(TCP_PORT);
WiFiUDP udp;
esp8266::polledTimeout::periodic statusPeriod(STATUSDELAY_MS);
void fqdn(Print& out, const String& fqdn) {
out.print(F("resolving "));
out.print(fqdn);
out.print(F(": "));
IPAddress result;
if (WiFi.hostByName(fqdn.c_str(), result)) {
result.printTo(out);
out.println();
} else {
out.println(F("timeout or not found"));
}
}
void status(Print& out) {
out.println(F("------------------------------"));
out.println(ESP.getFullVersion());
dns_setserver(DNS_MAX_SERVERS - 1, IPAddress(8, 8, 8, 8));
for (int i = 0; i < DNS_MAX_SERVERS; i++) {
IPAddress dns = WiFi.dnsIP(i);
if (dns.isSet()) {
out.printf("dns%d: %s\n", i, dns.toString().c_str());
}
}
out.println(F("Try me at these addresses:"));
out.println(F("(with 'telnet <addr> or 'nc -u <addr> 23')"));
for (auto a : addrList) {
out.printf("IF='%s' IPv6=%d local=%d hostname='%s' addr= %s",
a.ifname().c_str(),
a.isV6(),
a.isLocal(),
a.ifhostname(),
a.toString().c_str());
if (a.isLegacy()) {
out.printf(" / mask:%s / gw:%s",
a.netmask().toString().c_str(),
a.gw().toString().c_str());
}
out.println();
}
// lwIP's dns client will ask for IPv4 first (by default)
// an example is provided with a fqdn which does not resolve with IPv4
fqdn(out, FQDN);
fqdn(out, FQDN6);
out.println(F("------------------------------"));
}
void setup() {
WiFi.hostname("ipv6test");
Serial.begin(115200);
Serial.println();
Serial.println(ESP.getFullVersion());
Serial.printf("IPV6 is%s enabled\n", LWIP_IPV6 ? emptyString.c_str() : " NOT");
WiFi.mode(WIFI_STA);
WiFi.begin(STASSID, STAPSK);
status(Serial);
#if 0 // 0: legacy connecting loop - 1: wait for IPv6
// legacy loop (still valid with IPv4 only)
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(500);
}
#else
// Use this loop instead to wait for an IPv6 routable address
// addr->isLocal() (meaning "not routable on internet") is true with:
// - IPV4 DHCP autoconfigured address 169.254.x.x
// (false for any other including 192.168./16 and 10./24 since NAT may be in the equation)
// - IPV6 link-local addresses (fe80::/64)
for (bool configured = false; !configured;) {
for (auto addr : addrList)
if ((configured = !addr.isLocal()
// && addr.isV6() // uncomment when IPv6 is mandatory
// && addr.ifnumber() == STATION_IF
)) {
break;
}
Serial.print('.');
delay(500);
}
#endif
Serial.println(F("connected: "));
statusServer.begin();
udp.begin(UDP_PORT);
Serial.print(F("TCP server on port "));
Serial.print(TCP_PORT);
Serial.print(F(" - UDP server on port "));
Serial.println(UDP_PORT);
statusPeriod.reset();
}
unsigned long statusTimeMs = 0;
void loop() {
if (statusServer.hasClient()) {
WiFiClient cli = statusServer.available();
status(cli);
}
// if there's data available, read a packet
int packetSize = udp.parsePacket();
if (packetSize) {
Serial.print(F("udp received "));
Serial.print(packetSize);
Serial.print(F(" bytes from "));
udp.remoteIP().printTo(Serial);
Serial.print(F(" :"));
Serial.println(udp.remotePort());
int c;
while ((c = udp.read()) >= 0) {
Serial.write(c);
}
// send a reply, to the IP address and port that sent us the packet we received
udp.beginPacket(udp.remoteIP(), udp.remotePort());
status(udp);
udp.endPacket();
}
if (statusPeriod) {
status(Serial);
}
}