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,6 +30,8 @@ enum {
30 RTU 30 RTU
31 }; 31 };
32 32
  33 +int test_raw_request(modbus_t *, int);
  34 +
33 int main(int argc, char *argv[]) 35 int main(int argc, char *argv[])
34 { 36 {
35 uint8_t *tab_rp_bits; 37 uint8_t *tab_rp_bits;
@@ -699,85 +701,8 @@ int main(int argc, char *argv[]) @@ -699,85 +701,8 @@ int main(int argc, char *argv[])
699 } 701 }
700 702
701 /** RAW REQUEST */ 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 printf("\nALL TESTS PASS WITH SUCCESS.\n"); 708 printf("\nALL TESTS PASS WITH SUCCESS.\n");
@@ -793,3 +718,88 @@ close: @@ -793,3 +718,88 @@ close:
793 718
794 return 0; 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 +}