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,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 */ |