Skip to content
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

Add AsyncUDP and simple NetBIOS name lookup server #2234

Merged
merged 2 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
uses: codespell-project/actions-codespell@master
with:
skip: ./ArduinoCore-API,./libraries/ESP8266SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api,./libraries/FreeRTOS,./tools/libbearssl/bearssl,./include,./libraries/WiFi/examples/BearSSL_Server,./ota/uzlib,./libraries/http-parser/lib,./libraries/WebServer/examples/HelloServerBearSSL/HelloServerBearSSL.ino,./libraries/HTTPUpdateServer/examples/SecureBearSSLUpdater/SecureBearSSLUpdater.ino,./.git,./libraries/FatFS/lib/fatfs,./libraries/FatFS/src/diskio.h,./libraries/FatFS/src/ff.cpp,./libraries/FatFS/src/ffconf.h,./libraries/FatFS/src/ffsystem.cpp,./libraries/FatFS/src/ff.h,./libraries/lwIP_WINC1500/src/driver,./libraries/lwIP_WINC1500/src/common,./libraries/lwIP_WINC1500/src/bus_wrapper,./libraries/lwIP_WINC1500/src/spi_flash
ignore_words_list: ser,dout,shiftIn
ignore_words_list: ser,dout,shiftIn,acount

# Consistent style
astyle:
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@
[submodule "libraries/FatFS/lib/SPIFTL"]
path = libraries/FatFS/lib/SPIFTL
url = https://github.com/earlephilhower/SPIFTL.git
[submodule "libraries/AsyncUDP"]
path = libraries/AsyncUDP
url = https://github.com/earlephilhower/AsyncUDP.git
1 change: 1 addition & 0 deletions libraries/AsyncUDP
Submodule AsyncUDP added at dd32bf
37 changes: 37 additions & 0 deletions libraries/NetBIOS/examples/PicoW_NetBIOS/PicoW_NetBIOS.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Modified from the ESP32-NetBIOS example

#include <WiFi.h>
#include <NetBIOS.h>

#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

void setup() {
Serial.begin(115200);

// Connect to WiFi network
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");

// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

// Windows (and other OSes using WINS/NetBIOS resolution should now be able to find the device by name)
NBNS.begin("PicoW");
}

void loop() {}
25 changes: 25 additions & 0 deletions libraries/NetBIOS/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#######################################
# Syntax Coloring Map For ESPNBNS
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

NetBIOS KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

begin KEYWORD2

#######################################
# Instances (KEYWORD2)
#######################################

NBNS KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################
9 changes: 9 additions & 0 deletions libraries/NetBIOS/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=NetBIOS
version=2.0.0
author=Pablo@xpablo.cz
maintainer=Earle F. Philhower, III <earlephilhower@yahoo.com>
sentence=Enables NBNS (NetBIOS) name resolution.
paragraph=With this library you can connect to your ESP from Windows using a short name
category=Communication
url=http://www.xpablo.cz/?p=751#more-751
architectures=rp2040
141 changes: 141 additions & 0 deletions libraries/NetBIOS/src/NetBIOS.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#include "NetBIOS.h"
#include <functional>
#include <lwip/netif.h>

#define NBNS_PORT 137
#define NBNS_MAX_HOSTNAME_LEN 32

typedef struct {
uint16_t id;
uint8_t flags1;
uint8_t flags2;
uint16_t qcount;
uint16_t acount;
uint16_t nscount;
uint16_t adcount;
uint8_t name_len;
char name[NBNS_MAX_HOSTNAME_LEN + 1];
uint16_t type;
uint16_t clas;
} __attribute__((packed)) nbns_question_t;

typedef struct {
uint16_t id;
uint8_t flags1;
uint8_t flags2;
uint16_t qcount;
uint16_t acount;
uint16_t nscount;
uint16_t adcount;
uint8_t name_len;
char name[NBNS_MAX_HOSTNAME_LEN + 1];
uint16_t type;
uint16_t clas;
uint32_t ttl;
uint16_t data_len;
uint16_t flags;
uint32_t addr;
} __attribute__((packed)) nbns_answer_t;

static void _getnbname(const char *nbname, char *name, uint8_t maxlen) {
uint8_t b;
uint8_t c = 0;

while ((*nbname) && (c < maxlen)) {
b = (*nbname++ - 'A') << 4;
c++;
if (*nbname) {
b |= *nbname++ - 'A';
c++;
}
if (!b || b == ' ') {
break;
}
*name++ = b;
}
*name = 0;
}

static void append_16(void *dst, uint16_t value) {
uint8_t *d = (uint8_t *)dst;
*d++ = (value >> 8) & 0xFF;
*d++ = value & 0xFF;
}

static void append_32(void *dst, uint32_t value) {
uint8_t *d = (uint8_t *)dst;
*d++ = (value >> 24) & 0xFF;
*d++ = (value >> 16) & 0xFF;
*d++ = (value >> 8) & 0xFF;
*d++ = value & 0xFF;
}

void NetBIOS::_onPacket(AsyncUDPPacket &packet) {
if (packet.length() >= sizeof(nbns_question_t)) {
nbns_question_t *question = (nbns_question_t *)packet.data();
if (0 == (question->flags1 & 0x80)) {
char name[NBNS_MAX_HOSTNAME_LEN + 1];
_getnbname(&question->name[0], (char *)&name, question->name_len);
if (_name.equals(name)) {
nbns_answer_t nbnsa;
nbnsa.id = question->id;
nbnsa.flags1 = 0x85;
nbnsa.flags2 = 0;
append_16((void *)&nbnsa.qcount, 0);
append_16((void *)&nbnsa.acount, 1);
append_16((void *)&nbnsa.nscount, 0);
append_16((void *)&nbnsa.adcount, 0);
nbnsa.name_len = question->name_len;
memcpy(&nbnsa.name[0], &question->name[0], question->name_len + 1);
append_16((void *)&nbnsa.type, 0x20);
append_16((void *)&nbnsa.clas, 1);
append_32((void *)&nbnsa.ttl, 300000);
append_16((void *)&nbnsa.data_len, 6);
append_16((void *)&nbnsa.flags, 0);
nbnsa.addr = packet.localIP(); // Wrong, but better than nothing
// Iterate over all netifs, see if the incoming address matches one of the netmaskes networks
// TODO - is there an easier way of seeing whicn netif produced a packet?
for (auto netif = netif_list; netif; netif = netif->next) {
auto maskedip = ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif));
auto maskedin = ((uint32_t)packet.localIP()) & ip4_addr_get_u32(netif_ip4_netmask(netif));
if (maskedip == maskedin) {
nbnsa.addr = ip4_addr_get_u32(netif_ip4_addr(netif));
break;
}
}
_udp.writeTo((uint8_t *)&nbnsa, sizeof(nbnsa), packet.remoteIP(), NBNS_PORT);
}
}
}
}

NetBIOS::NetBIOS() {}

NetBIOS::~NetBIOS() {
end();
}

bool NetBIOS::begin(const char *name) {
_name = name;
_name.toUpperCase();

if (_udp.connected()) {
return true;
}

_udp.onPacket(
[](void *arg, AsyncUDPPacket & packet) {
((NetBIOS *)(arg))->_onPacket(packet);
},
this
);
return _udp.listen(NBNS_PORT);
}

void NetBIOS::end() {
if (_udp.connected()) {
_udp.close();
}
}

NetBIOS NBNS;
21 changes: 21 additions & 0 deletions libraries/NetBIOS/src/NetBIOS.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//

#pragma once

#include <Arduino.h>
#include <AsyncUDP.h>

class NetBIOS {
protected:
AsyncUDP _udp;
String _name;
void _onPacket(AsyncUDPPacket &packet);

public:
NetBIOS();
~NetBIOS();
bool begin(const char *name);
void end();
};

extern NetBIOS NBNS;
2 changes: 1 addition & 1 deletion tests/restyle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ for dir in ./cores/rp2040 ./libraries/EEPROM ./libraries/I2S ./libraries/SingleF
./libraries/lwIP_w5500 ./libraries/lwIP_w5100 ./libraries/lwIP_enc28j60 \
./libraries/SPISlave ./libraries/lwIP_ESPHost ./libraries/FatFS\
./libraries/FatFSUSB ./libraries/BluetoothAudio ./libraries/BluetoothHCI \
./libraries/BluetoothHIDMaster; do
./libraries/BluetoothHIDMaster ./libraries/NetBIOS; do
find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" \) -a \! -path '*api*' -exec astyle --suffix=none --options=./tests/astyle_core.conf \{\} \;
find $dir -type f -name "*.ino" -exec astyle --suffix=none --options=./tests/astyle_examples.conf \{\} \;
done
Expand Down