• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

FFFTPのソースコードです。


Commit MetaInfo

Revisão79dd2b343ce394098b2f0f9d89e53bd8c28b7401 (tree)
Hora2011-11-12 17:41:28
Autors_kawamoto <s_kawamoto@user...>
Commiters_kawamoto

Mensagem de Log

Add support for IPv6 (not tested).

Mudança Sumário

Diff

Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
--- a/common.h
+++ b/common.h
@@ -952,6 +952,7 @@ typedef struct {
952952 // MLSD対応
953953 int UseMLSD; /* "MLSD"コマンドを使用する */
954954 // IPv6対応
955+ int InetFamily; /* IPv6接続かどうか (AF_INET/AF_INET6) */
955956 int UseIPv6; /* IPv6接続を許可しEPRT/EPSVコマンドを使用する */
956957 } HOSTDATA;
957958
@@ -1181,9 +1182,11 @@ typedef struct {
11811182 char Rsv; /* (予約) */
11821183 char Type; /* アドレスのタイプ */
11831184 /* 以後(可変長部分) */
1184- ulong AdrsInt; /* アドレス */
1185- ushort Port; /* ポート */
1186- char _dummy[2]; /* dummy */
1185+ // IPv6対応
1186+// ulong AdrsInt; /* アドレス */
1187+// ushort Port; /* ポート */
1188+// char _dummy[2]; /* dummy */
1189+ char _dummy[255+1+2]; /* dummy */
11871190 } SOCKS5REPLY;
11881191
11891192 #define SOCKS5REPLY_SIZE 4 /* 最初の固定部分のサイズ */
@@ -1416,7 +1419,13 @@ void DisconnectProc(void);
14161419 void DisconnectSet(void);
14171420 int AskConnecting(void);
14181421 SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork);
1422+// IPv6対応
1423+SOCKET connectsockIPv4(char *host, int port, char *PreMsg, int *CancelCheckWork);
1424+SOCKET connectsockIPv6(char *host, int port, char *PreMsg, int *CancelCheckWork);
14191425 SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork);
1426+// IPv6対応
1427+SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork);
1428+SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork);
14201429 int AskTryingConnect(void);
14211430 // 同時接続対応
14221431 //int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data);
@@ -1436,6 +1445,7 @@ int AskHostFeature(void);
14361445 // MLSD対応
14371446 int AskUseMLSD(void);
14381447 // IPv6対応
1448+int AskInetFamily(void);
14391449 int AskUseIPv6(void);
14401450
14411451 /*===== cache.c =====*/
@@ -1724,7 +1734,10 @@ char *AskLocalFreeSpace(char *Path);
17241734
17251735 int MakeSocketWin(HWND hWnd, HINSTANCE hInst);
17261736 void DeleteSocketWin(void);
1727-struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork);
1737+// IPv6対応
1738+//struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork);
1739+struct hostent *do_gethostbynameIPv4(const char *Name, char *Buf, int Len, int *CancelCheckWork);
1740+struct hostent *do_gethostbynameIPv6(const char *Name, char *Buf, int Len, int *CancelCheckWork);
17281741 SOCKET do_socket(int af, int type, int protocol);
17291742 int do_connect(SOCKET s, const struct sockaddr *name, int namelen, int *CancelCheckWork);
17301743 int do_closesocket(SOCKET s);
@@ -1736,6 +1749,10 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int
17361749 void RemoveReceivedData(SOCKET s);
17371750 int CheckClosedAndReconnect(void);
17381751 void CheckAllEventClosed(void);
1752+// IPv6対応
1753+char* AddressToStringIPv6(char* str, void* in6);
1754+char* inet6_ntoa(struct in6_addr in6);
1755+struct in6_addr inet6_addr(const char* cp);
17391756
17401757 /*===== updatebell.c =====*/
17411758
--- a/connect.c
+++ b/connect.c
@@ -35,7 +35,9 @@
3535 #include <string.h>
3636 #include <mbstring.h>
3737 #include <time.h>
38-#include <winsock.h>
38+// IPv6対応
39+//#include <winsock.h>
40+#include <ws2tcpip.h>
3941 #include <windowsx.h>
4042 #include <commctrl.h>
4143
@@ -65,6 +67,8 @@ static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass,
6567 static int CheckOneTimePassword(char *Pass, char *Reply, int Type);
6668 static BOOL CALLBACK BlkHookFnc(void);
6769 static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulong IP, char *Host, ushort Port);
70+// IPv6対応
71+static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port);
6872 static int SocksSendCmd(SOCKET Socket, void *Data, int Size, int *CancelCheckWork);
6973 // 同時接続対応
7074 //static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet);
@@ -107,8 +111,14 @@ static int TmpNameKanjiCode;
107111
108112 /* 接続中の接続先、SOCKSサーバのアドレス情報を保存しておく */
109113 /* この情報はlistenソケットを取得する際に用いる */
110-static struct sockaddr_in SocksSockAddr; /* SOCKSサーバのアドレス情報 */
111-static struct sockaddr_in CurSockAddr; /* 接続先ホストのアドレス情報 */
114+// IPv6対応
115+//static struct sockaddr_in SocksSockAddr; /* SOCKSサーバのアドレス情報 */
116+//static struct sockaddr_in CurSockAddr; /* 接続先ホストのアドレス情報 */
117+static struct sockaddr_in SocksSockAddrIPv4; /* SOCKSサーバのアドレス情報 */
118+static struct sockaddr_in CurSockAddrIPv4; /* 接続先ホストのアドレス情報 */
119+static struct sockaddr_in6 SocksSockAddrIPv6; /* SOCKSサーバのアドレス情報 */
120+static struct sockaddr_in6 CurSockAddrIPv6; /* 接続先ホストのアドレス情報 */
121+static const struct in6_addr IN6ADDR_NONE = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
112122
113123 static int UseIPadrs;
114124 static char DomainName[HOST_ADRS_LEN+1];
@@ -1789,8 +1799,34 @@ static int CheckOneTimePassword(char *Pass, char *Reply, int Type)
17891799 * SOCKET ソケット
17901800 *----------------------------------------------------------------------------*/
17911801
1802+// IPv6対応
17921803 SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
17931804 {
1805+ SOCKET Result;
1806+ Result = INVALID_SOCKET;
1807+ switch(CurHost.InetFamily)
1808+ {
1809+ case AF_UNSPEC:
1810+ if((Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)
1811+ CurHost.InetFamily = AF_INET;
1812+ else if(CurHost.UseIPv6 == YES && (Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)
1813+ CurHost.InetFamily = AF_INET6;
1814+ break;
1815+ case AF_INET:
1816+ Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork);
1817+ break;
1818+ case AF_INET6:
1819+ Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork);
1820+ break;
1821+ }
1822+ return Result;
1823+}
1824+
1825+
1826+// IPv6対応
1827+//SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
1828+SOCKET connectsockIPv4(char *host, int port, char *PreMsg, int *CancelCheckWork)
1829+{
17941830 struct sockaddr_in saSockAddr;
17951831 char HostEntry[MAXGETHOSTSTRUCT];
17961832 struct hostent *pHostEntry;
@@ -1814,10 +1850,15 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
18141850
18151851 UseIPadrs = YES;
18161852 strcpy(DomainName, host);
1817- memset(&CurSockAddr, 0, sizeof(CurSockAddr));
1818- CurSockAddr.sin_port = htons((u_short)port);
1819- CurSockAddr.sin_family = AF_INET;
1820- if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)
1853+ // IPv6対応
1854+// memset(&CurSockAddr, 0, sizeof(CurSockAddr));
1855+// CurSockAddr.sin_port = htons((u_short)port);
1856+// CurSockAddr.sin_family = AF_INET;
1857+// if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)
1858+ memset(&CurSockAddrIPv4, 0, sizeof(CurSockAddrIPv4));
1859+ CurSockAddrIPv4.sin_port = htons((u_short)port);
1860+ CurSockAddrIPv4.sin_family = AF_INET;
1861+ if((CurSockAddrIPv4.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)
18211862 {
18221863 // ホスト名が指定された
18231864 // ホスト名からアドレスを求める
@@ -1831,20 +1872,27 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
18311872 {
18321873 // アドレスを取得
18331874 SetTaskMsg(MSGJPN016, DomainName);
1834- pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);
1875+ // IPv6対応
1876+// pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);
1877+ pHostEntry = do_gethostbynameIPv4(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);
18351878 }
18361879
18371880 if(pHostEntry != NULL)
18381881 {
1839- memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);
1840- SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));
1882+ // IPv6対応
1883+// memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);
1884+// SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));
1885+ memcpy((char *)&CurSockAddrIPv4.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);
1886+ SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddrIPv4.sin_addr), ntohs(CurSockAddrIPv4.sin_port));
18411887 }
18421888 else
18431889 {
18441890 if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))
18451891 {
18461892 UseIPadrs = NO;
1847- SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port));
1893+ // IPv6対応
1894+// SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port));
1895+ SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddrIPv4.sin_port));
18481896 }
18491897 else
18501898 {
@@ -1854,7 +1902,9 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
18541902 }
18551903 }
18561904 else
1857- SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));
1905+ // IPv6対応
1906+// SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));
1907+ SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddrIPv4.sin_addr), ntohs(CurSockAddrIPv4.sin_port));
18581908
18591909 if((Fwall == FWALL_SOCKS4) || (Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))
18601910 {
@@ -1864,37 +1914,56 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
18641914 {
18651915 Socks4Cmd.Ver = SOCKS4_VER;
18661916 Socks4Cmd.Cmd = SOCKS4_CMD_CONNECT;
1867- Socks4Cmd.Port = CurSockAddr.sin_port;
1868- Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;
1917+ // IPv6対応
1918+// Socks4Cmd.Port = CurSockAddr.sin_port;
1919+// Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;
1920+ Socks4Cmd.Port = CurSockAddrIPv4.sin_port;
1921+ Socks4Cmd.AdrsInt = CurSockAddrIPv4.sin_addr.s_addr;
18691922 strcpy(Socks4Cmd.UserID, FwallUser);
18701923 Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;
18711924 }
18721925 else
18731926 {
1874- Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);
1927+ // IPv6対応
1928+// Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);
1929+ Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddrIPv4.sin_addr.s_addr, DomainName, CurSockAddrIPv4.sin_port);
18751930 }
18761931
1877- memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));
1878- if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)
1932+ // IPv6対応
1933+// memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));
1934+// if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)
1935+ memset(&SocksSockAddrIPv4, 0, sizeof(SocksSockAddrIPv4));
1936+ if((SocksSockAddrIPv4.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)
18791937 {
1880- if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)
1881- memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);
1938+ // IPv6対応
1939+// if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)
1940+// memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);
1941+ if((pHostEntry = do_gethostbynameIPv4(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)
1942+ memcpy((char *)&SocksSockAddrIPv4.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);
18821943 else
18831944 {
18841945 SetTaskMsg(MSGJPN021, FwallHost);
18851946 return INVALID_SOCKET;
18861947 }
18871948 }
1888- SocksSockAddr.sin_port = htons((u_short)FwallPort);
1889- SocksSockAddr.sin_family = AF_INET;
1890- SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port));
1949+ // IPv6対応
1950+// SocksSockAddr.sin_port = htons((u_short)FwallPort);
1951+// SocksSockAddr.sin_family = AF_INET;
1952+// SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port));
1953+ SocksSockAddrIPv4.sin_port = htons((u_short)FwallPort);
1954+ SocksSockAddrIPv4.sin_family = AF_INET;
1955+ SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddrIPv4.sin_addr), ntohs(SocksSockAddrIPv4.sin_port));
18911956 // connectで接続する先はSOCKSサーバ
1892- memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));
1957+ // IPv6対応
1958+// memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));
1959+ memcpy(&saSockAddr, &SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4));
18931960 }
18941961 else
18951962 {
18961963 // connectで接続するのは接続先のホスト
1897- memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));
1964+ // IPv6対応
1965+// memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));
1966+ memcpy(&saSockAddr, &CurSockAddrIPv4, sizeof(CurSockAddrIPv4));
18981967 }
18991968
19001969 /////////////
@@ -1963,6 +2032,155 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
19632032 }
19642033
19652034
2035+SOCKET connectsockIPv6(char *host, int port, char *PreMsg, int *CancelCheckWork)
2036+{
2037+ struct sockaddr_in6 saSockAddr;
2038+ char HostEntry[MAXGETHOSTSTRUCT];
2039+ struct hostent *pHostEntry;
2040+ SOCKET sSocket;
2041+ int Len;
2042+ int Fwall;
2043+ SOCKS5REQUEST Socks5Cmd;
2044+ SOCKS5REPLY Socks5Reply;
2045+
2046+ //////////////////////////////
2047+ // ホスト名解決と接続の準備
2048+ //////////////////////////////
2049+
2050+ Fwall = FWALL_NONE;
2051+ if(AskHostFireWall() == YES)
2052+ Fwall = FwallType;
2053+
2054+ sSocket = INVALID_SOCKET;
2055+
2056+ UseIPadrs = YES;
2057+ strcpy(DomainName, host);
2058+ memset(&CurSockAddrIPv6, 0, sizeof(CurSockAddrIPv6));
2059+ CurSockAddrIPv6.sin6_port = htons((u_short)port);
2060+ CurSockAddrIPv6.sin6_family = AF_INET6;
2061+ CurSockAddrIPv6.sin6_addr = inet6_addr(host);
2062+ if(memcmp(&CurSockAddrIPv6.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)
2063+ {
2064+ // ホスト名が指定された
2065+ // ホスト名からアドレスを求める
2066+ if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&
2067+ (FwallResolv == YES))
2068+ {
2069+ // ホスト名解決はSOCKSサーバに任せる
2070+ pHostEntry = NULL;
2071+ }
2072+ else
2073+ {
2074+ // アドレスを取得
2075+ SetTaskMsg(MSGJPN016, DomainName);
2076+ pHostEntry = do_gethostbynameIPv6(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);
2077+ }
2078+
2079+ if(pHostEntry != NULL)
2080+ {
2081+ memcpy((char *)&CurSockAddrIPv6.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);
2082+ SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet6_ntoa(CurSockAddrIPv6.sin6_addr), ntohs(CurSockAddrIPv6.sin6_port));
2083+ }
2084+ else
2085+ {
2086+ if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))
2087+ {
2088+ UseIPadrs = NO;
2089+ SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddrIPv6.sin6_port));
2090+ }
2091+ else
2092+ {
2093+ SetTaskMsg(MSGJPN019, host);
2094+ return(INVALID_SOCKET);
2095+ }
2096+ }
2097+ }
2098+ else
2099+ SetTaskMsg(MSGJPN020, PreMsg, inet6_ntoa(CurSockAddrIPv6.sin6_addr), ntohs(CurSockAddrIPv6.sin6_port));
2100+
2101+ if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))
2102+ {
2103+ // SOCKSを使う
2104+ // SOCKSに接続する準備
2105+ {
2106+ Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, (char*)&CurSockAddrIPv6.sin6_addr, DomainName, CurSockAddrIPv6.sin6_port);
2107+ }
2108+
2109+ memset(&SocksSockAddrIPv6, 0, sizeof(SocksSockAddrIPv6));
2110+ SocksSockAddrIPv6.sin6_addr = inet6_addr(FwallHost);
2111+ if(memcmp(&SocksSockAddrIPv6.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)
2112+ {
2113+ if((pHostEntry = do_gethostbynameIPv6(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)
2114+ memcpy((char *)&SocksSockAddrIPv6.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);
2115+ else
2116+ {
2117+ SetTaskMsg(MSGJPN021, FwallHost);
2118+ return INVALID_SOCKET;
2119+ }
2120+ }
2121+ SocksSockAddrIPv6.sin6_port = htons((u_short)FwallPort);
2122+ SocksSockAddrIPv6.sin6_family = AF_INET6;
2123+ SetTaskMsg(MSGJPN022, inet6_ntoa(SocksSockAddrIPv6.sin6_addr), ntohs(SocksSockAddrIPv6.sin6_port));
2124+ // connectで接続する先はSOCKSサーバ
2125+ memcpy(&saSockAddr, &SocksSockAddrIPv6, sizeof(SocksSockAddrIPv6));
2126+ }
2127+ else
2128+ {
2129+ // connectで接続するのは接続先のホスト
2130+ memcpy(&saSockAddr, &CurSockAddrIPv6, sizeof(CurSockAddrIPv6));
2131+ }
2132+
2133+ /////////////
2134+ // 接続実行
2135+ /////////////
2136+
2137+ inet6_ntoa(saSockAddr.sin6_addr);
2138+ if((sSocket = do_socket(AF_INET6, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)
2139+ {
2140+ if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)
2141+ {
2142+ if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))
2143+ {
2144+ if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)
2145+ {
2146+ DoClose(sSocket);
2147+ sSocket = INVALID_SOCKET;
2148+ }
2149+
2150+ Socks5Reply.Result = -1;
2151+ // 同時接続対応
2152+// if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||
2153+// (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) ||
2154+// (Socks5Reply.Result != SOCKS5_RES_OK))
2155+ if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||
2156+ (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) ||
2157+ (Socks5Reply.Result != SOCKS5_RES_OK))
2158+ {
2159+ SetTaskMsg(MSGJPN024, Socks5Reply.Result);
2160+ DoClose(sSocket);
2161+ sSocket = INVALID_SOCKET;
2162+ }
2163+
2164+ }
2165+
2166+ if(sSocket != INVALID_SOCKET)
2167+ SetTaskMsg(MSGJPN025);
2168+ }
2169+ else
2170+ {
2171+//#pragma aaa
2172+ SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/);
2173+ DoClose(sSocket);
2174+ sSocket = INVALID_SOCKET;
2175+ }
2176+ }
2177+ else
2178+ SetTaskMsg(MSGJPN027);
2179+
2180+ return(sSocket);
2181+}
2182+
2183+
19662184 /*----- リッスンソケットを取得 ------------------------------------------------
19672185 *
19682186 * Parameter
@@ -1972,8 +2190,30 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)
19722190 * SOCKET リッスンソケット
19732191 *----------------------------------------------------------------------------*/
19742192
2193+// IPv6対応
19752194 SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
19762195 {
2196+ SOCKET Result;
2197+ Result = INVALID_SOCKET;
2198+ switch(CurHost.InetFamily)
2199+ {
2200+ case AF_UNSPEC:
2201+ break;
2202+ case AF_INET:
2203+ Result = GetFTPListenSocketIPv4(ctrl_skt, CancelCheckWork);
2204+ break;
2205+ case AF_INET6:
2206+ Result = GetFTPListenSocketIPv6(ctrl_skt, CancelCheckWork);
2207+ break;
2208+ }
2209+ return Result;
2210+}
2211+
2212+
2213+// IPv6対応
2214+//SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
2215+SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork)
2216+{
19772217 SOCKET listen_skt;
19782218 int iLength;
19792219 char *a,*p;
@@ -1997,12 +2237,17 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
19972237 {
19982238 /*===== SOCKS4を使う =====*/
19992239 DoPrintf("Use SOCKS4 BIND");
2000- if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)
2240+ // IPv6対応
2241+// if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)
2242+ if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4), CancelCheckWork) != SOCKET_ERROR)
20012243 {
20022244 Socks4Cmd.Ver = SOCKS4_VER;
20032245 Socks4Cmd.Cmd = SOCKS4_CMD_BIND;
2004- Socks4Cmd.Port = CurSockAddr.sin_port;
2005- Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;
2246+ // IPv6対応
2247+// Socks4Cmd.Port = CurSockAddr.sin_port;
2248+// Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;
2249+ Socks4Cmd.Port = CurSockAddrIPv4.sin_port;
2250+ Socks4Cmd.AdrsInt = CurSockAddrIPv4.sin_addr.s_addr;
20062251 strcpy(Socks4Cmd.UserID, FwallUser);
20072252 Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;
20082253
@@ -2021,7 +2266,9 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
20212266 }
20222267
20232268 if(Socks4Reply.AdrsInt == 0)
2024- Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;
2269+ // IPv6対応
2270+// Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;
2271+ Socks4Reply.AdrsInt = SocksSockAddrIPv4.sin_addr.s_addr;
20252272
20262273 a = (char *)&Socks4Reply.AdrsInt;
20272274 p = (char *)&Socks4Reply.Port;
@@ -2031,7 +2278,9 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
20312278 {
20322279 /*===== SOCKS5を使う =====*/
20332280 DoPrintf("Use SOCKS5 BIND");
2034- if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)
2281+ // IPv6対応
2282+// if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)
2283+ if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4), CancelCheckWork) != SOCKET_ERROR)
20352284 {
20362285 if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)
20372286 {
@@ -2040,7 +2289,9 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
20402289 return(listen_skt);
20412290 }
20422291
2043- Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);
2292+ // IPv6対応
2293+// Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);
2294+ Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddrIPv4.sin_addr.s_addr, DomainName, CurSockAddrIPv4.sin_port);
20442295
20452296 Socks5Reply.Result = -1;
20462297 // 同時接続対応
@@ -2056,11 +2307,15 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
20562307 listen_skt = INVALID_SOCKET;
20572308 }
20582309
2059- if(Socks5Reply.AdrsInt == 0)
2060- Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;
2310+ // IPv6対応
2311+// if(Socks5Reply.AdrsInt == 0)
2312+// Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;
20612313
2062- a = (char *)&Socks5Reply.AdrsInt;
2063- p = (char *)&Socks5Reply.Port;
2314+ // IPv6対応
2315+// a = (char *)&Socks5Reply.AdrsInt;
2316+// p = (char *)&Socks5Reply.Port;
2317+ a = (char *)&Socks5Reply._dummy[0];
2318+ p = (char *)&Socks5Reply._dummy[4];
20642319 }
20652320 }
20662321 else
@@ -2136,6 +2391,140 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)
21362391 }
21372392
21382393
2394+SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork)
2395+{
2396+ SOCKET listen_skt;
2397+ int iLength;
2398+ char *a,*p;
2399+ struct sockaddr_in6 saCtrlAddr;
2400+ struct sockaddr_in6 saTmpAddr;
2401+ SOCKS5REQUEST Socks5Cmd;
2402+ SOCKS5REPLY Socks5Reply;
2403+
2404+ int Len;
2405+ int Fwall;
2406+
2407+ char Adrs[40];
2408+
2409+ Fwall = FWALL_NONE;
2410+ if(AskHostFireWall() == YES)
2411+ Fwall = FwallType;
2412+
2413+ if((listen_skt = do_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)
2414+ {
2415+ if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))
2416+ {
2417+ /*===== SOCKS5を使う =====*/
2418+ DoPrintf("Use SOCKS5 BIND");
2419+ if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv6, sizeof(SocksSockAddrIPv6), CancelCheckWork) != SOCKET_ERROR)
2420+ {
2421+ if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)
2422+ {
2423+ DoClose(listen_skt);
2424+ listen_skt = INVALID_SOCKET;
2425+ return(listen_skt);
2426+ }
2427+
2428+ Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, (char*)&CurSockAddrIPv6.sin6_addr, DomainName, CurSockAddrIPv6.sin6_port);
2429+
2430+ Socks5Reply.Result = -1;
2431+ // 同時接続対応
2432+// if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||
2433+// (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) ||
2434+// (Socks5Reply.Result != SOCKS5_RES_OK))
2435+ if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||
2436+ (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) ||
2437+ (Socks5Reply.Result != SOCKS5_RES_OK))
2438+ {
2439+ SetTaskMsg(MSGJPN029, Socks5Reply.Result);
2440+ DoClose(listen_skt);
2441+ listen_skt = INVALID_SOCKET;
2442+ }
2443+
2444+ // IPv6対応
2445+// if(Socks5Reply.AdrsInt == 0)
2446+// Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;
2447+
2448+ // IPv6対応
2449+// a = (char *)&Socks5Reply.AdrsInt;
2450+// p = (char *)&Socks5Reply.Port;
2451+ a = (char *)&Socks5Reply._dummy[0];
2452+ p = (char *)&Socks5Reply._dummy[16];
2453+ }
2454+ }
2455+ else
2456+ {
2457+ /*===== SOCKSを使わない =====*/
2458+ DoPrintf("Use normal BIND");
2459+ saCtrlAddr.sin6_port = htons(0);
2460+ saCtrlAddr.sin6_family = AF_INET6;
2461+ memset(&saCtrlAddr.sin6_addr, 0, 16);
2462+
2463+ if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr_in6)) != SOCKET_ERROR)
2464+ {
2465+ iLength = sizeof(saCtrlAddr);
2466+ if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)
2467+ {
2468+ if(do_listen(listen_skt, 1) == 0)
2469+ {
2470+ iLength = sizeof(saTmpAddr);
2471+ if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)
2472+ ReportWSError("getsockname", WSAGetLastError());
2473+
2474+ a = (char *)&saTmpAddr.sin6_addr;
2475+ p = (char *)&saCtrlAddr.sin6_port;
2476+ }
2477+ else
2478+ {
2479+ ReportWSError("listen", WSAGetLastError());
2480+ do_closesocket(listen_skt);
2481+ listen_skt = INVALID_SOCKET;
2482+ }
2483+ }
2484+ else
2485+ {
2486+ ReportWSError("getsockname", WSAGetLastError());
2487+ do_closesocket(listen_skt);
2488+ listen_skt = INVALID_SOCKET;
2489+ }
2490+ }
2491+ else
2492+ {
2493+ ReportWSError("bind", WSAGetLastError());
2494+ do_closesocket(listen_skt);
2495+ listen_skt = INVALID_SOCKET;
2496+ }
2497+
2498+ if(listen_skt == INVALID_SOCKET)
2499+ SetTaskMsg(MSGJPN030);
2500+ }
2501+ }
2502+ else
2503+ ReportWSError("socket create", WSAGetLastError());
2504+
2505+ if(listen_skt != INVALID_SOCKET)
2506+ {
2507+#define US(w) (((int)w)&0xffff)
2508+ // 同時接続対応
2509+// if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",
2510+// UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
2511+// UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)
2512+ if((command(ctrl_skt,NULL, CancelCheckWork, "EPRT |2|%s|%d|",
2513+ AddressToStringIPv6(Adrs, a),
2514+ US(p[0])) / 100) != FTP_COMPLETE)
2515+ {
2516+ SetTaskMsg(MSGJPN031);
2517+ do_closesocket(listen_skt);
2518+ listen_skt = INVALID_SOCKET;
2519+ }
2520+// else
2521+// DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));
2522+ }
2523+
2524+ return(listen_skt);
2525+}
2526+
2527+
21392528 /*----- ホストへ接続処理中かどうかを返す---------------------------------------
21402529 *
21412530 * Parameter
@@ -2229,6 +2618,44 @@ static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulo
22292618 }
22302619
22312620
2621+// IPv6対応
2622+static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port)
2623+{
2624+ uchar *Pos;
2625+ int Len;
2626+ int TotalLen;
2627+
2628+ Pos = (uchar *)Packet;
2629+ Pos += SOCKS5REQUEST_SIZE;
2630+ TotalLen = SOCKS5REQUEST_SIZE + 2; /* +2はポートの分 */
2631+
2632+ Packet->Ver = SOCKS5_VER;
2633+ Packet->Cmd = Cmd;
2634+ Packet->Rsv = 0;
2635+ if(ValidIP == YES)
2636+ {
2637+ /* IPアドレスを指定 */
2638+ Packet->Type = SOCKS5_ADRS_IPV6;
2639+ memcpy(Pos, IP, 16);
2640+ Pos += 16;
2641+ TotalLen += 16;
2642+ }
2643+ else
2644+ {
2645+ /* ホスト名を指定 */
2646+ Packet->Type = SOCKS5_ADRS_NAME;
2647+ Len = strlen(Host);
2648+ *Pos++ = Len;
2649+ strcpy(Pos, Host);
2650+ Pos += Len;
2651+ TotalLen += Len + 1;
2652+ }
2653+ *((ushort *)Pos) = Port;
2654+
2655+ return(TotalLen);
2656+}
2657+
2658+
22322659 /*----- SOCKSのコマンドを送る -------------------------------------------------
22332660 *
22342661 * Parameter
@@ -2281,7 +2708,7 @@ static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet, int *CancelChec
22812708 if(Packet->Type == SOCKS5_ADRS_IPV4)
22822709 Len = 4 + 2;
22832710 else if(Packet->Type == SOCKS5_ADRS_IPV6)
2284- Len = 6 + 2;
2711+ Len = 16 + 2;
22852712 else
22862713 {
22872714 // 同時接続対応
@@ -2496,6 +2923,11 @@ int AskUseMLSD(void)
24962923 }
24972924
24982925 // IPv6対応
2926+int AskInetFamily(void)
2927+{
2928+ return(CurHost.InetFamily);
2929+}
2930+
24992931 int AskUseIPv6(void)
25002932 {
25012933 return(CurHost.UseIPv6);
--- a/doc/eng/FFFTP.txt
+++ b/doc/eng/FFFTP.txt
@@ -34,6 +34,19 @@ Changes in Ver.1.99
3434 -- MLSD command became used for retrieving filenames on appropriate hosts.
3535 That is helpful for hosts that do not return filenames properly.
3636
37+-- Enhanced communication routines to reduce waiting time.
38+
39+-- Changed to display responses from hosts after decoding as Kanji code of
40+ filenames.
41+
42+-- Fixed bugs of arbitrary code execution in saving registry settings to a
43+ file.
44+
45+-- Fixed bugs of launching wrong files if correct ones contain no extensions.
46+
47+-- Internet Protocol Version 6 became available.
48+ IPv6 will be used when name resolution for IPv4 is unavailable.
49+
3750
3851 Outline
3952 -------
--- a/doc/eng/history.txt
+++ b/doc/eng/history.txt
@@ -6,6 +6,19 @@ Changes in Ver.1.99
66 -- MLSD command became used for retrieving filenames on appropriate hosts.
77 That is helpful for hosts that do not return filenames properly.
88
9+-- Enhanced communication routines to reduce waiting time.
10+
11+-- Changed to display responses from hosts after decoding as Kanji code of
12+ filenames.
13+
14+-- Fixed bugs of arbitrary code execution in saving registry settings to a
15+ file.
16+
17+-- Fixed bugs of launching wrong files if correct ones contain no extensions.
18+
19+-- Internet Protocol Version 6 became available.
20+ IPv6 will be used when name resolution for IPv4 is unavailable.
21+
922 Changes in Ver.1.98c
1023 --------------------
1124
--- a/doc/jpn/FFFTP.txt
+++ b/doc/jpn/FFFTP.txt
@@ -34,6 +34,21 @@ Ver 1.99
3434  取得するようにしました。LISTコマンドの応答に特定のファイルが
3535  含まれない一部のホストでも正しく列挙できる可能性が高くなります。
3636
37+・通信のルーチンを待ち時間が減るように改善しました。
38+
39+・ホストの応答をホストのファイル名の漢字コードでデコードしてからログに
40+ 表示するように変更しました。
41+
42+・レジストリの設定をファイルに保存するときに任意のコードが実行される
43+ 可能性があるバグを修正しました。
44+
45+・拡張子が無いファイルをダブルクリックした場合に選択されたものと異なる
46+ ファイルが表示されるバグを修正しました。
47+
48+・ホストとの接続にInternet Protocol Version 6(略称IPv6)が使用できる
49+ ようになりました。従来のIPv4で名前解決ができない場合にIPv6で接続を
50+ 試みるようにしました。
51+
3752
3853 Ver 1.96d以前へ戻す場合
3954 -----------------------
--- a/doc/jpn/history.txt
+++ b/doc/jpn/history.txt
@@ -6,6 +6,21 @@ FFFTP
66  取得するようにしました。LISTコマンドの応答に特定のファイルが
77  含まれない一部のホストでも正しく列挙できる可能性が高くなります。
88
9+・通信のルーチンを待ち時間が減るように改善しました。
10+
11+・ホストの応答をホストのファイル名の漢字コードでデコードしてからログに
12+ 表示するように変更しました。
13+
14+・レジストリの設定をファイルに保存するときに任意のコードが実行される
15+ 可能性があるバグを修正しました。
16+
17+・拡張子が無いファイルをダブルクリックした場合に選択されたものと異なる
18+ ファイルが表示されるバグを修正しました。
19+
20+・ホストとの接続にInternet Protocol Version 6(略称IPv6)が使用できる
21+ ようになりました。従来のIPv4で名前解決ができない場合にIPv6で接続を
22+ 試みるようにしました。
23+
924 ■Ver 1.98c
1025
1126 ・日本語ドメイン名のホストへの接続時にアドレスをPunycodeへ変換してから
--- a/getput.c
+++ b/getput.c
@@ -43,7 +43,7 @@
4343 #include <time.h>
4444 // IPv6対応
4545 //#include <winsock.h>
46-#include <winsock2.h>
46+#include <ws2tcpip.h>
4747 #include <windowsx.h>
4848 #include <commctrl.h>
4949 #include <process.h>
@@ -104,7 +104,11 @@ static int SetUploadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *M
104104 static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);
105105 static void DispTransferStatus(HWND hWnd, int End, TRANSPACKET *Pkt);
106106 static void DispTransFileInfo(TRANSPACKET *Pkt, char *Title, int SkipButton, int Info);
107-static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max);
107+// IPv6対応
108+//static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max);
109+static int GetAdrsAndPort(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max);
110+static int GetAdrsAndPortIPv4(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max);
111+static int GetAdrsAndPortIPv6(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max);
108112 static int IsSpecialDevice(char *Fname);
109113 static int MirrorDelNotify(int Cur, int Notify, TRANSPACKET *Pkt);
110114 static BOOL CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);
@@ -1316,7 +1320,10 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
13161320 SOCKET listen_socket = INVALID_SOCKET; // data listen socket
13171321 char Buf[1024];
13181322 int CreateMode;
1319- struct sockaddr_in saSockAddr1;
1323+ // IPv6対応
1324+// struct sockaddr_in saSockAddr1;
1325+ struct sockaddr_in saSockAddrIPv4;
1326+ struct sockaddr_in6 saSockAddrIPv6;
13201327 char Reply[ERR_MSG_LEN+7];
13211328
13221329 if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, CancelCheckWork)) != INVALID_SOCKET)
@@ -1331,8 +1338,20 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
13311338 // if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL)
13321339 if(SocksGet2ndBindReply(listen_socket, &data_socket, CancelCheckWork) == FFFTP_FAIL)
13331340 {
1334- iLength = sizeof(saSockAddr1);
1335- data_socket = do_accept(listen_socket, (struct sockaddr *)&saSockAddr1, (int *)&iLength);
1341+ // IPv6対応
1342+// iLength = sizeof(saSockAddr1);
1343+// data_socket = do_accept(listen_socket, (struct sockaddr *)&saSockAddr1, (int *)&iLength);
1344+ switch(AskInetFamily())
1345+ {
1346+ case AF_INET:
1347+ iLength=sizeof(saSockAddrIPv4);
1348+ data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv4, (int *)&iLength);
1349+ break;
1350+ case AF_INET6:
1351+ iLength=sizeof(saSockAddrIPv6);
1352+ data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv6, (int *)&iLength);
1353+ break;
1354+ }
13361355
13371356 if(shutdown(listen_socket, 1) != 0)
13381357 ReportWSError("shutdown listen", WSAGetLastError());
@@ -1345,7 +1364,19 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
13451364 iRetCode = 500;
13461365 }
13471366 else
1348- DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port));
1367+ // IPv6対応
1368+// DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port));
1369+ {
1370+ switch(AskInetFamily())
1371+ {
1372+ case AF_INET:
1373+ DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddrIPv4.sin_addr), ntohs(saSockAddrIPv4.sin_port));
1374+ break;
1375+ case AF_INET6:
1376+ DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet6_ntoa(saSockAddrIPv6.sin6_addr), ntohs(saSockAddrIPv6.sin6_port));
1377+ break;
1378+ }
1379+ }
13491380 }
13501381
13511382 if(data_socket != INVALID_SOCKET)
@@ -1403,15 +1434,29 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
14031434 SOCKET data_socket = INVALID_SOCKET; // data channel socket
14041435 char Buf[1024];
14051436 int CreateMode;
1406- char Adrs[20];
1437+ // IPv6対応
1438+// char Adrs[20];
1439+ char Adrs[40];
14071440 int Port;
14081441 int Flg;
14091442 char Reply[ERR_MSG_LEN+7];
14101443
1411- iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "PASV");
1444+ // IPv6対応
1445+// iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "PASV");
1446+ switch(AskInetFamily())
1447+ {
1448+ case AF_INET:
1449+ iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "PASV");
1450+ break;
1451+ case AF_INET6:
1452+ iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "EPSV");
1453+ break;
1454+ }
14121455 if(iRetCode/100 == FTP_COMPLETE)
14131456 {
1414- if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS)
1457+ // IPv6対応
1458+// if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS)
1459+ if(GetAdrsAndPort(Pkt->ctrl_skt, Buf, Adrs, &Port, 39) == FFFTP_SUCCESS)
14151460 {
14161461 if((data_socket = connectsock(Adrs, Port, MSGJPN091, CancelCheckWork)) != INVALID_SOCKET)
14171462 {
@@ -2475,7 +2520,10 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt)
24752520 SOCKET data_socket = INVALID_SOCKET; // data channel socket
24762521 SOCKET listen_socket = INVALID_SOCKET; // data listen socket
24772522 char Buf[1024];
2478- struct sockaddr_in saSockAddr1;
2523+ // IPv6対応
2524+// struct sockaddr_in saSockAddr1;
2525+ struct sockaddr_in saSockAddrIPv4;
2526+ struct sockaddr_in6 saSockAddrIPv6;
24792527 int Resume;
24802528 char Reply[ERR_MSG_LEN+7];
24812529
@@ -2498,8 +2546,20 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt)
24982546 // if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL)
24992547 if(SocksGet2ndBindReply(listen_socket, &data_socket, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL)
25002548 {
2501- iLength=sizeof(saSockAddr1);
2502- data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddr1, (int *)&iLength);
2549+ // IPv6対応
2550+// iLength=sizeof(saSockAddr1);
2551+// data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddr1, (int *)&iLength);
2552+ switch(AskInetFamily())
2553+ {
2554+ case AF_INET:
2555+ iLength=sizeof(saSockAddrIPv4);
2556+ data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv4, (int *)&iLength);
2557+ break;
2558+ case AF_INET6:
2559+ iLength=sizeof(saSockAddrIPv6);
2560+ data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv6, (int *)&iLength);
2561+ break;
2562+ }
25032563
25042564 if(shutdown(listen_socket, 1) != 0)
25052565 ReportWSError("shutdown listen", WSAGetLastError());
@@ -2512,7 +2572,19 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt)
25122572 iRetCode = 500;
25132573 }
25142574 else
2515- DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port));
2575+ // IPv6対応
2576+// DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port));
2577+ {
2578+ switch(AskInetFamily())
2579+ {
2580+ case AF_INET:
2581+ DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddrIPv4.sin_addr), ntohs(saSockAddrIPv4.sin_port));
2582+ break;
2583+ case AF_INET6:
2584+ DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet6_ntoa(saSockAddrIPv6.sin6_addr), ntohs(saSockAddrIPv6.sin6_port));
2585+ break;
2586+ }
2587+ }
25162588 }
25172589
25182590 if(data_socket != INVALID_SOCKET)
@@ -2566,7 +2638,9 @@ static int UpLoadPassive(TRANSPACKET *Pkt)
25662638 int iRetCode;
25672639 SOCKET data_socket = INVALID_SOCKET; // data channel socket
25682640 char Buf[1024];
2569- char Adrs[20];
2641+ // IPv6対応
2642+// char Adrs[20];
2643+ char Adrs[40];
25702644 int Port;
25712645 int Flg;
25722646 int Resume;
@@ -2574,10 +2648,22 @@ static int UpLoadPassive(TRANSPACKET *Pkt)
25742648
25752649 // 同時接続対応
25762650 // iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled, "PASV");
2577- iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV");
2651+ // IPv6対応
2652+// iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV");
2653+ switch(AskInetFamily())
2654+ {
2655+ case AF_INET:
2656+ iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV");
2657+ break;
2658+ case AF_INET6:
2659+ iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "EPSV");
2660+ break;
2661+ }
25782662 if(iRetCode/100 == FTP_COMPLETE)
25792663 {
2580- if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS)
2664+ // IPv6対応
2665+// if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS)
2666+ if(GetAdrsAndPort(Pkt->ctrl_skt, Buf, Adrs, &Port, 39) == FFFTP_SUCCESS)
25812667 {
25822668 // 同時接続対応
25832669 // if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled)) != INVALID_SOCKET)
@@ -3675,7 +3761,26 @@ static void DispTransFileInfo(TRANSPACKET *Pkt, char *Title, int SkipButton, int
36753761 * FFFTP_SUCCESS/FFFTP_FAIL
36763762 *----------------------------------------------------------------------------*/
36773763
3678-static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max)
3764+static int GetAdrsAndPort(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max)
3765+{
3766+ int Result;
3767+ Result = FFFTP_FAIL;
3768+ switch(AskInetFamily())
3769+ {
3770+ case AF_INET:
3771+ Result = GetAdrsAndPortIPv4(Skt, Str, Adrs, Port, Max);
3772+ break;
3773+ case AF_INET6:
3774+ Result = GetAdrsAndPortIPv6(Skt, Str, Adrs, Port, Max);
3775+ break;
3776+ }
3777+ return Result;
3778+}
3779+
3780+
3781+// IPv6対応
3782+//static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max)
3783+static int GetAdrsAndPortIPv4(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max)
36793784 {
36803785 char *Pos;
36813786 char *Btm;
@@ -3742,49 +3847,55 @@ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max)
37423847
37433848
37443849 // IPv6対応
3745-static int GetAdrsAndPortIPv6(char *Str, char *Adrs, int *Port, int Max, short *Family)
3850+static int GetAdrsAndPortIPv6(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max)
37463851 {
37473852 char *Pos;
37483853 char *Btm;
37493854 int Sts;
3855+ int i;
3856+ struct sockaddr_in6 SockAddr;
37503857
37513858 Sts = FFFTP_FAIL;
37523859
3753- Pos = strchr(Str, '|');
3754- if(Pos != NULL)
3860+ Btm = strchr(Str, '(');
3861+ if(Btm != NULL)
37553862 {
3756- Pos++;
3757- Btm = strchr(Pos, '|');
3863+ Btm++;
3864+ Btm = strchr(Btm, '|');
37583865 if(Btm != NULL)
37593866 {
3760- switch(atoi(Pos))
3761- {
3762- case 1:
3763- *Family = AF_INET;
3764- break;
3765- case 2:
3766- *Family = AF_INET6;
3767- break;
3768- }
37693867 Pos = Btm + 1;
37703868 Btm = strchr(Pos, '|');
37713869 if(Btm != NULL)
37723870 {
3773- if((Btm - Pos) <= Max)
3871+ Pos = Btm + 1;
3872+ Btm = strchr(Pos, '|');
3873+ if(Btm != NULL)
37743874 {
3775- if((Btm - Pos) > 0)
3875+ if((Btm - Pos) <= Max)
37763876 {
3777- strncpy(Adrs, Pos, Btm - Pos);
3778- *(Adrs + (Btm - Pos)) = NUL;
3779- }
3877+ if((Btm - Pos) > 0)
3878+ {
3879+ strncpy(Adrs, Pos, Btm - Pos);
3880+ *(Adrs + (Btm - Pos)) = NUL;
3881+ }
3882+ else
3883+ {
3884+ i = sizeof(SockAddr);
3885+ if(getpeername(Skt, (struct sockaddr*)&SockAddr, &i) != SOCKET_ERROR)
3886+ AddressToStringIPv6(Adrs, &SockAddr.sin6_addr);
3887+ }
37803888
3781- Pos = Btm + 1;
3782- Btm = strchr(Pos, '|');
3783- if(Btm != NULL)
3784- {
3785- Btm++;
3786- *Port = atoi(Pos);
3787- Sts = FFFTP_SUCCESS;
3889+ Pos = Btm + 1;
3890+ Btm = strchr(Pos, '|');
3891+ if(Btm != NULL)
3892+ {
3893+ Btm++;
3894+ *Port = atoi(Pos);
3895+ Btm = strchr(Btm, ')');
3896+ if(Btm != NULL)
3897+ Sts = FFFTP_SUCCESS;
3898+ }
37883899 }
37893900 }
37903901 }
--- a/hostman.c
+++ b/hostman.c
@@ -1328,6 +1328,7 @@ void CopyDefaultHost(HOSTDATA *Set)
13281328 Set->Feature = 0;
13291329 Set->UseMLSD = YES;
13301330 // IPv6対応
1331+ Set->InetFamily = AF_UNSPEC;
13311332 Set->UseIPv6 = YES;
13321333 return;
13331334 }
--- a/local.c
+++ b/local.c
@@ -182,7 +182,8 @@ void DispFileProperty(char *Fname)
182182 {
183183 SHELLEXECUTEINFO sInfo;
184184 // 異なるファイルが表示されるバグ修正
185- // 詳細は不明だが末尾に半角スペースを置くと拡張子の補完がされなくなる
185+ // UNCでない場合に末尾に半角スペースを置くと拡張子の補完がされなくなる
186+ // 現在UNC対応の予定は無い
186187 char Fname2[FMAX_PATH+1];
187188
188189 memset(&sInfo, NUL, sizeof(SHELLEXECUTEINFO));
--- a/registry.c
+++ b/registry.c
@@ -2351,7 +2351,6 @@ static int ReadStringFromReg(void *Handle, char *Name, char *Str, DWORD Size)
23512351 Sts = FFFTP_SUCCESS;
23522352 if(!CheckStringM(Str))
23532353 break;
2354- Str = Str;
23552354 // UTF-8ではない可能性がある
23562355 // Shift_JISとみなす
23572356 case KANJI_SJIS:
--- a/socket.c
+++ b/socket.c
@@ -651,7 +651,53 @@ static int UnRegistAsyncTableDbase(HANDLE Async)
651651
652652
653653
654-struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork)
654+// IPv6対応
655+//struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork)
656+struct hostent *do_gethostbynameIPv4(const char *Name, char *Buf, int Len, int *CancelCheckWork)
657+{
658+#if USE_THIS
659+ struct hostent *Ret;
660+ HANDLE hAsync;
661+ int Error;
662+
663+#if DBG_MSG
664+ DoPrintf("# Start gethostbyname");
665+#endif
666+ Ret = NULL;
667+ // 同時接続対応
668+// *CancelCheckWork = NO;
669+
670+ // UTF-8対応
671+// hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);
672+ hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);
673+ if(hAsync != NULL)
674+ {
675+ RegistAsyncTableDbase(hAsync);
676+ while((*CancelCheckWork == NO) && (AskAsyncDoneDbase(hAsync, &Error) != YES))
677+ {
678+ Sleep(1);
679+ if(BackgrndMessageProc() == YES)
680+ *CancelCheckWork = YES;
681+ }
682+
683+ if(*CancelCheckWork == YES)
684+ {
685+ WSACancelAsyncRequest(hAsync);
686+ }
687+ else if(Error == 0)
688+ {
689+ Ret = (struct hostent *)Buf;
690+ }
691+ UnRegistAsyncTableDbase(hAsync);
692+ }
693+ return(Ret);
694+#else
695+ return(gethostbyname(Name));
696+#endif
697+}
698+
699+
700+struct hostent *do_gethostbynameIPv6(const char *Name, char *Buf, int Len, int *CancelCheckWork)
655701 {
656702 #if USE_THIS
657703 struct hostent *Ret;
@@ -667,9 +713,7 @@ struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *Canc
667713
668714 // UTF-8対応
669715 // hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);
670- // IPv6対応
671-// hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);
672- hAsync = WSAAsyncGetHostByNameIPv6M(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len, AF_INET);
716+ hAsync = WSAAsyncGetHostByNameIPv6M(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len, AF_INET6);
673717 if(hAsync != NULL)
674718 {
675719 RegistAsyncTableDbase(hAsync);
@@ -1319,6 +1363,113 @@ int WSACancelAsyncRequestIPv6(HANDLE hAsyncTaskHandle)
13191363 return Result;
13201364 }
13211365
1366+char* AddressToStringIPv6(char* str, void* in6)
1367+{
1368+ char* pResult;
1369+ unsigned char* p;
1370+ int MaxZero;
1371+ int MaxZeroLen;
1372+ int i;
1373+ int j;
1374+ char Tmp[5];
1375+ pResult = str;
1376+ p = (unsigned char*)in6;
1377+ MaxZero = 8;
1378+ MaxZeroLen = 1;
1379+ for(i = 0; i < 8; i++)
1380+ {
1381+ for(j = i; j < 8; j++)
1382+ {
1383+ if(p[j * 2] != 0 || p[j * 2 + 1] != 0)
1384+ break;
1385+ }
1386+ if(j - i > MaxZeroLen)
1387+ {
1388+ MaxZero = i;
1389+ MaxZeroLen = j - i;
1390+ }
1391+ }
1392+ strcpy(str, "");
1393+ for(i = 0; i < 8; i++)
1394+ {
1395+ if(i == MaxZero)
1396+ {
1397+ if(i == 0)
1398+ strcat(str, ":");
1399+ strcat(str, ":");
1400+ }
1401+ else if(i < MaxZero || i >= MaxZero + MaxZeroLen)
1402+ {
1403+ sprintf(Tmp, "%x", (((int)p[i * 2] & 0xff) << 8) | ((int)p[i * 2 + 1] & 0xff));
1404+ strcat(str, Tmp);
1405+ if(i < 7)
1406+ strcat(str, ":");
1407+ }
1408+ }
1409+ return pResult;
1410+}
1411+
1412+// IPv6対応のinet_ntoa相当の関数
1413+// ただしANSI用
1414+char* inet6_ntoa(struct in6_addr in6)
1415+{
1416+ char* pResult;
1417+ static char Adrs[40];
1418+ pResult = NULL;
1419+ memset(Adrs, 0, sizeof(Adrs));
1420+ pResult = AddressToStringIPv6(Adrs, &in6);
1421+ return pResult;
1422+}
1423+
1424+// IPv6対応のinet_addr相当の関数
1425+// ただしANSI用
1426+struct in6_addr inet6_addr(const char* cp)
1427+{
1428+ struct in6_addr Result;
1429+ int AfterZero;
1430+ int i;
1431+ char* p;
1432+ memset(&Result, 0, sizeof(Result));
1433+ AfterZero = 0;
1434+ for(i = 0; i < 8; i++)
1435+ {
1436+ if(!cp)
1437+ {
1438+ memset(&Result, 0xff, sizeof(Result));
1439+ break;
1440+ }
1441+ if(i >= AfterZero)
1442+ {
1443+ if(strncmp(cp, ":", 1) == 0)
1444+ {
1445+ cp = cp + 1;
1446+ if(i == 0 && strncmp(cp, ":", 1) == 0)
1447+ cp = cp + 1;
1448+ p = (char*)cp;
1449+ AfterZero = 7;
1450+ while(p = strstr(p, ":"))
1451+ {
1452+ p = p + 1;
1453+ AfterZero--;
1454+ }
1455+ }
1456+ else
1457+ {
1458+ Result.u.Word[i] = (USHORT)strtol(cp, &p, 16);
1459+ Result.u.Word[i] = ((Result.u.Word[i] & 0xff00) >> 8) | ((Result.u.Word[i] & 0x00ff) << 8);
1460+ if(strncmp(p, ":", 1) != 0 && strlen(p) > 0)
1461+ {
1462+ memset(&Result, 0xff, sizeof(Result));
1463+ break;
1464+ }
1465+ if(cp = strstr(cp, ":"))
1466+ cp = cp + 1;
1467+ }
1468+ }
1469+ }
1470+ return Result;
1471+}
1472+
13221473 // UTF-8対応
13231474
13241475 static BOOL ConvertStringToPunycode(LPSTR Output, DWORD Count, LPCSTR Input)