1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <stdio.h> 35 #include <string.h> 36 #include <inttypes.h> 37 38 #include <rte_ether.h> 39 #include <rte_string_fns.h> 40 41 #include <cmdline_parse.h> 42 #include <cmdline_parse_etheraddr.h> 43 44 #include "test_cmdline.h" 45 46 struct ether_addr_str { 47 const char * str; 48 uint64_t address; 49 }; 50 51 /* valid strings */ 52 const struct ether_addr_str ether_addr_valid_strs[] = { 53 {"01:23:45:67:89:AB", 0xAB8967452301ULL}, 54 {"4567:89AB:CDEF", 0xEFCDAB896745ULL}, 55 }; 56 57 /* valid strings with various garbage at the end. 58 * these strings are still valid because parser checks for 59 * end of token, which is either space chars, null char or 60 * a hash sign. 61 */ 62 const char * ether_addr_garbage_strs[] = { 63 "00:11:22:33:44:55\0garbage", 64 "00:11:22:33:44:55#garbage", 65 "00:11:22:33:44:55 garbage", 66 "00:11:22:33:44:55\tgarbage", 67 "00:11:22:33:44:55\ngarbage", 68 "00:11:22:33:44:55\rgarbage", 69 "00:11:22:33:44:55#", 70 "00:11:22:33:44:55 ", 71 "00:11:22:33:44:55\t", 72 "00:11:22:33:44:55\n", 73 "00:11:22:33:44:55\r", 74 }; 75 #define GARBAGE_ETHERADDR 0x554433221100ULL /* corresponding address */ 76 77 78 const char * ether_addr_invalid_strs[] = { 79 /* valid chars, invalid syntax */ 80 "0123:45:67:89:AB", 81 "01:23:4567:89:AB", 82 "01:23:45:67:89AB", 83 "012:345:678:9AB", 84 "01:23:45:67:89:ABC", 85 "01:23:45:67:89:A", 86 "01:23:45:67:89", 87 "01:23:45:67:89:AB:CD", 88 /* invalid chars, valid syntax */ 89 "IN:VA:LI:DC:HA:RS", 90 "INVA:LIDC:HARS", 91 /* misc */ 92 "01 23 45 67 89 AB", 93 "01.23.45.67.89.AB", 94 "01,23,45,67,89,AB", 95 "01:23:45\0:67:89:AB", 96 "01:23:45#:67:89:AB", 97 "random invalid text", 98 "random text", 99 "", 100 "\0", 101 " ", 102 }; 103 104 #define ETHERADDR_VALID_STRS_SIZE \ 105 (sizeof(ether_addr_valid_strs) / sizeof(ether_addr_valid_strs[0])) 106 #define ETHERADDR_GARBAGE_STRS_SIZE \ 107 (sizeof(ether_addr_garbage_strs) / sizeof(ether_addr_garbage_strs[0])) 108 #define ETHERADDR_INVALID_STRS_SIZE \ 109 (sizeof(ether_addr_invalid_strs) / sizeof(ether_addr_invalid_strs[0])) 110 111 112 113 static int 114 is_addr_different(const struct ether_addr addr, uint64_t num) 115 { 116 int i; 117 for (i = 0; i < ETHER_ADDR_LEN; i++, num >>= 8) 118 if (addr.addr_bytes[i] != (num & 0xFF)) { 119 return 1; 120 } 121 return 0; 122 } 123 124 /* test invalid parameters */ 125 int 126 test_parse_etheraddr_invalid_param(void) 127 { 128 char buf[CMDLINE_TEST_BUFSIZE]; 129 struct ether_addr result; 130 int ret = 0; 131 132 /* try all null */ 133 ret = cmdline_parse_etheraddr(NULL, NULL, NULL); 134 if (ret != -1) { 135 printf("Error: parser accepted null parameters!\n"); 136 return -1; 137 } 138 139 /* try null buf */ 140 ret = cmdline_parse_etheraddr(NULL, NULL, (void*)&result); 141 if (ret != -1) { 142 printf("Error: parser accepted null string!\n"); 143 return -1; 144 } 145 146 /* try null result */ 147 148 /* copy string to buffer */ 149 rte_snprintf(buf, sizeof(buf), "%s", 150 ether_addr_valid_strs[0]); 151 152 ret = cmdline_parse_etheraddr(NULL, buf, NULL); 153 if (ret == -1) { 154 printf("Error: parser rejected null result!\n"); 155 return -1; 156 } 157 158 /* token is not used in ether_parse anyway so there's no point in 159 * testing it */ 160 161 /* test help function */ 162 memset(&buf, 0, sizeof(buf)); 163 164 /* try null buf */ 165 ret = cmdline_get_help_etheraddr(NULL, NULL, sizeof(buf)); 166 if (ret != -1) { 167 printf("Error: help function accepted null buffer!\n"); 168 return -1; 169 } 170 171 /* coverage! */ 172 ret = cmdline_get_help_etheraddr(NULL, buf, sizeof(buf)); 173 if (ret < 0) { 174 printf("Error: help function failed with valid parameters!\n"); 175 return -1; 176 } 177 178 return 0; 179 } 180 181 /* test valid parameters but invalid data */ 182 int 183 test_parse_etheraddr_invalid_data(void) 184 { 185 int ret = 0; 186 unsigned i; 187 struct ether_addr result; 188 189 /* test full strings */ 190 for (i = 0; i < ETHERADDR_INVALID_STRS_SIZE; i++) { 191 192 memset(&result, 0, sizeof(struct ether_addr)); 193 194 ret = cmdline_parse_etheraddr(NULL, ether_addr_invalid_strs[i], 195 (void*)&result); 196 if (ret != -1) { 197 printf("Error: parsing %s succeeded!\n", 198 ether_addr_invalid_strs[i]); 199 return -1; 200 } 201 } 202 203 return 0; 204 } 205 206 /* test valid parameters and data */ 207 int 208 test_parse_etheraddr_valid(void) 209 { 210 int ret = 0; 211 unsigned i; 212 struct ether_addr result; 213 214 /* test full strings */ 215 for (i = 0; i < ETHERADDR_VALID_STRS_SIZE; i++) { 216 217 memset(&result, 0, sizeof(struct ether_addr)); 218 219 ret = cmdline_parse_etheraddr(NULL, ether_addr_valid_strs[i].str, 220 (void*)&result); 221 if (ret < 0) { 222 printf("Error: parsing %s failed!\n", 223 ether_addr_valid_strs[i].str); 224 return -1; 225 } 226 if (is_addr_different(result, ether_addr_valid_strs[i].address)) { 227 printf("Error: parsing %s failed: address mismatch!\n", 228 ether_addr_valid_strs[i].str); 229 return -1; 230 } 231 } 232 233 /* test garbage strings */ 234 for (i = 0; i < ETHERADDR_GARBAGE_STRS_SIZE; i++) { 235 236 memset(&result, 0, sizeof(struct ether_addr)); 237 238 ret = cmdline_parse_etheraddr(NULL, ether_addr_garbage_strs[i], 239 (void*)&result); 240 if (ret < 0) { 241 printf("Error: parsing %s failed!\n", 242 ether_addr_garbage_strs[i]); 243 return -1; 244 } 245 if (is_addr_different(result, GARBAGE_ETHERADDR)) { 246 printf("Error: parsing %s failed: address mismatch!\n", 247 ether_addr_garbage_strs[i]); 248 return -1; 249 } 250 } 251 252 return 0; 253 } 254