1 /* 2 * Copyright 2019, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include "hash.h" 20 21 #include <linux/if_ether.h> 22 #include <stdint.h> 23 #include <string.h> 24 25 // Format macros for printf, e.g. printf("MAC address: " PRIMAC, MACARG(mac)) 26 #define PRIMAC "%02x:%02x:%02x:%02x:%02x:%02x" 27 #define MACARG(x) (x)[0], (x)[1], (x)[2], (x)[3],(x)[4], (x)[5] 28 29 struct MacAddress { MacAddressMacAddress30 MacAddress() { 31 memset(addr, 0, sizeof(addr)); 32 } MacAddressMacAddress33 MacAddress(uint8_t b1, uint8_t b2, uint8_t b3, 34 uint8_t b4, uint8_t b5, uint8_t b6) { 35 addr[0] = b1; addr[1] = b2; addr[2] = b3; 36 addr[3] = b4; addr[4] = b5; addr[5] = b6; 37 } 38 uint8_t addr[ETH_ALEN]; isBroadcastMacAddress39 bool isBroadcast() const { 40 return memcmp(addr, "\xFF\xFF\xFF\xFF\xFF\xFF", ETH_ALEN) == 0; 41 } isMulticastMacAddress42 bool isMulticast() const { 43 return addr[0] & 0x01; 44 } emptyMacAddress45 bool empty() const { 46 return memcmp(addr, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0; 47 } 48 uint8_t operator[](size_t index) const { 49 return addr[index]; 50 } 51 } __attribute__((__packed__)); 52 53 namespace std { 54 template<> struct hash<MacAddress> { 55 size_t operator()(const MacAddress& addr) const { 56 size_t seed = 0; 57 // Treat the first 4 bytes as an uint32_t to save some computation 58 hash_combine(seed, *reinterpret_cast<const uint32_t*>(addr.addr)); 59 // And the remaining 2 bytes as an uint16_t 60 hash_combine(seed, *reinterpret_cast<const uint16_t*>(addr.addr + 4)); 61 return seed; 62 } 63 }; 64 } 65 66 inline bool operator==(const MacAddress& left, const MacAddress& right) { 67 return memcmp(left.addr, right.addr, ETH_ALEN) == 0; 68 } 69 70 inline bool operator!=(const MacAddress& left, const MacAddress& right) { 71 return memcmp(left.addr, right.addr, ETH_ALEN) != 0; 72 } 73 74