|
|
nono 1.7.0
//
// nono
// Copyright (C) 2021 nono project
// Licensed under nono-license.txt
//
//
// MAC アドレス
//
#pragma once
#include "header.h"
// MAC アドレス格納用のクラス
class MacAddr
{
// addr.b[] をアクセスするためのヘルパー。
static inline std::size_t IDX(std::size_t n)
{
#if BYTE_ORDER == LITTLE_ENDIAN
return n;
#else
return 7 - n;
#endif
}
public:
// コンストラクタ
MacAddr()
{
}
// コンストラクタ
explicit MacAddr(uint64 addr_)
{
addr.q = addr_;
}
// コンストラクタ
explicit MacAddr(const uint8 *src)
: MacAddr(src[0], src[1], src[2], src[3], src[4], src[5])
{
}
// コンストラクタ
MacAddr(uint s0, uint s1, uint s2, uint s3, uint s4, uint s5)
{
addr.q = ((uint64)s0 << 0)
| ((uint64)s1 << 8)
| ((uint64)s2 << 16)
| ((uint64)s3 << 24)
| ((uint64)s4 << 32)
| ((uint64)s5 << 40);
}
// コピーコンストラクタ
MacAddr(const MacAddr& src)
{
addr.q = src.addr.q;
}
// コピー代入演算子
MacAddr& operator=(const MacAddr& src)
{
addr.q = src.addr.q;
return *this;
}
// [] 演算子
const uint8& operator[](std::size_t n) const
{
return addr.b[IDX(n)];
}
// [] 演算子
uint8& operator[](std::size_t n)
{
return addr.b[IDX(n)];
}
// MAC アドレスのバイト数を返す。
std::size_t size() const noexcept { return 6; }
// この MAC アドレスが 00:00:00:00:00:00 なら true
bool Empty() const noexcept { return (addr.q == 0); }
// MAC アドレスを適当に生成する。
void Generate();
// 文字列から MAC アドレスを作成する。"HH:HH:HH:HH:HH:HH" 形式のみ。
// 成功すれば true を返す。
bool FromString(const std::string& src);
// この MAC アドレスを dst に書き出す。
void ExportTo(uint8 *dst) const
{
for (std::size_t i = 0; i < size(); i++) {
dst[i] = (*this)[i];
}
}
// このアドレスがユニキャストアドレスなら true を返す。
bool IsUnicast() const noexcept
{
return ((addr.q & 0x01ULL) == 0);
}
// このアドレスがブロードキャストアドレスなら true を返す。
bool IsBroadcast() const noexcept
{
return (addr.q == 0x0000'ffff'ffff'ffffULL);
}
// 区切り文字なしの文字列形式を返す。主に ROM 埋め込み用で英字は大文字。
// 01:23:AB なら "0123AB" のような感じ。
std::string ToString() const;
// sep を区切り文字とする文字列形式を返す。主に表示用で英字は小文字。
// 01:23:AB で sep = ":" なら "01:23:ab" のような感じ。
std::string ToString(char sep) const;
// 内部の 64 ビット数をそのまま取得する。operator==() で必要なのと
// パフォーマンスのため EthernetDevice::CRC32() から使っている。
uint64 Get() const noexcept { return addr.q; }
private:
// AA:BB:CC:DD:EE:FF を .q = 0x0000FFEEDDCCBBAA として格納する。
// .b[] はエンディアンの影響を受けるので直接アクセスしないこと。
// 代わりに (*this)[] 演算子を使う。
union {
uint64 q {};
uint8 b[8];
} addr;
};
inline bool operator==(const MacAddr& lhs, const MacAddr& rhs)
{
return (lhs.Get() == rhs.Get());
}
inline bool operator!=(const MacAddr& lhs, const MacAddr& rhs)
{
return !(lhs == rhs);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.