Commit b4330d2143163bd92bbb10ac3b0705eb521fe3c3

Authored by Stéphane Raimbault
1 parent 1a45c24d

Add check on transaction ID for Modbus TCP

src/modbus-private.h
@@ -90,6 +90,8 @@ typedef struct _modbus_backend { @@ -90,6 +90,8 @@ typedef struct _modbus_backend {
90 ssize_t (*recv) (modbus_t *ctx, uint8_t *rsp, int rsp_length); 90 ssize_t (*recv) (modbus_t *ctx, uint8_t *rsp, int rsp_length);
91 int (*check_integrity) (modbus_t *ctx, uint8_t *msg, 91 int (*check_integrity) (modbus_t *ctx, uint8_t *msg,
92 const int msg_length); 92 const int msg_length);
  93 + int (*pre_check_confirmation) (modbus_t *ctx, const uint8_t *req,
  94 + const uint8_t *rsp, int rsp_length);
93 int (*connect) (modbus_t *ctx); 95 int (*connect) (modbus_t *ctx);
94 void (*close) (modbus_t *ctx); 96 void (*close) (modbus_t *ctx);
95 int (*flush) (modbus_t *ctx); 97 int (*flush) (modbus_t *ctx);
src/modbus-rtu.c
@@ -812,6 +812,7 @@ const modbus_backend_t _modbus_rtu_backend = { @@ -812,6 +812,7 @@ const modbus_backend_t _modbus_rtu_backend = {
812 _modbus_rtu_send, 812 _modbus_rtu_send,
813 _modbus_rtu_recv, 813 _modbus_rtu_recv,
814 _modbus_rtu_check_integrity, 814 _modbus_rtu_check_integrity,
  815 + NULL,
815 _modbus_rtu_connect, 816 _modbus_rtu_connect,
816 _modbus_rtu_close, 817 _modbus_rtu_close,
817 _modbus_rtu_flush, 818 _modbus_rtu_flush,
src/modbus-tcp.c
@@ -190,6 +190,22 @@ int _modbus_tcp_check_integrity(modbus_t *ctx, uint8_t *msg, const int msg_lengt @@ -190,6 +190,22 @@ int _modbus_tcp_check_integrity(modbus_t *ctx, uint8_t *msg, const int msg_lengt
190 return msg_length; 190 return msg_length;
191 } 191 }
192 192
  193 +int _modbus_tcp_pre_check_confirmation(modbus_t *ctx, const uint8_t *req,
  194 + const uint8_t *rsp, int rsp_length)
  195 +{
  196 + /* Check TID */
  197 + if (req[0] != rsp[0] || req[1] != rsp[1]) {
  198 + if (ctx->debug) {
  199 + fprintf(stderr, "Invalid TID received 0x%X (not 0x%X)\n",
  200 + (rsp[0] << 8) + rsp[1], (req[0] << 8) + req[1]);
  201 + }
  202 + errno = EMBBADDATA;
  203 + return -1;
  204 + } else {
  205 + return 0;
  206 + }
  207 +}
  208 +
193 static int _modbus_tcp_set_ipv4_options(int s) 209 static int _modbus_tcp_set_ipv4_options(int s)
194 { 210 {
195 int rc; 211 int rc;
@@ -352,7 +368,7 @@ int _modbus_tcp_flush(modbus_t *ctx) @@ -352,7 +368,7 @@ int _modbus_tcp_flush(modbus_t *ctx)
352 } 368 }
353 #endif 369 #endif
354 if (ctx->debug && rc != -1) { 370 if (ctx->debug && rc != -1) {
355 - printf("\n%d bytes flushed\n", rc); 371 + printf("%d bytes flushed\n", rc);
356 } 372 }
357 } while (rc == MODBUS_TCP_MAX_ADU_LENGTH); 373 } while (rc == MODBUS_TCP_MAX_ADU_LENGTH);
358 374
@@ -588,6 +604,7 @@ const modbus_backend_t _modbus_tcp_backend = { @@ -588,6 +604,7 @@ const modbus_backend_t _modbus_tcp_backend = {
588 _modbus_tcp_send, 604 _modbus_tcp_send,
589 _modbus_tcp_recv, 605 _modbus_tcp_recv,
590 _modbus_tcp_check_integrity, 606 _modbus_tcp_check_integrity,
  607 + _modbus_tcp_pre_check_confirmation,
591 _modbus_tcp_connect, 608 _modbus_tcp_connect,
592 _modbus_tcp_close, 609 _modbus_tcp_close,
593 _modbus_tcp_flush, 610 _modbus_tcp_flush,
@@ -609,6 +626,7 @@ const modbus_backend_t _modbus_tcp_pi_backend = { @@ -609,6 +626,7 @@ const modbus_backend_t _modbus_tcp_pi_backend = {
609 _modbus_tcp_send, 626 _modbus_tcp_send,
610 _modbus_tcp_recv, 627 _modbus_tcp_recv,
611 _modbus_tcp_check_integrity, 628 _modbus_tcp_check_integrity,
  629 + _modbus_tcp_pre_check_confirmation,
612 _modbus_tcp_pi_connect, 630 _modbus_tcp_pi_connect,
613 _modbus_tcp_close, 631 _modbus_tcp_close,
614 _modbus_tcp_flush, 632 _modbus_tcp_flush,
src/modbus.c
@@ -440,6 +440,14 @@ static int check_confirmation(modbus_t *ctx, uint8_t *req, @@ -440,6 +440,14 @@ static int check_confirmation(modbus_t *ctx, uint8_t *req,
440 int rsp_length_computed; 440 int rsp_length_computed;
441 const int offset = ctx->backend->header_length; 441 const int offset = ctx->backend->header_length;
442 442
  443 +
  444 + if (ctx->backend->pre_check_confirmation) {
  445 + rc = ctx->backend->pre_check_confirmation(ctx, req, rsp, rsp_length);
  446 + if (rc == -1) {
  447 + return -1;
  448 + }
  449 + }
  450 +
443 rsp_length_computed = compute_response_length_from_request(ctx, req); 451 rsp_length_computed = compute_response_length_from_request(ctx, req);
444 452
445 /* Check length */ 453 /* Check length */