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 static 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 static const char * const 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 static const char * const 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", 57 "01:23:45:67:89:AB:CD", 58 /* invalid chars, valid syntax */ 59 "IN:VA:LI:DC:HA:RS", 60 "INVA:LIDC:HARS", 61 /* misc */ 62 "01 23 45 67 89 AB", 63 "01,23,45,67,89,AB", 64 "01:23:45\0:67:89:AB", 65 "01:23:45#:67:89:AB", 66 "random invalid text", 67 "random text", 68 "", 69 "\0", 70 " ", 71 }; 72 73 static int 74 is_addr_different(const struct rte_ether_addr addr, uint64_t num) 75 { 76 int i; 77 for (i = 0; i < RTE_ETHER_ADDR_LEN; i++, num >>= 8) 78 if (addr.addr_bytes[i] != (num & 0xFF)) { 79 return 1; 80 } 81 return 0; 82 } 83 84 /* test invalid parameters */ 85 int 86 test_parse_etheraddr_invalid_param(void) 87 { 88 char buf[CMDLINE_TEST_BUFSIZE]; 89 struct rte_ether_addr result; 90 int ret = 0; 91 92 /* try all null */ 93 ret = cmdline_parse_etheraddr(NULL, NULL, NULL, 0); 94 if (ret != -1) { 95 printf("Error: parser accepted null parameters!\n"); 96 return -1; 97 } 98 99 /* try null buf */ 100 ret = cmdline_parse_etheraddr(NULL, NULL, (void*)&result, 101 sizeof(result)); 102 if (ret != -1) { 103 printf("Error: parser accepted null string!\n"); 104 return -1; 105 } 106 107 /* try null result */ 108 109 /* copy string to buffer */ 110 strlcpy(buf, ether_addr_valid_strs[0].str, sizeof(buf)); 111 112 ret = cmdline_parse_etheraddr(NULL, buf, NULL, 0); 113 if (ret == -1) { 114 printf("Error: parser rejected null result!\n"); 115 return -1; 116 } 117 118 /* token is not used in ether_parse anyway so there's no point in 119 * testing it */ 120 121 /* test help function */ 122 memset(&buf, 0, sizeof(buf)); 123 124 /* coverage! */ 125 ret = cmdline_get_help_etheraddr(NULL, buf, sizeof(buf)); 126 if (ret < 0) { 127 printf("Error: help function failed with valid parameters!\n"); 128 return -1; 129 } 130 131 return 0; 132 } 133 134 /* test valid parameters but invalid data */ 135 int 136 test_parse_etheraddr_invalid_data(void) 137 { 138 int ret = 0; 139 unsigned i; 140 struct rte_ether_addr result; 141 142 /* test full strings */ 143 for (i = 0; i < RTE_DIM(ether_addr_invalid_strs); i++) { 144 145 memset(&result, 0, sizeof(struct rte_ether_addr)); 146 147 ret = cmdline_parse_etheraddr(NULL, ether_addr_invalid_strs[i], 148 (void*)&result, sizeof(result)); 149 if (ret != -1) { 150 printf("Error: parsing %s succeeded!\n", 151 ether_addr_invalid_strs[i]); 152 return -1; 153 } 154 } 155 156 return 0; 157 } 158 159 /* test valid parameters and data */ 160 int 161 test_parse_etheraddr_valid(void) 162 { 163 int ret = 0; 164 unsigned i; 165 struct rte_ether_addr result; 166 167 /* test full strings */ 168 for (i = 0; i < RTE_DIM(ether_addr_valid_strs); i++) { 169 170 memset(&result, 0, sizeof(struct rte_ether_addr)); 171 172 ret = cmdline_parse_etheraddr(NULL, ether_addr_valid_strs[i].str, 173 (void*)&result, sizeof(result)); 174 if (ret < 0) { 175 printf("Error: parsing %s failed!\n", 176 ether_addr_valid_strs[i].str); 177 return -1; 178 } 179 if (is_addr_different(result, ether_addr_valid_strs[i].address)) { 180 printf("Error: parsing %s failed: address mismatch!\n", 181 ether_addr_valid_strs[i].str); 182 return -1; 183 } 184 } 185 186 /* test garbage strings */ 187 for (i = 0; i < RTE_DIM(ether_addr_garbage_strs); i++) { 188 189 memset(&result, 0, sizeof(struct rte_ether_addr)); 190 191 ret = cmdline_parse_etheraddr(NULL, ether_addr_garbage_strs[i], 192 (void*)&result, sizeof(result)); 193 if (ret < 0) { 194 printf("Error: parsing %s failed!\n", 195 ether_addr_garbage_strs[i]); 196 return -1; 197 } 198 if (is_addr_different(result, GARBAGE_ETHERADDR)) { 199 printf("Error: parsing %s failed: address mismatch!\n", 200 ether_addr_garbage_strs[i]); 201 return -1; 202 } 203 } 204 205 return 0; 206 } 207