Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2010-2014 Intel Corporation 3 : : */ 4 : : 5 : : #include <stdbool.h> 6 : : 7 : : #include <eal_export.h> 8 : : #include <rte_ether.h> 9 : : #include <rte_errno.h> 10 : : 11 : : RTE_EXPORT_SYMBOL(rte_eth_random_addr) 12 : : void 13 : 2000007 : rte_eth_random_addr(uint8_t *addr) 14 : : { 15 [ - + ]: 2000007 : uint64_t rand = rte_rand(); 16 : : uint8_t *p = (uint8_t *)&rand; 17 : : 18 : : rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN); 19 : 2000007 : addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR; /* clear multicast bit */ 20 : 2000007 : addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR; /* set local assignment bit */ 21 : 2000007 : } 22 : : 23 : : RTE_EXPORT_SYMBOL(rte_ether_format_addr) 24 : : void 25 : 1000000 : rte_ether_format_addr(char *buf, uint16_t size, 26 : : const struct rte_ether_addr *eth_addr) 27 : : { 28 : 1000000 : snprintf(buf, size, RTE_ETHER_ADDR_PRT_FMT, 29 : 1000000 : RTE_ETHER_ADDR_BYTES(eth_addr)); 30 : 1000000 : } 31 : : 32 : : static int8_t get_xdigit(char ch) 33 : : { 34 : 12000242 : if (ch >= '0' && ch <= '9') 35 : 7376532 : return ch - '0'; 36 [ - + + + : 4623710 : if (ch >= 'a' && ch <= 'f') + + ] 37 : 4 : return ch - 'a' + 10; 38 [ + + + + : 4623706 : if (ch >= 'A' && ch <= 'F') + - ] 39 : 4623699 : return ch - 'A' + 10; 40 : : return -1; 41 : : } 42 : : 43 : : /* Convert 00:11:22:33:44:55 to ethernet address */ 44 : 1000020 : static bool get_ether_addr6(const char *s0, struct rte_ether_addr *ea, 45 : : const char sep) 46 : : { 47 : : const char *s = s0; 48 : : int i; 49 : : 50 [ + + ]: 7000127 : for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) { 51 : : int8_t x; 52 : : 53 [ + + ]: 6000110 : x = get_xdigit(*s++); 54 : : if (x < 0) 55 : : return false; /* not a hex digit */ 56 : : 57 : 6000108 : ea->addr_bytes[i] = x; 58 [ + + + + ]: 6000108 : if (*s != sep && *s != '\0') { 59 [ + + ]: 6000096 : x = get_xdigit(*s++); 60 : : if (x < 0) 61 : : return false; /* not a hex digit */ 62 : 6000096 : ea->addr_bytes[i] <<= 4; 63 : 6000096 : ea->addr_bytes[i] |= x; 64 : : } 65 : : 66 [ + + ]: 6000108 : if (i < RTE_ETHER_ADDR_LEN - 1 && 67 [ + + ]: 5000091 : *s++ != sep) 68 : : return false; /* premature end of string */ 69 : : } 70 : : 71 : : /* return true if no trailing characters */ 72 : 1000017 : return *s == '\0'; 73 : : } 74 : : 75 : : /* Convert 0011:2233:4455 to ethernet address */ 76 : 7 : static bool get_ether_addr3(const char *s, struct rte_ether_addr *ea, 77 : : const char sep) 78 : : { 79 : : int i, j; 80 : : 81 [ + + ]: 13 : for (i = 0; i < RTE_ETHER_ADDR_LEN; i += 2) { 82 : : uint16_t w = 0; 83 : : 84 [ + + ]: 42 : for (j = 0; j < 4; j++) { 85 : : int8_t x; 86 : : 87 [ + + ]: 36 : x = get_xdigit(*s++); 88 : : if (x < 0) 89 : : return false; /* not a hex digit */ 90 : 31 : w = (w << 4) | x; 91 : : } 92 : : 93 : 6 : ea->addr_bytes[i] = w >> 8; 94 : 6 : ea->addr_bytes[i + 1] = w & 0xff; 95 : : 96 [ + + ]: 6 : if (i < RTE_ETHER_ADDR_LEN - 2 && 97 [ + - ]: 4 : *s++ != sep) 98 : : return false; 99 : : } 100 : : 101 : 2 : return *s == '\0'; 102 : : } 103 : : 104 : : /* 105 : : * Scan input to see if separated by dash, colon or period 106 : : * Returns separator and number of matches 107 : : * If separators are mixed will return 108 : : */ 109 : 1000045 : static unsigned int get_ether_sep(const char *s, char *sep) 110 : : { 111 : : static const char separators[] = "-:."; 112 : : unsigned int count = 0; 113 : : const char *cp; 114 : : 115 : 1000045 : cp = strpbrk(s, separators); 116 [ + + ]: 1000045 : if (cp == NULL) 117 : : return 0; /* no separator found */ 118 : : 119 : 1000038 : *sep = *cp; /* return the separator */ 120 : : do { 121 : 5000153 : ++count; 122 : : /* find next instance of separator */ 123 : 5000153 : cp = strchr(cp + 1, *sep); 124 [ + + ]: 5000153 : } while (cp != NULL); 125 : : 126 : : return count; 127 : : } 128 : : 129 : : /* 130 : : * Be liberal in accepting a wide variety of notational formats 131 : : * for MAC address including: 132 : : * - Linux format six groups of hexadecimal digits separated by colon 133 : : * - Windows format six groups separated by hyphen 134 : : * - two groups hexadecimal digits 135 : : */ 136 : : RTE_EXPORT_SYMBOL(rte_ether_unformat_addr) 137 : : int 138 : 1000045 : rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea) 139 : : { 140 : : unsigned int count; 141 : 1000045 : char sep = '\0'; 142 : : 143 : 1000045 : count = get_ether_sep(s, &sep); 144 [ + + + ]: 1000045 : switch (count) { 145 : 1000020 : case 5: /* i.e 01:23:45:67:89:AB */ 146 [ + + ]: 1000020 : if (get_ether_addr6(s, ea, sep)) 147 : : return 0; 148 : : break; 149 : 7 : case 2: /* i.e 0123.4567.89AB */ 150 [ + + ]: 7 : if (get_ether_addr3(s, ea, sep)) 151 : : return 0; 152 : : break; 153 : : default: 154 : : break; 155 : : } 156 : : 157 : 26 : rte_errno = EINVAL; 158 : 26 : return -1; 159 : : }