1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 2a9de470cSBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 3a9de470cSBruce Richardson */ 4a9de470cSBruce Richardson 5a9de470cSBruce Richardson #include <stdio.h> 6a9de470cSBruce Richardson #include <string.h> 7a9de470cSBruce Richardson #include <inttypes.h> 8a9de470cSBruce Richardson 9a9de470cSBruce Richardson #include <rte_ether.h> 10a9de470cSBruce Richardson #include <rte_string_fns.h> 11a9de470cSBruce Richardson 12a9de470cSBruce Richardson #include <cmdline_parse.h> 13a9de470cSBruce Richardson #include <cmdline_parse_etheraddr.h> 14a9de470cSBruce Richardson 15a9de470cSBruce Richardson #include "test_cmdline.h" 16a9de470cSBruce Richardson 17a9de470cSBruce Richardson struct ether_addr_str { 18a9de470cSBruce Richardson const char * str; 19a9de470cSBruce Richardson uint64_t address; 20a9de470cSBruce Richardson }; 21a9de470cSBruce Richardson 22a9de470cSBruce Richardson /* valid strings */ 23a9de470cSBruce Richardson const struct ether_addr_str ether_addr_valid_strs[] = { 24a9de470cSBruce Richardson {"01:23:45:67:89:AB", 0xAB8967452301ULL}, 25a9de470cSBruce Richardson {"4567:89AB:CDEF", 0xEFCDAB896745ULL}, 26a9de470cSBruce Richardson }; 27a9de470cSBruce Richardson 28a9de470cSBruce Richardson /* valid strings with various garbage at the end. 29a9de470cSBruce Richardson * these strings are still valid because parser checks for 30a9de470cSBruce Richardson * end of token, which is either space chars, null char or 31a9de470cSBruce Richardson * a hash sign. 32a9de470cSBruce Richardson */ 33a9de470cSBruce Richardson const char * ether_addr_garbage_strs[] = { 34a9de470cSBruce Richardson "00:11:22:33:44:55\0garbage", 35a9de470cSBruce Richardson "00:11:22:33:44:55#garbage", 36a9de470cSBruce Richardson "00:11:22:33:44:55 garbage", 37a9de470cSBruce Richardson "00:11:22:33:44:55\tgarbage", 38a9de470cSBruce Richardson "00:11:22:33:44:55\ngarbage", 39a9de470cSBruce Richardson "00:11:22:33:44:55\rgarbage", 40a9de470cSBruce Richardson "00:11:22:33:44:55#", 41a9de470cSBruce Richardson "00:11:22:33:44:55 ", 42a9de470cSBruce Richardson "00:11:22:33:44:55\t", 43a9de470cSBruce Richardson "00:11:22:33:44:55\n", 44a9de470cSBruce Richardson "00:11:22:33:44:55\r", 45a9de470cSBruce Richardson }; 46a9de470cSBruce Richardson #define GARBAGE_ETHERADDR 0x554433221100ULL /* corresponding address */ 47a9de470cSBruce Richardson 48a9de470cSBruce Richardson 49a9de470cSBruce Richardson const char * ether_addr_invalid_strs[] = { 50a9de470cSBruce Richardson /* valid chars, invalid syntax */ 51a9de470cSBruce Richardson "0123:45:67:89:AB", 52a9de470cSBruce Richardson "01:23:4567:89:AB", 53a9de470cSBruce Richardson "01:23:45:67:89AB", 54a9de470cSBruce Richardson "012:345:678:9AB", 55a9de470cSBruce Richardson "01:23:45:67:89:ABC", 56a9de470cSBruce Richardson "01:23:45:67:89:A", 57a9de470cSBruce Richardson "01:23:45:67:89", 58a9de470cSBruce Richardson "01:23:45:67:89:AB:CD", 59a9de470cSBruce Richardson /* invalid chars, valid syntax */ 60a9de470cSBruce Richardson "IN:VA:LI:DC:HA:RS", 61a9de470cSBruce Richardson "INVA:LIDC:HARS", 62a9de470cSBruce Richardson /* misc */ 63a9de470cSBruce Richardson "01 23 45 67 89 AB", 64a9de470cSBruce Richardson "01.23.45.67.89.AB", 65a9de470cSBruce Richardson "01,23,45,67,89,AB", 66a9de470cSBruce Richardson "01:23:45\0:67:89:AB", 67a9de470cSBruce Richardson "01:23:45#:67:89:AB", 68a9de470cSBruce Richardson "random invalid text", 69a9de470cSBruce Richardson "random text", 70a9de470cSBruce Richardson "", 71a9de470cSBruce Richardson "\0", 72a9de470cSBruce Richardson " ", 73a9de470cSBruce Richardson }; 74a9de470cSBruce Richardson 75a9de470cSBruce Richardson static int 766d13ea8eSOlivier Matz is_addr_different(const struct rte_ether_addr addr, uint64_t num) 77a9de470cSBruce Richardson { 78a9de470cSBruce Richardson int i; 7935b2d13fSOlivier Matz for (i = 0; i < RTE_ETHER_ADDR_LEN; i++, num >>= 8) 80a9de470cSBruce Richardson if (addr.addr_bytes[i] != (num & 0xFF)) { 81a9de470cSBruce Richardson return 1; 82a9de470cSBruce Richardson } 83a9de470cSBruce Richardson return 0; 84a9de470cSBruce Richardson } 85a9de470cSBruce Richardson 86a9de470cSBruce Richardson /* test invalid parameters */ 87a9de470cSBruce Richardson int 88a9de470cSBruce Richardson test_parse_etheraddr_invalid_param(void) 89a9de470cSBruce Richardson { 90a9de470cSBruce Richardson char buf[CMDLINE_TEST_BUFSIZE]; 916d13ea8eSOlivier Matz struct rte_ether_addr result; 92a9de470cSBruce Richardson int ret = 0; 93a9de470cSBruce Richardson 94a9de470cSBruce Richardson /* try all null */ 95a9de470cSBruce Richardson ret = cmdline_parse_etheraddr(NULL, NULL, NULL, 0); 96a9de470cSBruce Richardson if (ret != -1) { 97a9de470cSBruce Richardson printf("Error: parser accepted null parameters!\n"); 98a9de470cSBruce Richardson return -1; 99a9de470cSBruce Richardson } 100a9de470cSBruce Richardson 101a9de470cSBruce Richardson /* try null buf */ 102a9de470cSBruce Richardson ret = cmdline_parse_etheraddr(NULL, NULL, (void*)&result, 103a9de470cSBruce Richardson sizeof(result)); 104a9de470cSBruce Richardson if (ret != -1) { 105a9de470cSBruce Richardson printf("Error: parser accepted null string!\n"); 106a9de470cSBruce Richardson return -1; 107a9de470cSBruce Richardson } 108a9de470cSBruce Richardson 109a9de470cSBruce Richardson /* try null result */ 110a9de470cSBruce Richardson 111a9de470cSBruce Richardson /* copy string to buffer */ 112f9acaf84SBruce Richardson strlcpy(buf, ether_addr_valid_strs[0].str, sizeof(buf)); 113a9de470cSBruce Richardson 114a9de470cSBruce Richardson ret = cmdline_parse_etheraddr(NULL, buf, NULL, 0); 115a9de470cSBruce Richardson if (ret == -1) { 116a9de470cSBruce Richardson printf("Error: parser rejected null result!\n"); 117a9de470cSBruce Richardson return -1; 118a9de470cSBruce Richardson } 119a9de470cSBruce Richardson 120a9de470cSBruce Richardson /* token is not used in ether_parse anyway so there's no point in 121a9de470cSBruce Richardson * testing it */ 122a9de470cSBruce Richardson 123a9de470cSBruce Richardson /* test help function */ 124a9de470cSBruce Richardson memset(&buf, 0, sizeof(buf)); 125a9de470cSBruce Richardson 126a9de470cSBruce Richardson /* coverage! */ 127a9de470cSBruce Richardson ret = cmdline_get_help_etheraddr(NULL, buf, sizeof(buf)); 128a9de470cSBruce Richardson if (ret < 0) { 129a9de470cSBruce Richardson printf("Error: help function failed with valid parameters!\n"); 130a9de470cSBruce Richardson return -1; 131a9de470cSBruce Richardson } 132a9de470cSBruce Richardson 133a9de470cSBruce Richardson return 0; 134a9de470cSBruce Richardson } 135a9de470cSBruce Richardson 136a9de470cSBruce Richardson /* test valid parameters but invalid data */ 137a9de470cSBruce Richardson int 138a9de470cSBruce Richardson test_parse_etheraddr_invalid_data(void) 139a9de470cSBruce Richardson { 140a9de470cSBruce Richardson int ret = 0; 141a9de470cSBruce Richardson unsigned i; 1426d13ea8eSOlivier Matz struct rte_ether_addr result; 143a9de470cSBruce Richardson 144a9de470cSBruce Richardson /* test full strings */ 145*71bdd8a1SPavan Nikhilesh for (i = 0; i < RTE_DIM(ether_addr_invalid_strs); i++) { 146a9de470cSBruce Richardson 1476d13ea8eSOlivier Matz memset(&result, 0, sizeof(struct rte_ether_addr)); 148a9de470cSBruce Richardson 149a9de470cSBruce Richardson ret = cmdline_parse_etheraddr(NULL, ether_addr_invalid_strs[i], 150a9de470cSBruce Richardson (void*)&result, sizeof(result)); 151a9de470cSBruce Richardson if (ret != -1) { 152a9de470cSBruce Richardson printf("Error: parsing %s succeeded!\n", 153a9de470cSBruce Richardson ether_addr_invalid_strs[i]); 154a9de470cSBruce Richardson return -1; 155a9de470cSBruce Richardson } 156a9de470cSBruce Richardson } 157a9de470cSBruce Richardson 158a9de470cSBruce Richardson return 0; 159a9de470cSBruce Richardson } 160a9de470cSBruce Richardson 161a9de470cSBruce Richardson /* test valid parameters and data */ 162a9de470cSBruce Richardson int 163a9de470cSBruce Richardson test_parse_etheraddr_valid(void) 164a9de470cSBruce Richardson { 165a9de470cSBruce Richardson int ret = 0; 166a9de470cSBruce Richardson unsigned i; 1676d13ea8eSOlivier Matz struct rte_ether_addr result; 168a9de470cSBruce Richardson 169a9de470cSBruce Richardson /* test full strings */ 170*71bdd8a1SPavan Nikhilesh for (i = 0; i < RTE_DIM(ether_addr_valid_strs); i++) { 171a9de470cSBruce Richardson 1726d13ea8eSOlivier Matz memset(&result, 0, sizeof(struct rte_ether_addr)); 173a9de470cSBruce Richardson 174a9de470cSBruce Richardson ret = cmdline_parse_etheraddr(NULL, ether_addr_valid_strs[i].str, 175a9de470cSBruce Richardson (void*)&result, sizeof(result)); 176a9de470cSBruce Richardson if (ret < 0) { 177a9de470cSBruce Richardson printf("Error: parsing %s failed!\n", 178a9de470cSBruce Richardson ether_addr_valid_strs[i].str); 179a9de470cSBruce Richardson return -1; 180a9de470cSBruce Richardson } 181a9de470cSBruce Richardson if (is_addr_different(result, ether_addr_valid_strs[i].address)) { 182a9de470cSBruce Richardson printf("Error: parsing %s failed: address mismatch!\n", 183a9de470cSBruce Richardson ether_addr_valid_strs[i].str); 184a9de470cSBruce Richardson return -1; 185a9de470cSBruce Richardson } 186a9de470cSBruce Richardson } 187a9de470cSBruce Richardson 188a9de470cSBruce Richardson /* test garbage strings */ 189*71bdd8a1SPavan Nikhilesh for (i = 0; i < RTE_DIM(ether_addr_garbage_strs); i++) { 190a9de470cSBruce Richardson 1916d13ea8eSOlivier Matz memset(&result, 0, sizeof(struct rte_ether_addr)); 192a9de470cSBruce Richardson 193a9de470cSBruce Richardson ret = cmdline_parse_etheraddr(NULL, ether_addr_garbage_strs[i], 194a9de470cSBruce Richardson (void*)&result, sizeof(result)); 195a9de470cSBruce Richardson if (ret < 0) { 196a9de470cSBruce Richardson printf("Error: parsing %s failed!\n", 197a9de470cSBruce Richardson ether_addr_garbage_strs[i]); 198a9de470cSBruce Richardson return -1; 199a9de470cSBruce Richardson } 200a9de470cSBruce Richardson if (is_addr_different(result, GARBAGE_ETHERADDR)) { 201a9de470cSBruce Richardson printf("Error: parsing %s failed: address mismatch!\n", 202a9de470cSBruce Richardson ether_addr_garbage_strs[i]); 203a9de470cSBruce Richardson return -1; 204a9de470cSBruce Richardson } 205a9de470cSBruce Richardson } 206a9de470cSBruce Richardson 207a9de470cSBruce Richardson return 0; 208a9de470cSBruce Richardson } 209