OSDN Git Service

Add support for IPv6 (not tested).
authors_kawamoto <s_kawamoto@users.sourceforge.jp>
Sat, 12 Nov 2011 08:41:28 +0000 (17:41 +0900)
committers_kawamoto <s_kawamoto@users.sourceforge.jp>
Sat, 12 Nov 2011 08:41:28 +0000 (17:41 +0900)
13 files changed:
FFFTP_Eng_Release/FFFTP.exe
Release/FFFTP.exe
common.h
connect.c
doc/eng/FFFTP.txt
doc/eng/history.txt
doc/jpn/FFFTP.txt
doc/jpn/history.txt
getput.c
hostman.c
local.c
registry.c
socket.c

index 1bc2af7..ff13c9f 100644 (file)
Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
index 94794db..9f6beb7 100644 (file)
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
index a6c3eaa..c9064ce 100644 (file)
--- a/common.h
+++ b/common.h
@@ -952,6 +952,7 @@ typedef struct {
        // MLSD対応\r
        int UseMLSD;                                            /* "MLSD"コマンドを使用する */\r
        // IPv6対応\r
+       int InetFamily;                                         /* IPv6接続かどうか (AF_INET/AF_INET6) */\r
        int UseIPv6;                                            /* IPv6接続を許可しEPRT/EPSVコマンドを使用する */\r
 } HOSTDATA;\r
 \r
@@ -1181,9 +1182,11 @@ typedef struct {
        char Rsv;                               /* (予約) */\r
        char Type;                              /* アドレスのタイプ */\r
                                                        /* 以後(可変長部分) */\r
-       ulong AdrsInt;                  /* アドレス */\r
-       ushort Port;                    /* ポート */\r
-       char _dummy[2];                 /* dummy */\r
+       // IPv6対応\r
+//     ulong AdrsInt;                  /* アドレス */\r
+//     ushort Port;                    /* ポート */\r
+//     char _dummy[2];                 /* dummy */\r
+       char _dummy[255+1+2];   /* dummy */\r
 } SOCKS5REPLY;\r
 \r
 #define SOCKS5REPLY_SIZE 4     /* 最初の固定部分のサイズ */\r
@@ -1416,7 +1419,13 @@ void DisconnectProc(void);
 void DisconnectSet(void);\r
 int AskConnecting(void);\r
 SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork);\r
+// IPv6対応\r
+SOCKET connectsockIPv4(char *host, int port, char *PreMsg, int *CancelCheckWork);\r
+SOCKET connectsockIPv6(char *host, int port, char *PreMsg, int *CancelCheckWork);\r
 SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork);\r
+// IPv6対応\r
+SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork);\r
+SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork);\r
 int AskTryingConnect(void);\r
 // 同時接続対応\r
 //int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data);\r
@@ -1436,6 +1445,7 @@ int AskHostFeature(void);
 // MLSD対応\r
 int AskUseMLSD(void);\r
 // IPv6対応\r
+int AskInetFamily(void);\r
 int AskUseIPv6(void);\r
 \r
 /*===== cache.c =====*/\r
@@ -1724,7 +1734,10 @@ char *AskLocalFreeSpace(char *Path);
 \r
 int MakeSocketWin(HWND hWnd, HINSTANCE hInst);\r
 void DeleteSocketWin(void);\r
-struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork);\r
+// IPv6対応\r
+//struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork);\r
+struct hostent *do_gethostbynameIPv4(const char *Name, char *Buf, int Len, int *CancelCheckWork);\r
+struct hostent *do_gethostbynameIPv6(const char *Name, char *Buf, int Len, int *CancelCheckWork);\r
 SOCKET do_socket(int af, int type, int protocol);\r
 int do_connect(SOCKET s, const struct sockaddr *name, int namelen, int *CancelCheckWork);\r
 int do_closesocket(SOCKET s);\r
@@ -1736,6 +1749,10 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int
 void RemoveReceivedData(SOCKET s);\r
 int CheckClosedAndReconnect(void);\r
 void CheckAllEventClosed(void);\r
+// IPv6対応\r
+char* AddressToStringIPv6(char* str, void* in6);\r
+char* inet6_ntoa(struct in6_addr in6);\r
+struct in6_addr inet6_addr(const char* cp);\r
 \r
 /*===== updatebell.c =====*/\r
 \r
index fe01e66..dfbf5e0 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -35,7 +35,9 @@
 #include <string.h>\r
 #include <mbstring.h>\r
 #include <time.h>\r
-#include <winsock.h>\r
+// IPv6対応\r
+//#include <winsock.h>\r
+#include <ws2tcpip.h>\r
 #include <windowsx.h>\r
 #include <commctrl.h>\r
 \r
@@ -65,6 +67,8 @@ static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass,
 static int CheckOneTimePassword(char *Pass, char *Reply, int Type);\r
 static BOOL CALLBACK BlkHookFnc(void);\r
 static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulong IP, char *Host, ushort Port);\r
+// IPv6対応\r
+static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port);\r
 static int SocksSendCmd(SOCKET Socket, void *Data, int Size, int *CancelCheckWork);\r
 // 同時接続対応\r
 //static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet);\r
@@ -107,8 +111,14 @@ static int TmpNameKanjiCode;
 \r
 /* 接続中の接続先、SOCKSサーバのアドレス情報を保存しておく */\r
 /* この情報はlistenソケットを取得する際に用いる */\r
-static struct sockaddr_in SocksSockAddr;       /* SOCKSサーバのアドレス情報 */\r
-static struct sockaddr_in CurSockAddr;         /* 接続先ホストのアドレス情報 */\r
+// IPv6対応\r
+//static struct sockaddr_in SocksSockAddr;     /* SOCKSサーバのアドレス情報 */\r
+//static struct sockaddr_in CurSockAddr;               /* 接続先ホストのアドレス情報 */\r
+static struct sockaddr_in SocksSockAddrIPv4;   /* SOCKSサーバのアドレス情報 */\r
+static struct sockaddr_in CurSockAddrIPv4;             /* 接続先ホストのアドレス情報 */\r
+static struct sockaddr_in6 SocksSockAddrIPv6;  /* SOCKSサーバのアドレス情報 */\r
+static struct sockaddr_in6 CurSockAddrIPv6;            /* 接続先ホストのアドレス情報 */\r
+static const struct in6_addr IN6ADDR_NONE = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};\r
 \r
 static int UseIPadrs;\r
 static char DomainName[HOST_ADRS_LEN+1];\r
@@ -1789,8 +1799,34 @@ static int CheckOneTimePassword(char *Pass, char *Reply, int Type)
 *              SOCKET ソケット\r
 *----------------------------------------------------------------------------*/\r
 \r
+// IPv6対応\r
 SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
 {\r
+       SOCKET Result;\r
+       Result = INVALID_SOCKET;\r
+       switch(CurHost.InetFamily)\r
+       {\r
+       case AF_UNSPEC:\r
+               if((Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
+                       CurHost.InetFamily = AF_INET;\r
+               else if(CurHost.UseIPv6 == YES && (Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
+                       CurHost.InetFamily = AF_INET6;\r
+               break;\r
+       case AF_INET:\r
+               Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork);\r
+               break;\r
+       case AF_INET6:\r
+               Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork);\r
+               break;\r
+       }\r
+       return Result;\r
+}\r
+\r
+\r
+// IPv6対応\r
+//SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
+SOCKET connectsockIPv4(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
+{\r
        struct sockaddr_in saSockAddr;\r
        char HostEntry[MAXGETHOSTSTRUCT];\r
        struct hostent *pHostEntry;\r
@@ -1814,10 +1850,15 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
 \r
        UseIPadrs = YES;\r
        strcpy(DomainName, host);\r
-       memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
-       CurSockAddr.sin_port = htons((u_short)port);\r
-       CurSockAddr.sin_family = AF_INET;\r
-       if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)\r
+       // IPv6対応\r
+//     memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
+//     CurSockAddr.sin_port = htons((u_short)port);\r
+//     CurSockAddr.sin_family = AF_INET;\r
+//     if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)\r
+       memset(&CurSockAddrIPv4, 0, sizeof(CurSockAddrIPv4));\r
+       CurSockAddrIPv4.sin_port = htons((u_short)port);\r
+       CurSockAddrIPv4.sin_family = AF_INET;\r
+       if((CurSockAddrIPv4.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)\r
        {\r
                // ホスト名が指定された\r
                // ホスト名からアドレスを求める\r
@@ -1831,20 +1872,27 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
                {\r
                        // アドレスを取得\r
                        SetTaskMsg(MSGJPN016, DomainName);\r
-                       pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
+                       // IPv6対応\r
+//                     pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
+                       pHostEntry = do_gethostbynameIPv4(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
                }\r
 \r
                if(pHostEntry != NULL)\r
                {\r
-                       memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
-                       SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
+                       // IPv6対応\r
+//                     memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
+//                     SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
+                       memcpy((char *)&CurSockAddrIPv4.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
+                       SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddrIPv4.sin_addr), ntohs(CurSockAddrIPv4.sin_port));\r
                }\r
                else\r
                {\r
                        if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
                        {\r
                                UseIPadrs = NO;\r
-                               SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port));\r
+                               // IPv6対応\r
+//                             SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port));\r
+                               SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddrIPv4.sin_port));\r
                        }\r
                        else\r
                        {\r
@@ -1854,7 +1902,9 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
                }\r
        }\r
        else\r
-               SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
+               // IPv6対応\r
+//             SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
+               SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddrIPv4.sin_addr), ntohs(CurSockAddrIPv4.sin_port));\r
 \r
        if((Fwall == FWALL_SOCKS4) || (Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
        {\r
@@ -1864,37 +1914,56 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
                {\r
                        Socks4Cmd.Ver = SOCKS4_VER;\r
                        Socks4Cmd.Cmd = SOCKS4_CMD_CONNECT;\r
-                       Socks4Cmd.Port = CurSockAddr.sin_port;\r
-                       Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
+                       // IPv6対応\r
+//                     Socks4Cmd.Port = CurSockAddr.sin_port;\r
+//                     Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
+                       Socks4Cmd.Port = CurSockAddrIPv4.sin_port;\r
+                       Socks4Cmd.AdrsInt = CurSockAddrIPv4.sin_addr.s_addr;\r
                        strcpy(Socks4Cmd.UserID, FwallUser);\r
                        Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
                }\r
                else\r
                {\r
-                       Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
+                       // IPv6対応\r
+//                     Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
+                       Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddrIPv4.sin_addr.s_addr, DomainName, CurSockAddrIPv4.sin_port);\r
                }\r
 \r
-               memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
-               if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)\r
+               // IPv6対応\r
+//             memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
+//             if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)\r
+               memset(&SocksSockAddrIPv4, 0, sizeof(SocksSockAddrIPv4));\r
+               if((SocksSockAddrIPv4.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)\r
                {\r
-                       if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
-                               memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
+                       // IPv6対応\r
+//                     if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
+//                             memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
+                       if((pHostEntry = do_gethostbynameIPv4(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
+                               memcpy((char *)&SocksSockAddrIPv4.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
                        else\r
                        {\r
                                SetTaskMsg(MSGJPN021, FwallHost);\r
                                return INVALID_SOCKET;\r
                        }\r
                }\r
-               SocksSockAddr.sin_port = htons((u_short)FwallPort);\r
-               SocksSockAddr.sin_family = AF_INET;\r
-               SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port));\r
+               // IPv6対応\r
+//             SocksSockAddr.sin_port = htons((u_short)FwallPort);\r
+//             SocksSockAddr.sin_family = AF_INET;\r
+//             SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port));\r
+               SocksSockAddrIPv4.sin_port = htons((u_short)FwallPort);\r
+               SocksSockAddrIPv4.sin_family = AF_INET;\r
+               SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddrIPv4.sin_addr), ntohs(SocksSockAddrIPv4.sin_port));\r
                // connectで接続する先はSOCKSサーバ\r
-               memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
+               // IPv6対応\r
+//             memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
+               memcpy(&saSockAddr, &SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4));\r
        }\r
        else\r
        {\r
                // connectで接続するのは接続先のホスト\r
-               memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
+               // IPv6対応\r
+//             memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
+               memcpy(&saSockAddr, &CurSockAddrIPv4, sizeof(CurSockAddrIPv4));\r
        }\r
 \r
        /////////////\r
@@ -1963,6 +2032,155 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
 }\r
 \r
 \r
+SOCKET connectsockIPv6(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
+{\r
+       struct sockaddr_in6 saSockAddr;\r
+       char HostEntry[MAXGETHOSTSTRUCT];\r
+       struct hostent *pHostEntry;\r
+       SOCKET sSocket;\r
+       int Len;\r
+       int Fwall;\r
+       SOCKS5REQUEST Socks5Cmd;\r
+       SOCKS5REPLY Socks5Reply;\r
+\r
+       //////////////////////////////\r
+       // ホスト名解決と接続の準備\r
+       //////////////////////////////\r
+\r
+       Fwall = FWALL_NONE;\r
+       if(AskHostFireWall() == YES)\r
+               Fwall = FwallType;\r
+\r
+       sSocket = INVALID_SOCKET;\r
+\r
+       UseIPadrs = YES;\r
+       strcpy(DomainName, host);\r
+       memset(&CurSockAddrIPv6, 0, sizeof(CurSockAddrIPv6));\r
+       CurSockAddrIPv6.sin6_port = htons((u_short)port);\r
+       CurSockAddrIPv6.sin6_family = AF_INET6;\r
+       CurSockAddrIPv6.sin6_addr = inet6_addr(host);\r
+       if(memcmp(&CurSockAddrIPv6.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
+       {\r
+               // ホスト名が指定された\r
+               // ホスト名からアドレスを求める\r
+               if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
+                  (FwallResolv == YES))\r
+               {\r
+                       // ホスト名解決はSOCKSサーバに任せる\r
+                       pHostEntry = NULL;\r
+               }\r
+               else\r
+               {\r
+                       // アドレスを取得\r
+                       SetTaskMsg(MSGJPN016, DomainName);\r
+                       pHostEntry = do_gethostbynameIPv6(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
+               }\r
+\r
+               if(pHostEntry != NULL)\r
+               {\r
+                       memcpy((char *)&CurSockAddrIPv6.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
+                       SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet6_ntoa(CurSockAddrIPv6.sin6_addr), ntohs(CurSockAddrIPv6.sin6_port));\r
+               }\r
+               else\r
+               {\r
+                       if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+                       {\r
+                               UseIPadrs = NO;\r
+                               SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddrIPv6.sin6_port));\r
+                       }\r
+                       else\r
+                       {\r
+                               SetTaskMsg(MSGJPN019, host);\r
+                               return(INVALID_SOCKET);\r
+                       }\r
+               }\r
+       }\r
+       else\r
+               SetTaskMsg(MSGJPN020, PreMsg, inet6_ntoa(CurSockAddrIPv6.sin6_addr), ntohs(CurSockAddrIPv6.sin6_port));\r
+\r
+       if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+       {\r
+               // SOCKSを使う\r
+               // SOCKSに接続する準備\r
+               {\r
+                       Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, (char*)&CurSockAddrIPv6.sin6_addr, DomainName, CurSockAddrIPv6.sin6_port);\r
+               }\r
+\r
+               memset(&SocksSockAddrIPv6, 0, sizeof(SocksSockAddrIPv6));\r
+               SocksSockAddrIPv6.sin6_addr = inet6_addr(FwallHost);\r
+               if(memcmp(&SocksSockAddrIPv6.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
+               {\r
+                       if((pHostEntry = do_gethostbynameIPv6(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
+                               memcpy((char *)&SocksSockAddrIPv6.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
+                       else\r
+                       {\r
+                               SetTaskMsg(MSGJPN021, FwallHost);\r
+                               return INVALID_SOCKET;\r
+                       }\r
+               }\r
+               SocksSockAddrIPv6.sin6_port = htons((u_short)FwallPort);\r
+               SocksSockAddrIPv6.sin6_family = AF_INET6;\r
+               SetTaskMsg(MSGJPN022, inet6_ntoa(SocksSockAddrIPv6.sin6_addr), ntohs(SocksSockAddrIPv6.sin6_port));\r
+               // connectで接続する先はSOCKSサーバ\r
+               memcpy(&saSockAddr, &SocksSockAddrIPv6, sizeof(SocksSockAddrIPv6));\r
+       }\r
+       else\r
+       {\r
+               // connectで接続するのは接続先のホスト\r
+               memcpy(&saSockAddr, &CurSockAddrIPv6, sizeof(CurSockAddrIPv6));\r
+       }\r
+\r
+       /////////////\r
+       // 接続実行\r
+       /////////////\r
+\r
+       inet6_ntoa(saSockAddr.sin6_addr);\r
+       if((sSocket = do_socket(AF_INET6, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
+       {\r
+               if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
+               {\r
+                       if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+                       {\r
+                               if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
+                               {\r
+                                       DoClose(sSocket);\r
+                                       sSocket = INVALID_SOCKET;\r
+                               }\r
+\r
+                               Socks5Reply.Result = -1;\r
+                               // 同時接続対応\r
+//                             if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+//                                (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
+//                                (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+                                  (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
+                                  (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               {\r
+                                       SetTaskMsg(MSGJPN024, Socks5Reply.Result);\r
+                                       DoClose(sSocket);\r
+                                       sSocket = INVALID_SOCKET;\r
+                               }\r
+\r
+                       }\r
+\r
+                       if(sSocket != INVALID_SOCKET)\r
+                               SetTaskMsg(MSGJPN025);\r
+               }\r
+               else\r
+               {\r
+//#pragma aaa\r
+                       SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/);\r
+                       DoClose(sSocket);\r
+                       sSocket = INVALID_SOCKET;\r
+               }\r
+       }\r
+       else\r
+               SetTaskMsg(MSGJPN027);\r
+\r
+       return(sSocket);\r
+}\r
+\r
+\r
 /*----- リッスンソケットを取得 ------------------------------------------------\r
 *\r
 *      Parameter\r
@@ -1972,8 +2190,30 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
 *              SOCKET リッスンソケット\r
 *----------------------------------------------------------------------------*/\r
 \r
+// IPv6対応\r
 SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
 {\r
+       SOCKET Result;\r
+       Result = INVALID_SOCKET;\r
+       switch(CurHost.InetFamily)\r
+       {\r
+       case AF_UNSPEC:\r
+               break;\r
+       case AF_INET:\r
+               Result = GetFTPListenSocketIPv4(ctrl_skt, CancelCheckWork);\r
+               break;\r
+       case AF_INET6:\r
+               Result = GetFTPListenSocketIPv6(ctrl_skt, CancelCheckWork);\r
+               break;\r
+       }\r
+       return Result;\r
+}\r
+\r
+\r
+// IPv6対応\r
+//SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
+SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork)\r
+{\r
     SOCKET listen_skt;\r
     int iLength;\r
     char *a,*p;\r
@@ -1997,12 +2237,17 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
                {\r
                        /*===== SOCKS4を使う =====*/\r
                        DoPrintf("Use SOCKS4 BIND");\r
-                       if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
+                       // IPv6対応\r
+//                     if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
+                       if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4), CancelCheckWork) != SOCKET_ERROR)\r
                        {\r
                                Socks4Cmd.Ver = SOCKS4_VER;\r
                                Socks4Cmd.Cmd = SOCKS4_CMD_BIND;\r
-                               Socks4Cmd.Port = CurSockAddr.sin_port;\r
-                               Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
+                               // IPv6対応\r
+//                             Socks4Cmd.Port = CurSockAddr.sin_port;\r
+//                             Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
+                               Socks4Cmd.Port = CurSockAddrIPv4.sin_port;\r
+                               Socks4Cmd.AdrsInt = CurSockAddrIPv4.sin_addr.s_addr;\r
                                strcpy(Socks4Cmd.UserID, FwallUser);\r
                                Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
 \r
@@ -2021,7 +2266,9 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
                                }\r
 \r
                                if(Socks4Reply.AdrsInt == 0)\r
-                                       Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
+                                       // IPv6対応\r
+//                                     Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
+                                       Socks4Reply.AdrsInt = SocksSockAddrIPv4.sin_addr.s_addr;\r
 \r
                                a = (char *)&Socks4Reply.AdrsInt;\r
                                p = (char *)&Socks4Reply.Port;\r
@@ -2031,7 +2278,9 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
                {\r
                        /*===== SOCKS5を使う =====*/\r
                        DoPrintf("Use SOCKS5 BIND");\r
-                       if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
+                       // IPv6対応\r
+//                     if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
+                       if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4), CancelCheckWork) != SOCKET_ERROR)\r
                        {\r
                                if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
                                {\r
@@ -2040,7 +2289,9 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
                                        return(listen_skt);\r
                                }\r
 \r
-                               Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
+                               // IPv6対応\r
+//                             Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
+                               Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddrIPv4.sin_addr.s_addr, DomainName, CurSockAddrIPv4.sin_port);\r
 \r
                                Socks5Reply.Result = -1;\r
                                // 同時接続対応\r
@@ -2056,11 +2307,15 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
                                        listen_skt = INVALID_SOCKET;\r
                                }\r
 \r
-                               if(Socks5Reply.AdrsInt == 0)\r
-                                       Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
+                               // IPv6対応\r
+//                             if(Socks5Reply.AdrsInt == 0)\r
+//                                     Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
 \r
-                               a = (char *)&Socks5Reply.AdrsInt;\r
-                               p = (char *)&Socks5Reply.Port;\r
+                               // IPv6対応\r
+//                             a = (char *)&Socks5Reply.AdrsInt;\r
+//                             p = (char *)&Socks5Reply.Port;\r
+                               a = (char *)&Socks5Reply._dummy[0];\r
+                               p = (char *)&Socks5Reply._dummy[4];\r
                        }\r
                }\r
                else\r
@@ -2136,6 +2391,140 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
 }\r
 \r
 \r
+SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork)\r
+{\r
+    SOCKET listen_skt;\r
+    int iLength;\r
+    char *a,*p;\r
+       struct sockaddr_in6 saCtrlAddr;\r
+       struct sockaddr_in6 saTmpAddr;\r
+       SOCKS5REQUEST Socks5Cmd;\r
+       SOCKS5REPLY Socks5Reply;\r
+\r
+       int Len;\r
+       int Fwall;\r
+\r
+       char Adrs[40];\r
+\r
+       Fwall = FWALL_NONE;\r
+       if(AskHostFireWall() == YES)\r
+               Fwall = FwallType;\r
+\r
+       if((listen_skt = do_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
+       {\r
+               if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+               {\r
+                       /*===== SOCKS5を使う =====*/\r
+                       DoPrintf("Use SOCKS5 BIND");\r
+                       if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv6, sizeof(SocksSockAddrIPv6), CancelCheckWork) != SOCKET_ERROR)\r
+                       {\r
+                               if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
+                               {\r
+                                       DoClose(listen_skt);\r
+                                       listen_skt = INVALID_SOCKET;\r
+                                       return(listen_skt);\r
+                               }\r
+\r
+                               Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, (char*)&CurSockAddrIPv6.sin6_addr, DomainName, CurSockAddrIPv6.sin6_port);\r
+\r
+                               Socks5Reply.Result = -1;\r
+                               // 同時接続対応\r
+//                             if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+//                                (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
+//                                (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+                                  (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
+                                  (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               {\r
+                                       SetTaskMsg(MSGJPN029, Socks5Reply.Result);\r
+                                       DoClose(listen_skt);\r
+                                       listen_skt = INVALID_SOCKET;\r
+                               }\r
+\r
+                               // IPv6対応\r
+//                             if(Socks5Reply.AdrsInt == 0)\r
+//                                     Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
+\r
+                               // IPv6対応\r
+//                             a = (char *)&Socks5Reply.AdrsInt;\r
+//                             p = (char *)&Socks5Reply.Port;\r
+                               a = (char *)&Socks5Reply._dummy[0];\r
+                               p = (char *)&Socks5Reply._dummy[16];\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       /*===== SOCKSを使わない =====*/\r
+                       DoPrintf("Use normal BIND");\r
+                       saCtrlAddr.sin6_port = htons(0);\r
+                       saCtrlAddr.sin6_family = AF_INET6;\r
+                       memset(&saCtrlAddr.sin6_addr, 0, 16);\r
+\r
+                       if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr_in6)) != SOCKET_ERROR)\r
+                       {\r
+                               iLength = sizeof(saCtrlAddr);\r
+                               if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
+                               {\r
+                                       if(do_listen(listen_skt, 1) == 0)\r
+                                       {\r
+                                               iLength = sizeof(saTmpAddr);\r
+                                               if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
+                                                       ReportWSError("getsockname", WSAGetLastError());\r
+\r
+                                               a = (char *)&saTmpAddr.sin6_addr;\r
+                                               p = (char *)&saCtrlAddr.sin6_port;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               ReportWSError("listen", WSAGetLastError());\r
+                                               do_closesocket(listen_skt);\r
+                                               listen_skt = INVALID_SOCKET;\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       ReportWSError("getsockname", WSAGetLastError());\r
+                                       do_closesocket(listen_skt);\r
+                                       listen_skt = INVALID_SOCKET;\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               ReportWSError("bind", WSAGetLastError());\r
+                               do_closesocket(listen_skt);\r
+                               listen_skt = INVALID_SOCKET;\r
+                       }\r
+\r
+                       if(listen_skt == INVALID_SOCKET)\r
+                               SetTaskMsg(MSGJPN030);\r
+               }\r
+       }\r
+       else\r
+               ReportWSError("socket create", WSAGetLastError());\r
+\r
+       if(listen_skt != INVALID_SOCKET)\r
+       {\r
+#define  US(w)  (((int)w)&0xffff)\r
+               // 同時接続対応\r
+//             if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
+//                             UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
+//                             UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
+               if((command(ctrl_skt,NULL, CancelCheckWork, "EPRT |2|%s|%d|",\r
+                               AddressToStringIPv6(Adrs, a),\r
+                               US(p[0])) / 100) != FTP_COMPLETE)\r
+               {\r
+                       SetTaskMsg(MSGJPN031);\r
+                       do_closesocket(listen_skt);\r
+                       listen_skt = INVALID_SOCKET;\r
+               }\r
+//             else\r
+//                     DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
+       }\r
+\r
+       return(listen_skt);\r
+}\r
+\r
+\r
 /*----- ホストへ接続処理中かどうかを返す---------------------------------------\r
 *\r
 *      Parameter\r
@@ -2229,6 +2618,44 @@ static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulo
 }\r
 \r
 \r
+// IPv6対応\r
+static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port)\r
+{\r
+       uchar *Pos;\r
+       int Len;\r
+       int TotalLen;\r
+\r
+       Pos = (uchar *)Packet;\r
+       Pos += SOCKS5REQUEST_SIZE;\r
+       TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
+\r
+       Packet->Ver = SOCKS5_VER;\r
+       Packet->Cmd = Cmd;\r
+       Packet->Rsv = 0;\r
+       if(ValidIP == YES)\r
+       {\r
+               /* IPアドレスを指定 */\r
+               Packet->Type = SOCKS5_ADRS_IPV6;\r
+               memcpy(Pos, IP, 16);\r
+               Pos += 16;\r
+               TotalLen += 16;\r
+       }\r
+       else\r
+       {\r
+               /* ホスト名を指定 */\r
+               Packet->Type = SOCKS5_ADRS_NAME;\r
+               Len = strlen(Host);\r
+               *Pos++ = Len;\r
+               strcpy(Pos, Host);\r
+               Pos += Len;\r
+               TotalLen += Len + 1;\r
+       }\r
+       *((ushort *)Pos) = Port;\r
+\r
+       return(TotalLen);\r
+}\r
+\r
+\r
 /*----- SOCKSのコマンドを送る -------------------------------------------------\r
 *\r
 *      Parameter\r
@@ -2281,7 +2708,7 @@ static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet, int *CancelChec
                if(Packet->Type == SOCKS5_ADRS_IPV4)\r
                        Len = 4 + 2;\r
                else if(Packet->Type == SOCKS5_ADRS_IPV6)\r
-                       Len = 6 + 2;\r
+                       Len = 16 + 2;\r
                else\r
                {\r
                        // 同時接続対応\r
@@ -2496,6 +2923,11 @@ int AskUseMLSD(void)
 }\r
 \r
 // IPv6対応\r
+int AskInetFamily(void)\r
+{\r
+       return(CurHost.InetFamily);\r
+}\r
+\r
 int AskUseIPv6(void)\r
 {\r
        return(CurHost.UseIPv6);\r
index 485e43b..3a7925f 100644 (file)
@@ -34,6 +34,19 @@ Changes in Ver.1.99
 -- MLSD command became used for retrieving filenames on appropriate hosts.\r
    That is helpful for hosts that do not return filenames properly.\r
 \r
+-- Enhanced communication routines to reduce waiting time.\r
+\r
+-- Changed to display responses from hosts after decoding as Kanji code of\r
+   filenames.\r
+\r
+-- Fixed bugs of arbitrary code execution in saving registry settings to a\r
+   file.\r
+\r
+-- Fixed bugs of launching wrong files if correct ones contain no extensions.\r
+\r
+-- Internet Protocol Version 6 became available.\r
+   IPv6 will be used when name resolution for IPv4 is unavailable.\r
+\r
 \r
 Outline\r
 -------\r
index e891cb0..762b746 100644 (file)
@@ -6,6 +6,19 @@ Changes in Ver.1.99
 -- MLSD command became used for retrieving filenames on appropriate hosts.\r
    That is helpful for hosts that do not return filenames properly.\r
 \r
+-- Enhanced communication routines to reduce waiting time.\r
+\r
+-- Changed to display responses from hosts after decoding as Kanji code of\r
+   filenames.\r
+\r
+-- Fixed bugs of arbitrary code execution in saving registry settings to a\r
+   file.\r
+\r
+-- Fixed bugs of launching wrong files if correct ones contain no extensions.\r
+\r
+-- Internet Protocol Version 6 became available.\r
+   IPv6 will be used when name resolution for IPv4 is unavailable.\r
+\r
 Changes in Ver.1.98c\r
 --------------------\r
 \r
index 99a36b2..068e714 100644 (file)
@@ -34,6 +34,21 @@ Ver 1.99
 \81@\8eæ\93¾\82·\82é\82æ\82¤\82É\82µ\82Ü\82µ\82½\81BLIST\83R\83}\83\93\83h\82Ì\89\9e\93\9a\82É\93Á\92è\82Ì\83t\83@\83C\83\8b\82ª\r
 \81@\8aÜ\82Ü\82ê\82È\82¢\88ê\95\94\82Ì\83z\83X\83g\82Å\82à\90³\82µ\82­\97ñ\8b\93\82Å\82«\82é\89Â\94\\90«\82ª\8d\82\82­\82È\82è\82Ü\82·\81B\r
 \r
+\81E\92Ê\90M\82Ì\83\8b\81[\83`\83\93\82ð\91Ò\82¿\8e\9e\8aÔ\82ª\8c¸\82é\82æ\82¤\82É\89ü\91P\82µ\82Ü\82µ\82½\81B\r
+\r
+\81E\83z\83X\83g\82Ì\89\9e\93\9a\82ð\83z\83X\83g\82Ì\83t\83@\83C\83\8b\96¼\82Ì\8a¿\8e\9a\83R\81[\83h\82Å\83f\83R\81[\83h\82µ\82Ä\82©\82ç\83\8d\83O\82É\r
+\81@\95\\8e¦\82·\82é\82æ\82¤\82É\95Ï\8dX\82µ\82Ü\82µ\82½\81B\r
+\r
+\81E\83\8c\83W\83X\83g\83\8a\82Ì\90Ý\92è\82ð\83t\83@\83C\83\8b\82É\95Û\91\82·\82é\82Æ\82«\82É\94C\88Ó\82Ì\83R\81[\83h\82ª\8eÀ\8ds\82³\82ê\82é\r
+\81@\89Â\94\\90«\82ª\82 \82é\83o\83O\82ð\8fC\90³\82µ\82Ü\82µ\82½\81B\r
+\r
+\81E\8ag\92£\8eq\82ª\96³\82¢\83t\83@\83C\83\8b\82ð\83_\83u\83\8b\83N\83\8a\83b\83N\82µ\82½\8fê\8d\87\82É\91I\91ð\82³\82ê\82½\82à\82Ì\82Æ\88Ù\82È\82é\r
+\81@\83t\83@\83C\83\8b\82ª\95\\8e¦\82³\82ê\82é\83o\83O\82ð\8fC\90³\82µ\82Ü\82µ\82½\81B\r
+\r
+\81E\83z\83X\83g\82Æ\82Ì\90Ú\91±\82ÉInternet Protocol Version 6\81i\97ª\8fÌIPv6\81j\82ª\8eg\97p\82Å\82«\82é\r
+\81@\82æ\82¤\82É\82È\82è\82Ü\82µ\82½\81B\8f]\97\88\82ÌIPv4\82Å\96¼\91O\89ð\8c\88\82ª\82Å\82«\82È\82¢\8fê\8d\87\82ÉIPv6\82Å\90Ú\91±\82ð\r
+\81@\8e\8e\82Ý\82é\82æ\82¤\82É\82µ\82Ü\82µ\82½\81B\r
+\r
 \r
 Ver 1.96d\88È\91O\82Ö\96ß\82·\8fê\8d\87\r
 -----------------------\r
index 39098bc..4bff19c 100644 (file)
@@ -6,6 +6,21 @@ FFFTP
 \81@\8eæ\93¾\82·\82é\82æ\82¤\82É\82µ\82Ü\82µ\82½\81BLIST\83R\83}\83\93\83h\82Ì\89\9e\93\9a\82É\93Á\92è\82Ì\83t\83@\83C\83\8b\82ª\r
 \81@\8aÜ\82Ü\82ê\82È\82¢\88ê\95\94\82Ì\83z\83X\83g\82Å\82à\90³\82µ\82­\97ñ\8b\93\82Å\82«\82é\89Â\94\\90«\82ª\8d\82\82­\82È\82è\82Ü\82·\81B\r
 \r
+\81E\92Ê\90M\82Ì\83\8b\81[\83`\83\93\82ð\91Ò\82¿\8e\9e\8aÔ\82ª\8c¸\82é\82æ\82¤\82É\89ü\91P\82µ\82Ü\82µ\82½\81B\r
+\r
+\81E\83z\83X\83g\82Ì\89\9e\93\9a\82ð\83z\83X\83g\82Ì\83t\83@\83C\83\8b\96¼\82Ì\8a¿\8e\9a\83R\81[\83h\82Å\83f\83R\81[\83h\82µ\82Ä\82©\82ç\83\8d\83O\82É\r
+\81@\95\\8e¦\82·\82é\82æ\82¤\82É\95Ï\8dX\82µ\82Ü\82µ\82½\81B\r
+\r
+\81E\83\8c\83W\83X\83g\83\8a\82Ì\90Ý\92è\82ð\83t\83@\83C\83\8b\82É\95Û\91\82·\82é\82Æ\82«\82É\94C\88Ó\82Ì\83R\81[\83h\82ª\8eÀ\8ds\82³\82ê\82é\r
+\81@\89Â\94\\90«\82ª\82 \82é\83o\83O\82ð\8fC\90³\82µ\82Ü\82µ\82½\81B\r
+\r
+\81E\8ag\92£\8eq\82ª\96³\82¢\83t\83@\83C\83\8b\82ð\83_\83u\83\8b\83N\83\8a\83b\83N\82µ\82½\8fê\8d\87\82É\91I\91ð\82³\82ê\82½\82à\82Ì\82Æ\88Ù\82È\82é\r
+\81@\83t\83@\83C\83\8b\82ª\95\\8e¦\82³\82ê\82é\83o\83O\82ð\8fC\90³\82µ\82Ü\82µ\82½\81B\r
+\r
+\81E\83z\83X\83g\82Æ\82Ì\90Ú\91±\82ÉInternet Protocol Version 6\81i\97ª\8fÌIPv6\81j\82ª\8eg\97p\82Å\82«\82é\r
+\81@\82æ\82¤\82É\82È\82è\82Ü\82µ\82½\81B\8f]\97\88\82ÌIPv4\82Å\96¼\91O\89ð\8c\88\82ª\82Å\82«\82È\82¢\8fê\8d\87\82ÉIPv6\82Å\90Ú\91±\82ð\r
+\81@\8e\8e\82Ý\82é\82æ\82¤\82É\82µ\82Ü\82µ\82½\81B\r
+\r
 \81¡Ver 1.98c\r
 \r
 \81E\93ú\96{\8cê\83h\83\81\83C\83\93\96¼\82Ì\83z\83X\83g\82Ö\82Ì\90Ú\91±\8e\9e\82É\83A\83h\83\8c\83X\82ðPunycode\82Ö\95Ï\8a·\82µ\82Ä\82©\82ç\r
index 48f0d63..0fce875 100644 (file)
--- a/getput.c
+++ b/getput.c
@@ -43,7 +43,7 @@
 #include <time.h>\r
 // IPv6対応\r
 //#include <winsock.h>\r
-#include <winsock2.h>\r
+#include <ws2tcpip.h>\r
 #include <windowsx.h>\r
 #include <commctrl.h>\r
 #include <process.h>\r
@@ -104,7 +104,11 @@ static int SetUploadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *M
 static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);\r
 static void DispTransferStatus(HWND hWnd, int End, TRANSPACKET *Pkt);\r
 static void DispTransFileInfo(TRANSPACKET *Pkt, char *Title, int SkipButton, int Info);\r
-static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max);\r
+// IPv6対応\r
+//static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max);\r
+static int GetAdrsAndPort(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max);\r
+static int GetAdrsAndPortIPv4(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max);\r
+static int GetAdrsAndPortIPv6(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max);\r
 static int IsSpecialDevice(char *Fname);\r
 static int MirrorDelNotify(int Cur, int Notify, TRANSPACKET *Pkt);\r
 static BOOL CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
@@ -1316,7 +1320,10 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
        SOCKET listen_socket = INVALID_SOCKET; // data listen socket\r
        char Buf[1024];\r
        int CreateMode;\r
-       struct sockaddr_in saSockAddr1;\r
+       // IPv6対応\r
+//     struct sockaddr_in saSockAddr1;\r
+       struct sockaddr_in saSockAddrIPv4;\r
+       struct sockaddr_in6 saSockAddrIPv6;\r
        char Reply[ERR_MSG_LEN+7];\r
 \r
        if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, CancelCheckWork)) != INVALID_SOCKET)\r
@@ -1331,8 +1338,20 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
 //                             if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL)\r
                                if(SocksGet2ndBindReply(listen_socket, &data_socket, CancelCheckWork) == FFFTP_FAIL)\r
                                {\r
-                                       iLength = sizeof(saSockAddr1);\r
-                                       data_socket = do_accept(listen_socket, (struct sockaddr *)&saSockAddr1, (int *)&iLength);\r
+                                       // IPv6対応\r
+//                                     iLength = sizeof(saSockAddr1);\r
+//                                     data_socket = do_accept(listen_socket, (struct sockaddr *)&saSockAddr1, (int *)&iLength);\r
+                                       switch(AskInetFamily())\r
+                                       {\r
+                                       case AF_INET:\r
+                                               iLength=sizeof(saSockAddrIPv4);\r
+                                               data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv4, (int *)&iLength);\r
+                                               break;\r
+                                       case AF_INET6:\r
+                                               iLength=sizeof(saSockAddrIPv6);\r
+                                               data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv6, (int *)&iLength);\r
+                                               break;\r
+                                       }\r
 \r
                                        if(shutdown(listen_socket, 1) != 0)\r
                                                ReportWSError("shutdown listen", WSAGetLastError());\r
@@ -1345,7 +1364,19 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
                                                iRetCode = 500;\r
                                        }\r
                                        else\r
-                                               DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port));\r
+                                               // IPv6対応\r
+//                                             DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port));\r
+                                       {\r
+                                               switch(AskInetFamily())\r
+                                               {\r
+                                               case AF_INET:\r
+                                                       DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddrIPv4.sin_addr), ntohs(saSockAddrIPv4.sin_port));\r
+                                                       break;\r
+                                               case AF_INET6:\r
+                                                       DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet6_ntoa(saSockAddrIPv6.sin6_addr), ntohs(saSockAddrIPv6.sin6_port));\r
+                                                       break;\r
+                                               }\r
+                                       }\r
                                }\r
 \r
                                if(data_socket != INVALID_SOCKET)\r
@@ -1403,15 +1434,29 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
        SOCKET data_socket = INVALID_SOCKET;   // data channel socket\r
        char Buf[1024];\r
        int CreateMode;\r
-       char Adrs[20];\r
+       // IPv6対応\r
+//     char Adrs[20];\r
+       char Adrs[40];\r
        int Port;\r
        int Flg;\r
        char Reply[ERR_MSG_LEN+7];\r
 \r
-       iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "PASV");\r
+       // IPv6対応\r
+//     iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "PASV");\r
+       switch(AskInetFamily())\r
+       {\r
+       case AF_INET:\r
+               iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "PASV");\r
+               break;\r
+       case AF_INET6:\r
+               iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "EPSV");\r
+               break;\r
+       }\r
        if(iRetCode/100 == FTP_COMPLETE)\r
        {\r
-               if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS)\r
+               // IPv6対応\r
+//             if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS)\r
+               if(GetAdrsAndPort(Pkt->ctrl_skt, Buf, Adrs, &Port, 39) == FFFTP_SUCCESS)\r
                {\r
                        if((data_socket = connectsock(Adrs, Port, MSGJPN091, CancelCheckWork)) != INVALID_SOCKET)\r
                        {\r
@@ -2475,7 +2520,10 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt)
        SOCKET data_socket = INVALID_SOCKET;   // data channel socket\r
        SOCKET listen_socket = INVALID_SOCKET; // data listen socket\r
        char Buf[1024];\r
-       struct sockaddr_in saSockAddr1;\r
+       // IPv6対応\r
+//     struct sockaddr_in saSockAddr1;\r
+       struct sockaddr_in saSockAddrIPv4;\r
+       struct sockaddr_in6 saSockAddrIPv6;\r
        int Resume;\r
        char Reply[ERR_MSG_LEN+7];\r
 \r
@@ -2498,8 +2546,20 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt)
 //                     if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL)\r
                        if(SocksGet2ndBindReply(listen_socket, &data_socket, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL)\r
                        {\r
-                               iLength=sizeof(saSockAddr1);\r
-                               data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddr1, (int *)&iLength);\r
+                               // IPv6対応\r
+//                             iLength=sizeof(saSockAddr1);\r
+//                             data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddr1, (int *)&iLength);\r
+                               switch(AskInetFamily())\r
+                               {\r
+                               case AF_INET:\r
+                                       iLength=sizeof(saSockAddrIPv4);\r
+                                       data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv4, (int *)&iLength);\r
+                                       break;\r
+                               case AF_INET6:\r
+                                       iLength=sizeof(saSockAddrIPv6);\r
+                                       data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv6, (int *)&iLength);\r
+                                       break;\r
+                               }\r
 \r
                                if(shutdown(listen_socket, 1) != 0)\r
                                        ReportWSError("shutdown listen", WSAGetLastError());\r
@@ -2512,7 +2572,19 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt)
                                        iRetCode = 500;\r
                                }\r
                                else\r
-                                       DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port));\r
+                                       // IPv6対応\r
+//                                     DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port));\r
+                               {\r
+                                       switch(AskInetFamily())\r
+                                       {\r
+                                       case AF_INET:\r
+                                               DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddrIPv4.sin_addr), ntohs(saSockAddrIPv4.sin_port));\r
+                                               break;\r
+                                       case AF_INET6:\r
+                                               DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet6_ntoa(saSockAddrIPv6.sin6_addr), ntohs(saSockAddrIPv6.sin6_port));\r
+                                               break;\r
+                                       }\r
+                               }\r
                        }\r
 \r
                        if(data_socket != INVALID_SOCKET)\r
@@ -2566,7 +2638,9 @@ static int UpLoadPassive(TRANSPACKET *Pkt)
        int iRetCode;\r
        SOCKET data_socket = INVALID_SOCKET;   // data channel socket\r
        char Buf[1024];\r
-       char Adrs[20];\r
+       // IPv6対応\r
+//     char Adrs[20];\r
+       char Adrs[40];\r
        int Port;\r
        int Flg;\r
        int Resume;\r
@@ -2574,10 +2648,22 @@ static int UpLoadPassive(TRANSPACKET *Pkt)
 \r
        // 同時接続対応\r
 //     iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled, "PASV");\r
-       iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV");\r
+       // IPv6対応\r
+//     iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV");\r
+       switch(AskInetFamily())\r
+       {\r
+       case AF_INET:\r
+               iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV");\r
+               break;\r
+       case AF_INET6:\r
+               iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "EPSV");\r
+               break;\r
+       }\r
        if(iRetCode/100 == FTP_COMPLETE)\r
        {\r
-               if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS)\r
+               // IPv6対応\r
+//             if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS)\r
+               if(GetAdrsAndPort(Pkt->ctrl_skt, Buf, Adrs, &Port, 39) == FFFTP_SUCCESS)\r
                {\r
                        // 同時接続対応\r
 //                     if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled)) != INVALID_SOCKET)\r
@@ -3675,7 +3761,26 @@ static void DispTransFileInfo(TRANSPACKET *Pkt, char *Title, int SkipButton, int
 *                      FFFTP_SUCCESS/FFFTP_FAIL\r
 *----------------------------------------------------------------------------*/\r
 \r
-static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max)\r
+static int GetAdrsAndPort(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max)\r
+{\r
+       int Result;\r
+       Result = FFFTP_FAIL;\r
+       switch(AskInetFamily())\r
+       {\r
+       case AF_INET:\r
+               Result = GetAdrsAndPortIPv4(Skt, Str, Adrs, Port, Max);\r
+               break;\r
+       case AF_INET6:\r
+               Result = GetAdrsAndPortIPv6(Skt, Str, Adrs, Port, Max);\r
+               break;\r
+       }\r
+       return Result;\r
+}\r
+\r
+\r
+// IPv6対応\r
+//static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max)\r
+static int GetAdrsAndPortIPv4(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max)\r
 {\r
        char *Pos;\r
        char *Btm;\r
@@ -3742,49 +3847,55 @@ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max)
 \r
 \r
 // IPv6対応\r
-static int GetAdrsAndPortIPv6(char *Str, char *Adrs, int *Port, int Max, short *Family)\r
+static int GetAdrsAndPortIPv6(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max)\r
 {\r
        char *Pos;\r
        char *Btm;\r
        int Sts;\r
+       int i;\r
+       struct sockaddr_in6 SockAddr;\r
 \r
        Sts = FFFTP_FAIL;\r
 \r
-       Pos = strchr(Str, '|');\r
-       if(Pos != NULL)\r
+       Btm = strchr(Str, '(');\r
+       if(Btm != NULL)\r
        {\r
-               Pos++;\r
-               Btm = strchr(Pos, '|');\r
+               Btm++;\r
+               Btm = strchr(Btm, '|');\r
                if(Btm != NULL)\r
                {\r
-                       switch(atoi(Pos))\r
-                       {\r
-                       case 1:\r
-                               *Family = AF_INET;\r
-                               break;\r
-                       case 2:\r
-                               *Family = AF_INET6;\r
-                               break;\r
-                       }\r
                        Pos = Btm + 1;\r
                        Btm = strchr(Pos, '|');\r
                        if(Btm != NULL)\r
                        {\r
-                               if((Btm - Pos) <= Max)\r
+                               Pos = Btm + 1;\r
+                               Btm = strchr(Pos, '|');\r
+                               if(Btm != NULL)\r
                                {\r
-                                       if((Btm - Pos) > 0)\r
+                                       if((Btm - Pos) <= Max)\r
                                        {\r
-                                               strncpy(Adrs, Pos, Btm - Pos);\r
-                                               *(Adrs + (Btm - Pos)) = NUL;\r
-                                       }\r
+                                               if((Btm - Pos) > 0)\r
+                                               {\r
+                                                       strncpy(Adrs, Pos, Btm - Pos);\r
+                                                       *(Adrs + (Btm - Pos)) = NUL;\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       i = sizeof(SockAddr);\r
+                                                       if(getpeername(Skt, (struct sockaddr*)&SockAddr, &i) != SOCKET_ERROR)\r
+                                                               AddressToStringIPv6(Adrs, &SockAddr.sin6_addr);\r
+                                               }\r
 \r
-                                       Pos = Btm + 1;\r
-                                       Btm = strchr(Pos, '|');\r
-                                       if(Btm != NULL)\r
-                                       {\r
-                                               Btm++;\r
-                                               *Port = atoi(Pos);\r
-                                               Sts = FFFTP_SUCCESS;\r
+                                               Pos = Btm + 1;\r
+                                               Btm = strchr(Pos, '|');\r
+                                               if(Btm != NULL)\r
+                                               {\r
+                                                       Btm++;\r
+                                                       *Port = atoi(Pos);\r
+                                                       Btm = strchr(Btm, ')');\r
+                                                       if(Btm != NULL)\r
+                                                               Sts = FFFTP_SUCCESS;\r
+                                               }\r
                                        }\r
                                }\r
                        }\r
index d648a30..9896688 100644 (file)
--- a/hostman.c
+++ b/hostman.c
@@ -1328,6 +1328,7 @@ void CopyDefaultHost(HOSTDATA *Set)
        Set->Feature = 0;\r
        Set->UseMLSD = YES;\r
        // IPv6対応\r
+       Set->InetFamily = AF_UNSPEC;\r
        Set->UseIPv6 = YES;\r
        return;\r
 }\r
diff --git a/local.c b/local.c
index dfc0435..299ed0f 100644 (file)
--- a/local.c
+++ b/local.c
@@ -182,7 +182,8 @@ void DispFileProperty(char *Fname)
 {\r
        SHELLEXECUTEINFO sInfo;\r
        // 異なるファイルが表示されるバグ修正\r
-       // 詳細は不明だが末尾に半角スペースを置くと拡張子の補完がされなくなる\r
+       // UNCでない場合に末尾に半角スペースを置くと拡張子の補完がされなくなる\r
+       // 現在UNC対応の予定は無い\r
        char Fname2[FMAX_PATH+1];\r
 \r
        memset(&sInfo, NUL, sizeof(SHELLEXECUTEINFO));\r
index e85ce74..368745a 100644 (file)
@@ -2351,7 +2351,6 @@ static int ReadStringFromReg(void *Handle, char *Name, char *Str, DWORD Size)
                                Sts = FFFTP_SUCCESS;\r
                                if(!CheckStringM(Str))\r
                                        break;\r
-                               Str = Str;\r
                                // UTF-8ではない可能性がある\r
                                // Shift_JISとみなす\r
                        case KANJI_SJIS:\r
index f999f77..419d9c4 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -651,7 +651,53 @@ static int UnRegistAsyncTableDbase(HANDLE Async)
 \r
 \r
 \r
-struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
+// IPv6対応\r
+//struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
+struct hostent *do_gethostbynameIPv4(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
+{\r
+#if USE_THIS\r
+       struct hostent *Ret;\r
+       HANDLE hAsync;\r
+       int Error;\r
+\r
+#if DBG_MSG\r
+       DoPrintf("# Start gethostbyname");\r
+#endif\r
+       Ret = NULL;\r
+       // 同時接続対応\r
+//     *CancelCheckWork = NO;\r
+\r
+       // UTF-8対応\r
+//     hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
+       hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
+       if(hAsync != NULL)\r
+       {\r
+               RegistAsyncTableDbase(hAsync);\r
+               while((*CancelCheckWork == NO) && (AskAsyncDoneDbase(hAsync, &Error) != YES))\r
+               {\r
+                       Sleep(1);\r
+                       if(BackgrndMessageProc() == YES)\r
+                               *CancelCheckWork = YES;\r
+               }\r
+\r
+               if(*CancelCheckWork == YES)\r
+               {\r
+                       WSACancelAsyncRequest(hAsync);\r
+               }\r
+               else if(Error == 0)\r
+               {\r
+                       Ret = (struct hostent *)Buf;\r
+               }\r
+               UnRegistAsyncTableDbase(hAsync);\r
+       }\r
+       return(Ret);\r
+#else\r
+       return(gethostbyname(Name));\r
+#endif\r
+}\r
+\r
+\r
+struct hostent *do_gethostbynameIPv6(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
 {\r
 #if USE_THIS\r
        struct hostent *Ret;\r
@@ -667,9 +713,7 @@ struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *Canc
 \r
        // UTF-8対応\r
 //     hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
-       // IPv6対応\r
-//     hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
-       hAsync = WSAAsyncGetHostByNameIPv6M(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len, AF_INET);\r
+       hAsync = WSAAsyncGetHostByNameIPv6M(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len, AF_INET6);\r
        if(hAsync != NULL)\r
        {\r
                RegistAsyncTableDbase(hAsync);\r
@@ -1319,6 +1363,113 @@ int WSACancelAsyncRequestIPv6(HANDLE hAsyncTaskHandle)
        return Result;\r
 }\r
 \r
+char* AddressToStringIPv6(char* str, void* in6)\r
+{\r
+       char* pResult;\r
+       unsigned char* p;\r
+       int MaxZero;\r
+       int MaxZeroLen;\r
+       int i;\r
+       int j;\r
+       char Tmp[5];\r
+       pResult = str;\r
+       p = (unsigned char*)in6;\r
+       MaxZero = 8;\r
+       MaxZeroLen = 1;\r
+       for(i = 0; i < 8; i++)\r
+       {\r
+               for(j = i; j < 8; j++)\r
+               {\r
+                       if(p[j * 2] != 0 || p[j * 2 + 1] != 0)\r
+                               break;\r
+               }\r
+               if(j - i > MaxZeroLen)\r
+               {\r
+                       MaxZero = i;\r
+                       MaxZeroLen = j - i;\r
+               }\r
+       }\r
+       strcpy(str, "");\r
+       for(i = 0; i < 8; i++)\r
+       {\r
+               if(i == MaxZero)\r
+               {\r
+                       if(i == 0)\r
+                               strcat(str, ":");\r
+                       strcat(str, ":");\r
+               }\r
+               else if(i < MaxZero || i >= MaxZero + MaxZeroLen)\r
+               {\r
+                       sprintf(Tmp, "%x", (((int)p[i * 2] & 0xff) << 8) | ((int)p[i * 2 + 1] & 0xff));\r
+                       strcat(str, Tmp);\r
+                       if(i < 7)\r
+                               strcat(str, ":");\r
+               }\r
+       }\r
+       return pResult;\r
+}\r
+\r
+// IPv6対応のinet_ntoa相当の関数\r
+// ただしANSI用\r
+char* inet6_ntoa(struct in6_addr in6)\r
+{\r
+       char* pResult;\r
+       static char Adrs[40];\r
+       pResult = NULL;\r
+       memset(Adrs, 0, sizeof(Adrs));\r
+       pResult = AddressToStringIPv6(Adrs, &in6);\r
+       return pResult;\r
+}\r
+\r
+// IPv6対応のinet_addr相当の関数\r
+// ただしANSI用\r
+struct in6_addr inet6_addr(const char* cp)\r
+{\r
+       struct in6_addr Result;\r
+       int AfterZero;\r
+       int i;\r
+       char* p;\r
+       memset(&Result, 0, sizeof(Result));\r
+       AfterZero = 0;\r
+       for(i = 0; i < 8; i++)\r
+       {\r
+               if(!cp)\r
+               {\r
+                       memset(&Result, 0xff, sizeof(Result));\r
+                       break;\r
+               }\r
+               if(i >= AfterZero)\r
+               {\r
+                       if(strncmp(cp, ":", 1) == 0)\r
+                       {\r
+                               cp = cp + 1;\r
+                               if(i == 0 && strncmp(cp, ":", 1) == 0)\r
+                                       cp = cp + 1;\r
+                               p = (char*)cp;\r
+                               AfterZero = 7;\r
+                               while(p = strstr(p, ":"))\r
+                               {\r
+                                       p = p + 1;\r
+                                       AfterZero--;\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               Result.u.Word[i] = (USHORT)strtol(cp, &p, 16);\r
+                               Result.u.Word[i] = ((Result.u.Word[i] & 0xff00) >> 8) | ((Result.u.Word[i] & 0x00ff) << 8);\r
+                               if(strncmp(p, ":", 1) != 0 && strlen(p) > 0)\r
+                               {\r
+                                       memset(&Result, 0xff, sizeof(Result));\r
+                                       break;\r
+                               }\r
+                               if(cp = strstr(cp, ":"))\r
+                                       cp = cp + 1;\r
+                       }\r
+               }\r
+       }\r
+       return Result;\r
+}\r
+\r
 // UTF-8対応\r
 \r
 static BOOL ConvertStringToPunycode(LPSTR Output, DWORD Count, LPCSTR Input)\r