Beckhoff / ADS

Beckhoff protocol to communicate with TwinCAT devices.
MIT License
502 stars 194 forks source link

Specify Outbound TCP/UDP port #92

Closed Adrian-at-CrimsonAzure closed 5 years ago

Adrian-at-CrimsonAzure commented 5 years ago

I am using this library on Linux through the Pyads Python library. I am trying to run my application in a Docker container, but I need to be able to forward the sending port to the container. Right now it seems to pick a random port between 50000 and 60000 to send/receive AMS requests. Is there any way to set this?

Adrian-at-CrimsonAzure commented 5 years ago

The client picks a random port and, because it's not forwarded to the Docker container, the communication fails.

image This time it picked 56250, last time was 55664, on a different PLC it tried 33712 and 34072. I need a static port in order to get this connection through to my container.

pbruenn commented 5 years ago

Well, regarding Docker there is nothing special about AdsLib. What does curl google.com gives you, when you run it inside of your container? If that's working my guess is you are missing a ADS route on your TwinCAT system to your container.

Adrian-at-CrimsonAzure commented 5 years ago

I get a message back:

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

So I definitely have a network connection. If I run the application directly from the host, I make a connection to this PLC perfectly fine. The two UDP packets at the top are adding the route to the PLC (see this PR) so it should have a route. Port forward issues are the last thing I haven't tested, but I can't test them if I don't know what port the connection is going out on.

How well does AMS traverse subnets? The Docker container is technically running on 172.17.0.0/16 while the PLC is sitting on 192.168.200.0/24 and Docker is bridging the two. All normal communication makes it across, but what I've learned through the course of this project is that PLCs are not normal.

pbruenn commented 5 years ago

The general TCP connection is not special to any other tcp traffic. The „PLC fun“ is within ADS routing. Check the routes on your TwinCAT device. Verify the IPs and AmsNetIds are correct. Use SetLocalnetId in your application to make sure it keeps constant. Try to ping your container from the TwinCAT machine to see if IP routing is correct. Sorry for this messy response, currently I am on the road.

sdirkwinkel commented 5 years ago

The TCP-Connection seems to be working fine from your Wireshark output. The AMS-Router tries to find a route to send packets to. If the AMS-Router has a route to your container (172.17.0.0/16) it will not send packets through the connection from your docker host (192.168.200.0/24).

If you're adding a route for the container you need to add the hosts ip as a route. If you'd like to keep all ADS related functionality inside the container you might want to pass the host ip as an environment variable to the container or use some sort of networking without nat (bridge?).

Adrian-at-CrimsonAzure commented 5 years ago

So it turns out that the PLC terminates the connection if the hostname of the computer responding doesn't match the hostname in the route, even if the AMS ID is correct. That's one problem solved.

EDIT: To elaborate, the Docker container was adding the route using its hostname, but because traffic is being routed through the host the PLC terminates the connection because it's not expecting that host to respond. If I make the container hostname the same --hostname $HOSTNAME or change the hostname being added in the route, then everything works as expected.

I am still having another issue with a specific PLC that maybe someone could help with?