1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <stdio.h> 6 #include <string.h> 7 #include <inttypes.h> 8 9 #include <rte_ether.h> 10 #include <rte_string_fns.h> 11 12 #include <cmdline_parse.h> 13 #include <cmdline_parse_etheraddr.h> 14 15 #include "test_cmdline.h" 16 17 struct ether_addr_str { 18 const char * str; 19 uint64_t address; 20 }; 21 22 /* valid strings */ 23 const struct ether_addr_str ether_addr_valid_strs[] = { 24 {"01:23:45:67:89:AB", 0xAB8967452301ULL}, 25 {"4567:89AB:CDEF", 0xEFCDAB896745ULL}, 26 }; 27 28 /* valid strings with various garbage at the end. 29 * these strings are still valid because parser checks for 30 * end of token, which is either space chars, null char or 31 * a hash sign. 32 */ 33 const char * ether_addr_garbage_strs[] = { 34 "00:11:22:33:44:55\0garbage", 35 "00:11:22:33:44:55#garbage", 36 "00:11:22:33:44:55 garbage", 37 "00:11:22:33:44:55\tgarbage", 38 "00:11:22:33:44:55\ngarbage", 39 "00:11:22:33:44:55\rgarbage", 40 "00:11:22:33:44:55#", 41 "00:11:22:33:44:55 ", 42 "00:11:22:33:44:55\t", 43 "00:11:22:33:44:55\n", 44 "00:11:22:33:44:55\r", 45 }; 46 #define GARBAGE_ETHERADDR 0x554433221100ULL /* corresponding address */ 47 48 49 const char * ether_addr_invalid_strs[] = { 50 /* valid chars, invalid syntax */ 51 "0123:45:67:89:AB", 52 "01:23:4567:89:AB", 53 "01:23:45:67:89AB", 54 "012:345:678:9AB", 55 "01:23:45:67:89:ABC", 56 "01:23:45:67:89:A", 57 "01:23:45:67:89", 58 "01:23:45:67:89:AB:CD", 59 /* invalid chars, valid syntax */ 60 "IN:VA:LI:DC:HA:RS", 61 "INVA:LIDC:HARS", 62 /* misc */ 63 "01 23 45 67 89 AB", 64 "01.23.45.67.89.AB", 65 "01,23,45,67,89,AB", 66 "01:23:45\0:67:89:AB", 67 "01:23:45#:67:89:AB", 68 "random invalid text", 69 "random text", 70 "", 71 "\0", 72 " ", 73 }; 74 75 #define ETHERADDR_VALID_STRS_SIZE \ 76 (sizeof(ether_addr_valid_strs) / sizeof(ether_addr_valid_strs[0])) 77 #define ETHERADDR_GARBAGE_STRS_SIZE \ 78 (sizeof(ether_addr_garbage_strs) / sizeof(ether_addr_garbage_strs[0])) 79 #define ETHERADDR_INVALID_STRS_SIZE \ 80 (sizeof(ether_addr_invalid_strs) / sizeof(ether_addr_invalid_strs[0])) 81 82 83 84 static int 85 is_addr_different(const struct ether_addr addr, uint64_t num) 86 { 87 int i; 88 for (i = 0; i < ETHER_ADDR_LEN; i++, num >>= 8) 89 if (addr.addr_bytes[i] != (num & 0xFF)) { 90 return 1; 91 } 92 return 0; 93 } 94 95 /* test invalid parameters */ 96 int 97 test_parse_etheraddr_invalid_param(void) 98 { 99 char buf[CMDLINE_TEST_BUFSIZE]; 100 struct ether_addr result; 101 int ret = 0; 102 103 /* try all null */ 104 ret = cmdline_parse_etheraddr(NULL, NULL, NULL, 0); 105 if (ret != -1) { 106 printf("Error: parser accepted null parameters!\n"); 107 return -1; 108 } 109 110 /* try null buf */ 111 ret = cmdline_parse_etheraddr(NULL, NULL, (void*)&result, 112 sizeof(result)); 113 if (ret != -1) { 114 printf("Error: parser accepted null string!\n"); 115 return -1; 116 } 117 118 /* try null result */ 119 120 /* copy string to buffer */ 121 strlcpy(buf, ether_addr_valid_strs[0].str, sizeof(buf)); 122 123 ret = cmdline_parse_etheraddr(NULL, buf, NULL, 0); 124 if (ret == -1) { 125 printf("Error: parser rejected null result!\n"); 126 return -1; 127 } 128 129 /* token is not used in ether_parse anyway so there's no point in 130 * testing it */ 131 132 /* test help function */ 133 memset(&buf, 0, sizeof(buf)); 134 135 /* coverage! */ 136 ret = cmdline_get_help_etheraddr(NULL, buf, sizeof(buf)); 137 if (ret < 0) { 138 printf("Error: help function failed with valid parameters!\n"); 139 return -1; 140 } 141 142 return 0; 143 } 144 145 /* test valid parameters but invalid data */ 146 int 147 test_parse_etheraddr_invalid_data(void) 148 { 149 int ret = 0; 150 unsigned i; 151 struct ether_addr result; 152 153 /* test full strings */ 154 for (i = 0; i < ETHERADDR_INVALID_STRS_SIZE; i++) { 155 156 memset(&result, 0, sizeof(struct ether_addr)); 157 158 ret = cmdline_parse_etheraddr(NULL, ether_addr_invalid_strs[i], 159 (void*)&result, sizeof(result)); 160 if (ret != -1) { 161 printf("Error: parsing %s succeeded!\n", 162 ether_addr_invalid_strs[i]); 163 return -1; 164 } 165 } 166 167 return 0; 168 } 169 170 /* test valid parameters and data */ 171 int 172 test_parse_etheraddr_valid(void) 173 { 174 int ret = 0; 175 unsigned i; 176 struct ether_addr result; 177 178 /* test full strings */ 179 for (i = 0; i < ETHERADDR_VALID_STRS_SIZE; i++) { 180 181 memset(&result, 0, sizeof(struct ether_addr)); 182 183 ret = cmdline_parse_etheraddr(NULL, ether_addr_valid_strs[i].str, 184 (void*)&result, sizeof(result)); 185 if (ret < 0) { 186 printf("Error: parsing %s failed!\n", 187 ether_addr_valid_strs[i].str); 188 return -1; 189 } 190 if (is_addr_different(result, ether_addr_valid_strs[i].address)) { 191 printf("Error: parsing %s failed: address mismatch!\n", 192 ether_addr_valid_strs[i].str); 193 return -1; 194 } 195 } 196 197 /* test garbage strings */ 198 for (i = 0; i < ETHERADDR_GARBAGE_STRS_SIZE; i++) { 199 200 memset(&result, 0, sizeof(struct ether_addr)); 201 202 ret = cmdline_parse_etheraddr(NULL, ether_addr_garbage_strs[i], 203 (void*)&result, sizeof(result)); 204 if (ret < 0) { 205 printf("Error: parsing %s failed!\n", 206 ether_addr_garbage_strs[i]); 207 return -1; 208 } 209 if (is_addr_different(result, GARBAGE_ETHERADDR)) { 210 printf("Error: parsing %s failed: address mismatch!\n", 211 ether_addr_garbage_strs[i]); 212 return -1; 213 } 214 } 215 216 return 0; 217 } 218