From 694732f20362c554cba3981dd6e35b6aa300cf53 Mon Sep 17 00:00:00 2001 From: hreintke Date: Sat, 14 Sep 2019 16:05:56 +0200 Subject: [PATCH 01/22] Netdump library, initial commit --- libraries/Netdump/README.md | 52 ++++ libraries/Netdump/astyle_goodies.conf | 32 +++ libraries/Netdump/examples/Netdump.ino | 75 +++++ libraries/Netdump/keywords.txt | 1 + libraries/Netdump/library.properties | 9 + libraries/Netdump/src/Netdump.cpp | 198 +++++++++++++ libraries/Netdump/src/Netdump.h | 77 +++++ libraries/Netdump/src/NetdumpIP.cpp | 360 ++++++++++++++++++++++++ libraries/Netdump/src/NetdumpIP.h | 99 +++++++ libraries/Netdump/src/NetdumpPacket.cpp | 228 +++++++++++++++ libraries/Netdump/src/NetdumpPacket.h | 265 +++++++++++++++++ 11 files changed, 1396 insertions(+) create mode 100644 libraries/Netdump/README.md create mode 100644 libraries/Netdump/astyle_goodies.conf create mode 100644 libraries/Netdump/examples/Netdump.ino create mode 100644 libraries/Netdump/keywords.txt create mode 100644 libraries/Netdump/library.properties create mode 100644 libraries/Netdump/src/Netdump.cpp create mode 100644 libraries/Netdump/src/Netdump.h create mode 100644 libraries/Netdump/src/NetdumpIP.cpp create mode 100644 libraries/Netdump/src/NetdumpIP.h create mode 100644 libraries/Netdump/src/NetdumpPacket.cpp create mode 100644 libraries/Netdump/src/NetdumpPacket.h diff --git a/libraries/Netdump/README.md b/libraries/Netdump/README.md new file mode 100644 index 0000000000..7db9c725af --- /dev/null +++ b/libraries/Netdump/README.md @@ -0,0 +1,52 @@ + +esp8266/Arduino goodies +----------------------- + +* NetDump (lwip2) + Packet sniffer library to help study network issues, check example-sketches + Log examples on serial console: +``` +14:07:01.854 -> in 0 ARP who has 10.43.1.117 tell 10.43.1.254 +14:07:01.854 -> out 0 ARP 10.43.1.117 is at 5c:cf:7f:c3:ad:51 + +[...] hello-world, dumped in packets: +14:07:46.227 -> in 0 IPv4 10.43.1.254>10.43.1.117 TCP 54546>2[P.] seq:1945448681..1945448699 ack:6618 win:29200 len=18 +14:07:46.260 -> 5c cf 7f c3 ad 51 74 da 38 3a 1f 61 08 00 45 10 \..Qt.8:.a..E. +14:07:46.260 -> 00 3a b2 bc 40 00 40 06 70 29 0a 2b 01 fe 0a 2b .:..@.@.p).+...+ +14:07:46.260 -> 01 75 d5 12 00 02 73 f5 30 e9 00 00 19 da 50 18 .u....s.0.....P. +14:07:46.260 -> 72 10 f8 da 00 00 70 6c 20 68 65 6c 6c 6f 2d 77 r.....pl hello-w +14:07:46.260 -> 6f 72 6c 64 20 31 0d 0a orld 1.. +14:07:46.294 -> out 0 IPv4 10.43.1.117>10.43.1.254 TCP 2>54546[P.] seq:6618..6619 ack:1945448699 win:2126 len=1 +14:07:46.326 -> 00 20 00 00 00 00 aa aa 03 00 00 00 08 00 45 00 . ............E. +14:07:46.326 -> 00 29 00 0d 00 00 ff 06 a3 f9 0a 2b 01 75 0a 2b .).........+.u.+ +14:07:46.327 -> 01 fe 00 02 d5 12 00 00 19 da 73 f5 30 fb 50 18 ..........s.0.P. +14:07:46.327 -> 08 4e 93 d5 00 00 68 .N....h +14:07:46.327 -> in 0 IPv4 10.43.1.254>10.43.1.117 TCP 54546>2[.] seq:1945448699 ack:6619 win:29200 +14:07:46.327 -> 5c cf 7f c3 ad 51 74 da 38 3a 1f 61 08 00 45 10 \..Qt.8:.a..E. +14:07:46.360 -> 00 28 b2 bd 40 00 40 06 70 3a 0a 2b 01 fe 0a 2b .(..@.@.p:.+...+ +14:07:46.360 -> 01 75 d5 12 00 02 73 f5 30 fb 00 00 19 db 50 10 .u....s.0.....P. +14:07:46.360 -> 72 10 92 1b 00 00 r..... +14:07:46.360 -> out 0 IPv4 10.43.1.117>10.43.1.254 TCP 2>54546[P.] seq:6619..6630 ack:1945448699 win:2126 len=11 +14:07:46.360 -> 00 20 00 00 00 00 aa aa 03 00 00 00 08 00 45 00 . ............E. +14:07:46.360 -> 00 33 00 0e 00 00 ff 06 a3 ee 0a 2b 01 75 0a 2b .3.........+.u.+ +14:07:46.393 -> 01 fe 00 02 d5 12 00 00 19 db 73 f5 30 fb 50 18 ..........s.0.P. +14:07:46.393 -> 08 4e 16 a1 00 00 65 6c 6c 6f 2d 77 6f 72 6c 64 .N....ello-world +14:07:46.393 -> 0a . + +[...] help protocol decoding from inside the esp +14:08:11.715 -> in 0 IPv4 10.43.1.254>239.255.255.250 UDP 50315>1900 len=172 +14:08:11.716 -> 01 00 5e 7f ff fa 74 da 38 3a 1f 61 08 00 45 00 ....t.8:.a..E. +14:08:11.716 -> 00 c8 9b 40 40 00 01 11 e1 c1 0a 2b 01 fe ef ff ...@@......+.... +14:08:11.749 -> ff fa c4 8b 07 6c 00 b4 9c 28 4d 2d 53 45 41 52 .....l...(M-SEAR +14:08:11.749 -> 43 48 20 2a 20 48 54 54 50 2f 31 2e 31 0d 0a 48 CH * HTTP/1.1..H +14:08:11.749 -> 4f 53 54 3a 20 32 33 39 2e 32 35 35 2e 32 35 35 OST: 239.255.255 +14:08:11.749 -> 2e 32 35 30 3a 31 39 30 30 0d 0a 4d 41 4e 3a 20 .250:1900..MAN: +14:08:11.749 -> 22 73 73 64 70 3a 64 69 73 63 6f 76 65 72 22 0d "ssdp:discover". +14:08:11.749 -> 0a 4d 58 3a 20 31 0d 0a 53 54 3a 20 75 72 6e 3a .MX: 1..ST: urn: +14:08:11.782 -> 64 69 61 6c 2d 6d 75 6c 74 69 73 63 72 65 65 6e dial-multiscreen +14:08:11.782 -> 2d 6f 72 67 3a 73 65 72 76 69 63 65 3a 64 69 61 -org:service:dia +14:08:11.782 -> 6c 3a 31 0d 0a 55 53 45 52 2d 41 47 45 4e 54 3a l:1..USER-AGENT: +14:08:11.782 -> 20 47 6f 6f 67 6c 65 20 43 68 72 6f 6d 65 2f 36 Google Chrome/6 +14:08:11.782 -> 36 2e 30 2e 33 33 35 39 2e 31 31 37 20 4c 69 6e 6.0.3359.117 Lin +14:08:11.782 -> 75 78 0d 0a 0d 0a ux.... + diff --git a/libraries/Netdump/astyle_goodies.conf b/libraries/Netdump/astyle_goodies.conf new file mode 100644 index 0000000000..b1c6ed376e --- /dev/null +++ b/libraries/Netdump/astyle_goodies.conf @@ -0,0 +1,32 @@ +# Code formatting rules for Arduino examples, taken from: +# +# https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf +# + +mode=c +lineend=linux +style=allman + +# 4 spaces indentation +indent=spaces=4 + +# also indent macros +#indent-preprocessor + +# indent classes, switches (and cases), comments starting at column 1 +indent-col1-comments + +# put a space around operators +pad-oper + +# put a space after if/for/while +pad-header + +# if you like one-liners, keep them +keep-one-line-statements + +attach-closing-while +unpad-paren +pad-oper +remove-comment-prefix +add-braces \ No newline at end of file diff --git a/libraries/Netdump/examples/Netdump.ino b/libraries/Netdump/examples/Netdump.ino new file mode 100644 index 0000000000..a5aec8b284 --- /dev/null +++ b/libraries/Netdump/examples/Netdump.ino @@ -0,0 +1,75 @@ +// Do not remove the include below +#include "NetDumpTest.h" +#include +#include "LocalDefines.h" +#include +#include +#include + +/* + dump network packets on serial console + released to the public domain +*/ + + +Netdump nd; +ESP8266WebServer server(80); +WiFiServer ws(8000); + + +void handleRoot() { + static int rq = 0; + String a = "

You are connected, rq = "+String(rq++)+"

"; + server.send(200, "text/html", a); +} + + +File outfile = SPIFFS.open("test", "w"); + +void setup(void) { + Serial.begin(115200); + + WiFi.mode(WIFI_STA); + WiFi.begin(ssid,password); + SPIFFS.begin(); + + server.on("/", handleRoot); + server.begin(); + +/* +// To serial, include hex print only localIP traffic + nd.printDump(Serial, true, + [](NetdumpPacket n) + { + return ((n.ethType() != 0x8912) && + ((n.sourceIP()==WiFi.localIP()) || n.destIP()==WiFi.localIP()) ); + }); +*/ + +/* +// To serial, include hex print only localIP traffic + nd.printDump(Serial, false); // To serial all traffic, no hex dump +*/ + +/* + nd.printDump(outfile, false); // To file all traffic, no hex dump, format ascii +*/ + +/* + nd.fileDump(outfile, false); // To file all traffic, no hex dump, format pcap file +*/ + +/* +// To telnet, all traffic, use `n 10.0.0.212 8000 | tcpdump -r -` + ws.begin(); + nd.tcpDump(ws); + +*/ + + +} + +void loop(void) { + server.handleClient(); + +} diff --git a/libraries/Netdump/keywords.txt b/libraries/Netdump/keywords.txt new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/libraries/Netdump/keywords.txt @@ -0,0 +1 @@ + diff --git a/libraries/Netdump/library.properties b/libraries/Netdump/library.properties new file mode 100644 index 0000000000..1ff03d2128 --- /dev/null +++ b/libraries/Netdump/library.properties @@ -0,0 +1,9 @@ +name=NetDump +version=2 +author=David Gauchard +maintainer=David Gauchard +sentence=tcpdump-like logger for esp8266/Arduino +paragraph=Dumps input / output packets on "Print"able type, or provide a TCP server for the real tcpdump. Check examples. Some other unrelated and independant tools are included. +category=Communication +url=https:// +architectures=esp8266 diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp new file mode 100644 index 0000000000..10304d26e5 --- /dev/null +++ b/libraries/Netdump/src/Netdump.cpp @@ -0,0 +1,198 @@ +/* + NetDump library - tcpdump-like packet logger facility + + Copyright (c) 2018 David Gauchard. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Netdump.h" +#include +#include "Schedule.h" + +Netdump* Netdump::self; + +void Netdump::setCallback(NetdumpCallback nc) +{ + netDumpCallback = nc; +} +void Netdump::setCallback(NetdumpCallback nc, NetdumpFilter nf) +{ + netDumpFilter = nf; + netDumpCallback = nc; +} +void Netdump::setFilter(NetdumpFilter nf) +{ + netDumpFilter = nf; +} +void Netdump::reset() +{ + setCallback(nullptr, nullptr); +} +void Netdump::printDump(Print& out, NetdumpPacket::PacketDetail ndd, NetdumpFilter nf) +{ + out.printf("netDump starting\r\n"); +// setCallback(std::bind(&Netdump::printDumpProcess, this, std::ref(out), ndd, std::placeholders::_1), nf); + setCallback([&out, ndd, this](NetdumpPacket & ndp) + { + printDumpProcess(out, ndd, ndp); + }, nf); + + +} +void Netdump::fileDump(File outfile, NetdumpFilter nf) +{ + + char buf[24]; + + *(uint32_t*)&buf[0] = 0xa1b2c3d4; + *(uint32_t*)&buf[4] = 0x00040002; + *(uint32_t*)&buf[8] = 0; + *(uint32_t*)&buf[12] = 0; + *(uint32_t*)&buf[16] = 1024; + *(uint32_t*)&buf[20] = 1; + + outfile.write(buf, 24); + // setCallback( std::bind(&Netdump::fileDumpProcess, this, outfile, std::placeholders::_1)); + setCallback([outfile, this](NetdumpPacket & ndp) + { + fileDumpProcess(outfile, ndp); + }, nf); +} +void Netdump::tcpDump(WiFiServer &tcpDumpServer, NetdumpFilter nf) +{ + // Get initialize code from netdumpout.cpp + if (packetBuffer) + { + delete packetBuffer; + } + packetBuffer = new char[2048]; + bufferIndex = 0; + + // schedule_function(std::bind(&Netdump::tcpDumpLoop,this,std::ref(tcpDumpServer))); + schedule_function([&tcpDumpServer, this]() + { + tcpDumpLoop(tcpDumpServer); + }); + Serial.printf("scheduled\r\n"); +} + +void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int success) +{ + NetdumpPacket np(netif_idx, data, len, out, success); + if (self->netDumpCallback) + { + if (self->netDumpFilter && !self->netDumpFilter(np)) + { + return; + } + self->netDumpCallback(np); + } +} + +void Netdump::printDumpProcess(Print& out, NetdumpPacket::PacketDetail ndd, NetdumpPacket np) +{ + out.printf("%8d %s", millis(), np.toString(ndd).c_str()); +} +void Netdump::fileDumpProcess(File outfile, NetdumpPacket np) +{ + size_t incl_len = np.len > 1024 ? 1024 : np.len; + char buf[16]; + + struct timeval tv; + gettimeofday(&tv, nullptr); + *(uint32_t*)&buf[0] = tv.tv_sec; + *(uint32_t*)&buf[4] = tv.tv_usec; + *(uint32_t*)&buf[8] = incl_len; + *(uint32_t*)&buf[12] = np.len; + outfile.write(buf, 16); + + outfile.write(np.data, incl_len); +} +void Netdump::tcpDumpProcess(NetdumpPacket np) +{ + // Get capture code from netdumpout.cpp + if (np.isIPv4() && np.isTCP() + && ((np.out && np.getSrcPort() == tcpDumpClient.localPort()) + || (!np.out && np.getDstPort() == tcpDumpClient.localPort()) + ) + ) + { + // skip myself + return; + } + size_t incl_len = np.len > 1024 ? 1024 : np.len; + + struct timeval tv; + gettimeofday(&tv, nullptr); + *(uint32_t*)&packetBuffer[bufferIndex] = tv.tv_sec; + *(uint32_t*)&packetBuffer[bufferIndex + 4] = tv.tv_usec; + *(uint32_t*)&packetBuffer[bufferIndex + 8] = incl_len; + *(uint32_t*)&packetBuffer[bufferIndex + 12] = np.len; + bufferIndex += 16; + memcpy(&packetBuffer[bufferIndex], np.data, incl_len); + bufferIndex += incl_len; + if (bufferIndex && tcpDumpClient && tcpDumpClient.availableForWrite() >= bufferIndex) + { + tcpDumpClient.write(packetBuffer, bufferIndex); + bufferIndex = 0; + } + + +} +void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer) +{ + + if (tcpDumpServer.hasClient()) + { + tcpDumpClient = tcpDumpServer.available(); + //if (fastsend) + tcpDumpClient.setNoDelay(true); + + + // pcap-savefile(5) capture preamble + *(uint32_t*)&packetBuffer[0] = 0xa1b2c3d4; + *(uint32_t*)&packetBuffer[4] = 0x00040002; + *(uint32_t*)&packetBuffer[8] = 0; + *(uint32_t*)&packetBuffer[12] = 0; + *(uint32_t*)&packetBuffer[16] = 1024; + *(uint32_t*)&packetBuffer[20] = 1; + tcpDumpClient.write(packetBuffer, 24); + bufferIndex = 0; + // setCallback(std::bind(&Netdump::tcpDumpProcess,this,std::placeholders::_1)); + setCallback([this](NetdumpPacket & ndp) + { + tcpDumpProcess(ndp); + }); + + Serial.printf("client started\r\n"); + } + if (!tcpDumpClient || !tcpDumpClient.connected()) + { + setCallback(nullptr); + } + if (bufferIndex && tcpDumpClient && tcpDumpClient.availableForWrite() >= bufferIndex) + { + Serial.printf("tcp write %d\r\n", bufferIndex); + tcpDumpClient.write(packetBuffer, bufferIndex); + bufferIndex = 0; + } + // schedule_function(std::bind(&Netdump::tcpDumpLoop,this,std::ref(tcpDumpServer))); + schedule_function([&tcpDumpServer, this]() + { + tcpDumpLoop(tcpDumpServer); + }); +} diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h new file mode 100644 index 0000000000..ba9259a1f0 --- /dev/null +++ b/libraries/Netdump/src/Netdump.h @@ -0,0 +1,77 @@ +/* + NetDump library - tcpdump-like packet logger facility + + Copyright (c) 2018 David Gauchard. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __NETDUMP_H +#define __NETDUMP_H + +#include +#include +#include +#include +//#include +//#include +#include "NetdumpPacket.h" +#include + +using NetdumpFilter = std::function; +using NetdumpCallback = std::function; + +class Netdump +{ +public: + Netdump() + { + phy_capture = capture; + self = this; + }; + virtual ~Netdump() + { + phy_capture = nullptr; + }; + + void setCallback(NetdumpCallback nc); + void setCallback(NetdumpCallback nc, NetdumpFilter nf); + void setFilter(NetdumpFilter nf); + void reset(); + + void printDump(Print& out, NetdumpPacket::PacketDetail ndd, NetdumpFilter nf = nullptr); + void fileDump(File outfile, NetdumpFilter nf = nullptr); + void tcpDump(WiFiServer &tcpDumpServer, NetdumpFilter nf = nullptr); + + +private: + NetdumpCallback netDumpCallback = nullptr; + NetdumpFilter netDumpFilter = nullptr; + + static Netdump* self; + + static void capture(int netif_idx, const char* data, size_t len, int out, int success); + void printDumpProcess(Print& out, NetdumpPacket::PacketDetail ndd, NetdumpPacket np); + void fileDumpProcess(File outfile, NetdumpPacket np); + void tcpDumpProcess(NetdumpPacket np); + void tcpDumpLoop(WiFiServer &tcpDumpServer); + + WiFiClient tcpDumpClient; + char* packetBuffer; + size_t bufferIndex; +}; + +#endif /* LIBRARIES_ESPGOODIES_HR_SRC_NETDUMP_H_ */ diff --git a/libraries/Netdump/src/NetdumpIP.cpp b/libraries/Netdump/src/NetdumpIP.cpp new file mode 100644 index 0000000000..8f3a19ce95 --- /dev/null +++ b/libraries/Netdump/src/NetdumpIP.cpp @@ -0,0 +1,360 @@ +/* + NetdumpIP.cpp + + Created on: 18 mei 2019 + Author: Herman +*/ +#include +#include + +NetdumpIP::NetdumpIP() +{ +} + +NetdumpIP::~NetdumpIP() +{ +} + +NetdumpIP::NetdumpIP(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) +{ + setV4(); + (*this)[0] = first_octet; + (*this)[1] = second_octet; + (*this)[2] = third_octet; + (*this)[3] = fourth_octet; +} + +NetdumpIP::NetdumpIP(const uint8_t *address, bool v4) +{ + uint8_t cnt; + if (v4) + { + cnt = 4; + setV4(); + } + else + { + cnt = 16; + setV6(); + } + for (int i = 0; i < cnt; i++) + { + (*this)[i] = address[i]; + } +} + +NetdumpIP::NetdumpIP(IPAddress ip) +{ + if (!ip.isSet()) + { + setUnset(); + } + else if (ip.isV4()) + { + setV4(); + for (int i = 0; i < 4; i++) + { + rawip[i] = ip[i]; + } + } + else + { + setV6(); + for (int i = 0; i < 16; i++) + { + rawip[i] = ip[i]; + } + } +} + +NetdumpIP::NetdumpIP(String ip) +{ + if (!fromString(ip.c_str())) + { + setUnset(); + } +} + +bool NetdumpIP::fromString(const char *address) +{ + if (!fromString4(address)) + { + return fromString6(address); + } + return true; +} + +bool NetdumpIP::fromString4(const char *address) +{ + // TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats + + uint16_t acc = 0; // Accumulator + uint8_t dots = 0; + + while (*address) + { + char c = *address++; + if (c >= '0' && c <= '9') + { + acc = acc * 10 + (c - '0'); + if (acc > 255) + { + // Value out of [0..255] range + return false; + } + } + else if (c == '.') + { + if (dots == 3) + { + // Too much dots (there must be 3 dots) + return false; + } + (*this)[dots++] = acc; + acc = 0; + } + else + { + // Invalid char + return false; + } + } + + if (dots != 3) + { + // Too few dots (there must be 3 dots) + return false; + } + (*this)[3] = acc; + + setV4(); + return true; +} + +bool NetdumpIP::fromString6(const char *address) +{ + // TODO: test test test + + uint32_t acc = 0; // Accumulator + int dots = 0, doubledots = -1; + + while (*address) + { + char c = tolower(*address++); + if (isalnum(c)) + { + if (c >= 'a') + { + c -= 'a' - '0' - 10; + } + acc = acc * 16 + (c - '0'); + if (acc > 0xffff) + // Value out of range + { + return false; + } + } + else if (c == ':') + { + if (*address == ':') + { + if (doubledots >= 0) + // :: allowed once + { + return false; + } + // remember location + doubledots = dots + !!acc; + address++; + } + if (dots == 7) + // too many separators + { + return false; + } + reinterpret_cast(rawip)[dots++] = PP_HTONS(acc); + acc = 0; + } + else + // Invalid char + { + return false; + } + } + + if (doubledots == -1 && dots != 7) + // Too few separators + { + return false; + } + reinterpret_cast(rawip)[dots++] = PP_HTONS(acc); + + if (doubledots != -1) + { + for (int i = dots - doubledots - 1; i >= 0; i--) + { + reinterpret_cast(rawip)[8 - dots + doubledots + i] = reinterpret_cast(rawip)[doubledots + i]; + } + for (int i = doubledots; i < 8 - dots + doubledots; i++) + { + reinterpret_cast(rawip)[i] = 0; + } + } + + setV6(); + return true; +} + +String NetdumpIP::toString() +{ + StreamString sstr; + if (isV6()) + { + sstr.reserve(40); // 8 shorts x 4 chars each + 7 colons + nullterm + + } + else + { + sstr.reserve(16); // 4 bytes with 3 chars max + 3 dots + nullterm, or '(IP unset)' + } + printTo(sstr); + return sstr; +} + +size_t NetdumpIP::printTo(Print& p) +{ + size_t n = 0; + + if (!isSet()) + { + return p.print(F("(IP unset)")); + } + + if (isV6()) + { + int count0 = 0; + for (int i = 0; i < 8; i++) + { + uint16_t bit = PP_NTOHS(reinterpret_cast(rawip)[i]); + if (bit || count0 < 0) + { + n += p.printf("%x", bit); + if (count0 > 0) + // no more hiding 0 + { + count0 = -8; + } + } + else + { + count0++; + } + if ((i != 7 && count0 < 2) || count0 == 7) + { + n += p.print(':'); + } + } + return n; + } + for (int i = 0; i < 4; i++) + { + n += p.print((*this)[i], DEC); + if (i != 3) + { + n += p.print('.'); + } + } + return n; +} + +bool NetdumpIP::compareRaw(IPversion v, const uint8_t* a, const uint8_t* b) +{ + for (int i = 0; i < (v == IPversion::IPV4 ? 4 : 16); i++) + { + if (a[i] != b[i]) + { + return false; + } + } + return true; +} + +bool NetdumpIP::compareIP(IPAddress ip) +{ + switch (ipv) + { + case IPversion::UNSET : + if (ip.isSet()) + { + return false; + } + else + { + return true; + } + break; + case IPversion::IPV4 : + if (ip.isV6() || !ip.isSet()) + { + return false; + } + else + { + return compareRaw(IPversion::IPV4, rawip, &ip[0]); + } + break; + case IPversion::IPV6 : + if (ip.isV4() || !ip.isSet()) + { + return false; + } + else + { + return compareRaw(IPversion::IPV6, rawip, &ip[0]); + } + break; + default : + return false; + break; + } +} + +bool NetdumpIP::compareIP(NetdumpIP nip) +{ + switch (ipv) + { + case IPversion::UNSET : + if (nip.isSet()) + { + return false; + } + else + { + return true; + } + break; + case IPversion::IPV4 : + if (nip.isV6() || !nip.isSet()) + { + return false; + } + else + { + return compareRaw(IPversion::IPV4, rawip, nip.rawip); + } + break; + case IPversion::IPV6 : + if (nip.isV4() || !nip.isSet()) + { + return false; + } + else + { + return compareRaw(IPversion::IPV6, rawip, nip.rawip); + } + break; + default : + return false; + break; + } +} diff --git a/libraries/Netdump/src/NetdumpIP.h b/libraries/Netdump/src/NetdumpIP.h new file mode 100644 index 0000000000..91eb4b4818 --- /dev/null +++ b/libraries/Netdump/src/NetdumpIP.h @@ -0,0 +1,99 @@ +/* + NetdumpIP.h + + Created on: 18 mei 2019 + Author: Herman +*/ + +#ifndef LIBRARIES_ESPGOODIES_HR_SRC_NETDUMP_NETDUMPIP_H_ +#define LIBRARIES_ESPGOODIES_HR_SRC_NETDUMP_NETDUMPIP_H_ + +#include +#include +#include +#include + +class NetdumpIP +{ +public: + NetdumpIP(); + virtual ~NetdumpIP(); + + NetdumpIP(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); + NetdumpIP(const uint8_t *address, bool V4 = true); + NetdumpIP(IPAddress ip); + NetdumpIP(String ip); + + uint8_t& operator[](int index) + { + return rawip[index]; + } + + bool fromString(const char *address); + + String toString(); + +private: + enum class IPversion {UNSET, IPV4, IPV6}; + IPversion ipv = IPversion::UNSET; + + uint8_t rawip[16] = {0}; + + void setV4() + { + ipv = IPversion::IPV4; + }; + void setV6() + { + ipv = IPversion::IPV6; + }; + void setUnset() + { + ipv = IPversion::UNSET; + }; + bool isV4() + { + return (ipv == IPversion::IPV4); + }; + bool isV6() + { + return (ipv == IPversion::IPV6); + }; + bool isUnset() + { + return (ipv == IPversion::UNSET); + }; + bool isSet() + { + return (ipv != IPversion::UNSET); + }; + + bool compareRaw(IPversion v, const uint8_t* a, const uint8_t* b); + bool compareIP(IPAddress ip); + bool compareIP(NetdumpIP nip) ; + + bool fromString4(const char *address); + bool fromString6(const char *address); + + size_t printTo(Print& p) ; +public: + bool operator==(const IPAddress& addr) + { + return compareIP(addr); + }; + bool operator!=(const IPAddress& addr) + { + return compareIP(addr); + }; + bool operator==(const NetdumpIP& addr) + { + return compareIP(addr); + }; + bool operator!=(const NetdumpIP& addr) + { + return !compareIP(addr); + }; + +}; + +#endif /* LIBRARIES_ESPGOODIES_HR_SRC_NETDUMP_NETDUMPIP_H_ */ diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp new file mode 100644 index 0000000000..382005b39c --- /dev/null +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -0,0 +1,228 @@ +/* + NetDump library - tcpdump-like packet logger facility + + Copyright (c) 2018 David Gauchard. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Netdump.h" +#include + +void NetdumpPacket::printDetail(Print& out, String indent, const char* data, size_t size, PacketDetail pd) +{ + if (pd == PacketDetail::NONE) + { + return; + } + + uint16_t charCount = pd == PacketDetail::FULL ? 24 : 80; + + size_t start = 0; + while (start < size) + { + size_t end = start + charCount; + if (end > size) + { + end = size; + } + out.printf("%s", indent.c_str()); + if (pd == PacketDetail::FULL) + { + for (size_t i = start; i < end; i++) + { + out.printf("%02x ", (unsigned char)data[i]); + } + for (size_t i = end; i < start + charCount; i++) + { + out.print(" "); + } + } + for (size_t i = start; i < end; i++) + { + out.printf("%c", data[i] >= 32 && data[i] < 128 ? data[i] : '.'); + } + out.println(); + + start += charCount; + } +} + + +String NetdumpPacket::toString(PacketDetail netdumpDetail) +{ + StreamString sstr; + sstr.reserve(128); + + sstr.printf("%d %3s ", netif_idx, out ? "out" : "in "); + + if (isARP()) + { + sstr.printf("ARP "); + switch (getARPType()) + { + case 1 : sstr.printf("who has %s tell %s", getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); + break; + case 2 : sstr.printf("%s is at ", getIP(ETH_HDR_LEN + 14).toString().c_str()); + for (int i = 0; i < 6; i++) + { + sstr.printf("%02x", (unsigned char)data[ETH_HDR_LEN + 8 + i]); + if (i < 5) + { + sstr.print(':'); + } + } + break; + } + sstr.printf("\r\n"); + return sstr; + } + + if (isIP()) + { + if (isUDP()) + { + if (isMDNS() || isDNS()) + { + sstr.printf("%s%s>%s ", isMDNS() ? "MDNS " : "DNS ", sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf("ID=0x%04x ", ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8)); + sstr.printf("F=0x%04x ", ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 2)); + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 4)) + { + sstr.printf("Q=%d ", t); + } + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 6)) + { + sstr.printf("R=%d ", t); + } + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 8)) + { + sstr.printf("TR=%d ", t); + } + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 10)) + { + sstr.printf("DR=%d ", t); + } + sstr.printf("\r\n"); + } + else + { + String udpType; + + if (isSSDP()) + { + udpType = "SSDP"; + } + else if (isDHCP()) + { + udpType = "DHCP"; + } + else if (isWSDD()) + { + udpType = "WSDD"; + } + else + { + udpType = "UDP "; + } + sstr.printf("%s %s>%s ", udpType.c_str(), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf("%d:%d", getSrcPort(), getDstPort()); + sstr.printf("\r\n"); + } + printDetail(sstr, " H ", &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); + printDetail(sstr, " D ", &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); + return sstr; + } + else if (isTCP()) + { + sstr.printf(isHTTP() ? "HTTP " : "TCP "); + sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf("%d:%d ", getSrcPort(), getDstPort()); + uint16_t flags = getTcpFlags(); + sstr.print('['); + const char chars [] = "FSRPAUECN"; + for (uint8_t i = 0; i < sizeof chars; i++) + if (flags & (1 << i)) + { + sstr.print(chars[i]); + } + sstr.print(']'); + sstr.printf(" len: %u seq: %u, ack: %u, wnd: %u ", getTcpLen(), getTcpSeq(), getTcpAck(), getTcpWindow()); + sstr.printf("\r\n"); + printDetail(sstr, " H ", &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail); + printDetail(sstr, " D ", &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); + return sstr; + } + else if (isICMP()) + { + sstr.printf("ICMP "); + sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); + if (isIPv4()) + { + switch (getIcmpType()) + { + case 0 : sstr.printf("ping reply"); break; + case 8 : sstr.printf("ping request"); break; + default: sstr.printf("type(0x%02x)", getIcmpType()); break; + } + } + if (isIPv6()) + { + switch (getIcmpType()) + { + case 129 : sstr.printf("ping reply"); break; + case 128 : sstr.printf("ping request"); break; + case 135 : sstr.printf("Neighbour solicitation"); break; + case 136 : sstr.printf("Neighbour advertisement"); break; + default: sstr.printf("type(0x%02x)", getIcmpType()); break; + } + } + sstr.printf("\r\n"); + return sstr; + } + else if (isIGMP()) + { + sstr.printf("IGMP "); + switch (getIgmpType()) + { + case 1 : sstr.printf("Create Group Request"); break; + case 2 : sstr.printf("Create Group Reply"); break; + case 3 : sstr.printf("Join Group Request"); break; + case 4 : sstr.printf("Join Group Reply"); break; + case 5 : sstr.printf("Leave Group Request"); break; + case 6 : sstr.printf("Leave Group Reply"); break; + case 7 : sstr.printf("Confirm Group Request"); break; + case 8 : sstr.printf("Confirm Group Reply"); break; + case 0x11 : sstr.printf("Group Membership Query"); break; + case 0x12 : sstr.printf("IGMPv1 Membership Report"); break; + case 0x22 : sstr.printf("IGMPv3 Membership Report"); break; + default: sstr.printf("type(0x%02x)", getIgmpType()); break; + } + sstr.printf("\r\n"); + return sstr; + } + else + { + sstr.printf("UKWN type = %d\r\n", ipType()); + return sstr; + } + } + + sstr.printf("Unknown packet, type = 0x%04x\r\n", ethType()); + return sstr; + +} + diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h new file mode 100644 index 0000000000..ae924206a2 --- /dev/null +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -0,0 +1,265 @@ +/* + NetDump library - tcpdump-like packet logger facility + + Copyright (c) 2018 David Gauchard. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __NETDUMP_PACKET_H +#define __NETDUMP_PACKET_H + +#include +#include +#include +#include "NetdumpIP.h" + +#define ETH_HDR_LEN 14 + +class NetdumpPacket +{ +public: + NetdumpPacket(int n, const char* d, size_t l, int o, int s) + : netif_idx(n), data(d), len(l), out(o), success(s) + {}; + + virtual ~NetdumpPacket() {}; + + enum class PacketDetail + { + NONE, + FULL, + CHARS + }; + + int netif_idx; + const char* data; + size_t len; + int out; + int success; + + uint16_t ntoh16(uint16_t idx) + { + return data[idx + 1] | (((uint16_t)data[idx]) << 8); + }; + uint32_t ntoh32(uint16_t idx) + { + return ntoh16(idx + 2) | (((uint32_t)ntoh16(idx)) << 16); + }; + uint8_t byteData(uint16_t idx) + { + return data[idx]; + } + const char* byteIdx(uint16_t idx) + { + return &data[idx]; + }; + uint16_t ethType() + { + return ntoh16(12); + }; + uint8_t ipType() + { + return isIPv4() ? data[ETH_HDR_LEN + 9] : data[ETH_HDR_LEN + 6]; + }; + + uint16_t getIpHdrLen() + { + return isIPv4() ? (((unsigned char)data[ETH_HDR_LEN]) & 0x0f) << 2 : 40 ; // IPv6 is fixed length + } + uint16_t getIpTotLen() + { + return ntoh16(ETH_HDR_LEN + 2); + } + // uint16_t getIpOptLen() { return getIpHdrLen() - 20; } + // uint16_t getIpUsrLen() { return getIpTotLen() - getIpHdrLen(); } + + uint32_t getTcpSeq() + { + return ntoh32(ETH_HDR_LEN + getIpHdrLen() + 4); + } + uint32_t getTcpAck() + { + return ntoh32(ETH_HDR_LEN + getIpHdrLen() + 8); + } + uint16_t getTcpFlags() + { + return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 12); + } + uint16_t getTcpWindow() + { + return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 14); + } + uint8_t getTcpHdrLen() + { + return (data[ETH_HDR_LEN + getIpHdrLen() + 12] >> 4) * 4; + };//Header len is in multiple of 4 bytes + uint16_t getTcpLen() + { + return getIpTotLen() - getIpHdrLen() - getTcpHdrLen() ; + }; + + uint8_t getIcmpType() + { + return data[ETH_HDR_LEN + getIpHdrLen() + 0]; + } + uint8_t getIgmpType() + { + return data[ETH_HDR_LEN + getIpHdrLen() + 0]; + } + + uint8_t getARPType() + { + return data[ETH_HDR_LEN + 7]; + } + bool is_ARP_who() + { + return getARPType() == 1; + } + bool is_ARP_is() + { + return getARPType() == 2; + } + + uint8_t getUdpHdrLen() + { + return 8; + }; + uint16_t getUdpLen() + { + return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 4); + }; + + + bool isARP() + { + return (ethType() == 0x0806); + }; + bool isIPv4() + { + return (ethType() == 0x0800); + }; + bool isIPv6() + { + return (ethType() == 0x86dd); + }; + bool isIP() + { + return (isIPv4() || isIPv6()); + }; + bool isICMP() + { + return ((ipType() == 1) || ipType() == 58); + }; + bool isIGMP() + { + return ipType() == 2; + }; + bool isTCP() + { + return ipType() == 6; + }; + bool isUDP() + { + return ipType() == 17; + }; + bool isMDNS() + { + return hasPort(5353); + }; + bool isDNS() + { + return hasPort(53); + }; + bool isSSDP() + { + return hasPort(1900); + }; + bool isDHCP() + { + return (hasPort(546) || hasPort(547) || hasPort(67) || hasPort(68)); + }; + bool isWSDD() + { + return (hasPort(3702)); + }; + bool isHTTP() + { + return (hasPort(80)); + }; + + + NetdumpIP getIP(uint16_t idx) + { + return NetdumpIP(data[idx], + data[idx + 1], + data[idx + 2], + data[idx + 3]); + }; + + NetdumpIP getIP6(uint16_t idx) + { + return NetdumpIP((const uint8_t*)&data[idx], false); + }; + + + NetdumpIP sourceIP() + { + NetdumpIP ip; + if (isIPv4()) + { + ip = getIP(ETH_HDR_LEN + 12); + } + else if (isIPv6()) + { + ip = getIP6(ETH_HDR_LEN + 8); + } + return ip; + }; + + NetdumpIP destIP() + { + NetdumpIP ip; + if (isIPv4()) + { + ip = getIP(ETH_HDR_LEN + 16); + } + else if (isIPv6()) + { + ip = getIP6(ETH_HDR_LEN + 24); + } + return ip; + }; + uint16_t getSrcPort() + { + return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 0); + } + uint16_t getDstPort() + { + return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 2); + } + bool hasPort(uint16_t p) + { + return ((getSrcPort() == p) || (getDstPort() == p)); + } + + String toString(PacketDetail netdumpDetail = PacketDetail::NONE); + void printDetail(Print& out, String indent, const char* data, size_t size, PacketDetail pd); + +}; + + +#endif /* LIBRARIES_ESPGOODIES_HR_SRC_NETDUMP_PACKET_H_ */ From d17f83d9a58136cb1cfe3c9ef1a1bea7a1883c4b Mon Sep 17 00:00:00 2001 From: hreintke Date: Tue, 12 Nov 2019 11:43:31 +0100 Subject: [PATCH 02/22] Const update --- libraries/Netdump/src/Netdump.cpp | 34 +++++++--- libraries/Netdump/src/Netdump.h | 10 ++- libraries/Netdump/src/NetdumpIP.cpp | 34 +++++++--- libraries/Netdump/src/NetdumpIP.h | 22 +++--- libraries/Netdump/src/NetdumpPacket.cpp | 4 +- libraries/Netdump/src/NetdumpPacket.h | 90 ++++++++++++------------- 6 files changed, 109 insertions(+), 85 deletions(-) diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index 10304d26e5..e36a8f5574 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -1,7 +1,7 @@ /* NetDump library - tcpdump-like packet logger facility - Copyright (c) 2018 David Gauchard. All rights reserved. + Copyright (c) 2019 Herman Reintke. All rights reserved. This file is part of the esp8266 core for Arduino environment. This library is free software; you can redistribute it and/or @@ -56,16 +56,25 @@ void Netdump::printDump(Print& out, NetdumpPacket::PacketDetail ndd, NetdumpFilt void Netdump::fileDump(File outfile, NetdumpFilter nf) { - char buf[24]; + //char buf[24]; + uint32_t buf[6]; +/* *(uint32_t*)&buf[0] = 0xa1b2c3d4; *(uint32_t*)&buf[4] = 0x00040002; *(uint32_t*)&buf[8] = 0; *(uint32_t*)&buf[12] = 0; *(uint32_t*)&buf[16] = 1024; *(uint32_t*)&buf[20] = 1; - - outfile.write(buf, 24); +*/ + buf[0] = 0xa1b2c3d4; + buf[1] = 0x00040002; + buf[2] = 0; + buf[3] = 0; + buf[4] = 1024; + buf[5] = 1; + + outfile.write((uint8_t*)buf, 24); // setCallback( std::bind(&Netdump::fileDumpProcess, this, outfile, std::placeholders::_1)); setCallback([outfile, this](NetdumpPacket & ndp) { @@ -103,11 +112,12 @@ void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int } } -void Netdump::printDumpProcess(Print& out, NetdumpPacket::PacketDetail ndd, NetdumpPacket np) +void Netdump::printDumpProcess(Print& out, NetdumpPacket::PacketDetail ndd, const NetdumpPacket& np) { out.printf("%8d %s", millis(), np.toString(ndd).c_str()); } -void Netdump::fileDumpProcess(File outfile, NetdumpPacket np) + +void Netdump::fileDumpProcess(File outfile, const NetdumpPacket& np) { size_t incl_len = np.len > 1024 ? 1024 : np.len; char buf[16]; @@ -122,7 +132,7 @@ void Netdump::fileDumpProcess(File outfile, NetdumpPacket np) outfile.write(np.data, incl_len); } -void Netdump::tcpDumpProcess(NetdumpPacket np) +void Netdump::tcpDumpProcess(const NetdumpPacket& np) { // Get capture code from netdumpout.cpp if (np.isIPv4() && np.isTCP() @@ -155,7 +165,6 @@ void Netdump::tcpDumpProcess(NetdumpPacket np) } void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer) { - if (tcpDumpServer.hasClient()) { tcpDumpClient = tcpDumpServer.available(); @@ -191,8 +200,11 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer) bufferIndex = 0; } // schedule_function(std::bind(&Netdump::tcpDumpLoop,this,std::ref(tcpDumpServer))); - schedule_function([&tcpDumpServer, this]() + if (tcpDumpServer.status() != CLOSED) { - tcpDumpLoop(tcpDumpServer); - }); + schedule_function([&tcpDumpServer, this]() + { + tcpDumpLoop(tcpDumpServer); + }); + } } diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h index ba9259a1f0..aaaa8eacf9 100644 --- a/libraries/Netdump/src/Netdump.h +++ b/libraries/Netdump/src/Netdump.h @@ -1,7 +1,7 @@ /* NetDump library - tcpdump-like packet logger facility - Copyright (c) 2018 David Gauchard. All rights reserved. + Copyright (c) 2019 Herman Reintke. All rights reserved. This file is part of the esp8266 core for Arduino environment. This library is free software; you can redistribute it and/or @@ -26,8 +26,6 @@ #include #include #include -//#include -//#include #include "NetdumpPacket.h" #include @@ -64,9 +62,9 @@ class Netdump static Netdump* self; static void capture(int netif_idx, const char* data, size_t len, int out, int success); - void printDumpProcess(Print& out, NetdumpPacket::PacketDetail ndd, NetdumpPacket np); - void fileDumpProcess(File outfile, NetdumpPacket np); - void tcpDumpProcess(NetdumpPacket np); + void printDumpProcess(Print& out, NetdumpPacket::PacketDetail ndd, const NetdumpPacket& np); + void fileDumpProcess(File outfile, const NetdumpPacket& np); + void tcpDumpProcess(const NetdumpPacket& np); void tcpDumpLoop(WiFiServer &tcpDumpServer); WiFiClient tcpDumpClient; diff --git a/libraries/Netdump/src/NetdumpIP.cpp b/libraries/Netdump/src/NetdumpIP.cpp index 8f3a19ce95..f812984c02 100644 --- a/libraries/Netdump/src/NetdumpIP.cpp +++ b/libraries/Netdump/src/NetdumpIP.cpp @@ -1,8 +1,22 @@ /* - NetdumpIP.cpp + NetDump library - tcpdump-like packet logger facility + + Copyright (c) 2019 Herman Reintke. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software - Created on: 18 mei 2019 - Author: Herman */ #include #include @@ -43,7 +57,7 @@ NetdumpIP::NetdumpIP(const uint8_t *address, bool v4) } } -NetdumpIP::NetdumpIP(IPAddress ip) +NetdumpIP::NetdumpIP(const IPAddress& ip) { if (!ip.isSet()) { @@ -67,7 +81,7 @@ NetdumpIP::NetdumpIP(IPAddress ip) } } -NetdumpIP::NetdumpIP(String ip) +NetdumpIP::NetdumpIP(const String& ip) { if (!fromString(ip.c_str())) { @@ -267,7 +281,7 @@ size_t NetdumpIP::printTo(Print& p) return n; } -bool NetdumpIP::compareRaw(IPversion v, const uint8_t* a, const uint8_t* b) +bool NetdumpIP::compareRaw(IPversion v, const uint8_t* a, const uint8_t* b) const { for (int i = 0; i < (v == IPversion::IPV4 ? 4 : 16); i++) { @@ -279,7 +293,7 @@ bool NetdumpIP::compareRaw(IPversion v, const uint8_t* a, const uint8_t* b) return true; } -bool NetdumpIP::compareIP(IPAddress ip) +bool NetdumpIP::compareIP(const IPAddress& ip) const { switch (ipv) { @@ -300,7 +314,7 @@ bool NetdumpIP::compareIP(IPAddress ip) } else { - return compareRaw(IPversion::IPV4, rawip, &ip[0]); + return compareRaw(IPversion::IPV4, rawip, reinterpret_cast(&ip.v4())); } break; case IPversion::IPV6 : @@ -310,7 +324,7 @@ bool NetdumpIP::compareIP(IPAddress ip) } else { - return compareRaw(IPversion::IPV6, rawip, &ip[0]); + return compareRaw(IPversion::IPV6, rawip, reinterpret_cast(ip.raw6())); } break; default : @@ -319,7 +333,7 @@ bool NetdumpIP::compareIP(IPAddress ip) } } -bool NetdumpIP::compareIP(NetdumpIP nip) +bool NetdumpIP::compareIP(const NetdumpIP& nip) const { switch (ipv) { diff --git a/libraries/Netdump/src/NetdumpIP.h b/libraries/Netdump/src/NetdumpIP.h index 91eb4b4818..ab3999a38d 100644 --- a/libraries/Netdump/src/NetdumpIP.h +++ b/libraries/Netdump/src/NetdumpIP.h @@ -21,8 +21,8 @@ class NetdumpIP NetdumpIP(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); NetdumpIP(const uint8_t *address, bool V4 = true); - NetdumpIP(IPAddress ip); - NetdumpIP(String ip); + NetdumpIP(const IPAddress& ip); + NetdumpIP(const String& ip); uint8_t& operator[](int index) { @@ -51,33 +51,33 @@ class NetdumpIP { ipv = IPversion::UNSET; }; - bool isV4() + bool isV4() const { return (ipv == IPversion::IPV4); }; - bool isV6() + bool isV6() const { return (ipv == IPversion::IPV6); }; - bool isUnset() + bool isUnset() const { return (ipv == IPversion::UNSET); }; - bool isSet() + bool isSet() const { return (ipv != IPversion::UNSET); }; - bool compareRaw(IPversion v, const uint8_t* a, const uint8_t* b); - bool compareIP(IPAddress ip); - bool compareIP(NetdumpIP nip) ; + bool compareRaw(IPversion v, const uint8_t* a, const uint8_t* b) const; + bool compareIP(const IPAddress& ip) const; + bool compareIP(const NetdumpIP& nip) const; bool fromString4(const char *address); bool fromString6(const char *address); - size_t printTo(Print& p) ; + size_t printTo(Print& p); public: - bool operator==(const IPAddress& addr) + bool operator==(const IPAddress& addr) const { return compareIP(addr); }; diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index 382005b39c..db89d343b8 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -22,7 +22,7 @@ #include "Netdump.h" #include -void NetdumpPacket::printDetail(Print& out, String indent, const char* data, size_t size, PacketDetail pd) +void NetdumpPacket::printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const { if (pd == PacketDetail::NONE) { @@ -62,7 +62,7 @@ void NetdumpPacket::printDetail(Print& out, String indent, const char* data, siz } -String NetdumpPacket::toString(PacketDetail netdumpDetail) +String NetdumpPacket::toString(PacketDetail netdumpDetail) const { StreamString sstr; sstr.reserve(128); diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index ae924206a2..bc9e5934a3 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -1,7 +1,7 @@ /* NetDump library - tcpdump-like packet logger facility - Copyright (c) 2018 David Gauchard. All rights reserved. + Copyright (c) 2019 Herman Reintke. All rights reserved. This file is part of the esp8266 core for Arduino environment. This library is free software; you can redistribute it and/or @@ -51,158 +51,158 @@ class NetdumpPacket int out; int success; - uint16_t ntoh16(uint16_t idx) + uint16_t ntoh16(uint16_t idx) const { return data[idx + 1] | (((uint16_t)data[idx]) << 8); }; - uint32_t ntoh32(uint16_t idx) + uint32_t ntoh32(uint16_t idx) const { return ntoh16(idx + 2) | (((uint32_t)ntoh16(idx)) << 16); }; - uint8_t byteData(uint16_t idx) + uint8_t byteData(uint16_t idx) const { return data[idx]; } - const char* byteIdx(uint16_t idx) + const char* byteIdx(uint16_t idx) const { return &data[idx]; }; - uint16_t ethType() + uint16_t ethType() const { return ntoh16(12); }; - uint8_t ipType() + uint8_t ipType() const { return isIPv4() ? data[ETH_HDR_LEN + 9] : data[ETH_HDR_LEN + 6]; }; - uint16_t getIpHdrLen() + uint16_t getIpHdrLen() const { return isIPv4() ? (((unsigned char)data[ETH_HDR_LEN]) & 0x0f) << 2 : 40 ; // IPv6 is fixed length } - uint16_t getIpTotLen() + uint16_t getIpTotLen() const { return ntoh16(ETH_HDR_LEN + 2); } // uint16_t getIpOptLen() { return getIpHdrLen() - 20; } // uint16_t getIpUsrLen() { return getIpTotLen() - getIpHdrLen(); } - uint32_t getTcpSeq() + uint32_t getTcpSeq() const { return ntoh32(ETH_HDR_LEN + getIpHdrLen() + 4); } - uint32_t getTcpAck() + uint32_t getTcpAck() const { return ntoh32(ETH_HDR_LEN + getIpHdrLen() + 8); } - uint16_t getTcpFlags() + uint16_t getTcpFlags() const { return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 12); } - uint16_t getTcpWindow() + uint16_t getTcpWindow() const { return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 14); } - uint8_t getTcpHdrLen() + uint8_t getTcpHdrLen() const { return (data[ETH_HDR_LEN + getIpHdrLen() + 12] >> 4) * 4; };//Header len is in multiple of 4 bytes - uint16_t getTcpLen() + uint16_t getTcpLen() const { return getIpTotLen() - getIpHdrLen() - getTcpHdrLen() ; }; - uint8_t getIcmpType() + uint8_t getIcmpType() const { return data[ETH_HDR_LEN + getIpHdrLen() + 0]; } - uint8_t getIgmpType() + uint8_t getIgmpType() const { return data[ETH_HDR_LEN + getIpHdrLen() + 0]; } - uint8_t getARPType() + uint8_t getARPType() const { return data[ETH_HDR_LEN + 7]; } - bool is_ARP_who() + bool is_ARP_who() const { return getARPType() == 1; } - bool is_ARP_is() + bool is_ARP_is() const { return getARPType() == 2; } - uint8_t getUdpHdrLen() + uint8_t getUdpHdrLen() const { return 8; }; - uint16_t getUdpLen() + uint16_t getUdpLen() const { return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 4); }; - bool isARP() + bool isARP() const { return (ethType() == 0x0806); }; - bool isIPv4() + bool isIPv4() const { return (ethType() == 0x0800); }; - bool isIPv6() + bool isIPv6() const { return (ethType() == 0x86dd); }; - bool isIP() + bool isIP() const { return (isIPv4() || isIPv6()); }; - bool isICMP() + bool isICMP() const { return ((ipType() == 1) || ipType() == 58); }; - bool isIGMP() + bool isIGMP() const { return ipType() == 2; }; - bool isTCP() + bool isTCP() const { return ipType() == 6; }; - bool isUDP() + bool isUDP() const { return ipType() == 17; }; - bool isMDNS() + bool isMDNS() const { return hasPort(5353); }; - bool isDNS() + bool isDNS() const { return hasPort(53); }; - bool isSSDP() + bool isSSDP() const { return hasPort(1900); }; - bool isDHCP() + bool isDHCP() const { return (hasPort(546) || hasPort(547) || hasPort(67) || hasPort(68)); }; - bool isWSDD() + bool isWSDD() const { return (hasPort(3702)); }; - bool isHTTP() + bool isHTTP() const { return (hasPort(80)); }; - NetdumpIP getIP(uint16_t idx) + NetdumpIP getIP(uint16_t idx) const { return NetdumpIP(data[idx], data[idx + 1], @@ -210,13 +210,13 @@ class NetdumpPacket data[idx + 3]); }; - NetdumpIP getIP6(uint16_t idx) + NetdumpIP getIP6(uint16_t idx) const { return NetdumpIP((const uint8_t*)&data[idx], false); }; - NetdumpIP sourceIP() + NetdumpIP sourceIP() const { NetdumpIP ip; if (isIPv4()) @@ -230,7 +230,7 @@ class NetdumpPacket return ip; }; - NetdumpIP destIP() + NetdumpIP destIP() const { NetdumpIP ip; if (isIPv4()) @@ -243,21 +243,21 @@ class NetdumpPacket } return ip; }; - uint16_t getSrcPort() + uint16_t getSrcPort() const { return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 0); } - uint16_t getDstPort() + uint16_t getDstPort() const { return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 2); } - bool hasPort(uint16_t p) + bool hasPort(uint16_t p) const { return ((getSrcPort() == p) || (getDstPort() == p)); } - String toString(PacketDetail netdumpDetail = PacketDetail::NONE); - void printDetail(Print& out, String indent, const char* data, size_t size, PacketDetail pd); + String toString(PacketDetail netdumpDetail = PacketDetail::NONE) const; + void printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const; }; From da5307fab2908a1beac4cd2fcbaf2a85506e82a7 Mon Sep 17 00:00:00 2001 From: hreintke Date: Tue, 12 Nov 2019 16:11:46 +0100 Subject: [PATCH 03/22] Cleanup, added example --- libraries/Netdump/examples/Netdump.ino | 75 ------------ .../Netdump/examples/Netdump/Netdump.ino | 109 ++++++++++++++++++ libraries/Netdump/library.properties | 6 +- libraries/Netdump/src/Netdump.cpp | 9 +- libraries/Netdump/src/Netdump.h | 6 +- libraries/Netdump/src/NetdumpPacket.h | 5 + 6 files changed, 123 insertions(+), 87 deletions(-) delete mode 100644 libraries/Netdump/examples/Netdump.ino create mode 100644 libraries/Netdump/examples/Netdump/Netdump.ino diff --git a/libraries/Netdump/examples/Netdump.ino b/libraries/Netdump/examples/Netdump.ino deleted file mode 100644 index a5aec8b284..0000000000 --- a/libraries/Netdump/examples/Netdump.ino +++ /dev/null @@ -1,75 +0,0 @@ -// Do not remove the include below -#include "NetDumpTest.h" -#include -#include "LocalDefines.h" -#include -#include -#include - -/* - dump network packets on serial console - released to the public domain -*/ - - -Netdump nd; -ESP8266WebServer server(80); -WiFiServer ws(8000); - - -void handleRoot() { - static int rq = 0; - String a = "

You are connected, rq = "+String(rq++)+"

"; - server.send(200, "text/html", a); -} - - -File outfile = SPIFFS.open("test", "w"); - -void setup(void) { - Serial.begin(115200); - - WiFi.mode(WIFI_STA); - WiFi.begin(ssid,password); - SPIFFS.begin(); - - server.on("/", handleRoot); - server.begin(); - -/* -// To serial, include hex print only localIP traffic - nd.printDump(Serial, true, - [](NetdumpPacket n) - { - return ((n.ethType() != 0x8912) && - ((n.sourceIP()==WiFi.localIP()) || n.destIP()==WiFi.localIP()) ); - }); -*/ - -/* -// To serial, include hex print only localIP traffic - nd.printDump(Serial, false); // To serial all traffic, no hex dump -*/ - -/* - nd.printDump(outfile, false); // To file all traffic, no hex dump, format ascii -*/ - -/* - nd.fileDump(outfile, false); // To file all traffic, no hex dump, format pcap file -*/ - -/* -// To telnet, all traffic, use `n 10.0.0.212 8000 | tcpdump -r -` - ws.begin(); - nd.tcpDump(ws); - -*/ - - -} - -void loop(void) { - server.handleClient(); - -} diff --git a/libraries/Netdump/examples/Netdump/Netdump.ino b/libraries/Netdump/examples/Netdump/Netdump.ino new file mode 100644 index 0000000000..b77158bd83 --- /dev/null +++ b/libraries/Netdump/examples/Netdump/Netdump.ino @@ -0,0 +1,109 @@ +#include "Arduino.h" + +#include "Netdump.h" +#include +#include "LocalDefines.h" +#include +#include +#include "Schedule.h" + +Netdump nd; + +FS* filesystem = &SPIFFS; +//FS* filesystem = &LittleFS; + +ESP8266WebServer webServer(80); // Used for sending commands +WiFiServer tcpServer(8000); // Used to show netcat option. +File tracefile; + +void startSerial(int option) +{ + switch (option) + { + case 1 : //All Packets, show packet summary. + nd.printDump(Serial, NetdumpPacket::PacketDetail::NONE); + break; + + case 2 : // Only local IP traffic, full details + nd.printDump(Serial, NetdumpPacket::PacketDetail::FULL, + [](NetdumpPacket n) + { + return (n.hasIP(WiFi.localIP())); + } + ); + case 3 : // Only HTTP traffic, show packet content as chars + nd.printDump(Serial, NetdumpPacket::PacketDetail::CHARS, + [](NetdumpPacket n) + { + return (n.isHTTP()); + } + ); + }; +} + +void startTracefile() +{ + // To file all traffic, format pcap file + tracefile = filesystem->open("/tr.pcap", "w"); + nd.fileDump(tracefile); +} + +void startTcpDump() +{ + // To tcpserver, all traffic. + tcpServer.begin(); + nd.tcpDump(tcpServer); +} + +void setup(void) { + Serial.begin(115200); + + WiFi.mode(WIFI_STA); + WiFi.begin(ssid,password); + filesystem->begin(); + + webServer.on("/list", + []() + { + Dir dir = filesystem->openDir("/"); + String d = "

File list

"; + while (dir.next()) + { + d.concat("
  • " + dir.fileName() + "
  • "); + } + webServer.send(200, "text.html", d); + } + ); + + webServer.on("/req", + []() + { + static int rq = 0; + String a = "

    You are connected, Number of requests = " + String(rq++) + "

    "; + webServer.send(200, "text/html", a); + } + ); + + webServer.on("/reset" , + []() + { + nd.reset(); + tracefile.close(); + tcpServer.close(); + webServer.send(200, "text.html", "

    Netdump session reset

    "); + } + ); + + webServer.serveStatic("/", *filesystem, "/"); + webServer.begin(); + + //startSerial(3); + // startTcpDump(); + startTracefile(); + +} + +void loop(void) { + webServer.handleClient(); +} + diff --git a/libraries/Netdump/library.properties b/libraries/Netdump/library.properties index 1ff03d2128..2f6ad5e22e 100644 --- a/libraries/Netdump/library.properties +++ b/libraries/Netdump/library.properties @@ -1,9 +1,9 @@ name=NetDump version=2 -author=David Gauchard -maintainer=David Gauchard +author=Herman Reintke +maintainer=Herman Reintke sentence=tcpdump-like logger for esp8266/Arduino paragraph=Dumps input / output packets on "Print"able type, or provide a TCP server for the real tcpdump. Check examples. Some other unrelated and independant tools are included. category=Communication url=https:// -architectures=esp8266 +architectures=esp8266 lwip diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index e36a8f5574..c48b6affe6 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -83,7 +83,6 @@ void Netdump::fileDump(File outfile, NetdumpFilter nf) } void Netdump::tcpDump(WiFiServer &tcpDumpServer, NetdumpFilter nf) { - // Get initialize code from netdumpout.cpp if (packetBuffer) { delete packetBuffer; @@ -91,7 +90,6 @@ void Netdump::tcpDump(WiFiServer &tcpDumpServer, NetdumpFilter nf) packetBuffer = new char[2048]; bufferIndex = 0; - // schedule_function(std::bind(&Netdump::tcpDumpLoop,this,std::ref(tcpDumpServer))); schedule_function([&tcpDumpServer, this]() { tcpDumpLoop(tcpDumpServer); @@ -168,9 +166,8 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer) if (tcpDumpServer.hasClient()) { tcpDumpClient = tcpDumpServer.available(); - //if (fastsend) - tcpDumpClient.setNoDelay(true); + tcpDumpClient.setNoDelay(true); // pcap-savefile(5) capture preamble *(uint32_t*)&packetBuffer[0] = 0xa1b2c3d4; @@ -181,7 +178,7 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer) *(uint32_t*)&packetBuffer[20] = 1; tcpDumpClient.write(packetBuffer, 24); bufferIndex = 0; - // setCallback(std::bind(&Netdump::tcpDumpProcess,this,std::placeholders::_1)); + setCallback([this](NetdumpPacket & ndp) { tcpDumpProcess(ndp); @@ -199,7 +196,7 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer) tcpDumpClient.write(packetBuffer, bufferIndex); bufferIndex = 0; } - // schedule_function(std::bind(&Netdump::tcpDumpLoop,this,std::ref(tcpDumpServer))); + if (tcpDumpServer.status() != CLOSED) { schedule_function([&tcpDumpServer, this]() diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h index aaaa8eacf9..7257783094 100644 --- a/libraries/Netdump/src/Netdump.h +++ b/libraries/Netdump/src/Netdump.h @@ -68,8 +68,8 @@ class Netdump void tcpDumpLoop(WiFiServer &tcpDumpServer); WiFiClient tcpDumpClient; - char* packetBuffer; - size_t bufferIndex; + char* packetBuffer = nullptr; + size_t bufferIndex = 0; }; -#endif /* LIBRARIES_ESPGOODIES_HR_SRC_NETDUMP_H_ */ +#endif /* __NETDUMP_H */ diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index bc9e5934a3..e7d2be3364 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -230,6 +230,11 @@ class NetdumpPacket return ip; }; + bool hasIP(NetdumpIP ip) const + { + return ((ip == sourceIP()) || (ip == destIP())); + } + NetdumpIP destIP() const { NetdumpIP ip; From 9545dd331319bf12522334a659327af2c836f804 Mon Sep 17 00:00:00 2001 From: hreintke Date: Tue, 12 Nov 2019 16:19:12 +0100 Subject: [PATCH 04/22] Example should start Serial by default. --- libraries/Netdump/examples/Netdump/Netdump.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/Netdump/examples/Netdump/Netdump.ino b/libraries/Netdump/examples/Netdump/Netdump.ino index b77158bd83..3b312f3e04 100644 --- a/libraries/Netdump/examples/Netdump/Netdump.ino +++ b/libraries/Netdump/examples/Netdump/Netdump.ino @@ -97,9 +97,9 @@ void setup(void) { webServer.serveStatic("/", *filesystem, "/"); webServer.begin(); - //startSerial(3); + startSerial(1); // startTcpDump(); - startTracefile(); + // startTracefile(); } From 11426ee563522fd343351c2f8ed36a2e63efb868 Mon Sep 17 00:00:00 2001 From: hreintke Date: Wed, 13 Nov 2019 16:13:40 +0100 Subject: [PATCH 05/22] Further cleanup --- libraries/Netdump/src/Netdump.cpp | 82 +++++++++++-------------- libraries/Netdump/src/Netdump.h | 5 +- libraries/Netdump/src/NetdumpPacket.cpp | 4 ++ libraries/Netdump/src/NetdumpPacket.h | 41 ++++++++++--- 4 files changed, 76 insertions(+), 56 deletions(-) diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index c48b6affe6..338aefc20d 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -29,53 +29,43 @@ void Netdump::setCallback(NetdumpCallback nc) { netDumpCallback = nc; } + void Netdump::setCallback(NetdumpCallback nc, NetdumpFilter nf) { netDumpFilter = nf; netDumpCallback = nc; } + void Netdump::setFilter(NetdumpFilter nf) { netDumpFilter = nf; } + void Netdump::reset() { setCallback(nullptr, nullptr); } + void Netdump::printDump(Print& out, NetdumpPacket::PacketDetail ndd, NetdumpFilter nf) { out.printf("netDump starting\r\n"); -// setCallback(std::bind(&Netdump::printDumpProcess, this, std::ref(out), ndd, std::placeholders::_1), nf); setCallback([&out, ndd, this](NetdumpPacket & ndp) { printDumpProcess(out, ndd, ndp); }, nf); - - } + void Netdump::fileDump(File outfile, NetdumpFilter nf) { - - //char buf[24]; - uint32_t buf[6]; -/* - *(uint32_t*)&buf[0] = 0xa1b2c3d4; - *(uint32_t*)&buf[4] = 0x00040002; - *(uint32_t*)&buf[8] = 0; - *(uint32_t*)&buf[12] = 0; - *(uint32_t*)&buf[16] = 1024; - *(uint32_t*)&buf[20] = 1; -*/ buf[0] = 0xa1b2c3d4; buf[1] = 0x00040002; buf[2] = 0; buf[3] = 0; - buf[4] = 1024; + buf[4] = maxPcapLength; buf[5] = 1; outfile.write((uint8_t*)buf, 24); - // setCallback( std::bind(&Netdump::fileDumpProcess, this, outfile, std::placeholders::_1)); setCallback([outfile, this](NetdumpPacket & ndp) { fileDumpProcess(outfile, ndp); @@ -87,19 +77,18 @@ void Netdump::tcpDump(WiFiServer &tcpDumpServer, NetdumpFilter nf) { delete packetBuffer; } - packetBuffer = new char[2048]; + packetBuffer = new char[tcpBuffersize]; bufferIndex = 0; - schedule_function([&tcpDumpServer, this]() + schedule_function([&tcpDumpServer, this, nf]() { - tcpDumpLoop(tcpDumpServer); + tcpDumpLoop(tcpDumpServer, nf); }); - Serial.printf("scheduled\r\n"); } void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int success) { - NetdumpPacket np(netif_idx, data, len, out, success); + NetdumpPacket np(millis(), netif_idx, data, len, out, success); if (self->netDumpCallback) { if (self->netDumpFilter && !self->netDumpFilter(np)) @@ -112,12 +101,12 @@ void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int void Netdump::printDumpProcess(Print& out, NetdumpPacket::PacketDetail ndd, const NetdumpPacket& np) { - out.printf("%8d %s", millis(), np.toString(ndd).c_str()); + out.printf("%8d %s", np.getTime(), np.toString(ndd).c_str()); } void Netdump::fileDumpProcess(File outfile, const NetdumpPacket& np) { - size_t incl_len = np.len > 1024 ? 1024 : np.len; + size_t incl_len = np.getSize() > maxPcapLength ? maxPcapLength : np.getSize(); char buf[16]; struct timeval tv; @@ -125,43 +114,46 @@ void Netdump::fileDumpProcess(File outfile, const NetdumpPacket& np) *(uint32_t*)&buf[0] = tv.tv_sec; *(uint32_t*)&buf[4] = tv.tv_usec; *(uint32_t*)&buf[8] = incl_len; - *(uint32_t*)&buf[12] = np.len; + *(uint32_t*)&buf[12] = np.getSize(); outfile.write(buf, 16); - outfile.write(np.data, incl_len); + outfile.write(np.rawData(), incl_len); } + void Netdump::tcpDumpProcess(const NetdumpPacket& np) { - // Get capture code from netdumpout.cpp if (np.isIPv4() && np.isTCP() - && ((np.out && np.getSrcPort() == tcpDumpClient.localPort()) - || (!np.out && np.getDstPort() == tcpDumpClient.localPort()) + && ((np.getInOut() && np.getSrcPort() == tcpDumpClient.localPort()) + || (!np.getInOut() && np.getDstPort() == tcpDumpClient.localPort()) ) ) { // skip myself return; } - size_t incl_len = np.len > 1024 ? 1024 : np.len; + size_t incl_len = np.getSize() > maxPcapLength ? maxPcapLength : np.getSize(); + + if (bufferIndex+16+incl_len < tcpBuffersize) // only add if enough space available + { + struct timeval tv; + gettimeofday(&tv, nullptr); + *(uint32_t*)&packetBuffer[bufferIndex] = tv.tv_sec; + *(uint32_t*)&packetBuffer[bufferIndex + 4] = tv.tv_usec; + *(uint32_t*)&packetBuffer[bufferIndex + 8] = incl_len; + *(uint32_t*)&packetBuffer[bufferIndex + 12] = np.getSize(); + bufferIndex += 16; + memcpy(&packetBuffer[bufferIndex], np.rawData(), incl_len); + bufferIndex += incl_len; + } - struct timeval tv; - gettimeofday(&tv, nullptr); - *(uint32_t*)&packetBuffer[bufferIndex] = tv.tv_sec; - *(uint32_t*)&packetBuffer[bufferIndex + 4] = tv.tv_usec; - *(uint32_t*)&packetBuffer[bufferIndex + 8] = incl_len; - *(uint32_t*)&packetBuffer[bufferIndex + 12] = np.len; - bufferIndex += 16; - memcpy(&packetBuffer[bufferIndex], np.data, incl_len); - bufferIndex += incl_len; if (bufferIndex && tcpDumpClient && tcpDumpClient.availableForWrite() >= bufferIndex) { tcpDumpClient.write(packetBuffer, bufferIndex); bufferIndex = 0; } - - } -void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer) + +void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, NetdumpFilter nf) { if (tcpDumpServer.hasClient()) { @@ -174,7 +166,7 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer) *(uint32_t*)&packetBuffer[4] = 0x00040002; *(uint32_t*)&packetBuffer[8] = 0; *(uint32_t*)&packetBuffer[12] = 0; - *(uint32_t*)&packetBuffer[16] = 1024; + *(uint32_t*)&packetBuffer[16] = maxPcapLength; *(uint32_t*)&packetBuffer[20] = 1; tcpDumpClient.write(packetBuffer, 24); bufferIndex = 0; @@ -182,7 +174,7 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer) setCallback([this](NetdumpPacket & ndp) { tcpDumpProcess(ndp); - }); + }, nf); Serial.printf("client started\r\n"); } @@ -199,9 +191,9 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer) if (tcpDumpServer.status() != CLOSED) { - schedule_function([&tcpDumpServer, this]() + schedule_function([&tcpDumpServer, this, nf]() { - tcpDumpLoop(tcpDumpServer); + tcpDumpLoop(tcpDumpServer, nf); }); } } diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h index 7257783094..876dd3b255 100644 --- a/libraries/Netdump/src/Netdump.h +++ b/libraries/Netdump/src/Netdump.h @@ -65,11 +65,14 @@ class Netdump void printDumpProcess(Print& out, NetdumpPacket::PacketDetail ndd, const NetdumpPacket& np); void fileDumpProcess(File outfile, const NetdumpPacket& np); void tcpDumpProcess(const NetdumpPacket& np); - void tcpDumpLoop(WiFiServer &tcpDumpServer); + void tcpDumpLoop(WiFiServer &tcpDumpServer, NetdumpFilter nf); WiFiClient tcpDumpClient; char* packetBuffer = nullptr; size_t bufferIndex = 0; + + static constexpr int tcpBuffersize = 2048; + static constexpr int maxPcapLength = 1024; }; #endif /* __NETDUMP_H */ diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index db89d343b8..d589cff0d1 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -134,6 +134,10 @@ String NetdumpPacket::toString(PacketDetail netdumpDetail) const { udpType = "WSDD"; } + else if (isOTA()) + { + udpType = "OTA"; + } else { udpType = "UDP "; diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index e7d2be3364..2d24bad3b6 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -32,8 +32,8 @@ class NetdumpPacket { public: - NetdumpPacket(int n, const char* d, size_t l, int o, int s) - : netif_idx(n), data(d), len(l), out(o), success(s) + NetdumpPacket(unsigned long msec, int n, const char* d, size_t l, int o, int s) + : packetTime(msec), netif_idx(n), data(d), len(l), out(o), success(s) {}; virtual ~NetdumpPacket() {}; @@ -45,12 +45,22 @@ class NetdumpPacket CHARS }; - int netif_idx; - const char* data; - size_t len; - int out; - int success; - + const char* rawData() const + { + return data; + } + int getInOut() const + { + return out; + } + unsigned long getTime() const + { + return packetTime; + } + uint32_t getSize() const + { + return len; + } uint16_t ntoh16(uint16_t idx) const { return data[idx + 1] | (((uint16_t)data[idx]) << 8); @@ -200,6 +210,10 @@ class NetdumpPacket { return (hasPort(80)); }; + bool isOTA() const + { + return (hasPort(8266)); + } NetdumpIP getIP(uint16_t idx) const @@ -232,7 +246,7 @@ class NetdumpPacket bool hasIP(NetdumpIP ip) const { - return ((ip == sourceIP()) || (ip == destIP())); + return ((ip == sourceIP()) || (ip == destIP())); } NetdumpIP destIP() const @@ -264,7 +278,14 @@ class NetdumpPacket String toString(PacketDetail netdumpDetail = PacketDetail::NONE) const; void printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const; +private: + unsigned long packetTime; + int netif_idx; + const char* data; + size_t len; + int out; + int success; }; -#endif /* LIBRARIES_ESPGOODIES_HR_SRC_NETDUMP_PACKET_H_ */ +#endif /* __NETDUMP_PACKET_H */ From 991523024fb6e0ea65046855df3c1dd0bf22579e Mon Sep 17 00:00:00 2001 From: hreintke Date: Fri, 15 Nov 2019 17:37:04 +0100 Subject: [PATCH 06/22] Add PacketType & restructure printing using that --- libraries/Netdump/src/NetdumpPacket.cpp | 263 +++++++++++++----------- libraries/Netdump/src/NetdumpPacket.h | 42 +++- 2 files changed, 179 insertions(+), 126 deletions(-) diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index d589cff0d1..23107ebfe9 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -22,6 +22,8 @@ #include "Netdump.h" #include +constexpr char* NetdumpPacket::packetTypeArray[]; + void NetdumpPacket::printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const { if (pd == PacketDetail::NONE) @@ -61,17 +63,47 @@ void NetdumpPacket::printDetail(Print& out, const String& indent, const char* da } } +NetdumpPacket::PacketType NetdumpPacket::packetType() const +{ + if (isARP()) return PacketType::ARP; + if (isIP()) + { + if (isUDP()) + { + if (isMDNS()) return PacketType::MDNS; + if (isDNS()) return PacketType::DNS; + if (isSSDP()) return PacketType::SSDP; + if (isDHCP()) return PacketType::DHCP; + if (isWSDD()) return PacketType::WSDD; + if (isNETBIOS()) return PacketType::NETBIOS; + if (isSMB()) return PacketType::SMB; + if (isOTA()) return PacketType::OTA; + return PacketType::UDP; + } + if (isTCP()) + { + if (isHTTP()) return PacketType::HTTP; + return PacketType::TCP; + } + if (isICMP()) return PacketType::ICMP; + if (isIGMP()) return PacketType::IGMP; + return PacketType::IP; + } + return PacketType::UKNW; +} + String NetdumpPacket::toString(PacketDetail netdumpDetail) const { StreamString sstr; sstr.reserve(128); - sstr.printf("%d %3s ", netif_idx, out ? "out" : "in "); + sstr.printf("%d %3s %s ", netif_idx, out ? "out" : "in ", packetTypeString(packetType())); - if (isARP()) + switch (packetType()) + { + case PacketType::ARP : { - sstr.printf("ARP "); switch (getARPType()) { case 1 : sstr.printf("who has %s tell %s", getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); @@ -90,143 +122,130 @@ String NetdumpPacket::toString(PacketDetail netdumpDetail) const sstr.printf("\r\n"); return sstr; } - - if (isIP()) + case PacketType::MDNS : + case PacketType::DNS : { - if (isUDP()) + sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf("ID=0x%04x ", ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8)); + sstr.printf("F=0x%04x ", ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 2)); + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 4)) { - if (isMDNS() || isDNS()) - { - sstr.printf("%s%s>%s ", isMDNS() ? "MDNS " : "DNS ", sourceIP().toString().c_str(), destIP().toString().c_str()); - sstr.printf("ID=0x%04x ", ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8)); - sstr.printf("F=0x%04x ", ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 2)); - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 4)) - { - sstr.printf("Q=%d ", t); - } - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 6)) - { - sstr.printf("R=%d ", t); - } - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 8)) - { - sstr.printf("TR=%d ", t); - } - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 10)) - { - sstr.printf("DR=%d ", t); - } - sstr.printf("\r\n"); - } - else - { - String udpType; - - if (isSSDP()) - { - udpType = "SSDP"; - } - else if (isDHCP()) - { - udpType = "DHCP"; - } - else if (isWSDD()) - { - udpType = "WSDD"; - } - else if (isOTA()) - { - udpType = "OTA"; - } - else - { - udpType = "UDP "; - } - sstr.printf("%s %s>%s ", udpType.c_str(), sourceIP().toString().c_str(), destIP().toString().c_str()); - sstr.printf("%d:%d", getSrcPort(), getDstPort()); - sstr.printf("\r\n"); - } - printDetail(sstr, " H ", &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); - printDetail(sstr, " D ", &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); - return sstr; + sstr.printf("Q=%d ", t); } - else if (isTCP()) + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 6)) { - sstr.printf(isHTTP() ? "HTTP " : "TCP "); - sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); - sstr.printf("%d:%d ", getSrcPort(), getDstPort()); - uint16_t flags = getTcpFlags(); - sstr.print('['); - const char chars [] = "FSRPAUECN"; - for (uint8_t i = 0; i < sizeof chars; i++) - if (flags & (1 << i)) - { - sstr.print(chars[i]); - } - sstr.print(']'); - sstr.printf(" len: %u seq: %u, ack: %u, wnd: %u ", getTcpLen(), getTcpSeq(), getTcpAck(), getTcpWindow()); - sstr.printf("\r\n"); - printDetail(sstr, " H ", &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail); - printDetail(sstr, " D ", &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); - return sstr; + sstr.printf("R=%d ", t); + } + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 8)) + { + sstr.printf("TR=%d ", t); } - else if (isICMP()) + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 10)) { - sstr.printf("ICMP "); - sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); - if (isIPv4()) + sstr.printf("DR=%d ", t); + } + sstr.printf("\r\n"); + printDetail(sstr, " H ", &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); + printDetail(sstr, " D ", &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); + return sstr; + } + case PacketType::SSDP : + case PacketType::DHCP : + case PacketType::WSDD : + case PacketType::NETBIOS : + case PacketType::SMB : + case PacketType::OTA : + case PacketType::UDP : + { + sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf("%d:%d", getSrcPort(), getDstPort()); + sstr.printf("\r\n"); + printDetail(sstr, " H ", &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); + printDetail(sstr, " D ", &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); + return sstr; + } + case PacketType::TCP : + case PacketType::HTTP : + { + sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf("%d:%d ", getSrcPort(), getDstPort()); + uint16_t flags = getTcpFlags(); + sstr.print('['); + const char chars [] = "FSRPAUECN"; + for (uint8_t i = 0; i < sizeof chars; i++) + if (flags & (1 << i)) { - switch (getIcmpType()) - { - case 0 : sstr.printf("ping reply"); break; - case 8 : sstr.printf("ping request"); break; - default: sstr.printf("type(0x%02x)", getIcmpType()); break; - } + sstr.print(chars[i]); } - if (isIPv6()) + sstr.print(']'); + sstr.printf(" len: %u seq: %u, ack: %u, wnd: %u ", getTcpLen(), getTcpSeq(), getTcpAck(), getTcpWindow()); + sstr.printf("\r\n"); + printDetail(sstr, " H ", &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail); + printDetail(sstr, " D ", &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); + return sstr; + } + case PacketType::ICMP : + { + sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); + if (isIPv4()) + { + switch (getIcmpType()) { - switch (getIcmpType()) - { - case 129 : sstr.printf("ping reply"); break; - case 128 : sstr.printf("ping request"); break; - case 135 : sstr.printf("Neighbour solicitation"); break; - case 136 : sstr.printf("Neighbour advertisement"); break; - default: sstr.printf("type(0x%02x)", getIcmpType()); break; - } + case 0 : sstr.printf("ping reply"); break; + case 8 : sstr.printf("ping request"); break; + default: sstr.printf("type(0x%02x)", getIcmpType()); break; } - sstr.printf("\r\n"); - return sstr; } - else if (isIGMP()) + if (isIPv6()) { - sstr.printf("IGMP "); - switch (getIgmpType()) + switch (getIcmpType()) { - case 1 : sstr.printf("Create Group Request"); break; - case 2 : sstr.printf("Create Group Reply"); break; - case 3 : sstr.printf("Join Group Request"); break; - case 4 : sstr.printf("Join Group Reply"); break; - case 5 : sstr.printf("Leave Group Request"); break; - case 6 : sstr.printf("Leave Group Reply"); break; - case 7 : sstr.printf("Confirm Group Request"); break; - case 8 : sstr.printf("Confirm Group Reply"); break; - case 0x11 : sstr.printf("Group Membership Query"); break; - case 0x12 : sstr.printf("IGMPv1 Membership Report"); break; - case 0x22 : sstr.printf("IGMPv3 Membership Report"); break; - default: sstr.printf("type(0x%02x)", getIgmpType()); break; + case 129 : sstr.printf("ping reply"); break; + case 128 : sstr.printf("ping request"); break; + case 135 : sstr.printf("Neighbour solicitation"); break; + case 136 : sstr.printf("Neighbour advertisement"); break; + default: sstr.printf("type(0x%02x)", getIcmpType()); break; } - sstr.printf("\r\n"); - return sstr; } - else + sstr.printf("\r\n"); + return sstr; + } + case PacketType::IGMP : + { + switch (getIgmpType()) { - sstr.printf("UKWN type = %d\r\n", ipType()); - return sstr; + case 1 : sstr.printf("Create Group Request"); break; + case 2 : sstr.printf("Create Group Reply"); break; + case 3 : sstr.printf("Join Group Request"); break; + case 4 : sstr.printf("Join Group Reply"); break; + case 5 : sstr.printf("Leave Group Request"); break; + case 6 : sstr.printf("Leave Group Reply"); break; + case 7 : sstr.printf("Confirm Group Request"); break; + case 8 : sstr.printf("Confirm Group Reply"); break; + case 0x11 : sstr.printf("Group Membership Query"); break; + case 0x12 : sstr.printf("IGMPv1 Membership Report"); break; + case 0x22 : sstr.printf("IGMPv3 Membership Report"); break; + default: sstr.printf("type(0x%02x)", getIgmpType()); break; } + sstr.printf("\r\n"); + return sstr; + } + case PacketType::IP : + { + sstr.printf("Unknown IP type : %d\r\n", ipType()); + return sstr; + } + case PacketType::UKNW : + { + sstr.printf("Unknown packet, type = 0x%04x\r\n", ethType()); + return sstr; + } + default : + { + sstr.printf("Non identified packet\r\n"); + return sstr; + } } - - sstr.printf("Unknown packet, type = 0x%04x\r\n", ethType()); - return sstr; } diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index 2d24bad3b6..ba38e2eedc 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -45,6 +45,36 @@ class NetdumpPacket CHARS }; + enum class PacketType + { + ARP, + IP, + UDP, + MDNS, + DNS, + SSDP, + DHCP, + WSDD, + NETBIOS, + SMB, + OTA, + TCP, + HTTP, + ICMP, + IGMP, + UKNW, + }; + + static constexpr char* packetTypeArray[] = {"ARP ","IP ","UDP ","MDNS","DNS ", + "SSDP","DHCP","WSDD","NBIO", "SMB ","OTA ","TCP ", + "HTTP","ICMP","IGMP","UKNW"}; + + const char* packetTypeString (PacketType pt) const + { + return packetTypeArray[static_cast(pt)]; + } + PacketType packetType() const; + const char* rawData() const { return data; @@ -152,8 +182,6 @@ class NetdumpPacket { return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 4); }; - - bool isARP() const { return (ethType() == 0x0806); @@ -214,8 +242,14 @@ class NetdumpPacket { return (hasPort(8266)); } - - + bool isNETBIOS() const + { + return (hasPort(137) || hasPort(138) || hasPort(139)); + } + bool isSMB() const + { + return (hasPort(445)); + } NetdumpIP getIP(uint16_t idx) const { return NetdumpIP(data[idx], From a3e83f648fdec6458f8f9a656ca77a8e9e01a8e6 Mon Sep 17 00:00:00 2001 From: hreintke Date: Sun, 17 Nov 2019 16:06:13 +0100 Subject: [PATCH 07/22] Updates relating to @devyte comments Add namespace Strings to flash --- libraries/Netdump/src/Netdump.cpp | 43 ++++----- libraries/Netdump/src/Netdump.h | 36 ++++---- libraries/Netdump/src/NetdumpIP.cpp | 5 ++ libraries/Netdump/src/NetdumpIP.h | 7 +- libraries/Netdump/src/NetdumpPacket.cpp | 113 ++++++++++++------------ libraries/Netdump/src/NetdumpPacket.h | 18 ++-- 6 files changed, 124 insertions(+), 98 deletions(-) diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index 338aefc20d..e3c3771600 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -23,20 +23,23 @@ #include #include "Schedule.h" +namespace NetCapture +{ + Netdump* Netdump::self; -void Netdump::setCallback(NetdumpCallback nc) +void Netdump::setCallback(const Callback nc) { netDumpCallback = nc; } -void Netdump::setCallback(NetdumpCallback nc, NetdumpFilter nf) +void Netdump::setCallback(const Callback nc, const Filter nf) { netDumpFilter = nf; netDumpCallback = nc; } -void Netdump::setFilter(NetdumpFilter nf) +void Netdump::setFilter(const Filter nf) { netDumpFilter = nf; } @@ -46,16 +49,16 @@ void Netdump::reset() setCallback(nullptr, nullptr); } -void Netdump::printDump(Print& out, NetdumpPacket::PacketDetail ndd, NetdumpFilter nf) +void Netdump::printDump(Print& out, Packet::PacketDetail ndd, Filter nf) { out.printf("netDump starting\r\n"); - setCallback([&out, ndd, this](NetdumpPacket & ndp) + setCallback([&out, ndd, this](Packet & ndp) { printDumpProcess(out, ndd, ndp); }, nf); } -void Netdump::fileDump(File outfile, NetdumpFilter nf) +void Netdump::fileDump(File& outfile, Filter nf) { uint32_t buf[6]; buf[0] = 0xa1b2c3d4; @@ -66,12 +69,12 @@ void Netdump::fileDump(File outfile, NetdumpFilter nf) buf[5] = 1; outfile.write((uint8_t*)buf, 24); - setCallback([outfile, this](NetdumpPacket & ndp) + setCallback([&outfile, this](Packet & ndp) { fileDumpProcess(outfile, ndp); }, nf); } -void Netdump::tcpDump(WiFiServer &tcpDumpServer, NetdumpFilter nf) +void Netdump::tcpDump(WiFiServer &tcpDumpServer, Filter nf) { if (packetBuffer) { @@ -88,7 +91,7 @@ void Netdump::tcpDump(WiFiServer &tcpDumpServer, NetdumpFilter nf) void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int success) { - NetdumpPacket np(millis(), netif_idx, data, len, out, success); + Packet np(millis(), netif_idx, data, len, out, success); if (self->netDumpCallback) { if (self->netDumpFilter && !self->netDumpFilter(np)) @@ -99,14 +102,14 @@ void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int } } -void Netdump::printDumpProcess(Print& out, NetdumpPacket::PacketDetail ndd, const NetdumpPacket& np) +void Netdump::printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) { out.printf("%8d %s", np.getTime(), np.toString(ndd).c_str()); } -void Netdump::fileDumpProcess(File outfile, const NetdumpPacket& np) +void Netdump::fileDumpProcess(File& outfile, const Packet& np) { - size_t incl_len = np.getSize() > maxPcapLength ? maxPcapLength : np.getSize(); + size_t incl_len = np.getPacketSize() > maxPcapLength ? maxPcapLength : np.getPacketSize(); char buf[16]; struct timeval tv; @@ -114,13 +117,13 @@ void Netdump::fileDumpProcess(File outfile, const NetdumpPacket& np) *(uint32_t*)&buf[0] = tv.tv_sec; *(uint32_t*)&buf[4] = tv.tv_usec; *(uint32_t*)&buf[8] = incl_len; - *(uint32_t*)&buf[12] = np.getSize(); + *(uint32_t*)&buf[12] = np.getPacketSize(); outfile.write(buf, 16); outfile.write(np.rawData(), incl_len); } -void Netdump::tcpDumpProcess(const NetdumpPacket& np) +void Netdump::tcpDumpProcess(const Packet& np) { if (np.isIPv4() && np.isTCP() && ((np.getInOut() && np.getSrcPort() == tcpDumpClient.localPort()) @@ -131,7 +134,7 @@ void Netdump::tcpDumpProcess(const NetdumpPacket& np) // skip myself return; } - size_t incl_len = np.getSize() > maxPcapLength ? maxPcapLength : np.getSize(); + size_t incl_len = np.getPacketSize() > maxPcapLength ? maxPcapLength : np.getPacketSize(); if (bufferIndex+16+incl_len < tcpBuffersize) // only add if enough space available { @@ -140,7 +143,7 @@ void Netdump::tcpDumpProcess(const NetdumpPacket& np) *(uint32_t*)&packetBuffer[bufferIndex] = tv.tv_sec; *(uint32_t*)&packetBuffer[bufferIndex + 4] = tv.tv_usec; *(uint32_t*)&packetBuffer[bufferIndex + 8] = incl_len; - *(uint32_t*)&packetBuffer[bufferIndex + 12] = np.getSize(); + *(uint32_t*)&packetBuffer[bufferIndex + 12] = np.getPacketSize(); bufferIndex += 16; memcpy(&packetBuffer[bufferIndex], np.rawData(), incl_len); bufferIndex += incl_len; @@ -153,7 +156,7 @@ void Netdump::tcpDumpProcess(const NetdumpPacket& np) } } -void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, NetdumpFilter nf) +void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, Filter nf) { if (tcpDumpServer.hasClient()) { @@ -171,12 +174,10 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, NetdumpFilter nf) tcpDumpClient.write(packetBuffer, 24); bufferIndex = 0; - setCallback([this](NetdumpPacket & ndp) + setCallback([this](Packet & ndp) { tcpDumpProcess(ndp); }, nf); - - Serial.printf("client started\r\n"); } if (!tcpDumpClient || !tcpDumpClient.connected()) { @@ -197,3 +198,5 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, NetdumpFilter nf) }); } } + +} // namespace NetCapture diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h index 876dd3b255..ee120d0b06 100644 --- a/libraries/Netdump/src/Netdump.h +++ b/libraries/Netdump/src/Netdump.h @@ -29,43 +29,47 @@ #include "NetdumpPacket.h" #include -using NetdumpFilter = std::function; -using NetdumpCallback = std::function; +namespace NetCapture +{ class Netdump { public: + + using Filter = std::function; + using Callback = std::function; + Netdump() { phy_capture = capture; self = this; }; - virtual ~Netdump() + ~Netdump() { phy_capture = nullptr; }; - void setCallback(NetdumpCallback nc); - void setCallback(NetdumpCallback nc, NetdumpFilter nf); - void setFilter(NetdumpFilter nf); + void setCallback(const Callback nc); + void setCallback(const Callback nc, const Filter nf); + void setFilter(const Filter nf); void reset(); - void printDump(Print& out, NetdumpPacket::PacketDetail ndd, NetdumpFilter nf = nullptr); - void fileDump(File outfile, NetdumpFilter nf = nullptr); - void tcpDump(WiFiServer &tcpDumpServer, NetdumpFilter nf = nullptr); + void printDump(Print& out, Packet::PacketDetail ndd, Filter nf = nullptr); + void fileDump(File& outfile, Filter nf = nullptr); + void tcpDump(WiFiServer &tcpDumpServer, Filter nf = nullptr); private: - NetdumpCallback netDumpCallback = nullptr; - NetdumpFilter netDumpFilter = nullptr; + Callback netDumpCallback = nullptr; + Filter netDumpFilter = nullptr; static Netdump* self; static void capture(int netif_idx, const char* data, size_t len, int out, int success); - void printDumpProcess(Print& out, NetdumpPacket::PacketDetail ndd, const NetdumpPacket& np); - void fileDumpProcess(File outfile, const NetdumpPacket& np); - void tcpDumpProcess(const NetdumpPacket& np); - void tcpDumpLoop(WiFiServer &tcpDumpServer, NetdumpFilter nf); + void printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np); + void fileDumpProcess(File& outfile, const Packet& np); + void tcpDumpProcess(const Packet& np); + void tcpDumpLoop(WiFiServer &tcpDumpServer, Filter nf); WiFiClient tcpDumpClient; char* packetBuffer = nullptr; @@ -75,4 +79,6 @@ class Netdump static constexpr int maxPcapLength = 1024; }; +} // namespace NetCapture + #endif /* __NETDUMP_H */ diff --git a/libraries/Netdump/src/NetdumpIP.cpp b/libraries/Netdump/src/NetdumpIP.cpp index f812984c02..2a1c9212af 100644 --- a/libraries/Netdump/src/NetdumpIP.cpp +++ b/libraries/Netdump/src/NetdumpIP.cpp @@ -21,6 +21,9 @@ #include #include +namespace NetCapture +{ + NetdumpIP::NetdumpIP() { } @@ -372,3 +375,5 @@ bool NetdumpIP::compareIP(const NetdumpIP& nip) const break; } } + +} // namespace NetCapture diff --git a/libraries/Netdump/src/NetdumpIP.h b/libraries/Netdump/src/NetdumpIP.h index ab3999a38d..73b668ac3c 100644 --- a/libraries/Netdump/src/NetdumpIP.h +++ b/libraries/Netdump/src/NetdumpIP.h @@ -13,11 +13,14 @@ #include #include +namespace NetCapture +{ + class NetdumpIP { public: NetdumpIP(); - virtual ~NetdumpIP(); + ~NetdumpIP(); NetdumpIP(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); NetdumpIP(const uint8_t *address, bool V4 = true); @@ -96,4 +99,6 @@ class NetdumpIP }; +} // namespace NetCapture + #endif /* LIBRARIES_ESPGOODIES_HR_SRC_NETDUMP_NETDUMPIP_H_ */ diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index 23107ebfe9..708187e8fb 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -22,9 +22,12 @@ #include "Netdump.h" #include -constexpr char* NetdumpPacket::packetTypeArray[]; +namespace NetCapture +{ + +constexpr char* Packet::packetTypeArray[]; -void NetdumpPacket::printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const +void Packet::printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const { if (pd == PacketDetail::NONE) { @@ -63,7 +66,7 @@ void NetdumpPacket::printDetail(Print& out, const String& indent, const char* da } } -NetdumpPacket::PacketType NetdumpPacket::packetType() const +Packet::PacketType Packet::packetType() const { if (isARP()) return PacketType::ARP; if (isIP()) @@ -92,13 +95,12 @@ NetdumpPacket::PacketType NetdumpPacket::packetType() const return PacketType::UKNW; } - -String NetdumpPacket::toString(PacketDetail netdumpDetail) const +String Packet::toString(PacketDetail netdumpDetail) const { StreamString sstr; sstr.reserve(128); - sstr.printf("%d %3s %s ", netif_idx, out ? "out" : "in ", packetTypeString(packetType())); + sstr.printf_P(PSTR("%d %3s %s "), netif_idx, out ? "out" : "in ", packetTypeString(packetType())); switch (packetType()) { @@ -106,12 +108,12 @@ String NetdumpPacket::toString(PacketDetail netdumpDetail) const { switch (getARPType()) { - case 1 : sstr.printf("who has %s tell %s", getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); + case 1 : sstr.printf_P(PSTR("who has %s tell %s"), getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); break; - case 2 : sstr.printf("%s is at ", getIP(ETH_HDR_LEN + 14).toString().c_str()); + case 2 : sstr.printf_P(PSTR("%s is at "), getIP(ETH_HDR_LEN + 14).toString().c_str()); for (int i = 0; i < 6; i++) { - sstr.printf("%02x", (unsigned char)data[ETH_HDR_LEN + 8 + i]); + sstr.printf_P(PSTR("%02x"), (unsigned char)data[ETH_HDR_LEN + 8 + i]); if (i < 5) { sstr.print(':'); @@ -125,28 +127,28 @@ String NetdumpPacket::toString(PacketDetail netdumpDetail) const case PacketType::MDNS : case PacketType::DNS : { - sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); - sstr.printf("ID=0x%04x ", ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8)); - sstr.printf("F=0x%04x ", ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 2)); + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("ID=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8)); + sstr.printf_P(PSTR("F=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 2)); if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 4)) { - sstr.printf("Q=%d ", t); + sstr.printf_P(PSTR("Q=%d "), t); } if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 6)) { - sstr.printf("R=%d ", t); + sstr.printf_P(PSTR("R=%d "), t); } if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 8)) { - sstr.printf("TR=%d ", t); + sstr.printf_P(PSTR("TR=%d "), t); } if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 10)) { - sstr.printf("DR=%d ", t); + sstr.printf_P(PSTR("DR=%d "), t); } - sstr.printf("\r\n"); - printDetail(sstr, " H ", &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); - printDetail(sstr, " D ", &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); return sstr; } case PacketType::SSDP : @@ -157,18 +159,18 @@ String NetdumpPacket::toString(PacketDetail netdumpDetail) const case PacketType::OTA : case PacketType::UDP : { - sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); - sstr.printf("%d:%d", getSrcPort(), getDstPort()); - sstr.printf("\r\n"); - printDetail(sstr, " H ", &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); - printDetail(sstr, " D ", &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("%d:%d"), getSrcPort(), getDstPort()); + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); return sstr; } case PacketType::TCP : case PacketType::HTTP : { - sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); - sstr.printf("%d:%d ", getSrcPort(), getDstPort()); + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("%d:%d "), getSrcPort(), getDstPort()); uint16_t flags = getTcpFlags(); sstr.print('['); const char chars [] = "FSRPAUECN"; @@ -178,33 +180,33 @@ String NetdumpPacket::toString(PacketDetail netdumpDetail) const sstr.print(chars[i]); } sstr.print(']'); - sstr.printf(" len: %u seq: %u, ack: %u, wnd: %u ", getTcpLen(), getTcpSeq(), getTcpAck(), getTcpWindow()); - sstr.printf("\r\n"); - printDetail(sstr, " H ", &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail); - printDetail(sstr, " D ", &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); + sstr.printf_P(PSTR(" len: %u seq: %u, ack: %u, wnd: %u "), getTcpLen(), getTcpSeq(), getTcpAck(), getTcpWindow()); + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); return sstr; } case PacketType::ICMP : { - sstr.printf("%s>%s ", sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); if (isIPv4()) { switch (getIcmpType()) { - case 0 : sstr.printf("ping reply"); break; - case 8 : sstr.printf("ping request"); break; - default: sstr.printf("type(0x%02x)", getIcmpType()); break; + case 0 : sstr.printf_P(PSTR("ping reply")); break; + case 8 : sstr.printf_P(PSTR("ping request")); break; + default: sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType()); break; } } if (isIPv6()) { switch (getIcmpType()) { - case 129 : sstr.printf("ping reply"); break; - case 128 : sstr.printf("ping request"); break; - case 135 : sstr.printf("Neighbour solicitation"); break; - case 136 : sstr.printf("Neighbour advertisement"); break; - default: sstr.printf("type(0x%02x)", getIcmpType()); break; + case 129 : sstr.printf_P(PSTR("ping reply")); break; + case 128 : sstr.printf_P(PSTR("ping request")); break; + case 135 : sstr.printf_P(PSTR("Neighbour solicitation")); break; + case 136 : sstr.printf_P(PSTR("Neighbour advertisement")); break; + default: sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType()); break; } } sstr.printf("\r\n"); @@ -214,38 +216,39 @@ String NetdumpPacket::toString(PacketDetail netdumpDetail) const { switch (getIgmpType()) { - case 1 : sstr.printf("Create Group Request"); break; - case 2 : sstr.printf("Create Group Reply"); break; - case 3 : sstr.printf("Join Group Request"); break; - case 4 : sstr.printf("Join Group Reply"); break; - case 5 : sstr.printf("Leave Group Request"); break; - case 6 : sstr.printf("Leave Group Reply"); break; - case 7 : sstr.printf("Confirm Group Request"); break; - case 8 : sstr.printf("Confirm Group Reply"); break; - case 0x11 : sstr.printf("Group Membership Query"); break; - case 0x12 : sstr.printf("IGMPv1 Membership Report"); break; - case 0x22 : sstr.printf("IGMPv3 Membership Report"); break; - default: sstr.printf("type(0x%02x)", getIgmpType()); break; + case 1 : sstr.printf_P(PSTR("Create Group Request")); break; + case 2 : sstr.printf_P(PSTR("Create Group Reply")); break; + case 3 : sstr.printf_P(PSTR("Join Group Request")); break; + case 4 : sstr.printf_P(PSTR("Join Group Reply")); break; + case 5 : sstr.printf_P(PSTR("Leave Group Request")); break; + case 6 : sstr.printf_P(PSTR("Leave Group Reply")); break; + case 7 : sstr.printf_P(PSTR("Confirm Group Request")); break; + case 8 : sstr.printf_P(PSTR("Confirm Group Reply")); break; + case 0x11 : sstr.printf_P(PSTR("Group Membership Query")); break; + case 0x12 : sstr.printf_P(PSTR("IGMPv1 Membership Report")); break; + case 0x22 : sstr.printf_P(PSTR("IGMPv3 Membership Report")); break; + default: sstr.printf_P(PSTR("type(0x%02x)"), getIgmpType()); break; } - sstr.printf("\r\n"); + sstr.printf_P(PSTR("\r\n")); return sstr; } case PacketType::IP : { - sstr.printf("Unknown IP type : %d\r\n", ipType()); + sstr.printf_P(PSTR("Unknown IP type : %d\r\n"), ipType()); return sstr; } case PacketType::UKNW : { - sstr.printf("Unknown packet, type = 0x%04x\r\n", ethType()); + sstr.printf_P(("Unknown packet, type = 0x%04x\r\n"), ethType()); return sstr; } default : { - sstr.printf("Non identified packet\r\n"); + sstr.printf_P(PSTR("Non identified packet\r\n")); return sstr; } } } +} // namespace NetCapture diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index ba38e2eedc..440a7c5347 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -27,16 +27,19 @@ #include #include "NetdumpIP.h" -#define ETH_HDR_LEN 14 +namespace NetCapture +{ + +int constexpr ETH_HDR_LEN = 14; -class NetdumpPacket +class Packet { public: - NetdumpPacket(unsigned long msec, int n, const char* d, size_t l, int o, int s) + Packet(unsigned long msec, int n, const char* d, size_t l, int o, int s) : packetTime(msec), netif_idx(n), data(d), len(l), out(o), success(s) {}; - virtual ~NetdumpPacket() {}; + ~Packet() {}; enum class PacketDetail { @@ -87,7 +90,7 @@ class NetdumpPacket { return packetTime; } - uint32_t getSize() const + uint32_t getPacketSize() const { return len; } @@ -120,7 +123,7 @@ class NetdumpPacket { return isIPv4() ? (((unsigned char)data[ETH_HDR_LEN]) & 0x0f) << 2 : 40 ; // IPv6 is fixed length } - uint16_t getIpTotLen() const + uint16_t getIpTotalLen() const { return ntoh16(ETH_HDR_LEN + 2); } @@ -149,7 +152,7 @@ class NetdumpPacket };//Header len is in multiple of 4 bytes uint16_t getTcpLen() const { - return getIpTotLen() - getIpHdrLen() - getTcpHdrLen() ; + return getIpTotalLen() - getIpHdrLen() - getTcpHdrLen() ; }; uint8_t getIcmpType() const @@ -321,5 +324,6 @@ class NetdumpPacket int success; }; +} // namespace NetCapture #endif /* __NETDUMP_PACKET_H */ From eea5caa34f52c40bf8687c6862d5d6fb7851af7b Mon Sep 17 00:00:00 2001 From: hreintke Date: Mon, 18 Nov 2019 12:55:10 +0100 Subject: [PATCH 08/22] update pcap header writing & adding consts --- libraries/Netdump/src/Netdump.cpp | 66 +++++++++++++++---------------- libraries/Netdump/src/Netdump.h | 12 ++++-- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index e3c3771600..1c5cd78ab0 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -49,7 +49,7 @@ void Netdump::reset() setCallback(nullptr, nullptr); } -void Netdump::printDump(Print& out, Packet::PacketDetail ndd, Filter nf) +void Netdump::printDump(Print& out, Packet::PacketDetail ndd, const Filter nf) { out.printf("netDump starting\r\n"); setCallback([&out, ndd, this](Packet & ndp) @@ -58,23 +58,16 @@ void Netdump::printDump(Print& out, Packet::PacketDetail ndd, Filter nf) }, nf); } -void Netdump::fileDump(File& outfile, Filter nf) +void Netdump::fileDump(File& outfile, const Filter nf) { - uint32_t buf[6]; - buf[0] = 0xa1b2c3d4; - buf[1] = 0x00040002; - buf[2] = 0; - buf[3] = 0; - buf[4] = maxPcapLength; - buf[5] = 1; - - outfile.write((uint8_t*)buf, 24); + + writePcapHeader(outfile); setCallback([&outfile, this](Packet & ndp) { fileDumpProcess(outfile, ndp); }, nf); } -void Netdump::tcpDump(WiFiServer &tcpDumpServer, Filter nf) +void Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf) { if (packetBuffer) { @@ -102,6 +95,20 @@ void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int } } +void Netdump::writePcapHeader(Stream& s) +{ + uint32_t pcapHeader[6]; + pcapHeader[0] = 0xa1b2c3d4; // pcap magic number + pcapHeader[1] = 0x00040002; // pcap major/minor version + pcapHeader[2] = 0; // pcap UTC correction in seconds + pcapHeader[3] = 0; // pcap time stamp accuracy + pcapHeader[4] = maxPcapLength; // pcap max packet length per record + pcapHeader[5] = 1; // pacp data linkt type = ethernet + s.write(reinterpret_cast(pcapHeader), 24); +} + + + void Netdump::printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) { out.printf("%8d %s", np.getTime(), np.toString(ndd).c_str()); @@ -110,15 +117,15 @@ void Netdump::printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packe void Netdump::fileDumpProcess(File& outfile, const Packet& np) { size_t incl_len = np.getPacketSize() > maxPcapLength ? maxPcapLength : np.getPacketSize(); - char buf[16]; + uint32_t pcapHeader[4]; struct timeval tv; gettimeofday(&tv, nullptr); - *(uint32_t*)&buf[0] = tv.tv_sec; - *(uint32_t*)&buf[4] = tv.tv_usec; - *(uint32_t*)&buf[8] = incl_len; - *(uint32_t*)&buf[12] = np.getPacketSize(); - outfile.write(buf, 16); + pcapHeader[0] = tv.tv_sec; + pcapHeader[1] = tv.tv_usec; + pcapHeader[2] = incl_len; + pcapHeader[3] = np.getPacketSize(); + outfile.write(reinterpret_cast(pcapHeader), 16); // pcap record header outfile.write(np.rawData(), incl_len); } @@ -140,11 +147,12 @@ void Netdump::tcpDumpProcess(const Packet& np) { struct timeval tv; gettimeofday(&tv, nullptr); - *(uint32_t*)&packetBuffer[bufferIndex] = tv.tv_sec; - *(uint32_t*)&packetBuffer[bufferIndex + 4] = tv.tv_usec; - *(uint32_t*)&packetBuffer[bufferIndex + 8] = incl_len; - *(uint32_t*)&packetBuffer[bufferIndex + 12] = np.getPacketSize(); - bufferIndex += 16; + uint32_t* pcapHeader = reinterpret_cast(&packetBuffer[bufferIndex]); + pcapHeader[0] = tv.tv_sec; // add pcap record header + pcapHeader[1] = tv.tv_usec; + pcapHeader[2] = incl_len; + pcapHeader[3] = np.getPacketSize(); + bufferIndex += 16; // pcap header size memcpy(&packetBuffer[bufferIndex], np.rawData(), incl_len); bufferIndex += incl_len; } @@ -156,23 +164,15 @@ void Netdump::tcpDumpProcess(const Packet& np) } } -void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, Filter nf) +void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf) { if (tcpDumpServer.hasClient()) { tcpDumpClient = tcpDumpServer.available(); - tcpDumpClient.setNoDelay(true); - // pcap-savefile(5) capture preamble - *(uint32_t*)&packetBuffer[0] = 0xa1b2c3d4; - *(uint32_t*)&packetBuffer[4] = 0x00040002; - *(uint32_t*)&packetBuffer[8] = 0; - *(uint32_t*)&packetBuffer[12] = 0; - *(uint32_t*)&packetBuffer[16] = maxPcapLength; - *(uint32_t*)&packetBuffer[20] = 1; - tcpDumpClient.write(packetBuffer, 24); bufferIndex = 0; + writePcapHeader(tcpDumpClient); setCallback([this](Packet & ndp) { diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h index ee120d0b06..f6bced5838 100644 --- a/libraries/Netdump/src/Netdump.h +++ b/libraries/Netdump/src/Netdump.h @@ -54,9 +54,9 @@ class Netdump void setFilter(const Filter nf); void reset(); - void printDump(Print& out, Packet::PacketDetail ndd, Filter nf = nullptr); - void fileDump(File& outfile, Filter nf = nullptr); - void tcpDump(WiFiServer &tcpDumpServer, Filter nf = nullptr); + void printDump(Print& out, Packet::PacketDetail ndd, const Filter nf = nullptr); + void fileDump(File& outfile, const Filter nf = nullptr); + void tcpDump(WiFiServer &tcpDumpServer, const Filter nf = nullptr); private: @@ -69,7 +69,9 @@ class Netdump void printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np); void fileDumpProcess(File& outfile, const Packet& np); void tcpDumpProcess(const Packet& np); - void tcpDumpLoop(WiFiServer &tcpDumpServer, Filter nf); + void tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf); + + void writePcapHeader(Stream& s); WiFiClient tcpDumpClient; char* packetBuffer = nullptr; @@ -77,6 +79,8 @@ class Netdump static constexpr int tcpBuffersize = 2048; static constexpr int maxPcapLength = 1024; + static constexpr uint32_t pcapMagic = 0xa1b2c3d4; + }; } // namespace NetCapture From d15f9d922a81b6c9b33479c258708acf2b373b89 Mon Sep 17 00:00:00 2001 From: hreintke Date: Mon, 18 Nov 2019 14:04:23 +0100 Subject: [PATCH 09/22] Improve NetdumpPacket type testing and content retrieval --- libraries/Netdump/src/Netdump.cpp | 8 +-- libraries/Netdump/src/NetdumpPacket.h | 84 ++++++++++++--------------- 2 files changed, 38 insertions(+), 54 deletions(-) diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index 1c5cd78ab0..7f5d3355d1 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -107,8 +107,6 @@ void Netdump::writePcapHeader(Stream& s) s.write(reinterpret_cast(pcapHeader), 24); } - - void Netdump::printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) { out.printf("%8d %s", np.getTime(), np.toString(ndd).c_str()); @@ -132,11 +130,7 @@ void Netdump::fileDumpProcess(File& outfile, const Packet& np) void Netdump::tcpDumpProcess(const Packet& np) { - if (np.isIPv4() && np.isTCP() - && ((np.getInOut() && np.getSrcPort() == tcpDumpClient.localPort()) - || (!np.getInOut() && np.getDstPort() == tcpDumpClient.localPort()) - ) - ) + if (np.isTCP() && np.hasPort(tcpDumpClient.localPort())) { // skip myself return; diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index 440a7c5347..ef8542712c 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -36,7 +36,7 @@ class Packet { public: Packet(unsigned long msec, int n, const char* d, size_t l, int o, int s) - : packetTime(msec), netif_idx(n), data(d), len(l), out(o), success(s) + : packetTime(msec), netif_idx(n), data(d), packetLength(l), out(o), success(s) {}; ~Packet() {}; @@ -92,7 +92,7 @@ class Packet } uint32_t getPacketSize() const { - return len; + return packetLength; } uint16_t ntoh16(uint16_t idx) const { @@ -116,74 +116,69 @@ class Packet }; uint8_t ipType() const { - return isIPv4() ? data[ETH_HDR_LEN + 9] : data[ETH_HDR_LEN + 6]; + return isIP() ? isIPv4() ? data[ETH_HDR_LEN + 9] : data[ETH_HDR_LEN + 6] : 0; }; - uint16_t getIpHdrLen() const { return isIPv4() ? (((unsigned char)data[ETH_HDR_LEN]) & 0x0f) << 2 : 40 ; // IPv6 is fixed length } uint16_t getIpTotalLen() const { - return ntoh16(ETH_HDR_LEN + 2); + return isIP() ? ntoh16(ETH_HDR_LEN + 2) : 0; } - // uint16_t getIpOptLen() { return getIpHdrLen() - 20; } - // uint16_t getIpUsrLen() { return getIpTotLen() - getIpHdrLen(); } - uint32_t getTcpSeq() const { - return ntoh32(ETH_HDR_LEN + getIpHdrLen() + 4); + return isTCP() ? ntoh32(ETH_HDR_LEN + getIpHdrLen() + 4) : 0; } uint32_t getTcpAck() const { - return ntoh32(ETH_HDR_LEN + getIpHdrLen() + 8); + return isTCP() ? ntoh32(ETH_HDR_LEN + getIpHdrLen() + 8) : 0; } uint16_t getTcpFlags() const { - return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 12); + return isTCP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 12) : 0; } uint16_t getTcpWindow() const { - return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 14); + return isTCP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 14) : 0; } uint8_t getTcpHdrLen() const { - return (data[ETH_HDR_LEN + getIpHdrLen() + 12] >> 4) * 4; + return isTCP() ? (data[ETH_HDR_LEN + getIpHdrLen() + 12] >> 4) * 4 : 0; };//Header len is in multiple of 4 bytes uint16_t getTcpLen() const { - return getIpTotalLen() - getIpHdrLen() - getTcpHdrLen() ; + return isTCP() ? getIpTotalLen() - getIpHdrLen() - getTcpHdrLen() : 0 ; }; uint8_t getIcmpType() const { - return data[ETH_HDR_LEN + getIpHdrLen() + 0]; + return isICMP() ? data[ETH_HDR_LEN + getIpHdrLen() + 0] : 0; } uint8_t getIgmpType() const { - return data[ETH_HDR_LEN + getIpHdrLen() + 0]; + return isIGMP() ? data[ETH_HDR_LEN + getIpHdrLen() + 0] : 0; } - uint8_t getARPType() const { - return data[ETH_HDR_LEN + 7]; + return isARP() ? data[ETH_HDR_LEN + 7] : 0; } bool is_ARP_who() const { - return getARPType() == 1; + return (getARPType() == 1); } bool is_ARP_is() const { - return getARPType() == 2; + return (getARPType() == 2); } uint8_t getUdpHdrLen() const { - return 8; + return isUDP() ? 8 : 0; }; uint16_t getUdpLen() const { - return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 4); + return isUDP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 4) : 0; }; bool isARP() const { @@ -203,70 +198,65 @@ class Packet }; bool isICMP() const { - return ((ipType() == 1) || ipType() == 58); + return (isIP() && ((ipType() == 1) || (ipType() == 58))); }; bool isIGMP() const { - return ipType() == 2; + return (isIP() && (ipType() == 2)); }; bool isTCP() const { - return ipType() == 6; + return (isIP() && (ipType() == 6)); }; bool isUDP() const { - return ipType() == 17; + return (isIP() && ipType() == 17); }; bool isMDNS() const { - return hasPort(5353); + return (isUDP() && hasPort(5353)); }; bool isDNS() const { - return hasPort(53); + return (isUDP() && hasPort(53)); }; bool isSSDP() const { - return hasPort(1900); + return (isUDP() && hasPort(1900)); }; bool isDHCP() const { - return (hasPort(546) || hasPort(547) || hasPort(67) || hasPort(68)); + return (isUDP() && ((hasPort(546) || hasPort(547) || hasPort(67) || hasPort(68)))); }; bool isWSDD() const { - return (hasPort(3702)); + return (isUDP() && hasPort(3702)); }; bool isHTTP() const { - return (hasPort(80)); + return (isTCP() && hasPort(80)); }; bool isOTA() const { - return (hasPort(8266)); + return (isUDP() && hasPort(8266)); } bool isNETBIOS() const { - return (hasPort(137) || hasPort(138) || hasPort(139)); + return (isUDP() && (hasPort(137) || hasPort(138) || hasPort(139))); } bool isSMB() const { - return (hasPort(445)); + return (isUDP() && hasPort(445)); } NetdumpIP getIP(uint16_t idx) const { - return NetdumpIP(data[idx], - data[idx + 1], - data[idx + 2], - data[idx + 3]); + return isIPv4() ? NetdumpIP(data[idx], data[idx + 1], data[idx + 2], data[idx + 3]) : NetdumpIP(); }; NetdumpIP getIP6(uint16_t idx) const { - return NetdumpIP((const uint8_t*)&data[idx], false); + return isIPv6() ? NetdumpIP((const uint8_t*)&data[idx], false) : NetdumpIP(); }; - - NetdumpIP sourceIP() const { NetdumpIP ip; @@ -283,7 +273,7 @@ class Packet bool hasIP(NetdumpIP ip) const { - return ((ip == sourceIP()) || (ip == destIP())); + return (isIP() && ((ip == sourceIP()) || (ip == destIP()))); } NetdumpIP destIP() const @@ -301,15 +291,15 @@ class Packet }; uint16_t getSrcPort() const { - return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 0); + return isIP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 0) : 0; } uint16_t getDstPort() const { - return ntoh16(ETH_HDR_LEN + getIpHdrLen() + 2); + return isIP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 2) : 0; } bool hasPort(uint16_t p) const { - return ((getSrcPort() == p) || (getDstPort() == p)); + return (isIP() && ((getSrcPort() == p) || (getDstPort() == p))); } String toString(PacketDetail netdumpDetail = PacketDetail::NONE) const; @@ -319,7 +309,7 @@ class Packet unsigned long packetTime; int netif_idx; const char* data; - size_t len; + size_t packetLength; int out; int success; }; From de46b48d57ef8ff35f098539c50d43e81d092543 Mon Sep 17 00:00:00 2001 From: hreintke Date: Mon, 18 Nov 2019 14:46:59 +0100 Subject: [PATCH 10/22] Updates related to remarks --- libraries/Netdump/src/Netdump.cpp | 30 ++++++++++++++++++++------- libraries/Netdump/src/Netdump.h | 17 +++++---------- libraries/Netdump/src/NetdumpPacket.h | 2 +- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index 7f5d3355d1..9a431a4da9 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -28,6 +28,22 @@ namespace NetCapture Netdump* Netdump::self; +Netdump::Netdump() +{ + phy_capture = capture; + self = this; +}; + +Netdump::~Netdump() +{ + reset(); + phy_capture = nullptr; + if (packetBuffer) + { + delete[] packetBuffer; + } +}; + void Netdump::setCallback(const Callback nc) { netDumpCallback = nc; @@ -69,11 +85,11 @@ void Netdump::fileDump(File& outfile, const Filter nf) } void Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf) { - if (packetBuffer) + + if (!packetBuffer) { - delete packetBuffer; + packetBuffer = new char[tcpBuffersize]; } - packetBuffer = new char[tcpBuffersize]; bufferIndex = 0; schedule_function([&tcpDumpServer, this, nf]() @@ -95,7 +111,7 @@ void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int } } -void Netdump::writePcapHeader(Stream& s) +void Netdump::writePcapHeader(Stream& s) const { uint32_t pcapHeader[6]; pcapHeader[0] = 0xa1b2c3d4; // pcap magic number @@ -107,12 +123,12 @@ void Netdump::writePcapHeader(Stream& s) s.write(reinterpret_cast(pcapHeader), 24); } -void Netdump::printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) +void Netdump::printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) const { - out.printf("%8d %s", np.getTime(), np.toString(ndd).c_str()); + out.printf_P(PSTR("%8d %s"), np.getTime(), np.toString(ndd).c_str()); } -void Netdump::fileDumpProcess(File& outfile, const Packet& np) +void Netdump::fileDumpProcess(File& outfile, const Packet& np) const { size_t incl_len = np.getPacketSize() > maxPcapLength ? maxPcapLength : np.getPacketSize(); uint32_t pcapHeader[4]; diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h index f6bced5838..fa7c36d07d 100644 --- a/libraries/Netdump/src/Netdump.h +++ b/libraries/Netdump/src/Netdump.h @@ -39,15 +39,8 @@ class Netdump using Filter = std::function; using Callback = std::function; - Netdump() - { - phy_capture = capture; - self = this; - }; - ~Netdump() - { - phy_capture = nullptr; - }; + Netdump(); + ~Netdump(); void setCallback(const Callback nc); void setCallback(const Callback nc, const Filter nf); @@ -66,12 +59,12 @@ class Netdump static Netdump* self; static void capture(int netif_idx, const char* data, size_t len, int out, int success); - void printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np); - void fileDumpProcess(File& outfile, const Packet& np); + void printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) const; + void fileDumpProcess(File& outfile, const Packet& np) const; void tcpDumpProcess(const Packet& np); void tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf); - void writePcapHeader(Stream& s); + void writePcapHeader(Stream& s) const; WiFiClient tcpDumpClient; char* packetBuffer = nullptr; diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index ef8542712c..dc430f3d21 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -39,7 +39,7 @@ class Packet : packetTime(msec), netif_idx(n), data(d), packetLength(l), out(o), success(s) {}; - ~Packet() {}; + Packet() {}; enum class PacketDetail { From f05a6f34ec7d0ae9e81ce9411ebc511fa5b11f48 Mon Sep 17 00:00:00 2001 From: hreintke Date: Sun, 24 Nov 2019 13:37:42 +0100 Subject: [PATCH 11/22] Restructure PacketType --- libraries/Netdump/src/NetdumpPacket.cpp | 65 ++++++++++++++++--------- libraries/Netdump/src/NetdumpPacket.h | 53 +++++++------------- libraries/Netdump/src/PacketType.cpp | 45 +++++++++++++++++ libraries/Netdump/src/PacketType.h | 55 +++++++++++++++++++++ 4 files changed, 160 insertions(+), 58 deletions(-) create mode 100644 libraries/Netdump/src/PacketType.cpp create mode 100644 libraries/Netdump/src/PacketType.h diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index 708187e8fb..02d5bb39ec 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -25,8 +25,6 @@ namespace NetCapture { -constexpr char* Packet::packetTypeArray[]; - void Packet::printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const { if (pd == PacketDetail::NONE) @@ -34,7 +32,7 @@ void Packet::printDetail(Print& out, const String& indent, const char* data, siz return; } - uint16_t charCount = pd == PacketDetail::FULL ? 24 : 80; + uint16_t charCount = (pd == PacketDetail::FULL) ? 24 : 80; size_t start = 0; while (start < size) @@ -66,43 +64,64 @@ void Packet::printDetail(Print& out, const String& indent, const char* data, siz } } -Packet::PacketType Packet::packetType() const +void Packet::setPacketType(PacketType pt) +{ + thisPacketType = pt; + thisAllPacketTypes.emplace_back(pt); +} + +void Packet::setPacketTypes() { - if (isARP()) return PacketType::ARP; + if (isARP()) + { + setPacketType(PacketType::ARP); + } else if (isIP()) { + setPacketType(PacketType::IP); if (isUDP()) { - if (isMDNS()) return PacketType::MDNS; - if (isDNS()) return PacketType::DNS; - if (isSSDP()) return PacketType::SSDP; - if (isDHCP()) return PacketType::DHCP; - if (isWSDD()) return PacketType::WSDD; - if (isNETBIOS()) return PacketType::NETBIOS; - if (isSMB()) return PacketType::SMB; - if (isOTA()) return PacketType::OTA; - return PacketType::UDP; + setPacketType(PacketType::UDP); + if (isMDNS()) setPacketType(PacketType::MDNS); + if (isDNS()) setPacketType(PacketType::DNS); + if (isSSDP()) setPacketType(PacketType::SSDP); + if (isDHCP()) setPacketType(PacketType::DHCP); + if (isWSDD()) setPacketType(PacketType::WSDD); + if (isNETBIOS()) setPacketType(PacketType::NETBIOS); + if (isSMB()) setPacketType(PacketType::SMB); + if (isOTA()) setPacketType(PacketType::OTA); } if (isTCP()) { - if (isHTTP()) return PacketType::HTTP; - return PacketType::TCP; + setPacketType(PacketType::TCP); + if (isHTTP()) setPacketType(PacketType::HTTP); } - if (isICMP()) return PacketType::ICMP; - if (isIGMP()) return PacketType::IGMP; - return PacketType::IP; + if (isICMP()) setPacketType(PacketType::ICMP); + if (isIGMP()) setPacketType(PacketType::IGMP); + } else + { + setPacketType(PacketType::UKNW); } - return PacketType::UKNW; } -String Packet::toString(PacketDetail netdumpDetail) const +const PacketType Packet::packetType() const +{ + return thisPacketType; +} + +const std::vector Packet::allPacketTypes() const +{ + return thisAllPacketTypes; +} + +const String Packet::toString(PacketDetail netdumpDetail) const { StreamString sstr; sstr.reserve(128); - sstr.printf_P(PSTR("%d %3s %s "), netif_idx, out ? "out" : "in ", packetTypeString(packetType())); + sstr.printf_P(PSTR("%d %3s %-4s "), netif_idx, out ? "out" : "in ", packetType().toString().c_str()); - switch (packetType()) + switch (thisPacketType) { case PacketType::ARP : { diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index dc430f3d21..ae65e37c49 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -26,6 +26,8 @@ #include #include #include "NetdumpIP.h" +#include "PacketType.h" +#include namespace NetCapture { @@ -37,7 +39,9 @@ class Packet public: Packet(unsigned long msec, int n, const char* d, size_t l, int o, int s) : packetTime(msec), netif_idx(n), data(d), packetLength(l), out(o), success(s) - {}; + { + setPacketTypes(); + }; Packet() {}; @@ -48,37 +52,7 @@ class Packet CHARS }; - enum class PacketType - { - ARP, - IP, - UDP, - MDNS, - DNS, - SSDP, - DHCP, - WSDD, - NETBIOS, - SMB, - OTA, - TCP, - HTTP, - ICMP, - IGMP, - UKNW, - }; - - static constexpr char* packetTypeArray[] = {"ARP ","IP ","UDP ","MDNS","DNS ", - "SSDP","DHCP","WSDD","NBIO", "SMB ","OTA ","TCP ", - "HTTP","ICMP","IGMP","UKNW"}; - - const char* packetTypeString (PacketType pt) const - { - return packetTypeArray[static_cast(pt)]; - } - PacketType packetType() const; - - const char* rawData() const + const char* rawData() const { return data; } @@ -250,12 +224,12 @@ class Packet } NetdumpIP getIP(uint16_t idx) const { - return isIPv4() ? NetdumpIP(data[idx], data[idx + 1], data[idx + 2], data[idx + 3]) : NetdumpIP(); + return NetdumpIP(data[idx], data[idx + 1], data[idx + 2], data[idx + 3]); }; NetdumpIP getIP6(uint16_t idx) const { - return isIPv6() ? NetdumpIP((const uint8_t*)&data[idx], false) : NetdumpIP(); + return NetdumpIP((const uint8_t*)&data[idx], false); }; NetdumpIP sourceIP() const { @@ -302,16 +276,25 @@ class Packet return (isIP() && ((getSrcPort() == p) || (getDstPort() == p))); } - String toString(PacketDetail netdumpDetail = PacketDetail::NONE) const; + const String toString(PacketDetail netdumpDetail = PacketDetail::NONE) const; void printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const; + const PacketType packetType() const; + const std::vector allPacketTypes() const; + + private: + + void setPacketType(PacketType); + void setPacketTypes(); unsigned long packetTime; int netif_idx; const char* data; size_t packetLength; int out; int success; + PacketType thisPacketType; + std::vector thisAllPacketTypes; }; } // namespace NetCapture diff --git a/libraries/Netdump/src/PacketType.cpp b/libraries/Netdump/src/PacketType.cpp new file mode 100644 index 0000000000..9dc9e2034e --- /dev/null +++ b/libraries/Netdump/src/PacketType.cpp @@ -0,0 +1,45 @@ +/* + * PacketType.cpp + * + * Created on: 19 nov. 2019 + * Author: Herman + */ + +#include + +namespace NetCapture +{ + +PacketType::PacketType() +{ +} + +PacketType::~PacketType() +{ +} + +String PacketType::toString() const +{ + switch (ptype) + { + case PType::ARP : return PSTR("ARP"); + case PType::IP : return PSTR("IP"); + case PType::UDP : return PSTR("UDP"); + case PType::MDNS : return PSTR("MDNS"); + case PType::DNS : return PSTR("DNS"); + case PType::SSDP : return PSTR("SSDP"); + case PType::DHCP : return PSTR("DHCP"); + case PType::WSDD : return PSTR("WSDD"); + case PType::NETBIOS: return PSTR("NBIO"); + case PType::SMB : return PSTR("SMB"); + case PType::OTA : return PSTR("OTA"); + case PType::TCP : return PSTR("TCP"); + case PType::HTTP : return PSTR("HTTP"); + case PType::ICMP : return PSTR("ICMP"); + case PType::IGMP : return PSTR("IGMP"); + case PType::UKNW : return PSTR("UKNW"); + default : return PSTR("ERR"); + }; +} + +} /* namespace NetCapture */ diff --git a/libraries/Netdump/src/PacketType.h b/libraries/Netdump/src/PacketType.h new file mode 100644 index 0000000000..8a0e029b51 --- /dev/null +++ b/libraries/Netdump/src/PacketType.h @@ -0,0 +1,55 @@ +/* + * PacketType.h + * + * Created on: 19 nov. 2019 + * Author: Herman + */ + +#ifndef LIBRARIES_NETDUMP_SRC_PACKETTYPE_H_ +#define LIBRARIES_NETDUMP_SRC_PACKETTYPE_H_ +#include "Arduino.h" + +namespace NetCapture +{ + +class PacketType +{ +public: + + enum PType : int + { + ARP, + IP, + UDP, + MDNS, + DNS, + SSDP, + DHCP, + WSDD, + NETBIOS, + SMB, + OTA, + TCP, + HTTP, + ICMP, + IGMP, + UKNW, + }; + + PacketType(); + PacketType(PType pt) : ptype(pt) {}; + + ~PacketType(); + + operator PType() const { return ptype; }; + bool operator==(const PacketType& p) {return ptype == p.ptype;}; + + String toString() const; + +private: + PType ptype; +}; + +} /* namespace NetCapture */ + +#endif /* LIBRARIES_NETDUMP_SRC_PACKETTYPE_H_ */ From 328f240d7c7699f24515eaf618a6aca08e66ba8b Mon Sep 17 00:00:00 2001 From: hreintke Date: Sun, 24 Nov 2019 16:04:35 +0100 Subject: [PATCH 12/22] Restructure printing, add PacketDetail::RAW --- libraries/Netdump/src/Netdump.cpp | 1 - libraries/Netdump/src/NetdumpPacket.cpp | 313 ++++++++++++++---------- libraries/Netdump/src/NetdumpPacket.h | 15 +- libraries/Netdump/src/PacketType.cpp | 2 + libraries/Netdump/src/PacketType.h | 2 + 5 files changed, 199 insertions(+), 134 deletions(-) diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index 9a431a4da9..34cfcc2728 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -195,7 +195,6 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf) } if (bufferIndex && tcpDumpClient && tcpDumpClient.availableForWrite() >= bufferIndex) { - Serial.printf("tcp write %d\r\n", bufferIndex); tcpDumpClient.write(packetBuffer, bufferIndex); bufferIndex = 0; } diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index 02d5bb39ec..86d130f488 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -32,7 +32,7 @@ void Packet::printDetail(Print& out, const String& indent, const char* data, siz return; } - uint16_t charCount = (pd == PacketDetail::FULL) ? 24 : 80; + uint16_t charCount = (pd == PacketDetail::CHAR) ? 80 : 24; size_t start = 0; while (start < size) @@ -43,7 +43,7 @@ void Packet::printDetail(Print& out, const String& indent, const char* data, siz end = size; } out.printf("%s", indent.c_str()); - if (pd == PacketDetail::FULL) + if (pd != PacketDetail::CHAR) { for (size_t i = start; i < end; i++) { @@ -79,6 +79,7 @@ void Packet::setPacketTypes() if (isIP()) { setPacketType(PacketType::IP); + setPacketType(isIPv4() ? PacketType::IPv4 : PacketType::IPv6); if (isUDP()) { setPacketType(PacketType::UDP); @@ -114,160 +115,210 @@ const std::vector Packet::allPacketTypes() const return thisAllPacketTypes; } -const String Packet::toString(PacketDetail netdumpDetail) const +const String Packet::ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { - StreamString sstr; - sstr.reserve(128); - - sstr.printf_P(PSTR("%d %3s %-4s "), netif_idx, out ? "out" : "in ", packetType().toString().c_str()); + switch (getARPType()) + { + case 1 : sstr.printf_P(PSTR("who has %s tell %s"), getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); + break; + case 2 : sstr.printf_P(PSTR("%s is at "), getIP(ETH_HDR_LEN + 14).toString().c_str()); + for (int i = 0; i < 6; i++) + { + sstr.printf_P(PSTR("%02x"), (unsigned char)data[ETH_HDR_LEN + 8 + i]); + if (i < 5) + { + sstr.print(':'); + } + } + break; + } + sstr.printf("\r\n"); + return sstr; +} - switch (thisPacketType) - { - case PacketType::ARP : +const String Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("ID=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8)); + sstr.printf_P(PSTR("F=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 2)); + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 4)) { - switch (getARPType()) - { - case 1 : sstr.printf_P(PSTR("who has %s tell %s"), getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); - break; - case 2 : sstr.printf_P(PSTR("%s is at "), getIP(ETH_HDR_LEN + 14).toString().c_str()); - for (int i = 0; i < 6; i++) - { - sstr.printf_P(PSTR("%02x"), (unsigned char)data[ETH_HDR_LEN + 8 + i]); - if (i < 5) - { - sstr.print(':'); - } - } - break; - } - sstr.printf("\r\n"); - return sstr; + sstr.printf_P(PSTR("Q=%d "), t); } - case PacketType::MDNS : - case PacketType::DNS : + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 6)) { - sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); - sstr.printf_P(PSTR("ID=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8)); - sstr.printf_P(PSTR("F=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 2)); - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 4)) - { - sstr.printf_P(PSTR("Q=%d "), t); - } - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 6)) - { - sstr.printf_P(PSTR("R=%d "), t); - } - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 8)) - { - sstr.printf_P(PSTR("TR=%d "), t); - } - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 10)) - { - sstr.printf_P(PSTR("DR=%d "), t); - } - sstr.printf_P(PSTR("\r\n")); - printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); - printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); - return sstr; + sstr.printf_P(PSTR("R=%d "), t); } - case PacketType::SSDP : - case PacketType::DHCP : - case PacketType::WSDD : - case PacketType::NETBIOS : - case PacketType::SMB : - case PacketType::OTA : - case PacketType::UDP : + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 8)) { - sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); - sstr.printf_P(PSTR("%d:%d"), getSrcPort(), getDstPort()); - sstr.printf_P(PSTR("\r\n")); - printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); - printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); - return sstr; + sstr.printf_P(PSTR("TR=%d "), t); } - case PacketType::TCP : - case PacketType::HTTP : + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 10)) { - sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); - sstr.printf_P(PSTR("%d:%d "), getSrcPort(), getDstPort()); - uint16_t flags = getTcpFlags(); - sstr.print('['); - const char chars [] = "FSRPAUECN"; - for (uint8_t i = 0; i < sizeof chars; i++) - if (flags & (1 << i)) - { - sstr.print(chars[i]); - } - sstr.print(']'); - sstr.printf_P(PSTR(" len: %u seq: %u, ack: %u, wnd: %u "), getTcpLen(), getTcpSeq(), getTcpAck(), getTcpWindow()); - sstr.printf_P(PSTR("\r\n")); - printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail); - printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); - return sstr; + sstr.printf_P(PSTR("DR=%d "), t); } - case PacketType::ICMP : - { - sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); - if (isIPv4()) + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); + return sstr; +} + +const String Packet::UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("%d:%d"), getSrcPort(), getDstPort()); + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); + return sstr; +} + +const String Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("%d:%d "), getSrcPort(), getDstPort()); + uint16_t flags = getTcpFlags(); + sstr.print('['); + const char chars [] = "FSRPAUECN"; + for (uint8_t i = 0; i < sizeof chars; i++) + if (flags & (1 << i)) { - switch (getIcmpType()) - { - case 0 : sstr.printf_P(PSTR("ping reply")); break; - case 8 : sstr.printf_P(PSTR("ping request")); break; - default: sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType()); break; - } + sstr.print(chars[i]); } - if (isIPv6()) + sstr.print(']'); + sstr.printf_P(PSTR(" len: %u seq: %u, ack: %u, wnd: %u "), getTcpLen(), getTcpSeq(), getTcpAck(), getTcpWindow()); + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); + return sstr; +} + +const String Packet::ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + if (isIPv4()) + { + switch (getIcmpType()) { - switch (getIcmpType()) - { - case 129 : sstr.printf_P(PSTR("ping reply")); break; - case 128 : sstr.printf_P(PSTR("ping request")); break; - case 135 : sstr.printf_P(PSTR("Neighbour solicitation")); break; - case 136 : sstr.printf_P(PSTR("Neighbour advertisement")); break; - default: sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType()); break; - } + case 0 : sstr.printf_P(PSTR("ping reply")); break; + case 8 : sstr.printf_P(PSTR("ping request")); break; + default: sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType()); break; } - sstr.printf("\r\n"); - return sstr; } - case PacketType::IGMP : + if (isIPv6()) { - switch (getIgmpType()) + switch (getIcmpType()) { - case 1 : sstr.printf_P(PSTR("Create Group Request")); break; - case 2 : sstr.printf_P(PSTR("Create Group Reply")); break; - case 3 : sstr.printf_P(PSTR("Join Group Request")); break; - case 4 : sstr.printf_P(PSTR("Join Group Reply")); break; - case 5 : sstr.printf_P(PSTR("Leave Group Request")); break; - case 6 : sstr.printf_P(PSTR("Leave Group Reply")); break; - case 7 : sstr.printf_P(PSTR("Confirm Group Request")); break; - case 8 : sstr.printf_P(PSTR("Confirm Group Reply")); break; - case 0x11 : sstr.printf_P(PSTR("Group Membership Query")); break; - case 0x12 : sstr.printf_P(PSTR("IGMPv1 Membership Report")); break; - case 0x22 : sstr.printf_P(PSTR("IGMPv3 Membership Report")); break; - default: sstr.printf_P(PSTR("type(0x%02x)"), getIgmpType()); break; + case 129 : sstr.printf_P(PSTR("ping reply")); break; + case 128 : sstr.printf_P(PSTR("ping request")); break; + case 135 : sstr.printf_P(PSTR("Neighbour solicitation")); break; + case 136 : sstr.printf_P(PSTR("Neighbour advertisement")); break; + default: sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType()); break; } - sstr.printf_P(PSTR("\r\n")); - return sstr; - } - case PacketType::IP : - { - sstr.printf_P(PSTR("Unknown IP type : %d\r\n"), ipType()); - return sstr; } - case PacketType::UKNW : + sstr.printf("\r\n"); + return sstr; +} + +const String Packet::IGMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + switch (getIgmpType()) { - sstr.printf_P(("Unknown packet, type = 0x%04x\r\n"), ethType()); - return sstr; + case 1 : sstr.printf_P(PSTR("Create Group Request")); break; + case 2 : sstr.printf_P(PSTR("Create Group Reply")); break; + case 3 : sstr.printf_P(PSTR("Join Group Request")); break; + case 4 : sstr.printf_P(PSTR("Join Group Reply")); break; + case 5 : sstr.printf_P(PSTR("Leave Group Request")); break; + case 6 : sstr.printf_P(PSTR("Leave Group Reply")); break; + case 7 : sstr.printf_P(PSTR("Confirm Group Request")); break; + case 8 : sstr.printf_P(PSTR("Confirm Group Reply")); break; + case 0x11 : sstr.printf_P(PSTR("Group Membership Query")); break; + case 0x12 : sstr.printf_P(PSTR("IGMPv1 Membership Report")); break; + case 0x22 : sstr.printf_P(PSTR("IGMPv3 Membership Report")); break; + default: sstr.printf_P(PSTR("type(0x%02x)"), getIgmpType()); break; } - default : + sstr.printf_P(PSTR("\r\n")); + return sstr; +} + +const String Packet::IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("Unknown IP type : %d\r\n"), ipType()); + printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN], getIpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen()], getIpTotalLen() - getIpHdrLen() , netdumpDetail); + return sstr; +} + +const String Packet::toString(PacketDetail netdumpDetail) const +{ + StreamString sstr; + sstr.reserve(128); + + sstr.printf_P(PSTR("%d %3s %-4s "), netif_idx, out ? "out" : "in ", packetType().toString().c_str()); + + if (netdumpDetail == PacketDetail::RAW) { - sstr.printf_P(PSTR("Non identified packet\r\n")); + sstr.printf_P(PSTR(" : ")); + for (auto at : thisAllPacketTypes) + { + sstr.printf_P(PSTR("%s "),at.toString().c_str()); + } + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" D "), data, packetLength, netdumpDetail); return sstr; } - } + switch (thisPacketType) + { + case PacketType::ARP : + { + return ARPtoString(netdumpDetail,sstr); + } + case PacketType::MDNS : + case PacketType::DNS : + { + return DNStoString(netdumpDetail, sstr); + } + case PacketType::SSDP : + case PacketType::DHCP : + case PacketType::WSDD : + case PacketType::NETBIOS : + case PacketType::SMB : + case PacketType::OTA : + case PacketType::UDP : + { + return UDPtoString(netdumpDetail, sstr); + } + case PacketType::TCP : + case PacketType::HTTP : + { + return TCPtoString(netdumpDetail, sstr); + } + case PacketType::ICMP : + { + return ICMPtoString(netdumpDetail, sstr); + } + case PacketType::IGMP : + { + return IGMPtoString(netdumpDetail, sstr); + } + case PacketType::IPv4 : + case PacketType::IPv6 : + { + return IPtoString(netdumpDetail, sstr); + } + case PacketType::UKNW : + { + sstr.printf_P(("Unknown packet, type = 0x%04x\r\n"), ethType()); + return sstr; + } + default : + { + sstr.printf_P(PSTR("Non identified packet\r\n")); + return sstr; + } + } } } // namespace NetCapture diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index ae65e37c49..d7c3df9ab1 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -49,7 +49,8 @@ class Packet { NONE, FULL, - CHARS + CHAR, + RAW }; const char* rawData() const @@ -98,7 +99,7 @@ class Packet } uint16_t getIpTotalLen() const { - return isIP() ? ntoh16(ETH_HDR_LEN + 2) : 0; + return isIP() ? isIPv4() ? ntoh16(ETH_HDR_LEN + 2) : (packetLength - ETH_HDR_LEN) : 0; } uint32_t getTcpSeq() const { @@ -287,6 +288,16 @@ class Packet void setPacketType(PacketType); void setPacketTypes(); + + const String ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + const String DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const; + const String UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + const String TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + const String ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + const String IGMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + const String IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + + unsigned long packetTime; int netif_idx; const char* data; diff --git a/libraries/Netdump/src/PacketType.cpp b/libraries/Netdump/src/PacketType.cpp index 9dc9e2034e..45ae8f92cc 100644 --- a/libraries/Netdump/src/PacketType.cpp +++ b/libraries/Netdump/src/PacketType.cpp @@ -37,6 +37,8 @@ String PacketType::toString() const case PType::HTTP : return PSTR("HTTP"); case PType::ICMP : return PSTR("ICMP"); case PType::IGMP : return PSTR("IGMP"); + case PType::IPv4: return PSTR("IPv4"); + case PType::IPv6: return PSTR("IPv6"); case PType::UKNW : return PSTR("UKNW"); default : return PSTR("ERR"); }; diff --git a/libraries/Netdump/src/PacketType.h b/libraries/Netdump/src/PacketType.h index 8a0e029b51..cc4bf61791 100644 --- a/libraries/Netdump/src/PacketType.h +++ b/libraries/Netdump/src/PacketType.h @@ -33,6 +33,8 @@ class PacketType HTTP, ICMP, IGMP, + IPv4, + IPv6, UKNW, }; From a5b3ad7812c87f0393755ae5b4064a38006f2906 Mon Sep 17 00:00:00 2001 From: hreintke Date: Mon, 25 Nov 2019 15:39:46 +0100 Subject: [PATCH 13/22] Fix printing --- libraries/Netdump/src/NetdumpPacket.cpp | 83 +++++++++++++++---------- libraries/Netdump/src/NetdumpPacket.h | 20 +++--- 2 files changed, 62 insertions(+), 41 deletions(-) diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index 86d130f488..81406f0f85 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -115,28 +115,34 @@ const std::vector Packet::allPacketTypes() const return thisAllPacketTypes; } -const String Packet::ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +void Packet::MACtoString(int dataIdx, StreamString& sstr) const +{ + for (int i = 0; i < 6; i++) + { + sstr.printf_P(PSTR("%02x"), (unsigned char)data[dataIdx + i]); + if (i < 5) + { + sstr.print(':'); + } + } + +} + +void Packet::ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { switch (getARPType()) { case 1 : sstr.printf_P(PSTR("who has %s tell %s"), getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); break; case 2 : sstr.printf_P(PSTR("%s is at "), getIP(ETH_HDR_LEN + 14).toString().c_str()); - for (int i = 0; i < 6; i++) - { - sstr.printf_P(PSTR("%02x"), (unsigned char)data[ETH_HDR_LEN + 8 + i]); - if (i < 5) - { - sstr.print(':'); - } - } + MACtoString(ETH_HDR_LEN + 8, sstr); break; } sstr.printf("\r\n"); - return sstr; + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN], packetLength - ETH_HDR_LEN, netdumpDetail); } -const String Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const +void Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const { sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); sstr.printf_P(PSTR("ID=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8)); @@ -160,20 +166,18 @@ const String Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) sstr.printf_P(PSTR("\r\n")); printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); - return sstr; } -const String Packet::UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +void Packet::UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); sstr.printf_P(PSTR("%d:%d"), getSrcPort(), getDstPort()); sstr.printf_P(PSTR("\r\n")); printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); - return sstr; } -const String Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +void Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); sstr.printf_P(PSTR("%d:%d "), getSrcPort(), getDstPort()); @@ -190,10 +194,9 @@ const String Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) sstr.printf_P(PSTR("\r\n")); printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail); printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); - return sstr; } -const String Packet::ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +void Packet::ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); if (isIPv4()) @@ -217,10 +220,9 @@ const String Packet::ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr } } sstr.printf("\r\n"); - return sstr; } -const String Packet::IGMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +void Packet::IGMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { switch (getIgmpType()) { @@ -238,18 +240,27 @@ const String Packet::IGMPtoString(PacketDetail netdumpDetail, StreamString& sstr default: sstr.printf_P(PSTR("type(0x%02x)"), getIgmpType()); break; } sstr.printf_P(PSTR("\r\n")); - return sstr; } -const String Packet::IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +void Packet::IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); sstr.printf_P(PSTR("Unknown IP type : %d\r\n"), ipType()); printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN], getIpHdrLen(), netdumpDetail); printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen()], getIpTotalLen() - getIpHdrLen() , netdumpDetail); - return sstr; } +void Packet::UKNWtoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("Unknown EtherType 0x%04x Src : "), ethType()); + MACtoString(0,sstr); + sstr.printf_P(PSTR(" Dst : ")); + MACtoString(6,sstr); + sstr.printf_P(PSTR("\r\n")); +} + + + const String Packet::toString(PacketDetail netdumpDetail) const { StreamString sstr; @@ -273,12 +284,14 @@ const String Packet::toString(PacketDetail netdumpDetail) const { case PacketType::ARP : { - return ARPtoString(netdumpDetail,sstr); + ARPtoString(netdumpDetail,sstr); + break; } case PacketType::MDNS : case PacketType::DNS : { - return DNStoString(netdumpDetail, sstr); + DNStoString(netdumpDetail, sstr); + break; } case PacketType::SSDP : case PacketType::DHCP : @@ -288,37 +301,43 @@ const String Packet::toString(PacketDetail netdumpDetail) const case PacketType::OTA : case PacketType::UDP : { - return UDPtoString(netdumpDetail, sstr); + UDPtoString(netdumpDetail, sstr); + break; } case PacketType::TCP : case PacketType::HTTP : { - return TCPtoString(netdumpDetail, sstr); + TCPtoString(netdumpDetail, sstr); + break; } case PacketType::ICMP : { - return ICMPtoString(netdumpDetail, sstr); + ICMPtoString(netdumpDetail, sstr); + break; } case PacketType::IGMP : { - return IGMPtoString(netdumpDetail, sstr); + IGMPtoString(netdumpDetail, sstr); + break; } case PacketType::IPv4 : case PacketType::IPv6 : { - return IPtoString(netdumpDetail, sstr); + IPtoString(netdumpDetail, sstr); + break; } case PacketType::UKNW : { - sstr.printf_P(("Unknown packet, type = 0x%04x\r\n"), ethType()); - return sstr; + UKNWtoString(netdumpDetail, sstr); + break; } default : { sstr.printf_P(PSTR("Non identified packet\r\n")); - return sstr; + break; } } + return sstr; } } // namespace NetCapture diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index d7c3df9ab1..4ea268ca61 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -61,7 +61,7 @@ class Packet { return out; } - unsigned long getTime() const + time_t getTime() const { return packetTime; } @@ -289,16 +289,18 @@ class Packet void setPacketType(PacketType); void setPacketTypes(); - const String ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; - const String DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const; - const String UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; - const String TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; - const String ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; - const String IGMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; - const String IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void MACtoString(int dataIdx, StreamString& sstr) const; + void ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void IGMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void UKNWtoString(PacketDetail netdumpDetail, StreamString& sstr) const; - unsigned long packetTime; + time_t packetTime; int netif_idx; const char* data; size_t packetLength; From 6f4fb0c67c5ffb2365ca2a5bc79c2bb981160867 Mon Sep 17 00:00:00 2001 From: hreintke Date: Tue, 26 Nov 2019 15:54:09 +0100 Subject: [PATCH 14/22] Use CallbackList to facilitate multiple Netdump instances --- libraries/Netdump/src/Netdump.cpp | 17 ++++++++++++----- libraries/Netdump/src/Netdump.h | 12 ++++++++++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index 34cfcc2728..b2dc8c43d4 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -23,15 +23,17 @@ #include #include "Schedule.h" + namespace NetCapture { -Netdump* Netdump::self; +CallBackList Netdump::lwipCallback; Netdump::Netdump() { + using namespace std::placeholders; phy_capture = capture; - self = this; + lwipHandler = lwipCallback.add(std::bind(&Netdump::netdumpCapture,this,_1,_2,_3,_4,_5)); }; Netdump::~Netdump() @@ -99,15 +101,20 @@ void Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf) } void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int success) +{ + lwipCallback.execute(netif_idx,data,len,out,success); +} + +void Netdump::netdumpCapture(int netif_idx, const char* data, size_t len, int out, int success) { Packet np(millis(), netif_idx, data, len, out, success); - if (self->netDumpCallback) + if (netDumpCallback) { - if (self->netDumpFilter && !self->netDumpFilter(np)) + if (netDumpFilter && !netDumpFilter(np)) { return; } - self->netDumpCallback(np); + netDumpCallback(np); } } diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h index fa7c36d07d..b3e071ee7c 100644 --- a/libraries/Netdump/src/Netdump.h +++ b/libraries/Netdump/src/Netdump.h @@ -28,16 +28,20 @@ #include #include "NetdumpPacket.h" #include +#include "CallBackList.h" namespace NetCapture { +using namespace experimental::CBListImplentation; + class Netdump { public: using Filter = std::function; using Callback = std::function; + using LwipCallback = std::function; Netdump(); ~Netdump(); @@ -56,9 +60,11 @@ class Netdump Callback netDumpCallback = nullptr; Filter netDumpFilter = nullptr; - static Netdump* self; - static void capture(int netif_idx, const char* data, size_t len, int out, int success); + static CallBackList lwipCallback; + + void netdumpCapture(int netif_idx, const char* data, size_t len, int out, int success); + void printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) const; void fileDumpProcess(File& outfile, const Packet& np) const; void tcpDumpProcess(const Packet& np); @@ -74,6 +80,8 @@ class Netdump static constexpr int maxPcapLength = 1024; static constexpr uint32_t pcapMagic = 0xa1b2c3d4; + CallBackList::CallBackHandler lwipHandler; + }; } // namespace NetCapture From 112c03941a615515ac6aaaa09d568aba8be61af3 Mon Sep 17 00:00:00 2001 From: hreintke Date: Thu, 5 Dec 2019 12:59:13 +0100 Subject: [PATCH 15/22] Separate commit to show update on experimental CallbackList --- cores/esp8266/CallBackList.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cores/esp8266/CallBackList.h b/cores/esp8266/CallBackList.h index 187c86c2ad..8d419cbb89 100644 --- a/cores/esp8266/CallBackList.h +++ b/cores/esp8266/CallBackList.h @@ -64,7 +64,7 @@ class CallBackList } template - void execute(Args... params) { + int execute(Args... params) { for(auto it = std::begin(callBackEventList); it != std::end(callBackEventList); ) { CallBackHandler &handler = *it; if (handler->allowRemove() && handler.unique()) { @@ -75,6 +75,7 @@ class CallBackList ++it; } } + return callBackEventList.size(); } }; From 4f099cb3d89677fd60290fc195a487d1277f2309 Mon Sep 17 00:00:00 2001 From: hreintke Date: Thu, 5 Dec 2019 12:59:54 +0100 Subject: [PATCH 16/22] Further cleanup --- .../Netdump/examples/Netdump/Netdump.ino | 77 +++++++++++++++---- libraries/Netdump/src/Netdump.cpp | 6 +- libraries/Netdump/src/Netdump.h | 4 +- libraries/Netdump/src/NetdumpPacket.cpp | 4 + libraries/Netdump/src/NetdumpPacket.h | 3 +- 5 files changed, 74 insertions(+), 20 deletions(-) diff --git a/libraries/Netdump/examples/Netdump/Netdump.ino b/libraries/Netdump/examples/Netdump/Netdump.ino index 3b312f3e04..e43e364fa8 100644 --- a/libraries/Netdump/examples/Netdump/Netdump.ino +++ b/libraries/Netdump/examples/Netdump/Netdump.ino @@ -2,10 +2,19 @@ #include "Netdump.h" #include -#include "LocalDefines.h" #include #include -#include "Schedule.h" +#include "map" + +using namespace NetCapture; + +#ifndef STASSID +#define STASSID "your-ssid" +#define STAPSK "your-password" +#endif + +const char* ssid = STASSID; +const char* password = STAPSK; Netdump nd; @@ -16,28 +25,43 @@ ESP8266WebServer webServer(80); // Used for sending commands WiFiServer tcpServer(8000); // Used to show netcat option. File tracefile; +std::map packetCount; + +enum SerialOption +{ + AllFull, + LocalNone, + HTTPChar + +}; + + void startSerial(int option) { switch (option) { - case 1 : //All Packets, show packet summary. - nd.printDump(Serial, NetdumpPacket::PacketDetail::NONE); + case AllFull : //All Packets, show packet summary. + nd.printDump(Serial, Packet::PacketDetail::FULL); break; - case 2 : // Only local IP traffic, full details - nd.printDump(Serial, NetdumpPacket::PacketDetail::FULL, - [](NetdumpPacket n) + case LocalNone : // Only local IP traffic, full details + nd.printDump(Serial, Packet::PacketDetail::NONE, + [](Packet n) { return (n.hasIP(WiFi.localIP())); } ); - case 3 : // Only HTTP traffic, show packet content as chars - nd.printDump(Serial, NetdumpPacket::PacketDetail::CHARS, - [](NetdumpPacket n) + break; + case HTTPChar : // Only HTTP traffic, show packet content as chars + nd.printDump(Serial, Packet::PacketDetail::CHAR, + [](Packet n) { return (n.isHTTP()); } ); + break; + default : + Serial.printf("No valid SerialOption provided\r\n"); }; } @@ -55,6 +79,11 @@ void startTcpDump() nd.tcpDump(tcpServer); } +void capturePacket(Packet np) +{ + +} + void setup(void) { Serial.begin(115200); @@ -97,10 +126,30 @@ void setup(void) { webServer.serveStatic("/", *filesystem, "/"); webServer.begin(); - startSerial(1); - // startTcpDump(); - // startTracefile(); - + startSerial(AllFull); // Serial output examples, use enum SerialOption for selection + +// startTcpDump(); // tcpdump option + // startTracefile(); // output to SPIFFS or LittleFS +/* + // use a self provide callback, this count network packets + nd.setCallback( + [](Packet p) + { + Serial.printf("PKT : "); + for ( auto pp : p.allPacketTypes()) + { + Serial.printf("%s ",pp.toString().c_str()); + packetCount[pp]++; + } + Serial.printf("\r\n CNT "); + for (auto pc : packetCount) + { + Serial.printf("%s %d ", pc.first.toString().c_str(),pc.second); + } + Serial.printf("\r\n"); + } + ); +*/ } void loop(void) { diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index b2dc8c43d4..ef72b184f5 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -39,7 +39,6 @@ Netdump::Netdump() Netdump::~Netdump() { reset(); - phy_capture = nullptr; if (packetBuffer) { delete[] packetBuffer; @@ -102,7 +101,10 @@ void Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf) void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int success) { - lwipCallback.execute(netif_idx,data,len,out,success); + if (lwipCallback.execute(netif_idx,data,len,out,success) == 0) + { + phy_capture = nullptr; // No active callback/netdump instances, will be set again by new object. + } } void Netdump::netdumpCapture(int netif_idx, const char* data, size_t len, int out, int success) diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h index b3e071ee7c..a1060a3fb5 100644 --- a/libraries/Netdump/src/Netdump.h +++ b/libraries/Netdump/src/Netdump.h @@ -62,6 +62,7 @@ class Netdump static void capture(int netif_idx, const char* data, size_t len, int out, int success); static CallBackList lwipCallback; + CallBackList::CallBackHandler lwipHandler; void netdumpCapture(int netif_idx, const char* data, size_t len, int out, int success); @@ -79,9 +80,6 @@ class Netdump static constexpr int tcpBuffersize = 2048; static constexpr int maxPcapLength = 1024; static constexpr uint32_t pcapMagic = 0xa1b2c3d4; - - CallBackList::CallBackHandler lwipHandler; - }; } // namespace NetCapture diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index 81406f0f85..171891a515 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -259,6 +259,10 @@ void Packet::UKNWtoString(PacketDetail netdumpDetail, StreamString& sstr) const sstr.printf_P(PSTR("\r\n")); } +const String Packet::toString() const +{ + return toString(PacketDetail::NONE); +} const String Packet::toString(PacketDetail netdumpDetail) const diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index 4ea268ca61..1a049dd517 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -277,7 +277,8 @@ class Packet return (isIP() && ((getSrcPort() == p) || (getDstPort() == p))); } - const String toString(PacketDetail netdumpDetail = PacketDetail::NONE) const; + const String toString() const; + const String toString(PacketDetail netdumpDetail) const; void printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const; const PacketType packetType() const; From 3d41d25a5eb01d945ba7ab04bb4e896e99f1ea53 Mon Sep 17 00:00:00 2001 From: hreintke Date: Sun, 3 May 2020 16:17:12 +0200 Subject: [PATCH 17/22] Style update and small changes --- .../Netdump/examples/Netdump/Netdump.ino | 201 ++++++------- libraries/Netdump/src/Netdump.cpp | 28 +- libraries/Netdump/src/Netdump.h | 4 +- libraries/Netdump/src/NetdumpPacket.cpp | 282 ++++++++++-------- libraries/Netdump/src/NetdumpPacket.h | 22 +- libraries/Netdump/src/PacketType.cpp | 54 ++-- libraries/Netdump/src/PacketType.h | 78 ++--- 7 files changed, 353 insertions(+), 316 deletions(-) diff --git a/libraries/Netdump/examples/Netdump/Netdump.ino b/libraries/Netdump/examples/Netdump/Netdump.ino index e43e364fa8..385438bf02 100644 --- a/libraries/Netdump/examples/Netdump/Netdump.ino +++ b/libraries/Netdump/examples/Netdump/Netdump.ino @@ -3,8 +3,9 @@ #include "Netdump.h" #include #include +#include #include -#include "map" +#include using namespace NetCapture; @@ -25,134 +26,130 @@ ESP8266WebServer webServer(80); // Used for sending commands WiFiServer tcpServer(8000); // Used to show netcat option. File tracefile; -std::map packetCount; - -enum SerialOption -{ - AllFull, - LocalNone, - HTTPChar +std::map packetCount; +enum SerialOption { + AllFull, + LocalNone, + HTTPChar }; - -void startSerial(int option) -{ - switch (option) - { - case AllFull : //All Packets, show packet summary. - nd.printDump(Serial, Packet::PacketDetail::FULL); - break; - - case LocalNone : // Only local IP traffic, full details - nd.printDump(Serial, Packet::PacketDetail::NONE, - [](Packet n) - { - return (n.hasIP(WiFi.localIP())); - } - ); - break; - case HTTPChar : // Only HTTP traffic, show packet content as chars - nd.printDump(Serial, Packet::PacketDetail::CHAR, - [](Packet n) - { - return (n.isHTTP()); - } - ); - break; - default : - Serial.printf("No valid SerialOption provided\r\n"); - }; +void startSerial(int option) { + switch (option) { + case AllFull : //All Packets, show packet summary. + nd.printDump(Serial, Packet::PacketDetail::FULL); + break; + + case LocalNone : // Only local IP traffic, full details + nd.printDump(Serial, Packet::PacketDetail::NONE, + [](Packet n) { + return (n.hasIP(WiFi.localIP())); + } + ); + break; + case HTTPChar : // Only HTTP traffic, show packet content as chars + nd.printDump(Serial, Packet::PacketDetail::CHAR, + [](Packet n) { + return (n.isHTTP()); + } + ); + break; + default : + Serial.printf("No valid SerialOption provided\r\n"); + }; } -void startTracefile() -{ - // To file all traffic, format pcap file - tracefile = filesystem->open("/tr.pcap", "w"); - nd.fileDump(tracefile); +void startTracefile() { + // To file all traffic, format pcap file + tracefile = filesystem->open("/tr.pcap", "w"); + nd.fileDump(tracefile); } -void startTcpDump() -{ - // To tcpserver, all traffic. - tcpServer.begin(); - nd.tcpDump(tcpServer); -} - -void capturePacket(Packet np) -{ - +void startTcpDump() { + // To tcpserver, all traffic. + tcpServer.begin(); + nd.tcpDump(tcpServer); } void setup(void) { Serial.begin(115200); WiFi.mode(WIFI_STA); - WiFi.begin(ssid,password); + WiFi.begin(ssid, password); + + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.println("WiFi Failed"); + while (1) { + delay(1000); + } + } + + if (!MDNS.begin("netdumphost")) { + Serial.println("Error setting up MDNS responder!"); + } + filesystem->begin(); webServer.on("/list", - []() - { - Dir dir = filesystem->openDir("/"); - String d = "

    File list

    "; - while (dir.next()) - { - d.concat("
  • " + dir.fileName() + "
  • "); - } - webServer.send(200, "text.html", d); - } - ); + []() { + Dir dir = filesystem->openDir("/"); + String d = "

    File list

    "; + while (dir.next()) { + d.concat("
  • " + dir.fileName() + "
  • "); + } + webServer.send(200, "text.html", d); + } + ); webServer.on("/req", - []() - { - static int rq = 0; - String a = "

    You are connected, Number of requests = " + String(rq++) + "

    "; - webServer.send(200, "text/html", a); - } - ); - - webServer.on("/reset" , - []() - { - nd.reset(); - tracefile.close(); - tcpServer.close(); - webServer.send(200, "text.html", "

    Netdump session reset

    "); - } - ); + []() { + static int rq = 0; + String a = "

    You are connected, Number of requests = " + String(rq++) + "

    "; + webServer.send(200, "text/html", a); + } + ); + + webServer.on("/reset", + []() { + nd.reset(); + tracefile.close(); + tcpServer.close(); + webServer.send(200, "text.html", "

    Netdump session reset

    "); + } + ); webServer.serveStatic("/", *filesystem, "/"); webServer.begin(); startSerial(AllFull); // Serial output examples, use enum SerialOption for selection -// startTcpDump(); // tcpdump option - // startTracefile(); // output to SPIFFS or LittleFS -/* + // startTcpDump(); // tcpdump option + // startTracefile(); // output to SPIFFS or LittleFS + // use a self provide callback, this count network packets - nd.setCallback( - [](Packet p) - { - Serial.printf("PKT : "); - for ( auto pp : p.allPacketTypes()) - { - Serial.printf("%s ",pp.toString().c_str()); - packetCount[pp]++; - } - Serial.printf("\r\n CNT "); - for (auto pc : packetCount) - { - Serial.printf("%s %d ", pc.first.toString().c_str(),pc.second); - } - Serial.printf("\r\n"); - } - ); -*/ + /* + nd.setCallback( + [](Packet p) + { + Serial.printf("PKT : %s : ",p.sourceIP().toString().c_str()); + for ( auto pp : p.allPacketTypes()) + { + Serial.printf("%s ",pp.toString().c_str()); + packetCount[pp]++; + } + Serial.printf("\r\n CNT "); + for (auto pc : packetCount) + { + Serial.printf("%s %d ", pc.first.toString().c_str(),pc.second); + } + Serial.printf("\r\n"); + } + ); + */ } void loop(void) { - webServer.handleClient(); + webServer.handleClient(); + MDNS.update(); } diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index ef72b184f5..3adb32a9d0 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -31,17 +31,17 @@ CallBackList Netdump::lwipCallback; Netdump::Netdump() { - using namespace std::placeholders; + using namespace std::placeholders; phy_capture = capture; - lwipHandler = lwipCallback.add(std::bind(&Netdump::netdumpCapture,this,_1,_2,_3,_4,_5)); + lwipHandler = lwipCallback.add(std::bind(&Netdump::netdumpCapture, this, _1, _2, _3, _4, _5)); }; Netdump::~Netdump() { - reset(); + reset(); if (packetBuffer) { - delete[] packetBuffer; + delete[] packetBuffer; } }; @@ -69,7 +69,7 @@ void Netdump::reset() void Netdump::printDump(Print& out, Packet::PacketDetail ndd, const Filter nf) { out.printf("netDump starting\r\n"); - setCallback([&out, ndd, this](Packet & ndp) + setCallback([&out, ndd, this](const Packet & ndp) { printDumpProcess(out, ndd, ndp); }, nf); @@ -79,7 +79,7 @@ void Netdump::fileDump(File& outfile, const Filter nf) { writePcapHeader(outfile); - setCallback([&outfile, this](Packet & ndp) + setCallback([&outfile, this](const Packet & ndp) { fileDumpProcess(outfile, ndp); }, nf); @@ -89,7 +89,7 @@ void Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf) if (!packetBuffer) { - packetBuffer = new char[tcpBuffersize]; + packetBuffer = new char[tcpBuffersize]; } bufferIndex = 0; @@ -101,17 +101,17 @@ void Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf) void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int success) { - if (lwipCallback.execute(netif_idx,data,len,out,success) == 0) - { - phy_capture = nullptr; // No active callback/netdump instances, will be set again by new object. - } + if (lwipCallback.execute(netif_idx, data, len, out, success) == 0) + { + phy_capture = nullptr; // No active callback/netdump instances, will be set again by new object. + } } void Netdump::netdumpCapture(int netif_idx, const char* data, size_t len, int out, int success) { - Packet np(millis(), netif_idx, data, len, out, success); if (netDumpCallback) { + Packet np(millis(), netif_idx, data, len, out, success); if (netDumpFilter && !netDumpFilter(np)) { return; @@ -162,7 +162,7 @@ void Netdump::tcpDumpProcess(const Packet& np) } size_t incl_len = np.getPacketSize() > maxPcapLength ? maxPcapLength : np.getPacketSize(); - if (bufferIndex+16+incl_len < tcpBuffersize) // only add if enough space available + if (bufferIndex + 16 + incl_len < tcpBuffersize) // only add if enough space available { struct timeval tv; gettimeofday(&tv, nullptr); @@ -193,7 +193,7 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf) bufferIndex = 0; writePcapHeader(tcpDumpClient); - setCallback([this](Packet & ndp) + setCallback([this](const Packet & ndp) { tcpDumpProcess(ndp); }, nf); diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h index a1060a3fb5..bf16e7dd30 100644 --- a/libraries/Netdump/src/Netdump.h +++ b/libraries/Netdump/src/Netdump.h @@ -39,8 +39,8 @@ class Netdump { public: - using Filter = std::function; - using Callback = std::function; + using Filter = std::function; + using Callback = std::function; using LwipCallback = std::function; Netdump(); diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index 171891a515..86782dd921 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -66,79 +66,113 @@ void Packet::printDetail(Print& out, const String& indent, const char* data, siz void Packet::setPacketType(PacketType pt) { - thisPacketType = pt; - thisAllPacketTypes.emplace_back(pt); + thisPacketType = pt; + thisAllPacketTypes.emplace_back(pt); } void Packet::setPacketTypes() { - if (isARP()) - { - setPacketType(PacketType::ARP); - } else - if (isIP()) - { - setPacketType(PacketType::IP); - setPacketType(isIPv4() ? PacketType::IPv4 : PacketType::IPv6); - if (isUDP()) - { - setPacketType(PacketType::UDP); - if (isMDNS()) setPacketType(PacketType::MDNS); - if (isDNS()) setPacketType(PacketType::DNS); - if (isSSDP()) setPacketType(PacketType::SSDP); - if (isDHCP()) setPacketType(PacketType::DHCP); - if (isWSDD()) setPacketType(PacketType::WSDD); - if (isNETBIOS()) setPacketType(PacketType::NETBIOS); - if (isSMB()) setPacketType(PacketType::SMB); - if (isOTA()) setPacketType(PacketType::OTA); - } - if (isTCP()) - { - setPacketType(PacketType::TCP); - if (isHTTP()) setPacketType(PacketType::HTTP); - } - if (isICMP()) setPacketType(PacketType::ICMP); - if (isIGMP()) setPacketType(PacketType::IGMP); - } else - { - setPacketType(PacketType::UKNW); - } + if (isARP()) + { + setPacketType(PacketType::ARP); + } + else if (isIP()) + { + setPacketType(PacketType::IP); + setPacketType(isIPv4() ? PacketType::IPv4 : PacketType::IPv6); + if (isUDP()) + { + setPacketType(PacketType::UDP); + if (isMDNS()) + { + setPacketType(PacketType::MDNS); + } + if (isDNS()) + { + setPacketType(PacketType::DNS); + } + if (isSSDP()) + { + setPacketType(PacketType::SSDP); + } + if (isDHCP()) + { + setPacketType(PacketType::DHCP); + } + if (isWSDD()) + { + setPacketType(PacketType::WSDD); + } + if (isNETBIOS()) + { + setPacketType(PacketType::NETBIOS); + } + if (isSMB()) + { + setPacketType(PacketType::SMB); + } + if (isOTA()) + { + setPacketType(PacketType::OTA); + } + } + if (isTCP()) + { + setPacketType(PacketType::TCP); + if (isHTTP()) + { + setPacketType(PacketType::HTTP); + } + } + if (isICMP()) + { + setPacketType(PacketType::ICMP); + } + if (isIGMP()) + { + setPacketType(PacketType::IGMP); + } + } + else + { + setPacketType(PacketType::UKNW); + } } const PacketType Packet::packetType() const { - return thisPacketType; + return thisPacketType; } const std::vector Packet::allPacketTypes() const { - return thisAllPacketTypes; + return thisAllPacketTypes; } void Packet::MACtoString(int dataIdx, StreamString& sstr) const { - for (int i = 0; i < 6; i++) - { - sstr.printf_P(PSTR("%02x"), (unsigned char)data[dataIdx + i]); - if (i < 5) - { - sstr.print(':'); - } - } + for (int i = 0; i < 6; i++) + { + sstr.printf_P(PSTR("%02x"), (unsigned char)data[dataIdx + i]); + if (i < 5) + { + sstr.print(':'); + } + } } void Packet::ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { - switch (getARPType()) - { - case 1 : sstr.printf_P(PSTR("who has %s tell %s"), getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); - break; - case 2 : sstr.printf_P(PSTR("%s is at "), getIP(ETH_HDR_LEN + 14).toString().c_str()); - MACtoString(ETH_HDR_LEN + 8, sstr); - break; - } - sstr.printf("\r\n"); + switch (getARPType()) + { + case 1 : sstr.printf_P(PSTR("who has %s tell %s"), getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); + break; + case 2 : sstr.printf_P(PSTR("%s is at "), getIP(ETH_HDR_LEN + 14).toString().c_str()); + MACtoString(ETH_HDR_LEN + 8, sstr); + break; + } + sstr.printf("\r\n"); printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN], packetLength - ETH_HDR_LEN, netdumpDetail); } @@ -224,7 +258,7 @@ void Packet::ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const void Packet::IGMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { - switch (getIgmpType()) + switch (getIgmpType()) { case 1 : sstr.printf_P(PSTR("Create Group Request")); break; case 2 : sstr.printf_P(PSTR("Create Group Reply")); break; @@ -244,24 +278,24 @@ void Packet::IGMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const void Packet::IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { - sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); - sstr.printf_P(PSTR("Unknown IP type : %d\r\n"), ipType()); + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("Unknown IP type : %d\r\n"), ipType()); printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN], getIpHdrLen(), netdumpDetail); - printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen()], getIpTotalLen() - getIpHdrLen() , netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen()], getIpTotalLen() - getIpHdrLen(), netdumpDetail); } void Packet::UKNWtoString(PacketDetail netdumpDetail, StreamString& sstr) const { - sstr.printf_P(PSTR("Unknown EtherType 0x%04x Src : "), ethType()); - MACtoString(0,sstr); - sstr.printf_P(PSTR(" Dst : ")); - MACtoString(6,sstr); - sstr.printf_P(PSTR("\r\n")); + sstr.printf_P(PSTR("Unknown EtherType 0x%04x Src : "), ethType()); + MACtoString(0, sstr); + sstr.printf_P(PSTR(" Dst : ")); + MACtoString(6, sstr); + sstr.printf_P(PSTR("\r\n")); } const String Packet::toString() const { - return toString(PacketDetail::NONE); + return toString(PacketDetail::NONE); } @@ -274,72 +308,72 @@ const String Packet::toString(PacketDetail netdumpDetail) const if (netdumpDetail == PacketDetail::RAW) { - sstr.printf_P(PSTR(" : ")); - for (auto at : thisAllPacketTypes) - { - sstr.printf_P(PSTR("%s "),at.toString().c_str()); - } - sstr.printf_P(PSTR("\r\n")); - printDetail(sstr, PSTR(" D "), data, packetLength, netdumpDetail); - return sstr; + sstr.printf_P(PSTR(" : ")); + for (auto at : thisAllPacketTypes) + { + sstr.printf_P(PSTR("%s "), at.toString().c_str()); + } + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" D "), data, packetLength, netdumpDetail); + return sstr; } switch (thisPacketType) { - case PacketType::ARP : - { - ARPtoString(netdumpDetail,sstr); - break; - } - case PacketType::MDNS : - case PacketType::DNS : - { - DNStoString(netdumpDetail, sstr); - break; - } - case PacketType::SSDP : - case PacketType::DHCP : - case PacketType::WSDD : - case PacketType::NETBIOS : - case PacketType::SMB : - case PacketType::OTA : - case PacketType::UDP : - { - UDPtoString(netdumpDetail, sstr); - break; - } - case PacketType::TCP : - case PacketType::HTTP : - { - TCPtoString(netdumpDetail, sstr); - break; - } - case PacketType::ICMP : - { - ICMPtoString(netdumpDetail, sstr); - break; - } - case PacketType::IGMP : - { - IGMPtoString(netdumpDetail, sstr); - break; - } - case PacketType::IPv4 : - case PacketType::IPv6 : - { - IPtoString(netdumpDetail, sstr); - break; - } - case PacketType::UKNW : - { - UKNWtoString(netdumpDetail, sstr); - break; - } - default : - { - sstr.printf_P(PSTR("Non identified packet\r\n")); - break; - } + case PacketType::ARP : + { + ARPtoString(netdumpDetail, sstr); + break; + } + case PacketType::MDNS : + case PacketType::DNS : + { + DNStoString(netdumpDetail, sstr); + break; + } + case PacketType::SSDP : + case PacketType::DHCP : + case PacketType::WSDD : + case PacketType::NETBIOS : + case PacketType::SMB : + case PacketType::OTA : + case PacketType::UDP : + { + UDPtoString(netdumpDetail, sstr); + break; + } + case PacketType::TCP : + case PacketType::HTTP : + { + TCPtoString(netdumpDetail, sstr); + break; + } + case PacketType::ICMP : + { + ICMPtoString(netdumpDetail, sstr); + break; + } + case PacketType::IGMP : + { + IGMPtoString(netdumpDetail, sstr); + break; + } + case PacketType::IPv4 : + case PacketType::IPv6 : + { + IPtoString(netdumpDetail, sstr); + break; + } + case PacketType::UKNW : + { + UKNWtoString(netdumpDetail, sstr); + break; + } + default : + { + sstr.printf_P(PSTR("Non identified packet\r\n")); + break; + } } return sstr; } diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index 1a049dd517..af0d701619 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -40,7 +40,7 @@ class Packet Packet(unsigned long msec, int n, const char* d, size_t l, int o, int s) : packetTime(msec), netif_idx(n), data(d), packetLength(l), out(o), success(s) { - setPacketTypes(); + setPacketTypes(); }; Packet() {}; @@ -50,24 +50,24 @@ class Packet NONE, FULL, CHAR, - RAW + RAW }; - const char* rawData() const + const char* rawData() const { - return data; + return data; } int getInOut() const { - return out; + return out; } time_t getTime() const { - return packetTime; + return packetTime; } uint32_t getPacketSize() const { - return packetLength; + return packetLength; } uint16_t ntoh16(uint16_t idx) const { @@ -99,7 +99,7 @@ class Packet } uint16_t getIpTotalLen() const { - return isIP() ? isIPv4() ? ntoh16(ETH_HDR_LEN + 2) : (packetLength - ETH_HDR_LEN) : 0; + return isIP() ? isIPv4() ? ntoh16(ETH_HDR_LEN + 2) : (packetLength - ETH_HDR_LEN) : 0; } uint32_t getTcpSeq() const { @@ -213,15 +213,15 @@ class Packet }; bool isOTA() const { - return (isUDP() && hasPort(8266)); + return (isUDP() && hasPort(8266)); } bool isNETBIOS() const { - return (isUDP() && (hasPort(137) || hasPort(138) || hasPort(139))); + return (isUDP() && (hasPort(137) || hasPort(138) || hasPort(139))); } bool isSMB() const { - return (isUDP() && hasPort(445)); + return (isUDP() && hasPort(445)); } NetdumpIP getIP(uint16_t idx) const { diff --git a/libraries/Netdump/src/PacketType.cpp b/libraries/Netdump/src/PacketType.cpp index 45ae8f92cc..1bebea68ec 100644 --- a/libraries/Netdump/src/PacketType.cpp +++ b/libraries/Netdump/src/PacketType.cpp @@ -1,9 +1,9 @@ /* - * PacketType.cpp - * - * Created on: 19 nov. 2019 - * Author: Herman - */ + PacketType.cpp + + Created on: 19 nov. 2019 + Author: Herman +*/ #include @@ -20,28 +20,28 @@ PacketType::~PacketType() String PacketType::toString() const { - switch (ptype) - { - case PType::ARP : return PSTR("ARP"); - case PType::IP : return PSTR("IP"); - case PType::UDP : return PSTR("UDP"); - case PType::MDNS : return PSTR("MDNS"); - case PType::DNS : return PSTR("DNS"); - case PType::SSDP : return PSTR("SSDP"); - case PType::DHCP : return PSTR("DHCP"); - case PType::WSDD : return PSTR("WSDD"); - case PType::NETBIOS: return PSTR("NBIO"); - case PType::SMB : return PSTR("SMB"); - case PType::OTA : return PSTR("OTA"); - case PType::TCP : return PSTR("TCP"); - case PType::HTTP : return PSTR("HTTP"); - case PType::ICMP : return PSTR("ICMP"); - case PType::IGMP : return PSTR("IGMP"); - case PType::IPv4: return PSTR("IPv4"); - case PType::IPv6: return PSTR("IPv6"); - case PType::UKNW : return PSTR("UKNW"); - default : return PSTR("ERR"); - }; + switch (ptype) + { + case PType::ARP : return PSTR("ARP"); + case PType::IP : return PSTR("IP"); + case PType::UDP : return PSTR("UDP"); + case PType::MDNS : return PSTR("MDNS"); + case PType::DNS : return PSTR("DNS"); + case PType::SSDP : return PSTR("SSDP"); + case PType::DHCP : return PSTR("DHCP"); + case PType::WSDD : return PSTR("WSDD"); + case PType::NETBIOS: return PSTR("NBIO"); + case PType::SMB : return PSTR("SMB"); + case PType::OTA : return PSTR("OTA"); + case PType::TCP : return PSTR("TCP"); + case PType::HTTP : return PSTR("HTTP"); + case PType::ICMP : return PSTR("ICMP"); + case PType::IGMP : return PSTR("IGMP"); + case PType::IPv4: return PSTR("IPv4"); + case PType::IPv6: return PSTR("IPv6"); + case PType::UKNW : return PSTR("UKNW"); + default : return PSTR("ERR"); + }; } } /* namespace NetCapture */ diff --git a/libraries/Netdump/src/PacketType.h b/libraries/Netdump/src/PacketType.h index cc4bf61791..b6fb1db611 100644 --- a/libraries/Netdump/src/PacketType.h +++ b/libraries/Netdump/src/PacketType.h @@ -1,9 +1,9 @@ /* - * PacketType.h - * - * Created on: 19 nov. 2019 - * Author: Herman - */ + PacketType.h + + Created on: 19 nov. 2019 + Author: Herman +*/ #ifndef LIBRARIES_NETDUMP_SRC_PACKETTYPE_H_ #define LIBRARIES_NETDUMP_SRC_PACKETTYPE_H_ @@ -17,39 +17,45 @@ class PacketType public: enum PType : int - { - ARP, - IP, - UDP, - MDNS, - DNS, - SSDP, - DHCP, - WSDD, - NETBIOS, - SMB, - OTA, - TCP, - HTTP, - ICMP, - IGMP, - IPv4, - IPv6, - UKNW, - }; - - PacketType(); - PacketType(PType pt) : ptype(pt) {}; - - ~PacketType(); - - operator PType() const { return ptype; }; - bool operator==(const PacketType& p) {return ptype == p.ptype;}; - - String toString() const; + { + ARP, + IP, + UDP, + MDNS, + DNS, + SSDP, + DHCP, + WSDD, + NETBIOS, + SMB, + OTA, + TCP, + HTTP, + ICMP, + IGMP, + IPv4, + IPv6, + UKNW, + }; + + PacketType(); + PacketType(PType pt) : ptype(pt) {}; + + ~PacketType(); + + operator PType() const + { + return ptype; + }; + bool operator==(const PacketType& p) + { + return ptype == p.ptype; + }; + + String toString() const; private: - PType ptype; + PType ptype; }; } /* namespace NetCapture */ From 1b77c97240519972468325e8588e008201d16e44 Mon Sep 17 00:00:00 2001 From: hreintke Date: Sun, 24 May 2020 12:21:56 +0200 Subject: [PATCH 18/22] wip --- libraries/Netdump/astyle_goodies.conf | 32 -- libraries/Netdump/src/Netdump.cpp | 109 ++++- libraries/Netdump/src/Netdump.h | 16 +- libraries/Netdump/src/NetdumpPacket.cpp | 75 +-- libraries/Netdump/src/NetdumpPacket.h | 70 ++- libraries/Netdump/src/NetdumpUtils.cpp | 20 + libraries/Netdump/src/NetdumpUtils.h | 28 ++ libraries/Netdump/src/ieee80211_structs.h | 80 +++ libraries/Netdump/src/sdk_structs.h | 62 +++ libraries/Netdump/src/string_utils.cpp | 66 +++ libraries/Netdump/src/string_utils.h | 10 + libraries/Netdump/src/structures.h | 561 ++++++++++++++++++++++ 12 files changed, 1055 insertions(+), 74 deletions(-) delete mode 100644 libraries/Netdump/astyle_goodies.conf create mode 100644 libraries/Netdump/src/NetdumpUtils.cpp create mode 100644 libraries/Netdump/src/NetdumpUtils.h create mode 100644 libraries/Netdump/src/ieee80211_structs.h create mode 100644 libraries/Netdump/src/sdk_structs.h create mode 100644 libraries/Netdump/src/string_utils.cpp create mode 100644 libraries/Netdump/src/string_utils.h create mode 100644 libraries/Netdump/src/structures.h diff --git a/libraries/Netdump/astyle_goodies.conf b/libraries/Netdump/astyle_goodies.conf deleted file mode 100644 index b1c6ed376e..0000000000 --- a/libraries/Netdump/astyle_goodies.conf +++ /dev/null @@ -1,32 +0,0 @@ -# Code formatting rules for Arduino examples, taken from: -# -# https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf -# - -mode=c -lineend=linux -style=allman - -# 4 spaces indentation -indent=spaces=4 - -# also indent macros -#indent-preprocessor - -# indent classes, switches (and cases), comments starting at column 1 -indent-col1-comments - -# put a space around operators -pad-oper - -# put a space after if/for/while -pad-header - -# if you like one-liners, keep them -keep-one-line-statements - -attach-closing-while -unpad-paren -pad-oper -remove-comment-prefix -add-braces \ No newline at end of file diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp index 3adb32a9d0..5614763524 100644 --- a/libraries/Netdump/src/Netdump.cpp +++ b/libraries/Netdump/src/Netdump.cpp @@ -22,18 +22,35 @@ #include "Netdump.h" #include #include "Schedule.h" - +#include "sdk_structs.h" +#include "ieee80211_structs.h" +#include "string_utils.h" namespace NetCapture { CallBackList Netdump::lwipCallback; +CallBackList Netdump::wifiCallback; -Netdump::Netdump() +Netdump::Netdump(interface ifc) { - using namespace std::placeholders; - phy_capture = capture; - lwipHandler = lwipCallback.add(std::bind(&Netdump::netdumpCapture, this, _1, _2, _3, _4, _5)); + using namespace std::placeholders; + if (ifc == interface::LWIP) + { + phy_capture = lwipCapture; + lwipHandler = lwipCallback.add(std::bind(&Netdump::netdumpCapture, this, _1, _2, _3, _4, _5)); + } + else + { + wifi_set_opmode(STATION_MODE); + wifi_promiscuous_enable(0); + WiFi.disconnect(); + wifi_set_promiscuous_rx_cb(wifiCapture); + wifi_set_channel(6); + wifi_promiscuous_enable(1); + Serial.write("Prom mode\r\n"); + wifiHandler = wifiCallback.add(std::bind(&Netdump::wifidumpCapture,this, _1, _2)); + } }; Netdump::~Netdump() @@ -99,7 +116,7 @@ void Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf) }); } -void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int success) +void Netdump::lwipCapture(int netif_idx, const char* data, size_t len, int out, int success) { if (lwipCallback.execute(netif_idx, data, len, out, success) == 0) { @@ -120,6 +137,86 @@ void Netdump::netdumpCapture(int netif_idx, const char* data, size_t len, int ou } } +void Netdump::wifiCapture(unsigned char* data, uint16_t len) +{ + wifiCallback.execute(reinterpret_cast(data),len); +} + +void Netdump::wifidumpCapture(const char* buff, uint16_t len) +{ +// netdumpCapture(0, data, len, 0, 1); + + // First layer: type cast the received buffer into our generic SDK structure + const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff; + // Second layer: define pointer to where the actual 802.11 packet is within the structure + const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload; + // Third layer: define pointers to the 802.11 packet header and payload + const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr; + const uint8_t *data = ipkt->payload; + + // Pointer to the frame control section within the packet header + const wifi_header_frame_control_t *frame_ctrl = (wifi_header_frame_control_t *)&hdr->frame_ctrl; + // Parse MAC addresses contained in packet header into human-readable strings + char addr1[] = "00:00:00:00:00:00\0"; + char addr2[] = "00:00:00:00:00:00\0"; + char addr3[] = "00:00:00:00:00:00\0"; + + mac2str(hdr->addr1, addr1); + mac2str(hdr->addr2, addr2); + mac2str(hdr->addr3, addr3); + + // Output info to serial +// if (!(frame_ctrl->type == WIFI_PKT_MGMT && frame_ctrl->subtype == BEACON)) + if ((frame_ctrl->type == WIFI_PKT_DATA)) + Serial.printf("\r\n%s | %s | %s | %u | %02d | %u | %u(%-2u) | %-28s | %u | %u | %u | %u | %u | %u | %u | %u | ", + addr1, + addr2, + addr3, + wifi_get_channel(), + ppkt->rx_ctrl.rssi, + frame_ctrl->protocol, + frame_ctrl->type, + frame_ctrl->subtype, + wifi_pkt_type2str((wifi_promiscuous_pkt_type_t)frame_ctrl->type, (wifi_mgmt_subtypes_t)frame_ctrl->subtype), + frame_ctrl->to_ds, + frame_ctrl->from_ds, + frame_ctrl->more_frag, + frame_ctrl->retry, + frame_ctrl->pwr_mgmt, + frame_ctrl->more_data, + frame_ctrl->wep, + frame_ctrl->strict); + if (frame_ctrl->type == WIFI_PKT_DATA) + { + Serial.printf("\r\nData %04x",frame_ctrl->subtype); + } + // Print ESSID if beacon + /* + if (frame_ctrl->type == WIFI_PKT_MGMT && frame_ctrl->subtype == BEACON) + { + const wifi_mgmt_beacon_t *beacon_frame = (wifi_mgmt_beacon_t*) ipkt->payload; + char ssid[32] = {0}; + + if (beacon_frame->tag_length >= 32) + { + strncpy(ssid, beacon_frame->ssid, 31); + } + else + { + strncpy(ssid, beacon_frame->ssid, beacon_frame->tag_length); + } + + Serial.printf("%s", ssid); + } + */ +} + +/* + uint32_t timestamp = now(); //current timestamp + uint32_t microseconds = (unsigned int)(micros() - millis() * 1000); //micro seconds offset (0 - 999) + pcap.newPacketSerial(timestamp, microseconds, len, buf); //write packet to file +*/ + void Netdump::writePcapHeader(Stream& s) const { uint32_t pcapHeader[6]; diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h index bf16e7dd30..dbce742dc0 100644 --- a/libraries/Netdump/src/Netdump.h +++ b/libraries/Netdump/src/Netdump.h @@ -42,8 +42,15 @@ class Netdump using Filter = std::function; using Callback = std::function; using LwipCallback = std::function; + using WifiCallback = std::function; - Netdump(); + enum class interface + { + LWIP, + WIFI + }; + + Netdump(interface ifc = interface::WIFI); ~Netdump(); void setCallback(const Callback nc); @@ -60,11 +67,16 @@ class Netdump Callback netDumpCallback = nullptr; Filter netDumpFilter = nullptr; - static void capture(int netif_idx, const char* data, size_t len, int out, int success); + static void lwipCapture(int netif_idx, const char* data, size_t len, int out, int success); + static void wifiCapture(unsigned char* data, uint16_t len); static CallBackList lwipCallback; CallBackList::CallBackHandler lwipHandler; + static CallBackList wifiCallback; + CallBackList::CallBackHandler wifiHandler; + void netdumpCapture(int netif_idx, const char* data, size_t len, int out, int success); + void wifidumpCapture(const char* data, uint16_t len); void printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) const; void fileDumpProcess(File& outfile, const Packet& np) const; diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index 86782dd921..5e32f4aca3 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -25,7 +25,7 @@ namespace NetCapture { -void Packet::printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const +void Packet::printDetail(Print& out, const String& indent, const uint8_t* data, size_t size, PacketDetail pd) const { if (pd == PacketDetail::NONE) { @@ -149,57 +149,68 @@ const std::vector Packet::allPacketTypes() const return thisAllPacketTypes; } -void Packet::MACtoString(int dataIdx, StreamString& sstr) const +void Packet::MACtoString(const uint8_t* mac, StreamString& sstr) const { for (int i = 0; i < 6; i++) { - sstr.printf_P(PSTR("%02x"), (unsigned char)data[dataIdx + i]); + sstr.printf_P(PSTR("%02x"), mac[i]); if (i < 5) { sstr.print(':'); } } - } void Packet::ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { - switch (getARPType()) + if (!arpPacket) + { + sstr.printf_P(PSTR("ARPtoString access error\r\n")); + return; + } + switch (arpPacket->opcode()) { - case 1 : sstr.printf_P(PSTR("who has %s tell %s"), getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); + case 1 : sstr.printf_P(PSTR("who has %s tell %s"), arpPacket->targetIP().toString().c_str(), arpPacket->senderIP().toString().c_str()); break; - case 2 : sstr.printf_P(PSTR("%s is at "), getIP(ETH_HDR_LEN + 14).toString().c_str()); - MACtoString(ETH_HDR_LEN + 8, sstr); + case 2 : sstr.printf_P(PSTR("%s is at "), arpPacket->senderIP().toString().c_str()); + MACtoString(arpPacket->hdr->senderHardwareAddress, sstr); break; } sstr.printf("\r\n"); - printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN], packetLength - ETH_HDR_LEN, netdumpDetail); + printDetail(sstr, PSTR(" D "), arpPacket->raw, packetLength - ETH_HDR_LEN, netdumpDetail); } void Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const { - sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); - sstr.printf_P(PSTR("ID=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8)); - sstr.printf_P(PSTR("F=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 2)); - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 4)) + if (!dnsPacket || !udpPacket || !ipPacket) + { + sstr.printf_P(PSTR("DNStoString access error\r\n")); + return; + } + sstr.printf_P(PSTR("%s>%s "), ipPacket->sourceIP().toString().c_str(), ipPacket->destinationIP().toString().c_str()); + sstr.printf_P(PSTR("ID=0x%04x "), dnsPacket->id()); + sstr.printf_P(PSTR("F=0x%04x "), dnsPacket->flags()); + + if (uint16_t t = dnsPacket->qdcount()) { sstr.printf_P(PSTR("Q=%d "), t); } - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 6)) + if (uint16_t t = dnsPacket->ancount()) { sstr.printf_P(PSTR("R=%d "), t); } - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 8)) + if (uint16_t t = dnsPacket->nscount()) { sstr.printf_P(PSTR("TR=%d "), t); } - if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 10)) + if (uint16_t t = dnsPacket->arcount()) { sstr.printf_P(PSTR("DR=%d "), t); } + sstr.printf_P(PSTR("\r\n")); - printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); - printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); + printDetail(sstr, PSTR(" H "), udpPacket->raw, udpPacket->hdrLength(), netdumpDetail); + printDetail(sstr, PSTR(" D "), udpPacket->hdr->payload, udpPacket->length(), netdumpDetail); } void Packet::UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const @@ -207,12 +218,17 @@ void Packet::UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); sstr.printf_P(PSTR("%d:%d"), getSrcPort(), getDstPort()); sstr.printf_P(PSTR("\r\n")); - printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); - printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); + printDetail(sstr, PSTR(" H "), udpPacket->raw, getUdpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), udpPacket->hdr->payload, getUdpLen(), netdumpDetail); } void Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { + if (!tcpPacket) + { + sstr.printf_P(PSTR("TCPtoString access error\r\n")); + return; + } sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); sstr.printf_P(PSTR("%d:%d "), getSrcPort(), getDstPort()); uint16_t flags = getTcpFlags(); @@ -226,12 +242,17 @@ void Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const sstr.print(']'); sstr.printf_P(PSTR(" len: %u seq: %u, ack: %u, wnd: %u "), getTcpLen(), getTcpSeq(), getTcpAck(), getTcpWindow()); sstr.printf_P(PSTR("\r\n")); - printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail); - printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); + printDetail(sstr, PSTR(" H "), tcpPacket->raw, getTcpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), tcpPacket->hdr->payload, getTcpLen(), netdumpDetail); } void Packet::ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { + if (!icmpPacket || !ipPacket) + { + sstr.printf_P(PSTR("ICMPtoString access error\r\n")); + return; + } sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); if (isIPv4()) { @@ -280,16 +301,16 @@ void Packet::IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); sstr.printf_P(PSTR("Unknown IP type : %d\r\n"), ipType()); - printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN], getIpHdrLen(), netdumpDetail); - printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen()], getIpTotalLen() - getIpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" H "), ipPacket->raw(), getIpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), ipPacket->raw(), getIpTotalLen() - getIpHdrLen(), netdumpDetail); } void Packet::UKNWtoString(PacketDetail netdumpDetail, StreamString& sstr) const { sstr.printf_P(PSTR("Unknown EtherType 0x%04x Src : "), ethType()); - MACtoString(0, sstr); + MACtoString(rawData(), sstr); sstr.printf_P(PSTR(" Dst : ")); - MACtoString(6, sstr); + MACtoString(rawData()+6, sstr); sstr.printf_P(PSTR("\r\n")); } @@ -314,7 +335,7 @@ const String Packet::toString(PacketDetail netdumpDetail) const sstr.printf_P(PSTR("%s "), at.toString().c_str()); } sstr.printf_P(PSTR("\r\n")); - printDetail(sstr, PSTR(" D "), data, packetLength, netdumpDetail); + printDetail(sstr, PSTR(" D "), rawData(), packetLength, netdumpDetail); return sstr; } diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index af0d701619..382024dc56 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -28,19 +28,60 @@ #include "NetdumpIP.h" #include "PacketType.h" #include +#include "NetdumpUtils.h" +#include "structures.h" namespace NetCapture { -int constexpr ETH_HDR_LEN = 14; - class Packet { public: + static int constexpr ETH_HDR_LEN = 14; + Packet(unsigned long msec, int n, const char* d, size_t l, int o, int s) : packetTime(msec), netif_idx(n), data(d), packetLength(l), out(o), success(s) { setPacketTypes(); + ethernetFrame = new EthernetFrame(rawData()); + + switch (ethernetFrame->type()) + { + case 0x0800 : + ipv4Packet = new IPv4Packet(ethernetFrame->hdr->payload); + ipPacket = new IPPacket(ipv4Packet); + break; + case 0x86dd : + ipv6Packet = new IPv6Packet(ethernetFrame->hdr->payload); + ipPacket = new IPPacket(ipv6Packet); + break; + case 0x0806 : + arpPacket = new ARPPacket(ethernetFrame->hdr->payload); + break; + default : + break; + } + + if (ipPacket) + { + switch (ipPacket->packetType()) + { + case 17 : udpPacket = new UDPPacket(ipPacket->payload()); + break; + case 6 : tcpPacket = new TCPPacket(ipPacket->payload()); + break; + case 1 : icmpPacket = new ICMPPacket(ipPacket->payload()); + break; + default : break; + } + } + if (udpPacket) + { + if ((udpPacket->sourcePort() == 5353) || (udpPacket->destinationPort() == 5353)) + { + dnsPacket = new DNSPacket(udpPacket->hdr->payload); + } + } }; Packet() {}; @@ -53,9 +94,20 @@ class Packet RAW }; - const char* rawData() const + EthernetFrame* ethernetFrame = nullptr; + ARPPacket* arpPacket = nullptr; + IPv4Packet* ipv4Packet = nullptr; + IPv6Packet* ipv6Packet = nullptr; + IPPacket* ipPacket = nullptr; + UDPPacket* udpPacket = nullptr; + DNSPacket* dnsPacket = nullptr; + TCPPacket* tcpPacket = nullptr; + ICMPPacket* icmpPacket = nullptr; + + + const uint8_t* rawData() const { - return data; + return reinterpret_cast(data); } int getInOut() const { @@ -128,7 +180,7 @@ class Packet uint8_t getIcmpType() const { - return isICMP() ? data[ETH_HDR_LEN + getIpHdrLen() + 0] : 0; + return icmpPacket ? icmpPacket->hdr->type : 0; } uint8_t getIgmpType() const { @@ -234,6 +286,7 @@ class Packet }; NetdumpIP sourceIP() const { + return ipPacket ? ipPacket->sourceIP() : NetdumpIP(); NetdumpIP ip; if (isIPv4()) { @@ -253,6 +306,7 @@ class Packet NetdumpIP destIP() const { + return ipPacket ? ipPacket->destinationIP() : NetdumpIP(); NetdumpIP ip; if (isIPv4()) { @@ -266,10 +320,12 @@ class Packet }; uint16_t getSrcPort() const { + return tcpPacket ? tcpPacket->sourcePort() : (udpPacket ? udpPacket->sourcePort() : 0); return isIP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 0) : 0; } uint16_t getDstPort() const { + return tcpPacket ? tcpPacket->destinationPort() : (udpPacket ? udpPacket->destinationPort() : 0); return isIP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 2) : 0; } bool hasPort(uint16_t p) const @@ -279,7 +335,7 @@ class Packet const String toString() const; const String toString(PacketDetail netdumpDetail) const; - void printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const; + void printDetail(Print& out, const String& indent, const uint8_t* data, size_t size, PacketDetail pd) const; const PacketType packetType() const; const std::vector allPacketTypes() const; @@ -290,7 +346,7 @@ class Packet void setPacketType(PacketType); void setPacketTypes(); - void MACtoString(int dataIdx, StreamString& sstr) const; + void MACtoString(const uint8_t* mac, StreamString& sstr) const; void ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; void DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const; void UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; diff --git a/libraries/Netdump/src/NetdumpUtils.cpp b/libraries/Netdump/src/NetdumpUtils.cpp new file mode 100644 index 0000000000..ba813420ae --- /dev/null +++ b/libraries/Netdump/src/NetdumpUtils.cpp @@ -0,0 +1,20 @@ +/* + * NetdumpUtils.cpp + * + * Created on: 5 mei 2020 + * Author: Herman + */ + +#include + +NetdumpUtils::NetdumpUtils() +{ + // TODO Auto-generated constructor stub + +} + +NetdumpUtils::~NetdumpUtils() +{ + // TODO Auto-generated destructor stub +} + diff --git a/libraries/Netdump/src/NetdumpUtils.h b/libraries/Netdump/src/NetdumpUtils.h new file mode 100644 index 0000000000..739ce311a5 --- /dev/null +++ b/libraries/Netdump/src/NetdumpUtils.h @@ -0,0 +1,28 @@ +/* + * NetdumpUtils.h + * + * Created on: 5 mei 2020 + * Author: Herman + */ + +#ifndef LIBRARIES_NETDUMP_SRC_NETDUMPUTILS_H_ +#define LIBRARIES_NETDUMP_SRC_NETDUMPUTILS_H_ + +#include "Arduino.h" + +class NetdumpUtils +{ +public: + NetdumpUtils(); + ~NetdumpUtils(); + static uint16_t ntoh16(const uint8_t data[2]) + { + return data[1] | (((uint16_t)data[0]) << 8); + }; + static uint32_t ntoh32(const uint8_t data[4]) + { + return ntoh16(&data[2]) | (((uint32_t)ntoh16(&data[0])) << 16); + }; +}; + +#endif /* LIBRARIES_NETDUMP_SRC_NETDUMPUTILS_H_ */ diff --git a/libraries/Netdump/src/ieee80211_structs.h b/libraries/Netdump/src/ieee80211_structs.h new file mode 100644 index 0000000000..485e0443cf --- /dev/null +++ b/libraries/Netdump/src/ieee80211_structs.h @@ -0,0 +1,80 @@ +#ifndef _IEE80211_STRUCTS_H_ +#define _IEE80211_STRUCTS_H_ + +#include + +// IEEE802.11 data structures --------------------- + +typedef enum +{ + WIFI_PKT_MGMT, + WIFI_PKT_CTRL, + WIFI_PKT_DATA, + WIFI_PKT_MISC, +} wifi_promiscuous_pkt_type_t; + +typedef enum +{ + ASSOCIATION_REQ, + ASSOCIATION_RES, + REASSOCIATION_REQ, + REASSOCIATION_RES, + PROBE_REQ, + PROBE_RES, + NU1, /* ......................*/ + NU2, /* 0110, 0111 not used */ + BEACON, + ATIM, + DISASSOCIATION, + AUTHENTICATION, + DEAUTHENTICATION, + ACTION, + ACTION_NACK, +} wifi_mgmt_subtypes_t; + +typedef struct +{ + unsigned interval:16; + unsigned capability:16; + unsigned tag_number:8; + unsigned tag_length:8; + char ssid[0]; + uint8 rates[1]; +} wifi_mgmt_beacon_t; + +typedef struct +{ + unsigned protocol:2; + unsigned type:2; + unsigned subtype:4; + unsigned to_ds:1; + unsigned from_ds:1; + unsigned more_frag:1; + unsigned retry:1; + unsigned pwr_mgmt:1; + unsigned more_data:1; + unsigned wep:1; + unsigned strict:1; +} wifi_header_frame_control_t; + +/** + * Ref: https://github.com/lpodkalicki/blog/blob/master/esp32/016_wifi_sniffer/main/main.c + */ +typedef struct +{ + wifi_header_frame_control_t frame_ctrl; + //unsigned duration_id:16; /* !!!! ugly hack */ + uint8_t addr1[6]; /* receiver address */ + uint8_t addr2[6]; /* sender address */ + uint8_t addr3[6]; /* filtering address */ + unsigned sequence_ctrl:16; + uint8_t addr4[6]; /* optional */ +} wifi_ieee80211_mac_hdr_t; + +typedef struct +{ + wifi_ieee80211_mac_hdr_t hdr; + uint8_t payload[2]; /* network data ended with 4 bytes csum (CRC32) */ +} wifi_ieee80211_packet_t; + +#endif diff --git a/libraries/Netdump/src/sdk_structs.h b/libraries/Netdump/src/sdk_structs.h new file mode 100644 index 0000000000..d5af8f6a58 --- /dev/null +++ b/libraries/Netdump/src/sdk_structs.h @@ -0,0 +1,62 @@ +#ifndef _SDK_STRUCTS_H_ +#define _SDK_STRUCTS_H_ + +#include + +// SDK structures ----------------------------------- + +typedef struct +{ + signed rssi:8; /**< signal intensity of packet */ + unsigned rate:4; /**< data rate */ + unsigned is_group:1; + unsigned :1; /**< reserve */ + unsigned sig_mode:2; /**< 0:is not 11n packet; 1:is 11n packet */ + unsigned legacy_length:12; + unsigned damatch0:1; + unsigned damatch1:1; + unsigned bssidmatch0:1; + unsigned bssidmatch1:1; + unsigned mcs:7; /**< if is 11n packet, shows the modulation(range from 0 to 76) */ + unsigned cwb:1; /**< if is 11n packet, shows if is HT40 packet or not */ + unsigned HT_length:16; /**< reserve */ + unsigned smoothing:1; /**< reserve */ + unsigned not_sounding:1; /**< reserve */ + unsigned :1; /**< reserve */ + unsigned aggregation:1; /**< Aggregation */ + unsigned stbc:2; /**< STBC */ + unsigned fec_coding:1; /**< Flag is set for 11n packets which are LDPC */ + unsigned sgi:1; /**< SGI */ + unsigned rxend_state:8; + unsigned ampdu_cnt:8; /**< ampdu cnt */ + unsigned channel:4; /**< which channel this packet in */ + unsigned :4; /**< reserve */ + signed noise_floor:8; +} wifi_pkt_rx_ctrl_t; + +typedef struct { + wifi_pkt_rx_ctrl_t rx_ctrl; + uint8 buf[112]; + uint16 cnt; + uint16 len; //length of packet +} wifi_pkt_mgmt_t; + +typedef struct { + uint16 length; + uint16 seq; + uint8 address3[6]; +} wifi_pkt_lenseq_t; + +typedef struct { + wifi_pkt_rx_ctrl_t rx_ctrl; + uint8_t buf[36]; + uint16_t cnt; + wifi_pkt_lenseq_t lenseq[1]; +} wifi_pkt_data_t; + +typedef struct { + wifi_pkt_rx_ctrl_t rx_ctrl; /**< metadata header */ + uint8_t payload[0]; /**< Data or management payload. Length of payload is described by rx_ctrl.sig_len. Type of content determined by packet type argument of callback. */ +} wifi_promiscuous_pkt_t; + +#endif diff --git a/libraries/Netdump/src/string_utils.cpp b/libraries/Netdump/src/string_utils.cpp new file mode 100644 index 0000000000..c53871a123 --- /dev/null +++ b/libraries/Netdump/src/string_utils.cpp @@ -0,0 +1,66 @@ +#include "sdk_structs.h" +#include "ieee80211_structs.h" + +// Uncomment to enable MAC address masking +#define MASKED + +//Returns a human-readable string from a binary MAC address. +//If MASKED is defined, it masks the output with XX +void mac2str(const uint8_t* ptr, char* string) +{ +// #ifdef MASKED +// sprintf(string, "XX:XX:XX:%02x:%02x:XX", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); +// #else + sprintf(string, "%02x:%02x:%02x:%02x:%02x:%02x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); +// #endif + return; +} + +//Parses 802.11 packet type-subtype pair into a human-readable string +const char* wifi_pkt_type2str(wifi_promiscuous_pkt_type_t type, wifi_mgmt_subtypes_t subtype) +{ + switch(type) + { + case WIFI_PKT_MGMT: + switch(subtype) + { + case ASSOCIATION_REQ: + return "Mgmt: Association request"; + case ASSOCIATION_RES: + return "Mgmt: Association response"; + case REASSOCIATION_REQ: + return "Mgmt: Reassociation request"; + case REASSOCIATION_RES: + return "Mgmt: Reassociation response"; + case PROBE_REQ: + return "Mgmt: Probe request"; + case PROBE_RES: + return "Mgmt: Probe response"; + case BEACON: + return "Mgmt: Beacon frame"; + case ATIM: + return "Mgmt: ATIM"; + case DISASSOCIATION: + return "Mgmt: Dissasociation"; + case AUTHENTICATION: + return "Mgmt: Authentication"; + case DEAUTHENTICATION: + return "Mgmt: Deauthentication"; + case ACTION: + return "Mgmt: Action"; + case ACTION_NACK: + return "Mgmt: Action no ack"; + default: + return "Mgmt: Unsupported/error"; + } + + case WIFI_PKT_CTRL: + return "Control"; + + case WIFI_PKT_DATA: + return "Data"; + + default: + return "Unsupported/error"; + } +} diff --git a/libraries/Netdump/src/string_utils.h b/libraries/Netdump/src/string_utils.h new file mode 100644 index 0000000000..7d88b92556 --- /dev/null +++ b/libraries/Netdump/src/string_utils.h @@ -0,0 +1,10 @@ +#ifndef _STRING_UTILS_H_ +#define _STRING_UTILS_H_ + +#include "sdk_structs.h" +#include "ieee80211_structs.h" + +void mac2str(const uint8_t* ptr, char* string); +const char* wifi_pkt_type2str(wifi_promiscuous_pkt_type_t type, wifi_mgmt_subtypes_t subtype); + +#endif diff --git a/libraries/Netdump/src/structures.h b/libraries/Netdump/src/structures.h new file mode 100644 index 0000000000..196aaa0dad --- /dev/null +++ b/libraries/Netdump/src/structures.h @@ -0,0 +1,561 @@ +/* + * structures.h + * + * Created on: 5 mei 2020 + * Author: Herman + */ + +#ifndef LIBRARIES_NETDUMP_SRC_STRUCTURES_H_ +#define LIBRARIES_NETDUMP_SRC_STRUCTURES_H_ + +#include "Arduino.h" +#include "NetdumpUtils.h" +#include "NetdumpIP.h" + +namespace NetCapture +{ + +class EthernetFrame +{ +public: + + struct EthernetHeader + { + uint8_t destinationMAC[6]; + uint8_t sourceMAC[6]; + uint8_t type[2]; + uint8_t payload[]; + }; + + EthernetFrame(const uint8_t* frame) + { + hdr = reinterpret_cast(frame); + raw = frame; + }; + ~EthernetFrame(){}; + + const EthernetHeader* hdr; + const uint8_t* raw; + + String destinationMAC() {return "";} + const uint8_t* payload() { return hdr->payload;} + uint16_t type() {return NetdumpUtils::ntoh16(hdr->type);} +}; + +class ARPPacket +{ +public: + struct ARPHeader + { + uint8_t hardwareType[2]; + uint8_t protocolType[2]; + uint8_t hardwareAddressLength; + uint8_t protocolAddressLength; + uint8_t opcode[2]; + uint8_t senderHardwareAddress[6]; + uint8_t senderProtocolAddress[4]; + uint8_t targetHardwareAddress[6]; + uint8_t targetProtocolAddress[4]; + }; + + ARPPacket(const uint8_t* packet) + { + hdr = reinterpret_cast(packet); + raw = packet; + } + + const ARPHeader* hdr; + const uint8_t* raw; + + uint16_t opcode() + { + return NetdumpUtils::ntoh16(hdr->opcode); + } + NetdumpIP targetIP() + { + return NetdumpIP(hdr->targetProtocolAddress); + } + NetdumpIP senderIP() + { + return NetdumpIP(hdr->senderProtocolAddress); + } +}; + +class IPv4Packet +{ +public: + struct IPv4Header + { +// uint8_t version:4; +// uint8_t headerLength:4; + uint8_t version_header; +// uint8_t serviceType:6; +// uint8_t ecn:2; + uint8_t type_ecn; + uint8_t totalLength[2]; + uint8_t identification[2]; +// uint8_t flags:3; +// uint16_t fragmentOffset:13; + uint8_t flags_fragment[2]; + uint8_t ttl; + uint8_t protocol; + uint8_t headerChecksum[2]; + uint8_t sourceIP[4]; + uint8_t destinationIP[4]; + uint8_t payload[]; + }; + IPv4Packet(const uint8_t* packet) + { + hdr = reinterpret_cast(packet); + raw = packet; + } + + const IPv4Header* hdr; + const uint8_t* raw; + + uint16_t headerLength() + { + return (hdr->version_header & 0x0f) << 2; + } + uint8_t ipVersion() + { + return (hdr->version_header >> 4) & 0x0f; + } + uint8_t serviceType() + { + return (hdr->type_ecn >> 2) & 0x3f; + } + uint8_t flags() + { + return (NetdumpUtils::ntoh16(hdr->flags_fragment) >> 13) & 0x07; + } + uint16_t fragmentationOffset() + { + return (NetdumpUtils::ntoh16(hdr->flags_fragment) & 0x1fff); + } + NetdumpIP sourceIP() + { + return NetdumpIP(hdr->sourceIP); + } + NetdumpIP destinationIP() + { + return NetdumpIP(hdr->destinationIP); + } +}; + +class IPv6Packet +{ +public: + + struct IPv6Header + { + uint8_t version_traffic_flow[4]; + uint8_t payloadLength[2]; + uint8_t nextHeader; + uint8_t hopLimit; + uint8_t sourceAddress[16]; + uint8_t destinationAddress[16]; + uint8_t payload[]; + }; + + IPv6Packet(const uint8_t* data) + : raw(data), + hdr(reinterpret_cast(data)) + {}; + + const uint8_t* raw; + const IPv6Header* hdr; + + uint8_t type() + { + return hdr->nextHeader; + } + NetdumpIP sourceIP() + { + return NetdumpIP(hdr->sourceAddress,false); + } + NetdumpIP destinationIP() + { + return NetdumpIP(hdr->destinationAddress,false); + } +}; + +class IPPacket +{ +public: + IPPacket(IPv4Packet* i4) : ip4(true), ipv4(i4) + { + }; + IPPacket(IPv6Packet* i6) : ip4(false), ipv6(i6) + { + }; + + union ipv4v6 + { + IPv4Packet::IPv4Header* ipv4h; + IPv6Packet::IPv6Header* ipv6h; + }; + + ipv4v6 ht; + + bool ip4 = false; + IPv4Packet* ipv4 = nullptr; + IPv6Packet* ipv6 = nullptr; + + uint8_t packetType() + { + return ip4 ? ipv4->hdr->protocol : ipv6->type(); + } + NetdumpIP sourceIP() + { + return ip4 ? ipv4->sourceIP() : ipv6->sourceIP(); + } + NetdumpIP destinationIP() + { + return ip4 ? ipv4->destinationIP() : ipv6->destinationIP(); + } + const uint8_t* payload() + { + return ip4 ? ipv4->hdr->payload : ipv6->hdr->payload; + } + const uint8_t* raw() + { + return ip4 ? ipv4->raw : ipv6->raw; + } +}; + +class IPPacket_1 : public IPv4Packet, public IPv6Packet +{ +public: + IPPacket_1(IPv4Packet* i4) : IPv4Packet(i4->raw), IPv6Packet(nullptr) + { + const uint8_t* raw = IPv4Packet::raw; + hdr = reinterpret_cast(IPv4Packet::raw); + } + const uint8_t* raw; + const IPv4Header* hdr; + + +}; + +class TCPPacket +{ +public: + struct TCPHeader + { + uint8_t sourcePort[2]; + uint8_t destinationPort[2]; + uint8_t sequenceNumber[4]; + uint8_t acknowledgementNumber[4]; + uint8_t dataOffset:4; + uint8_t reserved:6; + uint8_t controlFlags:6; + uint8_t window[2]; + uint8_t checksum[2]; + uint8_t urgentPointer[2]; + uint8_t payload[]; + }; + + TCPPacket(const uint8_t* packet) + { + hdr = reinterpret_cast(packet); + raw = packet; + } + + const TCPHeader* hdr; + const uint8_t* raw; + + uint16_t sourcePort() const + { + return NetdumpUtils::ntoh16(hdr->sourcePort); + } + uint16_t destinationPort() const + { + return NetdumpUtils::ntoh16(hdr->destinationPort); + } + uint32_t sequenceNumber() const + { + return NetdumpUtils::ntoh32(hdr->sequenceNumber); + } +}; + +class UDPPacket +{ +public: + struct UDPHeader + { + uint8_t sourcePort[2]; + uint8_t destinationPort[2]; + uint8_t length[2]; + uint8_t checksum[2]; + uint8_t payload[]; + }; + + UDPPacket(const uint8_t* packet) + { + hdr = reinterpret_cast(packet); + raw = packet; + } + + const UDPHeader* hdr; + const uint8_t* raw; + + uint16_t sourcePort() + { + return NetdumpUtils::ntoh16(hdr->sourcePort); + } + uint16_t destinationPort() + { + return NetdumpUtils::ntoh16(hdr->destinationPort); + } + uint16_t length() + { + return NetdumpUtils::ntoh16(hdr->length); + } + uint16_t checksum() + { + return NetdumpUtils::ntoh16(hdr->checksum); + } + uint16_t hdrLength() + { + return 8; + } +}; + +class DNSPacket +{ +public: + + struct DNSHeaderFlags + { + uint8_t opcode:4; + uint8_t aa:1; + uint8_t tc:1; + uint8_t rd:1; + uint8_t z:1; + uint8_t ad:1; + uint8_t cd:1; + uint8_t rcode:4; + }; + + struct DNSHeader + { + uint8_t id[2]; + uint8_t flags[2]; + uint8_t qdcount[2]; + uint8_t ancount[2]; + uint8_t nscount[2]; + uint8_t arcount[2]; + uint8_t questions[]; + uint8_t details[]; + }; + + struct DNSQuestion + { + String qname = ""; + uint16_t qtype = 0; + uint16_t qclass = 0; + }; + + struct DNSAnswer + { + String name; + uint16_t type; + uint16_t aclass; + uint32_t ttl; + uint16_t rdlength; + const uint8_t* rdata; + + NetCapture::NetdumpIP getIP() + { + if (type == 1) + { + return NetdumpIP(rdata[0],rdata[1],rdata[2],rdata[3]); + } + else if (type == 28) + { + return NetdumpIP(rdata, false); + } + else + { + return NetdumpIP(); + } + } + + }; + + DNSPacket(const uint8_t* packet) + : raw(packet), + hdr(reinterpret_cast(packet)) + {}; + + const uint8_t* raw; + const DNSHeader* hdr; + + uint16_t id() + { + return (NetdumpUtils::ntoh16(hdr->id)); + } + uint16_t qdcount() + { + return (NetdumpUtils::ntoh16(hdr->qdcount)); + } + uint16_t ancount() + { + return (NetdumpUtils::ntoh16(hdr->ancount)); + } + uint16_t nscount() + { + return (NetdumpUtils::ntoh16(hdr->nscount)); + } + uint16_t arcount() + { + return (NetdumpUtils::ntoh16(hdr->arcount)); + } + uint16_t flags() + { + return (NetdumpUtils::ntoh16(hdr->flags)); + } + + using questionResult = std::tuple; + + DNSQuestion getQuestion(uint8_t questionIdx) + { + if (questionIdx >= qdcount()) + { + Serial.printf("Question index too high %d\r\n",questionIdx); + return DNSQuestion(); + } + + const uint8_t* qPtr = hdr->details; + DNSQuestion dq; + + for (uint8_t idx=0;idx<=questionIdx;idx++) + { + std::tie(dq,qPtr) = getQuestion1(qPtr); + } + return dq; + } + + using qNameResult = std::tuple; + + questionResult getQuestion1(const uint8_t* questionPtr) + { + DNSQuestion dq; + + String n; + const uint8_t* p; + std::tie(n,p) = qName(questionPtr); // c++17 : auto [n,p] = qName(questionPtr); + + dq.qname = n; + dq.qtype = NetdumpUtils::ntoh16(p); + dq.qclass = NetdumpUtils::ntoh16(&p[2]); + return std::make_tuple(dq,p+4); + } + + qNameResult qName(const uint8_t* qname) + { + String qn; + const uint8_t* returnvalue = nullptr; + while (*qname != 0x00) + { + if (((*qname) & 0xc0) == 0) + { + if (qn.length() != 0) + { + qn += String('.'); + } + uint8_t l = *qname; + qname++; + for(int idx=0;idx; + + DNSAnswer getAnswer(uint8_t answerIdx) + { + if (answerIdx >= ancount()) + { + Serial.printf("answer index too high %d\r\n",answerIdx); + return DNSAnswer(); + } + + const uint8_t* qPtr = hdr->details; + DNSQuestion dq; + + for (uint8_t idx=0;idx(packet); + raw = packet; + } + + const ICMPHeader* hdr; + const uint8_t* raw; + +}; + +} // namespace NetCapture + +#endif /* LIBRARIES_NETDUMP_SRC_STRUCTURES_H_ */ From d1a142bf5431e70ebeab3253d012842fdd05c780 Mon Sep 17 00:00:00 2001 From: hreintke Date: Wed, 27 May 2020 13:00:02 +0200 Subject: [PATCH 19/22] Use std::unique_ptr to prevent memory leak --- libraries/Netdump/src/NetdumpPacket.cpp | 11 ++++- libraries/Netdump/src/NetdumpPacket.h | 61 +++++++++++++++---------- libraries/Netdump/src/structures.h | 24 +++------- 3 files changed, 53 insertions(+), 43 deletions(-) diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index 5e32f4aca3..12ea621903 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -207,8 +207,17 @@ void Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const { sstr.printf_P(PSTR("DR=%d "), t); } - sstr.printf_P(PSTR("\r\n")); + for (int i = 0;iqdcount();i++) + { + DNSPacket::DNSQuestion dq = dnsPacket->getQuestion(i); + sstr.printf(" Q : %s, type %d\r\n",dq.qname.c_str(),dq.qtype); + } + for (int i=0;iancount();i++) + { + DNSPacket::DNSAnswer da = dnsPacket->getAnswer(i); + sstr.printf(" R : %s IP : %s\r\n",da.name.c_str(),da.getIP().toString().c_str()); + } printDetail(sstr, PSTR(" H "), udpPacket->raw, udpPacket->hdrLength(), netdumpDetail); printDetail(sstr, PSTR(" D "), udpPacket->hdr->payload, udpPacket->length(), netdumpDetail); } diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index 382024dc56..9b8d38939f 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -30,7 +30,7 @@ #include #include "NetdumpUtils.h" #include "structures.h" - +#include namespace NetCapture { @@ -43,20 +43,27 @@ class Packet : packetTime(msec), netif_idx(n), data(d), packetLength(l), out(o), success(s) { setPacketTypes(); - ethernetFrame = new EthernetFrame(rawData()); - +// ethernetFrame = new EthernetFrame(rawData()); + ethernetFrame.reset(new EthernetFrame(rawData())); +// ethernetFrame = std::unique_ptr(new EthernetFrame(rawData())); switch (ethernetFrame->type()) { case 0x0800 : - ipv4Packet = new IPv4Packet(ethernetFrame->hdr->payload); - ipPacket = new IPPacket(ipv4Packet); +// ipv4Packet = new IPv4Packet(ethernetFrame->hdr->payload); +// ipPacket = new IPPacket(ipv4Packet); + // ipv4Packet->reset(new IPv4Packet(ethernetFrame->hdr->payload)); + ipv4Packet.reset(new IPv4Packet(ethernetFrame->hdr->payload)); + ipPacket.reset(new IPPacket(ipv4Packet)); break; case 0x86dd : - ipv6Packet = new IPv6Packet(ethernetFrame->hdr->payload); - ipPacket = new IPPacket(ipv6Packet); +// ipv6Packet = new IPv6Packet(ethernetFrame->hdr->payload); +// ipPacket = new IPPacket(ipv6Packet); + ipv6Packet.reset(new IPv6Packet(ethernetFrame->hdr->payload)); + ipPacket.reset(new IPPacket(ipv6Packet)); break; case 0x0806 : - arpPacket = new ARPPacket(ethernetFrame->hdr->payload); +// arpPacket = new ARPPacket(ethernetFrame->hdr->payload); + arpPacket.reset(new ARPPacket(ethernetFrame->hdr->payload)); break; default : break; @@ -66,20 +73,25 @@ class Packet { switch (ipPacket->packetType()) { - case 17 : udpPacket = new UDPPacket(ipPacket->payload()); + case 17 : //udpPacket = new UDPPacket(ipPacket->payload()); + udpPacket.reset(new UDPPacket(ipPacket->payload())); break; - case 6 : tcpPacket = new TCPPacket(ipPacket->payload()); + case 6 : //tcpPacket = new TCPPacket(ipPacket->payload()); + tcpPacket.reset(new TCPPacket(ipPacket->payload())); break; - case 1 : icmpPacket = new ICMPPacket(ipPacket->payload()); + case 1 : //icmpPacket = new ICMPPacket(ipPacket->payload()); + icmpPacket.reset(new ICMPPacket(ipPacket->payload())); break; default : break; } } if (udpPacket) { - if ((udpPacket->sourcePort() == 5353) || (udpPacket->destinationPort() == 5353)) + if (((udpPacket->sourcePort() == 5353) || (udpPacket->destinationPort() == 5353)) + || ((udpPacket->sourcePort() == 53) || (udpPacket->destinationPort() == 53))) { - dnsPacket = new DNSPacket(udpPacket->hdr->payload); +// dnsPacket = new DNSPacket(udpPacket->hdr->payload); + dnsPacket.reset(new DNSPacket(udpPacket->hdr->payload)); } } }; @@ -94,15 +106,16 @@ class Packet RAW }; - EthernetFrame* ethernetFrame = nullptr; - ARPPacket* arpPacket = nullptr; - IPv4Packet* ipv4Packet = nullptr; - IPv6Packet* ipv6Packet = nullptr; - IPPacket* ipPacket = nullptr; - UDPPacket* udpPacket = nullptr; - DNSPacket* dnsPacket = nullptr; - TCPPacket* tcpPacket = nullptr; - ICMPPacket* icmpPacket = nullptr; + std::unique_ptr ethernetFrame = nullptr; +// EthernetFrame* ethernetFrame = nullptr; + std::unique_ptr arpPacket = nullptr; + std::unique_ptr ipv4Packet = nullptr; + std::unique_ptr ipv6Packet = nullptr; + std::unique_ptr ipPacket = nullptr; + std::unique_ptr udpPacket = nullptr; + std::unique_ptr dnsPacket = nullptr; + std::unique_ptr tcpPacket = nullptr; + std::unique_ptr icmpPacket = nullptr; const uint8_t* rawData() const @@ -320,12 +333,12 @@ class Packet }; uint16_t getSrcPort() const { - return tcpPacket ? tcpPacket->sourcePort() : (udpPacket ? udpPacket->sourcePort() : 0); + // return tcpPacket ? tcpPacket->sourcePort() : (udpPacket ? udpPacket->sourcePort() : 0); return isIP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 0) : 0; } uint16_t getDstPort() const { - return tcpPacket ? tcpPacket->destinationPort() : (udpPacket ? udpPacket->destinationPort() : 0); + // return tcpPacket ? tcpPacket->destinationPort() : (udpPacket ? udpPacket->destinationPort() : 0); return isIP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 2) : 0; } bool hasPort(uint16_t p) const diff --git a/libraries/Netdump/src/structures.h b/libraries/Netdump/src/structures.h index 196aaa0dad..012fc26799 100644 --- a/libraries/Netdump/src/structures.h +++ b/libraries/Netdump/src/structures.h @@ -183,11 +183,13 @@ class IPv6Packet class IPPacket { public: - IPPacket(IPv4Packet* i4) : ip4(true), ipv4(i4) + IPPacket(std::unique_ptr& i4) : ip4(true) { + ipv4.reset(new IPv4Packet(i4->raw)); }; - IPPacket(IPv6Packet* i6) : ip4(false), ipv6(i6) + IPPacket(std::unique_ptr& i6) : ip4(false) { + ipv6.reset(new IPv6Packet(i6->raw)); }; union ipv4v6 @@ -199,8 +201,8 @@ class IPPacket ipv4v6 ht; bool ip4 = false; - IPv4Packet* ipv4 = nullptr; - IPv6Packet* ipv6 = nullptr; + std::unique_ptr ipv4 = nullptr; + std::unique_ptr ipv6 = nullptr; uint8_t packetType() { @@ -224,20 +226,6 @@ class IPPacket } }; -class IPPacket_1 : public IPv4Packet, public IPv6Packet -{ -public: - IPPacket_1(IPv4Packet* i4) : IPv4Packet(i4->raw), IPv6Packet(nullptr) - { - const uint8_t* raw = IPv4Packet::raw; - hdr = reinterpret_cast(IPv4Packet::raw); - } - const uint8_t* raw; - const IPv4Header* hdr; - - -}; - class TCPPacket { public: From 5803720e3f2769eed105007ac8066b3c68e9e19b Mon Sep 17 00:00:00 2001 From: hreintke Date: Mon, 8 Jun 2020 10:36:04 +0200 Subject: [PATCH 20/22] Add LLMR Improve mDNS printf --- libraries/Netdump/src/NetdumpIP.h | 20 ++++++++++-------- libraries/Netdump/src/NetdumpPacket.cpp | 28 ++++++++++++++++++++++--- libraries/Netdump/src/NetdumpPacket.h | 11 ++++++++-- libraries/Netdump/src/PacketType.cpp | 1 + libraries/Netdump/src/PacketType.h | 1 + libraries/Netdump/src/structures.h | 1 + 6 files changed, 48 insertions(+), 14 deletions(-) diff --git a/libraries/Netdump/src/NetdumpIP.h b/libraries/Netdump/src/NetdumpIP.h index 73b668ac3c..df28b1c5ed 100644 --- a/libraries/Netdump/src/NetdumpIP.h +++ b/libraries/Netdump/src/NetdumpIP.h @@ -54,6 +54,17 @@ class NetdumpIP { ipv = IPversion::UNSET; }; + + bool compareRaw(IPversion v, const uint8_t* a, const uint8_t* b) const; + bool compareIP(const IPAddress& ip) const; + bool compareIP(const NetdumpIP& nip) const; + + bool fromString4(const char *address); + bool fromString6(const char *address); + + size_t printTo(Print& p); +public: + bool isV4() const { return (ipv == IPversion::IPV4); @@ -71,15 +82,6 @@ class NetdumpIP return (ipv != IPversion::UNSET); }; - bool compareRaw(IPversion v, const uint8_t* a, const uint8_t* b) const; - bool compareIP(const IPAddress& ip) const; - bool compareIP(const NetdumpIP& nip) const; - - bool fromString4(const char *address); - bool fromString6(const char *address); - - size_t printTo(Print& p); -public: bool operator==(const IPAddress& addr) const { return compareIP(addr); diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index 12ea621903..72ba248e8c 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -91,6 +91,10 @@ void Packet::setPacketTypes() { setPacketType(PacketType::DNS); } + if (isLLMNR()) + { + setPacketType(PacketType::LLMNR); + } if (isSSDP()) { setPacketType(PacketType::SSDP); @@ -216,7 +220,15 @@ void Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const for (int i=0;iancount();i++) { DNSPacket::DNSAnswer da = dnsPacket->getAnswer(i); - sstr.printf(" R : %s IP : %s\r\n",da.name.c_str(),da.getIP().toString().c_str()); + sstr.printf(" R : %s TP : %d TTL : %d",da.name.c_str(),da.type,da.ttl); + if (da.getIP().isSet()) + { + sstr.printf(" IP : %s\r\n",da.getIP().toString().c_str()); + } + else + { + sstr.printf("\r\n"); + } } printDetail(sstr, PSTR(" H "), udpPacket->raw, udpPacket->hdrLength(), netdumpDetail); printDetail(sstr, PSTR(" D "), udpPacket->hdr->payload, udpPacket->length(), netdumpDetail); @@ -259,16 +271,25 @@ void Packet::ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const { if (!icmpPacket || !ipPacket) { - sstr.printf_P(PSTR("ICMPtoString access error\r\n")); + sstr.printf_P(PSTR("ICMPtoString access error icmp\r\n")); return; } - sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + if (!ipPacket) + { + sstr.printf_P(PSTR("ICMPtoString access error ip\r\n")); + return; + } + + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); if (isIPv4()) { switch (getIcmpType()) { case 0 : sstr.printf_P(PSTR("ping reply")); break; + case 3 : sstr.printf_P(PSTR("destination unreachable")); break; + case 5 : sstr.printf_P(PSTR("redirect")); break; case 8 : sstr.printf_P(PSTR("ping request")); break; + default: sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType()); break; } } @@ -357,6 +378,7 @@ const String Packet::toString(PacketDetail netdumpDetail) const } case PacketType::MDNS : case PacketType::DNS : + case PacketType::LLMNR: { DNStoString(netdumpDetail, sstr); break; diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h index 9b8d38939f..9c06451771 100644 --- a/libraries/Netdump/src/NetdumpPacket.h +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -79,7 +79,9 @@ class Packet case 6 : //tcpPacket = new TCPPacket(ipPacket->payload()); tcpPacket.reset(new TCPPacket(ipPacket->payload())); break; - case 1 : //icmpPacket = new ICMPPacket(ipPacket->payload()); + case 1 : + case 58 : + //icmpPacket = new ICMPPacket(ipPacket->payload()); icmpPacket.reset(new ICMPPacket(ipPacket->payload())); break; default : break; @@ -88,7 +90,8 @@ class Packet if (udpPacket) { if (((udpPacket->sourcePort() == 5353) || (udpPacket->destinationPort() == 5353)) - || ((udpPacket->sourcePort() == 53) || (udpPacket->destinationPort() == 53))) + || ((udpPacket->sourcePort() == 53) || (udpPacket->destinationPort() == 53)) + || ((udpPacket->sourcePort() == 5355) || (udpPacket->destinationPort() == 5355))) { // dnsPacket = new DNSPacket(udpPacket->hdr->payload); dnsPacket.reset(new DNSPacket(udpPacket->hdr->payload)); @@ -260,6 +263,10 @@ class Packet { return (isUDP() && hasPort(53)); }; + bool isLLMNR() const + { + return (isUDP() && hasPort(5355)); + } bool isSSDP() const { return (isUDP() && hasPort(1900)); diff --git a/libraries/Netdump/src/PacketType.cpp b/libraries/Netdump/src/PacketType.cpp index 1bebea68ec..bc56bfaad1 100644 --- a/libraries/Netdump/src/PacketType.cpp +++ b/libraries/Netdump/src/PacketType.cpp @@ -39,6 +39,7 @@ String PacketType::toString() const case PType::IGMP : return PSTR("IGMP"); case PType::IPv4: return PSTR("IPv4"); case PType::IPv6: return PSTR("IPv6"); + case PType::LLMNR: return PSTR("LLMR"); case PType::UKNW : return PSTR("UKNW"); default : return PSTR("ERR"); }; diff --git a/libraries/Netdump/src/PacketType.h b/libraries/Netdump/src/PacketType.h index b6fb1db611..d6a10340ae 100644 --- a/libraries/Netdump/src/PacketType.h +++ b/libraries/Netdump/src/PacketType.h @@ -35,6 +35,7 @@ class PacketType IGMP, IPv4, IPv6, + LLMNR, UKNW, }; diff --git a/libraries/Netdump/src/structures.h b/libraries/Netdump/src/structures.h index 012fc26799..175cbf3610 100644 --- a/libraries/Netdump/src/structures.h +++ b/libraries/Netdump/src/structures.h @@ -512,6 +512,7 @@ class DNSPacket std::tie(n,p) = qName(answerPtr); // c++17 : auto [n,p] = qName(questionPtr); da.name = n; da.type = NetdumpUtils::ntoh16(p); + da.ttl = NetdumpUtils::ntoh32(p+4); da.rdlength = NetdumpUtils::ntoh16(p+8); uint16_t next = NetdumpUtils::ntoh16(p+8)+10; da.rdata = p+10; From a0f1e5a4fdfa7042bbad9de8312640a124acd5de Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 12 Aug 2020 20:02:25 +0200 Subject: [PATCH 21/22] use LittleFS SPIFFS is deprecated --- libraries/Netdump/examples/Netdump/Netdump.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/Netdump/examples/Netdump/Netdump.ino b/libraries/Netdump/examples/Netdump/Netdump.ino index 385438bf02..e1476a4028 100644 --- a/libraries/Netdump/examples/Netdump/Netdump.ino +++ b/libraries/Netdump/examples/Netdump/Netdump.ino @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include using namespace NetCapture; @@ -19,8 +19,8 @@ const char* password = STAPSK; Netdump nd; -FS* filesystem = &SPIFFS; -//FS* filesystem = &LittleFS; +//FS* filesystem = &SPIFFS; +FS* filesystem = &LittleFS; ESP8266WebServer webServer(80); // Used for sending commands WiFiServer tcpServer(8000); // Used to show netcat option. From 9be3d1321eb7b7540957f3556d3456f2b2efe5a2 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 12 Aug 2020 20:14:50 +0200 Subject: [PATCH 22/22] fixed "unused parameter" --- libraries/Netdump/src/NetdumpPacket.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp index 86782dd921..2f9da6df93 100644 --- a/libraries/Netdump/src/NetdumpPacket.cpp +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -230,7 +230,7 @@ void Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); } -void Packet::ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +void Packet::ICMPtoString(PacketDetail, StreamString& sstr) const { sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); if (isIPv4()) @@ -256,7 +256,7 @@ void Packet::ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const sstr.printf("\r\n"); } -void Packet::IGMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +void Packet::IGMPtoString(PacketDetail, StreamString& sstr) const { switch (getIgmpType()) { @@ -284,7 +284,7 @@ void Packet::IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen()], getIpTotalLen() - getIpHdrLen(), netdumpDetail); } -void Packet::UKNWtoString(PacketDetail netdumpDetail, StreamString& sstr) const +void Packet::UKNWtoString(PacketDetail, StreamString& sstr) const { sstr.printf_P(PSTR("Unknown EtherType 0x%04x Src : "), ethType()); MACtoString(0, sstr); pFad - Phonifier reborn

    Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

    Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


    Alternative Proxies:

    Alternative Proxy

    pFad Proxy

    pFad v3 Proxy

    pFad v4 Proxy