|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2021 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // NetDriver セレクタ ! 8: // ! 9: // ログレベルを受け取るために他のデバイスとかと同様最初に作成されて、 ! 10: // InitDriver() で実際に使うドライバを選択・作成するだけ。 ! 11: ! 12: #include "netdriver_selector.h" ! 13: #include "config.h" ! 14: #include "netdriver_none.h" ! 15: #if defined(HAVE_HOSTNET_AFPACKET) ! 16: #include "netdriver_afpacket.h" ! 17: #endif ! 18: #if defined(HAVE_HOSTNET_BPF) ! 19: #include "netdriver_bpf.h" ! 20: #endif ! 21: #if defined(HAVE_HOSTNET_TAP) ! 22: #include "netdriver_tap.h" ! 23: #endif ! 24: ! 25: std::unique_ptr<NetDriverSelector> gNetDriverSelector; ! 26: ! 27: // コンパイル済みのドライバ名一覧を返す ! 28: // (MainApp から呼ばれる) ! 29: /*static*/ std::vector<std::string> ! 30: NetDriverSelector::GetDrivers() ! 31: { ! 32: std::vector<std::string> list; ! 33: ! 34: #if defined(HAVE_HOSTNET_AFPACKET) ! 35: list.emplace_back("afpacket"); ! 36: #endif ! 37: #if defined(HAVE_HOSTNET_BPF) ! 38: list.emplace_back("bpf"); ! 39: #endif ! 40: #if defined(HAVE_HOSTNET_TAP) ! 41: list.emplace_back("tap"); ! 42: #endif ! 43: ! 44: return list; ! 45: } ! 46: ! 47: // コンストラクタ ! 48: // (ここのログ名 HostNet がコマンドラインで指定するやつになるので ! 49: // HostNetSelector とかに変えないように) ! 50: NetDriverSelector::NetDriverSelector(EthernetDevice *parent_) ! 51: : inherited("HostNet") ! 52: { ! 53: parent = parent_; ! 54: ! 55: AddAlias("NetDriver"); ! 56: } ! 57: ! 58: // デストラクタ ! 59: NetDriverSelector::~NetDriverSelector() ! 60: { ! 61: } ! 62: ! 63: // ここで実際の NetDriver を用意する (MainApp::Init1() から呼ばれる)。 ! 64: // ここでは putmsg() が使える。また作成した NetDriver クラスも ! 65: // (NetDriverSelector のログレベルをコピーするので) putmsg() が使える。 ! 66: // 成功すれば作成した NetDriver を返す。 ! 67: // 終了する場合は warnx() を出力してから NULL を返す。 ! 68: // ! 69: // 起動時のフェーズは Create() はログが使えない、Init() はログが使える、と ! 70: // 分かれており、ここもログが使えるので Init を冠しているが、やってることは ! 71: // Create なので関数名とメッセージ中の単語のずれは気持ち悪いけど仕方がない。 ! 72: NetDriver * ! 73: NetDriverSelector::InitDriver() ! 74: { ! 75: const ConfigItem& item = gConfig->Find("hostnet-driver"); ! 76: const std::string& type = item.AsString(); ! 77: bool fallback = gConfig->Find("hostnet-fallback").AsInt(); ! 78: NetDriver *driver; ! 79: ! 80: driver = NULL; ! 81: ! 82: if (type == "none") { ! 83: driver = InitNone(); ! 84: ! 85: } else if (type == "tap") { ! 86: #if defined(HAVE_HOSTNET_TAP) ! 87: driver = InitTap(); ! 88: #else ! 89: item.Err("hostnet driver %s not compiled", type.c_str()); ! 90: #endif ! 91: ! 92: } else if (type == "bpf") { ! 93: #if defined(HAVE_HOSTNET_BPF) ! 94: driver = InitBPF(); ! 95: #else ! 96: item.Err("hostnet driver %s not compiled", type.c_str()); ! 97: #endif ! 98: ! 99: } else if (type == "afpacket") { ! 100: #if defined(HAVE_HOSTNET_AFPACKET) ! 101: driver = InitAFPacket(); ! 102: #else ! 103: item.Err("hostnet driver %s not compiled", type.c_str()); ! 104: #endif ! 105: ! 106: } else if (type == "auto") { ! 107: // auto なら Tap -> { BPF, AFPacket } の順で試す。 ! 108: // ! 109: // Tap は事前の準備が面倒だが制約がない。 ! 110: // BPF, AFPacket (この2つは OS の違いだけでほぼ同じもの) は ! 111: // 準備に手間がかからないが自ホストと通信できない制約がある。 ! 112: // そのためどの環境でも Tap が使えれば Tap を、そうでなければ ! 113: // BPF, AFPacket を使う、という順にしておく。 ! 114: ! 115: driver = InitTap(); ! 116: if (driver == NULL) { ! 117: driver = InitAFPacket(); ! 118: } ! 119: if (driver == NULL) { ! 120: driver = InitBPF(); ! 121: } ! 122: ! 123: } else { ! 124: // 知らないドライバ種別 ! 125: item.Err(); ! 126: } ! 127: ! 128: if (driver == NULL) { ! 129: putmsg(1, "hostnet-fallback=%d", fallback ? 1 : 0); ! 130: ! 131: if (fallback) { ! 132: // 出来てない場合でフォールバックが指示されていれば ! 133: // None へフォールバックする ! 134: driver = InitNone(); ! 135: } else { ! 136: errmsg = "No host network driver found"; ! 137: putmsg(1, "%s", errmsg.c_str()); ! 138: warnx("%s (See details with options -C -Lhostnet=1)", ! 139: errmsg.c_str()); ! 140: ! 141: // NULL を返すと終了する ! 142: return NULL; ! 143: } ! 144: } ! 145: ! 146: // ドライバ名は Capitalize だがログはほぼ小文字なので雰囲気を揃える… ! 147: putmsg(1, "selected host driver: %s", ! 148: string_tolower(driver->GetDriverName()).c_str()); ! 149: ! 150: return driver; ! 151: } ! 152: ! 153: // None の場合 ! 154: NetDriver * ! 155: NetDriverSelector::InitNone() ! 156: { ! 157: NetDriverNone *driver = new NetDriverNone(loglevel); ! 158: // 失敗しても出来ることはあまりなさげ ! 159: assert(driver); ! 160: driver->InitDriver(); ! 161: return driver; ! 162: } ! 163: ! 164: // Tap の場合 ! 165: NetDriver * ! 166: NetDriverSelector::InitTap() ! 167: { ! 168: #if defined(HAVE_HOSTNET_TAP) ! 169: const ConfigItem& item = gConfig->Find("hostnet-tap-devpath"); ! 170: const std::string& devpath = item.AsString(); ! 171: ! 172: NetDriverTap *driver = NULL; ! 173: try { ! 174: driver = new NetDriverTap(parent, loglevel, devpath); ! 175: if (driver->InitDriver()) { ! 176: // 成功 ! 177: return driver; ! 178: } ! 179: errmsg = driver->errmsg; ! 180: delete driver; ! 181: } catch (...) { ! 182: errmsg = "Creating NetDriverTap failed"; ! 183: } ! 184: #endif ! 185: return NULL; ! 186: } ! 187: ! 188: // bpf の場合 ! 189: NetDriver * ! 190: NetDriverSelector::InitBPF() ! 191: { ! 192: #if defined(HAVE_HOSTNET_BPF) ! 193: const ConfigItem& item = gConfig->Find("hostnet-bpf-ifname"); ! 194: const std::string& ifname = item.AsString(); ! 195: ! 196: NetDriverBPF *driver = NULL; ! 197: try { ! 198: driver = new NetDriverBPF(parent, loglevel, ifname); ! 199: if (driver->InitDriver()) { ! 200: // 成功 ! 201: return driver; ! 202: } ! 203: errmsg = driver->errmsg; ! 204: delete driver; ! 205: } catch (...) { ! 206: errmsg = "Creating NetDriverBPF failed"; ! 207: } ! 208: #endif ! 209: return NULL; ! 210: } ! 211: ! 212: // AFPacket の場合 ! 213: NetDriver * ! 214: NetDriverSelector::InitAFPacket() ! 215: { ! 216: #if defined(HAVE_HOSTNET_AFPACKET) ! 217: const ConfigItem& item = gConfig->Find("hostnet-afpacket-ifname"); ! 218: const std::string& ifname = item.AsString(); ! 219: ! 220: NetDriverAFPacket *driver = NULL; ! 221: try { ! 222: driver = new NetDriverAFPacket(parent, loglevel, ifname); ! 223: if (driver->InitDriver()) { ! 224: // 成功 ! 225: return driver; ! 226: } ! 227: errmsg = driver->errmsg; ! 228: delete driver; ! 229: } catch (...) { ! 230: errmsg = "Creating NetDriverAFPacket failed"; ! 231: } ! 232: #endif ! 233: return NULL; ! 234: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.