--- nono/host/hostnet.cpp 2026/04/29 17:05:55 1.1.1.11 +++ nono/host/hostnet.cpp 2026/04/29 17:06:02 1.1.1.12 @@ -132,7 +132,7 @@ HostNetDevice::HostNetDevice(Device *par assert(ihwaddrfilter); monitor = gMonitorManager->Regist(ID_MONITOR_HOSTNET(n), this); - monitor->func = ToMonitorCallback(&HostNetDevice::MonitorUpdate); + monitor->SetCallback(&HostNetDevice::MonitorScreen); monitor->SetSize(48, 24); #if defined(HAVE_HOSTNET_SLIRP) @@ -403,7 +403,7 @@ HostNetDevice::Tx(const NetPacket& packe { // 長さ 0 のパケットは破棄する。バグでもないと通常は起きない。 // runt frame はどうするか? - if (packet.length < 1) { + if (packet.Length() < 1) { stat.txzero_pkts++; putlog(1, "Tx: drop empty packet"); return true; @@ -412,13 +412,13 @@ HostNetDevice::Tx(const NetPacket& packe // 送信キューに入れて.. if (txq.Enqueue(packet) == false) { stat.txqfull_pkts++; - stat.txqfull_bytes += packet.length; + stat.txqfull_bytes += packet.Length(); putlog(2, "txq exhausted"); return false; } stat.tx_pkts++; - stat.tx_bytes += packet.length; + stat.tx_bytes += packet.Length(); // ざっくりピーク値 stat.txq_peak = std::max((uint)txq.Length(), stat.txq_peak); @@ -441,7 +441,7 @@ HostNetDevice::EnableRx(bool enable) NetPacket drop; while (rxq.Dequeue(&drop)) { stat.rxdisable_pkts++; - stat.rxdisable_bytes += drop.length; + stat.rxdisable_bytes += drop.Length(); } } } @@ -455,17 +455,18 @@ HostNetDevice::Rx(NetPacket *dst) // キューが空 return false; } + uint length = dst->Length(); stat.rx_pkts++; - stat.rx_bytes += dst->length; + stat.rx_bytes += length; if (__predict_false(loglevel >= 2)) { - putlogn("Recv %u bytes", dst->length); + putlogn("Recv %u bytes", length); if (loglevel >= 4) { std::string buf; - for (uint i = 0; i < dst->length; i++) { + for (uint i = 0; i < length; i++) { if (i % 16 == 0) { buf += string_format("%04x:", i); } - buf += string_format(" %02x", (*dst)[i]); + buf += string_format(" %02x", dst->Peek(i)); if (i % 16 == 7) { buf += " "; } else if (i % 16 == 15) { @@ -504,7 +505,7 @@ HostNetDevice::Read() break; } stat.rxqfull_pkts++; - stat.rxqfull_bytes += discard.length; + stat.rxqfull_bytes += discard.Length(); continue; } @@ -520,45 +521,45 @@ HostNetDevice::Read() NetPacket& packet = *p; stat.read_pkts++; - stat.read_bytes += packet.length; + stat.read_bytes += packet.Length(); if (rx_enable == false) { rxq.CancelWrite(); stat.rxdisable_pkts++; - stat.rxdisable_bytes += packet.length; + stat.rxdisable_bytes += packet.Length(); continue; } // イーサネットフレームより長いパケットはゲスト OS が期待していない。 // ここでドロップしてみる。 // これによりゲストでの dropping chained buffer が出なくなる。 - if (packet.length > 1518) { + if (packet.Length() > 1518) { rxq.CancelWrite(); stat.rxjumbo_pkts++; - stat.rxjumbo_bytes += packet.length; + stat.rxjumbo_bytes += packet.Length(); continue; } // ホストカーネルから直接着信したパケット(というかフレームか)は // 60バイトパディングされないまま読み出せるので、ここでパディングする。 - while (packet.length < 60) { - packet.Append(0x00); + while (packet.Length() < 60) { + packet.Resize(60); } // デバイスがこのアドレス宛のフレームを受け取るか。 // 受け取らないと分かっているフレームは VM へのキューに入れる前に // 落としておきたい。 - MacAddr dstaddr(&packet[0]); + MacAddr dstaddr(packet.Data()); auto res = ihwaddrfilter->HWAddrFilter(dstaddr); if (res != 0) { switch (res) { case IHWAddrFilter::HPF_DROP_UNICAST: stat.rxnotme_pkts++; - stat.rxnotme_bytes += packet.length; + stat.rxnotme_bytes += packet.Length(); break; case IHWAddrFilter::HPF_DROP_MULTICAST: stat.rxmcast_pkts++; - stat.rxmcast_bytes += packet.length; + stat.rxmcast_bytes += packet.Length(); break; default: assertmsg(false, "corrupted res=%u", res); @@ -568,9 +569,7 @@ HostNetDevice::Read() } // CRC XXX 計算すること - for (int i = 0; i < 4; i++) { - packet.Append(0x00); - } + packet.Resize(packet.Length() + 4); rxq.EndWrite(); queued++; @@ -595,15 +594,16 @@ HostNetDevice::Write() while ((p = txq.BeginRead()) != NULL) { const NetPacket& packet = *p; + uint length = packet.Length(); if (__predict_false(loglevel >= 2)) { - putlogn("Send %u bytes", packet.length); + putlogn("Send %u bytes", length); if (loglevel >= 4) { std::string buf; - for (uint i = 0; i < packet.length; i++) { + for (uint i = 0; i < length; i++) { if (i % 16 == 0) { buf += string_format("%04x:", i); } - buf += string_format(" %02x", packet[i]); + buf += string_format(" %02x", packet.Peek(i)); if (i % 16 == 7) { buf += " "; } else if (i % 16 == 15) { @@ -617,9 +617,9 @@ HostNetDevice::Write() } } stat.write_pkts++; - stat.write_bytes += packet.length; + stat.write_bytes += length; - driver->Write(packet.data(), packet.length); + driver->Write(packet.Data(), length); txq.EndRead(); } } @@ -645,7 +645,7 @@ HostNetDevice::CountTXUnsupp(size_t byte // モニタ void -HostNetDevice::MonitorUpdate(Monitor *, TextScreen& screen) +HostNetDevice::MonitorScreen(Monitor *, TextScreen& screen) { screen.Clear(); @@ -655,7 +655,7 @@ HostNetDevice::MonitorUpdate(Monitor *, screen.Print(0, 1, "HostNet Driver: %s", driver->GetDriverName().c_str()); // 次の2行はドライバ依存情報 - driver->MonitorUpdateMD(screen, 2); + driver->MonitorScreenMD(screen, 2); } // 01234567890123456 @@ -1493,6 +1493,53 @@ HostNetDevice::GetServByPort(uint16 port } +// +// NetPacket +// + +// このパケットを src から srclen バイトの内容に置き換える。 +void +NetPacket::Assign(const void *src, uint srclen) +{ + Resize(srclen); + uint copylen = std::min(srclen, (uint)buf.size()); + memcpy(buf.data(), src, copylen); +} + +// パケット長を変更する。 +void +NetPacket::Resize(uint newlength) +{ + uint cliplength = newlength; + + if (__predict_false(cliplength > buf.size())) { + cliplength = buf.size(); + } + + // 新たに増えたところは 0 で埋める。 + if (cliplength > length) { + memset(Data() + length, 0, cliplength - length); + } + + // 長さは buf.size() を超えることを許容する。 + length = newlength; +} + +// パケットに1バイト追加する。 +void +NetPacket::Append(uint8 data) +{ + if (__predict_true(length < buf.size())) { + buf[length] = data; + } + length++; +} + + +// +// IHWAddrFilter +// + // IHWAddrFilter の デストラクタ IHWAddrFilter::~IHWAddrFilter() {