1 /*
2 * h_port.c
3 * (C)1998-2011 by Marc Huber <Marc.Huber@web.de>
4 * All rights reserved.
5 *
6 * $Id: h_port.c,v 1.11 2015/03/14 06:11:25 marc Exp marc $
7 *
8 */
9
10 #include "headers.h"
11
12 static const char rcsid[] __attribute__ ((used)) = "$Id: h_port.c,v 1.11 2015/03/14 06:11:25 marc Exp marc $";
13
14 #define MODE_PORT 0
15 #define MODE_LPRT 1
16 #define MODE_EPRT 2
17
18 static char *modelist[] = { "PORT", "LPRT", "EPRT" };
19
do_port(int mode,struct context * ctx,char * arg)20 static void do_port(int mode, struct context *ctx, char *arg)
21 {
22 int af_d;
23
24 DebugIn(DEBUG_COMMAND);
25
26 if (ctx->dfn > -1)
27 cleanup_data(ctx, ctx->dfn);
28
29 if (ctx->epsv_all) {
30 reply(ctx, MSG_500_EPSV_only);
31 DebugOut(DEBUG_COMMAND);
32 return;
33 }
34
35 switch (mode) {
36 case MODE_LPRT:
37 af_d = foobar_eval(&ctx->sa_d_remote, arg);
38 break;
39 case MODE_EPRT:
40 af_d = rfc2428_eval(&ctx->sa_d_remote, arg);
41 break;
42 default:
43 af_d = rfc959_eval(&ctx->sa_d_remote, arg);
44 }
45
46 if (af_d == -2) {
47 char buf[160];
48 switch (mode) {
49 case MODE_LPRT:
50 replyf(ctx, MSG_521_Supported_AF, print_foobar_families(buf, sizeof(buf)));
51 break;
52 case MODE_EPRT:
53 replyf(ctx, MSG_522_Supported_AF, print_rfc2428_families(buf, sizeof(buf)));
54 }
55 DebugOut(DEBUG_COMMAND);
56 return;
57 }
58
59 if (af_d < 0)
60 reply(ctx, MSG_501_Syntax_error);
61 /* rfc2577 suggests to deny connections to reserved ports: */
62 else if (su_get_port(&ctx->sa_d_remote) < IPPORT_RESERVED) {
63 ctx->sa_d_remote = ctx->sa_c_remote;
64 reply(ctx, MSG_504_Command_not_implemented);
65 } else if (!ctx->address_mismatch && !su_equal_addr(&ctx->sa_d_remote, &ctx->sa_c_remote))
66 replyf(ctx, MSG_501_port_denied, modelist[mode]);
67 else
68 replyf(ctx, MSG_200_port_successful, modelist[mode]);
69
70 DebugOut(DEBUG_COMMAND);
71 }
72
h_port(struct context * ctx,char * arg)73 void h_port(struct context *ctx, char *arg)
74 {
75 do_port(MODE_PORT, ctx, arg);
76 }
77
h_lprt(struct context * ctx,char * arg)78 void h_lprt(struct context *ctx, char *arg)
79 {
80 do_port(MODE_LPRT, ctx, arg);
81 }
82
h_eprt(struct context * ctx,char * arg)83 void h_eprt(struct context *ctx, char *arg)
84 {
85 do_port(MODE_EPRT, ctx, arg);
86 }
87