Commit c1665d400c2a490e6110f92e8fd34c5cf87d55db
1 parent
c3358643
Filter of IP addresses in IPv4 server (closes #190)
- protect against NULL IP address BTW - update documentation
Showing
5 changed files
with
48 additions
and
28 deletions
NEWS
| 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 | This release introduces API changes on modbus_get_byte_timeout, | 9 | This release introduces API changes on modbus_get_byte_timeout, |
| 5 | modbus_get_response_timeout, modbus_set_byte_timeout, | 10 | modbus_get_response_timeout, modbus_set_byte_timeout, |
| 6 | modbus_set_response_timeout to ease writing of language bindings. | 11 | modbus_set_response_timeout to ease writing of language bindings. |
| 7 | 12 | ||
| 13 | +- Filter of IP addresses in IPv4 server (closes #190) | ||
| 8 | - Allow to listen any hosts in IPv6 (closes #32) | 14 | - Allow to listen any hosts in IPv6 (closes #32) |
| 9 | - Define and public export of MODBUS_MAX_PDU_LENGTH (closes #167) | 15 | - Define and public export of MODBUS_MAX_PDU_LENGTH (closes #167) |
| 10 | - Truncate data from response in report_slave_id to new max arg (closes #167) | 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,21 +14,22 @@ SYNOPSIS | ||
| 14 | 14 | ||
| 15 | DESCRIPTION | 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 | The _ip_ argument specifies the IP address of the server to which the client | 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 | The _port_ argument is the TCP port to use. Set the port to | 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 | port number greater than or equal to 1024 because it’s not necessary to have | 26 | port number greater than or equal to 1024 because it’s not necessary to have |
| 26 | administrator privileges. | 27 | administrator privileges. |
| 27 | 28 | ||
| 28 | 29 | ||
| 29 | RETURN VALUE | 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 | if successful. Otherwise it shall return NULL and set errno to one of the values | 33 | if successful. Otherwise it shall return NULL and set errno to one of the values |
| 33 | defined below. | 34 | defined below. |
| 34 | 35 | ||
| @@ -60,7 +61,7 @@ if (modbus_connect(ctx) == -1) { | @@ -60,7 +61,7 @@ if (modbus_connect(ctx) == -1) { | ||
| 60 | 61 | ||
| 61 | SEE ALSO | 62 | SEE ALSO |
| 62 | -------- | 63 | -------- |
| 63 | -linkmb:modbus_new_rtu[3] | 64 | +linkmb:modbus_tcp_listen[3] |
| 64 | linkmb:modbus_free[3] | 65 | linkmb:modbus_free[3] |
| 65 | 66 | ||
| 66 | 67 |
doc/modbus_tcp_listen.txt
| @@ -14,13 +14,16 @@ SYNOPSIS | @@ -14,13 +14,16 @@ SYNOPSIS | ||
| 14 | 14 | ||
| 15 | DESCRIPTION | 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 | RETURN VALUE | 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 | successful. Otherwise it shall return -1 and set errno. | 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,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 | /* Handle until 10 established connections */ | 45 | /* Handle until 10 established connections */ |
| 42 | server_socket = modbus_tcp_listen(ctx, 10); | 46 | server_socket = modbus_tcp_listen(ctx, 10); |
| @@ -58,8 +62,8 @@ modbus_free(ctx); | @@ -58,8 +62,8 @@ modbus_free(ctx); | ||
| 58 | 62 | ||
| 59 | SEE ALSO | 63 | SEE ALSO |
| 60 | -------- | 64 | -------- |
| 65 | +linkmb:modbus_new_tcp[3] | ||
| 61 | linkmb:modbus_tcp_accept[3] | 66 | linkmb:modbus_tcp_accept[3] |
| 62 | -linkmb:modbus_tcp_pi_accept[3] | ||
| 63 | linkmb:modbus_tcp_pi_listen[3] | 67 | linkmb:modbus_tcp_pi_listen[3] |
| 64 | 68 | ||
| 65 | AUTHORS | 69 | AUTHORS |
src/modbus-tcp.c
| @@ -515,7 +515,13 @@ int modbus_tcp_listen(modbus_t *ctx, int nb_connection) | @@ -515,7 +515,13 @@ int modbus_tcp_listen(modbus_t *ctx, int nb_connection) | ||
| 515 | addr.sin_family = AF_INET; | 515 | addr.sin_family = AF_INET; |
| 516 | /* If the modbus port is < to 1024, we need the setuid root. */ | 516 | /* If the modbus port is < to 1024, we need the setuid root. */ |
| 517 | addr.sin_port = htons(ctx_tcp->port); | 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 | if (bind(new_s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { | 525 | if (bind(new_s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { |
| 520 | close(new_s); | 526 | close(new_s); |
| 521 | return -1; | 527 | return -1; |
| @@ -807,22 +813,25 @@ modbus_t* modbus_new_tcp(const char *ip, int port) | @@ -807,22 +813,25 @@ modbus_t* modbus_new_tcp(const char *ip, int port) | ||
| 807 | ctx->backend_data = (modbus_tcp_t *) malloc(sizeof(modbus_tcp_t)); | 813 | ctx->backend_data = (modbus_tcp_t *) malloc(sizeof(modbus_tcp_t)); |
| 808 | ctx_tcp = (modbus_tcp_t *)ctx->backend_data; | 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 | ctx_tcp->port = port; | 835 | ctx_tcp->port = port; |
| 827 | ctx_tcp->t_id = 0; | 836 | ctx_tcp->t_id = 0; |
| 828 | 837 |
tests/unit-test-client.c
| @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) | @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) | ||
| 98 | MODBUS_ERROR_RECOVERY_PROTOCOL); | 98 | MODBUS_ERROR_RECOVERY_PROTOCOL); |
| 99 | 99 | ||
| 100 | if (use_backend == RTU) { | 100 | if (use_backend == RTU) { |
| 101 | - modbus_set_slave(ctx, SERVER_ID); | 101 | + modbus_set_slave(ctx, SERVER_ID); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); | 104 | modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); |