Commit c1665d400c2a490e6110f92e8fd34c5cf87d55db

Authored by Stéphane Raimbault
1 parent c3358643

Filter of IP addresses in IPv4 server (closes #190)

- protect against NULL IP address BTW
- update documentation
1   -libmodbus 3.1.2 (2013-XX-XX)
  1 +libmodbus 3.1.2 (2014-XX-XX)
2 2 ============================
3 3  
  4 +If you still want to listen any addresses in your TCP IPv4 server, you must now
  5 +set the IP address to NULL in modbus_new_tcp before listening. Now,
  6 +modbus_tcp_listen only listen the IP address set in the Modbus context (see
  7 +documentation).
  8 +
4 9 This release introduces API changes on modbus_get_byte_timeout,
5 10 modbus_get_response_timeout, modbus_set_byte_timeout,
6 11 modbus_set_response_timeout to ease writing of language bindings.
7 12  
  13 +- Filter of IP addresses in IPv4 server (closes #190)
8 14 - Allow to listen any hosts in IPv6 (closes #32)
9 15 - Define and public export of MODBUS_MAX_PDU_LENGTH (closes #167)
10 16 - Truncate data from response in report_slave_id to new max arg (closes #167)
... ...
doc/modbus_new_tcp.txt
... ... @@ -14,21 +14,22 @@ SYNOPSIS
14 14  
15 15 DESCRIPTION
16 16 -----------
17   -The _modbus_new_tcp()_ function shall allocate and initialize a modbus_t
18   -structure to communicate with a Modbus TCP/IPv4 server.
  17 +The *modbus_new_tcp()* function shall allocate and initialize a modbus_t
  18 +structure to communicate with a Modbus TCP IPv4 server.
19 19  
20 20 The _ip_ argument specifies the IP address of the server to which the client
21   -wants etablish a connection.
  21 +wants etablish a connection. A NULL value can be used to listen any addresses in
  22 +server mode.
22 23  
23 24 The _port_ argument is the TCP port to use. Set the port to
24   -_MODBUS_TCP_DEFAULT_PORT_ to use the default one (502). It’s convenient to use a
  25 +*MODBUS_TCP_DEFAULT_PORT* to use the default one (502). It’s convenient to use a
25 26 port number greater than or equal to 1024 because it’s not necessary to have
26 27 administrator privileges.
27 28  
28 29  
29 30 RETURN VALUE
30 31 ------------
31   -The _modbus_new_tcp()_ function shall return a pointer to a *modbus_t* structure
  32 +The *modbus_new_tcp()* function shall return a pointer to a *modbus_t* structure
32 33 if successful. Otherwise it shall return NULL and set errno to one of the values
33 34 defined below.
34 35  
... ... @@ -60,7 +61,7 @@ if (modbus_connect(ctx) == -1) {
60 61  
61 62 SEE ALSO
62 63 --------
63   -linkmb:modbus_new_rtu[3]
  64 +linkmb:modbus_tcp_listen[3]
64 65 linkmb:modbus_free[3]
65 66  
66 67  
... ...
doc/modbus_tcp_listen.txt
... ... @@ -14,13 +14,16 @@ SYNOPSIS
14 14  
15 15 DESCRIPTION
16 16 -----------
17   -The _modbus_tcp_listen()_ function shall create a socket and listen for
18   -'nb_connection' incoming connections.
  17 +The *modbus_tcp_listen()* function shall create a socket and listen to maximum
  18 +_nb_connection_ incoming connections on the specified IP address. The context
  19 +_ctx _must be allocated and initialized with linkmb:modbus_new_tcp[3] before to
  20 +set the IP address to listen, if IP address is o NULL, any addresses will be
  21 +listen.
19 22  
20 23  
21 24 RETURN VALUE
22 25 ------------
23   -The _modbus_tcp_listen()_ function shall return a new socket if
  26 +The *modbus_tcp_listen()* function shall return a new socket if
24 27 successful. Otherwise it shall return -1 and set errno.
25 28  
26 29  
... ... @@ -36,7 +39,8 @@ For detailed examples, see source files in tests directory:
36 39 -------------------
37 40 ...
38 41  
39   -ctx = modbus_new_tcp("127.0.0.1", 502);
  42 +/* To listen any addresses on port 502 */
  43 +ctx = modbus_new_tcp(NULL, 502);
40 44  
41 45 /* Handle until 10 established connections */
42 46 server_socket = modbus_tcp_listen(ctx, 10);
... ... @@ -58,8 +62,8 @@ modbus_free(ctx);
58 62  
59 63 SEE ALSO
60 64 --------
  65 +linkmb:modbus_new_tcp[3]
61 66 linkmb:modbus_tcp_accept[3]
62   -linkmb:modbus_tcp_pi_accept[3]
63 67 linkmb:modbus_tcp_pi_listen[3]
64 68  
65 69 AUTHORS
... ...
src/modbus-tcp.c
... ... @@ -515,7 +515,13 @@ int modbus_tcp_listen(modbus_t *ctx, int nb_connection)
515 515 addr.sin_family = AF_INET;
516 516 /* If the modbus port is < to 1024, we need the setuid root. */
517 517 addr.sin_port = htons(ctx_tcp->port);
518   - addr.sin_addr.s_addr = INADDR_ANY;
  518 + if (ctx_tcp->ip[0] == '0') {
  519 + /* Listen any addresses */
  520 + addr.sin_addr.s_addr = INADDR_ANY;
  521 + } else {
  522 + /* Listen only specified IP address */
  523 + addr.sin_addr.s_addr = inet_addr(ctx_tcp->ip);
  524 + }
519 525 if (bind(new_s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
520 526 close(new_s);
521 527 return -1;
... ... @@ -807,22 +813,25 @@ modbus_t* modbus_new_tcp(const char *ip, int port)
807 813 ctx->backend_data = (modbus_tcp_t *) malloc(sizeof(modbus_tcp_t));
808 814 ctx_tcp = (modbus_tcp_t *)ctx->backend_data;
809 815  
810   - dest_size = sizeof(char) * 16;
811   - ret_size = strlcpy(ctx_tcp->ip, ip, dest_size);
812   - if (ret_size == 0) {
813   - fprintf(stderr, "The IP string is empty\n");
814   - modbus_free(ctx);
815   - errno = EINVAL;
816   - return NULL;
817   - }
  816 + if (ip != NULL) {
  817 + dest_size = sizeof(char) * 16;
  818 + ret_size = strlcpy(ctx_tcp->ip, ip, dest_size);
  819 + if (ret_size == 0) {
  820 + fprintf(stderr, "The IP string is empty\n");
  821 + modbus_free(ctx);
  822 + errno = EINVAL;
  823 + return NULL;
  824 + }
818 825  
819   - if (ret_size >= dest_size) {
820   - fprintf(stderr, "The IP string has been truncated\n");
821   - modbus_free(ctx);
822   - errno = EINVAL;
823   - return NULL;
  826 + if (ret_size >= dest_size) {
  827 + fprintf(stderr, "The IP string has been truncated\n");
  828 + modbus_free(ctx);
  829 + errno = EINVAL;
  830 + return NULL;
  831 + }
  832 + } else {
  833 + ctx_tcp->ip[0] = '0';
824 834 }
825   -
826 835 ctx_tcp->port = port;
827 836 ctx_tcp->t_id = 0;
828 837  
... ...
tests/unit-test-client.c
... ... @@ -98,7 +98,7 @@ int main(int argc, char *argv[])
98 98 MODBUS_ERROR_RECOVERY_PROTOCOL);
99 99  
100 100 if (use_backend == RTU) {
101   - modbus_set_slave(ctx, SERVER_ID);
  101 + modbus_set_slave(ctx, SERVER_ID);
102 102 }
103 103  
104 104 modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec);
... ...