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