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