source: lab.git/Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Network.c @ b14ab8e

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

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

  • Property mode set to 100644
File size: 170.5 KB
Line 
1// SoftEther UT-VPN SourceCode
2//
3// Copyright (C) 2004-2010 SoftEther Corporation.
4// Copyright (C) 2004-2010 University of Tsukuba, Japan.
5// Copyright (C) 2003-2010 Daiyuu Nobori.
6// All Rights Reserved.
7//
8// http://utvpn.tsukuba.ac.jp/
9//
10// This program is free software; you can redistribute it and/or
11// modify it under the terms of the GNU General Public License
12// version 2 as published by the Free Software Foundation.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License version 2
20// along with this program; if not, write to the Free Software
21// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22//
23// このファイルは GPL バージョン 2 ライセンスで公開されています。
24// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
25// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
26// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
27// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
28//
29// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
30// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
31// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
32// ホストされています。
33// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
34// および、試験または研究のために利用が行われることを想定して配布
35// しています。
36// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
37// あります。
38// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
39// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
40// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
41// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
42// に組み込みさせていただきます。
43//
44// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
45// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
46//
47// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
48// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
49// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
50// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
51// ください。
52//
53// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
54// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
55// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
56// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
57// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
58// 公益保護にご協力いただきますようお願い申し上げます。
59//
60// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
61// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
62// を保護するための努力を行います。
63//
64// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
65// 日本国内の脆弱性情報届出受付公的機関:
66//         独立行政法人 情報処理推進機構
67//         http://www.ipa.go.jp/security/vuln/report/
68//
69// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
70// 連絡先: http://www.softether.co.jp/jp/contact/
71
72// -----------------------------------------------
73// [ChangeLog]
74// 2010.05.20
75//  新規リリース by SoftEther
76// -----------------------------------------------
77
78// Network.c
79// ネットワーク通信モジュール
80
81#define ENCRYPT_C
82#define NETWORK_C
83
84#define __WINCRYPT_H__
85
86#ifdef  WIN32
87// Socket API のために windows.h をインクルード
88#define _WIN32_WINNT        0x0502
89#define WINVER              0x0502
90#include <Ws2tcpip.h>
91#include <Wspiapi.h>
92#include <winsock2.h>
93#include <Ws2tcpip.h>
94#include <windows.h>
95#include <Iphlpapi.h>
96#endif  // WIN32
97
98#include <stdio.h>
99#include <stdlib.h>
100#include <string.h>
101#include <wchar.h>
102#include <stdarg.h>
103#include <time.h>
104#include <openssl/ssl.h>
105#include <openssl/err.h>
106#include <openssl/rand.h>
107#include <openssl/engine.h>
108#include <openssl/bio.h>
109#include <openssl/x509.h>
110#include <openssl/pkcs7.h>
111#include <openssl/pkcs12.h>
112#include <openssl/rc4.h>
113#include <openssl/md5.h>
114#include <openssl/sha.h>
115#include <Mayaqua/Mayaqua.h>
116
117#ifdef  OS_WIN32
118NETWORK_WIN32_FUNCTIONS *w32net;
119struct ROUTE_CHANGE_DATA
120{
121    OVERLAPPED Overlapped;
122    HANDLE Handle;
123    UINT NumCalled;
124};
125#endif  // OS_WIN32
126
127// SSL でブロッキングするかどうか
128#if defined(UNIX_BSD)
129#define FIX_SSL_BLOCKING
130#endif
131
132// IPV6_V6ONLY 定数
133#ifdef  UNIX_LINUX
134#ifndef IPV6_V6ONLY
135#define IPV6_V6ONLY 26
136#endif  // IPV6_V6ONLY
137#endif  // UNIX_LINUX
138
139#ifdef  UNIX_SOLARIS
140#ifndef IPV6_V6ONLY
141#define IPV6_V6ONLY 0x27
142#endif  // IPV6_V6ONLY
143#endif  // UNIX_SOLARIS
144
145// SSL_CTX
146static SSL_CTX *ssl_ctx = NULL;
147
148// DNS キャッシュリスト
149static LIST *DnsCache;
150
151// ロック関係
152static LOCK *machine_name_lock = NULL;
153static LOCK *disconnect_function_lock = NULL;
154static LOCK *aho = NULL;
155static LOCK *socket_library_lock = NULL;
156extern LOCK *openssl_lock;
157static LOCK *ssl_accept_lock = NULL;
158static LOCK *ssl_connect_lock = NULL;
159static TOKEN_LIST *cipher_list_token = NULL;
160static COUNTER *num_tcp_connections = NULL;
161static LOCK *dns_lock = NULL;
162static LOCK *unix_dns_server_addr_lock = NULL;
163static IP unix_dns_server;
164static LIST *HostCacheList = NULL;
165static LIST *WaitThreadList = NULL;
166static bool disable_cache = false;
167static bool NetworkReleaseMode = false;         // ネットワークリリースモード
168
169static char *cipher_list = "RC4-MD5 RC4-SHA AES128-SHA AES256-SHA DES-CBC-SHA DES-CBC3-SHA";
170static LIST *ip_clients = NULL;
171
172// ルーティングテーブル変更検出を初期化
173ROUTE_CHANGE *NewRouteChange()
174{
175#ifdef  OS_WIN32
176    return Win32NewRouteChange();
177#else   // OS_WIN32
178    return NULL;
179#endif  // OS_WIN32
180}
181
182// ルーティングテーブル変更検出を解放
183void FreeRouteChange(ROUTE_CHANGE *r)
184{
185#ifdef  OS_WIN32
186    Win32FreeRouteChange(r);
187#endif  // OS_WIN32
188}
189
190// ルーティングテーブルが変更されたかどうか取得
191bool IsRouteChanged(ROUTE_CHANGE *r)
192{
193#ifdef  OS_WIN32
194    return Win32IsRouteChanged(r);
195#else   // OS_WIN32
196    return false;
197#endif  // OS_WIN32
198}
199
200// ルーティングテーブル変更検出機能 (Win32)
201#ifdef  OS_WIN32
202ROUTE_CHANGE *Win32NewRouteChange()
203{
204    ROUTE_CHANGE *r;
205    bool ret;
206
207    if (MsIsNt() == false)
208    {
209        return NULL;
210    }
211
212    if (w32net->CancelIPChangeNotify == NULL ||
213        w32net->NotifyRouteChange == NULL)
214    {
215        return NULL;
216    }
217
218    r = ZeroMalloc(sizeof(ROUTE_CHANGE));
219
220    r->Data = ZeroMalloc(sizeof(ROUTE_CHANGE_DATA));
221
222    r->Data->Overlapped.hEvent = CreateEventA(NULL, false, true, NULL);
223
224    ret = w32net->NotifyRouteChange(&r->Data->Handle, &r->Data->Overlapped);
225    if (!(ret == NO_ERROR || ret == WSA_IO_PENDING || WSAGetLastError() == WSA_IO_PENDING))
226    {
227        Free(r->Data);
228        Free(r);
229
230        return NULL;
231    }
232
233    return r;
234}
235
236void Win32FreeRouteChange(ROUTE_CHANGE *r)
237{
238    // 引数チェック
239    if (r == NULL)
240    {
241        return;
242    }
243
244    w32net->CancelIPChangeNotify(&r->Data->Overlapped);
245    CloseHandle(r->Data->Overlapped.hEvent);
246
247    Free(r->Data);
248    Free(r);
249}
250
251bool Win32IsRouteChanged(ROUTE_CHANGE *r)
252{
253    // 引数チェック
254    if (r == NULL)
255    {
256        return false;
257    }
258
259    if ((r->Data->NumCalled++) == 0)
260    {
261        return true;
262    }
263
264    if (WaitForSingleObject(r->Data->Overlapped.hEvent, 0) == WAIT_OBJECT_0)
265    {
266        w32net->NotifyRouteChange(&r->Data->Handle, &r->Data->Overlapped);
267        return true;
268    }
269
270    return false;
271}
272
273#endif  // OS_WIN32
274
275
276// TCP コネクションのプロセス ID の取得が成功するかどうかを取得
277bool CanGetTcpProcessId()
278{
279    UINT i;
280    bool ret = false;
281    LIST *o = GetTcpTableList();
282
283    if (o == NULL)
284    {
285        return false;
286    }
287
288    for (i = 0;i < LIST_NUM(o);i++)
289    {
290        TCPTABLE *t = LIST_DATA(o, i);
291
292        if (t->ProcessId != 0)
293        {
294            ret = true;
295            break;
296        }
297    }
298
299    FreeTcpTableList(o);
300
301    return ret;
302}
303
304
305
306
307#define USE_OLD_GETIP
308
309// Linux における arp_filter を設定する
310void SetLinuxArpFilter()
311{
312    char *filename = "/proc/sys/net/ipv4/conf/all/arp_filter";
313    char *data = "1\n";
314    IO *o;
315
316    o = FileCreate(filename);
317    if (o == NULL)
318    {
319        return;
320    }
321
322    FileWrite(o, data, StrLen(data));
323    FileFlush(o);
324
325    FileClose(o);
326}
327
328// 指定された文字列が IPv6 マスクかどうか判定する
329bool IsIpMask6(char *str)
330{
331    IP mask;
332    // 引数チェック
333    if (str == NULL)
334    {
335        return false;
336    }
337
338    return StrToMask6(&mask, str);
339}
340
341// 指定された文字列が IPv6 アドレスかどうか判定する
342bool IsStrIPv6Address(char *str)
343{
344    IP ip;
345    // 引数チェック
346    if (str == NULL)
347    {
348        return false;
349    }
350
351    if (StrToIP6(&ip, str) == false)
352    {
353        return false;
354    }
355
356    return true;
357}
358
359// サブネットマスクを整数に変換する
360UINT SubnetMaskToInt6(IP *a)
361{
362    UINT i;
363    // 引数チェック
364    if (IsIP6(a) == false)
365    {
366        return 0;
367    }
368
369    for (i = 0;i <= 128;i++)
370    {
371        IP tmp;
372
373        IntToSubnetMask6(&tmp, i);
374
375        if (CmpIpAddr(a, &tmp) == 0)
376        {
377            return i;
378        }
379    }
380
381    return 0;
382}
383UINT SubnetMaskToInt4(IP *a)
384{
385    UINT i;
386    // 引数チェック
387    if (IsIP4(a) == false)
388    {
389        return 0;
390    }
391
392    for (i = 0;i <= 32;i++)
393    {
394        IP tmp;
395
396        IntToSubnetMask4(&tmp, i);
397
398        if (CmpIpAddr(a, &tmp) == 0)
399        {
400            return i;
401        }
402    }
403
404    return 0;
405}
406UINT SubnetMaskToInt(IP *a)
407{
408    if (IsIP6(a))
409    {
410        return SubnetMaskToInt6(a);
411    }
412    else
413    {
414        return SubnetMaskToInt4(a);
415    }
416}
417
418// 指定した IP アドレスがサブネットマスクかどうか調べる
419bool IsSubnetMask6(IP *a)
420{
421    UINT i;
422    // 引数チェック
423    if (IsIP6(a) == false)
424    {
425        return false;
426    }
427
428    for (i = 0;i <= 128;i++)
429    {
430        IP tmp;
431
432        IntToSubnetMask6(&tmp, i);
433
434        if (CmpIpAddr(a, &tmp) == 0)
435        {
436            return true;
437        }
438    }
439
440    return false;
441}
442
443// MAC アドレスからグローバルアドレスを生成する
444void GenerateEui64GlobalAddress(IP *ip, IP *prefix, IP *subnet, UCHAR *mac)
445{
446    UCHAR tmp[8];
447    IP a;
448    IP subnet_not;
449    IP or1, or2;
450    // 引数チェック
451    if (ip == NULL || prefix == NULL || subnet == NULL || mac == NULL)
452    {
453        return;
454    }
455
456    GenerateEui64Address6(tmp, mac);
457
458    ZeroIP6(&a);
459
460    Copy(&a.ipv6_addr[8], tmp, 8);
461
462    IPNot6(&subnet_not, subnet);
463    IPAnd6(&or1, &a, &subnet_not);
464    IPAnd6(&or2, prefix, subnet);
465
466    IPOr6(ip, &or1, &or2);
467}
468
469// MAC アドレスからローカルアドレスを生成する
470void GenerateEui64LocalAddress(IP *a, UCHAR *mac)
471{
472    UCHAR tmp[8];
473    // 引数チェック
474    if (a == NULL || mac == NULL)
475    {
476        return;
477    }
478
479    GenerateEui64Address6(tmp, mac);
480
481    ZeroIP6(a);
482    a->ipv6_addr[0] = 0xfe;
483    a->ipv6_addr[1] = 0x80;
484
485    Copy(&a->ipv6_addr[8], tmp, 8);
486}
487
488// MAC アドレスから EUI-64 アドレスを生成する
489void GenerateEui64Address6(UCHAR *dst, UCHAR *mac)
490{
491    // 引数チェック
492    if (dst == NULL || mac == NULL)
493    {
494        return;
495    }
496
497    Copy(dst, mac, 3);
498    Copy(dst + 5, mac, 3);
499
500    dst[3] = 0xff;
501    dst[4] = 0xfe;
502    dst[0] = ((~(dst[0] & 0x02)) & 0x02) | (dst[0] & 0xfd);
503}
504
505// 同一のネットワークかどうか調べる
506bool IsInSameNetwork6(IP *a1, IP *a2, IP *subnet)
507{
508    IP prefix1, prefix2;
509    // 引数チェック
510    if (IsIP6(a1) == false || IsIP6(a2) == false || IsIP6(subnet) == false)
511    {
512        return false;
513    }
514
515    if (a1->ipv6_scope_id != a2->ipv6_scope_id)
516    {
517        return false;
518    }
519
520    GetPrefixAddress6(&prefix1, a1, subnet);
521    GetPrefixAddress6(&prefix2, a2, subnet);
522
523    if (CmpIpAddr(&prefix1, &prefix2) == 0)
524    {
525        return true;
526    }
527
528    return false;
529}
530
531// ネットワークプレフィックスアドレスかどうかチェックする
532bool IsNetworkAddress6(IP *ip, IP *subnet)
533{
534    return IsNetworkPrefixAddress6(ip, subnet);
535}
536bool IsNetworkPrefixAddress6(IP *ip, IP *subnet)
537{
538    IP host;
539    // 引数チェック
540    if (ip == NULL || subnet == NULL)
541    {
542        return false;
543    }
544
545    if (IsIP6(ip) == false || IsIP6(subnet) == false)
546    {
547        return false;
548    }
549
550    GetHostAddress6(&host, ip, subnet);
551
552    if (IsZeroIp(&host))
553    {
554        return true;
555    }
556
557    return false;
558}
559
560// ユニキャストアドレスが有効かどうかチェックする
561bool CheckUnicastAddress(IP *ip)
562{
563    // 引数チェック
564    if (ip == NULL)
565    {
566        return false;
567    }
568
569    if ((GetIPAddrType6(ip) & IPV6_ADDR_UNICAST) == 0)
570    {
571        return false;
572    }
573
574    return true;
575}
576
577// ホストアドレスの取得
578void GetHostAddress6(IP *dst, IP *ip, IP *subnet)
579{
580    IP not;
581    // 引数チェック
582    if (dst == NULL || ip == NULL || subnet == NULL)
583    {
584        return;
585    }
586
587    IPNot6(&not, subnet);
588
589    IPAnd6(dst, ip, &not);
590
591    dst->ipv6_scope_id = ip->ipv6_scope_id;
592}
593
594// プレフィックスアドレスの取得
595void GetPrefixAddress6(IP *dst, IP *ip, IP *subnet)
596{
597    // 引数チェック
598    if (dst == NULL || ip == NULL || subnet == NULL)
599    {
600        return;
601    }
602
603    IPAnd6(dst, ip, subnet);
604
605    dst->ipv6_scope_id = ip->ipv6_scope_id;
606}
607
608// 要請ノードマルチキャストアドレスを取得
609void GetSoliciationMulticastAddr6(IP *dst, IP *src)
610{
611    IP prefix;
612    IP mask104;
613    IP or1, or2;
614
615    // 引数チェック
616    if (dst == NULL || src == NULL)
617    {
618        return;
619    }
620
621    ZeroIP6(&prefix);
622    prefix.ipv6_addr[0] = 0xff;
623    prefix.ipv6_addr[1] = 0x02;
624    prefix.ipv6_addr[11] = 0x01;
625    prefix.ipv6_addr[12] = 0xff;
626
627    IntToSubnetMask6(&mask104, 104);
628
629    IPAnd6(&or1, &prefix, &mask104);
630    IPAnd6(&or2, src, &mask104);
631
632    IPOr6(dst, &or1, &or2);
633
634    dst->ipv6_scope_id = src->ipv6_scope_id;
635}
636
637// マルチキャストアドレスに対応した MAC アドレスの生成
638void GenerateMulticastMacAddress6(UCHAR *mac, IP *ip)
639{
640    // 引数チェック
641    if (mac == NULL)
642    {
643        return;
644    }
645
646    mac[0] = 0x33;
647    mac[1] = 0x33;
648    mac[2] = ip->ipv6_addr[12];
649    mac[3] = ip->ipv6_addr[13];
650    mac[4] = ip->ipv6_addr[14];
651    mac[5] = ip->ipv6_addr[15];
652}
653
654// IPv6 アドレスのタイプの取得
655UINT GetIPv6AddrType(IPV6_ADDR *addr)
656{
657    IP ip;
658    // 引数チェック
659    if (addr == NULL)
660    {
661        return 0;
662    }
663
664    IPv6AddrToIP(&ip, addr);
665
666    return GetIPAddrType6(&ip);
667}
668UINT GetIPAddrType6(IP *ip)
669{
670    UINT ret = 0;
671    // 引数チェック
672    if (IsIP6(ip) == false)
673    {
674        return 0;
675    }
676
677    if (ip->ipv6_addr[0] == 0xff)
678    {
679        IP all_node, all_router;
680
681        GetAllNodeMulticaseAddress6(&all_node);
682
683        GetAllRouterMulticastAddress6(&all_router);
684
685        ret |= IPV6_ADDR_MULTICAST;
686
687        if (Cmp(ip->ipv6_addr, all_node.ipv6_addr, 16) == 0)
688        {
689            ret |= IPV6_ADDR_ALL_NODE_MULTICAST;
690        }
691        else if (Cmp(ip->ipv6_addr, all_router.ipv6_addr, 16) == 0)
692        {
693            ret |= IPV6_ADDR_ALL_ROUTER_MULTICAST;
694        }
695        else
696        {
697            if (ip->ipv6_addr[1] == 0x02 && ip->ipv6_addr[2] == 0 && ip->ipv6_addr[3] == 0 &&
698                ip->ipv6_addr[4] == 0 && ip->ipv6_addr[5] == 0 && ip->ipv6_addr[6] == 0 &&
699                ip->ipv6_addr[7] == 0 && ip->ipv6_addr[8] == 0 && ip->ipv6_addr[9] == 0 &&
700                ip->ipv6_addr[10] == 0 && ip->ipv6_addr[11] == 0x01 && ip->ipv6_addr[12] == 0xff)
701            {
702                ret |= IPV6_ADDR_SOLICIATION_MULTICAST;
703            }
704        }
705    }
706    else
707    {
708        ret |= IPV6_ADDR_UNICAST;
709
710        if (ip->ipv6_addr[0] == 0xfe && (ip->ipv6_addr[1] & 0xc0) == 0x80)
711        {
712            ret |= IPV6_ADDR_LOCAL_UNICAST;
713        }
714        else
715        {
716            ret |= IPV6_ADDR_GLOBAL_UNICAST;
717
718            if (IsZero(&ip->ipv6_addr, 16))
719            {
720                ret |= IPV6_ADDR_ZERO;
721            }
722            else
723            {
724                IP loopback;
725
726                GetLoopbackAddress6(&loopback);
727
728                if (Cmp(ip->ipv6_addr, loopback.ipv6_addr, 16) == 0)
729                {
730                    ret |= IPV6_ADDR_LOOPBACK;
731                }
732            }
733        }
734    }
735
736    return ret;
737}
738
739// すべてのビットが立っているアドレス
740void GetAllFilledAddress6(IP *ip)
741{
742    UINT i;
743    // 引数チェック
744    if (ip == NULL)
745    {
746        return;
747    }
748
749    ZeroIP6(ip);
750
751    for (i = 0;i < 15;i++)
752    {
753        ip->ipv6_addr[i] = 0xff;
754    }
755}
756
757// ループバックアドレス
758void GetLoopbackAddress6(IP *ip)
759{
760    // 引数チェック
761    if (ip == NULL)
762    {
763        return;
764    }
765
766    ZeroIP6(ip);
767
768    ip->ipv6_addr[15] = 0x01;
769}
770
771// 全ノードマルチキャストアドレス
772void GetAllNodeMulticaseAddress6(IP *ip)
773{
774    // 引数チェック
775    if (ip == NULL)
776    {
777        return;
778    }
779
780    ZeroIP6(ip);
781
782    ip->ipv6_addr[0] = 0xff;
783    ip->ipv6_addr[1] = 0x02;
784    ip->ipv6_addr[15] = 0x01;
785}
786
787// 全ルータマルチキャストアドレス
788void GetAllRouterMulticastAddress6(IP *ip)
789{
790    // 引数チェック
791    if (ip == NULL)
792    {
793        return;
794    }
795
796    ZeroIP6(ip);
797
798    ip->ipv6_addr[0] = 0xff;
799    ip->ipv6_addr[1] = 0x02;
800    ip->ipv6_addr[15] = 0x02;
801}
802
803// IPv6 アドレスの論理演算
804void IPAnd6(IP *dst, IP *a, IP *b)
805{
806    UINT i;
807    // 引数チェック
808    if (dst == NULL || IsIP6(a) == false || IsIP6(b) == false)
809    {
810        return;
811    }
812
813    ZeroIP6(dst);
814    for (i = 0;i < 16;i++)
815    {
816        dst->ipv6_addr[i] = a->ipv6_addr[i] & b->ipv6_addr[i];
817    }
818}
819void IPOr6(IP *dst, IP *a, IP *b)
820{
821    UINT i;
822    // 引数チェック
823    if (dst == NULL || IsIP6(a) == false || IsIP6(b) == false)
824    {
825        return;
826    }
827
828    ZeroIP6(dst);
829    for (i = 0;i < 16;i++)
830    {
831        dst->ipv6_addr[i] = a->ipv6_addr[i] | b->ipv6_addr[i];
832    }
833}
834void IPNot6(IP *dst, IP *a)
835{
836    UINT i;
837    // 引数チェック
838    if (dst == NULL || IsIP6(a) == false)
839    {
840        return;
841    }
842
843    ZeroIP6(dst);
844    for (i = 0;i < 16;i++)
845    {
846        dst->ipv6_addr[i] = ~(a->ipv6_addr[i]);
847    }
848}
849
850// サブネットマスクの作成
851void IntToSubnetMask6(IP *ip, UINT i)
852{
853    UINT j = i / 8;
854    UINT k = i % 8;
855    UINT z;
856    IP a;
857
858    ZeroIP6(&a);
859
860    for (z = 0;z < 16;z++)
861    {
862        if (z < j)
863        {
864            a.ipv6_addr[z] = 0xff;
865        }
866        else if (z == j)
867        {
868            a.ipv6_addr[z] = ~(0xff >> k);
869        }
870    }
871
872    Copy(ip, &a, sizeof(IP));
873}
874
875// IP アドレスを文字列に変換
876void IP6AddrToStr(char *str, UINT size, IPV6_ADDR *addr)
877{
878    // 引数チェック
879    if (str == NULL || addr == NULL)
880    {
881        return;
882    }
883
884    IPToStr6Array(str, size, addr->Value);
885}
886void IPToStr6Array(char *str, UINT size, UCHAR *bytes)
887{
888    IP ip;
889    // 引数チェック
890    if (str == NULL || bytes == NULL)
891    {
892        return;
893    }
894
895    SetIP6(&ip, bytes);
896
897    IPToStr6(str, size, &ip);
898}
899void IPToStr6(char *str, UINT size, IP *ip)
900{
901    char tmp[MAX_SIZE];
902
903    IPToStr6Inner(tmp, ip);
904
905    StrCpy(str, size, tmp);
906}
907void IPToStr6Inner(char *str, IP *ip)
908{
909    UINT i;
910    USHORT values[8];
911    UINT zero_started_index;
912    UINT max_zero_len;
913    UINT max_zero_start;
914    IP a;
915    // 引数チェック
916    if (str == NULL || ip == NULL)
917    {
918        return;
919    }
920
921    Copy(&a, ip, sizeof(IP));
922
923    for (i = 0;i < 8;i++)
924    {
925        Copy(&values[i], &a.ipv6_addr[i * 2], sizeof(USHORT));
926        values[i] = Endian16(values[i]);
927    }
928
929    // 省略できる場所があるかどうか検索
930    zero_started_index = INFINITE;
931    max_zero_len = 0;
932    max_zero_start = INFINITE;
933    for (i = 0;i < 9;i++)
934    {
935        USHORT v = (i != 8 ? values[i] : 1);
936
937        if (values[i] == 0)
938        {
939            if (zero_started_index == INFINITE)
940            {
941                zero_started_index = i;
942            }
943        }
944        else
945        {
946            UINT zero_len;
947
948            if (zero_started_index != INFINITE)
949            {
950                zero_len = i - zero_started_index;
951                if (zero_len >= 2)
952                {
953                    if (max_zero_len < zero_len)
954                    {
955                        max_zero_start = zero_started_index;
956                        max_zero_len = zero_len;
957                    }
958                }
959
960                zero_started_index = INFINITE;
961            }
962        }
963    }
964
965    // 文字列を形成
966    StrCpy(str, 0, "");
967    for (i = 0;i < 8;i++)
968    {
969        char tmp[16];
970
971        ToHex(tmp, values[i]);
972        StrLower(tmp);
973
974        if (i == max_zero_start)
975        {
976            if (i == 0)
977            {
978                StrCat(str, 0, "::");
979            }
980            else
981            {
982                StrCat(str, 0, ":");
983            }
984            i += max_zero_len - 1;
985        }
986        else
987        {
988            StrCat(str, 0, tmp);
989            if (i != 7)
990            {
991                StrCat(str, 0, ":");
992            }
993        }
994    }
995
996    // スコープ ID
997    if (ip->ipv6_scope_id != 0)
998    {
999        char tmp[64];
1000
1001        StrCat(str, 0, "%");
1002        ToStr(tmp, ip->ipv6_scope_id);
1003
1004        StrCat(str, 0, tmp);
1005    }
1006}
1007
1008// 文字列を IP アドレスに変換
1009bool StrToIP6(IP *ip, char *str)
1010{
1011    TOKEN_LIST *t;
1012    char tmp[MAX_PATH];
1013    IP a;
1014    UINT i;
1015    UINT scope_id = 0;
1016    // 引数チェック
1017    if (str == NULL || ip == NULL)
1018    {
1019        return false;
1020    }
1021
1022    ZeroIP6(&a);
1023
1024    StrCpy(tmp, sizeof(tmp), str);
1025    Trim(tmp);
1026
1027    if (StartWith(tmp, "[") && EndWith(tmp, "]"))
1028    {
1029        // かぎかっこで囲まれている場合はそれを除去
1030        StrCpy(tmp, sizeof(tmp), &tmp[1]);
1031
1032        if (StrLen(tmp) >= 1)
1033        {
1034            tmp[StrLen(tmp) - 1] = 0;
1035        }
1036    }
1037
1038    // スコープ ID がある場合はそれを解析して除去
1039    i = SearchStrEx(tmp, "%", 0, false);
1040    if (i != INFINITE)
1041    {
1042        char ss[MAX_PATH];
1043
1044        StrCpy(ss, sizeof(ss), &tmp[i + 1]);
1045
1046        tmp[i] = 0;
1047
1048        Trim(tmp);
1049
1050        Trim(ss);
1051
1052        scope_id = ToInt(ss);
1053    }
1054
1055    // トークン分割
1056    t = ParseTokenWithNullStr(tmp, ":");
1057    if (t->NumTokens >= 3 && t->NumTokens <= 8)
1058    {
1059        UINT i, n;
1060        bool b = true;
1061        UINT k = 0;
1062
1063        n = 0;
1064
1065        for (i = 0;i < t->NumTokens;i++)
1066        {
1067            char *str = t->Token[i];
1068
1069            if (i != 0 && i != (t->NumTokens - 1) && StrLen(str) == 0)
1070            {
1071                n++;
1072                if (n == 1)
1073                {
1074                    k += 2 * (8 - t->NumTokens + 1);
1075                }
1076                else
1077                {
1078                    b = false;
1079                    break;
1080                }
1081            }
1082            else
1083            {
1084                UCHAR chars[2];
1085
1086                if (CheckIPItemStr6(str) == false)
1087                {
1088                    b = false;
1089                    break;
1090                }
1091
1092                IPItemStrToChars6(chars, str);
1093
1094                a.ipv6_addr[k++] = chars[0];
1095                a.ipv6_addr[k++] = chars[1];
1096            }
1097        }
1098
1099        if (n != 0 && n != 1)
1100        {
1101            b = false;
1102        }
1103        else if (n == 0 && t->NumTokens != 8)
1104        {
1105            b = false;
1106        }
1107
1108        if (b == false)
1109        {
1110            FreeToken(t);
1111            return false;
1112        }
1113    }
1114    else
1115    {
1116        FreeToken(t);
1117        return false;
1118    }
1119
1120    FreeToken(t);
1121
1122    Copy(ip, &a, sizeof(IP));
1123
1124    ip->ipv6_scope_id = scope_id;
1125
1126    return true;
1127}
1128bool StrToIP6Addr(IPV6_ADDR *ip, char *str)
1129{
1130    IP ip2;
1131    // 引数チェック
1132    if (ip == NULL || str == NULL)
1133    {
1134        Zero(ip, sizeof(IPV6_ADDR));
1135        return false;
1136    }
1137
1138    if (StrToIP6(&ip2, str) == false)
1139    {
1140        return false;
1141    }
1142
1143    if (IPToIPv6Addr(ip, &ip2) == false)
1144    {
1145        return false;
1146    }
1147
1148    return true;
1149}
1150
1151// IP アドレスの文字から UCHAR 型に変換
1152void IPItemStrToChars6(UCHAR *chars, char *str)
1153{
1154    char tmp[5];
1155    BUF *b;
1156    UINT len;
1157    // 引数チェック
1158    if (chars == NULL)
1159    {
1160        return;
1161    }
1162
1163    Zero(tmp, sizeof(tmp));
1164
1165    len = StrLen(str);
1166    switch (len)
1167    {
1168    case 0:
1169        tmp[0] = tmp[1] = tmp[2] = tmp[3] = '0';
1170        break;
1171
1172    case 1:
1173        tmp[0] = tmp[1] = tmp[2] = '0';
1174        tmp[3] = str[0];
1175        break;
1176
1177    case 2:
1178        tmp[0] = tmp[1] = '0';
1179        tmp[2] = str[0];
1180        tmp[3] = str[1];
1181        break;
1182
1183    case 3:
1184        tmp[0] = '0';
1185        tmp[1] = str[0];
1186        tmp[2] = str[1];
1187        tmp[3] = str[2];
1188        break;
1189
1190    case 4:
1191        tmp[0] = str[0];
1192        tmp[1] = str[1];
1193        tmp[2] = str[2];
1194        tmp[3] = str[3];
1195        break;
1196    }
1197
1198    b = StrToBin(tmp);
1199
1200    chars[0] = ((UCHAR *)b->Buf)[0];
1201    chars[1] = ((UCHAR *)b->Buf)[1];
1202
1203    FreeBuf(b);
1204}
1205
1206// IP アドレスの要素文字列の中に不正な文字が含まれていないかどうかチェックする
1207bool CheckIPItemStr6(char *str)
1208{
1209    UINT i, len;
1210    // 引数チェック
1211    if (str == NULL)
1212    {
1213        return false;
1214    }
1215
1216    len = StrLen(str);
1217    if (len >= 5)
1218    {
1219        // 長さ不正
1220        return false;
1221    }
1222
1223    for (i = 0;i < len;i++)
1224    {
1225        char c = str[i];
1226
1227        if ((c >= 'a' && c <= 'f') ||
1228            (c >= 'A' && c <= 'F') ||
1229            (c >= '0' && c <= '9'))
1230        {
1231        }
1232        else
1233        {
1234            return false;
1235        }
1236    }
1237
1238    return true;
1239}
1240
1241// ゼロの IPv4 アドレスを作成する
1242void ZeroIP4(IP *ip)
1243{
1244    // 引数チェック
1245    if (ip == NULL)
1246    {
1247        return;
1248    }
1249
1250    Zero(ip, sizeof(IP));
1251}
1252
1253// ゼロの IPv6 アドレスを作成する
1254void ZeroIP6(IP *ip)
1255{
1256    // 引数チェック
1257    if (ip == NULL)
1258    {
1259        return;
1260    }
1261
1262    SetIP6(ip, NULL);
1263}
1264
1265// localhost の IP アドレスを取得する
1266void GetLocalHostIP6(IP *ip)
1267{
1268    ZeroIP6(ip);
1269
1270    ip->ipv6_addr[15] = 1;
1271}
1272
1273// IPV6_ADDR を IP に変換
1274void IPv6AddrToIP(IP *ip, IPV6_ADDR *addr)
1275{
1276    // 引数チェック
1277    if (ip == NULL || addr == NULL)
1278    {
1279        return;
1280    }
1281
1282    SetIP6(ip, addr->Value);
1283}
1284
1285// IP を IPV6_ADDR に変換
1286bool IPToIPv6Addr(IPV6_ADDR *addr, IP *ip)
1287{
1288    UINT i;
1289    // 引数チェック
1290    if (addr == NULL || ip == NULL)
1291    {
1292        Zero(addr, sizeof(IPV6_ADDR));
1293        return false;
1294    }
1295
1296    if (IsIP6(ip) == false)
1297    {
1298        Zero(addr, sizeof(IPV6_ADDR));
1299        return false;
1300    }
1301
1302    for (i = 0;i < 16;i++)
1303    {
1304        addr->Value[i] = ip->ipv6_addr[i];
1305    }
1306
1307    return true;
1308}
1309
1310// IPv6 アドレスをセットする
1311void SetIP6(IP *ip, UCHAR *value)
1312{
1313    // 引数チェック
1314    if (ip == NULL)
1315    {
1316        return;
1317    }
1318
1319    Zero(ip, sizeof(IP));
1320
1321    ip->addr[0] = 223;
1322    ip->addr[1] = 255;
1323    ip->addr[2] = 255;
1324    ip->addr[3] = 254;
1325
1326    if (value != NULL)
1327    {
1328        UINT i;
1329
1330        for (i = 0;i < 16;i++)
1331        {
1332            ip->ipv6_addr[i] = value[i];
1333        }
1334    }
1335}
1336
1337// 指定されたアドレスが IPv6 アドレスかどうかチェックする
1338bool IsIP6(IP *ip)
1339{
1340    // 引数チェック
1341    if (ip == NULL)
1342    {
1343        return false;
1344    }
1345
1346    if (ip->addr[0] == 223 && ip->addr[1] == 255 && ip->addr[2] == 255 && ip->addr[3] == 254)
1347    {
1348        return true;
1349    }
1350
1351    return false;
1352}
1353bool IsIP4(IP *ip)
1354{
1355    // 引数チェック
1356    if (ip == NULL)
1357    {
1358        return false;
1359    }
1360
1361    return (IsIP6(ip) ? false : true);
1362}
1363
1364// IPv6 のサブネット長をチェック
1365bool CheckSubnetLength6(UINT i)
1366{
1367    if (i >= 1 && i <= 127)
1368    {
1369        return true;
1370    }
1371
1372    return false;
1373}
1374
1375// ソケットから対応する TCP コネクションのプロセス ID を取得
1376UINT GetTcpProcessIdFromSocket(SOCK *s)
1377{
1378    LIST *o;
1379    TCPTABLE *t;
1380    UINT pid = 0;
1381    // 引数チェック
1382    if (s == NULL)
1383    {
1384        return 0;
1385    }
1386
1387    o = GetTcpTableList();
1388    if (o == NULL)
1389    {
1390        return 0;
1391    }
1392
1393    t = GetTcpTableFromEndPoint(o, &s->LocalIP, s->LocalPort,
1394        &s->RemoteIP, s->RemotePort);
1395
1396    if (t != NULL)
1397    {
1398        pid = t->ProcessId;
1399    }
1400
1401    FreeTcpTableList(o);
1402
1403    return pid;
1404}
1405UINT GetTcpProcessIdFromSocketReverse(SOCK *s)
1406{
1407    LIST *o;
1408    TCPTABLE *t;
1409    UINT pid = 0;
1410    // 引数チェック
1411    if (s == NULL)
1412    {
1413        return 0;
1414    }
1415
1416    o = GetTcpTableList();
1417    if (o == NULL)
1418    {
1419        return 0;
1420    }
1421
1422    t = GetTcpTableFromEndPoint(o, &s->RemoteIP, s->RemotePort,
1423        &s->LocalIP, s->LocalPort);
1424
1425    if (t != NULL)
1426    {
1427        pid = t->ProcessId;
1428    }
1429
1430    FreeTcpTableList(o);
1431
1432    return pid;
1433}
1434
1435// エンドポイントから TCP テーブルを検索
1436TCPTABLE *GetTcpTableFromEndPoint(LIST *o, IP *local_ip, UINT local_port, IP *remote_ip, UINT remote_port)
1437{
1438    IP local;
1439    UINT i;
1440    // 引数チェック
1441    if (o == NULL)
1442    {
1443        return NULL;
1444    }
1445
1446    SetIP(&local, 127, 0, 0, 1);
1447
1448    if (local_ip == NULL)
1449    {
1450        local_ip = &local;
1451    }
1452
1453    if (remote_ip == NULL)
1454    {
1455        remote_ip = &local;
1456    }
1457
1458    for (i = 0;i < LIST_NUM(o);i++)
1459    {
1460        TCPTABLE *t = LIST_DATA(o, i);
1461
1462        if (t->Status == TCP_STATE_SYN_SENT || t->Status == TCP_STATE_SYN_RCVD ||
1463            t->Status == TCP_STATE_ESTAB)
1464        {
1465            if (CmpIpAddr(&t->LocalIP, local_ip) == 0)
1466            {
1467                if (CmpIpAddr(&t->RemoteIP, remote_ip) == 0)
1468                {
1469                    if (t->LocalPort == local_port)
1470                    {
1471                        if (t->RemotePort == remote_port)
1472                        {
1473                            return t;
1474                        }
1475                    }
1476                }
1477            }
1478        }
1479    }
1480
1481    return NULL;
1482}
1483
1484// TCP テーブルリストを取得 (Win32)
1485#ifdef  OS_WIN32
1486LIST *Win32GetTcpTableList()
1487{
1488    LIST *o;
1489
1490    // Windows XP SP2 以降用
1491    o = Win32GetTcpTableListByGetExtendedTcpTable();
1492    if (o != NULL)
1493    {
1494        return o;
1495    }
1496
1497    // Windows XP 以降用
1498    o = Win32GetTcpTableListByAllocateAndGetTcpExTableFromStack();
1499    if (o != NULL)
1500    {
1501        return o;
1502    }
1503
1504    // 古い Windows 用
1505    return Win32GetTcpTableListByGetTcpTable();
1506}
1507
1508// TCP テーブルリストを取得: Windows XP SP2 以降用
1509LIST *Win32GetTcpTableListByGetExtendedTcpTable()
1510{
1511    UINT need_size;
1512    UINT i;
1513    MIB_TCPTABLE_OWNER_PID *table;
1514    bool ok = false;
1515    LIST *o;
1516    if (w32net->GetExtendedTcpTable == NULL)
1517    {
1518        return NULL;
1519    }
1520
1521    for (i = 0;i < 128;i++)
1522    {
1523        UINT ret;
1524        table = MallocFast(sizeof(MIB_TCPTABLE_OWNER_PID));
1525        need_size = sizeof(MIB_TCPTABLE_OWNER_PID);
1526        ret = w32net->GetExtendedTcpTable(table, &need_size, true, AF_INET, _TCP_TABLE_OWNER_PID_ALL, 0);
1527        if (ret == NO_ERROR)
1528        {
1529            ok = true;
1530            break;
1531        }
1532        else
1533        {
1534            Free(table);
1535            if (ret != ERROR_INSUFFICIENT_BUFFER)
1536            {
1537                return NULL;
1538            }
1539        }
1540
1541        table = MallocFast(need_size);
1542
1543        ret = w32net->GetExtendedTcpTable(table, &need_size, true, AF_INET, _TCP_TABLE_OWNER_PID_ALL, 0);
1544        if (ret == NO_ERROR)
1545        {
1546            ok = true;
1547            break;
1548        }
1549        else
1550        {
1551            Free(table);
1552
1553            if (ret != ERROR_INSUFFICIENT_BUFFER)
1554            {
1555                return NULL;
1556            }
1557        }
1558    }
1559
1560    if (ok == false)
1561    {
1562        return NULL;
1563    }
1564
1565    o = NewListEx(NULL, true);
1566
1567    for (i = 0;i < table->dwNumEntries;i++)
1568    {
1569        MIB_TCPROW_OWNER_PID *r = &table->table[i];
1570        TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
1571
1572        UINTToIP(&t->LocalIP, r->dwLocalAddr);
1573        t->LocalPort = Endian16((USHORT)r->dwLocalPort);
1574
1575        if (r->dwState != TCP_STATE_LISTEN)
1576        {
1577            UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
1578            t->RemotePort = Endian16((USHORT)r->dwRemotePort);
1579        }
1580
1581        t->Status = r->dwState;
1582        t->ProcessId = r->dwOwningPid;
1583
1584        Add(o, t);
1585    }
1586
1587    Free(table);
1588
1589    return o;
1590}
1591
1592// TCP テーブルリストを取得: Windows XP 以降用
1593LIST *Win32GetTcpTableListByAllocateAndGetTcpExTableFromStack()
1594{
1595    HANDLE heap;
1596    UINT i;
1597    MIB_TCPTABLE_OWNER_PID *table;
1598    bool ok = false;
1599    LIST *o;
1600    if (w32net->AllocateAndGetTcpExTableFromStack == NULL)
1601    {
1602        return NULL;
1603    }
1604
1605    heap = GetProcessHeap();
1606
1607    if (w32net->AllocateAndGetTcpExTableFromStack(&table, true, heap, HEAP_GROWABLE, AF_INET) != ERROR_SUCCESS)
1608    {
1609        return NULL;
1610    }
1611
1612    o = NewListEx(NULL, true);
1613
1614    for (i = 0;i < table->dwNumEntries;i++)
1615    {
1616        MIB_TCPROW_OWNER_PID *r = &table->table[i];
1617        TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
1618
1619        UINTToIP(&t->LocalIP, r->dwLocalAddr);
1620        t->LocalPort = Endian16((USHORT)r->dwLocalPort);
1621
1622        if (r->dwState != TCP_STATE_LISTEN)
1623        {
1624            UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
1625            t->RemotePort = Endian16((USHORT)r->dwRemotePort);
1626        }
1627
1628        t->ProcessId = r->dwOwningPid;
1629        t->Status = r->dwState;
1630
1631        Add(o, t);
1632    }
1633
1634    HeapFree(heap, 0, table);
1635
1636    return o;
1637}
1638
1639// TCP テーブルリストを取得: 古い Windows 用
1640LIST *Win32GetTcpTableListByGetTcpTable()
1641{
1642    UINT need_size;
1643    UINT i;
1644    MIB_TCPTABLE *table;
1645    bool ok = false;
1646    LIST *o;
1647    if (w32net->GetTcpTable == NULL)
1648    {
1649        return NULL;
1650    }
1651
1652    for (i = 0;i < 128;i++)
1653    {
1654        UINT ret;
1655        table = MallocFast(sizeof(MIB_TCPTABLE));
1656        need_size = sizeof(MIB_TCPTABLE);
1657        ret = w32net->GetTcpTable(table, &need_size, true);
1658        if (ret == NO_ERROR)
1659        {
1660            ok = true;
1661            break;
1662        }
1663        else
1664        {
1665            Free(table);
1666            if (ret != ERROR_INSUFFICIENT_BUFFER)
1667            {
1668                return NULL;
1669            }
1670        }
1671
1672        table = MallocFast(need_size);
1673
1674        ret = w32net->GetTcpTable(table, &need_size, true);
1675        if (ret == NO_ERROR)
1676        {
1677            ok = true;
1678            break;
1679        }
1680        else
1681        {
1682            Free(table);
1683
1684            if (ret != ERROR_INSUFFICIENT_BUFFER)
1685            {
1686                return NULL;
1687            }
1688        }
1689    }
1690
1691    if (ok == false)
1692    {
1693        return NULL;
1694    }
1695
1696    o = NewListEx(NULL, true);
1697
1698    for (i = 0;i < table->dwNumEntries;i++)
1699    {
1700        MIB_TCPROW *r = &table->table[i];
1701        TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
1702
1703        UINTToIP(&t->LocalIP, r->dwLocalAddr);
1704        t->LocalPort = Endian16((USHORT)r->dwLocalPort);
1705
1706        if (r->dwState != TCP_STATE_LISTEN)
1707        {
1708            UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
1709            t->RemotePort = Endian16((USHORT)r->dwRemotePort);
1710        }
1711
1712        t->Status = r->dwState;
1713
1714        Add(o, t);
1715    }
1716
1717    Free(table);
1718
1719    return o;
1720}
1721
1722#endif  // OS_WIN32
1723
1724// TCP テーブルの表示
1725void PrintTcpTableList(LIST *o)
1726{
1727    UINT i;
1728    // 引数チェック
1729    if (o == NULL)
1730    {
1731        Print("o == NULL\n\n");
1732        return;
1733    }
1734
1735    Print("--- TCPTABLE: %u Entries ---\n", LIST_NUM(o));
1736    for (i = 0;i < LIST_NUM(o);i++)
1737    {
1738        char tmp1[MAX_PATH], tmp2[MAX_PATH];
1739        TCPTABLE *t = LIST_DATA(o, i);
1740
1741        IPToStr(tmp1, sizeof(tmp1), &t->LocalIP);
1742        IPToStr(tmp2, sizeof(tmp2), &t->RemoteIP);
1743
1744        Print("%s:%u <--> %s:%u  state=%u  pid=%u\n",
1745            tmp1, t->LocalPort,
1746            tmp2, t->RemotePort,
1747            t->Status,
1748            t->ProcessId);
1749    }
1750    Print("------\n\n");
1751}
1752
1753// TCP テーブルの比較
1754int CompareTcpTable(void *p1, void *p2)
1755{
1756    TCPTABLE *t1, *t2;
1757    if (p1 == NULL || p2 == NULL)
1758    {
1759        return 0;
1760    }
1761    t1 = *(TCPTABLE **)p1;
1762    t2 = *(TCPTABLE **)p2;
1763    if (t1 == NULL || t2 == NULL)
1764    {
1765        return 0;
1766    }
1767
1768    return Cmp(t1, t2, sizeof(TCPTABLE));
1769}
1770
1771// TCP テーブルリストを取得
1772LIST *GetTcpTableList()
1773{
1774#ifdef  OS_WIN32
1775    return Win32GetTcpTableList();
1776#else   // OS_WIN32
1777    return NULL;
1778#endif  // OS_WIN32
1779}
1780
1781// TCP テーブルリストを解放
1782void FreeTcpTableList(LIST *o)
1783{
1784    UINT i;
1785    // 引数チェック
1786    if (o == NULL)
1787    {
1788        return;
1789    }
1790
1791    for (i = 0;i < LIST_NUM(o);i++)
1792    {
1793        TCPTABLE *t = LIST_DATA(o, i);
1794
1795        Free(t);
1796    }
1797
1798    ReleaseList(o);
1799}
1800
1801// 指定された IP アドレスから接続中のクライアント数の取得
1802UINT GetNumIpClient(IP *ip)
1803{
1804    IP_CLIENT *c;
1805    UINT ret = 0;
1806    // 引数チェック
1807    if (ip == NULL)
1808    {
1809        return 0;
1810    }
1811
1812    LockList(ip_clients);
1813    {
1814        c = SearchIpClient(ip);
1815
1816        if (c != NULL)
1817        {
1818            ret = c->NumConnections;
1819        }
1820    }
1821    UnlockList(ip_clients);
1822
1823    return ret;
1824}
1825
1826// IP クライアントエントリに追加
1827void AddIpClient(IP *ip)
1828{
1829    IP_CLIENT *c;
1830    // 引数チェック
1831    if (ip == NULL)
1832    {
1833        return;
1834    }
1835
1836    LockList(ip_clients);
1837    {
1838        c = SearchIpClient(ip);
1839
1840        if (c == NULL)
1841        {
1842            c = ZeroMallocFast(sizeof(IP_CLIENT));
1843            Copy(&c->IpAddress, ip, sizeof(IP));
1844            c->NumConnections = 0;
1845
1846            Add(ip_clients, c);
1847        }
1848
1849        c->NumConnections++;
1850    }
1851    UnlockList(ip_clients);
1852}
1853
1854// IP クライアントリストから削除
1855void DelIpClient(IP *ip)
1856{
1857    IP_CLIENT *c;
1858    // 引数チェック
1859    if (ip == NULL)
1860    {
1861        return;
1862    }
1863
1864    LockList(ip_clients);
1865    {
1866        c = SearchIpClient(ip);
1867
1868        if (c != NULL)
1869        {
1870            c->NumConnections--;
1871
1872            if (c->NumConnections == 0)
1873            {
1874                Delete(ip_clients, c);
1875                Free(c);
1876            }
1877        }
1878    }
1879    UnlockList(ip_clients);
1880}
1881
1882// IP クライアントエントリの検索
1883IP_CLIENT *SearchIpClient(IP *ip)
1884{
1885    IP_CLIENT t;
1886    // 引数チェック
1887    if (ip == NULL)
1888    {
1889        return NULL;
1890    }
1891
1892    Zero(&t, sizeof(t));
1893    Copy(&t.IpAddress, ip, sizeof(IP));
1894
1895    return Search(ip_clients, &t);
1896}
1897
1898// クライアントリストの初期化
1899void InitIpClientList()
1900{
1901    ip_clients = NewList(CompareIpClientList);
1902}
1903
1904// クライアントリストの解放
1905void FreeIpClientList()
1906{
1907    UINT i;
1908
1909    for (i = 0;i < LIST_NUM(ip_clients);i++)
1910    {
1911        IP_CLIENT *c = LIST_DATA(ip_clients, i);
1912
1913        Free(c);
1914    }
1915
1916    ReleaseList(ip_clients);
1917    ip_clients = NULL;
1918}
1919
1920// クライアントリストエントリの比較
1921int CompareIpClientList(void *p1, void *p2)
1922{
1923    IP_CLIENT *c1, *c2;
1924    if (p1 == NULL || p2 == NULL)
1925    {
1926        return 0;
1927    }
1928    c1 = *(IP_CLIENT **)p1;
1929    c2 = *(IP_CLIENT **)p2;
1930    if (c1 == NULL || c2 == NULL)
1931    {
1932        return 0;
1933    }
1934
1935    return CmpIpAddr(&c1->IpAddress, &c2->IpAddress);
1936}
1937
1938// MAC アドレスの正規化
1939bool NormalizeMacAddress(char *dst, UINT size, char *src)
1940{
1941    BUF *b;
1942    bool ret = false;
1943    // 引数チェック
1944    if (dst == NULL || src == NULL)
1945    {
1946        return false;
1947    }
1948
1949    b = StrToBin(src);
1950
1951    if (b != NULL && b->Size == 6)
1952    {
1953        ret = true;
1954
1955        BinToStr(dst, size, b->Buf, b->Size);
1956    }
1957
1958    FreeBuf(b);
1959
1960    return ret;
1961}
1962
1963// IP アドレスが空かどうか識別する
1964bool IsZeroIP(IP *ip)
1965{
1966    return IsZeroIp(ip);
1967}
1968bool IsZeroIp(IP *ip)
1969{
1970    // 引数チェック
1971    if (ip == NULL)
1972    {
1973        return true;
1974    }
1975
1976    if (IsIP6(ip) == false)
1977    {
1978        return IsZero(ip->addr, sizeof(ip->addr));
1979    }
1980    else
1981    {
1982        return IsZero(ip->ipv6_addr, sizeof(ip->ipv6_addr));
1983    }
1984}
1985bool IsZeroIP6Addr(IPV6_ADDR *addr)
1986{
1987    // 引数チェック
1988    if (addr == NULL)
1989    {
1990        return true;
1991    }
1992
1993    return IsZero(addr, sizeof(IPV6_ADDR));
1994}
1995
1996// 指定された IP アドレスがホストとして意味があるかどうかを調べる
1997bool IsHostIPAddress4(IP *ip)
1998{
1999    UINT a;
2000    // 引数チェック
2001    if (ip == NULL)
2002    {
2003        return false;
2004    }
2005
2006    a = IPToUINT(ip);
2007
2008    if (a == 0 || a == 0xffffffff)
2009    {
2010        return false;
2011    }
2012
2013    return true;
2014}
2015bool IsHostIPAddress32(UINT ip)
2016{
2017    IP p;
2018
2019    UINTToIP(&p, ip);
2020
2021    return IsHostIPAddress4(&p);
2022}
2023
2024// 指定された IP アドレスとサブネットマスクが正しくネットワークを示すかどうか調べる
2025bool IsNetworkAddress(IP *ip, IP *mask)
2026{
2027    if (IsIP4(ip))
2028    {
2029        return IsNetworkAddress4(ip, mask);
2030    }
2031    else
2032    {
2033        return IsNetworkAddress6(ip, mask);
2034    }
2035}
2036bool IsNetworkAddress4(IP *ip, IP *mask)
2037{
2038    UINT a, b;
2039    // 引数チェック
2040    if (ip == NULL || mask == NULL)
2041    {
2042        return false;
2043    }
2044
2045    if (IsIP4(ip) == false || IsIP4(mask) == false)
2046    {
2047        return false;
2048    }
2049
2050    if (IsSubnetMask4(mask) == false)
2051    {
2052        return false;
2053    }
2054
2055    a = IPToUINT(ip);
2056    b = IPToUINT(mask);
2057
2058    if ((a & b) == a)
2059    {
2060        return true;
2061    }
2062
2063    return false;
2064}
2065bool IsNetworkAddress32(UINT ip, UINT mask)
2066{
2067    IP a, b;
2068
2069    UINTToIP(&a, ip);
2070    UINTToIP(&b, mask);
2071
2072    return IsNetworkAddress4(&a, &b);
2073}
2074
2075// 整数をサブネットマスクに変換する
2076UINT IntToSubnetMask32(UINT i)
2077{
2078    UINT ret = 0xFFFFFFFF;
2079
2080    // 汚いコード
2081    switch (i)
2082    {
2083    case 0:     ret = 0x00000000;   break;
2084    case 1:     ret = 0x80000000;   break;
2085    case 2:     ret = 0xC0000000;   break;
2086    case 3:     ret = 0xE0000000;   break;
2087    case 4:     ret = 0xF0000000;   break;
2088    case 5:     ret = 0xF8000000;   break;
2089    case 6:     ret = 0xFC000000;   break;
2090    case 7:     ret = 0xFE000000;   break;
2091    case 8:     ret = 0xFF000000;   break;
2092    case 9:     ret = 0xFF800000;   break;
2093    case 10:    ret = 0xFFC00000;   break;
2094    case 11:    ret = 0xFFE00000;   break;
2095    case 12:    ret = 0xFFF00000;   break;
2096    case 13:    ret = 0xFFF80000;   break;
2097    case 14:    ret = 0xFFFC0000;   break;
2098    case 15:    ret = 0xFFFE0000;   break;
2099    case 16:    ret = 0xFFFF0000;   break;
2100    case 17:    ret = 0xFFFF8000;   break;
2101    case 18:    ret = 0xFFFFC000;   break;
2102    case 19:    ret = 0xFFFFE000;   break;
2103    case 20:    ret = 0xFFFFF000;   break;
2104    case 21:    ret = 0xFFFFF800;   break;
2105    case 22:    ret = 0xFFFFFC00;   break;
2106    case 23:    ret = 0xFFFFFE00;   break;
2107    case 24:    ret = 0xFFFFFF00;   break;
2108    case 25:    ret = 0xFFFFFF80;   break;
2109    case 26:    ret = 0xFFFFFFC0;   break;
2110    case 27:    ret = 0xFFFFFFE0;   break;
2111    case 28:    ret = 0xFFFFFFF0;   break;
2112    case 29:    ret = 0xFFFFFFF8;   break;
2113    case 30:    ret = 0xFFFFFFFC;   break;
2114    case 31:    ret = 0xFFFFFFFE;   break;
2115    case 32:    ret = 0xFFFFFFFF;   break;
2116    }
2117
2118    if (IsLittleEndian())
2119    {
2120        ret = Swap32(ret);
2121    }
2122
2123    return ret;
2124}
2125void IntToSubnetMask4(IP *ip, UINT i)
2126{
2127    UINT m;
2128    // 引数チェック
2129    if (ip == NULL)
2130    {
2131        return;
2132    }
2133
2134    m = IntToSubnetMask32(i);
2135
2136    UINTToIP(ip, m);
2137}
2138
2139// 指定された IP アドレスがサブネットマスクかどうか調べる
2140bool IsSubnetMask(IP *ip)
2141{
2142    if (IsIP6(ip))
2143    {
2144        return IsSubnetMask6(ip);
2145    }
2146    else
2147    {
2148        return IsSubnetMask4(ip);
2149    }
2150}
2151bool IsSubnetMask4(IP *ip)
2152{
2153    UINT i;
2154    // 引数チェック
2155    if (ip == NULL)
2156    {
2157        return false;
2158    }
2159
2160    if (IsIP6(ip))
2161    {
2162        return false;
2163    }
2164
2165    i = IPToUINT(ip);
2166
2167    if (IsLittleEndian())
2168    {
2169        i = Swap32(i);
2170    }
2171
2172    // 汚いコード
2173    switch (i)
2174    {
2175    case 0x00000000:
2176    case 0x80000000:
2177    case 0xC0000000:
2178    case 0xE0000000:
2179    case 0xF0000000:
2180    case 0xF8000000:
2181    case 0xFC000000:
2182    case 0xFE000000:
2183    case 0xFF000000:
2184    case 0xFF800000:
2185    case 0xFFC00000:
2186    case 0xFFE00000:
2187    case 0xFFF00000:
2188    case 0xFFF80000:
2189    case 0xFFFC0000:
2190    case 0xFFFE0000:
2191    case 0xFFFF0000:
2192    case 0xFFFF8000:
2193    case 0xFFFFC000:
2194    case 0xFFFFE000:
2195    case 0xFFFFF000:
2196    case 0xFFFFF800:
2197    case 0xFFFFFC00:
2198    case 0xFFFFFE00:
2199    case 0xFFFFFF00:
2200    case 0xFFFFFF80:
2201    case 0xFFFFFFC0:
2202    case 0xFFFFFFE0:
2203    case 0xFFFFFFF0:
2204    case 0xFFFFFFF8:
2205    case 0xFFFFFFFC:
2206    case 0xFFFFFFFE:
2207    case 0xFFFFFFFF:
2208        return true;
2209    }
2210
2211    return false;
2212}
2213bool IsSubnetMask32(UINT ip)
2214{
2215    IP p;
2216
2217    UINTToIP(&p, ip);
2218
2219    return IsSubnetMask4(&p);
2220}
2221
2222// ネットワークリリースモード
2223void SetNetworkReleaseMode()
2224{
2225    NetworkReleaseMode = true;
2226}
2227
2228#ifdef  OS_UNIX         // UNIX 用コード
2229
2230// ソケットをノンブロッキングモードにしたり解除したりする
2231void UnixSetSocketNonBlockingMode(int fd, bool nonblock)
2232{
2233    UINT flag = 0;
2234    // 引数チェック
2235    if (fd == INVALID_SOCKET)
2236    {
2237        return;
2238    }
2239
2240    if (nonblock)
2241    {
2242        flag = 1;
2243    }
2244
2245#ifdef  FIONBIO
2246    ioctl(fd, FIONBIO, &flag);
2247#else   // FIONBIO
2248    {
2249        int flag = fcntl(fd, F_GETFL, 0);
2250        if (flag != -1)
2251        {
2252            if (nonblock)
2253            {
2254                flag |= O_NONBLOCK;
2255            }
2256            else
2257            {
2258                flag = flag & ~O_NONBLOCK;
2259
2260                fcntl(fd, F_SETFL, flag);
2261            }
2262        }
2263    }
2264#endif  // FIONBIO
2265}
2266
2267// 何もしない
2268void UnixIpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
2269{
2270}
2271
2272// 何もしない
2273void UnixRouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry)
2274{
2275}
2276
2277// 何もしない
2278int UnixCompareRouteEntryByMetric(void *p1, void *p2)
2279{
2280    return 1;
2281}
2282
2283// 何もしない
2284ROUTE_TABLE *UnixGetRouteTable()
2285{
2286    ROUTE_TABLE *ret = ZeroMalloc(sizeof(ROUTE_TABLE));
2287    ret->NumEntry = 0;
2288    ret->Entry = ZeroMalloc(0);
2289
2290    return ret;
2291}
2292
2293// 何もしない
2294bool UnixAddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
2295{
2296    return true;
2297}
2298
2299// 何もしない
2300void UnixDeleteRouteEntry(ROUTE_ENTRY *e)
2301{
2302    return;
2303}
2304
2305// 何もしない
2306UINT UnixGetVLanInterfaceID(char *instance_name)
2307{
2308    return 1;
2309}
2310
2311// 何もしない
2312char **UnixEnumVLan(char *tag_name)
2313{
2314    char **list;
2315
2316    list = ZeroMalloc(sizeof(char *));
2317
2318    return list;
2319}
2320
2321// 何もしない
2322void UnixRenewDhcp()
2323{
2324}
2325
2326// デフォルトの DNS サーバーの IP アドレスを取得
2327bool UnixGetDefaultDns(IP *ip)
2328{
2329    BUF *b;
2330    // 引数チェック
2331    if (ip == NULL)
2332    {
2333        return false;
2334    }
2335
2336    Lock(unix_dns_server_addr_lock);
2337    {
2338        if (IsZero(&unix_dns_server, sizeof(IP)) == false)
2339        {
2340            Copy(ip, &unix_dns_server, sizeof(IP));
2341            Unlock(unix_dns_server_addr_lock);
2342            return true;
2343        }
2344
2345        ip->addr[0] = 127;
2346        ip->addr[1] = 0;
2347        ip->addr[2] = 0;
2348        ip->addr[3] = 1;
2349
2350        b = ReadDump("/etc/resolv.conf");
2351        if (b != NULL)
2352        {
2353            char *s;
2354            bool f = false;
2355            while ((s = CfgReadNextLine(b)) != NULL)
2356            {
2357                TOKEN_LIST *t = ParseToken(s, "\" \t,");
2358                if (t->NumTokens == 2)
2359                {
2360                    if (StrCmpi(t->Token[0], "nameserver") == 0)
2361                    {
2362                        StrToIP(ip, t->Token[1]);
2363                        f = true;
2364                    }
2365                }
2366                FreeToken(t);
2367
2368                Free(s);
2369
2370                if (f)
2371                {
2372                    break;
2373                }
2374            }
2375            FreeBuf(b);
2376        }
2377        Copy(&unix_dns_server, ip, sizeof(IP));
2378    }
2379    Unlock(unix_dns_server_addr_lock);
2380
2381    return true;
2382}
2383
2384
2385// Select 処理
2386void UnixSelect(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
2387{
2388    UINT reads[MAXIMUM_WAIT_OBJECTS];
2389    UINT writes[MAXIMUM_WAIT_OBJECTS];
2390    UINT num_read, num_write, i;
2391    UINT p1, p2;
2392    SOCK *s;
2393    UCHAR tmp[MAX_SIZE];
2394    // 引数チェック
2395    if (timeout == 0)
2396    {
2397        return;
2398    }
2399
2400    // 配列の初期化
2401    Zero(reads, sizeof(reads));
2402    Zero(writes, sizeof(writes));
2403    num_read = num_write = 0;
2404
2405    // イベント配列の設定
2406    if (set != NULL)
2407    {
2408        for (i = 0;i < set->NumSocket;i++)
2409        {
2410            s = set->Sock[i];
2411            if (s != NULL)
2412            {
2413                UnixInitAsyncSocket(s);
2414                reads[num_read++] = s->socket;
2415                if (s->WriteBlocked)
2416                {
2417                    writes[num_write++] = s->socket;
2418                }
2419            }
2420        }
2421    }
2422
2423    p1 = p2 = -1;
2424
2425    if (c1 != NULL)
2426    {
2427        reads[num_read++] = p1 = c1->pipe_read;
2428    }
2429    if (c2 != NULL)
2430    {
2431        reads[num_read++] = p2 = c2->pipe_read;
2432    }
2433
2434    // select を呼び出す
2435    UnixSelectInner(num_read, reads, num_write, writes, timeout);
2436
2437    // pipe から読んでおく
2438    if (c1 != NULL && c1->SpecialFlag == false && p1 != -1)
2439    {
2440        read(p1, tmp, sizeof(tmp));
2441    }
2442    if (c2 != NULL && c2->SpecialFlag == false && p2 != -1)
2443    {
2444        read(p2, tmp, sizeof(tmp));
2445    }
2446}
2447
2448// キャンセル
2449void UnixCancel(CANCEL *c)
2450{
2451    // 引数チェック
2452    if (c == NULL)
2453    {
2454        return;
2455    }
2456
2457    UnixWritePipe(c->pipe_write);
2458}
2459
2460// キャンセルオブジェクトの解放
2461void UnixCleanupCancel(CANCEL *c)
2462{
2463    // 引数チェック
2464    if (c == NULL)
2465    {
2466        return;
2467    }
2468
2469    if (c->SpecialFlag == false)
2470    {
2471        UnixDeletePipe(c->pipe_read, c->pipe_write);
2472    }
2473
2474    Free(c);
2475}
2476
2477// 新しいキャンセルオブジェクトの作成
2478CANCEL *UnixNewCancel()
2479{
2480    CANCEL *c = ZeroMallocFast(sizeof(CANCEL));
2481
2482    c->ref = NewRef();
2483    c->SpecialFlag = false;
2484
2485    UnixNewPipe(&c->pipe_read, &c->pipe_write);
2486
2487    return c;
2488}
2489
2490// ソケットをソケットイベントに追加する
2491void UnixJoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
2492{
2493    // 引数チェック
2494    if (sock == NULL || event == NULL || sock->AsyncMode)
2495    {
2496        return;
2497    }
2498    if (sock->ListenMode != false || (sock->Type == SOCK_TCP && sock->Connected == false))
2499    {
2500        return;
2501    }
2502
2503    sock->AsyncMode = true;
2504
2505    LockList(event->SockList);
2506    {
2507        Add(event->SockList, sock);
2508        AddRef(sock->ref);
2509    }
2510    UnlockList(event->SockList);
2511
2512    // ソケットを非同期にする
2513    UnixSetSocketNonBlockingMode(sock->socket, true);
2514
2515    // SOCK_EVENT の参照カウンタを増加
2516    AddRef(event->ref);
2517    sock->SockEvent = event;
2518
2519    // ソケットイベントを叩く
2520    SetSockEvent(event);
2521}
2522
2523// ソケットイベントを待機する
2524bool UnixWaitSockEvent(SOCK_EVENT *event, UINT timeout)
2525{
2526    UINT num_read, num_write;
2527    UINT *reads, *writes;
2528    UINT n;
2529    char tmp[MAX_SIZE];
2530    // 引数チェック
2531    if (event == NULL)
2532    {
2533        return false;
2534    }
2535
2536    LockList(event->SockList);
2537    {
2538        UINT i;
2539        num_read = LIST_NUM(event->SockList) + 1;
2540        reads = ZeroMallocFast(sizeof(SOCK *) * num_read);
2541
2542        num_write = 0;
2543
2544        for (i = 0;i < (num_read - 1);i++)
2545        {
2546            SOCK *s = LIST_DATA(event->SockList, i);
2547            reads[i] = s->socket;
2548            if (s->WriteBlocked)
2549            {
2550                num_write++;
2551            }
2552        }
2553
2554        reads[num_read - 1] = event->pipe_read;
2555
2556        writes = ZeroMallocFast(sizeof(SOCK *) * num_write);
2557
2558        n = 0;
2559
2560        for (i = 0;i < (num_read - 1);i++)
2561        {
2562            SOCK *s = LIST_DATA(event->SockList, i);
2563            if (s->WriteBlocked)
2564            {
2565                writes[n++] = s->socket;
2566            }
2567        }
2568    }
2569    UnlockList(event->SockList);
2570
2571    if (0)
2572    {
2573        UINT i;
2574        Print("UnixSelectInner: ");
2575        for (i = 0;i < num_read;i++)
2576        {
2577            Print("%u ", reads[i]);
2578        }
2579        Print("\n");
2580    }
2581
2582    UnixSelectInner(num_read, reads, num_write, writes, timeout);
2583
2584    read(event->pipe_read, tmp, sizeof(tmp));
2585
2586    Free(reads);
2587    Free(writes);
2588
2589    return true;
2590}
2591
2592// ソケットイベントをセットする
2593void UnixSetSockEvent(SOCK_EVENT *event)
2594{
2595    // 引数チェック
2596    if (event == NULL)
2597    {
2598        return;
2599    }
2600
2601    UnixWritePipe(event->pipe_write);
2602}
2603
2604// ソケットの select の実行
2605void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, UINT timeout)
2606{
2607    struct pollfd *p;
2608    UINT num;
2609    UINT i;
2610    UINT n;
2611    UINT num_read_total, num_write_total;
2612
2613    if (num_read != 0 && reads == NULL)
2614    {
2615        num_read = 0;
2616    }
2617    if (num_write != 0 && writes == NULL)
2618    {
2619        num_write = 0;
2620    }
2621
2622    if (timeout == 0)
2623    {
2624        return;
2625    }
2626
2627    num_read_total = num_write_total = 0;
2628    for (i = 0;i < num_read;i++)
2629    {
2630        if (reads[i] != INVALID_SOCKET)
2631        {
2632            num_read_total++;
2633        }
2634    }
2635    for (i = 0;i < num_write;i++)
2636    {
2637        if (writes[i] != INVALID_SOCKET)
2638        {
2639            num_write_total++;
2640        }
2641    }
2642
2643    num = num_read_total + num_write_total;
2644    p = ZeroMallocFast(sizeof(struct pollfd) * num);
2645
2646    n = 0;
2647
2648    for (i = 0;i < num_read;i++)
2649    {
2650        if (reads[i] != INVALID_SOCKET)
2651        {
2652            struct pollfd *pfd = &p[n++];
2653            pfd->fd = reads[i];
2654            pfd->events = POLLIN | POLLPRI | POLLERR | POLLHUP;
2655        }
2656    }
2657
2658    for (i = 0;i < num_write;i++)
2659    {
2660        if (writes[i] != INVALID_SOCKET)
2661        {
2662            struct pollfd *pfd = &p[n++];
2663            pfd->fd = writes[i];
2664            pfd->events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLOUT;
2665        }
2666    }
2667
2668    if (num != 0)
2669    {
2670        poll(p, num, timeout == INFINITE ? -1 : (int)timeout);
2671    }
2672    else
2673    {
2674        SleepThread(timeout);
2675    }
2676
2677    Free(p);
2678}
2679
2680// ソケットイベントのクリーンアップ
2681void UnixCleanupSockEvent(SOCK_EVENT *event)
2682{
2683    UINT i;
2684    // 引数チェック
2685    if (event == NULL)
2686    {
2687        return;
2688    }
2689
2690    for (i = 0;i < LIST_NUM(event->SockList);i++)
2691    {
2692        SOCK *s = LIST_DATA(event->SockList, i);
2693
2694        ReleaseSock(s);
2695    }
2696
2697    ReleaseList(event->SockList);
2698
2699    UnixDeletePipe(event->pipe_read, event->pipe_write);
2700
2701    Free(event);
2702}
2703
2704// ソケットイベントを作成する
2705SOCK_EVENT *UnixNewSockEvent()
2706{
2707    SOCK_EVENT *e = ZeroMallocFast(sizeof(SOCK_EVENT));
2708
2709    e->SockList = NewList(NULL);
2710    e->ref = NewRef();
2711
2712    UnixNewPipe(&e->pipe_read, &e->pipe_write);
2713
2714    return e;
2715}
2716
2717// パイプを閉じる
2718void UnixDeletePipe(int p1, int p2)
2719{
2720    if (p1 != -1)
2721    {
2722        close(p1);
2723    }
2724
2725    if (p2 != -1)
2726    {
2727        close(p2);
2728    }
2729}
2730
2731// パイプに書き込む
2732void UnixWritePipe(int pipe_write)
2733{
2734    char c = 1;
2735    write(pipe_write, &c, 1);
2736}
2737
2738// 新しいパイプを作成する
2739void UnixNewPipe(int *pipe_read, int *pipe_write)
2740{
2741    int fd[2];
2742    // 引数チェック
2743    if (pipe_read == NULL || pipe_write == NULL)
2744    {
2745        return;
2746    }
2747
2748    fd[0] = fd[1] = 0;
2749
2750    pipe(fd);
2751
2752    *pipe_read = fd[0];
2753    *pipe_write = fd[1];
2754
2755    UnixSetSocketNonBlockingMode(*pipe_write, true);
2756    UnixSetSocketNonBlockingMode(*pipe_read, true);
2757}
2758
2759// 非同期ソケットの解放
2760void UnixFreeAsyncSocket(SOCK *sock)
2761{
2762    UINT p;
2763    // 引数チェック
2764    if (sock == NULL)
2765    {
2766        return;
2767    }
2768
2769    Lock(sock->lock);
2770    {
2771        if (sock->AsyncMode == false)
2772        {
2773            Unlock(sock->lock);
2774            return;
2775        }
2776
2777        sock->AsyncMode = false;
2778
2779        // このソケットが SockEvent に関連付けられているかどうか調べる
2780        if (sock->SockEvent != NULL)
2781        {
2782            SOCK_EVENT *e = sock->SockEvent;
2783
2784            AddRef(e->ref);
2785
2786            p = e->pipe_write;
2787            LockList(e->SockList);
2788            {
2789                if (Delete(e->SockList, sock))
2790                {
2791                    ReleaseSock(sock);
2792                }
2793            }
2794            UnlockList(e->SockList);
2795
2796            // ソケットイベントを解放する
2797            ReleaseSockEvent(sock->SockEvent);
2798            sock->SockEvent = NULL;
2799
2800            SetSockEvent(e);
2801
2802            ReleaseSockEvent(e);
2803        }
2804    }
2805    Unlock(sock->lock);
2806}
2807
2808// ソケットを非同期に設定する
2809void UnixInitAsyncSocket(SOCK *sock)
2810{
2811    // 引数チェック
2812    if (sock == NULL)
2813    {
2814        return;
2815    }
2816    if (sock->AsyncMode)
2817    {
2818        // すでに非同期ソケットになっている
2819        return;
2820    }
2821    if (sock->ListenMode != false || (sock->Type == SOCK_TCP && sock->Connected == false))
2822    {
2823        return;
2824    }
2825
2826    sock->AsyncMode = true;
2827
2828    UnixSetSocketNonBlockingMode(sock->socket, true);
2829}
2830
2831// ソケットライブラリの初期化
2832void UnixInitSocketLibrary()
2833{
2834    // 特に何もしない
2835}
2836
2837// ソケットライブラリの解放
2838void UnixFreeSocketLibrary()
2839{
2840    // 特に何もしない
2841}
2842
2843#endif  // OS_UNIX
2844
2845#ifdef  OS_WIN32        // Windows 用コード
2846
2847NETWORK_WIN32_FUNCTIONS *w32net;
2848
2849// IP_ADAPTER_INDEX_MAP の比較
2850int CompareIpAdapterIndexMap(void *p1, void *p2)
2851{
2852    IP_ADAPTER_INDEX_MAP *a1, *a2;
2853    if (p1 == NULL || p2 == NULL)
2854    {
2855        return 0;
2856    }
2857    a1 = *(IP_ADAPTER_INDEX_MAP **)p1;
2858    a2 = *(IP_ADAPTER_INDEX_MAP **)p2;
2859    if (a1 == NULL || a2 == NULL)
2860    {
2861        return 0;
2862    }
2863
2864    if (a1->Index > a2->Index)
2865    {
2866        return 1;
2867    }
2868    else if (a1->Index < a2->Index)
2869    {
2870        return -1;
2871    }
2872    else
2873    {
2874        return 0;
2875    }
2876}
2877
2878// アダプタの IP アドレスを更新
2879bool Win32RenewAddressByGuid(char *guid)
2880{
2881    IP_ADAPTER_INDEX_MAP a;
2882    // 引数チェック
2883    if (guid == NULL)
2884    {
2885        return false;
2886    }
2887
2888    Zero(&a, sizeof(a));
2889    if (Win32GetAdapterFromGuid(&a, guid) == false)
2890    {
2891        return false;
2892    }
2893
2894    return Win32RenewAddress(&a);
2895}
2896bool Win32RenewAddress(void *a)
2897{
2898    DWORD ret;
2899    // 引数チェック
2900    if (a == NULL)
2901    {
2902        return false;
2903    }
2904    if (w32net->IpRenewAddress == NULL)
2905    {
2906        return false;
2907    }
2908
2909    ret = w32net->IpRenewAddress(a);
2910
2911    if (ret == NO_ERROR)
2912    {
2913        return true;
2914    }
2915    else
2916    {
2917        Debug("IpRenewAddress: Error: %u\n", ret);
2918        return false;
2919    }
2920}
2921
2922// アダプタの IP アドレスを解放
2923bool Win32ReleaseAddress(void *a)
2924{
2925    DWORD ret;
2926    // 引数チェック
2927    if (a == NULL)
2928    {
2929        return false;
2930    }
2931    if (w32net->IpReleaseAddress == NULL)
2932    {
2933        return false;
2934    }
2935
2936    ret = w32net->IpReleaseAddress(a);
2937
2938    if (ret == NO_ERROR)
2939    {
2940        return true;
2941    }
2942    else
2943    {
2944        Debug("IpReleaseAddress: Error: %u\n", ret);
2945        return false;
2946    }
2947}
2948bool Win32ReleaseAddressByGuid(char *guid)
2949{
2950    IP_ADAPTER_INDEX_MAP a;
2951    // 引数チェック
2952    if (guid == NULL)
2953    {
2954        return false;
2955    }
2956
2957    Zero(&a, sizeof(a));
2958    if (Win32GetAdapterFromGuid(&a, guid) == false)
2959    {
2960        return false;
2961    }
2962
2963    return Win32ReleaseAddress(&a);
2964}
2965void Win32ReleaseAddressByGuidExThread(THREAD *t, void *param)
2966{
2967    WIN32_RELEASEADDRESS_THREAD_PARAM *p;
2968    // 引数チェック
2969    if (t == NULL || param == NULL)
2970    {
2971        return;
2972    }
2973
2974    p = (WIN32_RELEASEADDRESS_THREAD_PARAM *)param;
2975
2976    AddRef(p->Ref);
2977
2978    NoticeThreadInit(t);
2979
2980    AddWaitThread(t);
2981
2982    if (p->Renew == false)
2983    {
2984        p->Ok = Win32ReleaseAddressByGuid(p->Guid);
2985    }
2986    else
2987    {
2988        p->Ok = Win32RenewAddressByGuid(p->Guid);
2989    }
2990
2991    ReleaseWin32ReleaseAddressByGuidThreadParam(p);
2992
2993    DelWaitThread(t);
2994}
2995bool Win32RenewAddressByGuidEx(char *guid, UINT timeout)
2996{
2997    return Win32ReleaseOrRenewAddressByGuidEx(guid, timeout, true);
2998}
2999bool Win32ReleaseAddressByGuidEx(char *guid, UINT timeout)
3000{
3001    return Win32ReleaseOrRenewAddressByGuidEx(guid, timeout, false);
3002}
3003bool Win32ReleaseOrRenewAddressByGuidEx(char *guid, UINT timeout, bool renew)
3004{
3005    THREAD *t;
3006    WIN32_RELEASEADDRESS_THREAD_PARAM *p;
3007    bool ret = false;
3008    UINT64 start_tick = 0;
3009    UINT64 end_tick = 0;
3010    // 引数チェック
3011    if (guid == NULL)
3012    {
3013        return false;
3014    }
3015    if (timeout == 0)
3016    {
3017        timeout = INFINITE;
3018    }
3019
3020    p = ZeroMalloc(sizeof(WIN32_RELEASEADDRESS_THREAD_PARAM));
3021    p->Ref = NewRef();
3022    StrCpy(p->Guid, sizeof(p->Guid), guid);
3023    p->Timeout = timeout;
3024    p->Renew = renew;
3025
3026    t = NewThread(Win32ReleaseAddressByGuidExThread, p);
3027    WaitThreadInit(t);
3028    start_tick = Tick64();
3029    end_tick = start_tick + (UINT64)timeout;
3030
3031    while (true)
3032    {
3033        UINT64 now = Tick64();
3034        UINT64 remain;
3035        UINT remain32;
3036
3037        if (now >= end_tick)
3038        {
3039            break;
3040        }
3041
3042        remain = end_tick - now;
3043        remain32 = MIN((UINT)remain, 100);
3044
3045        if (WaitThread(t, remain32))
3046        {
3047            break;
3048        }
3049    }
3050
3051    ReleaseThread(t);
3052
3053    if (p->Ok)
3054    {
3055        ret = true;
3056    }
3057
3058    ReleaseWin32ReleaseAddressByGuidThreadParam(p);
3059
3060    return ret;
3061}
3062void ReleaseWin32ReleaseAddressByGuidThreadParam(WIN32_RELEASEADDRESS_THREAD_PARAM *p)
3063{
3064    // 引数チェック
3065    if (p == NULL)
3066    {
3067        return;
3068    }
3069
3070    if (Release(p->Ref) == 0)
3071    {
3072        Free(p);
3073    }
3074}
3075
3076// アダプタを GUID から取得
3077bool Win32GetAdapterFromGuid(void *a, char *guid)
3078{
3079    bool ret = false;
3080    IP_INTERFACE_INFO *info;
3081    UINT size;
3082    int i;
3083    LIST *o;
3084    wchar_t tmp[MAX_SIZE];
3085
3086    // 引数チェック
3087    if (a == NULL || guid == NULL)
3088    {
3089        return false;
3090    }
3091    if (w32net->GetInterfaceInfo == NULL)
3092    {
3093        return false;
3094    }
3095
3096    UniFormat(tmp, sizeof(tmp), L"\\DEVICE\\TCPIP_%S", guid);
3097
3098    size = sizeof(IP_INTERFACE_INFO);
3099    info = ZeroMallocFast(size);
3100
3101    if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
3102    {
3103        Free(info);
3104        info = ZeroMallocFast(size);
3105    }
3106
3107    if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
3108    {
3109        Free(info);
3110        return false;
3111    }
3112
3113    o = NewListFast(CompareIpAdapterIndexMap);
3114
3115    for (i = 0;i < info->NumAdapters;i++)
3116    {
3117        IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
3118
3119        Add(o, a);
3120    }
3121
3122    Sort(o);
3123
3124    for (i = 0;i < (int)(LIST_NUM(o));i++)
3125    {
3126        IP_ADAPTER_INDEX_MAP *e = LIST_DATA(o, i);
3127
3128        if (UniStrCmpi(e->Name, tmp) == 0)
3129        {
3130            Copy(a, e, sizeof(IP_ADAPTER_INDEX_MAP));
3131            ret = true;
3132            break;
3133        }
3134    }
3135
3136    ReleaseList(o);
3137
3138    Free(info);
3139
3140    return ret;
3141}
3142
3143// テスト
3144void Win32NetworkTest()
3145{
3146    IP_INTERFACE_INFO *info;
3147    UINT size;
3148    int i;
3149    LIST *o;
3150
3151    size = sizeof(IP_INTERFACE_INFO);
3152    info = ZeroMallocFast(size);
3153
3154    if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
3155    {
3156        Free(info);
3157        info = ZeroMallocFast(size);
3158    }
3159
3160    if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
3161    {
3162        Free(info);
3163        return;
3164    }
3165
3166    o = NewListFast(CompareIpAdapterIndexMap);
3167
3168    for (i = 0;i < info->NumAdapters;i++)
3169    {
3170        IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
3171
3172        Add(o, a);
3173    }
3174
3175    Sort(o);
3176
3177    for (i = 0;i < (int)(LIST_NUM(o));i++)
3178    {
3179        IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
3180
3181        DoNothing();
3182    }
3183
3184    ReleaseList(o);
3185
3186    Free(info);
3187}
3188
3189// 指定された LAN カードの DHCP アドレスを更新する
3190void Win32RenewDhcp9x(UINT if_id)
3191{
3192    IP_INTERFACE_INFO *info;
3193    UINT size;
3194    int i;
3195    LIST *o;
3196    // 引数チェック
3197    if (if_id == 0)
3198    {
3199        return;
3200    }
3201
3202    size = sizeof(IP_INTERFACE_INFO);
3203    info = ZeroMallocFast(size);
3204
3205    if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
3206    {
3207        Free(info);
3208        info = ZeroMallocFast(size);
3209    }
3210
3211    if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
3212    {
3213        Free(info);
3214        return;
3215    }
3216
3217    o = NewListFast(CompareIpAdapterIndexMap);
3218
3219    for (i = 0;i < info->NumAdapters;i++)
3220    {
3221        IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
3222
3223        Add(o, a);
3224    }
3225
3226    Sort(o);
3227
3228    for (i = 0;i < (int)(LIST_NUM(o));i++)
3229    {
3230        IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
3231
3232        if (a->Index == if_id)
3233        {
3234            char arg[MAX_PATH];
3235            Format(arg, sizeof(arg), "/renew %u", i);
3236            Run("ipconfig.exe", arg, true, false);
3237        }
3238    }
3239
3240    ReleaseList(o);
3241
3242    Free(info);
3243}
3244
3245// 指定された LAN カードの DHCP アドレスを解放する
3246void Win32ReleaseDhcp9x(UINT if_id, bool wait)
3247{
3248    IP_INTERFACE_INFO *info;
3249    UINT size;
3250    int i;
3251    LIST *o;
3252    // 引数チェック
3253    if (if_id == 0)
3254    {
3255        return;
3256    }
3257
3258    size = sizeof(IP_INTERFACE_INFO);
3259    info = ZeroMallocFast(size);
3260
3261    if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
3262    {
3263        Free(info);
3264        info = ZeroMallocFast(size);
3265    }
3266
3267    if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
3268    {
3269        Free(info);
3270        return;
3271    }
3272
3273    o = NewListFast(CompareIpAdapterIndexMap);
3274
3275    for (i = 0;i < info->NumAdapters;i++)
3276    {
3277        IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
3278
3279        Add(o, a);
3280    }
3281
3282    Sort(o);
3283
3284    for (i = 0;i < (int)(LIST_NUM(o));i++)
3285    {
3286        IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
3287
3288        if (a->Index == if_id)
3289        {
3290            char arg[MAX_PATH];
3291            Format(arg, sizeof(arg), "/release %u", i);
3292            Run("ipconfig.exe", arg, true, wait);
3293        }
3294    }
3295
3296    ReleaseList(o);
3297
3298    Free(info);
3299}
3300
3301// DHCP サーバーから IP アドレスを再取得する
3302void Win32RenewDhcp()
3303{
3304    if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType))
3305    {
3306        Run("ipconfig.exe", "/renew", true, false);
3307        if (MsIsVista())
3308        {
3309            Run("ipconfig.exe", "/renew6", true, false);
3310        }
3311        else
3312        {
3313            Run("netsh.exe", "int ipv6 renew", true, false);
3314        }
3315    }
3316    else
3317    {
3318        Run("ipconfig.exe", "/renew_all", true, false);
3319    }
3320}
3321
3322// 指定された文字列を含む仮想 LAN カードの一覧を列挙する
3323char **Win32EnumVLan(char *tag_name)
3324{
3325    MIB_IFTABLE *p;
3326    UINT ret;
3327    UINT size_needed;
3328    UINT num_retry = 0;
3329    UINT i;
3330    LIST *o;
3331    char **ss;
3332    // 引数チェック
3333    if (tag_name == 0)
3334    {
3335        return NULL;
3336    }
3337
3338RETRY:
3339    p = ZeroMallocFast(sizeof(MIB_IFTABLE));
3340    size_needed = 0;
3341
3342    // 必要なサイズを調べる
3343    ret = w32net->GetIfTable(p, &size_needed, 0);
3344    if (ret == ERROR_INSUFFICIENT_BUFFER)
3345    {
3346        // 必要なサイズ分のメモリブロックを再確保
3347        Free(p);
3348        p = ZeroMallocFast(size_needed);
3349    }
3350    else if (ret != NO_ERROR)
3351    {
3352        // 取得失敗
3353FAILED:
3354        Free(p);
3355        return NULL;
3356    }
3357
3358    // 実際に取得する
3359    ret = w32net->GetIfTable(p, &size_needed, FALSE);
3360    if (ret != NO_ERROR)
3361    {
3362        // 取得失敗
3363        if ((++num_retry) >= 5)
3364        {
3365            goto FAILED;
3366        }
3367        Free(p);
3368        goto RETRY;
3369    }
3370
3371    // 検索
3372    ret = 0;
3373    o = NewListFast(CompareStr);
3374    for (i = 0;i < p->dwNumEntries;i++)
3375    {
3376        MIB_IFROW *r = &p->table[i];
3377        if (SearchStrEx(r->bDescr, tag_name, 0, false) != INFINITE)
3378        {
3379            char *s = CopyStr(r->bDescr);
3380            Add(o, s);
3381        }
3382    }
3383
3384    Free(p);
3385
3386    // ソート
3387    Sort(o);
3388
3389    // 文字列に変換
3390    ss = ZeroMallocFast(sizeof(char *) * (LIST_NUM(o) + 1));
3391    for (i = 0;i < LIST_NUM(o);i++)
3392    {
3393        ss[i] = LIST_DATA(o, i);
3394    }
3395    ss[LIST_NUM(o)] = NULL;
3396
3397    ReleaseList(o);
3398
3399    return ss;
3400}
3401
3402// 仮想 LAN カードのインスタンス名から仮想 LAN カードの ID を取得する
3403UINT Win32GetVLanInterfaceID(char *instance_name)
3404{
3405    MIB_IFTABLE *p;
3406    UINT ret;
3407    UINT size_needed;
3408    UINT num_retry = 0;
3409    UINT i;
3410    char ps_miniport_str[MAX_SIZE];
3411    char ps_miniport_str2[MAX_SIZE];
3412    // 引数チェック
3413    if (instance_name == 0)
3414    {
3415        return 0;
3416    }
3417
3418RETRY:
3419    p = ZeroMallocFast(sizeof(MIB_IFTABLE));
3420    size_needed = 0;
3421
3422    // 必要なサイズを調べる
3423    ret = w32net->GetIfTable(p, &size_needed, 0);
3424    if (ret == ERROR_INSUFFICIENT_BUFFER)
3425    {
3426        // 必要なサイズ分のメモリブロックを再確保
3427        Free(p);
3428        p = ZeroMallocFast(size_needed);
3429    }
3430    else if (ret != NO_ERROR)
3431    {
3432        // 取得失敗
3433FAILED:
3434        Free(p);
3435        Debug("******** GetIfTable Failed 1. Err = %u\n", ret);
3436        return 0;
3437    }
3438
3439    // 実際に取得する
3440    ret = w32net->GetIfTable(p, &size_needed, FALSE);
3441    if (ret != NO_ERROR)
3442    {
3443        // 取得失敗
3444        if ((++num_retry) >= 5)
3445        {
3446            goto FAILED;
3447        }
3448        Free(p);
3449        Debug("******** GetIfTable Failed 2. Err = %u\n", ret);
3450        goto RETRY;
3451    }
3452
3453    // "%s - パケット スケジューラ ミニポート"
3454    Format(ps_miniport_str, sizeof(ps_miniport_str), "%s - ", instance_name);
3455    Format(ps_miniport_str2, sizeof(ps_miniport_str2), "%s (Microsoft", instance_name);
3456
3457    // 検索
3458    ret = 0;
3459    for (i = 0;i < p->dwNumEntries;i++)
3460    {
3461        MIB_IFROW *r = &p->table[i];
3462        if (instance_name[0] != '@')
3463        {
3464            if (StrCmpi(r->bDescr, instance_name) == 0 || StartWith(r->bDescr, ps_miniport_str) || StartWith(r->bDescr, ps_miniport_str2))
3465            {
3466                ret = r->dwIndex;
3467            }
3468        }
3469        else
3470        {
3471            if (SearchStrEx(r->bDescr, &instance_name[1], 0, false) != INFINITE)
3472            {
3473                ret = r->dwIndex;
3474            }
3475        }
3476
3477        Debug("if[%u] (0x%x): %s\n", i, r->dwIndex, r->bDescr);
3478    }
3479
3480    Free(p);
3481
3482    return ret;
3483}
3484
3485// デフォルトの DNS サーバーアドレスを取得する
3486bool Win32GetDefaultDns(IP *ip, char *domain, UINT size)
3487{
3488    FIXED_INFO *info;
3489    UINT info_size;
3490    char *dns_name;
3491    // 引数チェック
3492    if (ip == NULL)
3493    {
3494        return false;
3495    }
3496    Zero(ip, sizeof(IP));
3497    info_size = 0;
3498    info = ZeroMallocFast(sizeof(FIXED_INFO));
3499    if (w32net->GetNetworkParams(info, &info_size) == ERROR_BUFFER_OVERFLOW)
3500    {
3501        Free(info);
3502        info = ZeroMallocFast(info_size);
3503    }
3504    if (w32net->GetNetworkParams(info, &info_size) != NO_ERROR)
3505    {
3506        Free(info);
3507        return false;
3508    }
3509
3510    if (info->DnsServerList.IpAddress.String == NULL)
3511    {
3512        Free(info);
3513        return false;
3514    }
3515
3516    dns_name = info->DnsServerList.IpAddress.String;
3517    StrToIP(ip, dns_name);
3518
3519    if (domain != NULL)
3520    {
3521        StrCpy(domain, size, info->DomainName);
3522        Trim(domain);
3523    }
3524
3525    Free(info);
3526
3527    return true;
3528}
3529
3530// Win32 用 IP 変換関数
3531void Win32UINTToIP(IP *ip, UINT i)
3532{
3533    UINTToIP(ip, i);
3534}
3535
3536// Win32 用 IP 変換関数
3537UINT Win32IPToUINT(IP *ip)
3538{
3539    return IPToUINT(ip);
3540}
3541
3542// ルーティングテーブルからルーティングエントリを削除
3543void Win32DeleteRouteEntry(ROUTE_ENTRY *e)
3544{
3545    MIB_IPFORWARDROW *p;
3546    // 引数チェック
3547    if (e == NULL)
3548    {
3549        return;
3550    }
3551
3552    p = ZeroMallocFast(sizeof(MIB_IPFORWARDROW));
3553    Win32RouteEntryToIpForwardRow(p, e);
3554
3555    // 削除
3556    w32net->DeleteIpForwardEntry(p);
3557
3558    Free(p);
3559}
3560
3561// ルーティングテーブルにルーティングエントリを追加
3562bool Win32AddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
3563{
3564    bool ret = false;
3565    bool dummy = false;
3566    MIB_IPFORWARDROW *p;
3567    UINT err = 0;
3568    // 引数チェック
3569    if (e == NULL)
3570    {
3571        return false;
3572    }
3573    if (already_exists == NULL)
3574    {
3575        already_exists = &dummy;
3576    }
3577
3578    *already_exists = false;
3579
3580    p = ZeroMallocFast(sizeof(MIB_IPFORWARDROW));
3581    Win32RouteEntryToIpForwardRow(p, e);
3582
3583    // 追加
3584    err = w32net->CreateIpForwardEntry(p);
3585    if (err != 0)
3586    {
3587        if (err == ERROR_OBJECT_ALREADY_EXISTS)
3588        {
3589            Debug("CreateIpForwardEntry: Already Exists\n");
3590            *already_exists = true;
3591            ret = true;
3592        }
3593        else
3594        {
3595            Debug("CreateIpForwardEntry Error: %u\n", err);
3596            ret = false;
3597        }
3598    }
3599    else
3600    {
3601        ret = true;
3602    }
3603
3604    Free(p);
3605
3606    return ret;
3607}
3608
3609// ルーティングテーブルの取得
3610ROUTE_TABLE *Win32GetRouteTable()
3611{
3612    ROUTE_TABLE *t = ZeroMallocFast(sizeof(ROUTE_TABLE));
3613    MIB_IPFORWARDTABLE *p;
3614    UINT ret;
3615    UINT size_needed;
3616    UINT num_retry = 0;
3617    LIST *o;
3618    UINT i;
3619    ROUTE_ENTRY *e;
3620
3621RETRY:
3622    p = ZeroMallocFast(sizeof(MIB_IFTABLE));
3623    size_needed = 0;
3624
3625    // 必要なサイズを調べる
3626    ret = w32net->GetIpForwardTable(p, &size_needed, 0);
3627    if (ret == ERROR_INSUFFICIENT_BUFFER)
3628    {
3629        // 必要なサイズ分のメモリブロックを再確保
3630        Free(p);
3631        p = ZeroMallocFast(size_needed);
3632    }
3633    else if (ret != NO_ERROR)
3634    {
3635        // 取得失敗
3636FAILED:
3637        Free(p);
3638        t->Entry = MallocFast(0);
3639        return t;
3640    }
3641
3642    // 実際に取得する
3643    ret = w32net->GetIpForwardTable(p, &size_needed, FALSE);
3644    if (ret != NO_ERROR)
3645    {
3646        // 取得失敗
3647        if ((++num_retry) >= 5)
3648        {
3649            goto FAILED;
3650        }
3651        Free(p);
3652        goto RETRY;
3653    }
3654
3655    // リストに追加していく
3656    o = NewListFast(Win32CompareRouteEntryByMetric);
3657    for (i = 0;i < p->dwNumEntries;i++)
3658    {
3659        e = ZeroMallocFast(sizeof(ROUTE_ENTRY));
3660        Win32IpForwardRowToRouteEntry(e, &p->table[i]);
3661        Add(o, e);
3662    }
3663    Free(p);
3664
3665    // メトリック順にソート
3666    Sort(o);
3667
3668    // 結果を結合
3669    t->NumEntry = LIST_NUM(o);
3670    t->Entry = ToArrayEx(o, true);
3671    ReleaseList(o);
3672
3673    return t;
3674}
3675
3676// ルーティングエントリをメトリックによってソートする
3677int Win32CompareRouteEntryByMetric(void *p1, void *p2)
3678{
3679    ROUTE_ENTRY *e1, *e2;
3680    // 引数チェック
3681    if (p1 == NULL || p2 == NULL)
3682    {
3683        return 0;
3684    }
3685
3686    e1 = *(ROUTE_ENTRY **)p1;
3687    e2 = *(ROUTE_ENTRY **)p2;
3688    if (e1 == NULL || e2 == NULL)
3689    {
3690        return 0;
3691    }
3692
3693    if (e1->Metric > e2->Metric)
3694    {
3695        return 1;
3696    }
3697    else if (e1->Metric == e2->Metric)
3698    {
3699        return 0;
3700    }
3701    else
3702    {
3703        return -1;
3704    }
3705}
3706
3707// ROUTE_ENTRY を MIB_IPFORWARDROW に変換
3708void Win32RouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry)
3709{
3710    MIB_IPFORWARDROW *r;
3711    // 引数チェック
3712    if (entry == NULL || ip_forward_row == NULL)
3713    {
3714        return;
3715    }
3716
3717    r = (MIB_IPFORWARDROW *)ip_forward_row;
3718    Zero(r, sizeof(MIB_IPFORWARDROW));
3719
3720    // IP アドレス
3721    r->dwForwardDest = Win32IPToUINT(&entry->DestIP);
3722    // サブネットマスク
3723    r->dwForwardMask = Win32IPToUINT(&entry->DestMask);
3724    // ゲートウェイ IP アドレス
3725    r->dwForwardNextHop = Win32IPToUINT(&entry->GatewayIP);
3726    // ローカルルーティングフラグ
3727    if (entry->LocalRouting)
3728    {
3729        // ローカル
3730        r->dwForwardType = 3;
3731    }
3732    else
3733    {
3734        // リモートルータ
3735        r->dwForwardType = 4;
3736    }
3737    // プロトコル
3738    r->dwForwardProto = r->dwForwardType - 1;   // 大抵の場合 1 引けば良い
3739    if (entry->PPPConnection)
3740    {
3741        // PPP ちゃうかな? 危険!
3742        r->dwForwardProto++;
3743    }
3744    // メトリック
3745    r->dwForwardMetric1 = entry->Metric;
3746
3747    if (MsIsVista() == false)
3748    {
3749        r->dwForwardMetric2 = r->dwForwardMetric3 = r->dwForwardMetric4 = r->dwForwardMetric5 = INFINITE;
3750    }
3751    else
3752    {
3753        r->dwForwardMetric2 = r->dwForwardMetric3 = r->dwForwardMetric4 = r->dwForwardMetric5 = 0;
3754        r->dwForwardAge = 163240;
3755    }
3756
3757    // インターフェイス ID
3758    r->dwForwardIfIndex = entry->InterfaceID;
3759
3760    Debug("Win32RouteEntryToIpForwardRow()\n");
3761    Debug(" r->dwForwardDest=%X\n", r->dwForwardDest);
3762    Debug(" r->dwForwardMask=%X\n", r->dwForwardMask);
3763    Debug(" r->dwForwardNextHop=%X\n", r->dwForwardNextHop);
3764    Debug(" r->dwForwardType=%u\n", r->dwForwardType);
3765    Debug(" r->dwForwardProto=%u\n", r->dwForwardProto);
3766    Debug(" r->dwForwardMetric1=%u\n", r->dwForwardMetric1);
3767    Debug(" r->dwForwardMetric2=%u\n", r->dwForwardMetric2);
3768    Debug(" r->dwForwardIfIndex=%u\n", r->dwForwardIfIndex);
3769}
3770
3771// MIB_IPFORWARDROW を ROUTE_ENTRY に変換
3772void Win32IpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
3773{
3774    MIB_IPFORWARDROW *r;
3775    // 引数チェック
3776    if (entry == NULL || ip_forward_row == NULL)
3777    {
3778        return;
3779    }
3780
3781    r = (MIB_IPFORWARDROW *)ip_forward_row;
3782
3783    Zero(entry, sizeof(ROUTE_ENTRY));
3784    // IP アドレス
3785    Win32UINTToIP(&entry->DestIP, r->dwForwardDest);
3786    // サブネットマスク
3787    Win32UINTToIP(&entry->DestMask, r->dwForwardMask);
3788    // ゲートウェイ IP アドレス
3789    Win32UINTToIP(&entry->GatewayIP, r->dwForwardNextHop);
3790    // ローカルルーティングフラグ
3791    if (r->dwForwardType == 3)
3792    {
3793        entry->LocalRouting = true;
3794    }
3795    else
3796    {
3797        entry->LocalRouting = false;
3798    }
3799    if (entry->LocalRouting && r->dwForwardProto == 3)
3800    {
3801        // PPP。危険!
3802        entry->PPPConnection = true;
3803    }
3804    // メトリック
3805    entry->Metric = r->dwForwardMetric1;
3806    // インターフェイス ID
3807    entry->InterfaceID = r->dwForwardIfIndex;
3808}
3809
3810// ソケットライブラリの初期化
3811void Win32InitSocketLibrary()
3812{
3813    WSADATA data;
3814    Zero(&data, sizeof(data));
3815    WSAStartup(MAKEWORD(2, 2), &data);
3816
3817    // DLL 関数の読み込み
3818    w32net = ZeroMalloc(sizeof(NETWORK_WIN32_FUNCTIONS));
3819    w32net->hIpHlpApi32 = LoadLibrary("iphlpapi.dll");
3820
3821    if (w32net->hIpHlpApi32 != NULL)
3822    {
3823        w32net->CreateIpForwardEntry =
3824            (DWORD (__stdcall *)(PMIB_IPFORWARDROW))
3825            GetProcAddress(w32net->hIpHlpApi32, "CreateIpForwardEntry");
3826
3827        w32net->DeleteIpForwardEntry =
3828            (DWORD (__stdcall *)(PMIB_IPFORWARDROW))
3829            GetProcAddress(w32net->hIpHlpApi32, "DeleteIpForwardEntry");
3830
3831        w32net->GetIfTable =
3832            (DWORD (__stdcall *)(PMIB_IFTABLE, PULONG, BOOL))
3833            GetProcAddress(w32net->hIpHlpApi32, "GetIfTable");
3834
3835        w32net->GetIpForwardTable =
3836            (DWORD (__stdcall *)(PMIB_IPFORWARDTABLE, PULONG, BOOL))
3837            GetProcAddress(w32net->hIpHlpApi32, "GetIpForwardTable");
3838
3839        w32net->GetNetworkParams =
3840            (DWORD (__stdcall *)(PFIXED_INFO,PULONG))
3841            GetProcAddress(w32net->hIpHlpApi32, "GetNetworkParams");
3842
3843        w32net->IpRenewAddress =
3844            (DWORD (__stdcall *)(PIP_ADAPTER_INDEX_MAP))
3845            GetProcAddress(w32net->hIpHlpApi32, "IpRenewAddress");
3846
3847        w32net->IpReleaseAddress =
3848            (DWORD (__stdcall *)(PIP_ADAPTER_INDEX_MAP))
3849            GetProcAddress(w32net->hIpHlpApi32, "IpReleaseAddress");
3850
3851        w32net->GetInterfaceInfo =
3852            (DWORD (__stdcall *)(PIP_INTERFACE_INFO, PULONG))
3853            GetProcAddress(w32net->hIpHlpApi32, "GetInterfaceInfo");
3854
3855        w32net->GetAdaptersInfo =
3856            (DWORD (__stdcall *)(PIP_ADAPTER_INFO, PULONG))
3857            GetProcAddress(w32net->hIpHlpApi32, "GetAdaptersInfo");
3858
3859        w32net->GetExtendedTcpTable =
3860            (DWORD (__stdcall *)(PVOID,PDWORD,BOOL,ULONG,_TCP_TABLE_CLASS,ULONG))
3861            GetProcAddress(w32net->hIpHlpApi32, "GetExtendedTcpTable");
3862
3863        w32net->AllocateAndGetTcpExTableFromStack =
3864            (DWORD (__stdcall *)(PVOID *,BOOL,HANDLE,DWORD,DWORD))
3865            GetProcAddress(w32net->hIpHlpApi32, "AllocateAndGetTcpExTableFromStack");
3866
3867        w32net->GetTcpTable =
3868            (DWORD (__stdcall *)(PMIB_TCPTABLE,PDWORD,BOOL))
3869            GetProcAddress(w32net->hIpHlpApi32, "GetTcpTable");
3870
3871        w32net->NotifyRouteChange =
3872            (DWORD (__stdcall *)(PHANDLE,LPOVERLAPPED))
3873            GetProcAddress(w32net->hIpHlpApi32, "NotifyRouteChange");
3874
3875        w32net->CancelIPChangeNotify =
3876            (BOOL (__stdcall *)(LPOVERLAPPED))
3877            GetProcAddress(w32net->hIpHlpApi32, "CancelIPChangeNotify");
3878
3879        w32net->NhpAllocateAndGetInterfaceInfoFromStack =
3880            (DWORD (__stdcall *)(IP_INTERFACE_NAME_INFO **,PDWORD,BOOL,HANDLE,DWORD))
3881            GetProcAddress(w32net->hIpHlpApi32, "NhpAllocateAndGetInterfaceInfoFromStack");
3882    }
3883}
3884
3885// ソケットライブラリの解放
3886void Win32FreeSocketLibrary()
3887{
3888    if (w32net != NULL)
3889    {
3890        FreeLibrary(w32net->hIpHlpApi32);
3891
3892        Free(w32net);
3893        w32net = NULL;
3894    }
3895
3896    WSACleanup();
3897}
3898
3899// キャンセル
3900void Win32Cancel(CANCEL *c)
3901{
3902    // 引数チェック
3903    if (c == NULL)
3904    {
3905        return;
3906    }
3907
3908    SetEvent((HANDLE)c->hEvent);
3909}
3910
3911// キャンセルのクリーンアップ
3912void Win32CleanupCancel(CANCEL *c)
3913{
3914    // 引数チェック
3915    if (c == NULL)
3916    {
3917        return;
3918    }
3919
3920    if (c->SpecialFlag == false)
3921    {
3922        CloseHandle(c->hEvent);
3923    }
3924
3925    Free(c);
3926}
3927
3928// 新しいキャンセルオブジェクト
3929CANCEL *Win32NewCancel()
3930{
3931    CANCEL *c = ZeroMallocFast(sizeof(CANCEL));
3932    c->ref = NewRef();
3933    c->SpecialFlag = false;
3934    c->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
3935
3936    return c;
3937}
3938
3939// ソケットイベントの待機
3940bool Win32WaitSockEvent(SOCK_EVENT *event, UINT timeout)
3941{
3942    // 引数チェック
3943    if (event == NULL || timeout == 0)
3944    {
3945        return false;
3946    }
3947
3948    if (WaitForSingleObject((HANDLE)event->hEvent, timeout) == WAIT_OBJECT_0)
3949    {
3950        return true;
3951    }
3952    else
3953    {
3954        return false;
3955    }
3956}
3957
3958// ソケットイベントのクリーンアップ
3959void Win32CleanupSockEvent(SOCK_EVENT *event)
3960{
3961    // 引数チェック
3962    if (event == NULL)
3963    {
3964        return;
3965    }
3966
3967    CloseHandle((HANDLE)event->hEvent);
3968
3969    Free(event);
3970}
3971
3972// ソケットイベントのセット
3973void Win32SetSockEvent(SOCK_EVENT *event)
3974{
3975    // 引数チェック
3976    if (event == NULL)
3977    {
3978        return;
3979    }
3980
3981    SetEvent((HANDLE)event->hEvent);
3982}
3983
3984// ソケットイベントの作成
3985SOCK_EVENT *Win32NewSockEvent()
3986{
3987    SOCK_EVENT *e = ZeroMallocFast(sizeof(SOCK_EVENT));
3988
3989    e->ref = NewRef();
3990    e->hEvent = (void *)CreateEvent(NULL, FALSE, FALSE, NULL);
3991
3992    return e;
3993}
3994
3995// ソケットをソケットイベントに関連付けして非同期に設定する
3996void Win32JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
3997{
3998    HANDLE hEvent;
3999    // 引数チェック
4000    if (sock == NULL || event == NULL || sock->AsyncMode)
4001    {
4002        return;
4003    }
4004    if (sock->ListenMode != false || (sock->Type != SOCK_UDP && sock->Connected == false))
4005    {
4006        return;
4007    }
4008
4009    sock->AsyncMode = true;
4010
4011    hEvent = event->hEvent;
4012
4013    // 関連付け
4014    WSAEventSelect(sock->socket, hEvent, FD_READ | FD_WRITE | FD_CLOSE);
4015
4016    // SOCK_EVENT の参照カウンタを増加
4017    AddRef(event->ref);
4018    sock->SockEvent = event;
4019}
4020
4021// ソケットを非同期に設定する
4022void Win32InitAsyncSocket(SOCK *sock)
4023{
4024    // 引数チェック
4025    if (sock == NULL)
4026    {
4027        return;
4028    }
4029    if (sock->AsyncMode)
4030    {
4031        // すでに非同期ソケットになっている
4032        return;
4033    }
4034    if (sock->ListenMode != false || (sock->Type == SOCK_TCP && sock->Connected == false))
4035    {
4036        return;
4037    }
4038
4039    sock->AsyncMode = true;
4040
4041    // イベントの作成
4042    sock->hEvent = (void *)CreateEvent(NULL, FALSE, FALSE, NULL);
4043
4044    // 関連付け
4045    WSAEventSelect(sock->socket, sock->hEvent, FD_READ | FD_WRITE | FD_CLOSE);
4046}
4047
4048// 非同期ソケットを解放
4049void Win32FreeAsyncSocket(SOCK *sock)
4050{
4051    // 引数チェック
4052    if (sock == NULL)
4053    {
4054        return;
4055    }
4056
4057    // 非同期ソケット
4058    if (sock->hEvent != NULL)
4059    {
4060        CloseHandle((HANDLE)sock->hEvent);
4061    }
4062    sock->hEvent = NULL;
4063    sock->AsyncMode = false;
4064
4065    // ソケットイベント
4066    if (sock->SockEvent != NULL)
4067    {
4068        ReleaseSockEvent(sock->SockEvent);
4069        sock->SockEvent = NULL;
4070    }
4071}
4072
4073// Win32 版 Select 関数
4074void Win32Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
4075{
4076    HANDLE array[MAXIMUM_WAIT_OBJECTS];
4077    UINT n, i;
4078    SOCK *s;
4079    // 引数チェック
4080    if (timeout == 0)
4081    {
4082        return;
4083    }
4084
4085    // 配列の初期化
4086    Zero(array, sizeof(array));
4087    n = 0;
4088
4089    // イベント配列の設定
4090    if (set != NULL)
4091    {
4092        for (i = 0;i < set->NumSocket;i++)
4093        {
4094            s = set->Sock[i];
4095            if (s != NULL)
4096            {
4097                Win32InitAsyncSocket(s);
4098                if (s->hEvent != NULL)
4099                {
4100                    array[n++] = (HANDLE)s->hEvent;
4101                }
4102            }
4103        }
4104    }
4105    if (c1 != NULL && c1->hEvent != NULL)
4106    {
4107        array[n++] = c1->hEvent;
4108    }
4109    if (c2 != NULL && c2->hEvent != NULL)
4110    {
4111        array[n++] = c2->hEvent;
4112    }
4113
4114    if (n == 0)
4115    {
4116        // 待つイベントが 1 つも登録されていない場合は
4117        // 通常の待ち関数を呼ぶ
4118        SleepThread(timeout);
4119    }
4120    else
4121    {
4122        // イベントが 1 つ以上登録されている場合はイベントを待つ
4123        if (n == 1)
4124        {
4125            // イベントが 1 つの場合は軽量版を呼び出す
4126            WaitForSingleObject(array[0], timeout);
4127        }
4128        else
4129        {
4130            // イベントが複数の場合
4131            WaitForMultipleObjects(n, array, false, timeout);
4132        }
4133    }
4134}
4135
4136#endif  // OS_WIN32
4137
4138// IPv6 がサポートされているかどうか調べる
4139bool IsIPv6Supported()
4140{
4141#ifdef  NO_IPV6
4142    return false;
4143#else   // NO_IPV6
4144    SOCKET s;
4145
4146    s = socket(AF_INET6, SOCK_STREAM, 0);
4147    if (s == INVALID_SOCKET)
4148    {
4149        return false;
4150    }
4151
4152    closesocket(s);
4153
4154    return true;
4155#endif  // NO_IPV6
4156}
4157
4158// ホストキャッシュからホスト名の取得
4159bool GetHostCache(char *hostname, UINT size, IP *ip)
4160{
4161    bool ret;
4162    // 引数チェック
4163    if (hostname == NULL || ip == NULL)
4164    {
4165        return false;
4166    }
4167
4168    ret = false;
4169
4170    LockList(HostCacheList);
4171    {
4172        HOSTCACHE t, *c;
4173        Zero(&t, sizeof(t));
4174        Copy(&t.IpAddress, ip, sizeof(IP));
4175
4176        c = Search(HostCacheList, &t);
4177        if (c != NULL)
4178        {
4179            if (IsEmptyStr(c->HostName) == false)
4180            {
4181                ret = true;
4182                StrCpy(hostname, size, c->HostName);
4183            }
4184            else
4185            {
4186                ret = true;
4187                StrCpy(hostname, size, "");
4188            }
4189        }
4190    }
4191    UnlockList(HostCacheList);
4192
4193    return ret;
4194}
4195
4196// ホスト名キャッシュへ追加
4197void AddHostCache(IP *ip, char *hostname)
4198{
4199    // 引数チェック
4200    if (ip == NULL || hostname == NULL)
4201    {
4202        return;
4203    }
4204    if (IsNetworkNameCacheEnabled() == false)
4205    {
4206        return;
4207    }
4208
4209    LockList(HostCacheList);
4210    {
4211        HOSTCACHE t, *c;
4212        UINT i;
4213        LIST *o;
4214
4215        Zero(&t, sizeof(t));
4216        Copy(&t.IpAddress, ip, sizeof(IP));
4217
4218        c = Search(HostCacheList, &t);
4219        if (c == NULL)
4220        {
4221            c = ZeroMalloc(sizeof(HOSTCACHE));
4222            Copy(&c->IpAddress, ip, sizeof(IP));
4223            Add(HostCacheList, c);
4224        }
4225
4226        StrCpy(c->HostName, sizeof(c->HostName), hostname);
4227        c->Expires = Tick64() + (UINT64)EXPIRES_HOSTNAME;
4228
4229        o = NewListFast(NULL);
4230
4231        for (i = 0;i < LIST_NUM(HostCacheList);i++)
4232        {
4233            HOSTCACHE *c = LIST_DATA(HostCacheList, i);
4234
4235            if (c->Expires <= Tick64())
4236            {
4237                Add(o, c);
4238            }
4239        }
4240
4241        for (i = 0;i < LIST_NUM(o);i++)
4242        {
4243            HOSTCACHE *c = LIST_DATA(o, i);
4244
4245            if (Delete(HostCacheList, c))
4246            {
4247                Free(c);
4248            }
4249        }
4250
4251        ReleaseList(o);
4252    }
4253    UnlockList(HostCacheList);
4254}
4255
4256// ホスト名キャッシュの比較
4257int CompareHostCache(void *p1, void *p2)
4258{
4259    HOSTCACHE *c1, *c2;
4260    if (p1 == NULL || p2 == NULL)
4261    {
4262        return 0;
4263    }
4264    c1 = *(HOSTCACHE **)p1;
4265    c2 = *(HOSTCACHE **)p2;
4266    if (c1 == NULL || c2 == NULL)
4267    {
4268        return 0;
4269    }
4270
4271    return CmpIpAddr(&c1->IpAddress, &c2->IpAddress);
4272}
4273
4274// ホスト名キャッシュの解放
4275void FreeHostCache()
4276{
4277    UINT i;
4278
4279    for (i = 0;i < LIST_NUM(HostCacheList);i++)
4280    {
4281        HOSTCACHE *c = LIST_DATA(HostCacheList, i);
4282
4283        Free(c);
4284    }
4285
4286    ReleaseList(HostCacheList);
4287    HostCacheList = NULL;
4288}
4289
4290// ホスト名キャッシュの初期化
4291void InitHostCache()
4292{
4293    HostCacheList = NewList(CompareHostCache);
4294}
4295
4296// スレッドをスレッド待機リストに追加する
4297void AddWaitThread(THREAD *t)
4298{
4299    // 引数チェック
4300    if (t == NULL)
4301    {
4302        return;
4303    }
4304
4305    AddRef(t->ref);
4306
4307    LockList(WaitThreadList);
4308    {
4309        Add(WaitThreadList, t);
4310    }
4311    UnlockList(WaitThreadList);
4312}
4313
4314// スレッドを待機リストから削除する
4315void DelWaitThread(THREAD *t)
4316{
4317    // 引数チェック
4318    if (t == NULL)
4319    {
4320        return;
4321    }
4322
4323    LockList(WaitThreadList);
4324    {
4325        if (Delete(WaitThreadList, t))
4326        {
4327            ReleaseThread(t);
4328        }
4329    }
4330    UnlockList(WaitThreadList);
4331}
4332
4333// スレッド待機リストの作成
4334void InitWaitThread()
4335{
4336    WaitThreadList = NewList(NULL);
4337}
4338
4339// スレッド待機リストの解放
4340void FreeWaitThread()
4341{
4342    UINT i, num;
4343    THREAD **threads;
4344
4345    LockList(WaitThreadList);
4346    {
4347        num = LIST_NUM(WaitThreadList);
4348        threads = ToArray(WaitThreadList);
4349        DeleteAll(WaitThreadList);
4350    }
4351    UnlockList(WaitThreadList);
4352
4353    for (i = 0;i < num;i++)
4354    {
4355        THREAD *t = threads[i];
4356        WaitThread(t, INFINITE);
4357        ReleaseThread(t);
4358    }
4359
4360    Free(threads);
4361
4362    ReleaseList(WaitThreadList);
4363    WaitThreadList = NULL;
4364}
4365
4366// 暗号リスト名をチェックする
4367bool CheckCipherListName(char *name)
4368{
4369    UINT i;
4370    // 引数チェック
4371    if (name == NULL)
4372    {
4373        return false;
4374    }
4375
4376    for (i = 0;i < cipher_list_token->NumTokens;i++)
4377    {
4378        if (StrCmpi(cipher_list_token->Token[i], name) == 0)
4379        {
4380            return true;
4381        }
4382    }
4383
4384    return false;
4385}
4386
4387// DHCP サーバーの IP アドレス更新
4388void RenewDhcp()
4389{
4390#ifdef  OS_WIN32
4391    Win32RenewDhcp();
4392#else
4393    UnixRenewDhcp();
4394#endif
4395}
4396
4397// UNIX 用ドメイン名を取得
4398bool UnixGetDomainName(char *name, UINT size)
4399{
4400    bool ret = false;
4401    BUF *b = ReadDump("/etc/resolv.conf");
4402
4403    if (b == NULL)
4404    {
4405        return false;
4406    }
4407
4408    while (true)
4409    {
4410        char *s = CfgReadNextLine(b);
4411        TOKEN_LIST *t;
4412
4413        if (s == NULL)
4414        {
4415            break;
4416        }
4417
4418        Trim(s);
4419
4420        t = ParseToken(s, " \t");
4421        if (t != NULL)
4422        {
4423            if (t->NumTokens == 2)
4424            {
4425                if (StrCmpi(t->Token[0], "domain") == 0)
4426                {
4427                    StrCpy(name, size, t->Token[1]);
4428                    ret = true;
4429                }
4430            }
4431            FreeToken(t);
4432        }
4433
4434        Free(s);
4435    }
4436
4437    FreeBuf(b);
4438
4439    return ret;
4440}
4441
4442// ドメイン名を取得
4443bool GetDomainName(char *name, UINT size)
4444{
4445    bool ret = false;
4446    IP ip;
4447    // 引数チェック
4448    if (name == NULL)
4449    {
4450        return false;
4451    }
4452
4453#ifdef  OS_WIN32
4454    ret = Win32GetDefaultDns(&ip, name, size);
4455#else   // OS_WIN32
4456    ret = UnixGetDomainName(name, size);
4457#endif  // OS_WIN32
4458
4459    return ret;
4460}
4461
4462// デフォルトの DNS サーバーの取得
4463bool GetDefaultDns(IP *ip)
4464{
4465    bool ret = false;
4466#ifdef  OS_WIN32
4467    ret = Win32GetDefaultDns(ip, NULL, 0);
4468#else
4469    ret = UnixGetDefaultDns(ip);
4470#endif  // OS_WIN32
4471    return ret;
4472}
4473
4474// ソケットイベントの作成
4475SOCK_EVENT *NewSockEvent()
4476{
4477    SOCK_EVENT *e = NULL;
4478#ifdef  OS_WIN32
4479    e = Win32NewSockEvent();
4480#else
4481    e = UnixNewSockEvent();
4482#endif  // OS_WIN32
4483    return e;
4484}
4485
4486// ソケットイベントのセット
4487void SetSockEvent(SOCK_EVENT *event)
4488{
4489#ifdef  OS_WIN32
4490    Win32SetSockEvent(event);
4491#else
4492    UnixSetSockEvent(event);
4493#endif  // OS_WIN32
4494}
4495
4496// ソケットイベントのクリーンアップ
4497void CleanupSockEvent(SOCK_EVENT *event)
4498{
4499#ifdef  OS_WIN32
4500    Win32CleanupSockEvent(event);
4501#else
4502    UnixCleanupSockEvent(event);
4503#endif  // OS_WIN32
4504}
4505
4506// ソケットイベントの待機
4507bool WaitSockEvent(SOCK_EVENT *event, UINT timeout)
4508{
4509    bool ret = false;
4510#ifdef  OS_WIN32
4511    ret = Win32WaitSockEvent(event, timeout);
4512#else
4513    ret = UnixWaitSockEvent(event, timeout);
4514#endif  // OS_WIN32
4515    return ret;
4516}
4517
4518// ソケットイベントの解放
4519void ReleaseSockEvent(SOCK_EVENT *event)
4520{
4521    // 引数チェック
4522    if (event == NULL)
4523    {
4524        return;
4525    }
4526
4527    if (Release(event->ref) == 0)
4528    {
4529        CleanupSockEvent(event);
4530    }
4531}
4532
4533// ソケットをソケットイベントに所属させる
4534void JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
4535{
4536#ifdef  OS_WIN32
4537    Win32JoinSockToSockEvent(sock, event);
4538#else
4539    UnixJoinSockToSockEvent(sock, event);
4540#endif  // OS_WIN32
4541}
4542
4543// 新しい特殊キャンセルオブジェクト
4544CANCEL *NewCancelSpecial(void *hEvent)
4545{
4546    CANCEL *c;
4547    // 引数チェック
4548    if (hEvent == NULL)
4549    {
4550        return NULL;
4551    }
4552
4553    c = ZeroMalloc(sizeof(CANCEL));
4554    c->ref = NewRef();
4555    c->SpecialFlag = true;
4556
4557#ifdef  OS_WIN32
4558    c->hEvent = (HANDLE)hEvent;
4559#else   // OS_WIN32
4560    c->pipe_read = (int)hEvent;
4561    c->pipe_write = -1;
4562#endif  // OS_WIN32
4563
4564    return c;
4565}
4566
4567// キャンセルオブジェクトの作成
4568CANCEL *NewCancel()
4569{
4570    CANCEL *c = NULL;
4571#ifdef  OS_WIN32
4572    c = Win32NewCancel();
4573#else
4574    c = UnixNewCancel();
4575#endif  // OS_WIN32
4576    return c;
4577}
4578
4579// キャンセルオブジェクトの解放
4580void ReleaseCancel(CANCEL *c)
4581{
4582    // 引数チェック
4583    if (c == NULL)
4584    {
4585        return;
4586    }
4587
4588    if (Release(c->ref) == 0)
4589    {
4590        CleanupCancel(c);
4591    }
4592}
4593
4594// キャンセルオブジェクトのクリーンアップ
4595void CleanupCancel(CANCEL *c)
4596{
4597#ifdef  OS_WIN32
4598    Win32CleanupCancel(c);
4599#else
4600    UnixCleanupCancel(c);
4601#endif
4602}
4603
4604// キャンセル発動
4605void Cancel(CANCEL *c)
4606{
4607#ifdef  OS_WIN32
4608    Win32Cancel(c);
4609#else
4610    UnixCancel(c);
4611#endif
4612}
4613
4614// 指定されたルーティングテーブルから最適なルートを計算する
4615ROUTE_ENTRY *GetBestRouteEntryFromRouteTable(ROUTE_TABLE *table, IP *ip)
4616{
4617    return GetBestRouteEntryFromRouteTableEx(table, ip, 0);
4618}
4619ROUTE_ENTRY *GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE *table, IP *ip, UINT exclude_if_id)
4620{
4621    UINT i;
4622    UINT max_mask = 0;
4623    UINT min_metric = INFINITE;
4624    ROUTE_ENTRY *ret = NULL;
4625    ROUTE_ENTRY *tmp = NULL;
4626    // 引数チェック
4627    if (ip == NULL || table == NULL)
4628    {
4629        return NULL;
4630    }
4631
4632    if (IsIP6(ip))
4633    {
4634        // IPv6 は非サポート
4635        return NULL;
4636    }
4637
4638    // 対象となるルーティングテーブルのうち、
4639    //  第一条件: サブネットマスクが最も大きい
4640    //  第二条件: メトリック値が最も小さい
4641    // ものを選択する
4642    for (i = 0;i < table->NumEntry;i++)
4643    {
4644        ROUTE_ENTRY *e = table->Entry[i];
4645        UINT dest, net, mask;
4646
4647        dest = IPToUINT(ip);
4648        net = IPToUINT(&e->DestIP);
4649        mask = IPToUINT(&e->DestMask);
4650
4651        if (exclude_if_id != 0)
4652        {
4653            if (e->InterfaceID == exclude_if_id)
4654            {
4655                continue;
4656            }
4657        }
4658
4659        // マスクテスト
4660        if ((dest & mask) == (net & mask))
4661        {
4662            // これはルーティングの対象となり得る
4663            if (mask >= max_mask)
4664            {
4665                max_mask = mask;
4666                if (min_metric >= e->Metric)
4667                {
4668                    min_metric = e->Metric;
4669                    tmp = e;
4670                }
4671            }
4672        }
4673    }
4674
4675    if (tmp != NULL)
4676    {
4677        UINT dest, gateway, mask;
4678
4679        // エントリを生成
4680        ret = ZeroMallocFast(sizeof(ROUTE_ENTRY));
4681
4682        Copy(&ret->DestIP, ip, sizeof(IP));
4683        ret->DestMask.addr[0] = 255;
4684        ret->DestMask.addr[1] = 255;
4685        ret->DestMask.addr[2] = 255;
4686        ret->DestMask.addr[3] = 255;
4687        Copy(&ret->GatewayIP, &tmp->GatewayIP, sizeof(IP));
4688        ret->InterfaceID = tmp->InterfaceID;
4689        ret->LocalRouting = tmp->LocalRouting;
4690        ret->OldIfMetric = tmp->Metric;
4691        ret->Metric = 1;
4692        ret->PPPConnection = tmp->PPPConnection;
4693
4694        // ルーティング制御関係の計算
4695        dest = IPToUINT(&tmp->DestIP);
4696        gateway = IPToUINT(&tmp->GatewayIP);
4697        mask = IPToUINT(&tmp->DestMask);
4698        if ((dest & mask) == (gateway & mask))
4699        {
4700#ifdef  OS_WIN32
4701            if (MsIsVista() == false)
4702            {
4703                // Windows 用調整
4704                ret->PPPConnection = true;
4705            }
4706#endif  // OS_WIN32
4707        }
4708    }
4709
4710    return ret;
4711}
4712
4713// ルーティングエントリを解放する
4714void FreeRouteEntry(ROUTE_ENTRY *e)
4715{
4716    // 引数チェック
4717    if (e == NULL)
4718    {
4719        return;
4720    }
4721
4722    Free(e);
4723}
4724
4725// 現在のルーティングテーブルを解析して最適なルートエントリを取得する
4726ROUTE_ENTRY *GetBestRouteEntry(IP *ip)
4727{
4728    return GetBestRouteEntryEx(ip, 0);
4729}
4730ROUTE_ENTRY *GetBestRouteEntryEx(IP *ip, UINT exclude_if_id)
4731{
4732    ROUTE_TABLE *table;
4733    ROUTE_ENTRY *e = NULL;
4734    // 引数チェック
4735    if (ip == NULL)
4736    {
4737        return NULL;
4738    }
4739
4740    table = GetRouteTable();
4741    if (table == NULL)
4742    {
4743        return NULL;
4744    }
4745
4746    e = GetBestRouteEntryFromRouteTableEx(table, ip, exclude_if_id);
4747    FreeRouteTable(table);
4748
4749    return e;
4750}
4751
4752// 仮想 LAN カードのインターフェース ID の取得
4753UINT GetVLanInterfaceID(char *tag_name)
4754{
4755    UINT ret = 0;
4756#ifdef  OS_WIN32
4757    ret = Win32GetVLanInterfaceID(tag_name);
4758#else   // OS_WIN32
4759    ret = UnixGetVLanInterfaceID(tag_name);
4760#endif  // OS_WIN32
4761    return ret;
4762}
4763
4764// 仮想 LAN カードの列挙変数の解放
4765void FreeEnumVLan(char **s)
4766{
4767    char *a;
4768    UINT i;
4769    // 引数チェック
4770    if (s == NULL)
4771    {
4772        return;
4773    }
4774
4775    i = 0;
4776    while (true)
4777    {
4778        a = s[i++];
4779        if (a == NULL)
4780        {
4781            break;
4782        }
4783        Free(a);
4784    }
4785
4786    Free(s);
4787}
4788
4789// 仮想 LAN カードの列挙
4790char **EnumVLan(char *tag_name)
4791{
4792    char **ret = NULL;
4793#ifdef  OS_WIN32
4794    ret = Win32EnumVLan(tag_name);
4795#else   // OS_WIN32
4796    ret = UnixEnumVLan(tag_name);
4797#endif  // OS_WIN32
4798    return ret;
4799}
4800
4801// ルーティングテーブルを表示する
4802void DebugPrintRouteTable(ROUTE_TABLE *r)
4803{
4804    UINT i;
4805    // 引数チェック
4806    if (r == NULL)
4807    {
4808        return;
4809    }
4810
4811    if (IsDebug() == false)
4812    {
4813        return;
4814    }
4815
4816    Debug("---- Routing Table (%u Entries) ----\n", r->NumEntry);
4817
4818    for (i = 0;i < r->NumEntry;i++)
4819    {
4820        Debug("   ");
4821
4822        DebugPrintRoute(r->Entry[i]);
4823    }
4824
4825    Debug("------------------------------------\n");
4826}
4827
4828// ルーティングテーブルエントリを表示する
4829void DebugPrintRoute(ROUTE_ENTRY *e)
4830{
4831    char tmp[MAX_SIZE];
4832    // 引数チェック
4833    if (e == NULL)
4834    {
4835        return;
4836    }
4837
4838    if (IsDebug() == false)
4839    {
4840        return;
4841    }
4842
4843    RouteToStr(tmp, sizeof(tmp), e);
4844
4845    Debug("%s\n", tmp);
4846}
4847
4848// ルーティングテーブルエントリを文字列にする
4849void RouteToStr(char *str, UINT str_size, ROUTE_ENTRY *e)
4850{
4851    char dest_ip[MAX_PATH];
4852    char dest_mask[MAX_PATH];
4853    char gateway_ip[MAX_PATH];
4854    // 引数チェック
4855    if (str == NULL || e == NULL)
4856    {
4857        return;
4858    }
4859
4860    IPToStr(dest_ip, sizeof(dest_ip), &e->DestIP);
4861    IPToStr(dest_mask, sizeof(dest_mask), &e->DestMask);
4862    IPToStr(gateway_ip, sizeof(gateway_ip), &e->GatewayIP);
4863
4864    Format(str, str_size, "%s/%s %s m=%u oif=%u if=%u lo=%u p=%u",
4865        dest_ip, dest_mask, gateway_ip,
4866        e->Metric, e->OldIfMetric, e->InterfaceID,
4867        e->LocalRouting, e->PPPConnection);
4868}
4869
4870// ルーティングテーブルの削除
4871void DeleteRouteEntry(ROUTE_ENTRY *e)
4872{
4873    Debug("DeleteRouteEntry();\n");
4874#ifdef  OS_WIN32
4875    Win32DeleteRouteEntry(e);
4876#else   // OS_WIN32
4877    UnixDeleteRouteEntry(e);
4878#endif
4879}
4880
4881// ルーティングテーブルの追加
4882bool AddRouteEntry(ROUTE_ENTRY *e)
4883{
4884    bool dummy = false;
4885    return AddRouteEntryEx(e, &dummy);
4886}
4887bool AddRouteEntryEx(ROUTE_ENTRY *e, bool *already_exists)
4888{
4889    bool ret = false;
4890    Debug("AddRouteEntryEx();\n");
4891#ifdef  OS_WIN32
4892    ret = Win32AddRouteEntry(e, already_exists);
4893#else   // OS_WIN32
4894    ret = UnixAddRouteEntry(e, already_exists);
4895#endif
4896    return ret;
4897}
4898
4899// ルーティングテーブルの取得
4900ROUTE_TABLE *GetRouteTable()
4901{
4902    ROUTE_TABLE *t = NULL;
4903    UINT i;
4904    BUF *buf = NewBuf();
4905    UCHAR hash[MD5_SIZE];
4906
4907#ifdef  OS_WIN32
4908    t = Win32GetRouteTable();
4909#else   //OS_WIN32
4910    t = UnixGetRouteTable();
4911#endif  // OS_WIN32
4912
4913    WriteBuf(buf, &t->NumEntry, sizeof(t->NumEntry));
4914
4915    for (i = 0;i < t->NumEntry;i++)
4916    {
4917        ROUTE_ENTRY *e = t->Entry[i];
4918
4919        WriteBuf(buf, e, sizeof(ROUTE_ENTRY));
4920    }
4921
4922    Hash(hash, buf->Buf, buf->Size, false);
4923
4924    FreeBuf(buf);
4925
4926    Copy(&t->HashedValue, hash, sizeof(t->HashedValue));
4927
4928    return t;
4929}
4930
4931// ルーティングテーブルの解放
4932void FreeRouteTable(ROUTE_TABLE *t)
4933{
4934    UINT i;
4935    // 引数チェック
4936    if (t == NULL)
4937    {
4938        return;
4939    }
4940
4941    for (i = 0;i < t->NumEntry;i++)
4942    {
4943        Free(t->Entry[i]);
4944    }
4945    Free(t->Entry);
4946    Free(t);
4947}
4948
4949// UDP 受信
4950UINT RecvFrom(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size)
4951{
4952    SOCKET s;
4953    int ret, sz;
4954    struct sockaddr_in addr;
4955    // 引数チェック
4956    if (sock == NULL || src_addr == NULL || src_port == NULL || data == NULL)
4957    {
4958        return false;
4959    }
4960    if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
4961    {
4962        return false;
4963    }
4964    if (size == 0)
4965    {
4966        return false;
4967    }
4968
4969    if (sock->IPv6)
4970    {
4971        return RecvFrom6(sock, src_addr, src_port, data, size);
4972    }
4973
4974    s = sock->socket;
4975
4976    sz = sizeof(addr);
4977    ret = recvfrom(s, data, size, 0, (struct sockaddr *)&addr, (int *)&sz);
4978    if (ret > 0)
4979    {
4980        InAddrToIP(src_addr, &addr.sin_addr);
4981        *src_port = (UINT)ntohs(addr.sin_port);
4982
4983        Lock(sock->lock);
4984        {
4985            sock->RecvNum++;
4986            sock->RecvSize += (UINT64)ret;
4987        }
4988        Unlock(sock->lock);
4989
4990        // Debug("UDP RecvFrom: %u\n", ret);
4991
4992        return (UINT)ret;
4993    }
4994    else
4995    {
4996        sock->IgnoreRecvErr = false;
4997
4998#ifdef  OS_WIN32
4999        if (WSAGetLastError() == WSAECONNRESET)
5000        {
5001            sock->IgnoreRecvErr = true;
5002        }
5003        else if (WSAGetLastError() == WSAEWOULDBLOCK)
5004        {
5005            return SOCK_LATER;
5006        }
5007        else
5008        {
5009            UINT e = WSAGetLastError();
5010//          Debug("RecvFrom Error: %u\n", e);
5011        }
5012#else   // OS_WIN32
5013        if (errno == ECONNREFUSED || errno == ECONNRESET)
5014        {
5015            sock->IgnoreRecvErr = true;
5016        }
5017        else if (errno == EAGAIN)
5018        {
5019            return SOCK_LATER;
5020        }
5021#endif  // OS_WIN32
5022        return 0;
5023    }
5024}
5025UINT RecvFrom6(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size)
5026{
5027    SOCKET s;
5028    int ret, sz;
5029    struct sockaddr_in6 addr;
5030    // 引数チェック
5031    if (sock == NULL || src_addr == NULL || src_port == NULL || data == NULL)
5032    {
5033        return false;
5034    }
5035    if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
5036    {
5037        return false;
5038    }
5039    if (size == 0)
5040    {
5041        return false;
5042    }
5043
5044    s = sock->socket;
5045
5046    sz = sizeof(addr);
5047    ret = recvfrom(s, data, size, 0, (struct sockaddr *)&addr, (int *)&sz);
5048    if (ret > 0)
5049    {
5050        InAddrToIP6(src_addr, &addr.sin6_addr);
5051        src_addr->ipv6_scope_id = addr.sin6_scope_id;
5052        *src_port = (UINT)ntohs(addr.sin6_port);
5053
5054        Lock(sock->lock);
5055        {
5056            sock->RecvNum++;
5057            sock->RecvSize += (UINT64)ret;
5058        }
5059        Unlock(sock->lock);
5060
5061        // Debug("UDP RecvFrom: %u\n", ret);
5062
5063        return (UINT)ret;
5064    }
5065    else
5066    {
5067        sock->IgnoreRecvErr = false;
5068
5069#ifdef  OS_WIN32
5070        if (WSAGetLastError() == WSAECONNRESET)
5071        {
5072            sock->IgnoreRecvErr = true;
5073        }
5074        else if (WSAGetLastError() == WSAEWOULDBLOCK)
5075        {
5076            return SOCK_LATER;
5077        }
5078        else
5079        {
5080            UINT e = WSAGetLastError();
5081            //          Debug("RecvFrom Error: %u\n", e);
5082        }
5083#else   // OS_WIN32
5084        if (errno == ECONNREFUSED || errno == ECONNRESET)
5085        {
5086            sock->IgnoreRecvErr = true;
5087        }
5088        else if (errno == EAGAIN)
5089        {
5090            return SOCK_LATER;
5091        }
5092#endif  // OS_WIN32
5093        return 0;
5094    }
5095}
5096
5097// OpenSSL のロック
5098void LockOpenSSL()
5099{
5100    Lock(openssl_lock);
5101}
5102
5103// OpenSSL のロック解除
5104void UnlockOpenSSL()
5105{
5106    Unlock(openssl_lock);
5107}
5108
5109
5110// UDP 送信
5111UINT SendTo(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size)
5112{
5113    SOCKET s;
5114    int ret;
5115    struct sockaddr_in addr;
5116    // 引数チェック
5117    if (sock == NULL || dest_addr == NULL || dest_port == 0 || data == NULL)
5118    {
5119        return 0;
5120    }
5121    if (dest_port >= 65536)
5122    {
5123        return 0;
5124    }
5125    if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
5126    {
5127        return 0;
5128    }
5129    if (size == 0)
5130    {
5131        return 0;
5132    }
5133
5134    if (sock->IPv6)
5135    {
5136        return SendTo6(sock, dest_addr, dest_port, data, size);
5137    }
5138
5139    if (IsIP4(dest_addr) == false)
5140    {
5141        return 0;
5142    }
5143
5144    s = sock->socket;
5145    Zero(&addr, sizeof(addr));
5146    addr.sin_family = AF_INET;
5147    addr.sin_port = htons((USHORT)dest_port);
5148    IPToInAddr(&addr.sin_addr, dest_addr);
5149
5150    if (dest_addr->addr[0] == 255 && dest_addr->addr[1] == 255 && 
5151        dest_addr->addr[2] == 255 && dest_addr->addr[3] == 255)
5152    {
5153        if (sock->UdpBroadcast == false)
5154        {
5155            bool yes = true;
5156
5157            sock->UdpBroadcast = true;
5158
5159            setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes));
5160        }
5161    }
5162
5163    ret = sendto(s, data, size, 0, (struct sockaddr *)&addr, sizeof(addr));
5164    if (ret != (int)size)
5165    {
5166        sock->IgnoreSendErr = false;
5167
5168#ifdef  OS_WIN32
5169        if (WSAGetLastError() == WSAECONNRESET)
5170        {
5171            sock->IgnoreSendErr = true;
5172        }
5173        else if (WSAGetLastError() == WSAEWOULDBLOCK)
5174        {
5175            return SOCK_LATER;
5176        }
5177        else
5178        {
5179            UINT e = WSAGetLastError();
5180        }
5181#else   // OS_WIN32
5182        if (errno == ECONNREFUSED || errno == ECONNRESET)
5183        {
5184            sock->IgnoreRecvErr = true;
5185        }
5186        else if (errno == EAGAIN)
5187        {
5188            return SOCK_LATER;
5189        }
5190#endif  // OS_WIN32
5191        return 0;
5192    }
5193
5194    Lock(sock->lock);
5195    {
5196        sock->SendSize += (UINT64)size;
5197        sock->SendNum++;
5198    }
5199    Unlock(sock->lock);
5200
5201    return ret;
5202}
5203UINT SendTo6(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size)
5204{
5205    SOCKET s;
5206    int ret;
5207    struct sockaddr_in6 addr;
5208    UINT type;
5209    // 引数チェック
5210    if (sock == NULL || dest_addr == NULL || dest_port == 0 || data == NULL)
5211    {
5212        return 0;
5213    }
5214    if (dest_port >= 65536)
5215    {
5216        return 0;
5217    }
5218    if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
5219    {
5220        return 0;
5221    }
5222    if (size == 0)
5223    {
5224        return 0;
5225    }
5226
5227    if (IsIP6(dest_addr) == false)
5228    {
5229        return 0;
5230    }
5231
5232    s = sock->socket;
5233    Zero(&addr, sizeof(addr));
5234    addr.sin6_family = AF_INET6;
5235    addr.sin6_port = htons((USHORT)dest_port);
5236    IPToInAddr6(&addr.sin6_addr, dest_addr);
5237    addr.sin6_scope_id = dest_addr->ipv6_scope_id;
5238
5239    type = GetIPAddrType6(dest_addr);
5240
5241    if (type & IPV6_ADDR_MULTICAST)
5242    {
5243        if (sock->UdpBroadcast == false)
5244        {
5245            bool yes = true;
5246
5247            sock->UdpBroadcast = true;
5248
5249            setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes));
5250        }
5251    }
5252
5253    ret = sendto(s, data, size, 0, (struct sockaddr *)&addr, sizeof(addr));
5254    if (ret != (int)size)
5255    {
5256        sock->IgnoreSendErr = false;
5257
5258#ifdef  OS_WIN32
5259        if (WSAGetLastError() == WSAECONNRESET)
5260        {
5261            sock->IgnoreSendErr = true;
5262        }
5263        else if (WSAGetLastError() == WSAEWOULDBLOCK)
5264        {
5265            return SOCK_LATER;
5266        }
5267        else
5268        {
5269            UINT e = WSAGetLastError();
5270        }
5271#else   // OS_WIN32
5272        if (errno == ECONNREFUSED || errno == ECONNRESET)
5273        {
5274            sock->IgnoreRecvErr = true;
5275        }
5276        else if (errno == EAGAIN)
5277        {
5278            return SOCK_LATER;
5279        }
5280#endif  // OS_WIN32
5281        return 0;
5282    }
5283
5284    Lock(sock->lock);
5285    {
5286        sock->SendSize += (UINT64)size;
5287        sock->SendNum++;
5288    }
5289    Unlock(sock->lock);
5290
5291    return ret;
5292}
5293
5294// UDP ソケットの作成と初期化
5295// port が 0 の場合は OS がランダムに割り当てる
5296SOCK *NewUDP(UINT port)
5297{
5298    return NewUDPEx(port, false);
5299}
5300SOCK *NewUDPEx(UINT port, bool ipv6)
5301{
5302    if (ipv6 == false)
5303    {
5304        return NewUDP4(port);
5305    }
5306    else
5307    {
5308        return NewUDP6(port);
5309    }
5310}
5311SOCK *NewUDP4(UINT port)
5312{
5313    SOCK *sock;
5314    SOCKET s;
5315    struct sockaddr_in addr;
5316
5317    s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
5318    if (s == INVALID_SOCKET)
5319    {
5320        return NULL;
5321    }
5322
5323    Zero(&addr, sizeof(addr));
5324    addr.sin_family = AF_INET;
5325    addr.sin_addr.s_addr = htonl(INADDR_ANY);
5326    if (port == 0)
5327    {
5328        addr.sin_port = 0;
5329    }
5330    else
5331    {
5332        addr.sin_port = htons((USHORT)port);
5333    }
5334
5335    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
5336    {
5337        // 失敗
5338        closesocket(s);
5339        return NULL;
5340    }
5341
5342    sock = NewSock();
5343
5344    sock->Type = SOCK_UDP;
5345    sock->Connected = false;
5346    sock->AsyncMode = false;
5347    sock->ServerMode = false;
5348    if (port != 0)
5349    {
5350        sock->ServerMode = true;
5351    }
5352
5353    sock->socket = s;
5354
5355    QuerySocketInformation(sock);
5356
5357    return sock;
5358}
5359SOCK *NewUDP6(UINT port)
5360{
5361    SOCK *sock;
5362    SOCKET s;
5363    struct sockaddr_in6 addr;
5364
5365    s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
5366    if (s == INVALID_SOCKET)
5367    {
5368        return NULL;
5369    }
5370
5371    Zero(&addr, sizeof(addr));
5372    addr.sin6_family = AF_INET6;
5373    if (port == 0)
5374    {
5375        addr.sin6_port = 0;
5376    }
5377    else
5378    {
5379        addr.sin6_port = htons((USHORT)port);
5380    }
5381
5382    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
5383    {
5384        // 失敗
5385        closesocket(s);
5386        return NULL;
5387    }
5388
5389    sock = NewSock();
5390
5391    sock->Type = SOCK_UDP;
5392    sock->Connected = false;
5393    sock->AsyncMode = false;
5394    sock->ServerMode = false;
5395    sock->IPv6 = true;
5396    if (port != 0)
5397    {
5398        sock->ServerMode = true;
5399    }
5400
5401    sock->socket = s;
5402
5403    QuerySocketInformation(sock);
5404
5405    return sock;
5406}
5407
5408// Select 関数
5409void Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
5410{
5411#ifdef  OS_WIN32
5412    Win32Select(set, timeout, c1, c2);
5413#else
5414    UnixSelect(set, timeout, c1, c2);
5415#endif  // OS_WIN32
5416}
5417
5418// ソケットセットにソケットを追加
5419void AddSockSet(SOCKSET *set, SOCK *sock)
5420{
5421    // 引数チェック
5422    if (set == NULL || sock == NULL)
5423    {
5424        return;
5425    }
5426    if (sock->Type == SOCK_TCP && sock->Connected == false)
5427    {
5428        return;
5429    }
5430
5431    if (set->NumSocket >= MAX_SOCKSET_NUM)
5432    {
5433        // 上限
5434        return;
5435    }
5436    set->Sock[set->NumSocket++] = sock;
5437}
5438
5439// ソケットセットの初期化
5440void InitSockSet(SOCKSET *set)
5441{
5442    // 引数チェック
5443    if (set == NULL)
5444    {
5445        return;
5446    }
5447
5448    Zero(set, sizeof(SOCKSET));
5449}
5450
5451// TCP すべて受信
5452bool RecvAll(SOCK *sock, void *data, UINT size, bool secure)
5453{
5454    UINT recv_size, sz, ret;
5455    // 引数チェック
5456    if (sock == NULL || data == NULL)
5457    {
5458        return false;
5459    }
5460    if (size == 0)
5461    {
5462        return true;
5463    }
5464    if (sock->AsyncMode)
5465    {
5466        return false;
5467    }
5468
5469    recv_size = 0;
5470
5471    while (true)
5472    {
5473        sz = size - recv_size;
5474        ret = Recv(sock, (UCHAR *)data + recv_size, sz, secure);
5475        if (ret == 0)
5476        {
5477            return false;
5478        }
5479        recv_size += ret;
5480        if (recv_size >= size)
5481        {
5482            return true;
5483        }
5484    }
5485}
5486
5487// TCP 送信バッファを送信する
5488bool SendNow(SOCK *sock, int secure)
5489{
5490    bool ret;
5491    // 引数チェック
5492    if (sock == NULL || sock->AsyncMode != false)
5493    {
5494        return false;
5495    }
5496    if (sock->SendBuf->Size == 0)
5497    {
5498        return true;
5499    }
5500
5501    ret = SendAll(sock, sock->SendBuf->Buf, sock->SendBuf->Size, secure);
5502    ClearBuf(sock->SendBuf);
5503
5504    return ret;
5505}
5506
5507// TCP 送信バッファ追加
5508void SendAdd(SOCK *sock, void *data, UINT size)
5509{
5510    // 引数チェック
5511    if (sock == NULL || data == NULL || size == 0 || sock->AsyncMode != false)
5512    {
5513        return;
5514    }
5515
5516    WriteBuf(sock->SendBuf, data, size);
5517}
5518
5519// TCP すべて送信
5520bool SendAll(SOCK *sock, void *data, UINT size, bool secure)
5521{
5522    UCHAR *buf;
5523    UINT sent_size;
5524    UINT ret;
5525    // 引数チェック
5526    if (sock == NULL || data == NULL)
5527    {
5528        return false;
5529    }
5530    if (sock->AsyncMode)
5531    {
5532        return false;
5533    }
5534    if (size == 0)
5535    {
5536        return true;
5537    }
5538
5539    buf = (UCHAR *)data;
5540    sent_size = 0;
5541
5542    while (true)
5543    {
5544        ret = Send(sock, buf, size - sent_size, secure);
5545        if (ret == 0)
5546        {
5547            return false;
5548        }
5549        sent_size += ret;
5550        buf += ret;
5551        if (sent_size >= size)
5552        {
5553            return true;
5554        }
5555    }
5556}
5557
5558// 使用したい暗号化アルゴリズム名を設定する
5559void SetWantToUseCipher(SOCK *sock, char *name)
5560{
5561    // 引数チェック
5562    if (sock == NULL || name == NULL)
5563    {
5564        return;
5565    }
5566
5567    if (sock->WaitToUseCipher)
5568    {
5569        Free(sock->WaitToUseCipher);
5570    }
5571    sock->WaitToUseCipher = CopyStr(name);
5572}
5573
5574// TCP-SSL 通信を開始する
5575bool StartSSL(SOCK *sock, X *x, K *priv)
5576{
5577    return StartSSLEx(sock, x, priv, false);
5578}
5579bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls)
5580{
5581    X509 *x509;
5582    EVP_PKEY *key;
5583    UINT prev_timeout = 1024;
5584
5585#ifdef UNIX_SOLARIS
5586    SOCKET_TIMEOUT_PARAM *ttparam;
5587#endif //UNIX_SOLARIS
5588
5589    // 引数チェック
5590    if (sock == NULL)
5591    {
5592        Debug("StartSSL Error: #0\n");
5593        return false;
5594    }
5595    if (sock->Connected == false || sock->socket == INVALID_SOCKET ||
5596        sock->ListenMode != false)
5597    {
5598        Debug("StartSSL Error: #1\n");
5599        return false;
5600    }
5601    if (x != NULL && priv == NULL)
5602    {
5603        Debug("StartSSL Error: #2\n");
5604        return false;
5605    }
5606
5607    if (sock->SecureMode)
5608    {
5609        Debug("StartSSL Error: #3\n");
5610        // すでに SSL 通信が開始されている
5611        return true;
5612    }
5613
5614    Lock(sock->ssl_lock);
5615    if (sock->SecureMode)
5616    {
5617        Debug("StartSSL Error: #4\n");
5618        // すでに SSL 通信が開始されている
5619        Unlock(sock->ssl_lock);
5620        return true;
5621    }
5622
5623    Lock(openssl_lock);
5624    {
5625        if (sock->ServerMode)
5626        {
5627            SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
5628        }
5629        else
5630        {
5631            if (client_tls == false)
5632            {
5633                SSL_CTX_set_ssl_version(ssl_ctx, SSLv3_method());
5634            }
5635            else
5636            {
5637                SSL_CTX_set_ssl_version(ssl_ctx, TLSv1_client_method());
5638            }
5639        }
5640        sock->ssl = SSL_new(ssl_ctx);
5641        SSL_set_fd(sock->ssl, (int)sock->socket);
5642    }
5643    Unlock(openssl_lock);
5644
5645    if (x != NULL)
5646    {
5647        // 証明書と秘密鍵のチェック
5648        if (CheckXandK(x, priv))
5649        {
5650            // 証明書を使用する
5651            x509 = x->x509;
5652            key = priv->pkey;
5653
5654            Lock(openssl_lock);
5655            {
5656                SSL_use_certificate(sock->ssl, x509);
5657                SSL_use_PrivateKey(sock->ssl, key);
5658            }
5659            Unlock(openssl_lock);
5660        }
5661    }
5662
5663    if (sock->WaitToUseCipher != NULL)
5664    {
5665        // 使用したい暗号化アルゴリズム名を設定する
5666        Lock(openssl_lock);
5667        {
5668            SSL_set_cipher_list(sock->ssl, sock->WaitToUseCipher);
5669        }
5670        Unlock(openssl_lock);
5671    }
5672
5673    if (sock->ServerMode)
5674    {
5675//      Lock(ssl_connect_lock);
5676
5677// SOLARIS用タイムアウトスレッドの起動
5678#ifdef UNIX_SOLARIS
5679        ttparam = NewSocketTimeout(sock);
5680#endif // UNIX_SOLARIS
5681
5682        // サーバーモード
5683        if (SSL_accept(sock->ssl) <= 0)
5684        {
5685
5686// タイムアウトスレッドの停止
5687#ifdef UNIX_SOLARIS
5688            FreeSocketTimeout(ttparam);
5689#endif // UNIX_SOLARIS
5690
5691            //          Unlock(ssl_connect_lock);
5692            // SSL-Accept 失敗
5693            Lock(openssl_lock);
5694            {
5695                SSL_free(sock->ssl);
5696            }
5697            Unlock(openssl_lock);
5698
5699            Unlock(sock->ssl_lock);
5700            Debug("StartSSL Error: #5\n");
5701            return false;
5702        }
5703
5704// タイムアウトスレッドの停止
5705#ifdef UNIX_SOLARIS
5706        FreeSocketTimeout(ttparam);
5707#endif // UNIX_SOLARIS
5708
5709        //      Unlock(ssl_connect_lock);
5710    }
5711    else
5712    {
5713        prev_timeout = GetTimeout(sock);
5714        SetTimeout(sock, TIMEOUT_SSL_CONNECT);
5715        Lock(ssl_connect_lock);
5716        // クライアントモード
5717        if (SSL_connect(sock->ssl) <= 0)
5718        {
5719            Unlock(ssl_connect_lock);
5720            // SSL-connect 失敗
5721            Lock(openssl_lock);
5722            {
5723                SSL_free(sock->ssl);
5724            }
5725            Unlock(openssl_lock);
5726
5727            Unlock(sock->ssl_lock);
5728            Debug("StartSSL Error: #5\n");
5729            SetTimeout(sock, prev_timeout);
5730            return false;
5731        }
5732        Unlock(ssl_connect_lock);
5733        SetTimeout(sock, prev_timeout);
5734    }
5735
5736    // SSL 通信が開始された
5737    sock->SecureMode = true;
5738
5739    // リモートホストの証明書を取得する
5740    Lock(openssl_lock);
5741    {
5742        x509 = SSL_get_peer_certificate(sock->ssl);
5743    }
5744    Unlock(openssl_lock);
5745
5746    if (x509 == NULL)
5747    {
5748        // リモートホストに証明書は存在しない
5749        sock->RemoteX = NULL;
5750    }
5751    else
5752    {
5753        // 証明書を取得できた
5754        sock->RemoteX = X509ToX(x509);
5755    }
5756
5757    // ローカルホストの証明書を取得する
5758    Lock(openssl_lock);
5759    {
5760        x509 = SSL_get_certificate(sock->ssl);
5761    }
5762    Unlock(openssl_lock);
5763
5764    if (x509 == NULL)
5765    {
5766        // リモートホストに証明書は存在しない
5767        sock->LocalX = NULL;
5768    }
5769    else
5770    {
5771        X *local_x;
5772        // 証明書を取得できた
5773        local_x = X509ToX(x509);
5774        local_x->do_not_free = true;
5775        sock->LocalX = CloneX(local_x);
5776        FreeX(local_x);
5777    }
5778
5779    // 自動再試行モード
5780    SSL_set_mode(sock->ssl, SSL_MODE_AUTO_RETRY);
5781
5782    // へんなフラグ
5783    SSL_set_mode(sock->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
5784
5785    // 暗号化に使用しているアルゴリズム名を取得
5786    Lock(openssl_lock);
5787    {
5788        sock->CipherName = CopyStr((char *)SSL_get_cipher(sock->ssl));
5789    }
5790    Unlock(openssl_lock);
5791
5792    Unlock(sock->ssl_lock);
5793
5794    return true;
5795}
5796
5797// TCP-SSL 受信
5798UINT SecureRecv(SOCK *sock, void *data, UINT size)
5799{
5800    SOCKET s;
5801    int ret, e = 0;
5802    SSL *ssl;
5803
5804#ifdef UNIX_SOLARIS
5805    SOCKET_TIMEOUT_PARAM *ttparam;
5806#endif //UNIX_SOLARIS
5807
5808    s = sock->socket;
5809    ssl = sock->ssl;
5810
5811    if (sock->AsyncMode)
5812    {
5813        // 非同期モードの場合はデータが 1 バイトでも読み出し可能かどうか確認する。
5814        // 読み出し可能なデータが無い場合に read をしてしまうとブロッキングするため
5815        // それは避けなければならない。
5816        char c;
5817        Lock(sock->ssl_lock);
5818        {
5819            if (sock->Connected == false)
5820            {
5821                Unlock(sock->ssl_lock);
5822                Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
5823                return 0;
5824            }
5825            ret = SSL_peek(ssl, &c, sizeof(c));
5826        }
5827        Unlock(sock->ssl_lock);
5828        if (ret == 0)
5829        {
5830            // 通信が切れておる
5831            Disconnect(sock);
5832            Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
5833            return 0;
5834        }
5835        if (ret < 0)
5836        {
5837            // エラーが発生した
5838            e = SSL_get_error(ssl, ret);
5839            if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
5840            {
5841                // パケットがまだ届いていない、つまり read してはいけない
5842                return SOCK_LATER;
5843            }
5844        }
5845    }
5846
5847    // 受信する
5848    Lock(sock->ssl_lock);
5849    {
5850        if (sock->Connected == false)
5851        {
5852            Unlock(sock->ssl_lock);
5853            Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
5854            return 0;
5855        }
5856
5857#ifdef  OS_UNIX
5858        if (sock->AsyncMode == false)
5859        {
5860            sock->CallingThread = pthread_self();
5861        }
5862#endif  // OS_UNIX
5863
5864// SOLARIS用タイムアウトスレッドの起動
5865#ifdef UNIX_SOLARIS
5866        ttparam = NewSocketTimeout(sock);
5867#endif // UNIX_SOLARIS
5868
5869        ret = SSL_read(ssl, data, size);
5870
5871// タイムアウトスレッドの停止
5872#ifdef UNIX_SOLARIS
5873        FreeSocketTimeout(ttparam);
5874#endif // UNIX_SOLARIS
5875
5876
5877#ifdef  OS_UNIX
5878        if (sock->AsyncMode == false)
5879        {
5880            sock->CallingThread = 0;
5881        }
5882#endif  // OS_UNIX
5883
5884        if (ret < 0)
5885        {
5886            e = SSL_get_error(ssl, ret);
5887        }
5888
5889    }
5890    Unlock(sock->ssl_lock);
5891    if (ret > 0)
5892    {
5893        // 受信成功
5894        sock->RecvSize += (UINT64)ret;
5895        sock->RecvNum++;
5896        return (UINT)ret;
5897    }
5898    if (ret == 0)
5899    {
5900        // 通信切断
5901        Disconnect(sock);
5902        Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
5903        return 0;
5904    }
5905    if (sock->AsyncMode)
5906    {
5907        if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
5908        {
5909            // パケットがまだ届いていない
5910            return SOCK_LATER;
5911        }
5912    }
5913    Disconnect(sock);
5914    Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
5915    return 0;
5916}
5917
5918// TCP-SSL 送信
5919UINT SecureSend(SOCK *sock, void *data, UINT size)
5920{
5921    SOCKET s;
5922    int ret, e;
5923    SSL *ssl;
5924    s = sock->socket;
5925    ssl = sock->ssl;
5926
5927    if (sock->AsyncMode)
5928    {
5929        // 非同期モード
5930        SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
5931    }
5932
5933    // 送信
5934    Lock(sock->ssl_lock);
5935    {
5936        if (sock->Connected == false)
5937        {
5938            Unlock(sock->ssl_lock);
5939            Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
5940            return 0;
5941        }
5942
5943        ret = SSL_write(ssl, data, size);
5944        if (ret < 0)
5945        {
5946            e = SSL_get_error(ssl, ret);
5947        }
5948    }
5949    Unlock(sock->ssl_lock);
5950
5951    if (ret > 0)
5952    {
5953        // 送信成功
5954        sock->SendSize += (UINT64)ret;
5955        sock->SendNum++;
5956        sock->WriteBlocked = false;
5957        return (UINT)ret;
5958    }
5959    if (ret == 0)
5960    {
5961        // 切断
5962        Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
5963        Disconnect(sock);
5964        return 0;
5965    }
5966
5967    if (sock->AsyncMode)
5968    {
5969        // エラー値の確認
5970        if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
5971        {
5972            sock->WriteBlocked = true;
5973            return SOCK_LATER;
5974        }
5975        Debug("%s %u e=%u\n", __FILE__, __LINE__, e);
5976    }
5977    //Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
5978    Disconnect(sock);
5979    return 0;
5980}
5981
5982// TCP 受信
5983UINT Recv(SOCK *sock, void *data, UINT size, bool secure)
5984{
5985    SOCKET s;
5986    int ret;
5987
5988#ifdef UNIX_SOLARIS
5989    SOCKET_TIMEOUT_PARAM *ttparam;
5990#endif //UNIX_SOLARIS
5991
5992    // 引数チェック
5993    if (sock == NULL || data == NULL || size == 0)
5994    {
5995        return 0;
5996    }
5997    if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
5998        sock->socket == INVALID_SOCKET)
5999    {
6000        return 0;
6001    }
6002    if (secure != false && sock->SecureMode == false)
6003    {
6004        return 0;
6005    }
6006
6007    if (secure)
6008    {
6009        return SecureRecv(sock, data, size);
6010    }
6011
6012    // 受信
6013    s = sock->socket;
6014
6015
6016#ifdef  OS_UNIX
6017    if (sock->AsyncMode == false)
6018    {
6019        sock->CallingThread = pthread_self();
6020    }
6021#endif  // OS_UNIX
6022
6023// SOLARIS用タイムアウトスレッドの開始
6024#ifdef UNIX_SOLARIS
6025    ttparam = NewSocketTimeout(sock);
6026#endif // UNIX_SOLARIS
6027
6028    ret = recv(s, data, size, 0);
6029
6030// タイムアウトスレッドの停止
6031#ifdef UNIX_SOLARIS
6032    FreeSocketTimeout(ttparam);
6033#endif // UNIX_SOLARIS
6034
6035#ifdef  OS_UNIX
6036    if (sock->AsyncMode == false)
6037    {
6038        sock->CallingThread = 0;
6039    }
6040#endif  // OS_UNIX
6041
6042    if (ret > 0)
6043    {
6044        // 受信成功
6045        Lock(sock->lock);
6046        {
6047            sock->RecvSize += (UINT64)ret;
6048            sock->SendNum++;
6049        }
6050        Unlock(sock->lock);
6051        return (UINT)ret;
6052    }
6053
6054    // 送信失敗
6055    if (sock->AsyncMode)
6056    {
6057        // 非同期モードの場合、エラーを調べる
6058        if (ret == SOCKET_ERROR)
6059        {
6060#ifdef  OS_WIN32
6061            if (WSAGetLastError() == WSAEWOULDBLOCK)
6062            {
6063                // ブロッキングしている
6064                return SOCK_LATER;
6065            }
6066            else
6067            {
6068                Debug("Socket Error: %u\n", WSAGetLastError());
6069            }
6070#else   // OS_WIN32
6071            if (errno == EAGAIN)
6072            {
6073                // ブロッキングしている
6074                return SOCK_LATER;
6075            }
6076#endif  // OS_WIN32
6077        }
6078    }
6079
6080    // 切断された
6081    Disconnect(sock);
6082    return 0;
6083}
6084
6085// TCP 送信
6086UINT Send(SOCK *sock, void *data, UINT size, bool secure)
6087{
6088    SOCKET s;
6089    int ret;
6090    // 引数チェック
6091    if (sock == NULL || data == NULL || size == 0)
6092    {
6093        return 0;
6094    }
6095    size = MIN(size, MAX_SEND_BUF_MEM_SIZE);
6096    if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
6097        sock->socket == INVALID_SOCKET)
6098    {
6099        return 0;
6100    }
6101    if (secure != false && sock->SecureMode == false)
6102    {
6103        return 0;
6104    }
6105
6106    if (secure)
6107    {
6108        return SecureSend(sock, data, size);
6109    }
6110
6111    // 送信
6112    s = sock->socket;
6113    ret = send(s, data, size, 0);
6114    if (ret > 0)
6115    {
6116        // 送信成功
6117        Lock(sock->lock);
6118        {
6119            sock->SendSize += (UINT64)ret;
6120            sock->SendNum++;
6121        }
6122        Unlock(sock->lock);
6123        sock->WriteBlocked = false;
6124        return (UINT)ret;
6125    }
6126
6127    // 送信失敗
6128    if (sock->AsyncMode)
6129    {
6130        // 非同期モードの場合、エラーを調べる
6131        if (ret == SOCKET_ERROR)
6132        {
6133#ifdef  OS_WIN32
6134            if (WSAGetLastError() == WSAEWOULDBLOCK)
6135            {
6136                // ブロッキングしている
6137                sock->WriteBlocked = true;
6138                return SOCK_LATER;
6139            }
6140            else
6141            {
6142                Debug("Socket Error: %u\n", WSAGetLastError());
6143            }
6144#else   // OS_WIN32
6145            if (errno == EAGAIN)
6146            {
6147                // ブロッキングしている
6148                sock->WriteBlocked = true;
6149                return SOCK_LATER;
6150            }
6151#endif  // OS_WIN32
6152        }
6153    }
6154
6155    // 切断された
6156    Disconnect(sock);
6157    return 0;
6158}
6159
6160// タイムアウトの取得 (ミリ秒)
6161UINT GetTimeout(SOCK *sock)
6162{
6163    // 引数チェック
6164    if (sock == NULL)
6165    {
6166        return INFINITE;
6167    }
6168    if (sock->Type != SOCK_TCP)
6169    {
6170        return INFINITE;
6171    }
6172
6173    return sock->TimeOut;
6174}
6175
6176// タイムアウト時間の設定 (ミリ秒)
6177void SetTimeout(SOCK *sock, UINT timeout)
6178{
6179    // 引数チェック
6180    if (sock == NULL)
6181    {
6182        return;
6183    }
6184    if (sock->Type != SOCK_TCP)
6185    {
6186        return;
6187    }
6188
6189    if (timeout == INFINITE)
6190    {
6191        timeout = TIMEOUT_INFINITE;
6192    }
6193
6194    sock->TimeOut = timeout;
6195
6196//  Debug("SetTimeout(%u)\n",timeout);
6197
6198#ifdef OS_WIN32
6199    setsockopt(sock->socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(UINT));
6200    setsockopt(sock->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(UINT));
6201#endif
6202
6203#ifdef OS_UNIX
6204#ifndef UNIX_SOLARIS
6205    {
6206        struct timeval tv_timeout;
6207
6208        tv_timeout.tv_sec = timeout / 1000; // miliseconds to seconds
6209        tv_timeout.tv_usec = (timeout % 1000) * 1000; // miliseconds to microseconds
6210
6211        setsockopt(sock->socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv_timeout, sizeof(tv_timeout));
6212        setsockopt(sock->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv_timeout, sizeof(tv_timeout));
6213    }
6214#endif // UNIX_SOLARIS
6215#endif // OS_UNIX
6216}
6217
6218// 接続受諾初期化
6219void AcceptInit(SOCK *s)
6220{
6221    char tmp[MAX_SIZE];
6222    // 引数チェック
6223    if (s == NULL)
6224    {
6225        return;
6226    }
6227
6228    Zero(tmp, sizeof(tmp));
6229    if (GetHostName(tmp, sizeof(tmp), &s->RemoteIP) == false ||
6230        IsEmptyStr(tmp))
6231    {
6232        IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
6233    }
6234
6235    s->RemoteHostname = CopyStr(tmp);
6236}
6237
6238// TCP 接続受諾
6239SOCK *Accept(SOCK *sock)
6240{
6241    SOCK *ret;
6242    SOCKET s, new_socket;
6243    int size;
6244    struct sockaddr_in addr;
6245    bool true_flag = true;
6246    // 引数チェック
6247    if (sock == NULL)
6248    {
6249        return NULL;
6250    }
6251    if (sock->ListenMode == false || sock->Type != SOCK_TCP || sock->ServerMode == false)
6252    {
6253        return NULL;
6254    }
6255    if (sock->CancelAccept)
6256    {
6257        return NULL;
6258    }
6259    if (sock->IPv6)
6260    {
6261        return Accept6(sock);
6262    }
6263
6264    s = sock->socket;
6265    if (s == INVALID_SOCKET)
6266    {
6267        return NULL;
6268    }
6269    Zero(&addr, sizeof(addr));
6270    size = sizeof(addr);
6271
6272#ifdef  OS_UNIX
6273    sock->CallingThread = pthread_self();
6274#endif  // OS_UNIX
6275
6276    new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
6277
6278#ifdef  OS_UNIX
6279    sock->CallingThread = 0;
6280#endif  // OS_UNIX
6281
6282    if (new_socket == INVALID_SOCKET)
6283    {
6284        return NULL;
6285    }
6286    if (sock->CancelAccept)
6287    {
6288        closesocket(new_socket);
6289        return NULL;
6290    }
6291
6292    ret = NewSock();
6293    ret->socket = new_socket;
6294    ret->Connected = true;
6295    ret->AsyncMode = false;
6296    ret->Type = SOCK_TCP;
6297    ret->ServerMode = true;
6298    ret->SecureMode = false;
6299
6300    // TCP オプションの設定
6301    setsockopt(ret->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
6302
6303    SetSockPriorityHigh(ret);
6304
6305    // タイムアウト値の初期化
6306    SetTimeout(ret, TIMEOUT_INFINITE);
6307
6308    // ソケット情報
6309    QuerySocketInformation(ret);
6310
6311    AddIpClient(&ret->RemoteIP);
6312
6313    return ret;
6314}
6315SOCK *Accept6(SOCK *sock)
6316{
6317    SOCK *ret;
6318    SOCKET s, new_socket;
6319    int size;
6320    struct sockaddr_in6 addr;
6321    bool true_flag = true;
6322    // 引数チェック
6323    if (sock == NULL)
6324    {
6325        return NULL;
6326    }
6327    if (sock->ListenMode == false || sock->Type != SOCK_TCP || sock->ServerMode == false)
6328    {
6329        return NULL;
6330    }
6331    if (sock->CancelAccept)
6332    {
6333        return NULL;
6334    }
6335    if (sock->IPv6 == false)
6336    {
6337        return NULL;
6338    }
6339
6340    s = sock->socket;
6341    if (s == INVALID_SOCKET)
6342    {
6343        return NULL;
6344    }
6345    Zero(&addr, sizeof(addr));
6346    size = sizeof(addr);
6347
6348#ifdef  OS_UNIX
6349    sock->CallingThread = pthread_self();
6350#endif  // OS_UNIX
6351
6352    new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
6353
6354#ifdef  OS_UNIX
6355    sock->CallingThread = 0;
6356#endif  // OS_UNIX
6357
6358    if (new_socket == INVALID_SOCKET)
6359    {
6360        return NULL;
6361    }
6362    if (sock->CancelAccept)
6363    {
6364        closesocket(new_socket);
6365        return NULL;
6366    }
6367
6368    ret = NewSock();
6369    ret->socket = new_socket;
6370    ret->Connected = true;
6371    ret->AsyncMode = false;
6372    ret->Type = SOCK_TCP;
6373    ret->ServerMode = true;
6374    ret->SecureMode = false;
6375
6376    // TCP オプションの設定
6377    setsockopt(ret->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
6378
6379    SetSockPriorityHigh(ret);
6380
6381    // タイムアウト値の初期化
6382    SetTimeout(ret, TIMEOUT_INFINITE);
6383
6384    // ソケット情報
6385    QuerySocketInformation(ret);
6386
6387    AddIpClient(&ret->RemoteIP);
6388
6389    return ret;
6390}
6391
6392// TCP 待ち受け (IPv6)
6393SOCK *Listen6(UINT port)
6394{
6395    return ListenEx6(port, false);
6396}
6397SOCK *ListenEx6(UINT port, bool local_only)
6398{
6399    SOCKET s;
6400    SOCK *sock;
6401    struct sockaddr_in6 addr;
6402    struct in6_addr in;
6403    bool true_flag = true;
6404    IP localhost;
6405    // 引数チェック
6406    if (port == 0 || port >= 65536)
6407    {
6408        return NULL;
6409    }
6410
6411    // 初期化
6412    Zero(&addr, sizeof(addr));
6413    Zero(&in, sizeof(in));
6414    GetLocalHostIP6(&localhost);
6415
6416    addr.sin6_port = htons((UINT)port);
6417    addr.sin6_family = AF_INET6;
6418
6419    if (local_only)
6420    {
6421        IPToInAddr6(&addr.sin6_addr, &localhost);
6422    }
6423
6424    // ソケットの作成
6425    s = socket(AF_INET6, SOCK_STREAM, 0);
6426    if (s == INVALID_SOCKET)
6427    {
6428        return NULL;
6429    }
6430
6431#ifdef  OS_UNIX
6432    // UNIX 系では IPv6 Only フラグを立てる必要がある
6433    setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &true_flag, sizeof(true_flag));
6434#endif  // OS_UNIX
6435
6436    //SetSocketSendRecvBufferSize(s, SOCKET_BUFFER_SIZE);
6437
6438#ifdef  OS_UNIX
6439    // Windows 系 OS は REUSEADDR の実装にバグがあるっぽいので
6440    // UNIX 系のみ有効にした。
6441    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
6442#endif  // OS_UNIX
6443
6444    if (bind(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) != 0)
6445    {
6446        // bind 失敗
6447        closesocket(s);
6448        return NULL;
6449    }
6450    if (listen(s, SOMAXCONN))
6451    {
6452        // listen 失敗
6453        closesocket(s);
6454        return NULL;
6455    }
6456
6457    // 成功
6458    sock = NewSock();
6459    sock->Connected = false;
6460    sock->AsyncMode = false;
6461    sock->ServerMode = true;
6462    sock->Type = SOCK_TCP;
6463    sock->socket = s;
6464    sock->ListenMode = true;
6465    sock->SecureMode = false;
6466    sock->LocalPort = port;
6467    sock->IPv6 = true;
6468
6469    return sock;
6470}
6471
6472// TCP 待ち受け
6473SOCK *Listen(UINT port)
6474{
6475    return ListenEx(port, false);
6476}
6477SOCK *ListenEx(UINT port, bool local_only)
6478{
6479    SOCKET s;
6480    SOCK *sock;
6481    struct sockaddr_in addr;
6482    struct in_addr in;
6483    bool true_flag = true;
6484    IP localhost;
6485    // 引数チェック
6486    if (port == 0 || port >= 65536)
6487    {
6488        return NULL;
6489    }
6490
6491    // 初期化
6492    Zero(&addr, sizeof(addr));
6493    Zero(&in, sizeof(in));
6494    SetIP(&localhost, 127, 0, 0, 1);
6495
6496    addr.sin_port = htons((UINT)port);
6497    *((UINT *)&addr.sin_addr) = htonl(INADDR_ANY);
6498    addr.sin_family = AF_INET;
6499
6500    if (local_only)
6501    {
6502        IPToInAddr(&addr.sin_addr, &localhost);
6503    }
6504
6505    // ソケットの作成
6506    s = socket(AF_INET, SOCK_STREAM, 0);
6507    if (s == INVALID_SOCKET)
6508    {
6509        return NULL;
6510    }
6511
6512    //SetSocketSendRecvBufferSize(s, SOCKET_BUFFER_SIZE);
6513
6514#ifdef  OS_UNIX
6515    // Windows 系 OS は REUSEADDR の実装にバグがあるっぽいので
6516    // UNIX 系のみ有効にした。
6517    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
6518#endif  // OS_UNIX
6519
6520    if (bind(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0)
6521    {
6522        // bind 失敗
6523        closesocket(s);
6524        return NULL;
6525    }
6526    if (listen(s, SOMAXCONN))
6527    {
6528        // listen 失敗
6529        closesocket(s);
6530        return NULL;
6531    }
6532
6533    // 成功
6534    sock = NewSock();
6535    sock->Connected = false;
6536    sock->AsyncMode = false;
6537    sock->ServerMode = true;
6538    sock->Type = SOCK_TCP;
6539    sock->socket = s;
6540    sock->ListenMode = true;
6541    sock->SecureMode = false;
6542    sock->LocalPort = port;
6543
6544    return sock;
6545}
6546
6547// TCP 切断
6548void Disconnect(SOCK *sock)
6549{
6550    SOCKET s;
6551    bool true_flag = true;
6552    bool false_flag = false;
6553    // 引数チェック
6554    if (sock == NULL)
6555    {
6556        return;
6557    }
6558
6559    sock->Disconnecting = true;
6560
6561#ifdef  OS_UNIX
6562    UnixFreeAsyncSocket(sock);
6563#endif  // UnixFreeAsyncSocket
6564
6565    if (sock->Type == SOCK_TCP && sock->ListenMode)
6566    {
6567        // Listen 中のソケットの場合は localhost に対して接続する
6568        sock->CancelAccept = true;
6569
6570        if (sock->IPv6 == false)
6571        {
6572            CheckTCPPort("127.0.0.1", sock->LocalPort);
6573        }
6574        else
6575        {
6576            CheckTCPPort("::1", sock->LocalPort);
6577        }
6578    }
6579
6580    Lock(disconnect_function_lock);
6581
6582    Lock(sock->disconnect_lock);
6583
6584    if (sock->Type == SOCK_TCP)
6585    {
6586        if (sock->socket != INVALID_SOCKET)
6587        {
6588            // 強制切断フラグ
6589            #ifdef  SO_DONTLINGER
6590                setsockopt(sock->socket, SOL_SOCKET, SO_DONTLINGER, (char *)&true_flag, sizeof(bool));
6591            #else   // SO_DONTLINGER
6592                setsockopt(sock->socket, SOL_SOCKET, SO_LINGER, (char *)&false_flag, sizeof(bool));
6593            #endif  // SO_DONTLINGER
6594//          setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
6595        }
6596
6597        // TCP ソケット
6598        Lock(sock->lock);
6599        {
6600            if (sock->socket == INVALID_SOCKET)
6601            {
6602                Unlock(sock->lock);
6603                Unlock(sock->disconnect_lock);
6604                Unlock(disconnect_function_lock);
6605                return;
6606            }
6607            s = sock->socket;
6608
6609            if (sock->Connected)
6610            {
6611                struct linger ling;
6612                Zero(&ling, sizeof(ling));
6613
6614
6615#if 0
6616                // SSL 切断
6617                Lock(sock->ssl_lock);
6618                {
6619                    if (sock->SecureMode)
6620                    {
6621                        SSL_shutdown(sock->ssl);
6622                    }
6623                }
6624                Unlock(sock->ssl_lock);
6625#endif
6626                // 切断
6627                shutdown(s, 2);
6628            }
6629
6630            // ソケットを閉じる
6631            closesocket(s);
6632
6633#ifdef  OS_UNIX
6634#ifdef  FIX_SSL_BLOCKING
6635            if (sock->CallingThread != NULL)
6636            {
6637                pthread_kill(sock->CallingThread, 64);
6638            }
6639#endif  // FIX_SSL_BLOCKING
6640#endif  // OS_UNIX
6641
6642            // SSL を解放
6643            Lock(sock->ssl_lock);
6644            {
6645                if (sock->SecureMode)
6646                {
6647                    if (sock->ssl != NULL)
6648                    {
6649                        Lock(openssl_lock);
6650                        {
6651                            SSL_free(sock->ssl);
6652                        }
6653                        Unlock(openssl_lock);
6654                        sock->ssl = NULL;
6655                    }
6656                    sock->Connected = false;
6657                    // 証明書を解放
6658                    if (sock->RemoteX != NULL)
6659                    {
6660                        FreeX(sock->RemoteX);
6661                        sock->RemoteX = NULL;
6662                    }
6663                    if (sock->LocalX != NULL)
6664                    {
6665                        FreeX(sock->LocalX);
6666                        sock->LocalX = NULL;
6667                    }
6668
6669                    // 暗号化アルゴリズム名
6670                    if (sock->CipherName != NULL)
6671                    {
6672                        Free(sock->CipherName);
6673                        sock->CipherName = NULL;
6674                    }
6675                    sock->SecureMode = false;
6676                }
6677            }
6678            Unlock(sock->ssl_lock);
6679
6680            // 初期化
6681            sock->socket = INVALID_SOCKET;
6682            sock->Type = 0;
6683            sock->AsyncMode = false;
6684            sock->Connected = false;
6685            sock->ListenMode = false;
6686            sock->SecureMode = false;
6687
6688            if (sock->ServerMode && sock->ListenMode == false)
6689            {
6690                DelIpClient(&sock->RemoteIP);
6691            }
6692        }
6693        Unlock(sock->lock);
6694    }
6695    else if (sock->Type == SOCK_UDP)
6696    {
6697        // UDP ソケット
6698        Lock(sock->lock);
6699        {
6700            if (sock->socket == INVALID_SOCKET)
6701            {
6702                Unlock(sock->lock);
6703                Unlock(sock->disconnect_lock);
6704                Unlock(disconnect_function_lock);
6705                return;
6706            }
6707
6708            s = sock->socket;
6709
6710            // ソケットを閉じる
6711            closesocket(s);
6712
6713            // 初期化
6714            sock->socket = INVALID_SOCKET;
6715            sock->Type = 0;
6716            sock->AsyncMode = false;
6717            sock->Connected = false;
6718            sock->ListenMode = false;
6719            sock->SecureMode = false;
6720        }
6721        Unlock(sock->lock);
6722    }
6723    Unlock(sock->disconnect_lock);
6724
6725    Unlock(disconnect_function_lock);
6726}
6727
6728typedef struct TCP_PORT_CHECK
6729{
6730    REF *ref;
6731    char hostname[MAX_SIZE];
6732    UINT port;
6733    bool ok;
6734} TCP_PORT_CHECK;
6735
6736// TCP ポートチェック用スレッド
6737void CheckTCPPortThread(THREAD *thread, void *param)
6738{
6739    TCP_PORT_CHECK *c;
6740    SOCK *s;
6741    // 引数チェック
6742    if (thread == NULL || param == NULL)
6743    {
6744        return;
6745    }
6746
6747    c = (TCP_PORT_CHECK *)param;
6748    AddRef(c->ref);
6749    NoticeThreadInit(thread);
6750
6751    AddWaitThread(thread);
6752
6753    s = Connect(c->hostname, c->port);
6754    if (s != NULL)
6755    {
6756        c->ok = true;
6757        Disconnect(s);
6758        ReleaseSock(s);
6759    }
6760
6761    if (Release(c->ref) == 0)
6762    {
6763        Free(c);
6764    }
6765
6766    DelWaitThread(thread);
6767}
6768
6769// TCP ポートに接続可能かどうかチェックする
6770bool CheckTCPPortEx(char *hostname, UINT port, UINT timeout)
6771{
6772    SOCK *s;
6773    // 引数チェック
6774    if (hostname == NULL || port == 0 || port >= 65536)
6775    {
6776        return false;
6777    }
6778
6779    if (timeout == 0)
6780    {
6781        timeout = TIMEOUT_TCP_PORT_CHECK;
6782    }
6783
6784    s = ConnectEx(hostname, port, timeout);
6785    if (s == NULL)
6786    {
6787        return false;
6788    }
6789    else
6790    {
6791        Disconnect(s);
6792        ReleaseSock(s);
6793        return true;
6794    }
6795}
6796bool CheckTCPPort(char *hostname, UINT port)
6797{
6798    return CheckTCPPortEx(hostname, port, TIMEOUT_TCP_PORT_CHECK);
6799}
6800
6801#ifdef  OS_UNIX
6802// タイムアウト付き接続 (UNIX 版)
6803int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag)
6804{
6805    SOCKSET set;
6806    bool ok = false;
6807    UINT64 start_time;
6808    // 引数チェック
6809    if (s == INVALID_SOCKET || addr == NULL)
6810    {
6811        return -1;
6812    }
6813    if (timeout == 0)
6814    {
6815        timeout = TIMEOUT_TCP_PORT_CHECK;
6816    }
6817
6818    UnixSetSocketNonBlockingMode(s, true);
6819
6820    start_time = Tick64();
6821
6822    while (true)
6823    {
6824        int ret;
6825        ret = connect(s, addr, size);
6826        if (ret == 0 || errno == EISCONN)
6827        {
6828            ok = true;
6829            break;
6830        }
6831        else
6832        {
6833            if (((start_time + (UINT64)timeout) <= Tick64()) || (errno != EAGAIN && errno != EINPROGRESS && errno != EALREADY))
6834            {
6835                // 失敗
6836                break;
6837            }
6838            else if (*cancel_flag)
6839            {
6840                // キャンセル
6841                break;
6842            }
6843            else
6844            {
6845                // 接続中
6846                SleepThread(50);
6847                UnixSelectInner(1, (UINT *)&s, 1, (UINT *)&s, 100);
6848            }
6849        }
6850    }
6851
6852    UnixSetSocketNonBlockingMode(s, false);
6853
6854    if (ok)
6855    {
6856        return 0;
6857    }
6858    else
6859    {
6860        return -1;
6861    }
6862}
6863#else
6864// タイムアウト付き接続 (Win32 版)
6865int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag)
6866{
6867    UINT64 start_time;
6868    bool ok = false;
6869    bool timeouted = false;
6870    WSAEVENT hEvent;
6871    UINT zero = 0;
6872    UINT tmp = 0;
6873    UINT ret_size = 0;
6874    bool is_nt = false;
6875    // 引数チェック
6876    if (s == INVALID_SOCKET || addr == NULL)
6877    {
6878        return -1;
6879    }
6880    if (timeout == 0)
6881    {
6882        timeout = TIMEOUT_TCP_PORT_CHECK;
6883    }
6884
6885    is_nt = OS_IS_WINDOWS_NT(GetOsInfo()->OsType);
6886
6887    // イベントを作成
6888    hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
6889
6890    // ソケットをイベントに関連付ける
6891    WSAEventSelect(s, hEvent, FD_CONNECT);
6892
6893    start_time = Tick64();
6894
6895    while (true)
6896    {
6897        int ret;
6898       
6899        ret = connect(s, addr, size);
6900
6901        if (ret == 0)
6902        {
6903            ok = true;
6904            break;
6905        }
6906        else
6907        {
6908            int err = WSAGetLastError();
6909            //Debug("err=%u\n", err);
6910            //Debug("cancel_flag=%u\n", *cancel_flag);
6911            if (timeouted && ((err == WSAEALREADY) || (err == WSAEWOULDBLOCK && !is_nt)))
6912            {
6913                // タイムアウト
6914                ok = false;
6915                break;
6916            }
6917            if (*cancel_flag)
6918            {
6919                // キャンセル
6920                ok = false;
6921                break;
6922            }
6923            if (err == WSAEISCONN || (err == WSAEINVAL && is_nt))
6924            {
6925                ok = true;
6926                break;
6927            }
6928            if (((start_time + (UINT64)timeout) <= Tick64()) || (err != WSAEWOULDBLOCK && err != WSAEALREADY && (is_nt || err != WSAEINVAL)))
6929            {
6930                // 失敗 (タイムアウト)
6931                break;
6932            }
6933            else
6934            {
6935                SleepThread(10);
6936                // 接続中
6937                if (WaitForSingleObject(hEvent, 100) == WAIT_OBJECT_0)
6938                {
6939                    timeouted = true;
6940                }
6941            }
6942        }
6943    }
6944
6945    // ソケットをイベントから外す
6946    WSAEventSelect(s, hEvent, 0);
6947
6948    // 同期ソケットに戻す
6949    WSAIoctl(s, FIONBIO, &zero, sizeof(zero), &tmp, sizeof(tmp), &ret_size, NULL, NULL);
6950
6951    // イベントを閉じる
6952    CloseHandle(hEvent);
6953
6954    if (ok)
6955    {
6956        return 0;
6957    }
6958    else
6959    {
6960        return -1;
6961    }
6962}
6963#endif  // OS_UNIX
6964
6965// ソケットのパケットの優先順位を向上させる (未使用)
6966void SetSockPriorityHigh(SOCK *s)
6967{
6968    int value;
6969    // 引数チェック
6970    if (s == NULL)
6971    {
6972        return;
6973    }
6974
6975    value = 16;
6976
6977#ifdef  IP_TOS
6978    //setsockopt(s->socket, IPPROTO_IP, IP_TOS, (char *)&value, sizeof(int));
6979#endif  // IP_TOS
6980}
6981
6982// TCP 接続
6983SOCK *Connect(char *hostname, UINT port)
6984{
6985    return ConnectEx(hostname, port, 0);
6986}
6987SOCK *ConnectEx(char *hostname, UINT port, UINT timeout)
6988{
6989    return ConnectEx2(hostname, port, timeout, NULL);
6990}
6991SOCK *ConnectEx2(char *hostname, UINT port, UINT timeout, bool *cancel_flag)
6992{
6993    SOCK *sock;
6994    SOCKET s;
6995    struct linger ling;
6996    struct sockaddr_in sockaddr4;
6997    struct in_addr addr4;
6998    IP ip4;
6999    struct sockaddr_in6 sockaddr6;
7000    struct in6_addr addr6;
7001    IP ip6;
7002    bool true_flag = true;
7003    bool false_flag = false;
7004    char tmp[MAX_SIZE];
7005    IP current_ip;
7006    bool is_ipv6 = false;
7007    bool dummy = false;
7008    // 引数チェック
7009    if (hostname == NULL || port == 0 || port >= 65536)
7010    {
7011        return NULL;
7012    }
7013    if (timeout == 0)
7014    {
7015        timeout = TIMEOUT_TCP_PORT_CHECK;
7016    }
7017    if (cancel_flag == NULL)
7018    {
7019        cancel_flag = &dummy;
7020    }
7021
7022    Zero(&current_ip, sizeof(current_ip));
7023
7024    Zero(&sockaddr4, sizeof(sockaddr4));
7025    Zero(&addr4, sizeof(addr4));
7026    Zero(&ip4, sizeof(ip4));
7027
7028    Zero(&sockaddr6, sizeof(sockaddr6));
7029    Zero(&addr6, sizeof(addr6));
7030    Zero(&ip6, sizeof(ip6));
7031
7032    // 正引き
7033    if (GetIP46Ex(&ip4, &ip6, hostname, 0, cancel_flag) == false)
7034    {
7035        return NULL;
7036    }
7037
7038    s = INVALID_SOCKET;
7039
7040    // IPv4 で接続を試行する
7041    if (IsZeroIp(&ip4) == false)
7042    {
7043        // sockaddr_in の生成
7044        IPToInAddr(&addr4, &ip4);
7045        sockaddr4.sin_port = htons((USHORT)port);
7046        sockaddr4.sin_family = AF_INET;
7047        sockaddr4.sin_addr.s_addr = addr4.s_addr;
7048
7049        // ソケット作成
7050        s = socket(AF_INET, SOCK_STREAM, 0);
7051        if (s != INVALID_SOCKET)
7052        {
7053            // 接続
7054            if (connect_timeout(s, (struct sockaddr *)&sockaddr4, sizeof(struct sockaddr_in), timeout, cancel_flag) != 0)
7055            {
7056                // 接続失敗
7057                closesocket(s);
7058                s = INVALID_SOCKET;
7059            }
7060            else
7061            {
7062                Copy(&current_ip, &ip4, sizeof(IP));
7063            }
7064        }
7065    }
7066
7067    // IPv6 で接続を試行する
7068    if (s == INVALID_SOCKET && IsZeroIp(&ip6) == false)
7069    {
7070        // sockaddr_in6 の生成
7071        IPToInAddr6(&addr6, &ip6);
7072        sockaddr6.sin6_port = htons((USHORT)port);
7073        sockaddr6.sin6_family = AF_INET6;
7074        sockaddr6.sin6_scope_id = ip6.ipv6_scope_id;
7075        Copy(&sockaddr6.sin6_addr, &addr6, sizeof(addr6));
7076
7077        // ソケット作成
7078        s = socket(AF_INET6, SOCK_STREAM, 0);
7079        if (s != INVALID_SOCKET)
7080        {
7081            // 接続
7082            if (connect_timeout(s, (struct sockaddr *)&sockaddr6, sizeof(struct sockaddr_in6), timeout, cancel_flag) != 0)
7083            {
7084                // 接続失敗
7085                closesocket(s);
7086                s = INVALID_SOCKET;
7087            }
7088            else
7089            {
7090                Copy(&current_ip, &ip6, sizeof(IP));
7091
7092                is_ipv6 = true;
7093            }
7094        }
7095    }
7096
7097    if (s == INVALID_SOCKET)
7098    {
7099        // IPv4, IPv6 の両方で接続失敗
7100        return NULL;
7101    }
7102
7103    // SOCK の作成
7104    sock = NewSock();
7105    sock->socket = s;
7106    sock->Type = SOCK_TCP;
7107    sock->ServerMode = false;
7108
7109    SetSockPriorityHigh(sock);
7110
7111    // ホスト名解決
7112    if (GetHostName(tmp, sizeof(tmp), &current_ip) == false)
7113    {
7114        StrCpy(tmp, sizeof(tmp), hostname);
7115    }
7116
7117    //Debug("PTR: %s\n", tmp);
7118
7119    sock->RemoteHostname = CopyStr(tmp);
7120
7121//  Debug("new socket: %u\n", s);
7122
7123    Zero(&ling, sizeof(ling));
7124    // 強制切断フラグ
7125#ifdef  SO_DONTLINGER
7126    setsockopt(sock->socket, SOL_SOCKET, SO_DONTLINGER, (char *)&true_flag, sizeof(bool));
7127#else   // SO_DONTLINGER
7128    setsockopt(sock->socket, SOL_SOCKET, SO_LINGER, (char *)&false_flag, sizeof(bool));
7129#endif  // SO_DONTLINGER
7130//  setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
7131
7132    // TCP オプションの設定
7133    setsockopt(sock->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
7134
7135    // タイムアウト値の初期化
7136    SetTimeout(sock, TIMEOUT_INFINITE);
7137
7138    // ソケット情報の取得
7139    QuerySocketInformation(sock);
7140
7141    sock->Connected = true;
7142    sock->AsyncMode = false;
7143    sock->SecureMode = false;
7144    sock->IPv6 = is_ipv6;
7145
7146    return sock;
7147}
7148
7149// ソケットの送受信バッファサイズを最大にする
7150void SetSocketSendRecvBufferSize(int s, UINT size)
7151{
7152    int value = (int)size;
7153    // 引数チェック
7154    if (s == INVALID_SOCKET)
7155    {
7156        return;
7157    }
7158
7159    setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, sizeof(int));
7160    setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, sizeof(int));
7161}
7162
7163// ソケット情報の取得
7164void QuerySocketInformation(SOCK *sock)
7165{
7166    // 引数チェック
7167    if (sock == NULL)
7168    {
7169        return;
7170    }
7171
7172    Lock(sock->lock);
7173    {
7174        struct sockaddr_in6 sockaddr6;
7175        struct in6_addr *addr6;
7176        int size;
7177
7178        if (sock->Type == SOCK_TCP)
7179        {
7180            // リモートホストの情報を取得
7181            size = sizeof(sockaddr6);
7182            if (getpeername(sock->socket, (struct sockaddr *)&sockaddr6, (int *)&size) == 0)
7183            {
7184                if (size >= sizeof(struct sockaddr_in6))
7185                {
7186                    sock->RemotePort = (UINT)ntohs(sockaddr6.sin6_port);
7187                    addr6 = &sockaddr6.sin6_addr;
7188                    InAddrToIP6(&sock->RemoteIP, addr6);
7189                    sock->RemoteIP.ipv6_scope_id = sockaddr6.sin6_scope_id;
7190                }
7191                else
7192                {
7193                    struct sockaddr_in *sockaddr;
7194                    struct in_addr *addr;
7195
7196                    sockaddr = (struct sockaddr_in *)&sockaddr6;
7197                    sock->RemotePort = (UINT)ntohs(sockaddr->sin_port);
7198                    addr = &sockaddr->sin_addr;
7199                    InAddrToIP(&sock->RemoteIP, addr);
7200                }
7201            }
7202        }
7203
7204        // ローカルホストの情報を取得
7205        size = sizeof(sockaddr6);
7206        if (getsockname(sock->socket, (struct sockaddr *)&sockaddr6, (int *)&size) == 0)
7207        {
7208            if (size >= sizeof(struct sockaddr_in6))
7209            {
7210                sock->LocalPort = (UINT)ntohs(sockaddr6.sin6_port);
7211                addr6 = &sockaddr6.sin6_addr;
7212                InAddrToIP6(&sock->LocalIP, addr6);
7213                sock->LocalIP.ipv6_scope_id = sockaddr6.sin6_scope_id;
7214            }
7215            else
7216            {
7217                struct sockaddr_in *sockaddr;
7218                struct in_addr *addr;
7219
7220                sockaddr = (struct sockaddr_in *)&sockaddr6;
7221                sock->LocalPort = (UINT)ntohs(sockaddr->sin_port);
7222                addr = &sockaddr->sin_addr;
7223                InAddrToIP(&sock->LocalIP, addr);
7224            }
7225        }
7226    }
7227    Unlock(sock->lock);
7228}
7229
7230// ソケットの解放
7231void ReleaseSock(SOCK *s)
7232{
7233    // 引数チェック
7234    if (s == NULL)
7235    {
7236        return;
7237    }
7238
7239    if (Release(s->ref) == 0)
7240    {
7241        if (s->ListenMode == false && s->ServerMode)
7242        {
7243            Print("");
7244        }
7245        CleanupSock(s);
7246    }
7247}
7248
7249// ソケットのクリーンアップ
7250void CleanupSock(SOCK *s)
7251{
7252    // 引数チェック
7253    if (s == NULL)
7254    {
7255        return;
7256    }
7257
7258//  {Debug("CleanupSock: Disconnect() Called: %s %u\n", __FILE__, __LINE__);Disconnect(s);}
7259    Disconnect(s);
7260
7261#ifdef  OS_WIN32
7262    Win32FreeAsyncSocket(s);
7263#else   // OS_WIN32
7264    UnixFreeAsyncSocket(s);
7265#endif  // OS_WIN32
7266
7267    FreeBuf(s->SendBuf);
7268    if (s->socket != INVALID_SOCKET)
7269    {
7270#ifdef  OS_WIN32
7271        closesocket(s->socket);
7272#else   // OS_WIN32
7273        close(s->socket);
7274#endif  // OS_WIN32
7275    }
7276    Free(s->RemoteHostname);
7277
7278    Free(s->WaitToUseCipher);
7279    DeleteLock(s->lock);
7280    DeleteLock(s->ssl_lock);
7281    DeleteLock(s->disconnect_lock);
7282
7283    Dec(num_tcp_connections);
7284
7285    Free(s);
7286}
7287
7288// 新しいソケットの作成
7289SOCK *NewSock()
7290{
7291    SOCK *s = ZeroMallocFast(sizeof(SOCK));
7292
7293    s->ref = NewRef();
7294    s->lock = NewLock();
7295    s->SendBuf = NewBuf();
7296    s->socket = INVALID_SOCKET;
7297    s->ssl_lock = NewLock();
7298    s->disconnect_lock = NewLock();
7299
7300    Inc(num_tcp_connections);
7301
7302    return s;
7303}
7304
7305// IP を UINT に変換する
7306UINT IPToUINT(IP *ip)
7307{
7308    UCHAR *b;
7309    UINT i, value = 0;
7310    // 引数チェック
7311    if (ip == NULL)
7312    {
7313        return 0;
7314    }
7315
7316    b = (UCHAR *)&value;
7317    for (i = 0;i < 4;i++)
7318    {
7319        b[i] = ip->addr[i];
7320    }
7321
7322    return value;
7323}
7324
7325// UNIT を IP に変換する
7326void UINTToIP(IP *ip, UINT value)
7327{
7328    UCHAR *b;
7329    UINT i;
7330    // 引数チェック
7331    if (ip == NULL)
7332    {
7333        return;
7334    }
7335
7336    ZeroIP4(ip);
7337
7338    b = (UCHAR *)&value;
7339    for (i = 0;i < 4;i++)
7340    {
7341        ip->addr[i] = b[i];
7342    }
7343}
7344
7345// コンピュータのホスト名を取得
7346void GetMachineHostName(char *name, UINT size)
7347{
7348    char tmp[MAX_SIZE];
7349    UINT i, len;
7350    // 引数チェック
7351    if (name == NULL)
7352    {
7353        return;
7354    }
7355
7356    GetMachineName(tmp, sizeof(tmp));
7357
7358    len = StrLen(tmp);
7359    for (i = 0;i < len;i++)
7360    {
7361        if (tmp[i] == '.')
7362        {
7363            tmp[i] = 0;
7364        }
7365    }
7366
7367    ConvertSafeFileName(name, size, tmp);
7368}
7369
7370// このコンピュータの IP アドレスを取得
7371void GetMachineIp(IP *ip)
7372{
7373    char tmp[MAX_SIZE];
7374    // 引数チェック
7375    if (ip == NULL)
7376    {
7377        return;
7378    }
7379
7380    Zero(ip, sizeof(IP));
7381    SetIP(ip, 127, 0, 0, 1);
7382
7383    GetMachineName(tmp, sizeof(tmp));
7384    GetIP(ip, tmp);
7385}
7386
7387// コンピュータ名を hosts から取得
7388bool GetMachineNameFromHosts(char *name, UINT size)
7389{
7390    bool ret = false;
7391    char *s;
7392    BUF *b;
7393    // 引数チェック
7394    if (name == NULL)
7395    {
7396        return false;
7397    }
7398
7399    b = ReadDump("/etc/hosts");
7400    if (b == NULL)
7401    {
7402        return false;
7403    }
7404
7405    while (true)
7406    {
7407        s = CfgReadNextLine(b);
7408        if (s == NULL)
7409        {
7410            break;
7411        }
7412        else
7413        {
7414            TOKEN_LIST *t = ParseToken(s, " \t");
7415
7416            if (t != NULL)
7417            {
7418                if (t->NumTokens >= 2)
7419                {
7420                    if (StrCmpi(t->Token[0], "127.0.0.1") == 0)
7421                    {
7422                        UINT i;
7423
7424                        for (i = 1;i < t->NumTokens;i++)
7425                        {
7426                            if (StartWith(t->Token[i], "localhost") == false)
7427                            {
7428                                StrCpy(name, size, t->Token[i]);
7429                                ret = true;
7430                            }
7431                        }
7432                    }
7433                }
7434            }
7435            FreeToken(t);
7436        }
7437
7438        Free(s);
7439    }
7440
7441    FreeBuf(b);
7442
7443    return ret;
7444}
7445
7446// このコンピュータのコンピュータ名を取得
7447void GetMachineName(char *name, UINT size)
7448{
7449    GetMachineNameEx(name, size, false);
7450}
7451void GetMachineNameEx(char *name, UINT size, bool no_load_hosts)
7452{
7453    static char name_cache[MAX_SIZE];
7454    static bool name_cached = false;
7455    char tmp[MAX_SIZE];
7456    char tmp2[MAX_SIZE];
7457    IP ip;
7458    // 引数チェック
7459    if (name == NULL)
7460    {
7461        return;
7462    }
7463
7464    Lock(machine_name_lock);
7465    {
7466        if (name_cached != false)
7467        {
7468            StrCpy(name, size, name_cache);
7469            Unlock(machine_name_lock);
7470            return;
7471        }
7472        if (gethostname(tmp, MAX_SIZE) != 0)
7473        {
7474            StrCpy(name, size, "Unknown");
7475            Unlock(machine_name_lock);
7476            return;
7477        }
7478        if (GetIP(&ip, tmp) == false)
7479        {
7480            StrCpy(name, size, tmp);
7481            Unlock(machine_name_lock);
7482            return;
7483        }
7484        if (GetHostNameInner(name, size, &ip) == false || StartWith(name, "localhost"))
7485        {
7486            StrCpy(name, size, tmp);
7487        }
7488        if (StartWith(name, "localhost"))
7489        {
7490            if (no_load_hosts == false && OS_IS_UNIX(GetOsInfo()->OsType))
7491            {
7492                if (GetMachineNameFromHosts(tmp2, sizeof(tmp2)))
7493                {
7494                    StrCpy(name, sizeof(name), tmp2);
7495                }
7496            }
7497        }
7498
7499        StrCpy(name_cache, sizeof(name_cache), name);
7500        name_cached = true;
7501    }
7502    Unlock(machine_name_lock);
7503}
7504
7505// ホスト名取得スレッド
7506void GetHostNameThread(THREAD *t, void *p)
7507{
7508    IP *ip;
7509    char hostname[256];
7510    // 引数チェック
7511    if (t == NULL || p == NULL)
7512    {
7513        return;
7514    }
7515
7516    ip = (IP *)p;
7517
7518    AddWaitThread(t);
7519
7520    NoticeThreadInit(t);
7521
7522    if (GetHostNameInner(hostname, sizeof(hostname), ip))
7523    {
7524        AddHostCache(ip, hostname);
7525    }
7526
7527    Free(ip);
7528
7529    DelWaitThread(t);
7530}
7531
7532// ホスト名の取得
7533bool GetHostName(char *hostname, UINT size, IP *ip)
7534{
7535    THREAD *t;
7536    IP *p_ip;
7537    bool ret;
7538    // 引数チェック
7539    if (hostname == NULL || ip == NULL)
7540    {
7541        return false;
7542    }
7543
7544    if (GetHostCache(hostname, size, ip))
7545    {
7546        if (IsEmptyStr(hostname) == false)
7547        {
7548            return true;
7549        }
7550        else
7551        {
7552            return false;
7553        }
7554    }
7555
7556    p_ip = ZeroMalloc(sizeof(IP));
7557    Copy(p_ip, ip, sizeof(IP));
7558
7559    t = NewThread(GetHostNameThread, p_ip);
7560
7561    WaitThreadInit(t);
7562
7563    WaitThread(t, TIMEOUT_HOSTNAME);
7564
7565    ReleaseThread(t);
7566
7567    ret = GetHostCache(hostname, size, ip);
7568    if (ret == false)
7569    {
7570        if (IsIP4(ip))
7571        {
7572            ret = GetNetBiosName(hostname, size, ip);
7573            if (ret)
7574            {
7575                AddHostCache(ip, hostname);
7576            }
7577        }
7578    }
7579    else
7580    {
7581        if (IsEmptyStr(hostname))
7582        {
7583            ret = false;
7584        }
7585    }
7586    if (ret == false)
7587    {
7588        AddHostCache(ip, "");
7589        StrCpy(hostname, size, "");
7590    }
7591
7592    return ret;
7593}
7594
7595// DNS 逆引きクエリを行う
7596bool GetHostNameInner(char *hostname, UINT size, IP *ip)
7597{
7598    struct in_addr addr;
7599    struct sockaddr_in sa;
7600    char tmp[MAX_SIZE];
7601    char ip_str[64];
7602    // 引数チェック
7603    if (hostname == NULL || ip == NULL)
7604    {
7605        return false;
7606    }
7607
7608    if (IsIP6(ip))
7609    {
7610        return GetHostNameInner6(hostname, size, ip);
7611    }
7612
7613    // 逆引き
7614    IPToInAddr(&addr, ip);
7615    Zero(&sa, sizeof(sa));
7616    sa.sin_family = AF_INET;
7617
7618#if defined(UNIX_BSD) || defined(UNIX_MACOS)
7619    sa.sin_len = INET_ADDRSTRLEN;
7620#endif  // UNIX_BSD || UNIX_MACOS
7621
7622    Copy(&sa.sin_addr, &addr, sizeof(struct in_addr));
7623    sa.sin_port = 0;
7624
7625    if (getnameinfo((struct sockaddr *)&sa, sizeof(sa), tmp, sizeof(tmp), NULL, 0, 0) != 0)
7626    {
7627        return false;
7628    }
7629
7630    IPToStr(ip_str, sizeof(ip_str), ip);
7631
7632    if (StrCmpi(tmp, ip_str) == 0)
7633    {
7634        return false;
7635    }
7636
7637    if (IsEmptyStr(tmp))
7638    {
7639        return false;
7640    }
7641
7642    StrCpy(hostname, size, tmp);
7643
7644    return true;
7645}
7646bool GetHostNameInner6(char *hostname, UINT size, IP *ip)
7647{
7648    struct in6_addr addr;
7649    struct sockaddr_in6 sa;
7650    char tmp[MAX_SIZE];
7651    char ip_str[256];
7652    // 引数チェック
7653    if (hostname == NULL || ip == NULL)
7654    {
7655        return false;
7656    }
7657
7658    // 逆引き
7659    IPToInAddr6(&addr, ip);
7660    Zero(&sa, sizeof(sa));
7661    sa.sin6_family = AF_INET6;
7662
7663#if defined(UNIX_BSD) || defined(UNIX_MACOS)
7664    sa.sin6_len = INET6_ADDRSTRLEN;
7665#endif  // UNIX_BSD || UNIX_MACOS
7666
7667    Copy(&sa.sin6_addr, &addr, sizeof(struct in6_addr));
7668    sa.sin6_port = 0;
7669
7670    if (getnameinfo((struct sockaddr *)&sa, sizeof(sa), tmp, sizeof(tmp), NULL, 0, 0) != 0)
7671    {
7672        return false;
7673    }
7674
7675    IPToStr(ip_str, sizeof(ip_str), ip);
7676
7677    if (StrCmpi(tmp, ip_str) == 0)
7678    {
7679        return false;
7680    }
7681
7682    if (IsEmptyStr(tmp))
7683    {
7684        return false;
7685    }
7686
7687    StrCpy(hostname, size, tmp);
7688
7689    return true;
7690}
7691
7692#define NUM_NBT_QUERYS_SEND         3
7693
7694// IP アドレスからそのマシンの NetBIOS 名を取得する
7695bool GetNetBiosName(char *name, UINT size, IP *ip)
7696{
7697    SOCK *s;
7698    UINT i, j;
7699    bool flag = false;
7700    bool ok = false;
7701    NBTREQUEST req;
7702    UCHAR buf[1024];
7703    USHORT tran_id[NUM_NBT_QUERYS_SEND];
7704    UINT64 timeout_tick;
7705    // 引数チェック
7706    if (name == NULL || ip == NULL)
7707    {
7708        return false;
7709    }
7710
7711    IPToStr(name, size, ip);
7712
7713    for (i = 0;i < NUM_NBT_QUERYS_SEND;i++)
7714    {
7715        tran_id[i] = Rand16();
7716    }
7717
7718    s = NewUDP(0);
7719    if (s == NULL)
7720    {
7721        return false;
7722    }
7723
7724    for (j = 0;j < NUM_NBT_QUERYS_SEND;j++)
7725    {
7726        Zero(&req, sizeof(req));
7727        req.TransactionId = Endian16(tran_id[j]);
7728        req.NumQuestions = Endian16(1);
7729        req.Query[0] = 0x20;
7730        req.Query[1] = 0x43;
7731        req.Query[2] = 0x4b;
7732        for (i = 3;i <= 32;i++)
7733        {
7734            req.Query[i] = 0x41;
7735        }
7736        req.Query[35] = 0x21;
7737        req.Query[37] = 0x01;
7738
7739        if (SendTo(s, ip, 137, &req, sizeof(req)) == 0)
7740        {
7741            ReleaseSock(s);
7742            return false;
7743        }
7744    }
7745
7746    timeout_tick = Tick() + (UINT64)TIMEOUT_NETBIOS_HOSTNAME;
7747
7748    while (1)
7749    {
7750        UINT ret;
7751        IP src_ip;
7752        UINT src_port;
7753        SOCKSET set;
7754        if (Tick() >= timeout_tick)
7755        {
7756            break;
7757        }
7758        InitSockSet(&set);
7759        AddSockSet(&set, s);
7760        Select(&set, 100, NULL, NULL);
7761
7762        if (flag == false)
7763        {
7764            flag = true;
7765        }
7766        else
7767        {
7768            SleepThread(10);
7769        }
7770
7771        ret = RecvFrom(s, &src_ip, &src_port, buf, sizeof(buf));
7772
7773        if (ret == SOCK_LATER)
7774        {
7775            continue;
7776        }
7777        else if (ret == 0)
7778        {
7779            break;
7780        }
7781        else
7782        {
7783            if (ret >= sizeof(NBTRESPONSE))
7784            {
7785                NBTRESPONSE *r = (NBTRESPONSE *)buf;
7786                bool b = false;
7787                UINT i;
7788                USHORT id = Endian16(r->TransactionId);
7789                for (i = 0;i < NUM_NBT_QUERYS_SEND;i++)
7790                {
7791                    if (id == tran_id[i])
7792                    {
7793                        b = true;
7794                        break;
7795                    }
7796                }
7797                if (b)
7798                {
7799                    if (r->Flags != 0 && r->NumQuestions == 0 && r->AnswerRRs >= 1)
7800                    {
7801                        if (r->Response[0] == 0x20 && r->Response[1] == 0x43 &&
7802                            r->Response[2] == 0x4b)
7803                        {
7804                            if (r->Response[34] == 0x00 && r->Response[35] == 0x21 &&
7805                                r->Response[36] == 0x00 && r->Response[37] == 0x01)
7806                            {
7807                                char *a = (char *)(&r->Response[45]);
7808                                if (StrCheckLen(a, 15))
7809                                {
7810                                    if (IsEmptyStr(a) == false)
7811                                    {
7812                                        StrCpy(name, size, a);
7813                                        Trim(name);
7814                                        ok = true;
7815                                    }
7816                                    else
7817                                    {
7818                                        ok = false;
7819                                        break;
7820                                    }
7821                                }
7822                            }
7823                        }
7824                    }
7825                }
7826            }
7827        }
7828    }
7829
7830    ReleaseSock(s);
7831    return ok;
7832}
7833
7834// IP アドレスを設定する
7835void SetIP(IP *ip, UCHAR a1, UCHAR a2, UCHAR a3, UCHAR a4)
7836{
7837    // 引数チェック
7838    if (ip == NULL)
7839    {
7840        return;
7841    }
7842
7843    Zero(ip, sizeof(IP));
7844    ip->addr[0] = a1;
7845    ip->addr[1] = a2;
7846    ip->addr[2] = a3;
7847    ip->addr[3] = a4;
7848}
7849
7850// DNS 正引きを行って結果を v4 と v6 のどちらかで得る (両方の場合は IPv4 優先)
7851bool GetIP46Any4(IP *ip, char *hostname)
7852{
7853    IP ip4, ip6;
7854    bool b = false;
7855    // 引数チェック
7856    if (ip == NULL || hostname == NULL)
7857    {
7858        return false;
7859    }
7860
7861    if (GetIP46(&ip4, &ip6, hostname) == false)
7862    {
7863        return false;
7864    }
7865
7866    if (IsZeroIp(&ip6) == false)
7867    {
7868        Copy(ip, &ip6, sizeof(IP));
7869
7870        b = true;
7871    }
7872
7873    if (IsZeroIp(&ip4) == false)
7874    {
7875        Copy(ip, &ip4, sizeof(IP));
7876
7877        b = true;
7878    }
7879
7880    return b;
7881}
7882
7883// DNS 正引きを行って結果を v4 と v6 のどちらかで得る (両方の場合は IPv6 優先)
7884bool GetIP46Any6(IP *ip, char *hostname)
7885{
7886    IP ip4, ip6;
7887    bool b = false;
7888    // 引数チェック
7889    if (ip == NULL || hostname == NULL)
7890    {
7891        return false;
7892    }
7893
7894    if (GetIP46(&ip4, &ip6, hostname) == false)
7895    {
7896        return false;
7897    }
7898
7899    if (IsZeroIp(&ip4) == false)
7900    {
7901        Copy(ip, &ip4, sizeof(IP));
7902
7903        b = true;
7904    }
7905
7906    if (IsZeroIp(&ip6) == false)
7907    {
7908        Copy(ip, &ip6, sizeof(IP));
7909
7910        b = true;
7911    }
7912
7913    return b;
7914}
7915
7916// DNS 正引きを行って結果を v4 と v6 の両方で得る
7917bool GetIP46(IP *ip4, IP *ip6, char *hostname)
7918{
7919    return GetIP46Ex(ip4, ip6, hostname, 0, NULL);
7920}
7921bool GetIP46Ex(IP *ip4, IP *ip6, char *hostname, UINT timeout, bool *cancel)
7922{
7923    IP a, b;
7924    bool ok_a, ok_b;
7925    // 引数チェック
7926    if (ip4 == NULL || ip6 == NULL || hostname == NULL)
7927    {
7928        return false;
7929    }
7930
7931    ZeroIP4(ip4);
7932    ZeroIP6(ip6);
7933
7934    ok_a = ok_b = false;
7935
7936    if (GetIP6Ex(&a, hostname, timeout, cancel))
7937    {
7938        ok_a = true;
7939    }
7940
7941    if (GetIP4Ex(&b, hostname, timeout, cancel))
7942    {
7943        ok_b = true;
7944    }
7945
7946    if (ok_a)
7947    {
7948        if (IsIP4(&a))
7949        {
7950            Copy(ip4, &a, sizeof(IP));
7951        }
7952    }
7953    if (ok_b)
7954    {
7955        if (IsIP4(&b))
7956        {
7957            Copy(ip4, &b, sizeof(IP));
7958        }
7959
7960        if (IsIP6(&b))
7961        {
7962            Copy(ip6, &b, sizeof(IP));
7963        }
7964    }
7965    if (ok_a)
7966    {
7967        if (IsIP6(&a))
7968        {
7969            Copy(ip6, &a, sizeof(IP));
7970        }
7971    }
7972
7973    if (IsZeroIp(ip4) && IsZeroIp(ip6))
7974    {
7975        return false;
7976    }
7977
7978    return true;
7979}
7980
7981// GetIP 用スレッドのパラメータのクリーンアップ
7982void CleanupGetIPThreadParam(GETIP_THREAD_PARAM *p)
7983{
7984    // 引数チェック
7985    if (p == NULL)
7986    {
7987        return;
7988    }
7989
7990    Free(p);
7991}
7992
7993// GetIP 用スレッドのパラメータの解放
7994void ReleaseGetIPThreadParam(GETIP_THREAD_PARAM *p)
7995{
7996    // 引数チェック
7997    if (p == NULL)
7998    {
7999        return;
8000    }
8001
8002    if (Release(p->Ref) == 0)
8003    {
8004        CleanupGetIPThreadParam(p);
8005    }
8006}
8007
8008// DNS 正引きクエリ (タイムアウト付き) を行うスレッド
8009void GetIP4Ex6ExThread(THREAD *t, void *param)
8010{
8011    GETIP_THREAD_PARAM *p;
8012    // 引数チェック
8013    if (t == NULL || param == NULL)
8014    {
8015        return;
8016    }
8017
8018    p = (GETIP_THREAD_PARAM *)param;
8019
8020    AddRef(p->Ref);
8021
8022    NoticeThreadInit(t);
8023
8024    AddWaitThread(t);
8025
8026    // 解決の実行
8027    if (p->IPv6 == false)
8028    {
8029        // IPv4
8030        p->Ok = GetIP4Inner(&p->Ip, p->HostName);
8031    }
8032    else
8033    {
8034        // IPv6
8035        p->Ok = GetIP6Inner(&p->Ip, p->HostName);
8036    }
8037
8038    ReleaseGetIPThreadParam(p);
8039
8040    DelWaitThread(t);
8041}
8042
8043// DNS 正引きクエリ (タイムアウト付き) を行う
8044bool GetIP4Ex6Ex(IP *ip, char *hostname, UINT timeout, bool ipv6, bool *cancel)
8045{
8046    GETIP_THREAD_PARAM *p;
8047    THREAD *t;
8048    bool ret = false;
8049    UINT64 start_tick = 0;
8050    UINT64 end_tick = 0;
8051    // 引数チェック
8052    if (ip == NULL || hostname == NULL)
8053    {
8054        return false;
8055    }
8056    if (timeout == 0)
8057    {
8058        timeout = TIMEOUT_GETIP;
8059    }
8060
8061    p = ZeroMalloc(sizeof(GETIP_THREAD_PARAM));
8062    p->Ref = NewRef();
8063    StrCpy(p->HostName, sizeof(p->HostName), hostname);
8064    p->IPv6 = ipv6;
8065    p->Timeout = timeout;
8066    p->Ok = false;
8067
8068    t = NewThread(GetIP4Ex6ExThread, p);
8069    WaitThreadInit(t);
8070
8071    if (cancel == NULL)
8072    {
8073        WaitThread(t, timeout);
8074    }
8075    else
8076    {
8077        start_tick = Tick64();
8078        end_tick = start_tick + (UINT64)timeout;
8079
8080        while (true)
8081        {
8082            UINT64 now = Tick64();
8083            UINT64 remain;
8084            UINT remain32;
8085
8086            if (*cancel)
8087            {
8088                break;
8089            }
8090
8091            if (now >= end_tick)
8092            {
8093                break;
8094            }
8095
8096            remain = end_tick - now;
8097            remain32 = MIN((UINT)remain, 100);
8098
8099            if (WaitThread(t, remain32))
8100            {
8101                break;
8102            }
8103        }
8104    }
8105
8106    ReleaseThread(t);
8107
8108    if (p->Ok)
8109    {
8110        ret = true;
8111        Copy(ip, &p->Ip, sizeof(IP));
8112    }
8113
8114    ReleaseGetIPThreadParam(p);
8115
8116    return ret;
8117}
8118bool GetIP4Ex(IP *ip, char *hostname, UINT timeout, bool *cancel)
8119{
8120    return GetIP4Ex6Ex(ip, hostname, timeout, false, cancel);
8121}
8122bool GetIP6Ex(IP *ip, char *hostname, UINT timeout, bool *cancel)
8123{
8124    return GetIP4Ex6Ex(ip, hostname, timeout, true, cancel);
8125}
8126bool GetIP4(IP *ip, char *hostname)
8127{
8128    return GetIP4Ex(ip, hostname, 0, NULL);
8129}
8130bool GetIP6(IP *ip, char *hostname)
8131{
8132    return GetIP6Ex(ip, hostname, 0, NULL);
8133}
8134
8135// DNS 正引きクエリを行う
8136bool GetIP(IP *ip, char *hostname)
8137{
8138    return GetIPEx(ip, hostname, false);
8139}
8140bool GetIPEx(IP *ip, char *hostname, bool ipv6)
8141{
8142    if (ipv6 == false)
8143    {
8144        return GetIP4(ip, hostname);
8145    }
8146    else
8147    {
8148        return GetIP6(ip, hostname);
8149    }
8150}
8151bool GetIP6Inner(IP *ip, char *hostname)
8152{
8153    struct sockaddr_in6 in;
8154    struct in6_addr addr;
8155    struct addrinfo hint;
8156    struct addrinfo *info;
8157    // 引数チェック
8158    if (ip == NULL || hostname == NULL)
8159    {
8160        return false;
8161    }
8162
8163    if (IsEmptyStr(hostname))
8164    {
8165        return false;
8166    }
8167
8168    if (StrCmpi(hostname, "localhost") == 0)
8169    {
8170        GetLocalHostIP6(ip);
8171        return true;
8172    }
8173
8174    if (StrToIP6(ip, hostname) == false && StrToIP(ip, hostname) == false)
8175    {
8176        // 正引き
8177        Zero(&hint, sizeof(hint));
8178        hint.ai_family = AF_INET6;
8179        hint.ai_socktype = SOCK_STREAM;
8180        hint.ai_protocol = IPPROTO_TCP;
8181        info = NULL;
8182
8183        if (getaddrinfo(hostname, NULL, &hint, &info) != 0 ||
8184            info->ai_family != AF_INET6)
8185        {
8186            if (info)
8187            {
8188                freeaddrinfo(info);
8189            }
8190            return QueryDnsCacheEx(ip, hostname, true);
8191        }
8192        // 正引き成功
8193        Copy(&in, info->ai_addr, sizeof(struct sockaddr_in6));
8194        freeaddrinfo(info);
8195
8196        Copy(&addr, &in.sin6_addr, sizeof(addr));
8197        InAddrToIP6(ip, &addr);
8198    }
8199
8200    // キャッシュ保存
8201    NewDnsCache(hostname, ip);
8202
8203    return true;
8204}
8205bool GetIP4Inner(IP *ip, char *hostname)
8206{
8207    struct sockaddr_in in;
8208    struct in_addr addr;
8209    struct addrinfo hint;
8210    struct addrinfo *info;
8211    // 引数チェック
8212    if (ip == NULL || hostname == NULL)
8213    {
8214        return false;
8215    }
8216
8217    if (IsEmptyStr(hostname))
8218    {
8219        return false;
8220    }
8221
8222    if (StrCmpi(hostname, "localhost") == 0)
8223    {
8224        SetIP(ip, 127, 0, 0, 1);
8225        return true;
8226    }
8227
8228    if (StrToIP6(ip, hostname) == false && StrToIP(ip, hostname) == false)
8229    {
8230        // 正引き
8231        Zero(&hint, sizeof(hint));
8232        hint.ai_family = AF_INET;
8233        hint.ai_socktype = SOCK_STREAM;
8234        hint.ai_protocol = IPPROTO_TCP;
8235        info = NULL;
8236
8237        if (getaddrinfo(hostname, NULL, &hint, &info) != 0 ||
8238            info->ai_family != AF_INET)
8239        {
8240            if (info)
8241            {
8242                freeaddrinfo(info);
8243            }
8244            return QueryDnsCache(ip, hostname);
8245        }
8246        // 正引き成功
8247        Copy(&in, info->ai_addr, sizeof(struct sockaddr_in));
8248        freeaddrinfo(info);
8249        Copy(&addr, &in.sin_addr, sizeof(addr));
8250        InAddrToIP(ip, &addr);
8251    }
8252
8253    // キャッシュ保存
8254    NewDnsCache(hostname, ip);
8255
8256    return true;
8257}
8258
8259// DNS キャッシュを検索する
8260bool QueryDnsCache(IP *ip, char *hostname)
8261{
8262    return QueryDnsCacheEx(ip, hostname, false);
8263}
8264bool QueryDnsCacheEx(IP *ip, char *hostname, bool ipv6)
8265{
8266    DNSCACHE *c;
8267    char tmp[MAX_SIZE];
8268    // 引数チェック
8269    if (ip == NULL || hostname == NULL)
8270    {
8271        return false;
8272    }
8273
8274    GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
8275
8276    c = FindDnsCache(tmp);
8277    if (c == NULL)
8278    {
8279        return false;
8280    }
8281
8282    Copy(ip, &c->IpAddress, sizeof(IP));
8283
8284    return true;
8285}
8286
8287// IP を文字列に変換
8288void IPToUniStr(wchar_t *str, UINT size, IP *ip)
8289{
8290    char tmp[128];
8291
8292    IPToStr(tmp, sizeof(tmp), ip);
8293    StrToUni(str, size, tmp);
8294}
8295
8296// IP を文字列に変換 (32bit UINT)
8297void IPToUniStr32(wchar_t *str, UINT size, UINT ip)
8298{
8299    char tmp[128];
8300
8301    IPToStr32(tmp, sizeof(tmp), ip);
8302    StrToUni(str, size, tmp);
8303}
8304
8305// IP を文字列に変換 (128bit byte array)
8306void IPToStr128(char *str, UINT size, UCHAR *ip_bytes)
8307{
8308    IP ip_st;
8309    // 引数チェック
8310    if (str == NULL)
8311    {
8312        return;
8313    }
8314
8315    SetIP6(&ip_st, ip_bytes);
8316    IPToStr(str, size, &ip_st);
8317}
8318
8319// IP を文字列に変換 (32bit UINT)
8320void IPToStr32(char *str, UINT size, UINT ip)
8321{
8322    IP ip_st;
8323    // 引数チェック
8324    if (str == NULL)
8325    {
8326        return;
8327    }
8328
8329    UINTToIP(&ip_st, ip);
8330    IPToStr(str, size, &ip_st);
8331}
8332
8333// IPv4 または IPv6 を文字列に変換
8334void IPToStr4or6(char *str, UINT size, UINT ip_4_uint, UCHAR *ip_6_bytes)
8335{
8336    IP ip4;
8337    IP ip6;
8338    IP ip;
8339    // 引数チェック
8340    if (str == NULL)
8341    {
8342        return;
8343    }
8344
8345    Zero(&ip, sizeof(ip));
8346
8347    UINTToIP(&ip4, ip_4_uint);
8348    SetIP6(&ip6, ip_6_bytes);
8349
8350    if (IsIP6(&ip4) || (IsZeroIp(&ip4) && (IsZeroIp(&ip6) == false)))
8351    {
8352        Copy(&ip, &ip6, sizeof(IP));
8353    }
8354    else
8355    {
8356        Copy(&ip, &ip4, sizeof(IP));
8357    }
8358
8359    IPToStr(str, size, &ip);
8360}
8361
8362// IP を文字列に変換
8363void IPToStr(char *str, UINT size, IP *ip)
8364{
8365    // 引数チェック
8366    if (str == NULL || ip == NULL)
8367    {
8368        return;
8369    }
8370
8371    if (IsIP6(ip))
8372    {
8373        IPToStr6(str, size, ip);
8374    }
8375    else
8376    {
8377        IPToStr4(str, size, ip);
8378    }
8379}
8380
8381// IPv4 を文字列に変換
8382void IPToStr4(char *str, UINT size, IP *ip)
8383{
8384    // 引数チェック
8385    if (str == NULL || ip == NULL)
8386    {
8387        return;
8388    }
8389
8390    // 変換
8391    snprintf(str, size != 0 ? size : 64, "%u.%u.%u.%u", ip->addr[0], ip->addr[1], ip->addr[2], ip->addr[3]);
8392}
8393
8394// 文字列を IP に変換
8395bool StrToIP(IP *ip, char *str)
8396{
8397    TOKEN_LIST *token;
8398    char *tmp;
8399    UINT i;
8400    // 引数チェック
8401    if (ip == NULL || str == NULL)
8402    {
8403        return false;
8404    }
8405
8406    if (StrToIP6(ip, str))
8407    {
8408        return true;
8409    }
8410
8411    Zero(ip, sizeof(IP));
8412
8413    tmp = CopyStr(str);
8414    Trim(tmp);
8415    token = ParseToken(tmp, ".");
8416    Free(tmp);
8417
8418    if (token->NumTokens != 4)
8419    {
8420        FreeToken(token);
8421        return false;
8422    }
8423    for (i = 0;i < 4;i++)
8424    {
8425        char *s = token->Token[i];
8426        if (s[0] < '0' || s[0] > '9' ||
8427            (ToInt(s) >= 256))
8428        {
8429            FreeToken(token);
8430            return false;
8431        }
8432    }
8433    Zero(ip, sizeof(IP));
8434    for (i = 0;i < 4;i++)
8435    {
8436        ip->addr[i] = (UCHAR)ToInt(token->Token[i]);
8437    }
8438
8439    FreeToken(token);
8440
8441    return true;
8442}
8443UINT StrToIP32(char *str)
8444{
8445    IP ip;
8446    // 引数チェック
8447    if (str == NULL)
8448    {
8449        return 0;
8450    }
8451
8452    if (StrToIP(&ip, str) == false)
8453    {
8454        return 0;
8455    }
8456
8457    return IPToUINT(&ip);
8458}
8459bool UniStrToIP(IP *ip, wchar_t *str)
8460{
8461    char *tmp;
8462    bool ret;
8463
8464    tmp = CopyUniToStr(str);
8465    ret = StrToIP(ip, tmp);
8466    Free(tmp);
8467
8468    return ret;
8469}
8470UINT UniStrToIP32(wchar_t *str)
8471{
8472    UINT ret;
8473    char *tmp;
8474
8475    tmp = CopyUniToStr(str);
8476    ret = StrToIP32(tmp);
8477    Free(tmp);
8478
8479    return ret;
8480}
8481
8482// IP を in_addr に変換
8483void IPToInAddr(struct in_addr *addr, IP *ip)
8484{
8485    UINT i;
8486    // 引数チェック
8487    if (addr == NULL || ip == NULL)
8488    {
8489        return;
8490    }
8491
8492    Zero(addr, sizeof(struct in_addr));
8493
8494    if (IsIP6(ip) == false)
8495    {
8496        for (i = 0;i < 4;i++)
8497        {
8498            ((UCHAR *)addr)[i] = ip->addr[i];
8499        }
8500    }
8501}
8502
8503// IP を in6_addr に変換
8504void IPToInAddr6(struct in6_addr *addr, IP *ip)
8505{
8506    UINT i;
8507    // 引数チェック
8508    if (addr == NULL || ip == NULL)
8509    {
8510        return;
8511    }
8512
8513    Zero(addr, sizeof(struct in_addr));
8514
8515    if (IsIP6(ip))
8516    {
8517        for (i = 0;i < 16;i++)
8518        {
8519            ((UCHAR *)addr)[i] = ip->ipv6_addr[i];
8520        }
8521    }
8522}
8523
8524// in_addr を IP に変換
8525void InAddrToIP(IP *ip, struct in_addr *addr)
8526{
8527    UINT i;
8528    // 引数チェック
8529    if (ip == NULL || addr == NULL)
8530    {
8531        return;
8532    }
8533
8534    Zero(ip, sizeof(IP));
8535
8536    for (i = 0;i < 4;i++)
8537    {
8538        ip->addr[i] = ((UCHAR *)addr)[i];
8539    }
8540}
8541
8542// in6_addr を IP に変換
8543void InAddrToIP6(IP *ip, struct in6_addr *addr)
8544{
8545    UINT i;
8546    // 引数チェック
8547    if (ip == NULL || addr == NULL)
8548    {
8549        return;
8550    }
8551
8552    ZeroIP6(ip);
8553    for (i = 0;i < 16;i++)
8554    {
8555        ip->ipv6_addr[i] = ((UCHAR *)addr)[i];
8556    }
8557}
8558
8559// DNS キャッシュの検索
8560DNSCACHE *FindDnsCache(char *hostname)
8561{
8562    return FindDnsCacheEx(hostname, false);
8563}
8564DNSCACHE *FindDnsCacheEx(char *hostname, bool ipv6)
8565{
8566    DNSCACHE *c;
8567    char tmp[MAX_SIZE];
8568    if (hostname == NULL)
8569    {
8570        return NULL;
8571    }
8572
8573    GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
8574
8575    LockDnsCache();
8576    {
8577        DNSCACHE t;
8578        t.HostName = tmp;
8579        c = Search(DnsCache, &t);
8580    }
8581    UnlockDnsCache();
8582
8583    return c;
8584}
8585
8586// DNS キャッシュ用の IPv4 / IPv6 キー名を生成
8587void GenDnsCacheKeyName(char *dst, UINT size, char *src, bool ipv6)
8588{
8589    // 引数チェック
8590    if (dst == NULL || src == NULL)
8591    {
8592        return;
8593    }
8594
8595    if (ipv6 == false)
8596    {
8597        StrCpy(dst, size, src);
8598    }
8599    else
8600    {
8601        Format(dst, size, "%s@ipv6", src);
8602    }
8603}
8604
8605// 新しい DNS キャッシュの登録
8606void NewDnsCache(char *hostname, IP *ip)
8607{
8608    NewDnsCacheEx(hostname, ip, IsIP6(ip));
8609}
8610void NewDnsCacheEx(char *hostname, IP *ip, bool ipv6)
8611{
8612    DNSCACHE *c;
8613    char tmp[MAX_PATH];
8614    // 引数チェック
8615    if (hostname == NULL || ip == NULL)
8616    {
8617        return;
8618    }
8619
8620    if (IsNetworkNameCacheEnabled() == false)
8621    {
8622        return;
8623    }
8624
8625    GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
8626
8627    LockDnsCache();
8628    {
8629        DNSCACHE t;
8630
8631        // まず hostname に該当するものがあるかどうか検索してみる
8632        t.HostName = tmp;
8633        c = Search(DnsCache, &t);
8634
8635        if (c == NULL)
8636        {
8637            // 新規登録
8638            c = ZeroMalloc(sizeof(DNSCACHE));
8639            c->HostName = CopyStr(tmp);
8640
8641            Copy(&c->IpAddress, ip, sizeof(IP));
8642
8643            Add(DnsCache, c);
8644        }
8645        else
8646        {
8647            // 更新
8648            Copy(&c->IpAddress, ip, sizeof(IP));
8649        }
8650    }
8651    UnlockDnsCache();
8652}
8653
8654// DNS キャッシュの名前比較
8655int CompareDnsCache(void *p1, void *p2)
8656{
8657    DNSCACHE *c1, *c2;
8658    if (p1 == NULL || p2 == NULL)
8659    {
8660        return 0;
8661    }
8662    c1 = *(DNSCACHE **)p1;
8663    c2 = *(DNSCACHE **)p2;
8664    if (c1 == NULL || c2 == NULL)
8665    {
8666        return 0;
8667    }
8668
8669    return StrCmpi(c1->HostName, c2->HostName);
8670}
8671
8672// DNS キャッシュの初期化
8673void InitDnsCache()
8674{
8675    // リスト作成
8676    DnsCache = NewList(CompareDnsCache);
8677}
8678
8679// DNS キャッシュの解放
8680void FreeDnsCache()
8681{
8682    LockDnsCache();
8683    {
8684        DNSCACHE *c;
8685        UINT i;
8686        for (i = 0;i < LIST_NUM(DnsCache);i++)
8687        {
8688            // エントリのメモリ解放
8689            c = LIST_DATA(DnsCache, i);
8690            Free(c->HostName);
8691            Free(c);
8692        }
8693    }
8694    UnlockDnsCache();
8695
8696    // リスト解放
8697    ReleaseList(DnsCache);
8698    DnsCache = NULL;
8699}
8700
8701// DNS キャッシュのロック
8702void LockDnsCache()
8703{
8704    LockList(DnsCache);
8705}
8706
8707// DNS キャッシュのロック解除
8708void UnlockDnsCache()
8709{
8710    UnlockList(DnsCache);
8711}
8712
8713// ネットワーク通信モジュールの初期化
8714void InitNetwork()
8715{
8716    num_tcp_connections = NewCounter();
8717
8718    // クライアントリストの初期化
8719    InitIpClientList();
8720
8721    // スレッド関係の初期化
8722    InitWaitThread();
8723
8724    // ホスト名キャッシュの初期化
8725    InitHostCache();
8726
8727#ifdef  OS_WIN32
8728    // ソケットライブラリの初期化
8729    Win32InitSocketLibrary();
8730#else
8731    UnixInitSocketLibrary();
8732#endif  // OS_WIN32
8733
8734    // DNS キャッシュの初期化
8735    InitDnsCache();
8736
8737    // OpenSSL の初期化
8738    ssl_ctx = SSL_CTX_new(SSLv23_method());
8739
8740    // ロック初期化
8741    machine_name_lock = NewLock();
8742    disconnect_function_lock = NewLock();
8743    aho = NewLock();
8744    socket_library_lock = NewLock();
8745    ssl_connect_lock = NewLock();
8746//  ssl_accept_lock = NewLock();
8747    dns_lock = NewLock();
8748    unix_dns_server_addr_lock = NewLock();
8749    Zero(&unix_dns_server, sizeof(unix_dns_server));
8750
8751    cipher_list_token = ParseToken(cipher_list, " ");
8752
8753    disable_cache = false;
8754}
8755
8756// ネットワーク名キャッシュの有効化
8757void EnableNetworkNameCache()
8758{
8759    disable_cache = false;
8760}
8761
8762// ネットワーク名キャッシュの無効化
8763void DisableNetworkNameCache()
8764{
8765    disable_cache = true;
8766}
8767
8768// ネットワーク名キャッシュが有効かどうか取得
8769bool IsNetworkNameCacheEnabled()
8770{
8771    return !disable_cache;
8772}
8773
8774// 暗号化アルゴリズムリストを取得
8775TOKEN_LIST *GetCipherList()
8776{
8777    return cipher_list_token;
8778}
8779
8780// TCP コネクション数カウンタを取得
8781COUNTER *GetNumTcpConnectionsCounter()
8782{
8783    return num_tcp_connections;
8784}
8785
8786// ネットワーク通信モジュールの解放
8787void FreeNetwork()
8788{
8789    FreeToken(cipher_list_token);
8790    cipher_list_token = NULL;
8791
8792    Zero(&unix_dns_server, sizeof(unix_dns_server));
8793
8794    // ロック解放
8795    DeleteLock(unix_dns_server_addr_lock);
8796    DeleteLock(dns_lock);
8797    DeleteLock(ssl_accept_lock);
8798    DeleteLock(machine_name_lock);
8799    DeleteLock(disconnect_function_lock);
8800    DeleteLock(aho);
8801    DeleteLock(socket_library_lock);
8802    DeleteLock(ssl_connect_lock);
8803    machine_name_lock = NULL;
8804    ssl_accept_lock = machine_name_lock = disconnect_function_lock =
8805        aho = socket_library_lock = ssl_connect_lock = NULL;
8806
8807    // OpenSSL の解放
8808    SSL_CTX_free(ssl_ctx);
8809    ssl_ctx = NULL;
8810
8811    // スレッド関係の解放
8812    FreeWaitThread();
8813
8814    // DNS キャッシュの解放
8815    FreeDnsCache();
8816
8817    // ホスト名キャッシュの解放
8818    FreeHostCache();
8819
8820#ifdef  OS_WIN32
8821    // ソケットライブラリの解放
8822    Win32FreeSocketLibrary();
8823#else
8824    UnixFreeSocketLibrary();
8825#endif  // OS_WIN32
8826
8827    DeleteCounter(num_tcp_connections);
8828    num_tcp_connections = NULL;
8829
8830    // クライアントリストの解放
8831    FreeIpClientList();
8832}
8833
8834// ソケットリストにソケットを追加する
8835void AddSockList(SOCKLIST *sl, SOCK *s)
8836{
8837    // 引数チェック
8838    if (sl == NULL || s == NULL)
8839    {
8840        return;
8841    }
8842
8843    LockList(sl->SockList);
8844    {
8845        if (IsInList(sl->SockList, s) == false)
8846        {
8847            AddRef(s->ref);
8848
8849            Insert(sl->SockList, s);
8850        }
8851    }
8852    UnlockList(sl->SockList);
8853}
8854
8855// ソケットリストからソケットを削除する
8856void DelSockList(SOCKLIST *sl, SOCK *s)
8857{
8858    // 引数チェック
8859    if (sl == NULL || s == NULL)
8860    {
8861        return;
8862    }
8863
8864    LockList(sl->SockList);
8865    {
8866        if (Delete(sl->SockList, s))
8867        {
8868            ReleaseSock(s);
8869        }
8870    }
8871    UnlockList(sl->SockList);
8872}
8873
8874// ソケットリストのソケットをすべて停止させて削除する
8875void StopSockList(SOCKLIST *sl)
8876{
8877    SOCK **ss;
8878    UINT num, i;
8879    // 引数チェック
8880    if (sl == NULL)
8881    {
8882        return;
8883    }
8884
8885    LockList(sl->SockList);
8886    {
8887        num = LIST_NUM(sl->SockList);
8888        ss = ToArray(sl->SockList);
8889
8890        DeleteAll(sl->SockList);
8891    }
8892    UnlockList(sl->SockList);
8893
8894    for (i = 0;i < num;i++)
8895    {
8896        SOCK *s = ss[i];
8897
8898        Disconnect(s);
8899        ReleaseSock(s);
8900    }
8901
8902    Free(ss);
8903}
8904
8905// ソケットリストの削除
8906void FreeSockList(SOCKLIST *sl)
8907{
8908    // 引数チェック
8909    if (sl == NULL)
8910    {
8911        return;
8912    }
8913
8914    StopSockList(sl);
8915
8916    ReleaseList(sl->SockList);
8917
8918    Free(sl);
8919}
8920
8921// ソケットリストの作成
8922SOCKLIST *NewSockList()
8923{
8924    SOCKLIST *sl = ZeroMallocFast(sizeof(SOCKLIST));
8925
8926    sl->SockList = NewList(NULL);
8927
8928    return sl;
8929}
8930
8931// Solarisでのソケットのタイムアウト用スレッド
8932void SocketTimeoutThread(THREAD *t, void *param)
8933{
8934    SOCKET_TIMEOUT_PARAM *ttparam;
8935    ttparam = (SOCKET_TIMEOUT_PARAM *)param;
8936
8937    // タイムアウト時間だけ待つ
8938    Select(NULL, ttparam->sock->TimeOut, ttparam->cancel, NULL);
8939
8940    // ブロック中ならディスコネクトする
8941    if(! ttparam->unblocked)
8942    {
8943//      Debug("Socket timeouted\n");
8944        closesocket(ttparam->sock->socket);
8945    }
8946    else
8947    {
8948//      Debug("Socket timeout cancelled\n");
8949    }
8950}
8951
8952// タイムアウト用スレッドの初期化と開始
8953SOCKET_TIMEOUT_PARAM *NewSocketTimeout(SOCK *sock)
8954{
8955    SOCKET_TIMEOUT_PARAM *ttp;
8956    if(! sock->AsyncMode && sock->TimeOut != TIMEOUT_INFINITE)
8957    {
8958//      Debug("NewSockTimeout(%u)\n",sock->TimeOut);
8959
8960        ttp = (SOCKET_TIMEOUT_PARAM*)Malloc(sizeof(SOCKET_TIMEOUT_PARAM));
8961
8962        // タイムアウトスレッド用のパラメータをセット
8963        ttp->cancel = NewCancel();
8964        ttp->sock = sock;
8965        ttp->unblocked = false;
8966        ttp->thread = NewThread(SocketTimeoutThread, ttp);
8967        return ttp;
8968    }
8969    return NULL;
8970}
8971
8972// タイムアウト用スレッドの停止と開放
8973void FreeSocketTimeout(SOCKET_TIMEOUT_PARAM *ttp)
8974{
8975    if(ttp == NULL)
8976    {
8977        return;
8978    }
8979
8980    ttp->unblocked = true;
8981    Cancel(ttp->cancel);
8982    WaitThread(ttp->thread, INFINITE);
8983    ReleaseCancel(ttp->cancel);
8984    ReleaseThread(ttp->thread);
8985    Free(ttp);
8986//  Debug("FreeSocketTimeout succeed\n");
8987    return;
8988}
8989
8990// IP アドレスとサブネット マスクのパース
8991bool ParseIpAndSubnetMask46(char *src, IP *ip, IP *mask)
8992{
8993    // 引数チェック
8994    if (src == NULL || ip == NULL || mask == NULL)
8995    {
8996        return false;
8997    }
8998
8999    if (ParseIpAndMask46(src, ip, mask) == false)
9000    {
9001        return false;
9002    }
9003
9004    if (IsIP4(ip))
9005    {
9006        return IsSubnetMask4(mask);
9007    }
9008    else
9009    {
9010        return IsSubnetMask6(mask);
9011    }
9012}
9013bool ParseIpAndSubnetMask6(char *src, IP *ip, IP *mask)
9014{
9015    if (ParseIpAndSubnetMask46(src, ip, mask) == false)
9016    {
9017        return false;
9018    }
9019
9020    if (IsIP6(ip) == false)
9021    {
9022        return false;
9023    }
9024
9025    return true;
9026}
9027bool ParseIpAndSubnetMask4(char *src, UINT *ip, UINT *mask)
9028{
9029    IP ip2, mask2;
9030    // 引数チェック
9031    if (src == NULL)
9032    {
9033        return false;
9034    }
9035
9036    if (ParseIpAndSubnetMask46(src, &ip2, &mask2) == false)
9037    {
9038        return false;
9039    }
9040
9041    if (IsIP4(&ip2) == false)
9042    {
9043        return false;
9044    }
9045
9046    if (ip != NULL)
9047    {
9048        *ip = IPToUINT(&ip2);
9049    }
9050
9051    if (mask != NULL)
9052    {
9053        *mask = IPToUINT(&mask2);
9054    }
9055
9056    return true;
9057}
9058
9059
9060// IP アドレスとマスクのパース
9061bool ParseIpAndMask46(char *src, IP *ip, IP *mask)
9062{
9063    TOKEN_LIST *t;
9064    char *ipstr;
9065    char *subnetstr;
9066    bool ret = false;
9067    IP ip2;
9068    IP mask2;
9069    // 引数チェック
9070    if (src == NULL || ip == NULL || mask == NULL)
9071    {
9072        return false;
9073    }
9074
9075    Zero(&ip2, sizeof(IP));
9076    Zero(&mask2, sizeof(IP));
9077
9078    t = ParseToken(src, "/");
9079    if (t->NumTokens != 2)
9080    {
9081        FreeToken(t);
9082        return false;
9083    }
9084
9085    ipstr = t->Token[0];
9086    subnetstr = t->Token[1];
9087    Trim(ipstr);
9088    Trim(subnetstr);
9089
9090    if (StrToIP(&ip2, ipstr))
9091    {
9092        if (StrToIP(&mask2, subnetstr))
9093        {
9094            // IP アドレス部とマスク部が同一の種類かどうか比較する
9095            if (IsIP6(&ip2) && IsIP6(&mask2))
9096            {
9097                // 両方とも IPv6
9098                ret = true;
9099                Copy(ip, &ip2, sizeof(IP));
9100                Copy(mask, &mask2, sizeof(IP));
9101            }
9102            else if (IsIP4(&ip2) && IsIP4(&mask2))
9103            {
9104                // 両方とも IPv4
9105                ret = true;
9106                Copy(ip, &ip2, sizeof(IP));
9107                Copy(mask, &mask2, sizeof(IP));
9108            }
9109        }
9110        else
9111        {
9112            if (IsNum(subnetstr))
9113            {
9114                UINT i = ToInt(subnetstr);
9115                // マスク部が数値
9116                if (IsIP6(&ip2) && i <= 128)
9117                {
9118                    ret = true;
9119                    Copy(ip, &ip2, sizeof(IP));
9120                    IntToSubnetMask6(mask, i);
9121                }
9122                else if (i <= 32)
9123                {
9124                    ret = true;
9125                    Copy(ip, &ip2, sizeof(IP));
9126                    IntToSubnetMask4(mask, i);
9127                }
9128            }
9129        }
9130    }
9131
9132    FreeToken(t);
9133
9134    return ret;
9135}
9136bool ParseIpAndMask4(char *src, UINT *ip, UINT *mask)
9137{
9138    IP ip_ip, ip_mask;
9139    if (ParseIpAndMask46(src, &ip_ip, &ip_mask) == false)
9140    {
9141        return false;
9142    }
9143
9144    if (IsIP4(&ip_ip) == false)
9145    {
9146        return false;
9147    }
9148
9149    if (ip != NULL)
9150    {
9151        *ip = IPToUINT(&ip_ip);
9152    }
9153
9154    if (mask != NULL)
9155    {
9156        *mask = IPToUINT(&ip_mask);
9157    }
9158
9159    return true;
9160}
9161bool ParseIpAndMask6(char *src, IP *ip, IP *mask)
9162{
9163    if (ParseIpAndMask46(src, ip, mask) == false)
9164    {
9165        return false;
9166    }
9167
9168    if (IsIP6(ip) == false)
9169    {
9170        return false;
9171    }
9172
9173    return true;
9174}
9175
9176
9177// IPv4 アドレスの指定が正しいかどうかチェックする
9178bool IsIpStr4(char *str)
9179{
9180    // 引数チェック
9181    if (str == NULL)
9182    {
9183        return false;
9184    }
9185
9186    if (StrToIP32(str) == 0 && StrCmpi(str, "0.0.0.0") != 0)
9187    {
9188        return false;
9189    }
9190
9191    return true;
9192}
9193
9194// IPv6 アドレスの指定が正しいかどうかチェックする
9195bool IsIpStr6(char *str)
9196{
9197    IP ip;
9198    // 引数チェック
9199    if (str == NULL)
9200    {
9201        return false;
9202    }
9203
9204    if (StrToIP6(&ip, str) == false)
9205    {
9206        return false;
9207    }
9208
9209    return true;
9210}
9211
9212// IP アドレスの指定が正しいかどうかチェックする
9213bool IsIpStr46(char *str)
9214{
9215    if (IsIpStr4(str) || IsIpStr6(str))
9216    {
9217        return true;
9218    }
9219
9220    return false;
9221}
9222
9223
9224// 文字列を IPv4 マスクに変換
9225bool StrToMask4(IP *mask, char *str)
9226{
9227    // 引数チェック
9228    if (mask == NULL || str == NULL)
9229    {
9230        return false;
9231    }
9232
9233    if (str[0] == '/')
9234    {
9235        str++;
9236    }
9237
9238    if (IsNum(str))
9239    {
9240        UINT n = ToInt(str);
9241
9242        if (n <= 32)
9243        {
9244            IntToSubnetMask4(mask, n);
9245            return true;
9246        }
9247        else
9248        {
9249            return false;
9250        }
9251    }
9252    else
9253    {
9254        if (StrToIP(mask, str) == false)
9255        {
9256            return false;
9257        }
9258        else
9259        {
9260            return IsIP4(mask);
9261        }
9262    }
9263}
9264
9265// 文字列を IPv6 マスクに変換
9266bool StrToMask6(IP *mask, char *str)
9267{
9268    // 引数チェック
9269    if (mask == NULL || str == NULL)
9270    {
9271        return false;
9272    }
9273
9274    if (str[0] == '/')
9275    {
9276        str++;
9277    }
9278
9279    if (IsNum(str))
9280    {
9281        UINT n = ToInt(str);
9282
9283        if (n <= 128)
9284        {
9285            IntToSubnetMask6(mask, n);
9286            return true;
9287        }
9288        else
9289        {
9290            return false;
9291        }
9292    }
9293    else
9294    {
9295        if (StrToIP(mask, str) == false)
9296        {
9297            return false;
9298        }
9299        else
9300        {
9301            return IsIP6(mask);
9302        }
9303    }
9304}
9305bool StrToMask6Addr(IPV6_ADDR *mask, char *str)
9306{
9307    IP ip;
9308
9309    if (StrToMask6(&ip, str) == false)
9310    {
9311        return false;
9312    }
9313
9314    if (IPToIPv6Addr(mask, &ip) == false)
9315    {
9316        return false;
9317    }
9318
9319    return true;
9320}
9321
9322// 文字列を IPv4 / IPv6 マスクに変換
9323bool StrToMask46(IP *mask, char *str, bool ipv6)
9324{
9325    if (ipv6)
9326    {
9327        return StrToMask6(mask, str);
9328    }
9329    else
9330    {
9331        return StrToMask4(mask, str);
9332    }
9333}
9334
9335
9336// IPv4 / IPv6 マスクを文字列に変換
9337void MaskToStr(char *str, UINT size, IP *mask)
9338{
9339    MaskToStrEx(str, size, mask, false);
9340}
9341void MaskToStrEx(char *str, UINT size, IP *mask, bool always_full_address)
9342{
9343    // 引数チェック
9344    if (str == NULL || mask == NULL)
9345    {
9346        return;
9347    }
9348
9349    if (always_full_address == false && IsSubnetMask(mask))
9350    {
9351        ToStr(str, SubnetMaskToInt(mask));
9352    }
9353    else
9354    {
9355        IPToStr(str, size, mask);
9356    }
9357}
9358void MaskToStr32(char *str, UINT size, UINT mask)
9359{
9360    MaskToStr32Ex(str, size, mask, false);
9361}
9362void MaskToStr32Ex(char *str, UINT size, UINT mask, bool always_full_address)
9363{
9364    IP ip;
9365
9366    UINTToIP(&ip, mask);
9367
9368    MaskToStrEx(str, size, &ip, always_full_address);
9369}
9370void Mask6AddrToStrEx(char *str, UINT size, IPV6_ADDR *mask, bool always_full_address)
9371{
9372    IP ip;
9373
9374    // 引数チェック
9375    if (str == NULL || mask == NULL)
9376    {
9377        StrCpy(str, size, "");
9378        return;
9379    }
9380
9381    IPv6AddrToIP(&ip, mask);
9382
9383    MaskToStrEx(str, size, &ip, always_full_address);
9384}
9385void Mask6AddrToStr(char *str, UINT size, IPV6_ADDR *mask)
9386{
9387    Mask6AddrToStrEx(str, size, mask, false);
9388}
9389
Note: See TracBrowser for help on using the repository browser.