Code-House / bacnet4j-wrapper

Simple facade for bacnet4j api.
GNU General Public License v3.0
48 stars 20 forks source link

Unable to discover bacnet devices with bacnet-client application running inside docker container #22

Closed saransh14 closed 11 months ago

saransh14 commented 11 months ago

I'm trying to discover the BACnet devices [simulated devices, using YABE for same] via the java application internally using the bacnet4j-wrapper.

successful-logs

Devices are getting discovered when running the application on local system, but when we're trying to run the code inside the docker container, the client application is unable to discover the devices. docker-container-logs

I've even tried using the --network="host" but no luck.

splatch commented 11 months ago

Hello, for docker issue comes from visibility of networks, try with --network host.

saransh14 commented 11 months ago

Hi, I created a java application using bacnet4j-wrapper, which discovers the bacnet devices and fetches all the objects which are part of the devices and eventually fetches the present-value using the BacNetIpClient.

NOTE: I'm using YABE simulator [Bacnet.Room.Simulator.exe] for simulating a BACnet device

I'm able to discover the devices when running the java application on my local system.

Following are the code snippets:

code-snip-1 code-snip-2

Following are the logs attached [when running the java application locallly]:

successful-logs

Wireshark analysis also if perfect in this case:

wireshark-1

Now I tried running the above java application inside a docker container with --network="host", I'm able to see the who-is request in wireshark, and infact the i-am been responded by the simulated device too, but the application is not able to listen to the i-am response and thus not discovering it.

Wireshark analysis [when running bacnet-client inside docker container with --network="host"] wireshark-2

splatch commented 11 months ago

Network trace from last screenshot indicate that there are two IP addresses used, 127.0.0.1 and 192.168.29.30. Your machine IP is probably 192.168.29.96. Can you check with other variant of constructor - BacNetIpClient(String ip, String broadcast, int deviceId) and see if it improves situation? The first ip should be your docker host which is visible to bacnet devices. Also are you running host using windows or linux?

saransh14 commented 11 months ago

YABE Device simulator is running on 192.168.29.30. I was initially running the BACnet-client Java application on my local setup [macOS, IP: 192.168.29.96]. This belongs to the success scenario.

Now I'm trying to run the BACnet-client Java application as docker container on my linux machine [IP: 192.168.29.30] Device simulator is also running on same linux machine [IP: 192.168.29.30]

NOTE: Docker is installed on linux machine [IP: 192.168.29.30], and YABE simulator is also running on same linux machine [IP: 192.168.29.30]

IP address 127.0.0.1 is the one sending the who-is request [BACnet-client docker container, IP is 127.0.0.1 because I'm using --network="host"]

When using other variant of constructor - BacNetIpClient(String ip, String broadcast, int deviceId) and defining values as BacNetIpClient("192.168.29.30", "255.255.255.255", "2002"), I'm get BindException (attaching the log trace). bind-exception

splatch commented 11 months ago

The --network=host indicates no network isolation, so your container can access host network interfaces. Namely it removes constraints and extra hop in routing the traffic. This means that you could actually bind any of host IP. When you run two processes which are trying to listen/broadcast bacnet packets they will end up fighting same network port. I usually ran simulator on another box to avoid conflicts. Anyhow - try broadcast address of 192.168.29.255. Making 255.255.255.255 will likely require root permissions.

saransh14 commented 11 months ago

When using other variant of constructor - BacNetIpClient(String ip, String broadcast, int deviceId) and defining values as BacNetIpClient("192.168.29.30", "192.168.29.255", "2002"), I'm getting the same BindException.

And when trying BacNetIpClient(String broadcast, int deviceId) and defining values as BacNetIpClient("192.168.29.255", "2002"), I'm unable to discover devices inside docker container and who-is requests is also not captured under wireshark

image
splatch commented 11 months ago

I've created a basic docker image, see #23.

Running it I can see devices in my host network: docker run --rm --net=host code-house/bacnet4j-wrapper:1.3.0-SNAPSHOT 192.168.2.255. Image uses DiscoveryMain class which you can find in project sources.

saransh14 commented 11 months ago

I've pushed my bacnet-client code onto github along with the Dockerfile that I've created. Link: https://github.com/saransh14/BACnet-Exploration

Can you please give it a try on your setup by dockerising and running the dockerimage as docker run --net host <image-name>

splatch commented 11 months ago

For me docker run --rm --net=host -e BROADCAST_ADDRESS=192.168.2.255 saransh14/bacnet-exploration did the trick. I am running linux host.

saransh14 commented 11 months ago

I'm still unable to discover the devices inside docker container. Now even I've ran the YABE simulator on another windows machine under same wifi-network, and bacnet-client as docker container on linux host machine

Are you using the bindIP same as "0.0.0.0", as specified in code base, while creating object for BacNetIpClient?

splatch commented 11 months ago

Yes, the above docker execution from your repo used your code. Only one parameter I tweaked was broadcast address. Anyhow, if you enumerate network interfaces using standard Java APIs you will get from it also a broadcast address which you can use to setup transport.

saransh14 commented 11 months ago

Thanks @splatch for your support, there was some network interface issue.

I'm now able to discover the BACnet devices under the docker environment using --network=host. I ran the YABE simulator on one linux machine and docker setup for bacnet-client application on another linux host machine so that both don't try to listen/broadcast bacnet packets and end up fighting same network port. Post then I was able to discover the BACnet device which were present under the same subnet.

Thanks for your support, closing this issue.