ARMmbed / mbed-os

Arm Mbed OS is a platform operating system designed for the internet of things
https://mbed.com
Other
4.68k stars 2.99k forks source link

Adding setstackopt, etc to the Networking library #3163

Closed Neuromancer2701 closed 7 years ago

Neuromancer2701 commented 8 years ago

Description

Reason to enhance or problem with existing solution I need broadcast, multicast and maybe unicast options.

Suggested enhancement I can't find any documentation on how this stack is implemented. Where do I start to implement the function below? int NetworkStack::setstackopt(int level, int optname, const void *optval, unsigned optlen) { return NSAPI_ERROR_UNSUPPORTED; }

Pros added what was existing functionality back into Mbed-OS

Cons

0xc0170 commented 8 years ago

@geky

geky commented 8 years ago

First thing, broadcast isn't a configuration of the socket. You should be able to send a packet to a broadcast address without any changes to the network interface if your router supports it: https://en.wikipedia.org/wiki/Broadcast_address

Second thing, unicast just describes the default behaviour of IP addresses. That is, a mapping of a single address to a single machine (more or less): https://en.wikipedia.org/wiki/Unicast


That leaves multicast as the only form of addressing that requires network stack specific configuration. The setsockopt and getsockopt are effective backdoors that allow non-portable configurations at the risk of returning NSAPI_ERROR_UNSUPPORTED for network stacks that don't support such a configuration.

Here's a good write up of how to use multicast on standard BSD sockets that support the feature: http://www.iitk.ac.in/LDP/HOWTO/Multicast-HOWTO-6.html

If you're interested in adding support to an existing network stack (lwip?), you can extend the nsapi_option_t enum with the required options, and add their behaviours to setsockopt and getsockopt. You can see the existing setsockopt implementation for lwip: https://github.com/ARMmbed/mbed-os/blob/master/features/FEATURE_LWIP/lwip-interface/lwip_stack.c#L802

Neuromancer2701 commented 8 years ago

Thanks for the details. I will test out the broadcast and look into the multicast implementation.

geky commented 8 years ago

Let us know if you run into any issues, it would be very interesting to see multicast support in a network interface.

Neuromancer2701 commented 8 years ago

So I was able to do some testing today with my nucleo_f767zi. I attempted to send and receive data from both broadcast addresses(192.168.1.255 and 255.255.255.255)

I just block indefinitely when trying to received data. Sending data I get a NSAPI_ERROR_PARAMETER error(ERR_VAL)

If I change the address to the unicast the exact same code works just fine. I am sending and receiving data from the python scripts from my laptop. And I have verified that the broadcast by wiresharking the network from my wife's laptop.

geky commented 8 years ago

Testing myself with a k64f, I can confirm that there is an issue on the device side. The broadcast packet appears to be getting through the ethernet driver on the device, but it seems to be being discarded by lwip. This will require more looking into.

@kjbracey-arm, any immediate thoughts? Should lwip be able to handle broadcast packets as is?

kjbracey commented 8 years ago

Probably need to enable the SO_BROADCAST socket option. lwIP won't let a socket send broadcasts unless that's set, which is standard behavioud. (If that socket option is built in, via IP_SOF_BROADCAST being in the config, which it is).

Looking at it lwIP's SO_BROADCAST also restricts reception of broadcasts, which is non-standard. (if IP_SOF_BROADCAST_RECV is enabled).

Given that non-standard reception thing, might be simplest to just have the abstraction layer always set SO_BROADCAST when creating lwIP sockets.

Neuromancer2701 commented 8 years ago

It looks like both filters are set in the lwipopts.h file // Broadcast

define IP_SOF_BROADCAST 1

define IP_SOF_BROADCAST_RECV 1

Neuromancer2701 commented 7 years ago

I was able to do a test I set both Filters to 0

define IP_SOF_BROADCAST 0

define IP_SOF_BROADCAST_RECV 0

in mbed-os/features/net/FEATURE_IPV4/lwip-interface/lwipopts.h

I was able to use send and receive using both addresses(192.168.1.255 and 255.255.255.255) that failed earlier. Should these filters be disable by default?