diff options
Diffstat (limited to 'src/ftp_decoder_util.cpp')
| -rw-r--r-- | src/ftp_decoder_util.cpp | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/src/ftp_decoder_util.cpp b/src/ftp_decoder_util.cpp new file mode 100644 index 0000000..8956887 --- /dev/null +++ b/src/ftp_decoder_util.cpp @@ -0,0 +1,163 @@ +#include "ftp_decoder_inner.h" +#include "ftp_decoder.h" +#include "ftp_decoder_util.h" +#include <ctype.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <libgen.h> + +void fstring_dup(const fstring *src, fstring *dst) +{ + dst->iov_base = (char *)malloc(src->iov_len); + assert(dst->iov_base); + memcpy((void *)dst->iov_base, src->iov_base, src->iov_len); + dst->iov_len = src->iov_len; +} +void fstring_safe_dup(const fstring *src, fstring *dst) +{ + if (dst->iov_base) + { + free(dst->iov_base); // free it if exist + } + fstring_dup(src, dst); +} + +void ftp_parse_result_free(struct ftp_parse_result *parse_result) +{ + for (int i = 0; i < FTP_MSG_MAX; i++) + { + if (i != FTP_INVENTORY && i != FTP_FILE_CONTENT) + { + if (parse_result->result_array[i].iov_base) + { + free(parse_result->result_array[i].iov_base); + } + } + } +} + +static void ftp_str_split(const char *payload, size_t len, fstring *left, fstring *rigth, int delim) +{ + const char *p = (char *)memchr(payload, delim, len); + if (NULL == p) + { + left->iov_base = (char *)payload; + left->iov_len = len; + rigth->iov_base = NULL; + rigth->iov_len = 0; + } + else + { + left->iov_base = (char *)payload; + left->iov_len = p - payload; + rigth->iov_base = (char *)p + 1; + rigth->iov_len = len - left->iov_len - 1; + } +} + +long ftp_skip_tail_crlf(const char *payload, long len) +{ + long new_len = 0; + for (long i = 0; i < len; i++, new_len++) + { + if ((payload[i] == '\r' || payload[i] == '\n')) + { + break; + } + } + return new_len; +} + +int ftp_cmd_readline(struct ftp_interact_line *line, const char *payload, size_t len) +{ + memset(line, 0, sizeof(struct ftp_interact_line)); + long skip_crlf_len = ftp_skip_tail_crlf(payload, len); + ftp_str_split(payload, skip_crlf_len, &line->cmd_refer, &line->arg_refer, ' '); + return 0; +} + +void ftp_strtolower(char *str, size_t len) +{ + for (size_t i = 0; i < len; i++) + { + str[i] = tolower(str[i]); + } +} + +int ftp_mkdir_p(const char *path, mode_t mode) +{ + struct stat st; + errno = 0; + + /* Try to make the directory */ + if (mkdir(path, mode) == 0) + return 0; + + /* If it fails for any reason but EEXIST, fail */ + if (errno != EEXIST) + return -1; + + /* Check if the existing path is a directory */ + if (stat(path, &st) != 0) + return -1; + + /* If not, fail with ENOTDIR */ + if (!S_ISDIR(st.st_mode)) + { + errno = ENOTDIR; + return -1; + } + + errno = 0; + return 0; +} + +int ftp_session_get_pkt_dir(struct session *sess) +{ + const struct packet *pkt = session_get0_current_packet(sess); + if (NULL == pkt) + { + return PACKET_DIRECTION_UNKNOWN; + } + return packet_get_direction(pkt); +} + +struct ftp_context *ftp_decoder_context_deep_dup(const struct ftp_context *src) +{ + struct ftp_context *new_ctx = (struct ftp_context *)calloc(1, sizeof(struct ftp_context)); + for (int i = 0; i < FTP_MSG_MAX; i++) + { + if (i != FTP_INVENTORY && i != FTP_FILE_CONTENT) + { + fstring_safe_dup(&src->parse_result.result_array[i], &new_ctx->parse_result.result_array[i]); + } + } + return new_ctx; +} + +const char *ftp_message_type_to_string(enum ftp_msg_type fmsg_type) +{ + switch (fmsg_type) + { + case FTP_BANNER: + return "FTP_BANNER"; + case FTP_ACCOUNT: + return "FTP_ACCOUNT"; + case FTP_PASSWORD: + return "FTP_PASSWORD"; + case FTP_URI: + return "FTP_URI"; + case FTP_TRANS_MODE: + return "FTP_TRANS_MODE"; + case FTP_TRANS_DIR: + return "FTP_TRANS_DIR"; + case FTP_INVENTORY: + return "FTP_INVENTORY"; + case FTP_FILE_CONTENT: + return "FTP_FILE_CONTENT"; + case FTP_MSG_MAX: + return "UNKNOWN"; + } + return "UNKNOWN"; +}
\ No newline at end of file |
