--- nono/host/hostnet.h 2026/04/29 17:05:30 1.1.1.4 +++ nono/host/hostnet.h 2026/04/29 17:06:02 1.1.1.9 @@ -12,17 +12,12 @@ #include "hostdevice.h" #include "macaddr.h" -#include "monitor.h" #include "netdriver.h" #include "spscqueue.h" -// パケット -class NetPacket : public std::array +// パケット。 +class NetPacket { - // ジャンボフレームでないイーサネットフレームは最大 1518バイトだが - // このパケットバッファの長さは 1519 バイト以上必要。 - // vm/lance が 1518 バイトを越えたことを検出するのに使っている。 - public: NetPacket() { Clear(); @@ -31,32 +26,84 @@ class NetPacket : public std::array buf {}; +}; + +// MAC アドレスフィルタ。 +// VM 側デバイスはこれを多重継承して実装すること。 +class IHWAddrFilter +{ + // インタフェース風にするため、メンバ変数を持たせないこと。 + public: + enum { + HPF_PASS = 0, // このフレームを受信する。 + HPF_DROP_UNICAST, // このユニキャストフレームを破棄する。 + HPF_DROP_MULTICAST, // このマルチキャストフレームを破棄する。 + }; + + public: + virtual ~IHWAddrFilter(); + + // デバイスがこの dstaddr 宛のフレームを受け付けるかどうかを返す。 + // デバイスは、自分宛て、ブロードキャスト、マルチキャスト + // (おそらくハッシュ)、プロミスキャスなどの状態を考慮すること。 + virtual int HWAddrFilter(const MacAddr& dstaddr) const = 0; }; class HostNetDevice : public HostDevice @@ -76,6 +123,8 @@ class HostNetDevice : public HostDevice uint64 write_pkts; uint64 write_bytes; uint64 txzero_pkts; // 送信長0で破棄したパケット数 + uint64 txunsupp_pkts; // 送信先が未対応で破棄したパケット数 + uint64 txunsupp_bytes; // 送信先が未対応で破棄したバイト数 uint64 txqfull_pkts; // キューが一杯だった回数 uint64 txqfull_bytes; // キューに入れられなかったバイト数 uint64 rxdisable_pkts; // 上位層が受信無効 @@ -94,11 +143,11 @@ class HostNetDevice : public HostDevice }; public: - HostNetDevice(Device *parent_, uint n); + HostNetDevice(Device *parent_, uint n, const std::string& portname_); ~HostNetDevice() override; void SetLogLevel(int loglevel_) override; - bool Init() override; + bool Create2() override; // パケットを送信する。 // data はプリアンブルを含まず、イーサネットフレームヘッダ(14バイト)、 @@ -114,48 +163,63 @@ class HostNetDevice : public HostDevice // 受信キューへの投入を許可/禁止する。 void EnableRx(bool enable); - // 受信用の自身の MAC アドレスを設定する。 - void SetMyAddr(const macaddr_t& myaddr_); - - // プロミスキャスモードを設定する。 - void SetPromisc(bool promisc_); - // マルチキャストフィルタを設定する。 void SetMCastFilter(uint64 filter); - // ドライバ名を返す (ステータスパネルから呼ばれる) - const std::string GetDriverName() const; + // ドライバ名を返す。 + const std::string& GetDriverName(); // 統計情報を返す (ステータスパネルから呼ばれる) uint64 GetTXPkts() const { return stat.tx_pkts; } uint64 GetRXPkts() const { return stat.rx_pkts; } + // 統計情報に1パケット分加算する (これだけ SLIRP の裏スレッドから呼ばれる) + void CountTXUnsupp(size_t bytes); + // コンパイル済みのドライバ名一覧を返す static std::vector GetDrivers(); + // libslirp のバージョン文字列を返す + static const char *GetSlirpVersion(); + + // デバッグ用。 + static std::vector DumpHex(const void *, size_t); + static std::vector DumpFrame(const void *, size_t); + private: - bool SelectDriver(); - bool CreateNone(); - bool CreateTap(); - bool CreateBPF(); - bool CreateAFPacket(); + bool SelectDriver(bool startup) override; + void CreateNone(); + void CreateSlirp(bool startup); + void CreateTap(); + void CreateBPF(); + void CreateAFPacket(); int Read() override; // 外部への書き出し(パケットを送信) - void Write(uint32 data) override; + void Write() override; + + DECLARE_MONITOR_SCREEN(MonitorScreen); - DECLARE_MONITOR_CALLBACK(MonitorUpdate); + // デバッグ用 (下請け) + static std::vector DumpARP(const void *, size_t); + static std::vector DumpIPv4(const void *, size_t); + static std::vector DumpICMPv4(const char *, const char *, + const void *, size_t); + static std::vector DumpTCPv4(const char *, const char *, + const void *, size_t); + static std::vector DumpUDPv4(const char *, const char *, + const void *, size_t); + static std::vector DumpDHCP(const void *, size_t); + static std::vector DumpIPv6(const void *, size_t); + static std::vector DumpICMPv6(const char *, const char *, + const void *, size_t); + static std::string DumpDHCPAddrList(const uint8 *, size_t); + static std::string GetServByPort(uint16 port_be, const char *protoname); std::unique_ptr driver {}; bool rx_enable {}; - macaddr_t myaddr {}; // 自身の MAC アドレス - bool promisc {}; // プロミスキャスモードなら true - - // マルチキャストフィルタ。 - // 64ビットのうち、LSB 側を0番目、MSB 側を63番目となるようにしたもの。 - uint64 multicast_filter {}; // キュー NetTxQueue txq {}; @@ -164,7 +228,7 @@ class HostNetDevice : public HostDevice // 統計情報 struct stat_t stat {}; - std::string errmsg {}; + Monitor *monitor {}; - Monitor monitor { this }; + IHWAddrFilter *ihwaddrfilter {}; };