Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #include "net/mac_address.h"
7 :
8 : #include <cstring>
9 : #include <cstdio>
10 : #if defined(__linux__)
11 : # include <netinet/ether.h>
12 : #endif
13 :
14 : #include "base/parse_object.h"
15 :
16 : using namespace std;
17 :
18 : const MacAddress MacAddress::kZeroMac(0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
19 : const MacAddress MacAddress::kBroadcastMac(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
20 : const MacAddress MacAddress::kMulticastMac(0x01, 0x00, 0x5E, 0, 0, 0);
21 :
22 15850975 : MacAddress::MacAddress() {
23 15850975 : memset(&addr_, 0, sizeof(addr_));
24 15850975 : }
25 :
26 80379 : MacAddress::MacAddress(const uint8_t *data) {
27 80379 : memcpy(&addr_, data, sizeof(addr_));
28 80379 : }
29 :
30 373384 : bool MacAddress::IsZero() const {
31 373384 : return CompareTo(ZeroMac()) == 0;
32 : }
33 :
34 1037766 : bool MacAddress::IsBroadcast() const {
35 1037766 : return CompareTo(BroadcastMac()) == 0;
36 : }
37 :
38 0 : bool MacAddress::IsMulticast() const {
39 0 : return CompareTo(MulticastMac(), 3) == 0;
40 : }
41 :
42 3233 : MacAddress::MacAddress(unsigned int a, unsigned int b, unsigned int c,
43 3233 : unsigned int d, unsigned int e, unsigned int f) {
44 3233 : u_int8_t *p = (u_int8_t *)&addr_;
45 :
46 3233 : p[0] = a; p[1] = b; p[2] = c; p[3] = d; p[4] = e; p[5] = f;
47 3233 : }
48 :
49 1407 : MacAddress::MacAddress(const std::string &s,
50 1407 : boost::system::error_code *errorp) {
51 1407 : *this = FromString(s, errorp);
52 1407 : }
53 :
54 1325886 : string MacAddress::ToString() const {
55 : static char hexchars[] = {
56 : '0', '1', '2', '3', '4', '5', '6', '7',
57 : '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
58 : };
59 : char temp[32];
60 1325886 : const u_int8_t *addr = (u_int8_t *) &addr_;
61 1325886 : int tidx = 0;
62 9281192 : for (int bidx = 0; bidx < 6; ++bidx) {
63 7955306 : if (bidx != 0)
64 6629431 : temp[tidx++] = ':';
65 7955306 : temp[tidx++] = hexchars[(addr[bidx] >> 4) & 0x0F];
66 7955306 : temp[tidx++] = hexchars[addr[bidx] & 0x0F];
67 : }
68 1325886 : temp[tidx] = '\0';
69 1325886 : return temp;
70 : }
71 :
72 43087 : MacAddress MacAddress::FromString(const std::string &str,
73 : boost::system::error_code *errorp) {
74 : struct ether_addr a;
75 43087 : u_int8_t *p = (u_int8_t*)&a;
76 : char extra;
77 :
78 43087 : int ret = sscanf(str.c_str(), "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx%c",
79 : &p[0], &p[1], &p[2], &p[3], &p[4], &p[5], &extra);
80 43088 : if ((size_t)ret != size() || strchr(str.c_str(), 'x') || strchr(str.c_str(), 'X')) {
81 1483 : if (errorp != NULL)
82 433 : *errorp = make_error_code(boost::system::errc::invalid_argument);
83 1483 : return MacAddress();
84 : }
85 41605 : return MacAddress(a);
86 : }
87 :
88 16545133 : int MacAddress::CompareTo(const MacAddress &rhs, int len) const {
89 16545133 : if (len == 0)
90 16545205 : return memcmp(&addr_, &rhs.addr_, sizeof(addr_));
91 8 : return memcmp(&addr_, &rhs.addr_, len);
92 : }
93 :
94 401697 : bool MacAddress::ToArray(u_int8_t *p, size_t s) const {
95 401697 : if (s < size())
96 0 : return false;
97 401678 : memcpy(p, &addr_, size());
98 401670 : return true;
99 : }
100 :
101 96 : MacAddress &MacAddress::operator=(const u_int8_t *c) {
102 96 : memcpy(&addr_, c, size());
103 96 : return *this;
104 : }
105 :
106 0 : MacAddress &MacAddress::operator=(const struct sockaddr *sa) {
107 0 : memcpy(&addr_, sa->sa_data, size());
108 0 : return *this;
109 : }
|