Commit 6cfed42b5e83a589b290a47322535af519241c61

Authored by Stéphane Raimbault
1 parent fc73565d

Slight refactor of unit-test-client

Showing 1 changed file with 89 additions and 79 deletions
tests/unit-test-client.c
... ... @@ -30,6 +30,8 @@ enum {
30 30 RTU
31 31 };
32 32  
  33 +int test_raw_request(modbus_t *, int);
  34 +
33 35 int main(int argc, char *argv[])
34 36 {
35 37 uint8_t *tab_rp_bits;
... ... @@ -699,85 +701,8 @@ int main(int argc, char *argv[])
699 701 }
700 702  
701 703 /** RAW REQUEST */
702   - printf("\nTEST RAW REQUESTS:\n");
703   - {
704   - int j;
705   - const int RAW_REQ_LENGTH = 6;
706   - uint8_t raw_req[] = {
707   - (use_backend == RTU) ? SERVER_ID : 0xFF,
708   - 0x03, 0x00, 0x01, 0x0, 0x05,
709   - };
710   - int req_length;
711   - uint8_t rsp[MODBUS_TCP_MAX_ADU_LENGTH];
712   - int tab_function[] = {0x01, 0x02, 0x03, 0x04};
713   - int tab_nb_max[] = {
714   - MODBUS_MAX_READ_BITS + 1,
715   - MODBUS_MAX_READ_BITS + 1,
716   - MODBUS_MAX_READ_REGISTERS + 1,
717   - MODBUS_MAX_READ_REGISTERS + 1
718   - };
719   -
720   - req_length = modbus_send_raw_request(ctx, raw_req,
721   - RAW_REQ_LENGTH * sizeof(uint8_t));
722   -
723   - printf("* modbus_send_raw_request: ");
724   - if ((use_backend == RTU && req_length == (RAW_REQ_LENGTH + 2)) ||
725   - ((use_backend == TCP || use_backend == TCP_PI) &&
726   - req_length == (RAW_REQ_LENGTH + 6))) {
727   - printf("OK\n");
728   - } else {
729   - printf("FAILED (%d)\n", req_length);
730   - goto close;
731   - }
732   -
733   - printf("* modbus_receive_confirmation: ");
734   - rc = modbus_receive_confirmation(ctx, rsp);
735   - if ((use_backend == RTU && rc == 15) ||
736   - ((use_backend == TCP || use_backend == TCP_PI) &&
737   - rc == 19)) {
738   - printf("OK\n");
739   - } else {
740   - printf("FAILED (%d)\n", rc);
741   - goto close;
742   - }
743   -
744   - /* Try to crash server with raw requests to bypass checks of client. */
745   -
746   - /* Address */
747   - raw_req[2] = 0;
748   - raw_req[3] = 0;
749   -
750   - /* Try to read more values than a response could hold for all data
751   - * types.
752   - */
753   - for (i=0; i<4; i++) {
754   - raw_req[1] = tab_function[i];
755   -
756   - for (j=0; j<2; j++) {
757   - if (j == 0) {
758   - /* Try to read zero values on first iteration */
759   - raw_req[4] = 0x00;
760   - raw_req[5] = 0x00;
761   - } else {
762   - /* Try to read max values + 1 on second iteration */
763   - raw_req[4] = (tab_nb_max[i] >> 8) & 0xFF;
764   - raw_req[5] = tab_nb_max[i] & 0xFF;
765   - }
766   -
767   - req_length = modbus_send_raw_request(ctx, raw_req,
768   - RAW_REQ_LENGTH * sizeof(uint8_t));
769   - printf("* try an exploit on function %d: ", tab_function[i]);
770   - rc = modbus_receive_confirmation(ctx, rsp);
771   - if (rc == 9 &&
772   - rsp[7] == (0x80 + tab_function[i]) &&
773   - rsp[8] == MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE) {
774   - printf("OK\n");
775   - } else {
776   - printf("FAILED\n");
777   - goto close;
778   - }
779   - }
780   - }
  704 + if (test_raw_request(ctx, use_backend) == -1) {
  705 + goto close;
781 706 }
782 707  
783 708 printf("\nALL TESTS PASS WITH SUCCESS.\n");
... ... @@ -793,3 +718,88 @@ close:
793 718  
794 719 return 0;
795 720 }
  721 +
  722 +int test_raw_request(modbus_t *ctx, int use_backend)
  723 +{
  724 + int rc;
  725 + int i, j;
  726 + const int RAW_REQ_LENGTH = 6;
  727 + uint8_t raw_req[] = {
  728 + (use_backend == RTU) ? SERVER_ID : 0xFF,
  729 + 0x03, 0x00, 0x01, 0x0, 0x05,
  730 + };
  731 + int req_length;
  732 + uint8_t rsp[MODBUS_TCP_MAX_ADU_LENGTH];
  733 + int tab_function[] = {0x01, 0x02, 0x03, 0x04};
  734 + int tab_nb_max[] = {
  735 + MODBUS_MAX_READ_BITS + 1,
  736 + MODBUS_MAX_READ_BITS + 1,
  737 + MODBUS_MAX_READ_REGISTERS + 1,
  738 + MODBUS_MAX_READ_REGISTERS + 1
  739 + };
  740 +
  741 + printf("\nTEST RAW REQUESTS:\n");
  742 +
  743 + req_length = modbus_send_raw_request(ctx, raw_req,
  744 + RAW_REQ_LENGTH * sizeof(uint8_t));
  745 +
  746 + printf("* modbus_send_raw_request: ");
  747 + if ((use_backend == RTU && req_length == (RAW_REQ_LENGTH + 2)) ||
  748 + ((use_backend == TCP || use_backend == TCP_PI) &&
  749 + req_length == (RAW_REQ_LENGTH + 6))) {
  750 + printf("OK\n");
  751 + } else {
  752 + printf("FAILED (%d)\n", req_length);
  753 + return -1;
  754 + }
  755 +
  756 + printf("* modbus_receive_confirmation: ");
  757 + rc = modbus_receive_confirmation(ctx, rsp);
  758 + if ((use_backend == RTU && rc == 15) ||
  759 + ((use_backend == TCP || use_backend == TCP_PI) &&
  760 + rc == 19)) {
  761 + printf("OK\n");
  762 + } else {
  763 + printf("FAILED (%d)\n", rc);
  764 + return -1;
  765 + }
  766 +
  767 + /* Try to crash server with raw requests to bypass checks of client. */
  768 +
  769 + /* Address */
  770 + raw_req[2] = 0;
  771 + raw_req[3] = 0;
  772 +
  773 + /* Try to read more values than a response could hold for all data
  774 + * types.
  775 + */
  776 + for (i=0; i<4; i++) {
  777 + raw_req[1] = tab_function[i];
  778 +
  779 + for (j=0; j<2; j++) {
  780 + if (j == 0) {
  781 + /* Try to read zero values on first iteration */
  782 + raw_req[4] = 0x00;
  783 + raw_req[5] = 0x00;
  784 + } else {
  785 + /* Try to read max values + 1 on second iteration */
  786 + raw_req[4] = (tab_nb_max[i] >> 8) & 0xFF;
  787 + raw_req[5] = tab_nb_max[i] & 0xFF;
  788 + }
  789 +
  790 + req_length = modbus_send_raw_request(ctx, raw_req,
  791 + RAW_REQ_LENGTH * sizeof(uint8_t));
  792 + printf("* try an exploit on function %d: ", tab_function[i]);
  793 + rc = modbus_receive_confirmation(ctx, rsp);
  794 + if (rc == 9 &&
  795 + rsp[7] == (0x80 + tab_function[i]) &&
  796 + rsp[8] == MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE) {
  797 + printf("OK\n");
  798 + } else {
  799 + printf("FAILED\n");
  800 + return -1;
  801 + }
  802 + }
  803 + }
  804 + return 0;
  805 +}
... ...