Modbus TCP: Problems using Port 502

B

Thread Starter

bierbauch

<p>While I'm trying to implement a modbus slave on a linux system, I've problems using port number 502. On modbus messaging implementation guide I found the following text line:

<p>"All MODBUS/TCP ADU are sent via TCP on registered port 502."

<p>I wanted to do so, but my linux system doesn't want to:
<pre>
int sockfd, i;
struct sockaddr_in address;
size_t addrlength = sizeof(struct sockaddr_in);

if ( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
printf("error on socket\n");

i = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));

address.sin_family = AF_INET;
address.sin_port = htons(PORT_NUMBER);
memset(&address.sin_addr, 0, sizeof(address.sin_addr));

if (bind(sockfd, (struct sockaddr *) &address, sizeof(address)))
printf("error on bind\n");

if (listen(sockfd, 5))
printf("error on listen\n");
</pre>

<p>Starting the routine, I get this message:
"error on bind". (with #define PORT_NUMBER 502)

<p>I only have to change PORT_NUMBER to:
#define PORT_NUMBER 2233 (for example)

<p>And - IT WORKS!

<p>What is wrong here? I want to use Port 502...

<p>Thanks for helping!
 
H

H.-J. Oertel

Linux maintains different systems for permission checking.
RTFM capabilities(7):
There you will find the CAP_NET_BIND_SERVICE:

Allow binding to Internet domain reserved socket ports (port numbers less than 1024).

That means that port numbers below can only be used by processes with super user privileges.

with best regards / mit freundlichen Grüßen

Heinz-Jürgen Oertel
+================================| port GmbH
| Germany http://www.port.de
| CAN Wiki http://www.CAN-Wiki.info/
| ETHERNET Powerlink http://www.epl-tools.com
+=================================================
 
Hello bierbauch:
> While I'm trying to implement a modbus slave on a linux system, I've
> problems using port number 502.
...
> Starting the routine, I get this message:
> "error on bind". (with #define PORT_NUMBER 502)

It would probably be useful to print out errno as well - it would give at
least some detail on the problem. Instead of
printf("error on bind\n");
you should use
perror("error on bind");

> I only have to change PORT_NUMBER to:
> #define PORT_NUMBER 2233 (for example)

> And - IT WORKS!

If it works for larger port numbers but not for 502, it's most likely that you don't have permission for the port. From the ip(7) man page:

The port numbers below 1024 are called reserved ports. Only processes with effective user id 0 or the CAP_NET_BIND_SERVICE capability may bind(2) to these sockets.

Try running your program as root and see if it works. If it does, then minimise the privileges the process actually needs (eg, make it drop
privileges after the bind).

HTH - HAND

Jiri
--
Jiri Baum <[email protected]> http://www.baum.com.au/~jiri
MAT LinuxPLC project --- http://mat.sf.net --- Machine Automation Tools
 
C

Curt Wuollet

I believe the ports below 2000 need different permissions/authorization. I read that someplace, but would be hard pressed to recall where. I believe it is a relatively recent thing as I haven't run into it. A google of linux port 2000 or similar might shed some light. Sorry for the late response, but my interest in this forum has been lagging since I have been getting censored.

Regards
cww
 
Hi there,

Did you ever get this up and running? I'm having the same problem with MODBUS TCP, but my tech says that he can't open that port... I'll ask in the AM whether or not he's using root permissions. Thanks.
 
C

Curt Wuollet

I vaguely recall that ports under a certain number require root permission which may be dropped after the open. Google should tell all.

Regards
cww
 
M

Michael Griffin

Anything below port 1024 requires root permission. The getting and dropping of root permission is accomplished via SUID, or set uid. The program starts up with root permissions, but then drops back to the same level as the user that called it after opening the port. There should be plenty of programming references available on how to do this.

For a brief explanation, there is an article at the following URL "http://linuxgazette.net/112/radcliffe.html". This describes accessing hardware addresses, but the same principle should apply to this application.
 
Top