1/* 2 * Utility routines. 3 * 4 * Copyright (C) 2018 Denys Vlasenko 5 * 6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 */ 8//kbuild:lib-$(CONFIG_FTPGET) += parse_pasv_epsv.o 9//kbuild:lib-$(CONFIG_FTPPUT) += parse_pasv_epsv.o 10//kbuild:lib-$(CONFIG_WGET) += parse_pasv_epsv.o 11 12#include "libbb.h" 13 14int FAST_FUNC parse_pasv_epsv(char *buf) 15{ 16/* 17 * PASV command will not work for IPv6. RFC2428 describes 18 * IPv6-capable "extended PASV" - EPSV. 19 * 20 * "EPSV [protocol]" asks server to bind to and listen on a data port 21 * in specified protocol. Protocol is 1 for IPv4, 2 for IPv6. 22 * If not specified, defaults to "same as used for control connection". 23 * If server understood you, it should answer "229 <some text>(|||port|)" 24 * where "|" are literal pipe chars and "port" is ASCII decimal port#. 25 * 26 * There is also an IPv6-capable replacement for PORT (EPRT), 27 * but we don't need that. 28 * 29 * NB: PASV may still work for some servers even over IPv6. 30 * For example, vsftp happily answers 31 * "227 Entering Passive Mode (0,0,0,0,n,n)" and proceeds as usual. 32 */ 33 char *ptr; 34 int port; 35 36 if (!ENABLE_FEATURE_IPV6 || buf[2] == '7' /* "227" */) { 37 /* Response is "227 garbageN1,N2,N3,N4,P1,P2[)garbage]" 38 * Server's IP is N1.N2.N3.N4 (we ignore it) 39 * Server's port for data connection is P1*256+P2 */ 40 ptr = strrchr(buf, ')'); 41 if (ptr) *ptr = '\0'; 42 43 ptr = strrchr(buf, ','); 44 if (!ptr) return -1; 45 *ptr = '\0'; 46 port = xatou_range(ptr + 1, 0, 255); 47 48 ptr = strrchr(buf, ','); 49 if (!ptr) return -1; 50 *ptr = '\0'; 51 port += xatou_range(ptr + 1, 0, 255) * 256; 52 } else { 53 /* Response is "229 garbage(|||P1|)" 54 * Server's port for data connection is P1 */ 55 ptr = strrchr(buf, '|'); 56 if (!ptr) return -1; 57 *ptr = '\0'; 58 59 ptr = strrchr(buf, '|'); 60 if (!ptr) return -1; 61 *ptr = '\0'; 62 port = xatou_range(ptr + 1, 0, 65535); 63 } 64 65 return port; 66} 67