1 /****************************************************************************
2 ** File: ftpctrl.c
3 **
4 ** Author: Mike Borella
5 **
6 ** Comments: FTP control module.
7 **
8 ** $Id: ftpctrl.c,v 1.5 2006/11/21 07:47:34 farooq-i-azam Exp $
9 **
10 ** This program is free software; you can redistribute it and/or modify
11 ** it under the terms of the GNU General Public License as published by
12 ** the Free Software Foundation; either version 2 of the License, or
13 ** (at your option) any later version.
14 **
15 ** This program is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ** GNU Library General Public License for more details.
19 **
20 ** You should have received a copy of the GNU General Public License
21 ** along with this program; if not, write to the Free Software
22 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 **
24 *****************************************************************************/
25
26 #include "ftpctrl.h"
27
28 extern struct arg_t * my_args;
29
30 /*----------------------------------------------------------------------------
31 **
32 ** dump_ftpctrl()
33 **
34 ** Parse and display FTP control packets
35 **
36 **----------------------------------------------------------------------------
37 */
38
dump_ftpctrl(packet_t * pkt)39 void dump_ftpctrl(packet_t *pkt)
40 {
41 u_int8_t * payload;
42 u_int32_t size;
43 u_int8_t * ptr;
44
45 /* Set the layer */
46 set_layer(LAYER_APPLICATION);
47
48 /* find the payload size, then allocate memory and read the packet */
49 size = get_packet_apparentbytesleft(pkt);
50 if (size <= 0)
51 return;
52 payload = (u_int8_t *) my_malloc (size+1);
53 payload[size] = '\0';
54 if (get_packet_bytes(payload, pkt, size) == 0)
55 {
56 my_free(payload);
57 return;
58 }
59
60 /* Get rid of carriage return and line feed at end of payload if it exists */
61 ptr = payload + strlen(payload);
62 while(1)
63 {
64 ptr --;
65 if (*ptr == 0x0D || *ptr == 0x0A)
66 *ptr = '\0';
67 else
68 break;
69 }
70
71 /*
72 * FTP control connections either have commands or response codes. If there
73 * is a response code, then this is a reply, otherwise it is a request. All
74 * response codes are 3 digits long followed by a space. Exception: Some
75 * replies are split over multiple packets and do not have a numeric code
76 * to begin with.
77 *
78 * We determine the direction by looking at the source port. Replies
79 * should always come from the FTP control port.
80 */
81
82 if (state_get_srcport() == PORT_FTPCTRL)
83 {
84 if (isdigit(payload[0]) && isdigit(payload[1]) && isdigit(payload[2]) &&
85 isspace(payload[3]))
86 {
87 /* process a reply with a reply code */
88 char replycode_str[4];
89 int replycode;
90
91 strncpy(replycode_str, payload, 3);
92 replycode_str[3] = '\0';
93 replycode = atoi(replycode_str);
94
95 if (my_args->m)
96 {
97 display_minimal_string("FTP control ");
98 display_minimal_string(replycode_str);
99 display_minimal_string(payload+3);
100 }
101 else
102 {
103 display_header_banner("FTP control");
104 display_string("Reply code", replycode_str);
105 display_string("Reply", payload+4);
106 }
107 }
108 else
109 {
110 /* process a reply without a reply code */
111 if (my_args->m)
112 {
113 display_minimal_string("FTP control ");
114 display_minimal_string(payload+3);
115 }
116 else
117 {
118 display_header_banner("FTP control");
119 display_string("Reply", payload);
120 }
121 }
122 }
123 else
124 {
125 /* process a request */
126 u_int8_t * requestcode_str;
127 u_int8_t * ptr;
128
129 /* find the first space, which separates the request code from request */
130 ptr = strchr(payload, ' ');
131 if (!ptr)
132 {
133 /* This is the case where there is nothing following the code */
134 ptr = payload + strlen(payload);
135 requestcode_str = payload;
136 payload = NULL;
137 }
138 else
139 {
140 requestcode_str = my_malloc((ptr - payload) + 1);
141 strncpy(requestcode_str, payload, ptr - payload);
142 requestcode_str[ptr - payload] = '\0';
143 }
144
145 if (my_args->m)
146 {
147 display_minimal_string("FTP control ");
148 display_minimal_string(requestcode_str);
149 display_minimal_string(" ");
150 display_minimal_string(ptr+1);
151 }
152 else
153 {
154 display_header_banner("FTP control");
155 display_string("Request code", requestcode_str);
156 if (payload && ptr)
157 display_string("Request", ptr+1);
158 }
159
160 /* free memory */
161 my_free(requestcode_str);
162 }
163
164 /* free memory */
165 my_free(payload);
166
167 /* dump the hex buffer */
168 hexbuffer_flush();
169
170 }
171