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 | 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); | ... | ... |