2 * User FTP Server, Share folders over FTP without being root.
3 * Copyright (C) 2008 Isaac Jurado
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option) any later
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 # include <sys/socket.h>
23 # include <arpa/inet.h>
28 /* This is needed by Solaris */
30 # define INADDR_NONE -1
35 * Parse a PORT argument and convert it to a internet address structure.
36 * Returns -1 when a parsing error occurs.
38 * The argument has the syntax "h1,h2,h3,h4,p1,p2". First, we need to split IP
39 * and port information "h1.h2.h3.h4\0p1,p2" (two strings). The IP string is
40 * finally parsed by inet_addr() into a 'in_addr_t' value. Finally, the port
41 * number is obtained as p1 * 256 + p2 and translated to network byte ordering
44 void parse_port_argument (void)
46 int commas
, port
, i
, j
;
47 struct sockaddr_in sai
;
51 warning("PORT without argument");
52 reply_c("501 Argument required.\r\n");
56 /* "h1,h2,h3,h4,p1,p2" ==> "h1.h2.h3.h4" "p1,p2" */
61 if (SS
.arg
[i
] == '\0')
63 warning("PORT invalid parameter '%s'", SS
.arg
);
64 reply_c("501 Invalid PORT parameter.\r\n");
77 /* "h1.h2.h3.h4" ==> struct in_addr */
78 sai
.sin_addr
.s_addr
= inet_addr(SS
.arg
);
79 if (sai
.sin_addr
.s_addr
== INADDR_NONE
)
81 error("PORT Translating IP '%s'", SS
.arg
);
82 reply_c("501 Invalid PORT parameter.\r\n");
85 /* Check if destination IP is the same as the client's */
86 if (sai
.sin_addr
.s_addr
!= SS
.client_address
.sin_addr
.s_addr
)
88 warning("PORT IP %s is not the same as the client's", SS
.arg
);
89 reply_c("501 Invalid PORT parameter.\r\n");
93 /* "p1,p2" ==> int (port number) */
95 while (SS
.arg
[j
] != ',')
98 port
= atoi(&SS
.arg
[i
]) * 256 + atoi(&SS
.arg
[j
+ 1]);
100 /* Save PORT information for later use when opening the data channel */
101 memset(&SS
.port_destination
, 0, sizeof(struct sockaddr_in
));
102 SS
.port_destination
.sin_family
= AF_INET
;
103 SS
.port_destination
.sin_addr
= sai
.sin_addr
;
104 SS
.port_destination
.sin_port
= htons(port
& 0x00FFFF);
106 SS
.mode
= ACTIVE_MODE
;
107 debug("PORT parsing results %s:%d\n", SS
.arg
, port
& 0x00FFFF);
108 reply_c("200 PORT Command OK.\r\n");