1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <stdbool.h> 6 7 #include <rte_ether.h> 8 #include <rte_errno.h> 9 10 void 11 rte_eth_random_addr(uint8_t *addr) 12 { 13 #ifdef RTE_EXEC_ENV_WINDOWS /* FIXME: random is not supported */ 14 RTE_SET_USED(addr); 15 #else 16 uint64_t rand = rte_rand(); 17 uint8_t *p = (uint8_t *)&rand; 18 19 rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN); 20 addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR; /* clear multicast bit */ 21 addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR; /* set local assignment bit */ 22 #endif 23 } 24 25 void 26 rte_ether_format_addr(char *buf, uint16_t size, 27 const struct rte_ether_addr *eth_addr) 28 { 29 snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X", 30 eth_addr->addr_bytes[0], 31 eth_addr->addr_bytes[1], 32 eth_addr->addr_bytes[2], 33 eth_addr->addr_bytes[3], 34 eth_addr->addr_bytes[4], 35 eth_addr->addr_bytes[5]); 36 } 37 38 static int8_t get_xdigit(char ch) 39 { 40 if (ch >= '0' && ch <= '9') 41 return ch - '0'; 42 if (ch >= 'a' && ch <= 'f') 43 return ch - 'a' + 10; 44 if (ch >= 'A' && ch <= 'F') 45 return ch - 'A' + 10; 46 return -1; 47 } 48 49 /* Convert 00:11:22:33:44:55 to ethernet address */ 50 static bool get_ether_addr6(const char *s0, struct rte_ether_addr *ea) 51 { 52 const char *s = s0; 53 int i; 54 55 for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) { 56 int8_t x; 57 58 x = get_xdigit(*s++); 59 if (x < 0) 60 return false; 61 62 ea->addr_bytes[i] = x << 4; 63 x = get_xdigit(*s++); 64 if (x < 0) 65 return false; 66 ea->addr_bytes[i] |= x; 67 68 if (i < RTE_ETHER_ADDR_LEN - 1 && 69 *s++ != ':') 70 return false; 71 } 72 73 /* return true if at end of string */ 74 return *s == '\0'; 75 } 76 77 /* Convert 0011:2233:4455 to ethernet address */ 78 static bool get_ether_addr3(const char *s, struct rte_ether_addr *ea) 79 { 80 int i, j; 81 82 for (i = 0; i < RTE_ETHER_ADDR_LEN; i += 2) { 83 uint16_t w = 0; 84 85 for (j = 0; j < 4; j++) { 86 int8_t x; 87 88 x = get_xdigit(*s++); 89 if (x < 0) 90 return false; 91 w = (w << 4) | x; 92 } 93 ea->addr_bytes[i] = w >> 8; 94 ea->addr_bytes[i + 1] = w & 0xff; 95 96 if (i < RTE_ETHER_ADDR_LEN - 2 && 97 *s++ != ':') 98 return false; 99 } 100 101 return *s == '\0'; 102 } 103 104 /* 105 * Like ether_aton_r but can handle either 106 * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX 107 * and is more restrictive. 108 */ 109 int 110 rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea) 111 { 112 if (get_ether_addr6(s, ea)) 113 return 0; 114 if (get_ether_addr3(s, ea)) 115 return 0; 116 117 rte_errno = EINVAL; 118 return -1; 119 } 120