Commit 8f1cc7b3c8de8ef64b2ea35676d3e6ac039dbc3d

Authored by Stéphane Raimbault
1 parent 652b5b05

Allow to listen any hosts in IPv6 (closes #32)

- allow an empty string or NULL for node argument
- protect against NULL in service argument
- new test for NULL service
- update documentation
doc/modbus_new_tcp_pi.txt
... ... @@ -14,11 +14,12 @@ SYNOPSIS
14 14  
15 15 DESCRIPTION
16 16 -----------
17   -The _modbus_new_tcp_pi()_ function shall allocate and initialize a modbus_t
18   -structure to communicate with a Modbus TCP IPv4 or Ipv6 server.
  17 +The *modbus_new_tcp_pi()* function shall allocate and initialize a modbus_t
  18 +structure to communicate with a Modbus TCP IPv4 or IPv6 server.
19 19  
20 20 The _node_ argument specifies the host name or IP address of the host to connect
21   -to, eg. '192.168.0.5' , '::1' or 'server.com'.
  21 +to, eg. "192.168.0.5" , "::1" or "server.com". A NULL value can be used to
  22 +listen any addresses in server mode.
22 23  
23 24 The _service_ argument is the service name/port number to connect to. To use the
24 25 default Modbus port use the string "502". On many Unix systems, it’s
... ... @@ -28,7 +29,7 @@ necessary to have administrator privileges.
28 29  
29 30 RETURN VALUE
30 31 ------------
31   -The _modbus_new_tcp_pi()_ function shall return a pointer to a *modbus_t* structure
  32 +The *modbus_new_tcp_pi()* 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  
... ... @@ -62,7 +63,7 @@ if (modbus_connect(ctx) == -1) {
62 63 SEE ALSO
63 64 --------
64 65 linkmb:modbus_new_tcp[3]
65   -linkmb:modbus_new_rtu[3]
  66 +linkmb:modbus_tcp_pi_listen[3]
66 67 linkmb:modbus_free[3]
67 68  
68 69  
... ...
doc/modbus_tcp_pi_listen.txt
... ... @@ -14,13 +14,16 @@ SYNOPSIS
14 14  
15 15 DESCRIPTION
16 16 -----------
17   -The _modbus_tcp_pi_listen()_ function shall create a socket and listen for
18   -'nb_connection' incoming connections.
  17 +The *modbus_tcp_pi_listen()* function shall create a socket and listen to
  18 +maximum _nb_connection_ incoming connections on the specified nodes. The
  19 +context *ctx* must be allocated and initialized with linkmb:modbus_new_tcp_pi[3]
  20 +before to set the node to listen, if node is set to 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  
... ... @@ -54,8 +57,8 @@ modbus_free(ctx);
54 57  
55 58 SEE ALSO
56 59 --------
  60 +linkmb:modbus_new_tcp_pi[3]
57 61 linkmb:modbus_tcp_pi_accept[3]
58   -linkmb:modbus_tcp_accept[3]
59 62 linkmb:modbus_tcp_listen[3]
60 63  
61 64 AUTHORS
... ...
src/modbus-tcp.c
... ... @@ -553,17 +553,20 @@ int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection)
553 553 }
554 554 #endif
555 555  
556   - if (ctx_tcp_pi->node[0] == 0)
  556 + if (ctx_tcp_pi->node[0] == 0) {
557 557 node = NULL; /* == any */
558   - else
  558 + } else {
559 559 node = ctx_tcp_pi->node;
  560 + }
560 561  
561   - if (ctx_tcp_pi->service[0] == 0)
  562 + if (ctx_tcp_pi->service[0] == 0) {
562 563 service = "502";
563   - else
  564 + } else {
564 565 service = ctx_tcp_pi->service;
  566 + }
565 567  
566 568 memset(&ai_hints, 0, sizeof (ai_hints));
  569 + /* If node is not NULL, than the AI_PASSIVE flag is ignored. */
567 570 ai_hints.ai_flags |= AI_PASSIVE;
568 571 #ifdef AI_ADDRCONFIG
569 572 ai_hints.ai_flags |= AI_ADDRCONFIG;
... ... @@ -845,24 +848,35 @@ modbus_t* modbus_new_tcp_pi(const char *node, const char *service)
845 848 ctx->backend_data = (modbus_tcp_pi_t *) malloc(sizeof(modbus_tcp_pi_t));
846 849 ctx_tcp_pi = (modbus_tcp_pi_t *)ctx->backend_data;
847 850  
848   - dest_size = sizeof(char) * _MODBUS_TCP_PI_NODE_LENGTH;
849   - ret_size = strlcpy(ctx_tcp_pi->node, node, dest_size);
850   - if (ret_size == 0) {
851   - fprintf(stderr, "The node string is empty\n");
852   - modbus_free(ctx);
853   - errno = EINVAL;
854   - return NULL;
  851 + if (node == NULL) {
  852 + /* The node argument can be empty to indicate any hosts */
  853 + ctx_tcp_pi->node[0] = '0';
  854 + } else {
  855 + dest_size = sizeof(char) * _MODBUS_TCP_PI_NODE_LENGTH;
  856 + ret_size = strlcpy(ctx_tcp_pi->node, node, dest_size);
  857 + if (ret_size == 0) {
  858 + fprintf(stderr, "The node string is empty\n");
  859 + modbus_free(ctx);
  860 + errno = EINVAL;
  861 + return NULL;
  862 + }
  863 +
  864 + if (ret_size >= dest_size) {
  865 + fprintf(stderr, "The node string has been truncated\n");
  866 + modbus_free(ctx);
  867 + errno = EINVAL;
  868 + return NULL;
  869 + }
855 870 }
856 871  
857   - if (ret_size >= dest_size) {
858   - fprintf(stderr, "The node string has been truncated\n");
859   - modbus_free(ctx);
860   - errno = EINVAL;
861   - return NULL;
  872 + if (service != NULL) {
  873 + dest_size = sizeof(char) * _MODBUS_TCP_PI_SERVICE_LENGTH;
  874 + ret_size = strlcpy(ctx_tcp_pi->service, service, dest_size);
  875 + } else {
  876 + /* Empty service is not allowed, error catched below. */
  877 + ret_size = 0;
862 878 }
863 879  
864   - dest_size = sizeof(char) * _MODBUS_TCP_PI_SERVICE_LENGTH;
865   - ret_size = strlcpy(ctx_tcp_pi->service, service, dest_size);
866 880 if (ret_size == 0) {
867 881 fprintf(stderr, "The service string is empty\n");
868 882 modbus_free(ctx);
... ...
tests/unit-test-client.c
... ... @@ -600,6 +600,9 @@ int main(int argc, char *argv[])
600 600 ctx = modbus_new_rtu(NULL, 0, 'A', 0, 0);
601 601 ASSERT_TRUE(ctx == NULL && errno == EINVAL, "");
602 602  
  603 + ctx = modbus_new_tcp_pi(NULL, NULL);
  604 + ASSERT_TRUE(ctx == NULL && errno == EINVAL, "");
  605 +
603 606 printf("\nALL TESTS PASS WITH SUCCESS.\n");
604 607  
605 608 close:
... ...