busybox/networking/parse_pasv_epsv.c
<<
>>
Prefs
   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