From 694732f20362c554cba3981dd6e35b6aa300cf53 Mon Sep 17 00:00:00 2001 From: hreintke Date: Sat, 14 Sep 2019 16:05:56 +0200 Subject: [PATCH 01/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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 */