* copy vendor drop to trunk
[lab.git] / Dev / utvpn / utvpn-unix-v101-7101-public / src / Cedar / Nat.c
1 // SoftEther UT-VPN SourceCode\r
2 // \r
3 // Copyright (C) 2004-2010 SoftEther Corporation.\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.\r
6 // All Rights Reserved.\r
7 // \r
8 // http://utvpn.tsukuba.ac.jp/\r
9 // \r
10 // This program is free software; you can redistribute it and/or\r
11 // modify it under the terms of the GNU General Public License\r
12 // version 2 as published by the Free Software Foundation.\r
13 // \r
14 // This program is distributed in the hope that it will be useful,\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
17 // GNU General Public License for more details.\r
18 // \r
19 // You should have received a copy of the GNU General Public License version 2\r
20 // along with this program; if not, write to the Free Software\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
22 // \r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。\r
28 // \r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって\r
32 // ホストされています。\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、\r
34 // および、試験または研究のために利用が行われることを想定して配布\r
35 // しています。\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に\r
37 // あります。\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース\r
42 // に組み込みさせていただきます。\r
43 // \r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。\r
46 // \r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意\r
51 // ください。\r
52 // \r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、\r
58 // 公益保護にご協力いただきますようお願い申し上げます。\r
59 // \r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客\r
62 // を保護するための努力を行います。\r
63 // \r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/\r
65 // 日本国内の脆弱性情報届出受付公的機関:\r
66 //         独立行政法人 情報処理推進機構\r
67 //         http://www.ipa.go.jp/security/vuln/report/\r
68 // \r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/\r
71 \r
72 // -----------------------------------------------\r
73 // [ChangeLog]\r
74 // 2010.05.20\r
75 //  新規リリース by SoftEther\r
76 // -----------------------------------------------\r
77 \r
78 // Nat.c\r
79 // User-mode Router\r
80 \r
81 #include "CedarPch.h"\r
82 \r
83 static LOCK *nat_lock = NULL;\r
84 static NAT *nat = NULL;\r
85 \r
86 \r
87 // NAT 管理者用接続を切断\r
88 void NatAdminDisconnect(RPC *r)\r
89 {\r
90         // 引数チェック\r
91         if (r == NULL)\r
92         {\r
93                 return;\r
94         }\r
95 \r
96         EndRpc(r);\r
97 }\r
98 \r
99 // NAT 管理者用接続\r
100 RPC *NatAdminConnect(CEDAR *cedar, char *hostname, UINT port, void *hashed_password, UINT *err)\r
101 {\r
102         UCHAR secure_password[SHA1_SIZE];\r
103         UCHAR random[SHA1_SIZE];\r
104         SOCK *sock;\r
105         RPC *rpc;\r
106         PACK *p;\r
107         UINT error;\r
108         // 引数チェック\r
109         if (cedar == NULL || hostname == NULL || port == 0 || hashed_password == NULL || err == NULL)\r
110         {\r
111                 if (err != NULL)\r
112                 {\r
113                         *err = ERR_INTERNAL_ERROR;\r
114                 }\r
115                 return NULL;\r
116         }\r
117 \r
118         // 接続\r
119         sock = Connect(hostname, port);\r
120         if (sock == NULL)\r
121         {\r
122                 *err = ERR_CONNECT_FAILED;\r
123                 return NULL;\r
124         }\r
125 \r
126         if (StartSSL(sock, NULL, NULL) == false)\r
127         {\r
128                 *err = ERR_PROTOCOL_ERROR;\r
129                 ReleaseSock(sock);\r
130                 return NULL;\r
131         }\r
132 \r
133         SetTimeout(sock, 5000);\r
134 \r
135         p = HttpClientRecv(sock);\r
136         if (p == NULL)\r
137         {\r
138                 *err = ERR_DISCONNECTED;\r
139                 ReleaseSock(sock);\r
140                 return NULL;\r
141         }\r
142 \r
143         if (PackGetData2(p, "auth_random", random, SHA1_SIZE) == false)\r
144         {\r
145                 FreePack(p);\r
146                 *err = ERR_PROTOCOL_ERROR;\r
147                 ReleaseSock(sock);\r
148                 return NULL;\r
149         }\r
150 \r
151         FreePack(p);\r
152 \r
153         SecurePassword(secure_password, hashed_password, random);\r
154 \r
155         p = NewPack();\r
156         PackAddData(p, "secure_password", secure_password, SHA1_SIZE);\r
157 \r
158         if (HttpClientSend(sock, p) == false)\r
159         {\r
160                 FreePack(p);\r
161                 *err = ERR_DISCONNECTED;\r
162                 ReleaseSock(sock);\r
163                 return NULL;\r
164         }\r
165 \r
166         FreePack(p);\r
167 \r
168         p = HttpClientRecv(sock);\r
169         if (p == NULL)\r
170         {\r
171                 *err = ERR_DISCONNECTED;\r
172                 ReleaseSock(sock);\r
173                 return NULL;\r
174         }\r
175 \r
176         error = GetErrorFromPack(p);\r
177 \r
178         FreePack(p);\r
179 \r
180         if (error != ERR_NO_ERROR)\r
181         {\r
182                 *err = error;\r
183                 ReleaseSock(sock);\r
184                 return NULL;\r
185         }\r
186 \r
187         SetTimeout(sock, TIMEOUT_INFINITE);\r
188 \r
189         rpc = StartRpcClient(sock, NULL);\r
190         ReleaseSock(sock);\r
191 \r
192         return rpc;\r
193 }\r
194 \r
195 // RPC 関数関係マクロ\r
196 #define DECLARE_RPC_EX(rpc_name, data_type, function, in_rpc, out_rpc, free_rpc)                \\r
197         else if (StrCmpi(name, rpc_name) == 0)                                                          \\r
198         {                                                                                                                                       \\r
199                 data_type t;                                                                                                    \\r
200                 Zero(&t, sizeof(t));                                                                                    \\r
201                 in_rpc(&t, p);                                                                                                  \\r
202                 err = function(n, &t);                                                                                  \\r
203                 if (err == ERR_NO_ERROR)                                                                                \\r
204                 {                                                                                                                               \\r
205                         out_rpc(ret, &t);                                                                                       \\r
206                 }                                                                                                                               \\r
207                 free_rpc(&t);                                                                                                   \\r
208                 ok = true;                                                                                                              \\r
209         }\r
210 #define DECLARE_RPC(rpc_name, data_type, function, in_rpc, out_rpc)             \\r
211         else if (StrCmpi(name, rpc_name) == 0)                                                          \\r
212         {                                                                                                                                       \\r
213                 data_type t;                                                                                                    \\r
214                 Zero(&t, sizeof(t));                                                                                    \\r
215                 in_rpc(&t, p);                                                                                                  \\r
216                 err = function(n, &t);                                                                                  \\r
217                 if (err == ERR_NO_ERROR)                                                                                \\r
218                 {                                                                                                                               \\r
219                         out_rpc(ret, &t);                                                                                       \\r
220                 }                                                                                                                               \\r
221                 ok = true;                                                                                                              \\r
222         }\r
223 #define DECLARE_SC_EX(rpc_name, data_type, function, in_rpc, out_rpc, free_rpc) \\r
224         UINT function(RPC *r, data_type *t)                                                                     \\r
225         {                                                                                                                                       \\r
226                 PACK *p, *ret;                                                                                                  \\r
227                 UINT err;                                                                                                               \\r
228                 if (r == NULL || t == NULL)                                                                             \\r
229                 {                                                                                                                               \\r
230                         return ERR_INTERNAL_ERROR;                                                                      \\r
231                 }                                                                                                                               \\r
232                 p = NewPack();                                                                                                  \\r
233                 out_rpc(p, t);                                                                                                  \\r
234                 free_rpc(t);                                                                                                    \\r
235                 Zero(t, sizeof(data_type));                                                                             \\r
236                 ret = AdminCall(r, rpc_name, p);                                                                \\r
237                 err = GetErrorFromPack(ret);                                                                    \\r
238                 if (err == ERR_NO_ERROR)                                                                                \\r
239                 {                                                                                                                               \\r
240                         in_rpc(t, ret);                                                                                         \\r
241                 }                                                                                                                               \\r
242                 FreePack(ret);                                                                                                  \\r
243                 return err;                                                                                                             \\r
244         }\r
245 #define DECLARE_SC(rpc_name, data_type, function, in_rpc, out_rpc)              \\r
246         UINT function(RPC *r, data_type *t)                                                                     \\r
247         {                                                                                                                                       \\r
248                 PACK *p, *ret;                                                                                                  \\r
249                 UINT err;                                                                                                               \\r
250                 if (r == NULL || t == NULL)                                                                             \\r
251                 {                                                                                                                               \\r
252                         return ERR_INTERNAL_ERROR;                                                                      \\r
253                 }                                                                                                                               \\r
254                 p = NewPack();                                                                                                  \\r
255                 out_rpc(p, t);                                                                                                  \\r
256                 ret = AdminCall(r, rpc_name, p);                                                                \\r
257                 err = GetErrorFromPack(ret);                                                                    \\r
258                 if (err == ERR_NO_ERROR)                                                                                \\r
259                 {                                                                                                                               \\r
260                         in_rpc(t, ret);                                                                                         \\r
261                 }                                                                                                                               \\r
262                 FreePack(ret);                                                                                                  \\r
263                 return err;                                                                                                             \\r
264         }\r
265 \r
266 // RPC サーバー関数\r
267 PACK *NiRpcServer(RPC *r, char *name, PACK *p)\r
268 {\r
269         NAT *n = (NAT *)r->Param;\r
270         PACK *ret;\r
271         UINT err;\r
272         bool ok;\r
273         // 引数チェック\r
274         if (r == NULL || name == NULL || p == NULL)\r
275         {\r
276                 return NULL;\r
277         }\r
278 \r
279         ret = NewPack();\r
280         err = ERR_NO_ERROR;\r
281         ok = false;\r
282 \r
283         if (0) {}\r
284 \r
285         // RPC 関数定義: ここから\r
286 \r
287 //      DECLARE_RPC("Online", RPC_DUMMY, NtOnline, InRpcDummy, OutRpcDummy)\r
288 //      DECLARE_RPC("Offline", RPC_DUMMY, NtOffline, InRpcDummy, OutRpcDummy)\r
289         DECLARE_RPC("SetHostOption", VH_OPTION, NtSetHostOption, InVhOption, OutVhOption)\r
290         DECLARE_RPC("GetHostOption", VH_OPTION, NtGetHostOption, InVhOption, OutVhOption)\r
291 //      DECLARE_RPC_EX("SetClientConfig", RPC_CREATE_LINK, NtSetClientConfig, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)\r
292 //      DECLARE_RPC_EX("GetClientConfig", RPC_CREATE_LINK, NtGetClientConfig, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)\r
293         DECLARE_RPC_EX("GetStatus", RPC_NAT_STATUS, NtGetStatus, InRpcNatStatus, OutRpcNatStatus, FreeRpcNatStatus)\r
294 //      DECLARE_RPC_EX("GetInfo", RPC_NAT_INFO, NtGetInfo, InRpcNatInfo, OutRpcNatInfo, FreeRpcNatInfo)\r
295         DECLARE_RPC_EX("EnumNatList", RPC_ENUM_NAT, NtEnumNatList, InRpcEnumNat, OutRpcEnumNat, FreeRpcEnumNat)\r
296         DECLARE_RPC_EX("EnumDhcpList", RPC_ENUM_DHCP, NtEnumDhcpList, InRpcEnumDhcp, OutRpcEnumDhcp, FreeRpcEnumDhcp)\r
297 //      DECLARE_RPC("SetPassword", RPC_SET_PASSWORD, NtSetPassword, InRpcSetPassword, OutRpcSetPassword)\r
298 \r
299         // RPC 関数定義: ここまで\r
300 \r
301         if (ok == false)\r
302         {\r
303                 err = ERR_NOT_SUPPORTED;\r
304         }\r
305 \r
306         PackAddInt(ret, "error", err);\r
307 \r
308         return ret;\r
309 }\r
310 \r
311 \r
312 \r
313 \r
314 // RPC 呼び出し定義ここから\r
315 \r
316 DECLARE_SC("Online", RPC_DUMMY, NcOnline, InRpcDummy, OutRpcDummy)\r
317 DECLARE_SC("Offline", RPC_DUMMY, NcOffline, InRpcDummy, OutRpcDummy)\r
318 DECLARE_SC("SetHostOption", VH_OPTION, NcSetHostOption, InVhOption, OutVhOption)\r
319 DECLARE_SC("GetHostOption", VH_OPTION, NcGetHostOption, InVhOption, OutVhOption)\r
320 DECLARE_SC_EX("SetClientConfig", RPC_CREATE_LINK, NcSetClientConfig, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)\r
321 DECLARE_SC_EX("GetClientConfig", RPC_CREATE_LINK, NcGetClientConfig, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)\r
322 DECLARE_SC_EX("GetStatus", RPC_NAT_STATUS, NcGetStatus, InRpcNatStatus, OutRpcNatStatus, FreeRpcNatStatus)\r
323 DECLARE_SC_EX("GetInfo", RPC_NAT_INFO, NcGetInfo, InRpcNatInfo, OutRpcNatInfo, FreeRpcNatInfo)\r
324 DECLARE_SC_EX("EnumNatList", RPC_ENUM_NAT, NcEnumNatList, InRpcEnumNat, OutRpcEnumNat, FreeRpcEnumNat)\r
325 DECLARE_SC_EX("EnumDhcpList", RPC_ENUM_DHCP, NcEnumDhcpList, InRpcEnumDhcp, OutRpcEnumDhcp, FreeRpcEnumDhcp)\r
326 DECLARE_SC("SetPassword", RPC_SET_PASSWORD, NcSetPassword, InRpcSetPassword, OutRpcSetPassword)\r
327 \r
328 // RPC 呼び出し定義ここまで\r
329 \r
330 \r
331 \r
332 // パスワードを設定する\r
333 UINT NtSetPassword(NAT *n, RPC_SET_PASSWORD *t)\r
334 {\r
335         Copy(n->HashedPassword, t->HashedPassword, SHA1_SIZE);\r
336 \r
337         NiWriteConfig(n);\r
338 \r
339         return ERR_NO_ERROR;\r
340 }\r
341 \r
342 // オンラインにする\r
343 UINT NtOnline(NAT *n, RPC_DUMMY *t)\r
344 {\r
345         UINT ret = ERR_NO_ERROR;\r
346 \r
347         Lock(n->lock);\r
348         {\r
349                 if (n->Online)\r
350                 {\r
351                         // すでにオンラインである\r
352                         ret = ERR_ALREADY_ONLINE;\r
353                 }\r
354                 else\r
355                 {\r
356                         if (n->ClientOption == NULL || n->ClientAuth == NULL)\r
357                         {\r
358                                 // 設定がまだ\r
359                                 ret = ERR_ACCOUNT_NOT_PRESENT;\r
360                         }\r
361                         else\r
362                         {\r
363                                 // OK\r
364                                 n->Online = true;\r
365 \r
366                                 // 接続開始\r
367                                 n->Virtual = NewVirtualHostEx(n->Cedar, n->ClientOption, n->ClientAuth,\r
368                                         &n->Option, n);\r
369                         }\r
370                 }\r
371         }\r
372         Unlock(n->lock);\r
373 \r
374         NiWriteConfig(n);\r
375 \r
376         return ret;\r
377 }\r
378 \r
379 // オフラインにする\r
380 UINT NtOffline(NAT *n, RPC_DUMMY *t)\r
381 {\r
382         UINT ret = ERR_NO_ERROR;\r
383 \r
384         Lock(n->lock);\r
385         {\r
386                 if (n->Online == false)\r
387                 {\r
388                         // オフラインである\r
389                         ret = ERR_OFFLINE;\r
390                 }\r
391                 else\r
392                 {\r
393                         // オフラインにする\r
394                         StopVirtualHost(n->Virtual);\r
395                         ReleaseVirtual(n->Virtual);\r
396                         n->Virtual = NULL;\r
397 \r
398                         n->Online = false;\r
399                 }\r
400         }\r
401         Unlock(n->lock);\r
402 \r
403         NiWriteConfig(n);\r
404 \r
405         return ret;\r
406 }\r
407 \r
408 // ホストオプションの設定\r
409 UINT NtSetHostOption(NAT *n, VH_OPTION *t)\r
410 {\r
411         UINT ret = ERR_NO_ERROR;\r
412 \r
413         Lock(n->lock);\r
414         {\r
415                 Copy(&n->Option, t, sizeof(VH_OPTION));\r
416         }\r
417         Unlock(n->lock);\r
418 \r
419         SetVirtualHostOption(n->Virtual, t);\r
420 \r
421         NiWriteConfig(n);\r
422 \r
423         return ret;\r
424 }\r
425 \r
426 // ホストオプションの取得\r
427 UINT NtGetHostOption(NAT *n, VH_OPTION *t)\r
428 {\r
429         UINT ret = ERR_NO_ERROR;\r
430 \r
431         Lock(n->lock);\r
432         {\r
433                 Copy(t, &n->Option, sizeof(VH_OPTION));\r
434         }\r
435         Unlock(n->lock);\r
436 \r
437         return ret;\r
438 }\r
439 \r
440 // 接続設定の設定\r
441 UINT NtSetClientConfig(NAT *n, RPC_CREATE_LINK *t)\r
442 {\r
443         Lock(n->lock);\r
444         {\r
445                 if (n->ClientOption != NULL || n->ClientAuth != NULL)\r
446                 {\r
447                         Free(n->ClientOption);\r
448                         CiFreeClientAuth(n->ClientAuth);\r
449                 }\r
450 \r
451                 n->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));\r
452                 Copy(n->ClientOption, t->ClientOption, sizeof(CLIENT_OPTION));\r
453                 n->ClientAuth = CopyClientAuth(t->ClientAuth);\r
454         }\r
455         Unlock(n->lock);\r
456 \r
457         NiWriteConfig(n);\r
458 \r
459         if (n->Online)\r
460         {\r
461                 NtOffline(n, NULL);\r
462                 NtOnline(n, NULL);\r
463         }\r
464 \r
465         return ERR_NO_ERROR;\r
466 }\r
467 \r
468 // 接続設定の取得\r
469 UINT NtGetClientConfig(NAT *n, RPC_CREATE_LINK *t)\r
470 {\r
471         UINT err = ERR_NO_ERROR;\r
472 \r
473         Lock(n->lock);\r
474         {\r
475                 if (n->ClientOption == NULL || n->ClientAuth == NULL)\r
476                 {\r
477                         err = ERR_ACCOUNT_NOT_PRESENT;\r
478                 }\r
479                 else\r
480                 {\r
481                         FreeRpcCreateLink(t);\r
482 \r
483                         Zero(t, sizeof(RPC_CREATE_LINK));\r
484                         t->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));\r
485                         Copy(t->ClientOption, n->ClientOption, sizeof(CLIENT_OPTION));\r
486                         t->ClientAuth = CopyClientAuth(n->ClientAuth);\r
487                 }\r
488         }\r
489         Unlock(n->lock);\r
490 \r
491         return err;\r
492 }\r
493 \r
494 // 状態の取得\r
495 UINT NtGetStatus(NAT *n, RPC_NAT_STATUS *t)\r
496 {\r
497         Lock(n->lock);\r
498         {\r
499                 VH *v = n->Virtual;\r
500                 FreeRpcNatStatus(t);\r
501                 Zero(t, sizeof(RPC_NAT_STATUS));\r
502 \r
503                 LockVirtual(v);\r
504                 {\r
505                         UINT i;\r
506 \r
507                         LockList(v->NatTable);\r
508                         {\r
509                                 for (i = 0;i < LIST_NUM(v->NatTable);i++)\r
510                                 {\r
511                                         NAT_ENTRY *e = LIST_DATA(v->NatTable, i);\r
512 \r
513                                         switch (e->Protocol)\r
514                                         {\r
515                                         case NAT_TCP:\r
516                                                 t->NumTcpSessions++;\r
517                                                 break;\r
518 \r
519                                         case NAT_UDP:\r
520                                                 t->NumUdpSessions++;\r
521                                                 break;\r
522                                         }\r
523                                 }\r
524                         }\r
525                         UnlockList(v->NatTable);\r
526 \r
527                         t->NumDhcpClients = LIST_NUM(v->DhcpLeaseList);\r
528                 }\r
529                 UnlockVirtual(v);\r
530         }\r
531         Unlock(n->lock);\r
532 \r
533         return ERR_NO_ERROR;\r
534 }\r
535 \r
536 // 情報の取得\r
537 UINT NtGetInfo(NAT *n, RPC_NAT_INFO *t)\r
538 {\r
539         OS_INFO *info;\r
540         FreeRpcNatInfo(t);\r
541         Zero(t, sizeof(RPC_NAT_INFO));\r
542 \r
543         StrCpy(t->NatProductName, sizeof(t->NatProductName), CEDAR_ROUTER_STR);\r
544         StrCpy(t->NatVersionString, sizeof(t->NatVersionString), n->Cedar->VerString);\r
545         StrCpy(t->NatBuildInfoString, sizeof(t->NatBuildInfoString), n->Cedar->BuildInfo);\r
546         t->NatVerInt = n->Cedar->Build;\r
547         t->NatBuildInt = n->Cedar->Build;\r
548 \r
549         GetMachineName(t->NatHostName, sizeof(t->NatHostName));\r
550 \r
551         info = GetOsInfo();\r
552 \r
553         CopyOsInfo(&t->OsInfo, info);\r
554 \r
555         GetMemInfo(&t->MemInfo);\r
556 \r
557         return ERR_NO_ERROR;\r
558 }\r
559 \r
560 // NAT リストの取得\r
561 UINT NtEnumNatList(NAT *n, RPC_ENUM_NAT *t)\r
562 {\r
563         UINT ret = ERR_NO_ERROR;\r
564         VH *v = NULL;\r
565 \r
566         Lock(n->lock);\r
567         {\r
568                 v = n->Virtual;\r
569 \r
570                 if (n->Online == false || v == NULL)\r
571                 {\r
572                         ret = ERR_OFFLINE;\r
573                 }\r
574                 else\r
575                 {\r
576                         LockVirtual(v);\r
577                         {\r
578                                 if (v->Active == false)\r
579                                 {\r
580                                         ret = ERR_OFFLINE;\r
581                                 }\r
582                                 else\r
583                                 {\r
584                                         FreeRpcEnumNat(t);\r
585                                         Zero(t, sizeof(RPC_ENUM_NAT));\r
586 \r
587                                         LockList(v->NatTable);\r
588                                         {\r
589                                                 UINT i;\r
590                                                 t->NumItem = LIST_NUM(v->NatTable);\r
591                                                 t->Items = ZeroMalloc(sizeof(RPC_ENUM_NAT_ITEM) * t->NumItem);\r
592 \r
593                                                 for (i = 0;i < t->NumItem;i++)\r
594                                                 {\r
595                                                         NAT_ENTRY *nat = LIST_DATA(v->NatTable, i);\r
596                                                         RPC_ENUM_NAT_ITEM *e = &t->Items[i];\r
597 \r
598                                                         e->Id = nat->Id;\r
599                                                         e->Protocol = nat->Protocol;\r
600                                                         e->SrcIp = nat->SrcIp;\r
601                                                         e->DestIp = nat->DestIp;\r
602                                                         e->SrcPort = nat->SrcPort;\r
603                                                         e->DestPort = nat->DestPort;\r
604 \r
605                                                         e->CreatedTime = TickToTime(nat->CreatedTime);\r
606                                                         e->LastCommTime = TickToTime(nat->LastCommTime);\r
607 \r
608                                                         IPToStr32(e->SrcHost, sizeof(e->SrcHost), e->SrcIp);\r
609                                                         IPToStr32(e->DestHost, sizeof(e->DestHost), e->DestIp);\r
610 \r
611                                                         if (nat->Sock != NULL)\r
612                                                         {\r
613                                                                 e->SendSize = nat->Sock->SendSize;\r
614                                                                 e->RecvSize = nat->Sock->RecvSize;\r
615 \r
616                                                                 if (nat->Sock->Type == SOCK_TCP)\r
617                                                                 {\r
618                                                                         StrCpy(e->DestHost, sizeof(e->DestHost), nat->Sock->RemoteHostname);\r
619                                                                 }\r
620                                                         }\r
621 \r
622                                                         e->TcpStatus = nat->TcpStatus;\r
623                                                 }\r
624                                         }\r
625                                         UnlockList(v->NatTable);\r
626                                 }\r
627                         }\r
628                         UnlockVirtual(v);\r
629                 }\r
630         }\r
631         Unlock(n->lock);\r
632 \r
633         return ret;\r
634 }\r
635 \r
636 UINT NtEnumDhcpList(NAT *n, RPC_ENUM_DHCP *t)\r
637 {\r
638         UINT ret = ERR_NO_ERROR;\r
639         VH *v = NULL;\r
640 \r
641         Lock(n->lock);\r
642         {\r
643                 v = n->Virtual;\r
644 \r
645                 if (n->Online == false || v == NULL)\r
646                 {\r
647                         ret = ERR_OFFLINE;\r
648                 }\r
649                 else\r
650                 {\r
651                         LockVirtual(v);\r
652                         {\r
653                                 if (v->Active == false)\r
654                                 {\r
655                                         ret = ERR_OFFLINE;\r
656                                 }\r
657                                 else\r
658                                 {\r
659                                         FreeRpcEnumDhcp(t);\r
660                                         Zero(t, sizeof(RPC_ENUM_DHCP));\r
661 \r
662                                         LockList(v->DhcpLeaseList);\r
663                                         {\r
664                                                 UINT i;\r
665                                                 t->NumItem = LIST_NUM(v->DhcpLeaseList);\r
666                                                 t->Items = ZeroMalloc(sizeof(RPC_ENUM_DHCP_ITEM) * t->NumItem);\r
667 \r
668                                                 for (i = 0;i < t->NumItem;i++)\r
669                                                 {\r
670                                                         DHCP_LEASE *dhcp = LIST_DATA(v->DhcpLeaseList, i);\r
671                                                         RPC_ENUM_DHCP_ITEM *e = &t->Items[i];\r
672 \r
673                                                         e->Id = dhcp->Id;\r
674                                                         e->LeasedTime = TickToTime(dhcp->LeasedTime);\r
675                                                         e->ExpireTime = TickToTime(dhcp->ExpireTime);\r
676                                                         Copy(e->MacAddress, dhcp->MacAddress, 6);\r
677                                                         e->IpAddress = dhcp->IpAddress;\r
678                                                         e->Mask = dhcp->Mask;\r
679                                                         StrCpy(e->Hostname, sizeof(e->Hostname), dhcp->Hostname);\r
680                                                 }\r
681                                         }\r
682                                         UnlockList(v->DhcpLeaseList);\r
683                                 }\r
684                         }\r
685                         UnlockVirtual(v);\r
686                 }\r
687         }\r
688         Unlock(n->lock);\r
689 \r
690         return ret;\r
691 }\r
692 \r
693 // VH_OPTION\r
694 void InVhOption(VH_OPTION *t, PACK *p)\r
695 {\r
696         // 引数チェック\r
697         if (t == NULL || p == NULL)\r
698         {\r
699                 return;\r
700         }\r
701 \r
702         Zero(t, sizeof(VH_OPTION));\r
703         PackGetData2(p, "MacAddress", t->MacAddress, 6);\r
704         PackGetIp(p, "Ip", &t->Ip);\r
705         PackGetIp(p, "Mask", &t->Mask);\r
706         t->UseNat = PackGetBool(p, "UseNat");\r
707         t->Mtu = PackGetInt(p, "Mtu");\r
708         t->NatTcpTimeout = PackGetInt(p, "NatTcpTimeout");\r
709         t->NatUdpTimeout = PackGetInt(p, "NatUdpTimeout");\r
710         t->UseDhcp = PackGetBool(p, "UseDhcp");\r
711         PackGetIp(p, "DhcpLeaseIPStart", &t->DhcpLeaseIPStart);\r
712         PackGetIp(p, "DhcpLeaseIPEnd", &t->DhcpLeaseIPEnd);\r
713         PackGetIp(p, "DhcpSubnetMask", &t->DhcpSubnetMask);\r
714         t->DhcpExpireTimeSpan = PackGetInt(p, "DhcpExpireTimeSpan");\r
715         PackGetIp(p, "DhcpGatewayAddress", &t->DhcpGatewayAddress);\r
716         PackGetIp(p, "DhcpDnsServerAddress", &t->DhcpDnsServerAddress);\r
717         PackGetStr(p, "DhcpDomainName", t->DhcpDomainName, sizeof(t->DhcpDomainName));\r
718         t->SaveLog = PackGetBool(p, "SaveLog");\r
719         PackGetStr(p, "RpcHubName", t->HubName, sizeof(t->HubName));\r
720 }\r
721 void OutVhOption(PACK *p, VH_OPTION *t)\r
722 {\r
723         // 引数チェック\r
724         if (t == NULL || p == NULL)\r
725         {\r
726                 return;\r
727         }\r
728 \r
729         PackAddData(p, "MacAddress", t->MacAddress, 6);\r
730         PackAddIp(p, "Ip", &t->Ip);\r
731         PackAddIp(p, "Mask", &t->Mask);\r
732         PackAddBool(p, "UseNat", t->UseNat);\r
733         PackAddInt(p, "Mtu", t->Mtu);\r
734         PackAddInt(p, "NatTcpTimeout", t->NatTcpTimeout);\r
735         PackAddInt(p, "NatUdpTimeout", t->NatUdpTimeout);\r
736         PackAddBool(p, "UseDhcp", t->UseDhcp);\r
737         PackAddIp(p, "DhcpLeaseIPStart", &t->DhcpLeaseIPStart);\r
738         PackAddIp(p, "DhcpLeaseIPEnd", &t->DhcpLeaseIPEnd);\r
739         PackAddIp(p, "DhcpSubnetMask", &t->DhcpSubnetMask);\r
740         PackAddInt(p, "DhcpExpireTimeSpan", t->DhcpExpireTimeSpan);\r
741         PackAddIp(p, "DhcpGatewayAddress", &t->DhcpGatewayAddress);\r
742         PackAddIp(p, "DhcpDnsServerAddress", &t->DhcpDnsServerAddress);\r
743         PackAddStr(p, "DhcpDomainName", t->DhcpDomainName);\r
744         PackAddBool(p, "SaveLog", t->SaveLog);\r
745         PackAddStr(p, "RpcHubName", t->HubName);\r
746 }\r
747 \r
748 // RPC_ENUM_DHCP\r
749 void InRpcEnumDhcp(RPC_ENUM_DHCP *t, PACK *p)\r
750 {\r
751         UINT i;\r
752         // 引数チェック\r
753         if (t == NULL || p == NULL)\r
754         {\r
755                 return;\r
756         }\r
757 \r
758         Zero(t, sizeof(RPC_ENUM_DHCP));\r
759         t->NumItem = PackGetInt(p, "NumItem");\r
760         t->Items = ZeroMalloc(sizeof(RPC_ENUM_DHCP_ITEM) * t->NumItem);\r
761         PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));\r
762 \r
763         for (i = 0;i < t->NumItem;i++)\r
764         {\r
765                 RPC_ENUM_DHCP_ITEM *e = &t->Items[i];\r
766 \r
767                 e->Id = PackGetIntEx(p, "Id", i);\r
768                 e->LeasedTime = PackGetInt64Ex(p, "LeasedTime", i);\r
769                 e->ExpireTime = PackGetInt64Ex(p, "ExpireTime", i);\r
770                 PackGetDataEx2(p, "MacAddress", e->MacAddress, 6, i);\r
771                 e->IpAddress = PackGetIp32Ex(p, "IpAddress", i);\r
772                 e->Mask = PackGetIntEx(p, "Mask", i);\r
773                 PackGetStrEx(p, "Hostname", e->Hostname, sizeof(e->Hostname), i);\r
774         }\r
775 }\r
776 void OutRpcEnumDhcp(PACK *p, RPC_ENUM_DHCP *t)\r
777 {\r
778         UINT i;\r
779         // 引数チェック\r
780         if (p == NULL || t == NULL)\r
781         {\r
782                 return;\r
783         }\r
784 \r
785         PackAddInt(p, "NumItem", t->NumItem);\r
786         PackAddStr(p, "HubName", t->HubName);\r
787 \r
788         for (i = 0;i < t->NumItem;i++)\r
789         {\r
790                 RPC_ENUM_DHCP_ITEM *e = &t->Items[i];\r
791 \r
792                 PackAddIntEx(p, "Id", e->Id, i, t->NumItem);\r
793                 PackAddInt64Ex(p, "LeasedTime", e->LeasedTime, i, t->NumItem);\r
794                 PackAddInt64Ex(p, "ExpireTime", e->ExpireTime, i, t->NumItem);\r
795                 PackAddDataEx(p, "MacAddress", e->MacAddress, 6, i, t->NumItem);\r
796                 PackAddIp32Ex(p, "IpAddress", e->IpAddress, i, t->NumItem);\r
797                 PackAddIntEx(p, "Mask", e->Mask, i, t->NumItem);\r
798                 PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumItem);\r
799         }\r
800 }\r
801 void FreeRpcEnumDhcp(RPC_ENUM_DHCP *t)\r
802 {\r
803         // 引数チェック\r
804         if (t == NULL)\r
805         {\r
806                 return;\r
807         }\r
808 \r
809         Free(t->Items);\r
810 }\r
811 \r
812 // RPC_ENUM_NAT\r
813 void InRpcEnumNat(RPC_ENUM_NAT *t, PACK *p)\r
814 {\r
815         UINT i;\r
816         // 引数チェック\r
817         if (t == NULL || p == NULL)\r
818         {\r
819                 return;\r
820         }\r
821 \r
822         Zero(t, sizeof(RPC_ENUM_NAT));\r
823         t->NumItem = PackGetInt(p, "NumItem");\r
824         PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));\r
825         t->Items = ZeroMalloc(sizeof(RPC_ENUM_NAT_ITEM) * t->NumItem);\r
826         for (i = 0;i < t->NumItem;i++)\r
827         {\r
828                 RPC_ENUM_NAT_ITEM *e = &t->Items[i];\r
829 \r
830                 e->Id = PackGetIntEx(p, "Id", i);\r
831                 e->Protocol = PackGetIntEx(p, "Protocol", i);\r
832                 e->SrcIp = PackGetIntEx(p, "SrcIp", i);\r
833                 PackGetStrEx(p, "SrcHost", e->SrcHost, sizeof(e->SrcHost), i);\r
834                 e->SrcPort = PackGetIntEx(p, "SrcPort", i);\r
835                 e->DestIp = PackGetIntEx(p, "DestIp", i);\r
836                 PackGetStrEx(p, "DestHost", e->DestHost, sizeof(e->DestHost), i);\r
837                 e->DestPort = PackGetIntEx(p, "DestPort", i);\r
838                 e->CreatedTime = PackGetInt64Ex(p, "CreatedTime", i);\r
839                 e->LastCommTime = PackGetInt64Ex(p, "LastCommTime", i);\r
840                 e->SendSize = PackGetInt64Ex(p, "SendSize", i);\r
841                 e->RecvSize = PackGetInt64Ex(p, "RecvSize", i);\r
842                 e->TcpStatus = PackGetIntEx(p, "TcpStatus", i);\r
843         }\r
844 }\r
845 void OutRpcEnumNat(PACK *p, RPC_ENUM_NAT *t)\r
846 {\r
847         UINT i;\r
848         // 引数チェック\r
849         if (t == NULL || p == NULL)\r
850         {\r
851                 return;\r
852         }\r
853 \r
854         PackAddInt(p, "NumItem", t->NumItem);\r
855         PackAddStr(p, "HubName", t->HubName);\r
856         for (i = 0;i < t->NumItem;i++)\r
857         {\r
858                 RPC_ENUM_NAT_ITEM *e = &t->Items[i];\r
859 \r
860                 PackAddIntEx(p, "Id", e->Id, i, t->NumItem);\r
861                 PackAddIntEx(p, "Protocol", e->Protocol, i, t->NumItem);\r
862                 PackAddIp32Ex(p, "SrcIp", e->SrcIp, i, t->NumItem);\r
863                 PackAddStrEx(p, "SrcHost", e->SrcHost, i, t->NumItem);\r
864                 PackAddIntEx(p, "SrcPort", e->SrcPort, i, t->NumItem);\r
865                 PackAddIp32Ex(p, "DestIp", e->DestIp, i, t->NumItem);\r
866                 PackAddStrEx(p, "DestHost", e->DestHost, i, t->NumItem);\r
867                 PackAddIntEx(p, "DestPort", e->DestPort, i, t->NumItem);\r
868                 PackAddInt64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumItem);\r
869                 PackAddInt64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumItem);\r
870                 PackAddInt64Ex(p, "SendSize", e->SendSize, i, t->NumItem);\r
871                 PackAddInt64Ex(p, "RecvSize", e->RecvSize, i, t->NumItem);\r
872                 PackAddIntEx(p, "TcpStatus", e->TcpStatus, i, t->NumItem);\r
873         }\r
874 }\r
875 void FreeRpcEnumNat(RPC_ENUM_NAT *t)\r
876 {\r
877         // 引数チェック\r
878         if (t == NULL)\r
879         {\r
880                 return;\r
881         }\r
882 \r
883         Free(t->Items);\r
884 }\r
885 \r
886 // RPC_NAT_INFO\r
887 void InRpcNatInfo(RPC_NAT_INFO *t, PACK *p)\r
888 {\r
889         // 引数チェック\r
890         if (t == NULL || p == NULL)\r
891         {\r
892                 return;\r
893         }\r
894 \r
895         Zero(t, sizeof(RPC_NAT_INFO));\r
896         PackGetStr(p, "NatProductName", t->NatProductName, sizeof(t->NatProductName));\r
897         PackGetStr(p, "NatVersionString", t->NatVersionString, sizeof(t->NatVersionString));\r
898         PackGetStr(p, "NatBuildInfoString", t->NatBuildInfoString, sizeof(t->NatBuildInfoString));\r
899         t->NatVerInt = PackGetInt(p, "NatVerInt");\r
900         t->NatBuildInt = PackGetInt(p, "NatBuildInt");\r
901         PackGetStr(p, "NatHostName", t->NatHostName, sizeof(t->NatHostName));\r
902         InRpcOsInfo(&t->OsInfo, p);\r
903         InRpcMemInfo(&t->MemInfo, p);\r
904 }\r
905 void OutRpcNatInfo(PACK *p, RPC_NAT_INFO *t)\r
906 {\r
907         // 引数チェック\r
908         if (t == NULL || p == NULL)\r
909         {\r
910                 return;\r
911         }\r
912 \r
913         PackAddStr(p, "NatProductName", t->NatProductName);\r
914         PackAddStr(p, "NatVersionString", t->NatVersionString);\r
915         PackAddStr(p, "NatBuildInfoString", t->NatBuildInfoString);\r
916         PackAddInt(p, "NatVerInt", t->NatVerInt);\r
917         PackAddInt(p, "NatBuildInt", t->NatBuildInt);\r
918         PackAddStr(p, "NatHostName", t->NatHostName);\r
919         OutRpcOsInfo(p, &t->OsInfo);\r
920         OutRpcMemInfo(p, &t->MemInfo);\r
921 }\r
922 void FreeRpcNatInfo(RPC_NAT_INFO *t)\r
923 {\r
924         // 引数チェック\r
925         if (t == NULL)\r
926         {\r
927                 return;\r
928         }\r
929 \r
930         FreeRpcOsInfo(&t->OsInfo);\r
931 }\r
932 \r
933 // RPC_NAT_STATUS\r
934 void InRpcNatStatus(RPC_NAT_STATUS *t, PACK *p)\r
935 {\r
936         // 引数チェック\r
937         if (t == NULL || p == NULL)\r
938         {\r
939                 return;\r
940         }\r
941 \r
942         Zero(t, sizeof(RPC_NAT_STATUS));\r
943         t->NumTcpSessions = PackGetInt(p, "NumTcpSessions");\r
944         t->NumUdpSessions = PackGetInt(p, "NumUdpSessions");\r
945         t->NumDhcpClients = PackGetInt(p, "NumDhcpClients");\r
946         PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));\r
947 }\r
948 void OutRpcNatStatus(PACK *p, RPC_NAT_STATUS *t)\r
949 {\r
950         // 引数チェック\r
951         if (p == NULL || t == NULL)\r
952         {\r
953                 return;\r
954         }\r
955 \r
956         PackAddStr(p, "HubName", t->HubName);\r
957         PackAddInt(p, "NumTcpSessions", t->NumTcpSessions);\r
958         PackAddInt(p, "NumUdpSessions", t->NumUdpSessions);\r
959         PackAddInt(p, "NumDhcpClients", t->NumDhcpClients);\r
960 }\r
961 void FreeRpcNatStatus(RPC_NAT_STATUS *t)\r
962 {\r
963 }\r
964 \r
965 // RPC_DUMMY\r
966 void InRpcDummy(RPC_DUMMY *t, PACK *p)\r
967 {\r
968         // 引数チェック\r
969         if (t == NULL || p == NULL)\r
970         {\r
971                 return;\r
972         }\r
973 \r
974         Zero(t, sizeof(RPC_DUMMY));\r
975         t->DummyValue = PackGetInt(p, "DummyValue");\r
976 }\r
977 void OutRpcDummy(PACK *p, RPC_DUMMY *t)\r
978 {\r
979         // 引数チェック\r
980         if (t == NULL || p == NULL)\r
981         {\r
982                 return;\r
983         }\r
984 \r
985         PackAddInt(p, "DummyValue", t->DummyValue);\r
986 }\r
987 \r
988 // 管理用メインプロシージャ\r
989 void NiAdminMain(NAT *n, SOCK *s)\r
990 {\r
991         RPC *r;\r
992         PACK *p;\r
993         // 引数チェック\r
994         if (n == NULL || s == NULL)\r
995         {\r
996                 return;\r
997         }\r
998 \r
999         p = NewPack();\r
1000         HttpServerSend(s, p);\r
1001         FreePack(p);\r
1002 \r
1003         r = StartRpcServer(s, NiRpcServer, n);\r
1004 \r
1005         RpcServer(r);\r
1006 \r
1007         RpcFree(r);\r
1008 }\r
1009 \r
1010 // 管理スレッド\r
1011 void NiAdminThread(THREAD *thread, void *param)\r
1012 {\r
1013         NAT_ADMIN *a = (NAT_ADMIN *)param;\r
1014         NAT *n;\r
1015         SOCK *s;\r
1016         UCHAR random[SHA1_SIZE];\r
1017         UINT err;\r
1018         // 引数チェック\r
1019         if (thread == NULL || param == NULL)\r
1020         {\r
1021                 return;\r
1022         }\r
1023 \r
1024         // 乱数生成\r
1025         Rand(random, sizeof(random));\r
1026 \r
1027         a->Thread = thread;\r
1028         AddRef(a->Thread->ref);\r
1029         s = a->Sock;\r
1030         AddRef(s->ref);\r
1031 \r
1032         n = a->Nat;\r
1033 \r
1034         LockList(n->AdminList);\r
1035         {\r
1036                 Add(n->AdminList, a);\r
1037         }\r
1038         UnlockList(n->AdminList);\r
1039 \r
1040         NoticeThreadInit(thread);\r
1041 \r
1042         err = ERR_AUTH_FAILED;\r
1043 \r
1044         if (StartSSL(s, n->AdminX, n->AdminK))\r
1045         {\r
1046                 PACK *p;\r
1047 \r
1048                 // 乱数を送信する\r
1049                 p = NewPack();\r
1050                 PackAddData(p, "auth_random", random, sizeof(random));\r
1051 \r
1052                 if (HttpServerSend(s, p))\r
1053                 {\r
1054                         PACK *p;\r
1055                         // パスワードを受け取る\r
1056                         p = HttpServerRecv(s);\r
1057                         if (p != NULL)\r
1058                         {\r
1059                                 UCHAR secure_password[SHA1_SIZE];\r
1060                                 UCHAR secure_check[SHA1_SIZE];\r
1061 \r
1062                                 if (PackGetData2(p, "secure_password", secure_password, sizeof(secure_password)))\r
1063                                 {\r
1064                                         SecurePassword(secure_check, n->HashedPassword, random);\r
1065 \r
1066                                         if (Cmp(secure_check, secure_password, SHA1_SIZE) == 0)\r
1067                                         {\r
1068                                                 UCHAR test[SHA1_SIZE];\r
1069                                                 // パスワード一致\r
1070                                                 Hash(test, "", 0, true);\r
1071                                                 SecurePassword(test, test, random);\r
1072 \r
1073 #if     0\r
1074                                                 if (Cmp(test, secure_check, SHA1_SIZE) == 0 && s->RemoteIP.addr[0] != 127)\r
1075                                                 {\r
1076                                                         // 空白パスワードは外部から接続できない\r
1077                                                         err = ERR_NULL_PASSWORD_LOCAL_ONLY;\r
1078                                                 }\r
1079                                                 else\r
1080 #endif\r
1081 \r
1082                                                 {\r
1083                                                         // 接続成功\r
1084                                                         err = ERR_NO_ERROR;\r
1085                                                         NiAdminMain(n, s);\r
1086                                                 }\r
1087                                         }\r
1088                                 }\r
1089 \r
1090                                 FreePack(p);\r
1091                         }\r
1092                 }\r
1093 \r
1094                 FreePack(p);\r
1095 \r
1096                 if (err != ERR_NO_ERROR)\r
1097                 {\r
1098                         p = PackError(err);\r
1099                         HttpServerSend(s, p);\r
1100                         FreePack(p);\r
1101                 }\r
1102         }\r
1103 \r
1104         Disconnect(s);\r
1105         ReleaseSock(s);\r
1106 }\r
1107 \r
1108 // 管理ポート Listen スレッド\r
1109 void NiListenThread(THREAD *thread, void *param)\r
1110 {\r
1111         NAT *n = (NAT *)param;\r
1112         SOCK *a;\r
1113         UINT i;\r
1114         bool b = false;\r
1115         // 引数チェック\r
1116         if (thread == NULL || param == NULL)\r
1117         {\r
1118                 return;\r
1119         }\r
1120 \r
1121         // 管理リストの初期化\r
1122         n->AdminList = NewList(NULL);\r
1123 \r
1124         while (true)\r
1125         {\r
1126                 a = Listen(DEFAULT_NAT_ADMIN_PORT);\r
1127                 if (b == false)\r
1128                 {\r
1129                         b = true;\r
1130                         NoticeThreadInit(thread);\r
1131                 }\r
1132                 if (a != NULL)\r
1133                 {\r
1134                         break;\r
1135                 }\r
1136 \r
1137                 Wait(n->HaltEvent, NAT_ADMIN_PORT_LISTEN_INTERVAL);\r
1138                 if (n->Halt)\r
1139                 {\r
1140                         return;\r
1141                 }\r
1142         }\r
1143 \r
1144         n->AdminListenSock = a;\r
1145         AddRef(a->ref);\r
1146 \r
1147         // 待ち受け\r
1148         while (true)\r
1149         {\r
1150                 SOCK *s = Accept(a);\r
1151                 THREAD *t;\r
1152                 NAT_ADMIN *admin;\r
1153                 if (s == NULL)\r
1154                 {\r
1155                         break;\r
1156                 }\r
1157                 if (n->Halt)\r
1158                 {\r
1159                         ReleaseSock(s);\r
1160                         break;\r
1161                 }\r
1162 \r
1163                 admin = ZeroMalloc(sizeof(NAT_ADMIN));\r
1164                 admin->Nat = n;\r
1165                 admin->Sock = s;\r
1166                 t = NewThread(NiAdminThread, admin);\r
1167                 WaitThreadInit(t);\r
1168                 ReleaseThread(t);\r
1169         }\r
1170 \r
1171         // すべての管理コネクションを切断\r
1172         LockList(n->AdminList);\r
1173         {\r
1174                 for (i = 0;i < LIST_NUM(n->AdminList);i++)\r
1175                 {\r
1176                         NAT_ADMIN *a = LIST_DATA(n->AdminList, i);\r
1177                         Disconnect(a->Sock);\r
1178                         WaitThread(a->Thread, INFINITE);\r
1179                         ReleaseThread(a->Thread);\r
1180                         ReleaseSock(a->Sock);\r
1181                         Free(a);\r
1182                 }\r
1183         }\r
1184         UnlockList(n->AdminList);\r
1185 \r
1186         ReleaseList(n->AdminList);\r
1187 \r
1188         ReleaseSock(a);\r
1189 }\r
1190 \r
1191 // 管理コマンド受付初期化\r
1192 void NiInitAdminAccept(NAT *n)\r
1193 {\r
1194         THREAD *t;\r
1195         // 引数チェック\r
1196         if (n == NULL)\r
1197         {\r
1198                 return;\r
1199         }\r
1200 \r
1201         t = NewThread(NiListenThread, n);\r
1202         WaitThreadInit(t);\r
1203         n->AdminAcceptThread = t;\r
1204 }\r
1205 \r
1206 // 管理コマンド受付終了\r
1207 void NiFreeAdminAccept(NAT *n)\r
1208 {\r
1209         // 引数チェック\r
1210         if (n == NULL)\r
1211         {\r
1212                 return;\r
1213         }\r
1214 \r
1215         n->Halt = true;\r
1216         Disconnect(n->AdminListenSock);\r
1217         Set(n->HaltEvent);\r
1218 \r
1219         while (true)\r
1220         {\r
1221                 if (WaitThread(n->AdminAcceptThread, 1000) == false)\r
1222                 {\r
1223                         Disconnect(n->AdminListenSock);\r
1224                 }\r
1225                 else\r
1226                 {\r
1227                         break;\r
1228                 }\r
1229         }\r
1230         ReleaseThread(n->AdminAcceptThread);\r
1231 \r
1232         ReleaseSock(n->AdminListenSock);\r
1233 }\r
1234 \r
1235 // ダイナミック仮想 HUB でサポートされていない DHCP オプションをクリアする\r
1236 void NiClearUnsupportedVhOptionForDynamicHub(VH_OPTION *o, bool initial)\r
1237 {\r
1238         // 引数チェック\r
1239         if (o == NULL)\r
1240         {\r
1241                 return;\r
1242         }\r
1243 \r
1244         o->UseNat = false;\r
1245 \r
1246         if (initial)\r
1247         {\r
1248                 Zero(&o->DhcpGatewayAddress, sizeof(IP));\r
1249                 Zero(&o->DhcpDnsServerAddress, sizeof(IP));\r
1250                 StrCpy(o->DhcpDomainName, sizeof(o->DhcpDomainName), "");\r
1251         }\r
1252 }\r
1253 \r
1254 // 仮想ホストのオプションを初期化する\r
1255 void NiSetDefaultVhOption(NAT *n, VH_OPTION *o)\r
1256 {\r
1257         // 引数チェック\r
1258         if (o == NULL)\r
1259         {\r
1260                 return;\r
1261         }\r
1262 \r
1263         Zero(o, sizeof(VH_OPTION));\r
1264         GenMacAddress(o->MacAddress);\r
1265 \r
1266         // 仮想 IP を 192.168.30.1/24 にする\r
1267         SetIP(&o->Ip, 192, 168, 30, 1);\r
1268         SetIP(&o->Mask, 255, 255, 255, 0);\r
1269         o->UseNat = true;\r
1270         o->Mtu = 1500;\r
1271         o->NatTcpTimeout = 7200;\r
1272         o->NatUdpTimeout = 60;\r
1273         o->UseDhcp = true;\r
1274         SetIP(&o->DhcpLeaseIPStart, 192, 168, 30, 10);\r
1275         SetIP(&o->DhcpLeaseIPEnd, 192, 168, 30, 200);\r
1276         SetIP(&o->DhcpSubnetMask, 255, 255, 255, 0);\r
1277         o->DhcpExpireTimeSpan = 7200;\r
1278         o->SaveLog = true;\r
1279 \r
1280         SetIP(&o->DhcpGatewayAddress, 192, 168, 30, 1);\r
1281         SetIP(&o->DhcpDnsServerAddress, 192, 168, 30, 1);\r
1282 \r
1283         GetDomainName(o->DhcpDomainName, sizeof(o->DhcpDomainName));\r
1284 }\r
1285 \r
1286 // NAT の設定を初期状態にする\r
1287 void NiInitDefaultConfig(NAT *n)\r
1288 {\r
1289         // 引数チェック\r
1290         if (n == NULL)\r
1291         {\r
1292                 return;\r
1293         }\r
1294 \r
1295         // 仮想ホストオプション初期化\r
1296         NiSetDefaultVhOption(n, &n->Option);\r
1297 \r
1298         // 管理用ポート初期化\r
1299         n->AdminPort = DEFAULT_NAT_ADMIN_PORT;\r
1300 \r
1301         // オフライン\r
1302         n->Online = false;\r
1303 \r
1304         // ログを保存\r
1305         n->Option.SaveLog = true;\r
1306 }\r
1307 \r
1308 // NAT の設定の初期化\r
1309 void NiInitConfig(NAT *n)\r
1310 {\r
1311         // 引数チェック\r
1312         if (n == NULL)\r
1313         {\r
1314                 return;\r
1315         }\r
1316 \r
1317         // 初期状態\r
1318         NiInitDefaultConfig(n);\r
1319 }\r
1320 \r
1321 // 仮想ホストオプションの読み込み (拡張)\r
1322 void NiLoadVhOptionEx(VH_OPTION *o, FOLDER *root)\r
1323 {\r
1324         FOLDER *host, *nat, *dhcp;\r
1325         char mac_address[MAX_SIZE];\r
1326         // 引数チェック\r
1327         if (o == NULL || root == NULL)\r
1328         {\r
1329                 return;\r
1330         }\r
1331 \r
1332         host = CfgGetFolder(root, "VirtualHost");\r
1333         nat = CfgGetFolder(root, "VirtualRouter");\r
1334         dhcp = CfgGetFolder(root, "VirtualDhcpServer");\r
1335 \r
1336         Zero(o, sizeof(VH_OPTION));\r
1337 \r
1338         GenMacAddress(o->MacAddress);\r
1339         if (CfgGetStr(host, "VirtualHostMacAddress", mac_address, sizeof(mac_address)))\r
1340         {\r
1341                 BUF *b = StrToBin(mac_address);\r
1342                 if (b != NULL)\r
1343                 {\r
1344                         if (b->Size == 6)\r
1345                         {\r
1346                                 Copy(o->MacAddress, b->Buf, 6);\r
1347                         }\r
1348                 }\r
1349                 FreeBuf(b);\r
1350         }\r
1351         CfgGetIp(host, "VirtualHostIp", &o->Ip);\r
1352         CfgGetIp(host, "VirtualHostIpSubnetMask", &o->Mask);\r
1353 \r
1354         o->UseNat = CfgGetBool(nat, "NatEnabled");\r
1355         o->Mtu = CfgGetInt(nat, "NatMtu");\r
1356         o->NatTcpTimeout = CfgGetInt(nat, "NatTcpTimeout");\r
1357         o->NatUdpTimeout = CfgGetInt(nat, "NatUdpTimeout");\r
1358 \r
1359         o->UseDhcp = CfgGetBool(dhcp, "DhcpEnabled");\r
1360         CfgGetIp(dhcp, "DhcpLeaseIPStart", &o->DhcpLeaseIPStart);\r
1361         CfgGetIp(dhcp, "DhcpLeaseIPEnd", &o->DhcpLeaseIPEnd);\r
1362         CfgGetIp(dhcp, "DhcpSubnetMask", &o->DhcpSubnetMask);\r
1363         o->DhcpExpireTimeSpan = CfgGetInt(dhcp, "DhcpExpireTimeSpan");\r
1364         CfgGetIp(dhcp, "DhcpGatewayAddress", &o->DhcpGatewayAddress);\r
1365         CfgGetIp(dhcp, "DhcpDnsServerAddress", &o->DhcpDnsServerAddress);\r
1366         CfgGetStr(dhcp, "DhcpDomainName", o->DhcpDomainName, sizeof(o->DhcpDomainName));\r
1367 \r
1368         Trim(o->DhcpDomainName);\r
1369         if (StrLen(o->DhcpDomainName) == 0)\r
1370         {\r
1371                 //GetDomainName(o->DhcpDomainName, sizeof(o->DhcpDomainName));\r
1372         }\r
1373 \r
1374         o->SaveLog = CfgGetBool(root, "SaveLog");\r
1375 }\r
1376 \r
1377 // 仮想ホストオプションの読み込み\r
1378 void NiLoadVhOption(NAT *n, FOLDER *root)\r
1379 {\r
1380         VH_OPTION *o;\r
1381         FOLDER *host, *nat, *dhcp;\r
1382         char mac_address[MAX_SIZE];\r
1383         // 引数チェック\r
1384         if (n == NULL || root == NULL)\r
1385         {\r
1386                 return;\r
1387         }\r
1388 \r
1389         host = CfgGetFolder(root, "VirtualHost");\r
1390         nat = CfgGetFolder(root, "VirtualRouter");\r
1391         dhcp = CfgGetFolder(root, "VirtualDhcpServer");\r
1392 \r
1393         o = &n->Option;\r
1394         Zero(o, sizeof(VH_OPTION));\r
1395 \r
1396         GenMacAddress(o->MacAddress);\r
1397         if (CfgGetStr(host, "VirtualHostMacAddress", mac_address, sizeof(mac_address)))\r
1398         {\r
1399                 BUF *b = StrToBin(mac_address);\r
1400                 if (b != NULL)\r
1401                 {\r
1402                         if (b->Size == 6)\r
1403                         {\r
1404                                 Copy(o->MacAddress, b->Buf, 6);\r
1405                         }\r
1406                 }\r
1407                 FreeBuf(b);\r
1408         }\r
1409         CfgGetIp(host, "VirtualHostIp", &o->Ip);\r
1410         CfgGetIp(host, "VirtualHostIpSubnetMask", &o->Mask);\r
1411 \r
1412         o->UseNat = CfgGetBool(nat, "NatEnabled");\r
1413         o->Mtu = CfgGetInt(nat, "NatMtu");\r
1414         o->NatTcpTimeout = CfgGetInt(nat, "NatTcpTimeout");\r
1415         o->NatUdpTimeout = CfgGetInt(nat, "NatUdpTimeout");\r
1416 \r
1417         o->UseDhcp = CfgGetBool(dhcp, "DhcpEnabled");\r
1418         CfgGetIp(dhcp, "DhcpLeaseIPStart", &o->DhcpLeaseIPStart);\r
1419         CfgGetIp(dhcp, "DhcpLeaseIPEnd", &o->DhcpLeaseIPEnd);\r
1420         CfgGetIp(dhcp, "DhcpSubnetMask", &o->DhcpSubnetMask);\r
1421         o->DhcpExpireTimeSpan = CfgGetInt(dhcp, "DhcpExpireTimeSpan");\r
1422         CfgGetIp(dhcp, "DhcpGatewayAddress", &o->DhcpGatewayAddress);\r
1423         CfgGetIp(dhcp, "DhcpDnsServerAddress", &o->DhcpDnsServerAddress);\r
1424         CfgGetStr(dhcp, "DhcpDomainName", o->DhcpDomainName, sizeof(o->DhcpDomainName));\r
1425 \r
1426         o->SaveLog = CfgGetBool(root, "SaveLog");\r
1427 }\r
1428 \r
1429 // VPN サーバーからの接続オプションの読み込み\r
1430 void NiLoadClientData(NAT *n, FOLDER *root)\r
1431 {\r
1432         FOLDER *co, *ca;\r
1433         // 引数チェック\r
1434         if (n == NULL || root == NULL)\r
1435         {\r
1436                 return;\r
1437         }\r
1438 \r
1439         co = CfgGetFolder(root, "VpnClientOption");\r
1440         ca = CfgGetFolder(root, "VpnClientAuth");\r
1441         if (co == NULL || ca == NULL)\r
1442         {\r
1443                 return;\r
1444         }\r
1445 \r
1446         n->ClientOption = CiLoadClientOption(co);\r
1447         n->ClientAuth = CiLoadClientAuth(ca);\r
1448 }\r
1449 \r
1450 // VPN サーバーへの接続オプションの書き込み\r
1451 void NiWriteClientData(NAT *n, FOLDER *root)\r
1452 {\r
1453         // 引数チェック\r
1454         if (n == NULL || root == NULL || n->ClientOption == NULL || n->ClientAuth == NULL)\r
1455         {\r
1456                 return;\r
1457         }\r
1458 \r
1459         CiWriteClientOption(CfgCreateFolder(root, "VpnClientOption"), n->ClientOption);\r
1460         CiWriteClientAuth(CfgCreateFolder(root, "VpnClientAuth"), n->ClientAuth);\r
1461 }\r
1462 \r
1463 // 仮想ホストオプションの書き込み (拡張)\r
1464 void NiWriteVhOptionEx(VH_OPTION *o, FOLDER *root)\r
1465 {\r
1466         FOLDER *host, *nat, *dhcp;\r
1467         char mac_address[MAX_SIZE];\r
1468         // 引数チェック\r
1469         if (o == NULL || root == NULL)\r
1470         {\r
1471                 return;\r
1472         }\r
1473 \r
1474         host = CfgCreateFolder(root, "VirtualHost");\r
1475         nat = CfgCreateFolder(root, "VirtualRouter");\r
1476         dhcp = CfgCreateFolder(root, "VirtualDhcpServer");\r
1477 \r
1478         MacToStr(mac_address, sizeof(mac_address), o->MacAddress);\r
1479         CfgAddStr(host, "VirtualHostMacAddress", mac_address);\r
1480         CfgAddIp(host, "VirtualHostIp", &o->Ip);\r
1481         CfgAddIp(host, "VirtualHostIpSubnetMask", &o->Mask);\r
1482 \r
1483         CfgAddBool(nat, "NatEnabled", o->UseNat);\r
1484         CfgAddInt(nat, "NatMtu", o->Mtu);\r
1485         CfgAddInt(nat, "NatTcpTimeout", o->NatTcpTimeout);\r
1486         CfgAddInt(nat, "NatUdpTimeout", o->NatUdpTimeout);\r
1487 \r
1488         CfgAddBool(dhcp, "DhcpEnabled", o->UseDhcp);\r
1489         CfgAddIp(dhcp, "DhcpLeaseIPStart", &o->DhcpLeaseIPStart);\r
1490         CfgAddIp(dhcp, "DhcpLeaseIPEnd", &o->DhcpLeaseIPEnd);\r
1491         CfgAddIp(dhcp, "DhcpSubnetMask", &o->DhcpSubnetMask);\r
1492         CfgAddInt(dhcp, "DhcpExpireTimeSpan", o->DhcpExpireTimeSpan);\r
1493         CfgAddIp(dhcp, "DhcpGatewayAddress", &o->DhcpGatewayAddress);\r
1494         CfgAddIp(dhcp, "DhcpDnsServerAddress", &o->DhcpDnsServerAddress);\r
1495         CfgAddStr(dhcp, "DhcpDomainName", o->DhcpDomainName);\r
1496 \r
1497         CfgAddBool(root, "SaveLog", o->SaveLog);\r
1498 }\r
1499 \r
1500 // 仮想ホストオプションの書き込み\r
1501 void NiWriteVhOption(NAT *n, FOLDER *root)\r
1502 {\r
1503         VH_OPTION *o;\r
1504         FOLDER *host, *nat, *dhcp;\r
1505         char mac_address[MAX_SIZE];\r
1506         // 引数チェック\r
1507         if (n == NULL || root == NULL)\r
1508         {\r
1509                 return;\r
1510         }\r
1511 \r
1512         host = CfgCreateFolder(root, "VirtualHost");\r
1513         nat = CfgCreateFolder(root, "VirtualRouter");\r
1514         dhcp = CfgCreateFolder(root, "VirtualDhcpServer");\r
1515 \r
1516         o = &n->Option;\r
1517 \r
1518         MacToStr(mac_address, sizeof(mac_address), o->MacAddress);\r
1519         CfgAddStr(host, "VirtualHostMacAddress", mac_address);\r
1520         CfgAddIp(host, "VirtualHostIp", &o->Ip);\r
1521         CfgAddIp(host, "VirtualHostIpSubnetMask", &o->Mask);\r
1522 \r
1523         CfgAddBool(nat, "NatEnabled", o->UseNat);\r
1524         CfgAddInt(nat, "NatMtu", o->Mtu);\r
1525         CfgAddInt(nat, "NatTcpTimeout", o->NatTcpTimeout);\r
1526         CfgAddInt(nat, "NatUdpTimeout", o->NatUdpTimeout);\r
1527 \r
1528         CfgAddBool(dhcp, "DhcpEnabled", o->UseDhcp);\r
1529         CfgAddIp(dhcp, "DhcpLeaseIPStart", &o->DhcpLeaseIPStart);\r
1530         CfgAddIp(dhcp, "DhcpLeaseIPEnd", &o->DhcpLeaseIPEnd);\r
1531         CfgAddIp(dhcp, "DhcpSubnetMask", &o->DhcpSubnetMask);\r
1532         CfgAddInt(dhcp, "DhcpExpireTimeSpan", o->DhcpExpireTimeSpan);\r
1533         CfgAddIp(dhcp, "DhcpGatewayAddress", &o->DhcpGatewayAddress);\r
1534         CfgAddIp(dhcp, "DhcpDnsServerAddress", &o->DhcpDnsServerAddress);\r
1535         CfgAddStr(dhcp, "DhcpDomainName", o->DhcpDomainName);\r
1536 \r
1537         CfgAddBool(root, "SaveLog", o->SaveLog);\r
1538 }\r
1539 \r
1540 // 設定ファイルを読み込む\r
1541 bool NiLoadConfig(NAT *n, FOLDER *root)\r
1542 {\r
1543         FOLDER *host;\r
1544         BUF *b;\r
1545         // 引数チェック\r
1546         if (n == NULL || root == NULL)\r
1547         {\r
1548                 return false;\r
1549         }\r
1550 \r
1551         host = CfgGetFolder(root, "VirtualHost");\r
1552         if (host == NULL)\r
1553         {\r
1554                 return false;\r
1555         }\r
1556 \r
1557         CfgGetByte(root, "HashedPassword", n->HashedPassword, sizeof(n->HashedPassword));\r
1558         n->AdminPort = CfgGetInt(root, "AdminPort");\r
1559         n->Online = CfgGetBool(root, "Online");\r
1560 \r
1561         b = CfgGetBuf(root, "AdminCert");\r
1562         if (b != NULL)\r
1563         {\r
1564                 n->AdminX = BufToX(b, false);\r
1565                 FreeBuf(b);\r
1566         }\r
1567 \r
1568         b = CfgGetBuf(root, "AdminKey");\r
1569         if (b != NULL)\r
1570         {\r
1571                 n->AdminK = BufToK(b, true, false, NULL);\r
1572                 FreeBuf(b);\r
1573         }\r
1574 \r
1575         NiLoadVhOption(n, root);\r
1576 \r
1577         NiLoadClientData(n, root);\r
1578 \r
1579         return true;\r
1580 }\r
1581 \r
1582 // 設定をファイルに書き込む\r
1583 void NiWriteConfig(NAT *n)\r
1584 {\r
1585         // 引数チェック\r
1586         if (n == NULL)\r
1587         {\r
1588                 return;\r
1589         }\r
1590 \r
1591         Lock(n->lock);\r
1592         {\r
1593                 FOLDER *root = CfgCreateFolder(NULL, TAG_ROOT);\r
1594                 BUF *b;\r
1595 \r
1596                 // 証明書\r
1597                 b = XToBuf(n->AdminX, false);\r
1598                 CfgAddBuf(root, "AdminCert", b);\r
1599                 FreeBuf(b);\r
1600 \r
1601                 // 秘密鍵\r
1602                 b = KToBuf(n->AdminK, false, NULL);\r
1603                 CfgAddBuf(root, "AdminKey", b);\r
1604                 FreeBuf(b);\r
1605 \r
1606                 // パスワード\r
1607                 CfgAddByte(root, "HashedPassword", n->HashedPassword, sizeof(n->HashedPassword));\r
1608                 CfgAddInt(root, "AdminPort", n->AdminPort);\r
1609                 CfgAddBool(root, "Online", n->Online);\r
1610 \r
1611                 // 仮想ホストオプション\r
1612                 NiWriteVhOption(n, root);\r
1613 \r
1614                 // 接続オプション\r
1615                 if (n->ClientOption != NULL && n->ClientAuth != NULL)\r
1616                 {\r
1617                         NiWriteClientData(n, root);\r
1618                 }\r
1619 \r
1620                 SaveCfgRw(n->CfgRw, root);\r
1621                 CfgDeleteFolder(root);\r
1622         }\r
1623         Unlock(n->lock);\r
1624 }\r
1625 \r
1626 // NAT の設定の解放\r
1627 void NiFreeConfig(NAT *n)\r
1628 {\r
1629         // 引数チェック\r
1630         if (n == NULL)\r
1631         {\r
1632                 return;\r
1633         }\r
1634 \r
1635         // 最新の設定の書き込み\r
1636         NiWriteConfig(n);\r
1637 \r
1638         // 設定 R/W の解放\r
1639         FreeCfgRw(n->CfgRw);\r
1640         n->CfgRw = NULL;\r
1641 \r
1642         Free(n->ClientOption);\r
1643         CiFreeClientAuth(n->ClientAuth);\r
1644 \r
1645         FreeX(n->AdminX);\r
1646         FreeK(n->AdminK);\r
1647 }\r
1648 \r
1649 // NAT の作成\r
1650 NAT *NiNewNatEx(SNAT *snat, VH_OPTION *o)\r
1651 {\r
1652         NAT *n = ZeroMalloc(sizeof(NAT));\r
1653 \r
1654         n->lock = NewLock();\r
1655         Hash(n->HashedPassword, "", 0, true);\r
1656         n->HaltEvent = NewEvent();\r
1657 \r
1658         //n->Cedar = NewCedar(NULL, NULL);\r
1659 \r
1660         n->SecureNAT = snat;\r
1661 \r
1662         // 優先順位を上げる\r
1663         //OSSetHighPriority();\r
1664 \r
1665         // 設定の初期化\r
1666         NiInitConfig(n);\r
1667 \r
1668 #if     0\r
1669         // 仮想ホストの動作を開始\r
1670         if (n->Online && n->ClientOption != NULL)\r
1671         {\r
1672                 n->Virtual = NewVirtualHostEx(n->Cedar, n->ClientOption, n->ClientAuth, &n->Option, n);\r
1673         }\r
1674         else\r
1675         {\r
1676                 n->Online = false;\r
1677                 n->Virtual = NULL;\r
1678         }\r
1679 #else\r
1680         n->Virtual = NewVirtualHostEx(n->Cedar, NULL, NULL, o, n);\r
1681         n->Online = true;\r
1682 #endif\r
1683 \r
1684         // 管理コマンド開始\r
1685         //NiInitAdminAccept(n);\r
1686 \r
1687         return n;\r
1688 }\r
1689 NAT *NiNewNat()\r
1690 {\r
1691         return NiNewNatEx(NULL, NULL);\r
1692 }\r
1693 \r
1694 // NAT の解放\r
1695 void NiFreeNat(NAT *n)\r
1696 {\r
1697         // 引数チェック\r
1698         if (n == NULL)\r
1699         {\r
1700                 return;\r
1701         }\r
1702 \r
1703         // 管理コマンド終了\r
1704         //NiFreeAdminAccept(n);\r
1705 \r
1706         // 仮想ホストが動作中の場合は停止\r
1707         Lock(n->lock);\r
1708         {\r
1709                 if (n->Virtual != NULL)\r
1710                 {\r
1711                         StopVirtualHost(n->Virtual);\r
1712                         ReleaseVirtual(n->Virtual);\r
1713                         n->Virtual = NULL;\r
1714                 }\r
1715         }\r
1716         Unlock(n->lock);\r
1717 \r
1718         // 設定の解放\r
1719         NiFreeConfig(n);\r
1720 \r
1721         // オブジェクトの削除\r
1722         ReleaseCedar(n->Cedar);\r
1723         ReleaseEvent(n->HaltEvent);\r
1724         DeleteLock(n->lock);\r
1725 \r
1726         Free(n);\r
1727 }\r
1728 \r
1729 // NAT の停止\r
1730 void NtStopNat()\r
1731 {\r
1732         Lock(nat_lock);\r
1733         {\r
1734                 if (nat != NULL)\r
1735                 {\r
1736                         NiFreeNat(nat);\r
1737                         nat = NULL;\r
1738                 }\r
1739         }\r
1740         Unlock(nat_lock);\r
1741 }\r
1742 \r
1743 // NAT の開始\r
1744 void NtStartNat()\r
1745 {\r
1746         Lock(nat_lock);\r
1747         {\r
1748                 if (nat == NULL)\r
1749                 {\r
1750                         nat = NiNewNat();\r
1751                 }\r
1752         }\r
1753         Unlock(nat_lock);\r
1754 }\r
1755 \r
1756 // NtXxx 関数の初期化\r
1757 void NtInit()\r
1758 {\r
1759         if (nat_lock != NULL)\r
1760         {\r
1761                 return;\r
1762         }\r
1763 \r
1764         nat_lock = NewLock();\r
1765 }\r
1766 \r
1767 // NtXxx 関数の解放\r
1768 void NtFree()\r
1769 {\r
1770         if (nat_lock == NULL)\r
1771         {\r
1772                 return;\r
1773         }\r
1774 \r
1775         DeleteLock(nat_lock);\r
1776         nat_lock = NULL;\r
1777 }\r
1778 \r