Skip to content

Netdump library #6518

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
694732f
Netdump library, initial commit
hreintke Sep 14, 2019
c9ce6e8
Merge branch 'master' into NetdumpLibrary
earlephilhower Oct 1, 2019
d17f83d
Const update
hreintke Nov 12, 2019
b1912a8
Merge branch 'NetdumpLibrary' of https://github.com/hreintke/Arduino …
hreintke Nov 12, 2019
da5307f
Cleanup, added example
hreintke Nov 12, 2019
9545dd3
Example should start Serial by default.
hreintke Nov 12, 2019
11426ee
Further cleanup
hreintke Nov 13, 2019
9915230
Add PacketType & restructure printing using that
hreintke Nov 15, 2019
a3e83f6
Updates relating to @devyte comments
hreintke Nov 17, 2019
eea5caa
update pcap header writing & adding consts
hreintke Nov 18, 2019
d15f9d9
Improve NetdumpPacket type testing and content retrieval
hreintke Nov 18, 2019
de46b48
Updates related to remarks
hreintke Nov 18, 2019
e7886ce
Merge branch 'master' into NetdumpLibrary
hreintke Nov 21, 2019
f05a6f3
Restructure PacketType
hreintke Nov 24, 2019
328f240
Restructure printing, add PacketDetail::RAW
hreintke Nov 24, 2019
a5b3ad7
Fix printing
hreintke Nov 25, 2019
6f4fb0c
Use CallbackList to facilitate multiple Netdump instances
hreintke Nov 26, 2019
112c039
Separate commit to show update on experimental CallbackList
hreintke Dec 5, 2019
4f099cb
Further cleanup
hreintke Dec 5, 2019
3d41d25
Style update and small changes
hreintke May 3, 2020
1b77c97
wip
hreintke May 24, 2020
4398807
Merge branch 'master' into NetdumpLibrary
hreintke May 24, 2020
d1a142b
Use std::unique_ptr to prevent memory leak
hreintke May 27, 2020
5803720
Add LLMR
hreintke Jun 8, 2020
89485e8
Merge branch 'master' into NetdumpLibrary
d-a-v Aug 12, 2020
a0f1e5a
use LittleFS
d-a-v Aug 12, 2020
8e72ecb
Merge branch 'master' into NetdumpLibrary
d-a-v Aug 12, 2020
9be3d13
fixed "unused parameter"
d-a-v Aug 12, 2020
5cdee28
Merge branch 'NetdumpLibrary' of https://github.com/hreintke/Arduino …
hreintke Aug 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
wip
  • Loading branch information
hreintke committed May 24, 2020
commit 1b77c97240519972468325e8588e008201d16e44
32 changes: 0 additions & 32 deletions libraries/Netdump/astyle_goodies.conf

This file was deleted.

109 changes: 103 additions & 6 deletions libraries/Netdump/src/Netdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,35 @@
#include "Netdump.h"
#include <lwip/init.h>
#include "Schedule.h"

#include "sdk_structs.h"
#include "ieee80211_structs.h"
#include "string_utils.h"

namespace NetCapture
{

CallBackList<Netdump::LwipCallback> Netdump::lwipCallback;
CallBackList<Netdump::WifiCallback> Netdump::wifiCallback;

Netdump::Netdump()
Netdump::Netdump(interface ifc)
{
using namespace std::placeholders;
phy_capture = capture;
lwipHandler = lwipCallback.add(std::bind(&Netdump::netdumpCapture, this, _1, _2, _3, _4, _5));
using namespace std::placeholders;
if (ifc == interface::LWIP)
{
phy_capture = lwipCapture;
lwipHandler = lwipCallback.add(std::bind(&Netdump::netdumpCapture, this, _1, _2, _3, _4, _5));
}
else
{
wifi_set_opmode(STATION_MODE);
wifi_promiscuous_enable(0);
WiFi.disconnect();
wifi_set_promiscuous_rx_cb(wifiCapture);
wifi_set_channel(6);
wifi_promiscuous_enable(1);
Serial.write("Prom mode\r\n");
wifiHandler = wifiCallback.add(std::bind(&Netdump::wifidumpCapture,this, _1, _2));
}
};

Netdump::~Netdump()
Expand Down Expand Up @@ -99,7 +116,7 @@ void Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf)
});
}

void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int success)
void Netdump::lwipCapture(int netif_idx, const char* data, size_t len, int out, int success)
{
if (lwipCallback.execute(netif_idx, data, len, out, success) == 0)
{
Expand All @@ -120,6 +137,86 @@ void Netdump::netdumpCapture(int netif_idx, const char* data, size_t len, int ou
}
}

void Netdump::wifiCapture(unsigned char* data, uint16_t len)
{
wifiCallback.execute(reinterpret_cast<const char*>(data),len);
}

void Netdump::wifidumpCapture(const char* buff, uint16_t len)
{
// netdumpCapture(0, data, len, 0, 1);

// First layer: type cast the received buffer into our generic SDK structure
const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;
// Second layer: define pointer to where the actual 802.11 packet is within the structure
const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload;
// Third layer: define pointers to the 802.11 packet header and payload
const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr;
const uint8_t *data = ipkt->payload;

// Pointer to the frame control section within the packet header
const wifi_header_frame_control_t *frame_ctrl = (wifi_header_frame_control_t *)&hdr->frame_ctrl;
// Parse MAC addresses contained in packet header into human-readable strings
char addr1[] = "00:00:00:00:00:00\0";
char addr2[] = "00:00:00:00:00:00\0";
char addr3[] = "00:00:00:00:00:00\0";

mac2str(hdr->addr1, addr1);
mac2str(hdr->addr2, addr2);
mac2str(hdr->addr3, addr3);

// Output info to serial
// if (!(frame_ctrl->type == WIFI_PKT_MGMT && frame_ctrl->subtype == BEACON))
if ((frame_ctrl->type == WIFI_PKT_DATA))
Serial.printf("\r\n%s | %s | %s | %u | %02d | %u | %u(%-2u) | %-28s | %u | %u | %u | %u | %u | %u | %u | %u | ",
addr1,
addr2,
addr3,
wifi_get_channel(),
ppkt->rx_ctrl.rssi,
frame_ctrl->protocol,
frame_ctrl->type,
frame_ctrl->subtype,
wifi_pkt_type2str((wifi_promiscuous_pkt_type_t)frame_ctrl->type, (wifi_mgmt_subtypes_t)frame_ctrl->subtype),
frame_ctrl->to_ds,
frame_ctrl->from_ds,
frame_ctrl->more_frag,
frame_ctrl->retry,
frame_ctrl->pwr_mgmt,
frame_ctrl->more_data,
frame_ctrl->wep,
frame_ctrl->strict);
if (frame_ctrl->type == WIFI_PKT_DATA)
{
Serial.printf("\r\nData %04x",frame_ctrl->subtype);
}
// Print ESSID if beacon
/*
if (frame_ctrl->type == WIFI_PKT_MGMT && frame_ctrl->subtype == BEACON)
{
const wifi_mgmt_beacon_t *beacon_frame = (wifi_mgmt_beacon_t*) ipkt->payload;
char ssid[32] = {0};

if (beacon_frame->tag_length >= 32)
{
strncpy(ssid, beacon_frame->ssid, 31);
}
else
{
strncpy(ssid, beacon_frame->ssid, beacon_frame->tag_length);
}

Serial.printf("%s", ssid);
}
*/
}

/*
uint32_t timestamp = now(); //current timestamp
uint32_t microseconds = (unsigned int)(micros() - millis() * 1000); //micro seconds offset (0 - 999)
pcap.newPacketSerial(timestamp, microseconds, len, buf); //write packet to file
*/

void Netdump::writePcapHeader(Stream& s) const
{
uint32_t pcapHeader[6];
Expand Down
16 changes: 14 additions & 2 deletions libraries/Netdump/src/Netdump.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,15 @@ class Netdump
using Filter = std::function<bool(const Packet&)>;
using Callback = std::function<void(const Packet&)>;
using LwipCallback = std::function<void(int, const char*, int, int, int)>;
using WifiCallback = std::function<void(const char*, int)>;

Netdump();
enum class interface
{
LWIP,
WIFI
};

Netdump(interface ifc = interface::WIFI);
~Netdump();

void setCallback(const Callback nc);
Expand All @@ -60,11 +67,16 @@ class Netdump
Callback netDumpCallback = nullptr;
Filter netDumpFilter = nullptr;

static void capture(int netif_idx, const char* data, size_t len, int out, int success);
static void lwipCapture(int netif_idx, const char* data, size_t len, int out, int success);
static void wifiCapture(unsigned char* data, uint16_t len);
static CallBackList<LwipCallback> lwipCallback;
CallBackList<LwipCallback>::CallBackHandler lwipHandler;
static CallBackList<WifiCallback> wifiCallback;
CallBackList<WifiCallback>::CallBackHandler wifiHandler;


void netdumpCapture(int netif_idx, const char* data, size_t len, int out, int success);
void wifidumpCapture(const char* data, uint16_t len);

void printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) const;
void fileDumpProcess(File& outfile, const Packet& np) const;
Expand Down
75 changes: 48 additions & 27 deletions libraries/Netdump/src/NetdumpPacket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
namespace NetCapture
{

void Packet::printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const
void Packet::printDetail(Print& out, const String& indent, const uint8_t* data, size_t size, PacketDetail pd) const
{
if (pd == PacketDetail::NONE)
{
Expand Down Expand Up @@ -149,70 +149,86 @@ const std::vector<PacketType> Packet::allPacketTypes() const
return thisAllPacketTypes;
}

void Packet::MACtoString(int dataIdx, StreamString& sstr) const
void Packet::MACtoString(const uint8_t* mac, StreamString& sstr) const
{
for (int i = 0; i < 6; i++)
{
sstr.printf_P(PSTR("%02x"), (unsigned char)data[dataIdx + i]);
sstr.printf_P(PSTR("%02x"), mac[i]);
if (i < 5)
{
sstr.print(':');
}
}

}

void Packet::ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
{
switch (getARPType())
if (!arpPacket)
{
sstr.printf_P(PSTR("ARPtoString access error\r\n"));
return;
}
switch (arpPacket->opcode())
{
case 1 : sstr.printf_P(PSTR("who has %s tell %s"), getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str());
case 1 : sstr.printf_P(PSTR("who has %s tell %s"), arpPacket->targetIP().toString().c_str(), arpPacket->senderIP().toString().c_str());
break;
case 2 : sstr.printf_P(PSTR("%s is at "), getIP(ETH_HDR_LEN + 14).toString().c_str());
MACtoString(ETH_HDR_LEN + 8, sstr);
case 2 : sstr.printf_P(PSTR("%s is at "), arpPacket->senderIP().toString().c_str());
MACtoString(arpPacket->hdr->senderHardwareAddress, sstr);
break;
}
sstr.printf("\r\n");
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN], packetLength - ETH_HDR_LEN, netdumpDetail);
printDetail(sstr, PSTR(" D "), arpPacket->raw, packetLength - ETH_HDR_LEN, netdumpDetail);
}

void Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const
{
sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str());
sstr.printf_P(PSTR("ID=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8));
sstr.printf_P(PSTR("F=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 2));
if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 4))
if (!dnsPacket || !udpPacket || !ipPacket)
{
sstr.printf_P(PSTR("DNStoString access error\r\n"));
return;
}
sstr.printf_P(PSTR("%s>%s "), ipPacket->sourceIP().toString().c_str(), ipPacket->destinationIP().toString().c_str());
sstr.printf_P(PSTR("ID=0x%04x "), dnsPacket->id());
sstr.printf_P(PSTR("F=0x%04x "), dnsPacket->flags());

if (uint16_t t = dnsPacket->qdcount())
{
sstr.printf_P(PSTR("Q=%d "), t);
}
if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 6))
if (uint16_t t = dnsPacket->ancount())
{
sstr.printf_P(PSTR("R=%d "), t);
}
if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 8))
if (uint16_t t = dnsPacket->nscount())
{
sstr.printf_P(PSTR("TR=%d "), t);
}
if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 10))
if (uint16_t t = dnsPacket->arcount())
{
sstr.printf_P(PSTR("DR=%d "), t);
}

sstr.printf_P(PSTR("\r\n"));
printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail);
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail);
printDetail(sstr, PSTR(" H "), udpPacket->raw, udpPacket->hdrLength(), netdumpDetail);
printDetail(sstr, PSTR(" D "), udpPacket->hdr->payload, udpPacket->length(), netdumpDetail);
}

void Packet::UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
{
sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str());
sstr.printf_P(PSTR("%d:%d"), getSrcPort(), getDstPort());
sstr.printf_P(PSTR("\r\n"));
printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail);
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail);
printDetail(sstr, PSTR(" H "), udpPacket->raw, getUdpHdrLen(), netdumpDetail);
printDetail(sstr, PSTR(" D "), udpPacket->hdr->payload, getUdpLen(), netdumpDetail);
}

void Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
{
if (!tcpPacket)
{
sstr.printf_P(PSTR("TCPtoString access error\r\n"));
return;
}
sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str());
sstr.printf_P(PSTR("%d:%d "), getSrcPort(), getDstPort());
uint16_t flags = getTcpFlags();
Expand All @@ -226,12 +242,17 @@ void Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
sstr.print(']');
sstr.printf_P(PSTR(" len: %u seq: %u, ack: %u, wnd: %u "), getTcpLen(), getTcpSeq(), getTcpAck(), getTcpWindow());
sstr.printf_P(PSTR("\r\n"));
printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail);
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail);
printDetail(sstr, PSTR(" H "), tcpPacket->raw, getTcpHdrLen(), netdumpDetail);
printDetail(sstr, PSTR(" D "), tcpPacket->hdr->payload, getTcpLen(), netdumpDetail);
}

void Packet::ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
{
if (!icmpPacket || !ipPacket)
{
sstr.printf_P(PSTR("ICMPtoString access error\r\n"));
return;
}
sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str());
if (isIPv4())
{
Expand Down Expand Up @@ -280,16 +301,16 @@ void Packet::IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
{
sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str());
sstr.printf_P(PSTR("Unknown IP type : %d\r\n"), ipType());
printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN], getIpHdrLen(), netdumpDetail);
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen()], getIpTotalLen() - getIpHdrLen(), netdumpDetail);
printDetail(sstr, PSTR(" H "), ipPacket->raw(), getIpHdrLen(), netdumpDetail);
printDetail(sstr, PSTR(" D "), ipPacket->raw(), getIpTotalLen() - getIpHdrLen(), netdumpDetail);
}

void Packet::UKNWtoString(PacketDetail netdumpDetail, StreamString& sstr) const
{
sstr.printf_P(PSTR("Unknown EtherType 0x%04x Src : "), ethType());
MACtoString(0, sstr);
MACtoString(rawData(), sstr);
sstr.printf_P(PSTR(" Dst : "));
MACtoString(6, sstr);
MACtoString(rawData()+6, sstr);
sstr.printf_P(PSTR("\r\n"));
}

Expand All @@ -314,7 +335,7 @@ const String Packet::toString(PacketDetail netdumpDetail) const
sstr.printf_P(PSTR("%s "), at.toString().c_str());
}
sstr.printf_P(PSTR("\r\n"));
printDetail(sstr, PSTR(" D "), data, packetLength, netdumpDetail);
printDetail(sstr, PSTR(" D "), rawData(), packetLength, netdumpDetail);
return sstr;
}

Expand Down
Loading
pFad - Phonifier reborn

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

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


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy