summaryrefslogtreecommitdiff
path: root/node/MAC.hpp
blob: c3a1186273d20d4011ef331a5eaf850cb746557c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
 * ZeroTier One - Global Peer to Peer Ethernet
 * Copyright (C) 2011-2014  ZeroTier Networks LLC
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * --
 *
 * ZeroTier may be used and distributed under the terms of the GPLv3, which
 * are available at: http://www.gnu.org/licenses/gpl-3.0.html
 *
 * If you would like to embed ZeroTier into a commercial application or
 * redistribute it in a modified binary form, please contact ZeroTier Networks
 * LLC. Start here: http://www.zerotier.com/
 */

#ifndef ZT_MAC_HPP
#define ZT_MAC_HPP

#include <stdio.h>
#include <stdlib.h>

#include "Constants.hpp"
#include "Array.hpp"
#include "Utils.hpp"

namespace ZeroTier {

/**
 * An Ethernet MAC address
 */
class MAC : public Array<unsigned char,6>
{
public:
	/**
	 * Create a zero/null MAC
	 */
	MAC()
		throw()
	{
		for(unsigned int i=0;i<6;++i)
			data[i] = 0;
	}

	/**
	 * Create a MAC consisting of only this octet
	 *
	 * @param octet Octet to fill MAC with (e.g. 0xff for broadcast-all)
	 */
	MAC(const unsigned char octet)
		throw()
	{
		for(unsigned int i=0;i<6;++i)
			data[i] = octet;
	}

	/**
	 * Create a MAC from raw bits
	 *
	 * @param bits 6 bytes of MAC address data
	 */
	MAC(const void *bits)
		throw()
	{
		for(unsigned int i=0;i<6;++i)
			data[i] = ((const unsigned char *)bits)[i];
	}

	/**
	 * @return True if non-NULL (not all zero)
	 */
	inline operator bool() const
		throw()
	{
		for(unsigned int i=0;i<6;++i) {
			if (data[i])
				return true;
		}
		return false;
	}

	/**
	 * @return True if this is the broadcast-all MAC (0xff:0xff:...)
	 */
	inline bool isBroadcast() const
		throw()
	{
		for(unsigned int i=0;i<6;++i) {
			if (data[i] != 0xff)
				return false;
		}
		return true;
	}

	/**
	 * @return True if this is a multicast/broadcast address
	 */
	inline bool isMulticast() const
		throw()
	{
		return ((data[0] & 1));
	}

	/**
	 * @return True if this is a ZeroTier unicast MAC
	 */
	inline bool isZeroTier() const
		throw()
	{
		return (data[0] == ZT_MAC_FIRST_OCTET);
	}

	/**
	 * Zero this MAC
	 */
	inline void zero()
		throw()
	{
		for(unsigned int i=0;i<6;++i)
			data[i] = 0;
	}

	/**
	 * @param s String hex representation (with or without :'s)
	 * @return True if string decoded into a full-length MAC
	 */
	inline void fromString(const char *s)
	{
		Utils::unhex(s,data,6);
	}

	/**
	 * @return MAC address in standard :-delimited hex format
	 */
	inline std::string toString() const
	{
		char tmp[32];
		Utils::snprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)data[0],(int)data[1],(int)data[2],(int)data[3],(int)data[4],(int)data[5]);
		return std::string(tmp);
	}
};

} // namespace ZeroTier

#endif