|
|
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.