cancel
Showing results for 
Search instead for 
Did you mean: 

Get AUTOIP working on lwIP

Spaghetto
Associate III

Hello forum,
I'm working in STM32CubeIDE with the STM32F107VCT6 on a custom board which successfully run a TCP Server application using Ethernet communication + FREERTOS + lwIP and I'm struggling in enabling AUTOIP feature.

My custom board need to be IP assigned if working in a network ...where a DHCP server exist, but also in a personal network (e.g. LAN cable connected from the board straight to the PC LAN Port)...where a DHCP server does not exist. Premise that DHCP if correctly working in the first scenario, I can't get the second one working.

Since switching dinamically to a static IP is not a good solution (I can't elect a static IP beforehand and...I'm freightened about doing this with lwIP) I was triggered by a forum post by LCE (here) talking of AUTOIP as solution, I've google around the web for lwIP AUTOIP feature but noone is talking about it or giving working examples, then my attempts follow below.

In STM32CubeIDE I've flagged:
General Settings > IPv4-DHCP Options > LWIP_AUTOIP (AUTOIP Module) > Enabled
Key Options > IPv4 - AUTOIP Options > LWIP_AUTOIP (AUTOIP Module) > Enabled
... > LWIP_DHCP_AUTOIP_COOP (DHCP/AUTOIP Cooperation Mode) > Enabled
...> LWIP_DHCP_AUTOIP_COOP_TRIES (DHCP AUTOIP Coop Tries) > 9 (...default value)

In lwipopts.h I correctly get:

 

 

/*----- Value in opt.h for LWIP_DHCP: 0 -----*/
#define LWIP_DHCP 1
//...
/*----- Default Value for LWIP_AUTOIP: 0 ---*/
#define LWIP_AUTOIP 1
/*----- Default Value for LWIP_DHCP_AUTOIP_COOP: 0 ---*/
#define LWIP_DHCP_AUTOIP_COOP 1

 

 

I set on the PC a static ip as follow:

Spaghetto_0-1707839941953.png

Then, I expect, when connecting the board to the PC something to show up in the AUTOIP ip range: 169.254.x.y
But.. "arp -a" don't show nothing...

Is the code not working, missing something or is me missing how detect the card?

Thanks

 

 

7 REPLIES 7
LCE
Principal

Don't know about MX, but I have it up and running.

Indeed a great help when connecting directly to a laptop without DHCP server capabilities.

See attached files how I use it.

I had to add 

#include "lwip/apps/netbiosns.h"

in LWIP/App/lwip.h

And LWIP_AUTOIP is enabled somewhere in

..\Middlewares\Third_Party\LwIP\src\include\lwip\opt.h

Pavel A.
Evangelist III

@Spaghetto Do you connect the board and PC with a cross cable or use a hub? Can you confirm that the LwIP and ETH init and start run to the end successfully, LwIP sees the cable connected and the interface comes UP? What is the APIPA address assigned to the board?

Spaghetto
Associate III

Oh Wireshark, how many times have you saved my ass since my youth?

Thank you both for you answers, LCE for pointing out this wonderful solution to the no-dhcp problem (I'm working for Automatic Test Equipments who are big racks full of instrumentation connected via LAN to a PC, everithing is set as static ip and no dhcp server is present), and Pavel to get me back to a lower level debug: the AUTOIP function is working flawlessly, it has always been. Let me explain with a Wireshark dump:

Spaghetto_0-1707900462585.jpeg

Look the 9 "LWIP_DHCP_AUTOIP_COOP_TRIES", look the 244 seconds (!!!) needed before the AUTOIP take place after the DHCP discover and broadcasts an arp probe with the pseudo generated ip. It was just taking too much time, I wasn't discovering it in the pc arp table because I was checking it too early.

Changing in STM32CubeIDE I've flagged:
Key Options > IPv4 - AUTOIP Options > LWIP_DHCP_AUTOIP_COOP_TRIES (DHCP AUTOIP Coop Tries) > 3

I can easily get, after just 10 seconds, the target ip in the command line "arp -a" answer.

Thanks

 

LCE
Principal

Ah, I think that's why I reduced my own DHCP timeout / number of retries, because I didn't want to wait that long. 
So in my application right now I think I quit DHCP process after only a few tries / seconds.

Spaghetto
Associate III

Sadly I celebrated too early.

Yes, the autoip function is working correctly, but, since the board is a TCP Server (and not a Client), it has to be discovered over the network, and "arp -a" will show the IP up only after communicating with the board (e.g. pinging, as I did in the last post without noticing!). So I can't just look from the scratch into the arp table to trace back the ip (here is a nice explanation), since sniffing over the network is not an option in the real life scenario the fastest ways is scanning the network with pings.

Then I used the fastest ip scanner I know, nmap, and look into the link-local ip range and this is what I got:

nmap -sn 169.254.0.0/16

Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-15 10:26 ora solare Europa occidentale
Nmap scan report for 169.254.67.0
Host is up (0.0061s latency).
MAC Address: 00:80:E1:00:00:42 (STMicroelectronics SRL)
Nmap scan report for 169.254.167.183
Host is up.
Nmap done: 65536 IP addresses (2 hosts up) scanned in 2563.93 seconds

Yes I discovered the board ip (169.254.67.0) but it took 43 min!!! It's clear that autoip function is usefull when the board is a client one (so it doesn't need to be targeted by other clients=>the ip doesn't need to be known beforehand) but this is not the case.

Am I correct? Does exist a better solution to this? Eg. forcing the APIPA to smaller range than 169.254.0.0/16 or to a single IP? The more I think about it, the better I convince myself that the best chance is a switch from DHCP to static after n tries, is there a quick way to do this enabling something in lwIP? I know I'm a dreamer....

LG

LCE
Principal

Interesting!

So you need the auto-detection from the PC side, I didn't get that.

The more I think about it, the better I convince myself that the best
> chance is a switch from DHCP to static after n tries, is there a quick
> way to do this enabling something in lwIP?

I think not, but it's not that hard - I think...

Check my dhcp_user.c file, there's a state where fixed IP address is assigned after AUTOIP fails (after DHCP fails).

But that didn't occur for some time in my setup, so I don't know if it works.

Spaghetto
Associate III

Ok let's get the hand dirty!

Modifying AUTOIP Range

Digging in the lwIP Middleware dumped in the project by the STM32CubeIDE automatic code generator, the range is cleverly defined in /Middlewares/Third_Party/LwIP/src/include/lwip/prot/autoip.h (see code below).

 

/* 169.254.0.0 */
#define AUTOIP_NET              0xA9FE0000
/* 169.254.1.0 */
#define AUTOIP_RANGE_START      (AUTOIP_NET | 0x0100)
/* 169.254.254.255 */
#define AUTOIP_RANGE_END        (AUTOIP_NET | 0xFEFF)

 

I've abandoned this way because it will need anyway the client to scan the network, as we already discussed, and an hostname is useless as well (a DNS does not exist!), but it could be a potential solution setting:

AUTOIP_NET=0xC0A80101 (192.168.1.1)
AUTOIP_RANGE_START=0x02 (192.168.1.2)
AUTOIP_RANGE_END=0xFF (192.168.1.255),

but I haven't checked it!

Switch from DHCP to static IP

A static IP switch to me is the best solution since, if a DHCP server exist, you can reach it in a straightforward way by hostname, if not you can reach it by a predefined IP (and maybe change it later at runtime storing it permanently in the flash, for future connection). The downside? A user code section doesn't exist in the lwIP Middleware so any future code generation will overwrite the user code...

Given that I'm really not into FW (I'm an HW Eng into R&D carrying out a proof-of-concept), the quick and dirty solution I've found cat&pasting your code @LCE is the following (code attached):

/Middlewares/Third_Party/LwIP/src/core/ipv4/dhcp.c

 

#if LWIP_DHCP_AUTOIP_COOP //ACTUALLY DISABLED!
  if (dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) {
    dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON;
    autoip_start(netif);
  }
#endif /* LWIP_DHCP_AUTOIP_COOP */

  if (dhcp->tries >= 4) { //TODO Turn off DHCP and switch to static IP
	  ip_addr_t ipaddr, netmask, gateway;
	  IP_ADDR4(&ipaddr, 192, 168, 1, 42);
	  IP_ADDR4(&netmask, 255, 255, 255, 0);
	  IP_ADDR4(&gateway, 192, 168, 1, 1);
	  netif_set_addr(netif, &ipaddr, &netmask, &gateway);
	  dhcp_stop(netif);
  }

 

I hooked the code right after the (disabled) section of where would start the autoip function, catching the dhcp re-tries, setting the static ip (forgive me the hard coded values, I'll change to memory stored one in the final code), stopping the dhcp.

As you can see below, it works as expected (rown1-4), I'm still working on it because I want to DHCP run again when disconnecting and reconnecting the cable, actually stick again on the static IP (row 5) without a new dhcp attempt. :\ Any hint?

static switch.JPG

Thanks for your precious support