From c1665d400c2a490e6110f92e8fd34c5cf87d55db Mon Sep 17 00:00:00 2001 From: Stéphane Raimbault Date: Wed, 15 Jan 2014 23:25:05 +0100 Subject: [PATCH] Filter of IP addresses in IPv4 server (closes #190) --- NEWS | 8 +++++++- doc/modbus_new_tcp.txt | 13 +++++++------ doc/modbus_tcp_listen.txt | 14 +++++++++----- src/modbus-tcp.c | 39 ++++++++++++++++++++++++--------------- tests/unit-test-client.c | 2 +- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/NEWS b/NEWS index a8c0fb1..79af07a 100644 --- a/NEWS +++ b/NEWS @@ -1,10 +1,16 @@ -libmodbus 3.1.2 (2013-XX-XX) +libmodbus 3.1.2 (2014-XX-XX) ============================ +If you still want to listen any addresses in your TCP IPv4 server, you must now +set the IP address to NULL in modbus_new_tcp before listening. Now, +modbus_tcp_listen only listen the IP address set in the Modbus context (see +documentation). + This release introduces API changes on modbus_get_byte_timeout, modbus_get_response_timeout, modbus_set_byte_timeout, modbus_set_response_timeout to ease writing of language bindings. +- Filter of IP addresses in IPv4 server (closes #190) - Allow to listen any hosts in IPv6 (closes #32) - Define and public export of MODBUS_MAX_PDU_LENGTH (closes #167) - Truncate data from response in report_slave_id to new max arg (closes #167) diff --git a/doc/modbus_new_tcp.txt b/doc/modbus_new_tcp.txt index 767de7d..b834b53 100644 --- a/doc/modbus_new_tcp.txt +++ b/doc/modbus_new_tcp.txt @@ -14,21 +14,22 @@ SYNOPSIS DESCRIPTION ----------- -The _modbus_new_tcp()_ function shall allocate and initialize a modbus_t -structure to communicate with a Modbus TCP/IPv4 server. +The *modbus_new_tcp()* function shall allocate and initialize a modbus_t +structure to communicate with a Modbus TCP IPv4 server. The _ip_ argument specifies the IP address of the server to which the client -wants etablish a connection. +wants etablish a connection. A NULL value can be used to listen any addresses in +server mode. The _port_ argument is the TCP port to use. Set the port to -_MODBUS_TCP_DEFAULT_PORT_ to use the default one (502). It’s convenient to use a +*MODBUS_TCP_DEFAULT_PORT* to use the default one (502). It’s convenient to use a port number greater than or equal to 1024 because it’s not necessary to have administrator privileges. RETURN VALUE ------------ -The _modbus_new_tcp()_ function shall return a pointer to a *modbus_t* structure +The *modbus_new_tcp()* function shall return a pointer to a *modbus_t* structure if successful. Otherwise it shall return NULL and set errno to one of the values defined below. @@ -60,7 +61,7 @@ if (modbus_connect(ctx) == -1) { SEE ALSO -------- -linkmb:modbus_new_rtu[3] +linkmb:modbus_tcp_listen[3] linkmb:modbus_free[3] diff --git a/doc/modbus_tcp_listen.txt b/doc/modbus_tcp_listen.txt index df65d46..df6496d 100644 --- a/doc/modbus_tcp_listen.txt +++ b/doc/modbus_tcp_listen.txt @@ -14,13 +14,16 @@ SYNOPSIS DESCRIPTION ----------- -The _modbus_tcp_listen()_ function shall create a socket and listen for -'nb_connection' incoming connections. +The *modbus_tcp_listen()* function shall create a socket and listen to maximum +_nb_connection_ incoming connections on the specified IP address. The context +_ctx _must be allocated and initialized with linkmb:modbus_new_tcp[3] before to +set the IP address to listen, if IP address is o NULL, any addresses will be +listen. RETURN VALUE ------------ -The _modbus_tcp_listen()_ function shall return a new socket if +The *modbus_tcp_listen()* function shall return a new socket if successful. Otherwise it shall return -1 and set errno. @@ -36,7 +39,8 @@ For detailed examples, see source files in tests directory: ------------------- ... -ctx = modbus_new_tcp("127.0.0.1", 502); +/* To listen any addresses on port 502 */ +ctx = modbus_new_tcp(NULL, 502); /* Handle until 10 established connections */ server_socket = modbus_tcp_listen(ctx, 10); @@ -58,8 +62,8 @@ modbus_free(ctx); SEE ALSO -------- +linkmb:modbus_new_tcp[3] linkmb:modbus_tcp_accept[3] -linkmb:modbus_tcp_pi_accept[3] linkmb:modbus_tcp_pi_listen[3] AUTHORS diff --git a/src/modbus-tcp.c b/src/modbus-tcp.c index 9879364..31ed7c3 100644 --- a/src/modbus-tcp.c +++ b/src/modbus-tcp.c @@ -515,7 +515,13 @@ int modbus_tcp_listen(modbus_t *ctx, int nb_connection) addr.sin_family = AF_INET; /* If the modbus port is < to 1024, we need the setuid root. */ addr.sin_port = htons(ctx_tcp->port); - addr.sin_addr.s_addr = INADDR_ANY; + if (ctx_tcp->ip[0] == '0') { + /* Listen any addresses */ + addr.sin_addr.s_addr = INADDR_ANY; + } else { + /* Listen only specified IP address */ + addr.sin_addr.s_addr = inet_addr(ctx_tcp->ip); + } if (bind(new_s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { close(new_s); return -1; @@ -807,22 +813,25 @@ modbus_t* modbus_new_tcp(const char *ip, int port) ctx->backend_data = (modbus_tcp_t *) malloc(sizeof(modbus_tcp_t)); ctx_tcp = (modbus_tcp_t *)ctx->backend_data; - dest_size = sizeof(char) * 16; - ret_size = strlcpy(ctx_tcp->ip, ip, dest_size); - if (ret_size == 0) { - fprintf(stderr, "The IP string is empty\n"); - modbus_free(ctx); - errno = EINVAL; - return NULL; - } + if (ip != NULL) { + dest_size = sizeof(char) * 16; + ret_size = strlcpy(ctx_tcp->ip, ip, dest_size); + if (ret_size == 0) { + fprintf(stderr, "The IP string is empty\n"); + modbus_free(ctx); + errno = EINVAL; + return NULL; + } - if (ret_size >= dest_size) { - fprintf(stderr, "The IP string has been truncated\n"); - modbus_free(ctx); - errno = EINVAL; - return NULL; + if (ret_size >= dest_size) { + fprintf(stderr, "The IP string has been truncated\n"); + modbus_free(ctx); + errno = EINVAL; + return NULL; + } + } else { + ctx_tcp->ip[0] = '0'; } - ctx_tcp->port = port; ctx_tcp->t_id = 0; diff --git a/tests/unit-test-client.c b/tests/unit-test-client.c index 2e0d61b..4f01e7b 100644 --- a/tests/unit-test-client.c +++ b/tests/unit-test-client.c @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) MODBUS_ERROR_RECOVERY_PROTOCOL); if (use_backend == RTU) { - modbus_set_slave(ctx, SERVER_ID); + modbus_set_slave(ctx, SERVER_ID); } modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); -- libgit2 0.21.4