source: lab.git/Dev/utvpn/utvpn-unix-v101-7101-public/src/Cedar/Nat.c @ 0dcad9a

trunk
Last change on this file since 0dcad9a was a1bae3e, checked in by mitty <mitty@…>, 12 years ago
  • copy vendor drop to trunk

git-svn-id: https://lab.mitty.jp/svn/lab/trunk@147 7d2118f6-f56c-43e7-95a2-4bb3031d96e7

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