PlatformIO Community

Add new layer 2 protocol support / Set ip address on device

Looking at how I can find esp32 (olimex PoE) board on a wired network without dhcp and then set its ip address.

Many IP Cameras support this and it would appear that it can be done by using another ethertype and then sending out a broadcast packet and receiving responses. Happy with what I need to do but have not managed to track down the right place to add support.

I had assumed that lwip raw would be available but seems not to be the case with esp32.

Has anyone done anything similar, pointers to ready-made solution! or any idea how I can intercept in this way?



They really send a different ethertype in the Ethernet layer? But if you say they talk IP, the layer above Ethernet has to be IP though and thus have 0x0800 (IPv4) as ethertype? But then how could any other network device recognize these packets as IP packets if the ethertype is wrong?

Are you 100% sure on this one?

It is btw. The default LWIP config in ESP-IDF is

Has LWIP_RAW enabled with 16 PCBs buffers available.

Since the Arduino-ESP32 derives from a precompiled ESP-IDF base, I assume it has the same LWIP config and thus RAW support.

Max, you made me think, just being wire-sharking an onvif camera, it might be they use WS-Discovery which is multicast UDP

On the raw side of things I was digging through the espressif site and found this

## Netconn API

lwIP supports two lower level APIs as well as the BSD Sockets API: the Netconn API and the Raw API.

The lwIP Raw API is designed for single threaded devices and is not supported in ESP-IDF.

Assuming that is right this may be tricky.

Ehm I’m not a 100% a lwIP expert but there might be a difference between a raw socket and the RAW API vs the Netconn API, with which connections are managed and interacted with in lwip.

Because this code compiles perfectly fine.

#include <Arduino.h>
#include "lwip/raw.h"
#include "lwip/ip_addr.h"

static u8_t
ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr)
    return 1; /* eat the packet */

void setup() {
  struct raw_pcb* ping_pcb = raw_new(IP_PROTO_ICMP);
  raw_recv(ping_pcb, ping_recv, NULL);
  raw_bind(ping_pcb, IP_ADDR_ANY);

void loop() {


platform = espressif32
board = esp32dev
framework = arduino

(partly taken from the ICMP / ping code in ESP-IDF, which acts on RAW sockets to handle a different protocol above the IP layer)

However if that’s not what is needed for that camera system it’s of no interest anyways. Reading up in shows that there is UDP multicast discovery at least involved? But then discovery tools like clearly show ONVIV devices having a e.g. HTTP endpoint.

Do you happen to have a Wireshark pcap(ng) dump of the camera traffic? That should very clearly show how the camera transmits its data.

the wireshark shows some broadcast udp which seems to contain some soap/xml

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="" xmlns:SOAP-ENC="" xmlns:wsa="" xmlns:wsdd="" xmlns:tdn="" >

`<SOAP-ENV:Header><wsa:MessageID>uuid:0009cddf-cddf-ea33-df33-e0629008579b</wsa:MessageID><wsa:To SOAP-ENV:mustUnderstand="true">urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To><wsa:Action SOAP-ENV:mustUnderstand="true"></wsa:Action><wsdd:AppSequence MessageNumber="1" InstanceId="1420070401"></wsdd:AppSequence></SOAP-ENV:Header><SOAP-ENV:Body><wsdd:Hello><wsa:EndpointReference><wsa:Address>uuid:0009cddf-cddf-ea33-df33-e0629008579b</wsa:Address></wsa:EndpointReference><wsdd:Types>tdn:NetworkVideoTransmitter</wsdd:Types><wsdd:Scopes>onvif:// onvif:// onvif:// onvif:// onvif:// onvif:// onvif:// </wsdd:Scopes><wsdd:XAddrs></wsdd:XAddrs><wsdd:MetadataVersion>1</wsdd:MetadataVersion></wsdd:Hello></SOAP-ENV:Body></SOAP-ENV:Envelope>`

So looking at UDP now, have got multicast udp working on the ssdp setup,
now sending packets and see them on wireshark even if the ip address is out of subnet, and seeing out of subnet packets on the esp32 so should be able to knock something together

thanks for setting me straight!