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