#include "ftp_splitter.h"
#include "protocols/ssl.h"
#include "protocols/packet.h"
+#include "utils/util.h"
#include <cstring>
FtpSplitter::FtpSplitter(bool c2s) : StreamSplitter(c2s) { }
-// flush at last line feed in data
+// flush at last CR or LF in data
// preproc will deal with any pipelined commands
StreamSplitter::Status FtpSplitter::scan(
Packet* p, const uint8_t* data, uint32_t len,
uint32_t, uint32_t* fp)
{
- if(IsSSL(data, len, p->packet_flags))
+ if ( IsSSL(data, len, p->packet_flags) )
{
*fp = len;
return FLUSH;
}
-#ifdef HAVE_MEMRCHR
- const uint8_t* lf = (const uint8_t*)memrchr(data, '\n', len);
-#else
- uint32_t n = len;
- const uint8_t* lf = nullptr, * tmp = data;
- while ( (tmp = (const uint8_t*)memchr(tmp, '\n', n)) )
- {
- lf = tmp++;
- n = len - (tmp - data);
- }
-#endif
+ const uint8_t* cr = snort_memrchr(data, '\r', len);
+ const uint8_t* lf = snort_memrchr(data, '\n', len);
+
+ const uint8_t* ptr = nullptr;
+
+ if ( cr && !lf )
+ ptr = cr;
+ else if ( !cr && lf )
+ ptr = lf;
+ else if ( cr && lf )
+ ptr = ( cr > lf ) ? cr : lf;
- if ( !lf )
+ if ( !ptr )
return SEARCH;
- *fp = lf - data + 1;
+ *fp = ptr - data + 1;
return FLUSH;
}
return p;
}
+const uint8_t* snort_memrchr(const uint8_t* buf, char c, size_t len)
+{
+#ifdef HAVE_MEMRCHR
+ return (const uint8_t*)memrchr(buf, c, len);
+#else
+ size_t n = len;
+ const uint8_t* tmp = buf;
+ const uint8_t* ptr = nullptr;
+
+ while ( n > 0 && (tmp = (const uint8_t*)memchr(tmp, c, n)) )
+ {
+ ptr = tmp++;
+ n = len - (tmp - buf);
+ }
+
+ return ptr;
+#endif
+}
+
void ts_print(const struct timeval* tvp, char* timebuf, bool yyyymmdd)
{
struct timeval tv;
SO_PUBLIC const char* get_error(int errnum);
SO_PUBLIC char* snort_strdup(const char*);
SO_PUBLIC char* snort_strndup(const char*, size_t);
+SO_PUBLIC const uint8_t* snort_memrchr(const uint8_t*, char, size_t);
SO_PUBLIC void ts_print(const struct timeval*, char*, bool yyyymmdd = false);
}