|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2021 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // MAC アドレス
9: //
10:
11: #pragma once
12:
13: #include "header.h"
14:
15: // MAC アドレス格納用のクラス
1.1.1.2 root 16: class MacAddr
1.1 root 17: {
1.1.1.2 root 18: // addr.b[] をアクセスするためのヘルパー。
19: static inline std::size_t IDX(std::size_t n)
20: {
21: #if BYTE_ORDER == LITTLE_ENDIAN
22: return n;
23: #else
24: return 7 - n;
25: #endif
26: }
27:
1.1 root 28: public:
1.1.1.2 root 29: // コンストラクタ
30: MacAddr()
31: {
32: }
33:
34: // コンストラクタ
35: explicit MacAddr(uint64 addr_)
36: {
37: addr.q = addr_;
38: }
39:
40: // コンストラクタ
41: explicit MacAddr(const uint8 *src)
42: : MacAddr(src[0], src[1], src[2], src[3], src[4], src[5])
43: {
44: }
45:
46: // コンストラクタ
47: MacAddr(uint s0, uint s1, uint s2, uint s3, uint s4, uint s5)
48: {
49: addr.q = ((uint64)s0 << 0)
50: | ((uint64)s1 << 8)
51: | ((uint64)s2 << 16)
52: | ((uint64)s3 << 24)
53: | ((uint64)s4 << 32)
54: | ((uint64)s5 << 40);
55: }
56:
57: // コピーコンストラクタ
58: MacAddr(const MacAddr& src)
59: {
60: addr.q = src.addr.q;
61: }
62:
63: // コピー代入演算子
64: MacAddr& operator=(const MacAddr& src)
65: {
66: addr.q = src.addr.q;
67: return *this;
68: }
69:
70: // [] 演算子
71: const uint8& operator[](std::size_t n) const
72: {
73: return addr.b[IDX(n)];
74: }
75:
76: // [] 演算子
77: uint8& operator[](std::size_t n)
78: {
79: return addr.b[IDX(n)];
80: }
81:
82: // MAC アドレスのバイト数を返す。
83: std::size_t size() const noexcept { return 6; }
84:
1.1 root 85: // この MAC アドレスが 00:00:00:00:00:00 なら true
1.1.1.2 root 86: bool Empty() const noexcept { return (addr.q == 0); }
1.1 root 87:
88: // MAC アドレスを適当に生成する。
89: void Generate();
90:
91: // 文字列から MAC アドレスを作成する。"HH:HH:HH:HH:HH:HH" 形式のみ。
92: // 成功すれば true を返す。
93: bool FromString(const std::string& src);
94:
1.1.1.2 root 95: // この MAC アドレスを dst に書き出す。
96: void ExportTo(uint8 *dst) const
97: {
98: for (std::size_t i = 0; i < size(); i++) {
99: dst[i] = (*this)[i];
100: }
101: }
102:
103: // このアドレスがユニキャストアドレスなら true を返す。
104: bool IsUnicast() const noexcept
105: {
106: return ((addr.q & 0x01ULL) == 0);
107: }
108:
109: // このアドレスがブロードキャストアドレスなら true を返す。
110: bool IsBroadcast() const noexcept
111: {
112: return (addr.q == 0x0000'ffff'ffff'ffffULL);
113: }
114:
1.1 root 115: // 区切り文字なしの文字列形式を返す。主に ROM 埋め込み用で英字は大文字。
116: // 01:23:AB なら "0123AB" のような感じ。
117: std::string ToString() const;
118:
119: // sep を区切り文字とする文字列形式を返す。主に表示用で英字は小文字。
120: // 01:23:AB で sep = ":" なら "01:23:ab" のような感じ。
121: std::string ToString(char sep) const;
1.1.1.2 root 122:
123: // 内部の 64 ビット数をそのまま取得する。operator==() で必要なのと
124: // パフォーマンスのため EthernetDevice::CRC32() から使っている。
125: uint64 Get() const noexcept { return addr.q; }
126:
127: private:
128: // AA:BB:CC:DD:EE:FF を .q = 0x0000FFEEDDCCBBAA として格納する。
129: // .b[] はエンディアンの影響を受けるので直接アクセスしないこと。
130: // 代わりに (*this)[] 演算子を使う。
131: union {
132: uint64 q {};
133: uint8 b[8];
134: } addr;
1.1 root 135: };
1.1.1.2 root 136:
1.1.1.3 ! root 137: inline bool operator==(const MacAddr& lhs, const MacAddr& rhs)
1.1.1.2 root 138: {
139: return (lhs.Get() == rhs.Get());
140: }
141:
1.1.1.3 ! root 142: inline bool operator!=(const MacAddr& lhs, const MacAddr& rhs)
1.1.1.2 root 143: {
144: return !(lhs == rhs);
145: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.