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 snprintf(buf, sizeof(buf), "%s", 150 ether_addr_valid_strs[0].str); 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 /* coverage! */ 165 ret = cmdline_get_help_etheraddr(NULL, buf, sizeof(buf)); 166 if (ret < 0) { 167 printf("Error: help function failed with valid parameters!\n"); 168 return -1; 169 } 170 171 return 0; 172 } 173 174 /* test valid parameters but invalid data */ 175 int 176 test_parse_etheraddr_invalid_data(void) 177 { 178 int ret = 0; 179 unsigned i; 180 struct ether_addr result; 181 182 /* test full strings */ 183 for (i = 0; i < ETHERADDR_INVALID_STRS_SIZE; i++) { 184 185 memset(&result, 0, sizeof(struct ether_addr)); 186 187 ret = cmdline_parse_etheraddr(NULL, ether_addr_invalid_strs[i], 188 (void*)&result); 189 if (ret != -1) { 190 printf("Error: parsing %s succeeded!\n", 191 ether_addr_invalid_strs[i]); 192 return -1; 193 } 194 } 195 196 return 0; 197 } 198 199 /* test valid parameters and data */ 200 int 201 test_parse_etheraddr_valid(void) 202 { 203 int ret = 0; 204 unsigned i; 205 struct ether_addr result; 206 207 /* test full strings */ 208 for (i = 0; i < ETHERADDR_VALID_STRS_SIZE; i++) { 209 210 memset(&result, 0, sizeof(struct ether_addr)); 211 212 ret = cmdline_parse_etheraddr(NULL, ether_addr_valid_strs[i].str, 213 (void*)&result); 214 if (ret < 0) { 215 printf("Error: parsing %s failed!\n", 216 ether_addr_valid_strs[i].str); 217 return -1; 218 } 219 if (is_addr_different(result, ether_addr_valid_strs[i].address)) { 220 printf("Error: parsing %s failed: address mismatch!\n", 221 ether_addr_valid_strs[i].str); 222 return -1; 223 } 224 } 225 226 /* test garbage strings */ 227 for (i = 0; i < ETHERADDR_GARBAGE_STRS_SIZE; i++) { 228 229 memset(&result, 0, sizeof(struct ether_addr)); 230 231 ret = cmdline_parse_etheraddr(NULL, ether_addr_garbage_strs[i], 232 (void*)&result); 233 if (ret < 0) { 234 printf("Error: parsing %s failed!\n", 235 ether_addr_garbage_strs[i]); 236 return -1; 237 } 238 if (is_addr_different(result, GARBAGE_ETHERADDR)) { 239 printf("Error: parsing %s failed: address mismatch!\n", 240 ether_addr_garbage_strs[i]); 241 return -1; 242 } 243 } 244 245 return 0; 246 } 247