* copy vendor drop to trunk
[lab.git] / Dev / utvpn / utvpn-unix-v101-7101-public / src / Cedar / Cedar.c
1 // SoftEther UT-VPN SourceCode\r
2 // \r
3 // Copyright (C) 2004-2010 SoftEther Corporation.\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.\r
6 // All Rights Reserved.\r
7 // \r
8 // http://utvpn.tsukuba.ac.jp/\r
9 // \r
10 // This program is free software; you can redistribute it and/or\r
11 // modify it under the terms of the GNU General Public License\r
12 // version 2 as published by the Free Software Foundation.\r
13 // \r
14 // This program is distributed in the hope that it will be useful,\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
17 // GNU General Public License for more details.\r
18 // \r
19 // You should have received a copy of the GNU General Public License version 2\r
20 // along with this program; if not, write to the Free Software\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
22 // \r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。\r
28 // \r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって\r
32 // ホストされています。\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、\r
34 // および、試験または研究のために利用が行われることを想定して配布\r
35 // しています。\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に\r
37 // あります。\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース\r
42 // に組み込みさせていただきます。\r
43 // \r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。\r
46 // \r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意\r
51 // ください。\r
52 // \r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、\r
58 // 公益保護にご協力いただきますようお願い申し上げます。\r
59 // \r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客\r
62 // を保護するための努力を行います。\r
63 // \r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/\r
65 // 日本国内の脆弱性情報届出受付公的機関:\r
66 //         独立行政法人 情報処理推進機構\r
67 //         http://www.ipa.go.jp/security/vuln/report/\r
68 // \r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/\r
71 \r
72 // -----------------------------------------------\r
73 // [ChangeLog]\r
74 // 2010.05.20\r
75 //  新規リリース by SoftEther\r
76 // -----------------------------------------------\r
77 \r
78 // Cedar.c\r
79 // Cedar 通信モジュールプログラムコード\r
80 \r
81 // Build 7101\r
82 \r
83 \r
84 #include "CedarPch.h"\r
85 \r
86 static UINT init_cedar_counter = 0;\r
87 static REF *cedar_log_ref = NULL;\r
88 static LOG *cedar_log;\r
89 \r
90 // 現在サポートされている Windows のバージョンかどうか取得する\r
91 // (以前、XP までしか想定していないコードを Vista (Longhorn) で動作させたときに\r
92 //  OS ごと大変おかしくなってしまったことがあるので、バージョンチェックは\r
93 //  必ず行うようにした。ただし、警告メッセージを画面に表示するだけであり、\r
94 //  動作は一応できるようにしている。)\r
95 bool IsSupportedWinVer(RPC_WINVER *v)\r
96 {\r
97         // 引数チェック\r
98         if (v == NULL)\r
99         {\r
100                 return false;\r
101         }\r
102 \r
103         if (v->IsWindows == false)\r
104         {\r
105                 return true;\r
106         }\r
107 \r
108         if (v->IsNT == false)\r
109         {\r
110                 return true;\r
111         }\r
112 \r
113         if (v->IsBeta)\r
114         {\r
115                 return true;\r
116         }\r
117 \r
118         if (v->VerMajor <= 4)\r
119         {\r
120                 // Windows NT\r
121                 return true;\r
122         }\r
123 \r
124         if (v->VerMajor == 5 && v->VerMinor == 0)\r
125         {\r
126                 // Windows 2000\r
127                 if (v->ServicePack <= 4)\r
128                 {\r
129                         // SP4 までサポート\r
130                         return true;\r
131                 }\r
132         }\r
133 \r
134         if (v->VerMajor == 5 && v->VerMinor == 1)\r
135         {\r
136                 // Windows XP x86\r
137                 if (v->ServicePack <= 3)\r
138                 {\r
139                         // SP3 までサポート\r
140                         return true;\r
141                 }\r
142         }\r
143 \r
144         if (v->VerMajor == 5 && v->VerMinor == 2)\r
145         {\r
146                 // Windows XP x64, Windows Server 2003\r
147                 if (v->ServicePack <= 2)\r
148                 {\r
149                         // SP2 までサポート\r
150                         return true;\r
151                 }\r
152         }\r
153 \r
154         if (v->VerMajor == 6 && v->VerMinor == 0)\r
155         {\r
156                 // Windows Vista, Server 2008\r
157                 if (v->ServicePack <= 2)\r
158                 {\r
159                         // SP2 までサポート\r
160                         return true;\r
161                 }\r
162         }\r
163 \r
164         if (v->VerMajor == 6 && v->VerMinor == 1)\r
165         {\r
166                 // Windows 7, Server 2008 R2\r
167                 if (v->ServicePack <= 0)\r
168                 {\r
169                         // SP0 までサポート\r
170                         return true;\r
171                 }\r
172         }\r
173 \r
174         return false;\r
175 }\r
176 \r
177 // Windows のバージョンを取得する\r
178 void GetWinVer(RPC_WINVER *v)\r
179 {\r
180         // 引数チェック\r
181         if (v == NULL)\r
182         {\r
183                 return;\r
184         }\r
185 \r
186 #ifdef  OS_WIN32\r
187         Win32GetWinVer(v);\r
188 #else   // OS_WIN32\r
189         Zero(v, sizeof(RPC_WINVER));\r
190         StrCpy(v->Title, sizeof(v->Title), GetOsInfo()->OsProductName);\r
191 #endif  // OS_WIN32\r
192 }\r
193 \r
194 // 簡易ログを閉じる\r
195 void FreeTinyLog(TINY_LOG *t)\r
196 {\r
197         // 引数チェック\r
198         if (t == NULL)\r
199         {\r
200                 return;\r
201         }\r
202 \r
203         FileClose(t->io);\r
204         DeleteLock(t->Lock);\r
205         Free(t);\r
206 }\r
207 \r
208 // 簡易ログの書き込み\r
209 void WriteTinyLog(TINY_LOG *t, char *str)\r
210 {\r
211         BUF *b;\r
212         char dt[MAX_PATH];\r
213         // 引数チェック\r
214         if (t == NULL)\r
215         {\r
216                 return;\r
217         }\r
218 \r
219         GetDateTimeStrMilli64(dt, sizeof(dt), LocalTime64());\r
220         StrCat(dt, sizeof(dt), ": ");\r
221 \r
222         b = NewBuf();\r
223 \r
224         WriteBuf(b, dt, StrLen(dt));\r
225         WriteBuf(b, str, StrLen(str));\r
226         WriteBuf(b, "\r\n", 2);\r
227 \r
228         Lock(t->Lock);\r
229         {\r
230                 FileWrite(t->io, b->Buf, b->Size);\r
231                 FileFlush(t->io);\r
232         }\r
233         Unlock(t->Lock);\r
234 \r
235         FreeBuf(b);\r
236 }\r
237 \r
238 // 簡易ログの初期化\r
239 TINY_LOG *NewTinyLog()\r
240 {\r
241         char name[MAX_PATH];\r
242         SYSTEMTIME st;\r
243         TINY_LOG *t;\r
244 \r
245         LocalTime(&st);\r
246 \r
247         MakeDir(TINY_LOG_DIRNAME);\r
248 \r
249         Format(name, sizeof(name), TINY_LOG_FILENAME,\r
250                 st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);\r
251 \r
252         t = ZeroMalloc(sizeof(TINY_LOG));\r
253 \r
254         StrCpy(t->FileName, sizeof(t->FileName), name);\r
255         t->io = FileCreate(name);\r
256         t->Lock = NewLock();\r
257 \r
258         return t;\r
259 }\r
260 \r
261 // 非 SSL リストのエントリの比較\r
262 int CompareNoSslList(void *p1, void *p2)\r
263 {\r
264         NON_SSL *n1, *n2;\r
265         if (p1 == NULL || p2 == NULL)\r
266         {\r
267                 return 0;\r
268         }\r
269         n1 = *(NON_SSL **)p1;\r
270         n2 = *(NON_SSL **)p2;\r
271         if (n1 == NULL || n2 == NULL)\r
272         {\r
273                 return 0;\r
274         }\r
275         return CmpIpAddr(&n1->IpAddress, &n2->IpAddress);\r
276 }\r
277 \r
278 // 指定された IP アドレスが非 SSL リストに存在するかどうかチェック\r
279 bool IsInNoSsl(CEDAR *c, IP *ip)\r
280 {\r
281         bool ret = false;\r
282         // 引数チェック\r
283         if (c == NULL || ip == NULL)\r
284         {\r
285                 return false;\r
286         }\r
287 \r
288         LockList(c->NonSslList);\r
289         {\r
290                 NON_SSL *n = SearchNoSslList(c, ip);\r
291 \r
292                 if (n != NULL)\r
293                 {\r
294                         if (n->EntryExpires > Tick64() && n->Count > NON_SSL_MIN_COUNT)\r
295                         {\r
296                                 n->EntryExpires = Tick64() + (UINT64)NON_SSL_ENTRY_EXPIRES;\r
297                                 ret = true;\r
298                         }\r
299                 }\r
300         }\r
301         UnlockList(c->NonSslList);\r
302 \r
303         return ret;\r
304 }\r
305 \r
306 // 非 SSL リストのエントリをデクリメント\r
307 void DecrementNoSsl(CEDAR *c, IP *ip, UINT num_dec)\r
308 {\r
309         // 引数チェック\r
310         if (c == NULL || ip == NULL)\r
311         {\r
312                 return;\r
313         }\r
314 \r
315         LockList(c->NonSslList);\r
316         {\r
317                 NON_SSL *n = SearchNoSslList(c, ip);\r
318 \r
319                 if (n != NULL)\r
320                 {\r
321                         if (n->Count >= num_dec)\r
322                         {\r
323                                 n->Count -= num_dec;\r
324                         }\r
325                 }\r
326         }\r
327         UnlockList(c->NonSslList);\r
328 }\r
329 \r
330 // 非 SSL リストにエントリを追加\r
331 bool AddNoSsl(CEDAR *c, IP *ip)\r
332 {\r
333         NON_SSL *n;\r
334         bool ret = true;\r
335         // 引数チェック\r
336         if (c == NULL || ip == NULL)\r
337         {\r
338                 return true;\r
339         }\r
340 \r
341         LockList(c->NonSslList);\r
342         {\r
343                 DeleteOldNoSsl(c);\r
344 \r
345                 n = SearchNoSslList(c, ip);\r
346 \r
347                 if (n == NULL)\r
348                 {\r
349                         n = ZeroMalloc(sizeof(NON_SSL));\r
350                         Copy(&n->IpAddress, ip, sizeof(IP));\r
351                         n->Count = 0;\r
352 \r
353                         Add(c->NonSslList, n);\r
354                 }\r
355 \r
356                 n->EntryExpires = Tick64() + (UINT64)NON_SSL_ENTRY_EXPIRES;\r
357 \r
358                 n->Count++;\r
359 \r
360                 if (n->Count > NON_SSL_MIN_COUNT)\r
361                 {\r
362                         ret = false;\r
363                 }\r
364         }\r
365         UnlockList(c->NonSslList);\r
366 \r
367         return ret;\r
368 }\r
369 \r
370 // 古い非 SSL リストの削除\r
371 void DeleteOldNoSsl(CEDAR *c)\r
372 {\r
373         UINT i;\r
374         LIST *o;\r
375         // 引数チェック\r
376         if (c == NULL)\r
377         {\r
378                 return;\r
379         }\r
380 \r
381         o = NewListFast(NULL);\r
382 \r
383         for (i = 0;i < LIST_NUM(c->NonSslList);i++)\r
384         {\r
385                 NON_SSL *n = LIST_DATA(c->NonSslList, i);\r
386 \r
387                 if (n->EntryExpires <= Tick64())\r
388                 {\r
389                         Add(o, n);\r
390                 }\r
391         }\r
392 \r
393         for (i = 0;i < LIST_NUM(o);i++)\r
394         {\r
395                 NON_SSL *n = LIST_DATA(o, i);\r
396 \r
397                 Delete(c->NonSslList, n);\r
398                 Free(n);\r
399         }\r
400 \r
401         ReleaseList(o);\r
402 }\r
403 \r
404 // 非 SSL リストの検索\r
405 NON_SSL *SearchNoSslList(CEDAR *c, IP *ip)\r
406 {\r
407         NON_SSL *n, t;\r
408         // 引数チェック\r
409         if (c == NULL || ip == NULL)\r
410         {\r
411                 return NULL;\r
412         }\r
413 \r
414         Zero(&t, sizeof(t));\r
415         Copy(&t.IpAddress, ip, sizeof(IP));\r
416 \r
417         n = Search(c->NonSslList, &t);\r
418 \r
419         if (n == NULL)\r
420         {\r
421                 return NULL;\r
422         }\r
423 \r
424         return n;\r
425 }\r
426 \r
427 // 非 SSL リストの初期化\r
428 void InitNoSslList(CEDAR *c)\r
429 {\r
430         // 引数チェック\r
431         if (c == NULL)\r
432         {\r
433                 return;\r
434         }\r
435 \r
436         c->NonSslList = NewList(CompareNoSslList);\r
437 }\r
438 \r
439 // 非 SSL リストの解放\r
440 void FreeNoSslList(CEDAR *c)\r
441 {\r
442         UINT i;\r
443         // 引数チェック\r
444         if (c == NULL)\r
445         {\r
446                 return;\r
447         }\r
448 \r
449         for (i = 0;i < LIST_NUM(c->NonSslList);i++)\r
450         {\r
451                 NON_SSL *n = LIST_DATA(c->NonSslList, i);\r
452 \r
453                 Free(n);\r
454         }\r
455 \r
456         ReleaseList(c->NonSslList);\r
457         c->NonSslList = NULL;\r
458 }\r
459 \r
460 // Cedar ログをとる\r
461 void CedarLog(char *str)\r
462 {\r
463         char *tmp;\r
464         // 引数チェック\r
465         if (str == NULL)\r
466         {\r
467                 return;\r
468         }\r
469         if (cedar_log_ref == NULL)\r
470         {\r
471                 return;\r
472         }\r
473 \r
474         tmp = CopyStr(str);\r
475 \r
476         // このあたりは急いで実装したのでコードがあまり美しくない。\r
477         if (StrLen(tmp) > 1)\r
478         {\r
479                 if (tmp[StrLen(tmp) - 1] == '\n')\r
480                 {\r
481                         tmp[StrLen(tmp) - 1] = 0;\r
482                 }\r
483                 if (StrLen(tmp) > 1)\r
484                 {\r
485                         if (tmp[StrLen(tmp) - 1] == '\r')\r
486                         {\r
487                                 tmp[StrLen(tmp) - 1] = 0;\r
488                         }\r
489                 }\r
490         }\r
491 \r
492         InsertStringRecord(cedar_log, tmp);\r
493 \r
494         Free(tmp);\r
495 }\r
496 \r
497 // ログを開始する\r
498 void StartCedarLog()\r
499 {\r
500         if (cedar_log_ref == NULL)\r
501         {\r
502                 cedar_log_ref = NewRef();\r
503         }\r
504         else\r
505         {\r
506                 AddRef(cedar_log_ref);\r
507         }\r
508 \r
509         cedar_log = NewLog("debug_log", "debug", LOG_SWITCH_DAY);\r
510 }\r
511 \r
512 // ログを停止する\r
513 void StopCedarLog()\r
514 {\r
515         if (cedar_log_ref == NULL)\r
516         {\r
517                 return;\r
518         }\r
519 \r
520         if (Release(cedar_log_ref) == 0)\r
521         {\r
522                 FreeLog(cedar_log);\r
523                 cedar_log = NULL;\r
524                 cedar_log_ref = NULL;\r
525         }\r
526 }\r
527 \r
528 // トラフィックのパケットサイズを取得する\r
529 UINT64 GetTrafficPacketSize(TRAFFIC *t)\r
530 {\r
531         // 引数チェック\r
532         if (t == NULL)\r
533         {\r
534                 return 0;\r
535         }\r
536 \r
537         return t->Recv.BroadcastBytes + t->Recv.UnicastBytes +\r
538                 t->Send.BroadcastBytes + t->Send.UnicastBytes;\r
539 }\r
540 \r
541 // トラフィックのパケット数を取得する\r
542 UINT64 GetTrafficPacketNum(TRAFFIC *t)\r
543 {\r
544         // 引数チェック\r
545         if (t == NULL)\r
546         {\r
547                 return 0;\r
548         }\r
549 \r
550         return t->Recv.BroadcastCount + t->Recv.UnicastCount +\r
551                 t->Send.BroadcastCount + t->Send.UnicastCount;\r
552 }\r
553 \r
554 // 非表示パスワードの内容が変更されたかどうかチェックする\r
555 bool IsHiddenPasswordChanged(char *str)\r
556 {\r
557         // 引数チェック\r
558         if (str == NULL)\r
559         {\r
560                 return true;\r
561         }\r
562 \r
563         if (StrCmpi(str, HIDDEN_PASSWORD) == 0)\r
564         {\r
565                 return true;\r
566         }\r
567         else\r
568         {\r
569                 return false;\r
570         }\r
571 }\r
572 \r
573 // 非表示パスワードを初期化する\r
574 void InitHiddenPassword(char *str, UINT size)\r
575 {\r
576         // 引数チェック\r
577         if (str == NULL)\r
578         {\r
579                 return;\r
580         }\r
581 \r
582         StrCpy(str, size, HIDDEN_PASSWORD);\r
583 }\r
584 \r
585 // 証明書が仮想 HUB に登録されている CA によって署名されているかどうか確認する\r
586 bool CheckSignatureByCaLinkMode(SESSION *s, X *x)\r
587 {\r
588         LINK *k;\r
589         HUB *h;\r
590         bool ret = false;\r
591         // 引数チェック\r
592         if (s == NULL || x == NULL)\r
593         {\r
594                 return false;\r
595         }\r
596 \r
597         if (s->LinkModeClient == false || (k = s->Link) == NULL)\r
598         {\r
599                 return false;\r
600         }\r
601 \r
602         h = k->Hub;\r
603 \r
604         if (h->HubDb != NULL)\r
605         {\r
606                 LockList(h->HubDb->RootCertList);\r
607                 {\r
608                         X *root_cert;\r
609                         root_cert = GetIssuerFromList(h->HubDb->RootCertList, x);\r
610                         if (root_cert != NULL)\r
611                         {\r
612                                 ret = true;\r
613                         }\r
614                 }\r
615                 UnlockList(h->HubDb->RootCertList);\r
616         }\r
617 \r
618         return ret;\r
619 }\r
620 \r
621 // 証明書が Cedar に登録されている CA によって署名されているかどうか確認する\r
622 bool CheckSignatureByCa(CEDAR *cedar, X *x)\r
623 {\r
624         X *ca;\r
625         // 引数チェック\r
626         if (cedar == NULL || x == NULL)\r
627         {\r
628                 return false;\r
629         }\r
630 \r
631         // 指定された証明書を署名した CA を取得\r
632         ca = FindCaSignedX(cedar->CaList, x);\r
633         if (ca == NULL)\r
634         {\r
635                 // 発見できなかった\r
636                 return false;\r
637         }\r
638 \r
639         // 発見した\r
640         FreeX(ca);\r
641         return true;\r
642 }\r
643 \r
644 // 指定された証明書を署名した CA を取得\r
645 X *FindCaSignedX(LIST *o, X *x)\r
646 {\r
647         X *ret;\r
648         // 引数チェック\r
649         if (o == NULL || x == NULL)\r
650         {\r
651                 return NULL;\r
652         }\r
653 \r
654         ret = NULL;\r
655 \r
656         LockList(o);\r
657         {\r
658                 UINT i;\r
659                 for (i = 0;i < LIST_NUM(o);i++)\r
660                 {\r
661                         X *ca = LIST_DATA(o, i);\r
662                         if (CheckXDateNow(ca))\r
663                         {\r
664                                 if (CompareName(ca->subject_name, x->issuer_name))\r
665                                 {\r
666                                         K *k = GetKFromX(ca);\r
667                                         if (k != NULL)\r
668                                         {\r
669                                                 if (CheckSignature(x, k))\r
670                                                 {\r
671                                                         ret = CloneX(ca);\r
672                                                 }\r
673                                                 FreeK(k);\r
674                                         }\r
675                                 }\r
676                                 else if (CompareX(ca, x))\r
677                                 {\r
678                                         ret = CloneX(ca);\r
679                                 }\r
680                         }\r
681 \r
682                         if (ret != NULL)\r
683                         {\r
684                                 break;\r
685                         }\r
686                 }\r
687         }\r
688         UnlockList(o);\r
689 \r
690         return ret;\r
691 }\r
692 \r
693 // Cedar から CA を削除する\r
694 bool DeleteCa(CEDAR *cedar, UINT ptr)\r
695 {\r
696         bool b = false;\r
697         // 引数チェック\r
698         if (cedar == NULL || ptr == 0)\r
699         {\r
700                 return false;\r
701         }\r
702 \r
703         LockList(cedar->CaList);\r
704         {\r
705                 UINT i;\r
706 \r
707                 for (i = 0;i < LIST_NUM(cedar->CaList);i++)\r
708                 {\r
709                         X *x = LIST_DATA(cedar->CaList, i);\r
710 \r
711                         if (POINTER_TO_KEY(x) == ptr)\r
712                         {\r
713                                 Delete(cedar->CaList, x);\r
714                                 FreeX(x);\r
715 \r
716                                 b = true;\r
717 \r
718                                 break;\r
719                         }\r
720                 }\r
721         }\r
722         UnlockList(cedar->CaList);\r
723 \r
724         return b;\r
725 }\r
726 \r
727 // Cedar に CA を追加する\r
728 void AddCa(CEDAR *cedar, X *x)\r
729 {\r
730         // 引数チェック\r
731         if (cedar == NULL || x == NULL)\r
732         {\r
733                 return;\r
734         }\r
735 \r
736         LockList(cedar->CaList);\r
737         {\r
738                 UINT i;\r
739                 bool ok = true;\r
740 \r
741                 for (i = 0;i < LIST_NUM(cedar->CaList);i++)\r
742                 {\r
743                         X *exist_x = LIST_DATA(cedar->CaList, i);\r
744                         if (CompareX(exist_x, x))\r
745                         {\r
746                                 ok = false;\r
747                                 break;\r
748                         }\r
749                 }\r
750 \r
751                 if (ok)\r
752                 {\r
753                         Insert(cedar->CaList, CloneX(x));\r
754                 }\r
755         }\r
756         UnlockList(cedar->CaList);\r
757 }\r
758 \r
759 // Cedar からコネクションを削除する\r
760 void DelConnection(CEDAR *cedar, CONNECTION *c)\r
761 {\r
762         // 引数チェック\r
763         if (cedar == NULL || c == NULL)\r
764         {\r
765                 return;\r
766         }\r
767 \r
768         LockList(cedar->ConnectionList);\r
769         {\r
770                 Debug("Connection %s Deleted from Cedar.\n", c->Name);\r
771                 if (Delete(cedar->ConnectionList, c))\r
772                 {\r
773                         ReleaseConnection(c);\r
774                 }\r
775         }\r
776         UnlockList(cedar->ConnectionList);\r
777 }\r
778 \r
779 // 現在の未確立コネクション数を取得する\r
780 UINT GetUnestablishedConnections(CEDAR *cedar)\r
781 {\r
782         UINT i, ret;\r
783         // 引数チェック\r
784         if (cedar == NULL)\r
785         {\r
786                 return 0;\r
787         }\r
788 \r
789         ret = 0;\r
790 \r
791         LockList(cedar->ConnectionList);\r
792         {\r
793                 for (i = 0;i < LIST_NUM(cedar->ConnectionList);i++)\r
794                 {\r
795                         CONNECTION *c = LIST_DATA(cedar->ConnectionList, i);\r
796 \r
797                         switch (c->Type)\r
798                         {\r
799                         case CONNECTION_TYPE_CLIENT:\r
800                         case CONNECTION_TYPE_INIT:\r
801                         case CONNECTION_TYPE_LOGIN:\r
802                         case CONNECTION_TYPE_ADDITIONAL:\r
803                                 switch (c->Status)\r
804                                 {\r
805                                 case CONNECTION_STATUS_ACCEPTED:\r
806                                 case CONNECTION_STATUS_NEGOTIATION:\r
807                                 case CONNECTION_STATUS_USERAUTH:\r
808                                         ret++;\r
809                                         break;\r
810                                 }\r
811                                 break;\r
812                         }\r
813                 }\r
814         }\r
815         UnlockList(cedar->ConnectionList);\r
816 \r
817         return ret + Count(cedar->AcceptingSockets);\r
818 }\r
819 \r
820 // Cedar にコネクションを追加する\r
821 void AddConnection(CEDAR *cedar, CONNECTION *c)\r
822 {\r
823         char tmp[MAX_SIZE];\r
824         UINT i;\r
825         // 引数チェック\r
826         if (cedar == NULL || c == NULL)\r
827         {\r
828                 return;\r
829         }\r
830 \r
831         //新しいコネクションの名前を決定する\r
832         i = Inc(cedar->ConnectionIncrement);\r
833         Format(tmp, sizeof(tmp), "CID-%u", i);\r
834         Lock(c->lock);\r
835         {\r
836                 Free(c->Name);\r
837                 c->Name = CopyStr(tmp);\r
838         }\r
839         Unlock(c->lock);\r
840 \r
841         LockList(cedar->ConnectionList);\r
842         {\r
843                 Add(cedar->ConnectionList, c);\r
844                 AddRef(c->ref);\r
845                 Debug("Connection %s Inserted to Cedar.\n", c->Name);\r
846         }\r
847         UnlockList(cedar->ConnectionList);\r
848 }\r
849 \r
850 // すべてのコネクションを停止\r
851 void StopAllConnection(CEDAR *c)\r
852 {\r
853         UINT num;\r
854         UINT i;\r
855         CONNECTION **connections;\r
856         // 引数チェック\r
857         if (c == NULL)\r
858         {\r
859                 return;\r
860         }\r
861 \r
862         LockList(c->ConnectionList);\r
863         {\r
864                 connections = ToArray(c->ConnectionList);\r
865                 num = LIST_NUM(c->ConnectionList);\r
866                 DeleteAll(c->ConnectionList);\r
867         }\r
868         UnlockList(c->ConnectionList);\r
869 \r
870         for (i = 0;i < num;i++)\r
871         {\r
872                 StopConnection(connections[i], false);\r
873                 ReleaseConnection(connections[i]);\r
874         }\r
875         Free(connections);\r
876 }\r
877 \r
878 // CEDAR から HUB を削除\r
879 void DelHub(CEDAR *c, HUB *h)\r
880 {\r
881         DelHubEx(c, h, false);\r
882 }\r
883 void DelHubEx(CEDAR *c, HUB *h, bool no_lock)\r
884 {\r
885         // 引数チェック\r
886         if (c == NULL || h == NULL)\r
887         {\r
888                 return;\r
889         }\r
890 \r
891         if (no_lock == false)\r
892         {\r
893                 LockHubList(c);\r
894         }\r
895 \r
896         if (Delete(c->HubList, h))\r
897         {\r
898                 ReleaseHub(h);\r
899         }\r
900 \r
901         if (no_lock == false)\r
902         {\r
903                 UnlockHubList(c);\r
904         }\r
905 }\r
906 \r
907 // CEDAR に HUB を追加\r
908 void AddHub(CEDAR *c, HUB *h)\r
909 {\r
910         // 引数チェック\r
911         if (c == NULL || h == NULL)\r
912         {\r
913                 return;\r
914         }\r
915 \r
916         LockHubList(c);\r
917         {\r
918 #if     0\r
919                 // HUB 数はここではチェックしないことにする\r
920                 if (LIST_NUM(c->HubList) >= MAX_HUBS)\r
921                 {\r
922                         // 上限数超過\r
923                         UnlockHubList(c);\r
924                         return;\r
925                 }\r
926 #endif\r
927 \r
928                 // 同一名の HUB が存在しないかどうかチェック\r
929                 if (IsHub(c, h->Name))\r
930                 {\r
931                         // 存在する\r
932                         UnlockHubList(c);\r
933                         return;\r
934                 }\r
935 \r
936                 // HUB を登録する\r
937                 Insert(c->HubList, h);\r
938                 AddRef(h->ref);\r
939         }\r
940         UnlockHubList(c);\r
941 }\r
942 \r
943 // CEDAR のすべての HUB を停止\r
944 void StopAllHub(CEDAR *c)\r
945 {\r
946         HUB **hubs;\r
947         UINT i, num;\r
948         // 引数チェック\r
949         if (c == NULL)\r
950         {\r
951                 return;\r
952         }\r
953 \r
954         LockHubList(c);\r
955         {\r
956                 hubs = ToArray(c->HubList);\r
957                 num = LIST_NUM(c->HubList);\r
958                 DeleteAll(c->HubList);\r
959         }\r
960         UnlockHubList(c);\r
961 \r
962         for (i = 0;i < num;i++)\r
963         {\r
964                 StopHub(hubs[i]);\r
965                 ReleaseHub(hubs[i]);\r
966         }\r
967 \r
968         Free(hubs);\r
969 }\r
970 \r
971 // CEDAR にリスナーを追加\r
972 void AddListener(CEDAR *c, LISTENER *r)\r
973 {\r
974         // 引数チェック\r
975         if (c == NULL || r == NULL)\r
976         {\r
977                 return;\r
978         }\r
979 \r
980         LockList(c->ListenerList);\r
981         {\r
982                 Add(c->ListenerList, r);\r
983                 AddRef(r->ref);\r
984         }\r
985         UnlockList(c->ListenerList);\r
986 }\r
987 \r
988 // CEDAR のすべてのリスナーを停止\r
989 void StopAllListener(CEDAR *c)\r
990 {\r
991         LISTENER **array;\r
992         UINT i, num;\r
993         // 引数チェック\r
994         if (c == NULL)\r
995         {\r
996                 return;\r
997         }\r
998 \r
999         LockList(c->ListenerList);\r
1000         {\r
1001                 array = ToArray(c->ListenerList);\r
1002                 num = LIST_NUM(c->ListenerList);\r
1003                 DeleteAll(c->ListenerList);\r
1004         }\r
1005         UnlockList(c->ListenerList);\r
1006 \r
1007         for (i = 0;i < num;i++)\r
1008         {\r
1009                 StopListener(array[i]);\r
1010                 ReleaseListener(array[i]);\r
1011         }\r
1012         Free(array);\r
1013 }\r
1014 \r
1015 // CEDAR の停止\r
1016 void StopCedar(CEDAR *c)\r
1017 {\r
1018         // 引数チェック\r
1019         if (c == NULL)\r
1020         {\r
1021                 return;\r
1022         }\r
1023 \r
1024         // 停止フラグ\r
1025         c->Halt = true;\r
1026 \r
1027         // すべてのリスナーを停止\r
1028         StopAllListener(c);\r
1029         // すべてのコネクションを停止\r
1030         StopAllConnection(c);\r
1031         // すべての HUB を停止\r
1032         StopAllHub(c);\r
1033         // すべての L3 スイッチを解放\r
1034         L3FreeAllSw(c);\r
1035 }\r
1036 \r
1037 // CEDAR のクリーンアップ\r
1038 void CleanupCedar(CEDAR *c)\r
1039 {\r
1040         UINT i;\r
1041         // 引数チェック\r
1042         if (c == NULL)\r
1043         {\r
1044                 return;\r
1045         }\r
1046 \r
1047         FreeCedarLayer3(c);\r
1048 \r
1049 /*\r
1050         for (i = 0;i < LIST_NUM(c->HubList);i++)\r
1051         {\r
1052                 HUB *h = LIST_DATA(c->HubList, i);\r
1053         }\r
1054 */\r
1055         for (i = 0;i < LIST_NUM(c->CaList);i++)\r
1056         {\r
1057                 X *x = LIST_DATA(c->CaList, i);\r
1058                 FreeX(x);\r
1059         }\r
1060         ReleaseList(c->CaList);\r
1061 \r
1062         ReleaseList(c->ListenerList);\r
1063         ReleaseList(c->HubList);\r
1064         ReleaseList(c->ConnectionList);\r
1065         //CleanupUDPEntry(c);\r
1066         ReleaseList(c->UDPEntryList);\r
1067         DeleteLock(c->lock);\r
1068         DeleteCounter(c->ConnectionIncrement);\r
1069         DeleteCounter(c->CurrentSessions);\r
1070 \r
1071         if (c->DebugLog != NULL)\r
1072         {\r
1073                 FreeLog(c->DebugLog);\r
1074         }\r
1075 \r
1076         if (c->ServerX)\r
1077         {\r
1078                 FreeX(c->ServerX);\r
1079         }\r
1080         if (c->ServerK)\r
1081         {\r
1082                 FreeK(c->ServerK);\r
1083         }\r
1084 \r
1085         if (c->CipherList)\r
1086         {\r
1087                 Free(c->CipherList);\r
1088         }\r
1089 \r
1090         for (i = 0;i < LIST_NUM(c->TrafficDiffList);i++)\r
1091         {\r
1092                 TRAFFIC_DIFF *d = LIST_DATA(c->TrafficDiffList, i);\r
1093                 Free(d->Name);\r
1094                 Free(d->HubName);\r
1095                 Free(d);\r
1096         }\r
1097 \r
1098         ReleaseList(c->TrafficDiffList);\r
1099 \r
1100         Free(c->ServerStr);\r
1101         Free(c->MachineName);\r
1102 \r
1103         Free(c->HttpUserAgent);\r
1104         Free(c->HttpAccept);\r
1105         Free(c->HttpAcceptLanguage);\r
1106         Free(c->HttpAcceptEncoding);\r
1107 \r
1108         FreeTraffic(c->Traffic);\r
1109 \r
1110         DeleteLock(c->TrafficLock);\r
1111 \r
1112         FreeNetSvcList(c);\r
1113 \r
1114         Free(c->VerString);\r
1115         Free(c->BuildInfo);\r
1116 \r
1117         FreeLocalBridgeList(c);\r
1118 \r
1119         DeleteCounter(c->AssignedBridgeLicense);\r
1120         DeleteCounter(c->AssignedClientLicense);\r
1121 \r
1122         FreeNoSslList(c);\r
1123 \r
1124         DeleteLock(c->CedarSuperLock);\r
1125 \r
1126         DeleteCounter(c->AcceptingSockets);\r
1127 \r
1128         Free(c);\r
1129 }\r
1130 \r
1131 // CEDAR の解放\r
1132 void ReleaseCedar(CEDAR *c)\r
1133 {\r
1134         // 引数チェック\r
1135         if (c == NULL)\r
1136         {\r
1137                 return;\r
1138         }\r
1139 \r
1140         if (Release(c->ref) == 0)\r
1141         {\r
1142                 CleanupCedar(c);\r
1143         }\r
1144 }\r
1145 \r
1146 // CipherList のセット\r
1147 void SetCedarCipherList(CEDAR *cedar, char *name)\r
1148 {\r
1149         // 引数チェック\r
1150         if (cedar == NULL)\r
1151         {\r
1152                 return;\r
1153         }\r
1154 \r
1155         if (cedar->CipherList != NULL)\r
1156         {\r
1157                 Free(cedar->CipherList);\r
1158         }\r
1159         if (name != NULL)\r
1160         {\r
1161                 cedar->CipherList = CopyStr(name);\r
1162         }\r
1163         else\r
1164         {\r
1165                 cedar->CipherList = NULL;\r
1166         }\r
1167 }\r
1168 \r
1169 // ネットサービスリストのソート\r
1170 int CompareNetSvc(void *p1, void *p2)\r
1171 {\r
1172         NETSVC *n1, *n2;\r
1173         if (p1 == NULL || p2 == NULL)\r
1174         {\r
1175                 return 0;\r
1176         }\r
1177         n1 = *(NETSVC **)p1;\r
1178         n2 = *(NETSVC **)p2;\r
1179         if (n1 == NULL || n2 == NULL)\r
1180         {\r
1181                 return 0;\r
1182         }\r
1183         if (n1->Port > n2->Port)\r
1184         {\r
1185                 return 1;\r
1186         }\r
1187         else if (n1->Port < n2->Port)\r
1188         {\r
1189                 return -1;\r
1190         }\r
1191         else if (n1->Udp > n2->Udp)\r
1192         {\r
1193                 return 1;\r
1194         }\r
1195         else if (n1->Udp < n2->Udp)\r
1196         {\r
1197                 return -1;\r
1198         }\r
1199         return 0;\r
1200 }\r
1201 \r
1202 // ネットサービスリストの初期化\r
1203 void InitNetSvcList(CEDAR *cedar)\r
1204 {\r
1205         char filename[MAX_PATH] = "/etc/services";\r
1206         BUF *b;\r
1207         // 引数チェック\r
1208         if (cedar == NULL)\r
1209         {\r
1210                 return;\r
1211         }\r
1212 \r
1213 #ifdef  OS_WIN32\r
1214         // 自力でがんばって読む\r
1215         Format(filename, sizeof(filename), "%s\\drivers\\etc\\services", MsGetSystem32Dir());\r
1216 #endif\r
1217 \r
1218         cedar->NetSvcList = NewList(CompareNetSvc);\r
1219 \r
1220         b = ReadDump(filename);\r
1221         if (b == NULL)\r
1222         {\r
1223                 return;\r
1224         }\r
1225 \r
1226         while (true)\r
1227         {\r
1228                 char *s = CfgReadNextLine(b);\r
1229                 if (s == NULL)\r
1230                 {\r
1231                         break;\r
1232                 }\r
1233 \r
1234                 Trim(s);\r
1235                 if (s[0] != '#')\r
1236                 {\r
1237                         TOKEN_LIST *t = ParseToken(s, " \t/");\r
1238                         if (t->NumTokens >= 3)\r
1239                         {\r
1240                                 NETSVC *n = ZeroMalloc(sizeof(NETSVC));\r
1241                                 n->Name = CopyStr(t->Token[0]);\r
1242                                 n->Udp = (StrCmpi(t->Token[2], "udp") == 0 ? true : false);\r
1243                                 n->Port = ToInt(t->Token[1]);\r
1244                                 Add(cedar->NetSvcList, n);\r
1245                         }\r
1246                         FreeToken(t);\r
1247                 }\r
1248                 Free(s);\r
1249         }\r
1250 \r
1251         FreeBuf(b);\r
1252 }\r
1253 \r
1254 // ネットサービス名の取得\r
1255 char *GetSvcName(CEDAR *cedar, bool udp, UINT port)\r
1256 {\r
1257         char *ret = NULL;\r
1258         NETSVC t;\r
1259         // 引数チェック\r
1260         if (cedar == NULL)\r
1261         {\r
1262                 return NULL;\r
1263         }\r
1264 \r
1265         t.Udp = (udp == 0 ? false : true);\r
1266         t.Port = port;\r
1267 \r
1268         LockList(cedar->NetSvcList);\r
1269         {\r
1270                 NETSVC *n = Search(cedar->NetSvcList, &t);\r
1271                 if (n != NULL)\r
1272                 {\r
1273                         ret = n->Name;\r
1274                 }\r
1275         }\r
1276         UnlockList(cedar->NetSvcList);\r
1277 \r
1278         return ret;\r
1279 }\r
1280 \r
1281 // ネットサービスリストの解放\r
1282 void FreeNetSvcList(CEDAR *cedar)\r
1283 {\r
1284         UINT i;\r
1285         // 引数チェック\r
1286         if (cedar == NULL)\r
1287         {\r
1288                 return;\r
1289         }\r
1290 \r
1291         for (i = 0;i < LIST_NUM(cedar->NetSvcList);i++)\r
1292         {\r
1293                 NETSVC *n = LIST_DATA(cedar->NetSvcList, i);\r
1294                 Free(n->Name);\r
1295                 Free(n);\r
1296         }\r
1297         ReleaseList(cedar->NetSvcList);\r
1298 }\r
1299 \r
1300 // CEDAR の証明書の変更\r
1301 void SetCedarCert(CEDAR *c, X *server_x, K *server_k)\r
1302 {\r
1303         // 引数チェック\r
1304         if (server_x == NULL || server_k == NULL)\r
1305         {\r
1306                 return;\r
1307         }\r
1308 \r
1309         Lock(c->lock);\r
1310         {\r
1311                 if (c->ServerX != NULL)\r
1312                 {\r
1313                         FreeX(c->ServerX);\r
1314                 }\r
1315 \r
1316                 if (c->ServerK != NULL)\r
1317                 {\r
1318                         FreeK(c->ServerK);\r
1319                 }\r
1320 \r
1321                 c->ServerX = CloneX(server_x);\r
1322                 c->ServerK = CloneK(server_k);\r
1323         }\r
1324         Unlock(c->lock);\r
1325 }\r
1326 \r
1327 // デバッグログを有効にする\r
1328 void EnableDebugLog(CEDAR *c)\r
1329 {\r
1330         // 引数チェック\r
1331         if (c == NULL || c->DebugLog != NULL)\r
1332         {\r
1333                 return;\r
1334         }\r
1335 \r
1336         c->DebugLog = NewLog("cedar_debug_log", "cedar", LOG_SWITCH_NO);\r
1337 }\r
1338 \r
1339 // CEDAR を VPN Bridge にする\r
1340 void SetCedarVpnBridge(CEDAR *c)\r
1341 {\r
1342         // 引数チェック\r
1343         if (c == NULL)\r
1344         {\r
1345                 return;\r
1346         }\r
1347 \r
1348         c->Bridge = true;\r
1349 \r
1350         Free(c->ServerStr);\r
1351         c->ServerStr = CopyStr(CEDAR_BRIDGE_STR);\r
1352 }\r
1353 \r
1354 // CEDAR の作成\r
1355 CEDAR *NewCedar(X *server_x, K *server_k)\r
1356 {\r
1357         CEDAR *c;\r
1358         char tmp[MAX_SIZE];\r
1359         char tmp2[MAX_SIZE];\r
1360         char *beta_str;\r
1361 \r
1362         c = ZeroMalloc(sizeof(CEDAR));\r
1363 \r
1364         c->AcceptingSockets = NewCounter();\r
1365 \r
1366         c->CedarSuperLock = NewLock();\r
1367 \r
1368 #ifdef  BETA_NUMBER\r
1369         c->Beta = BETA_NUMBER;\r
1370 #endif  // BETA_NUMBER\r
1371 \r
1372         InitNoSslList(c);\r
1373 \r
1374         c->AssignedBridgeLicense = NewCounter();\r
1375         c->AssignedClientLicense = NewCounter();\r
1376 \r
1377         Rand(c->UniqueId, sizeof(c->UniqueId));\r
1378 \r
1379         c->CreatedTick = Tick64();\r
1380 \r
1381         c->lock = NewLock();\r
1382         c->ref = NewRef();\r
1383 \r
1384         c->CurrentTcpConnections = GetNumTcpConnectionsCounter();\r
1385 \r
1386         c->ListenerList = NewList(CompareListener);\r
1387         c->UDPEntryList = NewList(CompareUDPEntry);\r
1388         c->HubList = NewList(CompareHub);\r
1389         c->ConnectionList = NewList(CompareConnection);\r
1390 \r
1391         c->ConnectionIncrement = NewCounter();\r
1392         c->CurrentSessions = NewCounter();\r
1393 \r
1394         if (server_k && server_x)\r
1395         {\r
1396                 c->ServerK = CloneK(server_k);\r
1397                 c->ServerX = CloneX(server_x);\r
1398         }\r
1399 \r
1400         c->Version = CEDAR_VER;\r
1401         c->Build = CEDAR_BUILD;\r
1402         c->ServerStr = CopyStr(CEDAR_SERVER_STR);\r
1403 \r
1404         GetMachineName(tmp, sizeof(tmp));\r
1405         c->MachineName = CopyStr(tmp);\r
1406 \r
1407         c->HttpUserAgent = CopyStr(DEFAULT_USER_AGENT);\r
1408         c->HttpAccept = CopyStr(DEFAULT_ACCEPT);\r
1409         c->HttpAcceptLanguage = CopyStr("ja");\r
1410         c->HttpAcceptEncoding = CopyStr(DEFAULT_ENCODING);\r
1411 \r
1412         c->Traffic = NewTraffic();\r
1413         c->TrafficLock = NewLock();\r
1414         c->CaList = NewList(CompareCert);\r
1415 \r
1416         c->TrafficDiffList = NewList(NULL);\r
1417 \r
1418         SetCedarCipherList(c, "RC4-MD5");\r
1419 \r
1420         c->ClientId = _II("CLIENT_ID");\r
1421 \r
1422         InitNetSvcList(c);\r
1423 \r
1424         InitLocalBridgeList(c);\r
1425 \r
1426         InitCedarLayer3(c);\r
1427 \r
1428 #ifdef  ALPHA_VERSION\r
1429         beta_str = "Alpha";\r
1430 #else   // ALPHA_VERSION\r
1431         beta_str = "Release Candidate";\r
1432 #endif  // ALPHA_VERSION\r
1433 \r
1434         ToStr(tmp2, c->Beta);\r
1435 \r
1436         Format(tmp, sizeof(tmp), "Version %u.%02u Build %u %s %s (%s)",\r
1437                 CEDAR_VER / 100, CEDAR_VER - (CEDAR_VER / 100) * 100,\r
1438                 CEDAR_BUILD,\r
1439                 c->Beta == 0 ? "" : beta_str,\r
1440                 c->Beta == 0 ? "" : tmp2,\r
1441                 _SS("LANGSTR"));\r
1442         Trim(tmp);\r
1443 \r
1444         if (true)\r
1445         {\r
1446                 SYSTEMTIME st;\r
1447                 Zero(&st, sizeof(st));\r
1448 \r
1449                 st.wYear = BUILD_DATE_Y;\r
1450                 st.wMonth = BUILD_DATE_M;\r
1451                 st.wDay = BUILD_DATE_D;\r
1452 \r
1453                 c->BuiltDate = SystemToUINT64(&st);\r
1454         }\r
1455 \r
1456         c->VerString = CopyStr(tmp);\r
1457 \r
1458         Format(tmp, sizeof(tmp), "Compiled %04u/%02u/%02u %02u:%02u:%02u by %s at %s",\r
1459                 BUILD_DATE_Y, BUILD_DATE_M, BUILD_DATE_D, BUILD_DATE_HO, BUILD_DATE_MI, BUILD_DATE_SE, BUILDER_NAME, BUILD_PLACE);\r
1460 \r
1461         c->BuildInfo = CopyStr(tmp);\r
1462 \r
1463         return c;\r
1464 }\r
1465 \r
1466 // 指定した日付よりも遅い日付にビルドされたものであるかどうか取得\r
1467 bool IsLaterBuild(CEDAR *c, UINT64 t)\r
1468 {\r
1469         SYSTEMTIME sb, st;\r
1470         UINT64 b;\r
1471         // 引数チェック\r
1472         if (c == NULL)\r
1473         {\r
1474                 return false;\r
1475         }\r
1476 \r
1477         Zero(&sb, sizeof(sb));\r
1478         Zero(&st, sizeof(st));\r
1479 \r
1480         UINT64ToSystem(&sb, c->BuiltDate);\r
1481         UINT64ToSystem(&st, t);\r
1482 \r
1483         // 時刻データを無視\r
1484         sb.wHour = sb.wMinute = sb.wSecond = sb.wMilliseconds = 0;\r
1485         st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;\r
1486 \r
1487         b = SystemToUINT64(&sb);\r
1488         t = SystemToUINT64(&st);\r
1489 \r
1490         if (b > t)\r
1491         {\r
1492                 return true;\r
1493         }\r
1494         else\r
1495         {\r
1496                 return false;\r
1497         }\r
1498 }\r
1499 \r
1500 // トラフィック情報の加算\r
1501 void AddTraffic(TRAFFIC *dst, TRAFFIC *diff)\r
1502 {\r
1503         // 引数チェック\r
1504         if (dst == NULL || diff == NULL)\r
1505         {\r
1506                 return;\r
1507         }\r
1508 \r
1509         dst->Recv.BroadcastBytes += diff->Recv.BroadcastBytes;\r
1510         dst->Recv.BroadcastCount += diff->Recv.BroadcastCount;\r
1511         dst->Recv.UnicastBytes += diff->Recv.UnicastBytes;\r
1512         dst->Recv.UnicastCount += diff->Recv.UnicastCount;\r
1513 \r
1514         dst->Send.BroadcastBytes += diff->Send.BroadcastBytes;\r
1515         dst->Send.BroadcastCount += diff->Send.BroadcastCount;\r
1516         dst->Send.UnicastBytes += diff->Send.UnicastBytes;\r
1517         dst->Send.UnicastCount += diff->Send.UnicastCount;\r
1518 }\r
1519 \r
1520 // トラフィック情報の作成\r
1521 TRAFFIC *NewTraffic()\r
1522 {\r
1523         TRAFFIC *t;\r
1524 \r
1525         // メモリ確保\r
1526         t = ZeroMalloc(sizeof(TRAFFIC));\r
1527         return t;\r
1528 }\r
1529 \r
1530 // トラフィック情報の解放\r
1531 void FreeTraffic(TRAFFIC *t)\r
1532 {\r
1533         // 引数チェック\r
1534         if (t == NULL)\r
1535         {\r
1536                 return;\r
1537         }\r
1538 \r
1539         // メモリ解放\r
1540         Free(t);\r
1541 }\r
1542 \r
1543 // Cedar 通信モジュールの初期化\r
1544 void InitCedar()\r
1545 {\r
1546         if ((init_cedar_counter++) > 0)\r
1547         {\r
1548                 return;\r
1549         }\r
1550 \r
1551         // プロトコル初期化\r
1552         InitProtocol();\r
1553 }\r
1554 \r
1555 // Cedar 通信モジュールの解放\r
1556 void FreeCedar()\r
1557 {\r
1558         if ((--init_cedar_counter) > 0)\r
1559         {\r
1560                 return;\r
1561         }\r
1562 \r
1563         // プロトコル解放\r
1564         FreeProtocol();\r
1565 }\r
1566 \r