/**************************************************************************** ** File: ftpctrl.c ** ** Author: Mike Borella ** ** Comments: FTP control module. ** ** $Id: ftpctrl.c,v 1.3 2001/11/15 20:15:59 mborella Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU Library General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** *****************************************************************************/ #include "ftpctrl.h" extern struct arg_t * my_args; /*---------------------------------------------------------------------------- ** ** dump_ftpctrl() ** ** Parse and display FTP control packets ** **---------------------------------------------------------------------------- */ void dump_ftpctrl(packet_t *pkt) { u_int8_t * payload; u_int32_t size; u_int8_t * ptr; /* Set the layer */ set_layer(LAYER_APPLICATION); /* find the payload size, then allocate memory and read the packet */ size = get_packet_apparentbytesleft(pkt); if (size <= 0) return; payload = (u_int8_t *) my_malloc (size+1); payload[size] = '\0'; if (get_packet_bytes(payload, pkt, size) == 0) { my_free(payload); return; } /* Get rid of carriage return and line feed at end of payload if it exists */ ptr = payload + strlen(payload); while(1) { ptr --; if (*ptr == 0x0D || *ptr == 0x0A) *ptr = '\0'; else break; } /* * FTP control connections either have commands or response codes. If there * is a response code, then this is a reply, otherwise it is a request. All * response codes are 3 digits long followed by a space. Exception: Some * replies are split over multiple packets and do not have a numeric code * to begin with. * * We determine the direction by looking at the source port. Replies * should always come from the FTP control port. */ if (state_get_srcport() == PORT_FTPCTRL) { if (isdigit(payload[0]) && isdigit(payload[1]) && isdigit(payload[2]) && isspace(payload[3])) { /* process a reply with a reply code */ char replycode_str[4]; int replycode; strncpy(replycode_str, payload, 3); replycode_str[3] = '\0'; replycode = atoi(replycode_str); if (my_args->m) { display_minimal_string("FTP control "); display_minimal_string(replycode_str); display_minimal_string(payload+3); } else { display_header_banner("FTP control"); display_string("Reply code", replycode_str); display_string("Reply", payload+4); } } else { /* process a reply without a reply code */ if (my_args->m) { display_minimal_string("FTP control "); display_minimal_string(payload+3); } else { display_header_banner("FTP control"); display_string("Reply", payload); } } } else { /* process a request */ u_int8_t * requestcode_str; u_int8_t * ptr; /* find the first space, which separates the request code from request */ ptr = strchr(payload, ' '); if (!ptr) { /* This is the case where there is nothing following the code */ ptr = payload + strlen(payload); requestcode_str = payload; payload = NULL; } else { requestcode_str = my_malloc((ptr - payload) + 1); strncpy(requestcode_str, payload, ptr - payload); requestcode_str[ptr - payload] = '\0'; } if (my_args->m) { display_minimal_string("FTP control "); display_minimal_string(requestcode_str); display_minimal_string(" "); display_minimal_string(ptr+1); } else { display_header_banner("FTP control"); display_string("Request code", requestcode_str); if (payload && ptr) display_string("Request", ptr+1); } /* free memory */ my_free(requestcode_str); } /* free memory */ my_free(payload); /* dump the hex buffer */ hexbuffer_flush(); }