Commit b4330d2143163bd92bbb10ac3b0705eb521fe3c3
1 parent
1a45c24d
Add check on transaction ID for Modbus TCP
Showing
4 changed files
with
30 additions
and
1 deletions
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
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 */ | ... | ... |