summaryrefslogtreecommitdiff
path: root/src/ftp_decoder_util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ftp_decoder_util.cpp')
-rw-r--r--src/ftp_decoder_util.cpp163
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