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, 0); 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 sizeof(result)); 142 if (ret != -1) { 143 printf("Error: parser accepted null string!\n"); 144 return -1; 145 } 146 147 /* try null result */ 148 149 /* copy string to buffer */ 150 snprintf(buf, sizeof(buf), "%s", 151 ether_addr_valid_strs[0].str); 152 153 ret = cmdline_parse_etheraddr(NULL, buf, NULL, 0); 154 if (ret == -1) { 155 printf("Error: parser rejected null result!\n"); 156 return -1; 157 } 158 159 /* token is not used in ether_parse anyway so there's no point in 160 * testing it */ 161 162 /* test help function */ 163 memset(&buf, 0, sizeof(buf)); 164 165 /* coverage! */ 166 ret = cmdline_get_help_etheraddr(NULL, buf, sizeof(buf)); 167 if (ret < 0) { 168 printf("Error: help function failed with valid parameters!\n"); 169 return -1; 170 } 171 172 return 0; 173 } 174 175 /* test valid parameters but invalid data */ 176 int 177 test_parse_etheraddr_invalid_data(void) 178 { 179 int ret = 0; 180 unsigned i; 181 struct ether_addr result; 182 183 /* test full strings */ 184 for (i = 0; i < ETHERADDR_INVALID_STRS_SIZE; i++) { 185 186 memset(&result, 0, sizeof(struct ether_addr)); 187 188 ret = cmdline_parse_etheraddr(NULL, ether_addr_invalid_strs[i], 189 (void*)&result, sizeof(result)); 190 if (ret != -1) { 191 printf("Error: parsing %s succeeded!\n", 192 ether_addr_invalid_strs[i]); 193 return -1; 194 } 195 } 196 197 return 0; 198 } 199 200 /* test valid parameters and data */ 201 int 202 test_parse_etheraddr_valid(void) 203 { 204 int ret = 0; 205 unsigned i; 206 struct ether_addr result; 207 208 /* test full strings */ 209 for (i = 0; i < ETHERADDR_VALID_STRS_SIZE; i++) { 210 211 memset(&result, 0, sizeof(struct ether_addr)); 212 213 ret = cmdline_parse_etheraddr(NULL, ether_addr_valid_strs[i].str, 214 (void*)&result, sizeof(result)); 215 if (ret < 0) { 216 printf("Error: parsing %s failed!\n", 217 ether_addr_valid_strs[i].str); 218 return -1; 219 } 220 if (is_addr_different(result, ether_addr_valid_strs[i].address)) { 221 printf("Error: parsing %s failed: address mismatch!\n", 222 ether_addr_valid_strs[i].str); 223 return -1; 224 } 225 } 226 227 /* test garbage strings */ 228 for (i = 0; i < ETHERADDR_GARBAGE_STRS_SIZE; i++) { 229 230 memset(&result, 0, sizeof(struct ether_addr)); 231 232 ret = cmdline_parse_etheraddr(NULL, ether_addr_garbage_strs[i], 233 (void*)&result, sizeof(result)); 234 if (ret < 0) { 235 printf("Error: parsing %s failed!\n", 236 ether_addr_garbage_strs[i]); 237 return -1; 238 } 239 if (is_addr_different(result, GARBAGE_ETHERADDR)) { 240 printf("Error: parsing %s failed: address mismatch!\n", 241 ether_addr_garbage_strs[i]); 242 return -1; 243 } 244 } 245 246 return 0; 247 } 248