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 90 ssize_t (*recv) (modbus_t *ctx, uint8_t *rsp, int rsp_length);
91 91 int (*check_integrity) (modbus_t *ctx, uint8_t *msg,
92 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 95 int (*connect) (modbus_t *ctx);
94 96 void (*close) (modbus_t *ctx);
95 97 int (*flush) (modbus_t *ctx);
... ...
src/modbus-rtu.c
... ... @@ -812,6 +812,7 @@ const modbus_backend_t _modbus_rtu_backend = {
812 812 _modbus_rtu_send,
813 813 _modbus_rtu_recv,
814 814 _modbus_rtu_check_integrity,
  815 + NULL,
815 816 _modbus_rtu_connect,
816 817 _modbus_rtu_close,
817 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 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 209 static int _modbus_tcp_set_ipv4_options(int s)
194 210 {
195 211 int rc;
... ... @@ -352,7 +368,7 @@ int _modbus_tcp_flush(modbus_t *ctx)
352 368 }
353 369 #endif
354 370 if (ctx->debug && rc != -1) {
355   - printf("\n%d bytes flushed\n", rc);
  371 + printf("%d bytes flushed\n", rc);
356 372 }
357 373 } while (rc == MODBUS_TCP_MAX_ADU_LENGTH);
358 374  
... ... @@ -588,6 +604,7 @@ const modbus_backend_t _modbus_tcp_backend = {
588 604 _modbus_tcp_send,
589 605 _modbus_tcp_recv,
590 606 _modbus_tcp_check_integrity,
  607 + _modbus_tcp_pre_check_confirmation,
591 608 _modbus_tcp_connect,
592 609 _modbus_tcp_close,
593 610 _modbus_tcp_flush,
... ... @@ -609,6 +626,7 @@ const modbus_backend_t _modbus_tcp_pi_backend = {
609 626 _modbus_tcp_send,
610 627 _modbus_tcp_recv,
611 628 _modbus_tcp_check_integrity,
  629 + _modbus_tcp_pre_check_confirmation,
612 630 _modbus_tcp_pi_connect,
613 631 _modbus_tcp_close,
614 632 _modbus_tcp_flush,
... ...
src/modbus.c
... ... @@ -440,6 +440,14 @@ static int check_confirmation(modbus_t *ctx, uint8_t *req,
440 440 int rsp_length_computed;
441 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 451 rsp_length_computed = compute_response_length_from_request(ctx, req);
444 452  
445 453 /* Check length */
... ...