PageRenderTime 32ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/src/Cedar/Nat.c

https://gitlab.com/benjdag/SoftEtherVPN
C | 1922 lines | 1387 code | 284 blank | 251 comment | 293 complexity | 9ce5db2df04db4a06858fd9e14cbbead MD5 | raw file
  1. // SoftEther VPN Source Code
  2. // Cedar Communication Module
  3. //
  4. // SoftEther VPN Server, Client and Bridge are free software under GPLv2.
  5. //
  6. // Copyright (c) 2012-2016 Daiyuu Nobori.
  7. // Copyright (c) 2012-2016 SoftEther VPN Project, University of Tsukuba, Japan.
  8. // Copyright (c) 2012-2016 SoftEther Corporation.
  9. //
  10. // All Rights Reserved.
  11. //
  12. // http://www.softether.org/
  13. //
  14. // Author: Daiyuu Nobori
  15. // Comments: Tetsuo Sugiyama, Ph.D.
  16. //
  17. // This program is free software; you can redistribute it and/or
  18. // modify it under the terms of the GNU General Public License
  19. // version 2 as published by the Free Software Foundation.
  20. //
  21. // This program is distributed in the hope that it will be useful,
  22. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. // GNU General Public License for more details.
  25. //
  26. // You should have received a copy of the GNU General Public License version 2
  27. // along with this program; if not, write to the Free Software
  28. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  29. //
  30. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  31. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  32. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  33. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  34. // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  35. // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  36. // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  37. //
  38. // THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
  39. // AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
  40. //
  41. //
  42. // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
  43. // UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
  44. // MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
  45. // SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
  46. // SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
  47. // CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
  48. // DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
  49. // MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
  50. // SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
  51. // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
  52. // EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
  53. // JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
  54. // AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
  55. // THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
  56. //
  57. // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS
  58. // YOU HAVE A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY
  59. // CRIMINAL LAWS OR CIVIL RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS
  60. // SOFTWARE IN OTHER COUNTRIES IS COMPLETELY AT YOUR OWN RISK. THE
  61. // SOFTETHER VPN PROJECT HAS DEVELOPED AND DISTRIBUTED THIS SOFTWARE TO
  62. // COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING CIVIL RIGHTS INCLUDING
  63. // PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER COUNTRIES' LAWS OR
  64. // CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES. WE HAVE
  65. // NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
  66. // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+
  67. // COUNTRIES AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE
  68. // WORLD, WITH DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY
  69. // COUNTRIES' LAWS, REGULATIONS AND CIVIL RIGHTS TO MAKE THE SOFTWARE
  70. // COMPLY WITH ALL COUNTRIES' LAWS BY THE PROJECT. EVEN IF YOU WILL BE
  71. // SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A PUBLIC SERVANT IN YOUR
  72. // COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE LIABLE TO
  73. // RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
  74. // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT
  75. // JUST A STATEMENT FOR WARNING AND DISCLAIMER.
  76. //
  77. //
  78. // SOURCE CODE CONTRIBUTION
  79. // ------------------------
  80. //
  81. // Your contribution to SoftEther VPN Project is much appreciated.
  82. // Please send patches to us through GitHub.
  83. // Read the SoftEther VPN Patch Acceptance Policy in advance:
  84. // http://www.softether.org/5-download/src/9.patch
  85. //
  86. //
  87. // DEAR SECURITY EXPERTS
  88. // ---------------------
  89. //
  90. // If you find a bug or a security vulnerability please kindly inform us
  91. // about the problem immediately so that we can fix the security problem
  92. // to protect a lot of users around the world as soon as possible.
  93. //
  94. // Our e-mail address for security reports is:
  95. // softether-vpn-security [at] softether.org
  96. //
  97. // Please note that the above e-mail address is not a technical support
  98. // inquiry address. If you need technical assistance, please visit
  99. // http://www.softether.org/ and ask your question on the users forum.
  100. //
  101. // Thank you for your cooperation.
  102. //
  103. //
  104. // NO MEMORY OR RESOURCE LEAKS
  105. // ---------------------------
  106. //
  107. // The memory-leaks and resource-leaks verification under the stress
  108. // test has been passed before release this source code.
  109. // Nat.c
  110. // User-mode Router
  111. #include "CedarPch.h"
  112. static LOCK *nat_lock = NULL;
  113. static NAT *nat = NULL;
  114. // Disconnect the connection for the NAT administrator
  115. void NatAdminDisconnect(RPC *r)
  116. {
  117. // Validate arguments
  118. if (r == NULL)
  119. {
  120. return;
  121. }
  122. EndRpc(r);
  123. }
  124. // Connection for NAT administrator
  125. RPC *NatAdminConnect(CEDAR *cedar, char *hostname, UINT port, void *hashed_password, UINT *err)
  126. {
  127. UCHAR secure_password[SHA1_SIZE];
  128. UCHAR random[SHA1_SIZE];
  129. SOCK *sock;
  130. RPC *rpc;
  131. PACK *p;
  132. UINT error;
  133. // Validate arguments
  134. if (cedar == NULL || hostname == NULL || port == 0 || hashed_password == NULL || err == NULL)
  135. {
  136. if (err != NULL)
  137. {
  138. *err = ERR_INTERNAL_ERROR;
  139. }
  140. return NULL;
  141. }
  142. // Connection
  143. sock = Connect(hostname, port);
  144. if (sock == NULL)
  145. {
  146. *err = ERR_CONNECT_FAILED;
  147. return NULL;
  148. }
  149. if (StartSSL(sock, NULL, NULL) == false)
  150. {
  151. *err = ERR_PROTOCOL_ERROR;
  152. ReleaseSock(sock);
  153. return NULL;
  154. }
  155. SetTimeout(sock, 5000);
  156. p = HttpClientRecv(sock);
  157. if (p == NULL)
  158. {
  159. *err = ERR_DISCONNECTED;
  160. ReleaseSock(sock);
  161. return NULL;
  162. }
  163. if (PackGetData2(p, "auth_random", random, SHA1_SIZE) == false)
  164. {
  165. FreePack(p);
  166. *err = ERR_PROTOCOL_ERROR;
  167. ReleaseSock(sock);
  168. return NULL;
  169. }
  170. FreePack(p);
  171. SecurePassword(secure_password, hashed_password, random);
  172. p = NewPack();
  173. PackAddData(p, "secure_password", secure_password, SHA1_SIZE);
  174. if (HttpClientSend(sock, p) == false)
  175. {
  176. FreePack(p);
  177. *err = ERR_DISCONNECTED;
  178. ReleaseSock(sock);
  179. return NULL;
  180. }
  181. FreePack(p);
  182. p = HttpClientRecv(sock);
  183. if (p == NULL)
  184. {
  185. *err = ERR_DISCONNECTED;
  186. ReleaseSock(sock);
  187. return NULL;
  188. }
  189. error = GetErrorFromPack(p);
  190. FreePack(p);
  191. if (error != ERR_NO_ERROR)
  192. {
  193. *err = error;
  194. ReleaseSock(sock);
  195. return NULL;
  196. }
  197. SetTimeout(sock, TIMEOUT_INFINITE);
  198. rpc = StartRpcClient(sock, NULL);
  199. ReleaseSock(sock);
  200. return rpc;
  201. }
  202. // RPC functional related macro
  203. #define DECLARE_RPC_EX(rpc_name, data_type, function, in_rpc, out_rpc, free_rpc) \
  204. else if (StrCmpi(name, rpc_name) == 0) \
  205. { \
  206. data_type t; \
  207. Zero(&t, sizeof(t)); \
  208. in_rpc(&t, p); \
  209. err = function(n, &t); \
  210. if (err == ERR_NO_ERROR) \
  211. { \
  212. out_rpc(ret, &t); \
  213. } \
  214. free_rpc(&t); \
  215. ok = true; \
  216. }
  217. #define DECLARE_RPC(rpc_name, data_type, function, in_rpc, out_rpc) \
  218. else if (StrCmpi(name, rpc_name) == 0) \
  219. { \
  220. data_type t; \
  221. Zero(&t, sizeof(t)); \
  222. in_rpc(&t, p); \
  223. err = function(n, &t); \
  224. if (err == ERR_NO_ERROR) \
  225. { \
  226. out_rpc(ret, &t); \
  227. } \
  228. ok = true; \
  229. }
  230. #define DECLARE_SC_EX(rpc_name, data_type, function, in_rpc, out_rpc, free_rpc) \
  231. UINT function(RPC *r, data_type *t) \
  232. { \
  233. PACK *p, *ret; \
  234. UINT err; \
  235. if (r == NULL || t == NULL) \
  236. { \
  237. return ERR_INTERNAL_ERROR; \
  238. } \
  239. p = NewPack(); \
  240. out_rpc(p, t); \
  241. free_rpc(t); \
  242. Zero(t, sizeof(data_type)); \
  243. ret = AdminCall(r, rpc_name, p); \
  244. err = GetErrorFromPack(ret); \
  245. if (err == ERR_NO_ERROR) \
  246. { \
  247. in_rpc(t, ret); \
  248. } \
  249. FreePack(ret); \
  250. return err; \
  251. }
  252. #define DECLARE_SC(rpc_name, data_type, function, in_rpc, out_rpc) \
  253. UINT function(RPC *r, data_type *t) \
  254. { \
  255. PACK *p, *ret; \
  256. UINT err; \
  257. if (r == NULL || t == NULL) \
  258. { \
  259. return ERR_INTERNAL_ERROR; \
  260. } \
  261. p = NewPack(); \
  262. out_rpc(p, t); \
  263. ret = AdminCall(r, rpc_name, p); \
  264. err = GetErrorFromPack(ret); \
  265. if (err == ERR_NO_ERROR) \
  266. { \
  267. in_rpc(t, ret); \
  268. } \
  269. FreePack(ret); \
  270. return err; \
  271. }
  272. // RPC server function
  273. PACK *NiRpcServer(RPC *r, char *name, PACK *p)
  274. {
  275. NAT *n = (NAT *)r->Param;
  276. PACK *ret;
  277. UINT err;
  278. bool ok;
  279. // Validate arguments
  280. if (r == NULL || name == NULL || p == NULL)
  281. {
  282. return NULL;
  283. }
  284. ret = NewPack();
  285. err = ERR_NO_ERROR;
  286. ok = false;
  287. if (0) {}
  288. // RPC function definition: From here
  289. // DECLARE_RPC("Online", RPC_DUMMY, NtOnline, InRpcDummy, OutRpcDummy)
  290. // DECLARE_RPC("Offline", RPC_DUMMY, NtOffline, InRpcDummy, OutRpcDummy)
  291. DECLARE_RPC("SetHostOption", VH_OPTION, NtSetHostOption, InVhOption, OutVhOption)
  292. DECLARE_RPC("GetHostOption", VH_OPTION, NtGetHostOption, InVhOption, OutVhOption)
  293. // DECLARE_RPC_EX("SetClientConfig", RPC_CREATE_LINK, NtSetClientConfig, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)
  294. // DECLARE_RPC_EX("GetClientConfig", RPC_CREATE_LINK, NtGetClientConfig, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)
  295. DECLARE_RPC_EX("GetStatus", RPC_NAT_STATUS, NtGetStatus, InRpcNatStatus, OutRpcNatStatus, FreeRpcNatStatus)
  296. // DECLARE_RPC_EX("GetInfo", RPC_NAT_INFO, NtGetInfo, InRpcNatInfo, OutRpcNatInfo, FreeRpcNatInfo)
  297. DECLARE_RPC_EX("EnumNatList", RPC_ENUM_NAT, NtEnumNatList, InRpcEnumNat, OutRpcEnumNat, FreeRpcEnumNat)
  298. DECLARE_RPC_EX("EnumDhcpList", RPC_ENUM_DHCP, NtEnumDhcpList, InRpcEnumDhcp, OutRpcEnumDhcp, FreeRpcEnumDhcp)
  299. // DECLARE_RPC("SetPassword", RPC_SET_PASSWORD, NtSetPassword, InRpcSetPassword, OutRpcSetPassword)
  300. // RPC function definition: To here
  301. if (ok == false)
  302. {
  303. err = ERR_NOT_SUPPORTED;
  304. }
  305. PackAddInt(ret, "error", err);
  306. return ret;
  307. }
  308. // RPC call definition: From here
  309. DECLARE_SC("Online", RPC_DUMMY, NcOnline, InRpcDummy, OutRpcDummy)
  310. DECLARE_SC("Offline", RPC_DUMMY, NcOffline, InRpcDummy, OutRpcDummy)
  311. DECLARE_SC("SetHostOption", VH_OPTION, NcSetHostOption, InVhOption, OutVhOption)
  312. DECLARE_SC("GetHostOption", VH_OPTION, NcGetHostOption, InVhOption, OutVhOption)
  313. DECLARE_SC_EX("SetClientConfig", RPC_CREATE_LINK, NcSetClientConfig, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)
  314. DECLARE_SC_EX("GetClientConfig", RPC_CREATE_LINK, NcGetClientConfig, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)
  315. DECLARE_SC_EX("GetStatus", RPC_NAT_STATUS, NcGetStatus, InRpcNatStatus, OutRpcNatStatus, FreeRpcNatStatus)
  316. DECLARE_SC_EX("GetInfo", RPC_NAT_INFO, NcGetInfo, InRpcNatInfo, OutRpcNatInfo, FreeRpcNatInfo)
  317. DECLARE_SC_EX("EnumNatList", RPC_ENUM_NAT, NcEnumNatList, InRpcEnumNat, OutRpcEnumNat, FreeRpcEnumNat)
  318. DECLARE_SC_EX("EnumDhcpList", RPC_ENUM_DHCP, NcEnumDhcpList, InRpcEnumDhcp, OutRpcEnumDhcp, FreeRpcEnumDhcp)
  319. DECLARE_SC("SetPassword", RPC_SET_PASSWORD, NcSetPassword, InRpcSetPassword, OutRpcSetPassword)
  320. // RPC call definition: To here
  321. // Set a password
  322. UINT NtSetPassword(NAT *n, RPC_SET_PASSWORD *t)
  323. {
  324. Copy(n->HashedPassword, t->HashedPassword, SHA1_SIZE);
  325. NiWriteConfig(n);
  326. return ERR_NO_ERROR;
  327. }
  328. // Online
  329. UINT NtOnline(NAT *n, RPC_DUMMY *t)
  330. {
  331. UINT ret = ERR_NO_ERROR;
  332. Lock(n->lock);
  333. {
  334. if (n->Online)
  335. {
  336. // It is already online
  337. ret = ERR_ALREADY_ONLINE;
  338. }
  339. else
  340. {
  341. if (n->ClientOption == NULL || n->ClientAuth == NULL)
  342. {
  343. // Setting is not yet done
  344. ret = ERR_ACCOUNT_NOT_PRESENT;
  345. }
  346. else
  347. {
  348. // OK
  349. n->Online = true;
  350. // Start connection
  351. n->Virtual = NewVirtualHostEx(n->Cedar, n->ClientOption, n->ClientAuth,
  352. &n->Option, n);
  353. }
  354. }
  355. }
  356. Unlock(n->lock);
  357. NiWriteConfig(n);
  358. return ret;
  359. }
  360. // Offline
  361. UINT NtOffline(NAT *n, RPC_DUMMY *t)
  362. {
  363. UINT ret = ERR_NO_ERROR;
  364. Lock(n->lock);
  365. {
  366. if (n->Online == false)
  367. {
  368. // It is offline
  369. ret = ERR_OFFLINE;
  370. }
  371. else
  372. {
  373. // Offline
  374. StopVirtualHost(n->Virtual);
  375. ReleaseVirtual(n->Virtual);
  376. n->Virtual = NULL;
  377. n->Online = false;
  378. }
  379. }
  380. Unlock(n->lock);
  381. NiWriteConfig(n);
  382. return ret;
  383. }
  384. // Set host options
  385. UINT NtSetHostOption(NAT *n, VH_OPTION *t)
  386. {
  387. UINT ret = ERR_NO_ERROR;
  388. Lock(n->lock);
  389. {
  390. Copy(&n->Option, t, sizeof(VH_OPTION));
  391. }
  392. Unlock(n->lock);
  393. SetVirtualHostOption(n->Virtual, t);
  394. NiWriteConfig(n);
  395. return ret;
  396. }
  397. // Get host options
  398. UINT NtGetHostOption(NAT *n, VH_OPTION *t)
  399. {
  400. UINT ret = ERR_NO_ERROR;
  401. Lock(n->lock);
  402. {
  403. Copy(t, &n->Option, sizeof(VH_OPTION));
  404. }
  405. Unlock(n->lock);
  406. return ret;
  407. }
  408. // Set the connection settings
  409. UINT NtSetClientConfig(NAT *n, RPC_CREATE_LINK *t)
  410. {
  411. Lock(n->lock);
  412. {
  413. if (n->ClientOption != NULL || n->ClientAuth != NULL)
  414. {
  415. Free(n->ClientOption);
  416. CiFreeClientAuth(n->ClientAuth);
  417. }
  418. n->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
  419. Copy(n->ClientOption, t->ClientOption, sizeof(CLIENT_OPTION));
  420. n->ClientAuth = CopyClientAuth(t->ClientAuth);
  421. }
  422. Unlock(n->lock);
  423. NiWriteConfig(n);
  424. if (n->Online)
  425. {
  426. NtOffline(n, NULL);
  427. NtOnline(n, NULL);
  428. }
  429. return ERR_NO_ERROR;
  430. }
  431. // Get the connection settings
  432. UINT NtGetClientConfig(NAT *n, RPC_CREATE_LINK *t)
  433. {
  434. UINT err = ERR_NO_ERROR;
  435. Lock(n->lock);
  436. {
  437. if (n->ClientOption == NULL || n->ClientAuth == NULL)
  438. {
  439. err = ERR_ACCOUNT_NOT_PRESENT;
  440. }
  441. else
  442. {
  443. FreeRpcCreateLink(t);
  444. Zero(t, sizeof(RPC_CREATE_LINK));
  445. t->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
  446. Copy(t->ClientOption, n->ClientOption, sizeof(CLIENT_OPTION));
  447. t->ClientAuth = CopyClientAuth(n->ClientAuth);
  448. }
  449. }
  450. Unlock(n->lock);
  451. return err;
  452. }
  453. // Get the state
  454. UINT NtGetStatus(NAT *n, RPC_NAT_STATUS *t)
  455. {
  456. Lock(n->lock);
  457. {
  458. VH *v = n->Virtual;
  459. FreeRpcNatStatus(t);
  460. Zero(t, sizeof(RPC_NAT_STATUS));
  461. LockVirtual(v);
  462. {
  463. UINT i;
  464. LockList(v->NatTable);
  465. {
  466. for (i = 0;i < LIST_NUM(v->NatTable);i++)
  467. {
  468. NAT_ENTRY *e = LIST_DATA(v->NatTable, i);
  469. switch (e->Protocol)
  470. {
  471. case NAT_TCP:
  472. t->NumTcpSessions++;
  473. break;
  474. case NAT_UDP:
  475. t->NumUdpSessions++;
  476. break;
  477. case NAT_ICMP:
  478. t->NumIcmpSessions++;
  479. break;
  480. case NAT_DNS:
  481. t->NumDnsSessions++;
  482. break;
  483. }
  484. }
  485. if (NnIsActive(v) && v->NativeNat != NULL)
  486. {
  487. NATIVE_NAT *nn = v->NativeNat;
  488. for (i = 0;i < LIST_NUM(nn->NatTableForSend->AllList);i++)
  489. {
  490. NATIVE_NAT_ENTRY *e = LIST_DATA(nn->NatTableForSend->AllList, i);
  491. switch (e->Protocol)
  492. {
  493. case NAT_TCP:
  494. t->NumTcpSessions++;
  495. break;
  496. case NAT_UDP:
  497. t->NumUdpSessions++;
  498. break;
  499. case NAT_ICMP:
  500. t->NumIcmpSessions++;
  501. break;
  502. case NAT_DNS:
  503. t->NumDnsSessions++;
  504. break;
  505. }
  506. }
  507. }
  508. }
  509. UnlockList(v->NatTable);
  510. t->NumDhcpClients = LIST_NUM(v->DhcpLeaseList);
  511. t->IsKernelMode = NnIsActiveEx(v, &t->IsRawIpMode);
  512. }
  513. UnlockVirtual(v);
  514. }
  515. Unlock(n->lock);
  516. return ERR_NO_ERROR;
  517. }
  518. // Get the information
  519. UINT NtGetInfo(NAT *n, RPC_NAT_INFO *t)
  520. {
  521. OS_INFO *info;
  522. FreeRpcNatInfo(t);
  523. Zero(t, sizeof(RPC_NAT_INFO));
  524. StrCpy(t->NatProductName, sizeof(t->NatProductName), CEDAR_ROUTER_STR);
  525. StrCpy(t->NatVersionString, sizeof(t->NatVersionString), n->Cedar->VerString);
  526. StrCpy(t->NatBuildInfoString, sizeof(t->NatBuildInfoString), n->Cedar->BuildInfo);
  527. t->NatVerInt = n->Cedar->Build;
  528. t->NatBuildInt = n->Cedar->Build;
  529. GetMachineName(t->NatHostName, sizeof(t->NatHostName));
  530. info = GetOsInfo();
  531. CopyOsInfo(&t->OsInfo, info);
  532. GetMemInfo(&t->MemInfo);
  533. return ERR_NO_ERROR;
  534. }
  535. // Get the NAT list
  536. UINT NtEnumNatList(NAT *n, RPC_ENUM_NAT *t)
  537. {
  538. UINT ret = ERR_NO_ERROR;
  539. VH *v = NULL;
  540. Lock(n->lock);
  541. {
  542. v = n->Virtual;
  543. if (n->Online == false || v == NULL)
  544. {
  545. ret = ERR_OFFLINE;
  546. }
  547. else
  548. {
  549. LockVirtual(v);
  550. {
  551. if (v->Active == false)
  552. {
  553. ret = ERR_OFFLINE;
  554. }
  555. else
  556. {
  557. FreeRpcEnumNat(t);
  558. Zero(t, sizeof(RPC_ENUM_NAT));
  559. LockList(v->NatTable);
  560. {
  561. UINT i;
  562. UINT num_usermode_nat = LIST_NUM(v->NatTable);
  563. UINT num_kernel_mode_nat = 0;
  564. NATIVE_NAT *native = NULL;
  565. if (NnIsActive(v) && (v->NativeNat != NULL))
  566. {
  567. native = v->NativeNat;
  568. num_kernel_mode_nat = LIST_NUM(native->NatTableForSend->AllList);
  569. }
  570. t->NumItem = num_usermode_nat + num_kernel_mode_nat;
  571. t->Items = ZeroMalloc(sizeof(RPC_ENUM_NAT_ITEM) * t->NumItem);
  572. // Enumerate entries of the user mode NAT
  573. for (i = 0;i < num_usermode_nat;i++)
  574. {
  575. NAT_ENTRY *nat = LIST_DATA(v->NatTable, i);
  576. RPC_ENUM_NAT_ITEM *e = &t->Items[i];
  577. e->Id = nat->Id;
  578. e->Protocol = nat->Protocol;
  579. e->SrcIp = nat->SrcIp;
  580. e->DestIp = nat->DestIp;
  581. e->SrcPort = nat->SrcPort;
  582. e->DestPort = nat->DestPort;
  583. e->CreatedTime = TickToTime(nat->CreatedTime);
  584. e->LastCommTime = TickToTime(nat->LastCommTime);
  585. IPToStr32(e->SrcHost, sizeof(e->SrcHost), e->SrcIp);
  586. IPToStr32(e->DestHost, sizeof(e->DestHost), e->DestIp);
  587. if (nat->Sock != NULL)
  588. {
  589. e->SendSize = nat->Sock->SendSize;
  590. e->RecvSize = nat->Sock->RecvSize;
  591. if (nat->Sock->Type == SOCK_TCP)
  592. {
  593. StrCpy(e->DestHost, sizeof(e->DestHost), nat->Sock->RemoteHostname);
  594. }
  595. }
  596. e->TcpStatus = nat->TcpStatus;
  597. }
  598. // Enumerate the entries in the kernel-mode NAT
  599. if (native != NULL)
  600. {
  601. for (i = 0;i < num_kernel_mode_nat;i++)
  602. {
  603. NATIVE_NAT_ENTRY *nat = LIST_DATA(native->NatTableForSend->AllList, i);
  604. RPC_ENUM_NAT_ITEM *e = &t->Items[num_usermode_nat + i];
  605. e->Id = nat->Id;
  606. e->Protocol = nat->Protocol;
  607. e->SrcIp = nat->SrcIp;
  608. e->DestIp = nat->DestIp;
  609. e->SrcPort = nat->SrcPort;
  610. e->DestPort = nat->DestPort;
  611. e->CreatedTime = TickToTime(nat->CreatedTime);
  612. e->LastCommTime = TickToTime(nat->LastCommTime);
  613. IPToStr32(e->SrcHost, sizeof(e->SrcHost), e->SrcIp);
  614. IPToStr32(e->DestHost, sizeof(e->DestHost), e->DestIp);
  615. e->SendSize = nat->TotalSent;
  616. e->RecvSize = nat->TotalRecv;
  617. e->TcpStatus = nat->Status;
  618. }
  619. }
  620. }
  621. UnlockList(v->NatTable);
  622. }
  623. }
  624. UnlockVirtual(v);
  625. }
  626. }
  627. Unlock(n->lock);
  628. return ret;
  629. }
  630. UINT NtEnumDhcpList(NAT *n, RPC_ENUM_DHCP *t)
  631. {
  632. UINT ret = ERR_NO_ERROR;
  633. VH *v = NULL;
  634. Lock(n->lock);
  635. {
  636. v = n->Virtual;
  637. if (n->Online == false || v == NULL)
  638. {
  639. ret = ERR_OFFLINE;
  640. }
  641. else
  642. {
  643. LockVirtual(v);
  644. {
  645. if (v->Active == false)
  646. {
  647. ret = ERR_OFFLINE;
  648. }
  649. else
  650. {
  651. FreeRpcEnumDhcp(t);
  652. Zero(t, sizeof(RPC_ENUM_DHCP));
  653. LockList(v->DhcpLeaseList);
  654. {
  655. UINT i;
  656. t->NumItem = LIST_NUM(v->DhcpLeaseList);
  657. t->Items = ZeroMalloc(sizeof(RPC_ENUM_DHCP_ITEM) * t->NumItem);
  658. for (i = 0;i < t->NumItem;i++)
  659. {
  660. DHCP_LEASE *dhcp = LIST_DATA(v->DhcpLeaseList, i);
  661. RPC_ENUM_DHCP_ITEM *e = &t->Items[i];
  662. e->Id = dhcp->Id;
  663. e->LeasedTime = TickToTime(dhcp->LeasedTime);
  664. e->ExpireTime = TickToTime(dhcp->ExpireTime);
  665. Copy(e->MacAddress, dhcp->MacAddress, 6);
  666. e->IpAddress = dhcp->IpAddress;
  667. e->Mask = dhcp->Mask;
  668. StrCpy(e->Hostname, sizeof(e->Hostname), dhcp->Hostname);
  669. }
  670. }
  671. UnlockList(v->DhcpLeaseList);
  672. }
  673. }
  674. UnlockVirtual(v);
  675. }
  676. }
  677. Unlock(n->lock);
  678. return ret;
  679. }
  680. // VH_OPTION
  681. void InVhOption(VH_OPTION *t, PACK *p)
  682. {
  683. // Validate arguments
  684. if (t == NULL || p == NULL)
  685. {
  686. return;
  687. }
  688. Zero(t, sizeof(VH_OPTION));
  689. PackGetData2(p, "MacAddress", t->MacAddress, 6);
  690. PackGetIp(p, "Ip", &t->Ip);
  691. PackGetIp(p, "Mask", &t->Mask);
  692. t->UseNat = PackGetBool(p, "UseNat");
  693. t->Mtu = PackGetInt(p, "Mtu");
  694. t->NatTcpTimeout = PackGetInt(p, "NatTcpTimeout");
  695. t->NatUdpTimeout = PackGetInt(p, "NatUdpTimeout");
  696. t->UseDhcp = PackGetBool(p, "UseDhcp");
  697. PackGetIp(p, "DhcpLeaseIPStart", &t->DhcpLeaseIPStart);
  698. PackGetIp(p, "DhcpLeaseIPEnd", &t->DhcpLeaseIPEnd);
  699. PackGetIp(p, "DhcpSubnetMask", &t->DhcpSubnetMask);
  700. t->DhcpExpireTimeSpan = PackGetInt(p, "DhcpExpireTimeSpan");
  701. PackGetIp(p, "DhcpGatewayAddress", &t->DhcpGatewayAddress);
  702. PackGetIp(p, "DhcpDnsServerAddress", &t->DhcpDnsServerAddress);
  703. PackGetIp(p, "DhcpDnsServerAddress2", &t->DhcpDnsServerAddress2);
  704. PackGetStr(p, "DhcpDomainName", t->DhcpDomainName, sizeof(t->DhcpDomainName));
  705. t->SaveLog = PackGetBool(p, "SaveLog");
  706. PackGetStr(p, "RpcHubName", t->HubName, sizeof(t->HubName));
  707. t->ApplyDhcpPushRoutes = PackGetBool(p, "ApplyDhcpPushRoutes");
  708. PackGetStr(p, "DhcpPushRoutes", t->DhcpPushRoutes, sizeof(t->DhcpPushRoutes));
  709. }
  710. void OutVhOption(PACK *p, VH_OPTION *t)
  711. {
  712. // Validate arguments
  713. if (t == NULL || p == NULL)
  714. {
  715. return;
  716. }
  717. PackAddData(p, "MacAddress", t->MacAddress, 6);
  718. PackAddIp(p, "Ip", &t->Ip);
  719. PackAddIp(p, "Mask", &t->Mask);
  720. PackAddBool(p, "UseNat", t->UseNat);
  721. PackAddInt(p, "Mtu", t->Mtu);
  722. PackAddInt(p, "NatTcpTimeout", t->NatTcpTimeout);
  723. PackAddInt(p, "NatUdpTimeout", t->NatUdpTimeout);
  724. PackAddBool(p, "UseDhcp", t->UseDhcp);
  725. PackAddIp(p, "DhcpLeaseIPStart", &t->DhcpLeaseIPStart);
  726. PackAddIp(p, "DhcpLeaseIPEnd", &t->DhcpLeaseIPEnd);
  727. PackAddIp(p, "DhcpSubnetMask", &t->DhcpSubnetMask);
  728. PackAddInt(p, "DhcpExpireTimeSpan", t->DhcpExpireTimeSpan);
  729. PackAddIp(p, "DhcpGatewayAddress", &t->DhcpGatewayAddress);
  730. PackAddIp(p, "DhcpDnsServerAddress", &t->DhcpDnsServerAddress);
  731. PackAddIp(p, "DhcpDnsServerAddress2", &t->DhcpDnsServerAddress2);
  732. PackAddStr(p, "DhcpDomainName", t->DhcpDomainName);
  733. PackAddBool(p, "SaveLog", t->SaveLog);
  734. PackAddStr(p, "RpcHubName", t->HubName);
  735. PackAddBool(p, "ApplyDhcpPushRoutes", true);
  736. PackAddStr(p, "DhcpPushRoutes", t->DhcpPushRoutes);
  737. }
  738. // RPC_ENUM_DHCP
  739. void InRpcEnumDhcp(RPC_ENUM_DHCP *t, PACK *p)
  740. {
  741. UINT i;
  742. // Validate arguments
  743. if (t == NULL || p == NULL)
  744. {
  745. return;
  746. }
  747. Zero(t, sizeof(RPC_ENUM_DHCP));
  748. t->NumItem = PackGetInt(p, "NumItem");
  749. t->Items = ZeroMalloc(sizeof(RPC_ENUM_DHCP_ITEM) * t->NumItem);
  750. PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
  751. for (i = 0;i < t->NumItem;i++)
  752. {
  753. RPC_ENUM_DHCP_ITEM *e = &t->Items[i];
  754. e->Id = PackGetIntEx(p, "Id", i);
  755. e->LeasedTime = PackGetInt64Ex(p, "LeasedTime", i);
  756. e->ExpireTime = PackGetInt64Ex(p, "ExpireTime", i);
  757. PackGetDataEx2(p, "MacAddress", e->MacAddress, 6, i);
  758. e->IpAddress = PackGetIp32Ex(p, "IpAddress", i);
  759. e->Mask = PackGetIntEx(p, "Mask", i);
  760. PackGetStrEx(p, "Hostname", e->Hostname, sizeof(e->Hostname), i);
  761. }
  762. }
  763. void OutRpcEnumDhcp(PACK *p, RPC_ENUM_DHCP *t)
  764. {
  765. UINT i;
  766. // Validate arguments
  767. if (p == NULL || t == NULL)
  768. {
  769. return;
  770. }
  771. PackAddInt(p, "NumItem", t->NumItem);
  772. PackAddStr(p, "HubName", t->HubName);
  773. for (i = 0;i < t->NumItem;i++)
  774. {
  775. RPC_ENUM_DHCP_ITEM *e = &t->Items[i];
  776. PackAddIntEx(p, "Id", e->Id, i, t->NumItem);
  777. PackAddInt64Ex(p, "LeasedTime", e->LeasedTime, i, t->NumItem);
  778. PackAddInt64Ex(p, "ExpireTime", e->ExpireTime, i, t->NumItem);
  779. PackAddDataEx(p, "MacAddress", e->MacAddress, 6, i, t->NumItem);
  780. PackAddIp32Ex(p, "IpAddress", e->IpAddress, i, t->NumItem);
  781. PackAddIntEx(p, "Mask", e->Mask, i, t->NumItem);
  782. PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumItem);
  783. }
  784. }
  785. void FreeRpcEnumDhcp(RPC_ENUM_DHCP *t)
  786. {
  787. // Validate arguments
  788. if (t == NULL)
  789. {
  790. return;
  791. }
  792. Free(t->Items);
  793. }
  794. // RPC_ENUM_NAT
  795. void InRpcEnumNat(RPC_ENUM_NAT *t, PACK *p)
  796. {
  797. UINT i;
  798. // Validate arguments
  799. if (t == NULL || p == NULL)
  800. {
  801. return;
  802. }
  803. Zero(t, sizeof(RPC_ENUM_NAT));
  804. t->NumItem = PackGetInt(p, "NumItem");
  805. PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
  806. t->Items = ZeroMalloc(sizeof(RPC_ENUM_NAT_ITEM) * t->NumItem);
  807. for (i = 0;i < t->NumItem;i++)
  808. {
  809. RPC_ENUM_NAT_ITEM *e = &t->Items[i];
  810. e->Id = PackGetIntEx(p, "Id", i);
  811. e->Protocol = PackGetIntEx(p, "Protocol", i);
  812. e->SrcIp = PackGetIntEx(p, "SrcIp", i);
  813. PackGetStrEx(p, "SrcHost", e->SrcHost, sizeof(e->SrcHost), i);
  814. e->SrcPort = PackGetIntEx(p, "SrcPort", i);
  815. e->DestIp = PackGetIntEx(p, "DestIp", i);
  816. PackGetStrEx(p, "DestHost", e->DestHost, sizeof(e->DestHost), i);
  817. e->DestPort = PackGetIntEx(p, "DestPort", i);
  818. e->CreatedTime = PackGetInt64Ex(p, "CreatedTime", i);
  819. e->LastCommTime = PackGetInt64Ex(p, "LastCommTime", i);
  820. e->SendSize = PackGetInt64Ex(p, "SendSize", i);
  821. e->RecvSize = PackGetInt64Ex(p, "RecvSize", i);
  822. e->TcpStatus = PackGetIntEx(p, "TcpStatus", i);
  823. }
  824. }
  825. void OutRpcEnumNat(PACK *p, RPC_ENUM_NAT *t)
  826. {
  827. UINT i;
  828. // Validate arguments
  829. if (t == NULL || p == NULL)
  830. {
  831. return;
  832. }
  833. PackAddInt(p, "NumItem", t->NumItem);
  834. PackAddStr(p, "HubName", t->HubName);
  835. for (i = 0;i < t->NumItem;i++)
  836. {
  837. RPC_ENUM_NAT_ITEM *e = &t->Items[i];
  838. PackAddIntEx(p, "Id", e->Id, i, t->NumItem);
  839. PackAddIntEx(p, "Protocol", e->Protocol, i, t->NumItem);
  840. PackAddIp32Ex(p, "SrcIp", e->SrcIp, i, t->NumItem);
  841. PackAddStrEx(p, "SrcHost", e->SrcHost, i, t->NumItem);
  842. PackAddIntEx(p, "SrcPort", e->SrcPort, i, t->NumItem);
  843. PackAddIp32Ex(p, "DestIp", e->DestIp, i, t->NumItem);
  844. PackAddStrEx(p, "DestHost", e->DestHost, i, t->NumItem);
  845. PackAddIntEx(p, "DestPort", e->DestPort, i, t->NumItem);
  846. PackAddInt64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumItem);
  847. PackAddInt64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumItem);
  848. PackAddInt64Ex(p, "SendSize", e->SendSize, i, t->NumItem);
  849. PackAddInt64Ex(p, "RecvSize", e->RecvSize, i, t->NumItem);
  850. PackAddIntEx(p, "TcpStatus", e->TcpStatus, i, t->NumItem);
  851. }
  852. }
  853. void FreeRpcEnumNat(RPC_ENUM_NAT *t)
  854. {
  855. // Validate arguments
  856. if (t == NULL)
  857. {
  858. return;
  859. }
  860. Free(t->Items);
  861. }
  862. // RPC_NAT_INFO
  863. void InRpcNatInfo(RPC_NAT_INFO *t, PACK *p)
  864. {
  865. // Validate arguments
  866. if (t == NULL || p == NULL)
  867. {
  868. return;
  869. }
  870. Zero(t, sizeof(RPC_NAT_INFO));
  871. PackGetStr(p, "NatProductName", t->NatProductName, sizeof(t->NatProductName));
  872. PackGetStr(p, "NatVersionString", t->NatVersionString, sizeof(t->NatVersionString));
  873. PackGetStr(p, "NatBuildInfoString", t->NatBuildInfoString, sizeof(t->NatBuildInfoString));
  874. t->NatVerInt = PackGetInt(p, "NatVerInt");
  875. t->NatBuildInt = PackGetInt(p, "NatBuildInt");
  876. PackGetStr(p, "NatHostName", t->NatHostName, sizeof(t->NatHostName));
  877. InRpcOsInfo(&t->OsInfo, p);
  878. InRpcMemInfo(&t->MemInfo, p);
  879. }
  880. void OutRpcNatInfo(PACK *p, RPC_NAT_INFO *t)
  881. {
  882. // Validate arguments
  883. if (t == NULL || p == NULL)
  884. {
  885. return;
  886. }
  887. PackAddStr(p, "NatProductName", t->NatProductName);
  888. PackAddStr(p, "NatVersionString", t->NatVersionString);
  889. PackAddStr(p, "NatBuildInfoString", t->NatBuildInfoString);
  890. PackAddInt(p, "NatVerInt", t->NatVerInt);
  891. PackAddInt(p, "NatBuildInt", t->NatBuildInt);
  892. PackAddStr(p, "NatHostName", t->NatHostName);
  893. OutRpcOsInfo(p, &t->OsInfo);
  894. OutRpcMemInfo(p, &t->MemInfo);
  895. }
  896. void FreeRpcNatInfo(RPC_NAT_INFO *t)
  897. {
  898. // Validate arguments
  899. if (t == NULL)
  900. {
  901. return;
  902. }
  903. FreeRpcOsInfo(&t->OsInfo);
  904. }
  905. // RPC_NAT_STATUS
  906. void InRpcNatStatus(RPC_NAT_STATUS *t, PACK *p)
  907. {
  908. // Validate arguments
  909. if (t == NULL || p == NULL)
  910. {
  911. return;
  912. }
  913. Zero(t, sizeof(RPC_NAT_STATUS));
  914. t->NumTcpSessions = PackGetInt(p, "NumTcpSessions");
  915. t->NumUdpSessions = PackGetInt(p, "NumUdpSessions");
  916. t->NumIcmpSessions = PackGetInt(p, "NumIcmpSessions");
  917. t->NumDnsSessions = PackGetInt(p, "NumDnsSessions");
  918. t->NumDhcpClients = PackGetInt(p, "NumDhcpClients");
  919. t->IsKernelMode = PackGetBool(p, "IsKernelMode");
  920. t->IsRawIpMode = PackGetBool(p, "IsRawIpMode");
  921. PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
  922. }
  923. void OutRpcNatStatus(PACK *p, RPC_NAT_STATUS *t)
  924. {
  925. // Validate arguments
  926. if (p == NULL || t == NULL)
  927. {
  928. return;
  929. }
  930. PackAddStr(p, "HubName", t->HubName);
  931. PackAddInt(p, "NumTcpSessions", t->NumTcpSessions);
  932. PackAddInt(p, "NumUdpSessions", t->NumUdpSessions);
  933. PackAddInt(p, "NumIcmpSessions", t->NumIcmpSessions);
  934. PackAddInt(p, "NumDnsSessions", t->NumDnsSessions);
  935. PackAddInt(p, "NumDhcpClients", t->NumDhcpClients);
  936. PackAddBool(p, "IsKernelMode", t->IsKernelMode);
  937. PackAddBool(p, "IsRawIpMode", t->IsRawIpMode);
  938. }
  939. void FreeRpcNatStatus(RPC_NAT_STATUS *t)
  940. {
  941. }
  942. // RPC_DUMMY
  943. void InRpcDummy(RPC_DUMMY *t, PACK *p)
  944. {
  945. // Validate arguments
  946. if (t == NULL || p == NULL)
  947. {
  948. return;
  949. }
  950. Zero(t, sizeof(RPC_DUMMY));
  951. t->DummyValue = PackGetInt(p, "DummyValue");
  952. }
  953. void OutRpcDummy(PACK *p, RPC_DUMMY *t)
  954. {
  955. // Validate arguments
  956. if (t == NULL || p == NULL)
  957. {
  958. return;
  959. }
  960. PackAddInt(p, "DummyValue", t->DummyValue);
  961. }
  962. // Main procedure for management
  963. void NiAdminMain(NAT *n, SOCK *s)
  964. {
  965. RPC *r;
  966. PACK *p;
  967. // Validate arguments
  968. if (n == NULL || s == NULL)
  969. {
  970. return;
  971. }
  972. p = NewPack();
  973. HttpServerSend(s, p);
  974. FreePack(p);
  975. r = StartRpcServer(s, NiRpcServer, n);
  976. RpcServer(r);
  977. RpcFree(r);
  978. }
  979. // Management thread
  980. void NiAdminThread(THREAD *thread, void *param)
  981. {
  982. NAT_ADMIN *a = (NAT_ADMIN *)param;
  983. NAT *n;
  984. SOCK *s;
  985. UCHAR random[SHA1_SIZE];
  986. UINT err;
  987. // Validate arguments
  988. if (thread == NULL || param == NULL)
  989. {
  990. return;
  991. }
  992. // Random number generation
  993. Rand(random, sizeof(random));
  994. a->Thread = thread;
  995. AddRef(a->Thread->ref);
  996. s = a->Sock;
  997. AddRef(s->ref);
  998. n = a->Nat;
  999. LockList(n->AdminList);
  1000. {
  1001. Add(n->AdminList, a);
  1002. }
  1003. UnlockList(n->AdminList);
  1004. NoticeThreadInit(thread);
  1005. err = ERR_AUTH_FAILED;
  1006. if (StartSSL(s, n->AdminX, n->AdminK))
  1007. {
  1008. PACK *p;
  1009. // Send the random number
  1010. p = NewPack();
  1011. PackAddData(p, "auth_random", random, sizeof(random));
  1012. if (HttpServerSend(s, p))
  1013. {
  1014. PACK *p;
  1015. // Receive a password
  1016. p = HttpServerRecv(s);
  1017. if (p != NULL)
  1018. {
  1019. UCHAR secure_password[SHA1_SIZE];
  1020. UCHAR secure_check[SHA1_SIZE];
  1021. if (PackGetData2(p, "secure_password", secure_password, sizeof(secure_password)))
  1022. {
  1023. SecurePassword(secure_check, n->HashedPassword, random);
  1024. if (Cmp(secure_check, secure_password, SHA1_SIZE) == 0)
  1025. {
  1026. UCHAR test[SHA1_SIZE];
  1027. // Password match
  1028. Hash(test, "", 0, true);
  1029. SecurePassword(test, test, random);
  1030. #if 0
  1031. if (Cmp(test, secure_check, SHA1_SIZE) == 0 && s->RemoteIP.addr[0] != 127)
  1032. {
  1033. // A client can not connect from the outside with blank password
  1034. err = ERR_NULL_PASSWORD_LOCAL_ONLY;
  1035. }
  1036. else
  1037. #endif
  1038. {
  1039. // Successful connection
  1040. err = ERR_NO_ERROR;
  1041. NiAdminMain(n, s);
  1042. }
  1043. }
  1044. }
  1045. FreePack(p);
  1046. }
  1047. }
  1048. FreePack(p);
  1049. if (err != ERR_NO_ERROR)
  1050. {
  1051. p = PackError(err);
  1052. HttpServerSend(s, p);
  1053. FreePack(p);
  1054. }
  1055. }
  1056. Disconnect(s);
  1057. ReleaseSock(s);
  1058. }
  1059. // Management port Listen thread
  1060. void NiListenThread(THREAD *thread, void *param)
  1061. {
  1062. NAT *n = (NAT *)param;
  1063. SOCK *a;
  1064. UINT i;
  1065. bool b = false;
  1066. // Validate arguments
  1067. if (thread == NULL || param == NULL)
  1068. {
  1069. return;
  1070. }
  1071. // Initialize the management list
  1072. n->AdminList = NewList(NULL);
  1073. while (true)
  1074. {
  1075. a = Listen(DEFAULT_NAT_ADMIN_PORT);
  1076. if (b == false)
  1077. {
  1078. b = true;
  1079. NoticeThreadInit(thread);
  1080. }
  1081. if (a != NULL)
  1082. {
  1083. break;
  1084. }
  1085. Wait(n->HaltEvent, NAT_ADMIN_PORT_LISTEN_INTERVAL);
  1086. if (n->Halt)
  1087. {
  1088. return;
  1089. }
  1090. }
  1091. n->AdminListenSock = a;
  1092. AddRef(a->ref);
  1093. // Waiting
  1094. while (true)
  1095. {
  1096. SOCK *s = Accept(a);
  1097. THREAD *t;
  1098. NAT_ADMIN *admin;
  1099. if (s == NULL)
  1100. {
  1101. break;
  1102. }
  1103. if (n->Halt)
  1104. {
  1105. ReleaseSock(s);
  1106. break;
  1107. }
  1108. admin = ZeroMalloc(sizeof(NAT_ADMIN));
  1109. admin->Nat = n;
  1110. admin->Sock = s;
  1111. t = NewThread(NiAdminThread, admin);
  1112. WaitThreadInit(t);
  1113. ReleaseThread(t);
  1114. }
  1115. // Disconnect all management connections
  1116. LockList(n->AdminList);
  1117. {
  1118. for (i = 0;i < LIST_NUM(n->AdminList);i++)
  1119. {
  1120. NAT_ADMIN *a = LIST_DATA(n->AdminList, i);
  1121. Disconnect(a->Sock);
  1122. WaitThread(a->Thread, INFINITE);
  1123. ReleaseThread(a->Thread);
  1124. ReleaseSock(a->Sock);
  1125. Free(a);
  1126. }
  1127. }
  1128. UnlockList(n->AdminList);
  1129. ReleaseList(n->AdminList);
  1130. ReleaseSock(a);
  1131. }
  1132. // Initialize receiving management command
  1133. void NiInitAdminAccept(NAT *n)
  1134. {
  1135. THREAD *t;
  1136. // Validate arguments
  1137. if (n == NULL)
  1138. {
  1139. return;
  1140. }
  1141. t = NewThread(NiListenThread, n);
  1142. WaitThreadInit(t);
  1143. n->AdminAcceptThread = t;
  1144. }
  1145. // Complete receiving management command
  1146. void NiFreeAdminAccept(NAT *n)
  1147. {
  1148. // Validate arguments
  1149. if (n == NULL)
  1150. {
  1151. return;
  1152. }
  1153. n->Halt = true;
  1154. Disconnect(n->AdminListenSock);
  1155. Set(n->HaltEvent);
  1156. while (true)
  1157. {
  1158. if (WaitThread(n->AdminAcceptThread, 1000) == false)
  1159. {
  1160. Disconnect(n->AdminListenSock);
  1161. }
  1162. else
  1163. {
  1164. break;
  1165. }
  1166. }
  1167. ReleaseThread(n->AdminAcceptThread);
  1168. ReleaseSock(n->AdminListenSock);
  1169. }
  1170. // Clear the DHCP options that are not supported by the dynamic Virtual HUB
  1171. void NiClearUnsupportedVhOptionForDynamicHub(VH_OPTION *o, bool initial)
  1172. {
  1173. // Validate arguments
  1174. if (o == NULL)
  1175. {
  1176. return;
  1177. }
  1178. o->UseNat = false;
  1179. if (initial)
  1180. {
  1181. Zero(&o->DhcpGatewayAddress, sizeof(IP));
  1182. Zero(&o->DhcpDnsServerAddress, sizeof(IP));
  1183. Zero(&o->DhcpDnsServerAddress2, sizeof(IP));
  1184. StrCpy(o->DhcpDomainName, sizeof(o->DhcpDomainName), "");
  1185. }
  1186. }
  1187. // Initialize the options for the virtual host
  1188. void NiSetDefaultVhOption(NAT *n, VH_OPTION *o)
  1189. {
  1190. // Validate arguments
  1191. if (o == NULL)
  1192. {
  1193. return;
  1194. }
  1195. Zero(o, sizeof(VH_OPTION));
  1196. GenMacAddress(o->MacAddress);
  1197. // Set the virtual IP to 192.168.30.1/24
  1198. SetIP(&o->Ip, 192, 168, 30, 1);
  1199. SetIP(&o->Mask, 255, 255, 255, 0);
  1200. o->UseNat = true;
  1201. o->Mtu = 1500;
  1202. o->NatTcpTimeout = 1800;
  1203. o->NatUdpTimeout = 60;
  1204. o->UseDhcp = true;
  1205. SetIP(&o->DhcpLeaseIPStart, 192, 168, 30, 10);
  1206. SetIP(&o->DhcpLeaseIPEnd, 192, 168, 30, 200);
  1207. SetIP(&o->DhcpSubnetMask, 255, 255, 255, 0);
  1208. o->DhcpExpireTimeSpan = 7200;
  1209. o->SaveLog = true;
  1210. SetIP(&o->DhcpGatewayAddress, 192, 168, 30, 1);
  1211. SetIP(&o->DhcpDnsServerAddress, 192, 168, 30, 1);
  1212. GetDomainName(o->DhcpDomainName, sizeof(o->DhcpDomainName));
  1213. }
  1214. // Reset the setting of NAT to the default
  1215. void NiInitDefaultConfig(NAT *n)
  1216. {
  1217. // Validate arguments
  1218. if (n == NULL)
  1219. {
  1220. return;
  1221. }
  1222. // Initialize the virtual host option
  1223. NiSetDefaultVhOption(n, &n->Option);
  1224. // Initialize management port
  1225. n->AdminPort = DEFAULT_NAT_ADMIN_PORT;
  1226. // Offline
  1227. n->Online = false;
  1228. // Save the log
  1229. n->Option.SaveLog = true;
  1230. }
  1231. // Initialize the NAT configuration
  1232. void NiInitConfig(NAT *n)
  1233. {
  1234. // Validate arguments
  1235. if (n == NULL)
  1236. {
  1237. return;
  1238. }
  1239. // Initial state
  1240. NiInitDefaultConfig(n);
  1241. }
  1242. // Read the virtual host option (extended)
  1243. void NiLoadVhOptionEx(VH_OPTION *o, FOLDER *root)
  1244. {
  1245. FOLDER *host, *nat, *dhcp;
  1246. char mac_address[MAX_SIZE];
  1247. // Validate arguments
  1248. if (o == NULL || root == NULL)
  1249. {
  1250. return;
  1251. }
  1252. host = CfgGetFolder(root, "VirtualHost");
  1253. nat = CfgGetFolder(root, "VirtualRouter");
  1254. dhcp = CfgGetFolder(root, "VirtualDhcpServer");
  1255. Zero(o, sizeof(VH_OPTION));
  1256. GenMacAddress(o->MacAddress);
  1257. if (CfgGetStr(host, "VirtualHostMacAddress", mac_address, sizeof(mac_address)))
  1258. {
  1259. BUF *b = StrToBin(mac_address);
  1260. if (b != NULL)
  1261. {
  1262. if (b->Size == 6)
  1263. {
  1264. Copy(o->MacAddress, b->Buf, 6);
  1265. }
  1266. }
  1267. FreeBuf(b);
  1268. }
  1269. CfgGetIp(host, "VirtualHostIp", &o->Ip);
  1270. CfgGetIp(host, "VirtualHostIpSubnetMask", &o->Mask);
  1271. o->UseNat = CfgGetBool(nat, "NatEnabled");
  1272. o->Mtu = CfgGetInt(nat, "NatMtu");
  1273. o->NatTcpTimeout = CfgGetInt(nat, "NatTcpTimeout");
  1274. o->NatUdpTimeout = CfgGetInt(nat, "NatUdpTimeout");
  1275. o->UseDhcp = CfgGetBool(dhcp, "DhcpEnabled");
  1276. CfgGetIp(dhcp, "DhcpLeaseIPStart", &o->DhcpLeaseIPStart);
  1277. CfgGetIp(dhcp, "DhcpLeaseIPEnd", &o->DhcpLeaseIPEnd);
  1278. CfgGetIp(dhcp, "DhcpSubnetMask", &o->DhcpSubnetMask);
  1279. o->DhcpExpireTimeSpan = CfgGetInt(dhcp, "DhcpExpireTimeSpan");
  1280. CfgGetIp(dhcp, "DhcpGatewayAddress", &o->DhcpGatewayAddress);
  1281. CfgGetIp(dhcp, "DhcpDnsServerAddress", &o->DhcpDnsServerAddress);
  1282. CfgGetIp(dhcp, "DhcpDnsServerAddress2", &o->DhcpDnsServerAddress2);
  1283. CfgGetStr(dhcp, "DhcpDomainName", o->DhcpDomainName, sizeof(o->DhcpDomainName));
  1284. CfgGetStr(dhcp, "DhcpPushRoutes", o->DhcpPushRoutes, sizeof(o->DhcpPushRoutes));
  1285. // Test code
  1286. // StrCpy(o->DhcpPushRoutes, sizeof(o->DhcpPushRoutes),
  1287. // "130.158.6.0/24/192.168.9.2 130.158.80.244/255.255.255.255/192.168.9.2");
  1288. NormalizeClasslessRouteTableStr(o->DhcpPushRoutes, sizeof(o->DhcpPushRoutes), o->DhcpPushRoutes);
  1289. o->ApplyDhcpPushRoutes = true;
  1290. Trim(o->DhcpDomainName);
  1291. if (StrLen(o->DhcpDomainName) == 0)
  1292. {
  1293. //GetDomainName(o->DhcpDomainName, sizeof(o->DhcpDomainName));
  1294. }
  1295. o->SaveLog = CfgGetBool(root, "SaveLog");
  1296. }
  1297. // Read the virtual host option
  1298. void NiLoadVhOption(NAT *n, FOLDER *root)
  1299. {
  1300. VH_OPTION *o;
  1301. FOLDER *host, *nat, *dhcp;
  1302. char mac_address[MAX_SIZE];
  1303. // Validate arguments
  1304. if (n == NULL || root == NULL)
  1305. {
  1306. return;
  1307. }
  1308. host = CfgGetFolder(root, "VirtualHost");
  1309. nat = CfgGetFolder(root, "VirtualRouter");
  1310. dhcp = CfgGetFolder(root, "VirtualDhcpServer");
  1311. o = &n->Option;
  1312. Zero(o, sizeof(VH_OPTION));
  1313. GenMacAddress(o->MacAddress);
  1314. if (CfgGetStr(host, "VirtualHostMacAddress", mac_address, sizeof(mac_address)))
  1315. {
  1316. BUF *b = StrToBin(mac_address);
  1317. if (b != NULL)
  1318. {
  1319. if (b->Size == 6)
  1320. {
  1321. Copy(o->MacAddress, b->Buf, 6);
  1322. }
  1323. }
  1324. FreeBuf(b);
  1325. }
  1326. CfgGetIp(host, "VirtualHostIp", &o->Ip);
  1327. CfgGetIp(host, "VirtualHostIpSubnetMask", &o->Mask);
  1328. o->UseNat = CfgGetBool(nat, "NatEnabled");
  1329. o->Mtu = CfgGetInt(nat, "NatMtu");
  1330. o->NatTcpTimeout = CfgGetInt(nat, "NatTcpTimeout");
  1331. o->NatUdpTimeout = CfgGetInt(nat, "NatUdpTimeout");
  1332. o->UseDhcp = CfgGetBool(dhcp, "DhcpEnabled");
  1333. CfgGetIp(dhcp, "DhcpLeaseIPStart", &o->DhcpLeaseIPStart);
  1334. CfgGetIp(dhcp, "DhcpLeaseIPEnd", &o->DhcpLeaseIPEnd);
  1335. CfgGetIp(dhcp, "DhcpSubnetMask", &o->DhcpSubnetMask);
  1336. o->DhcpExpireTimeSpan = CfgGetInt(dhcp, "DhcpExpireTimeSpan");
  1337. CfgGetIp(dhcp, "DhcpGatewayAddress", &o->DhcpGatewayAddress);
  1338. CfgGetIp(dhcp, "DhcpDnsServerAddress", &o->DhcpDnsServerAddress);
  1339. CfgGetIp(dhcp, "DhcpDnsServerAddress2", &o->DhcpDnsServerAddress2);
  1340. CfgGetStr(dhcp, "DhcpDomainName", o->DhcpDomainName, sizeof(o->DhcpDomainName));
  1341. o->SaveLog = CfgGetBool(root, "SaveLog");
  1342. }
  1343. // Read connection options from the VPN server
  1344. void NiLoadClientData(NAT *n, FOLDER *root)
  1345. {
  1346. FOLDER *co, *ca;
  1347. // Validate arguments
  1348. if (n == NULL || root == NULL)
  1349. {
  1350. return;
  1351. }
  1352. co = CfgGetFolder(root, "VpnClientOption");
  1353. ca = CfgGetFolder(root, "VpnClientAuth");
  1354. if (co == NULL || ca == NULL)
  1355. {
  1356. return;
  1357. }
  1358. n->ClientOption = CiLoadClientOption(co);
  1359. n->ClientAuth = CiLoadClientAuth(ca);
  1360. }
  1361. // Write connection options to the VPN server
  1362. void NiWriteClientData(NAT *n, FOLDER *root)
  1363. {
  1364. // Validate arguments
  1365. if (n == NULL || root == NULL || n->ClientOption == NULL || n->ClientAuth == NULL)
  1366. {
  1367. return;
  1368. }
  1369. CiWriteClientOption(CfgCreateFolder(root, "VpnClientOption"), n->ClientOption);
  1370. CiWriteClientAuth(CfgCreateFolder(root, "VpnClientAuth"), n->ClientAuth);
  1371. }
  1372. // Write the virtual host option (extended)
  1373. void NiWriteVhOptionEx(VH_OPTION *o, FOLDER *root)
  1374. {
  1375. FOLDER *host, *nat, *dhcp;
  1376. char mac_address[MAX_SIZE];
  1377. // Validate arguments
  1378. if (o == NULL || root == NULL)
  1379. {
  1380. return;
  1381. }
  1382. host = CfgCreateFolder(root, "VirtualHost");
  1383. nat = CfgCreateFolder(root, "VirtualRouter");
  1384. dhcp = CfgCreateFolder(root, "VirtualDhcpServer");
  1385. MacToStr(mac_address, sizeof(mac_address), o->MacAddress);
  1386. CfgAddStr(host, "VirtualHostMacAddress", mac_address);
  1387. CfgAddIp(host, "VirtualHostIp", &o->Ip);
  1388. CfgAddIp(host, "VirtualHostIpSubnetMask", &o->Mask);
  1389. CfgAddBool(nat, "NatEnabled", o->UseNat);
  1390. CfgAddInt(nat, "NatMtu", o->Mtu);
  1391. CfgAddInt(nat, "NatTcpTimeout", o->NatTcpTimeout);
  1392. CfgAddInt(nat, "NatUdpTimeout", o->NatUdpTimeout);
  1393. CfgAddBool(dhcp, "DhcpEnabled", o->UseDhcp);
  1394. CfgAddIp(dhcp, "DhcpLeaseIPStart", &o->DhcpLeaseIPStart);
  1395. CfgAddIp(dhcp, "DhcpLeaseIPEnd", &o->DhcpLeaseIPEnd);
  1396. CfgAddIp(dhcp, "DhcpSubnetMask", &o->DhcpSubnetMask);
  1397. CfgAddInt(dhcp, "DhcpExpireTimeSpan", o->DhcpExpireTimeSpan);
  1398. CfgAddIp(dhcp, "DhcpGatewayAddress", &o->DhcpGatewayAddress);
  1399. CfgAddIp(dhcp, "DhcpDnsServerAddress", &o->DhcpDnsServerAddress);
  1400. CfgAddIp(dhcp, "DhcpDnsServerAddress2", &o->DhcpDnsServerAddress2);
  1401. CfgAddStr(dhcp, "DhcpDomainName", o->DhcpDomainName);
  1402. CfgAddStr(dhcp, "DhcpPushRoutes", o->DhcpPushRoutes);
  1403. CfgAddBool(root, "SaveLog", o->SaveLog);
  1404. }
  1405. // Write the virtual host option
  1406. void NiWriteVhOption(NAT *n, FOLDER *root)
  1407. {
  1408. VH_OPTION *o;
  1409. FOLDER *host, *nat, *dhcp;
  1410. char mac_address[MAX_SIZE];
  1411. // Validate arguments
  1412. if (n == NULL || root == NULL)
  1413. {
  1414. return;
  1415. }
  1416. host = CfgCreateFolder(root, "VirtualHost");
  1417. nat = CfgCreateFolder(root, "VirtualRouter");
  1418. dhcp = CfgCreateFolder(root, "VirtualDhcpServer");
  1419. o = &n->Option;
  1420. MacToStr(mac_address, sizeof(mac_address), o->MacAddress);
  1421. CfgAddStr(host, "VirtualHostMacAddress", mac_address);
  1422. CfgAddIp(host, "VirtualHostIp", &o->Ip);
  1423. CfgAddIp(host, "VirtualHostIpSubnetMask", &o->Mask);
  1424. CfgAddBool(nat, "NatEnabled", o->UseNat);
  1425. CfgAddInt(nat, "NatMtu", o->Mtu);
  1426. CfgAddInt(nat, "NatTcpTimeout", o->NatTcpTimeout);
  1427. CfgAddInt(nat, "NatUdpTimeout", o->NatUdpTimeout);
  1428. CfgAddBool(dhcp, "DhcpEnabled", o->UseDhcp);
  1429. CfgAddIp(dhcp, "DhcpLeaseIPStart", &o->DhcpLeaseIPStart);
  1430. CfgAddIp(dhcp, "DhcpLeaseIPEnd", &o->DhcpLeaseIPEnd);
  1431. CfgAddIp(dhcp, "DhcpSubnetMask", &o->DhcpSubnetMask);
  1432. CfgAddInt(dhcp, "DhcpExpireTimeSpan", o->DhcpExpireTimeSpan);
  1433. CfgAddIp(dhcp, "DhcpGatewayAddress", &o->DhcpGatewayAddress);
  1434. CfgAddIp(dhcp, "DhcpDnsServerAddress", &o->DhcpDnsServerAddress);
  1435. CfgAddIp(dhcp, "DhcpDnsServerAddress2", &o->DhcpDnsServerAddress2);
  1436. CfgAddStr(dhcp, "DhcpDomainName", o->DhcpDomainName);
  1437. CfgAddBool(root, "SaveLog", o->SaveLog);
  1438. }
  1439. // Read the configuration file
  1440. bool NiLoadConfig(NAT *n, FOLDER *root)
  1441. {
  1442. FOLDER *host;
  1443. BUF *b;
  1444. // Validate arguments
  1445. if (n == NULL || root == NULL)
  1446. {
  1447. return false;
  1448. }
  1449. host = CfgGetFolder(root, "VirtualHost");
  1450. if (host == NULL)
  1451. {
  1452. return false;
  1453. }
  1454. CfgGetByte(root, "HashedPassword", n->HashedPassword, sizeof(n->HashedPassword));
  1455. n->AdminPort = CfgGetInt(root, "AdminPort");
  1456. n->Online = CfgGetBool(root, "Online");
  1457. b = CfgGetBuf(root, "AdminCert");
  1458. if (b != NULL)
  1459. {
  1460. n->AdminX = BufToX(b, false);
  1461. FreeBuf(b);
  1462. }
  1463. b = CfgGetBuf(root, "AdminKey");
  1464. if (b != NULL)
  1465. {
  1466. n->AdminK = BufToK(b, true, false, NULL);
  1467. FreeBuf(b);
  1468. }
  1469. NiLoadVhOption(n, root);
  1470. NiLoadClientData(n, root);
  1471. return true;
  1472. }
  1473. // Write the configuration to a file
  1474. void NiWriteConfig(NAT *n)
  1475. {
  1476. // Validate arguments
  1477. if (n == NULL)
  1478. {
  1479. return;
  1480. }
  1481. Lock(n->lock);
  1482. {
  1483. FOLDER *root = CfgCreateFolder(NULL, TAG_ROOT);
  1484. BUF *b;
  1485. // Certificate
  1486. b = XToBuf(n->AdminX, false);
  1487. CfgAddBuf(root, "AdminCert", b);
  1488. FreeBuf(b);
  1489. // Secret key
  1490. b = KToBuf(n->AdminK, false, NULL);
  1491. CfgAddBuf(root, "AdminKey", b);
  1492. FreeBuf(b);
  1493. // Password
  1494. CfgAddByte(root, "HashedPassword", n->HashedPassword, sizeof(n->HashedPassword));
  1495. CfgAddInt(root, "AdminPort", n->AdminPort);
  1496. CfgAddBool(root, "Online", n->Online);
  1497. // Virtual host option
  1498. NiWriteVhOption(n, root);
  1499. // Connection options
  1500. if (n->ClientOption != NULL && n->ClientAuth != NULL)
  1501. {
  1502. NiWriteClientData(n, root);
  1503. }
  1504. SaveCfgRw(n->CfgRw, root);
  1505. CfgDeleteFolder(root);
  1506. }
  1507. Unlock(n->lock);
  1508. }
  1509. // Release the NAT configuration
  1510. void NiFreeConfig(NAT *n)
  1511. {
  1512. // Validate arguments
  1513. if (n == NULL)
  1514. {
  1515. return;
  1516. }
  1517. // Write the latest configuration
  1518. NiWriteConfig(n);
  1519. // Release the configuration R/W
  1520. FreeCfgRw(n->CfgRw);
  1521. n->CfgRw = NULL;
  1522. Free(n->ClientOption);
  1523. CiFreeClientAuth(n->ClientAuth);
  1524. FreeX(n->AdminX);
  1525. FreeK(n->AdminK);
  1526. }
  1527. // Create a NAT
  1528. NAT *NiNewNatEx(SNAT *snat, VH_OPTION *o)
  1529. {
  1530. NAT *n = ZeroMalloc(sizeof(NAT));
  1531. n->lock = NewLock();
  1532. Hash(n->HashedPassword, "", 0, true);
  1533. n->HaltEvent = NewEvent();
  1534. //n->Cedar = NewCedar(NULL, NULL);
  1535. n->SecureNAT = snat;
  1536. // Raise the priority
  1537. //OSSetHighPriority();
  1538. // Initialize the settings
  1539. NiInitConfig(n);
  1540. #if 0
  1541. // Start the operation of the virtual host
  1542. if (n->Online && n->ClientOption != NULL)
  1543. {
  1544. n->Virtual = NewVirtualHostEx(n->Cedar, n->ClientOption, n->ClientAuth, &n->Option, n);
  1545. }
  1546. else
  1547. {
  1548. n->Online = false;
  1549. n->Virtual = NULL;
  1550. }
  1551. #else
  1552. n->Virtual = NewVirtualHostEx(n->Cedar, NULL, NULL, o, n);
  1553. n->Online = true;
  1554. #endif
  1555. // Start management command
  1556. //NiInitAdminAccept(n);
  1557. return n;
  1558. }
  1559. NAT *NiNewNat()
  1560. {
  1561. return NiNewNatEx(NULL, NULL);
  1562. }
  1563. // Release the NAT
  1564. void NiFreeNat(NAT *n)
  1565. {
  1566. // Validate arguments
  1567. if (n == NULL)
  1568. {
  1569. return;
  1570. }
  1571. // Complete management command
  1572. //NiFreeAdminAccept(n);
  1573. // Stop if the virtual host is running
  1574. Lock(n->lock);
  1575. {
  1576. if (n->Virtual != NULL)
  1577. {
  1578. StopVirtualHost(n->Virtual);
  1579. ReleaseVirtual(n->Virtual);
  1580. n->Virtual = NULL;
  1581. }
  1582. }
  1583. Unlock(n->lock);
  1584. // Release the settings
  1585. NiFreeConfig(n);
  1586. // Delete the object
  1587. ReleaseCedar(n->Cedar);
  1588. ReleaseEvent(n->HaltEvent);
  1589. DeleteLock(n->lock);
  1590. Free(n);
  1591. }
  1592. // Stop the NAT
  1593. void NtStopNat()
  1594. {
  1595. Lock(nat_lock);
  1596. {
  1597. if (nat != NULL)
  1598. {
  1599. NiFreeNat(nat);
  1600. nat = NULL;
  1601. }
  1602. }
  1603. Unlock(nat_lock);
  1604. }
  1605. // Start the NAT
  1606. void NtStartNat()
  1607. {
  1608. Lock(nat_lock);
  1609. {
  1610. if (nat == NULL)
  1611. {
  1612. nat = NiNewNat();
  1613. }
  1614. }
  1615. Unlock(nat_lock);
  1616. }
  1617. // Initialize the NtXxx function
  1618. void NtInit()
  1619. {
  1620. if (nat_lock != NULL)
  1621. {
  1622. return;
  1623. }
  1624. nat_lock = NewLock();
  1625. }
  1626. // Release the NtXxx function
  1627. void NtFree()
  1628. {
  1629. if (nat_lock == NULL)
  1630. {
  1631. return;
  1632. }
  1633. DeleteLock(nat_lock);
  1634. nat_lock = NULL;
  1635. }
  1636. // Developed by SoftEther VPN Project at University of Tsukuba in Japan.
  1637. // Department of Computer Science has dozens of overly-enthusiastic geeks.
  1638. // Join us: http://www.tsukuba.ac.jp/english/admission/