71 static SCMutex segment_pool_memuse_mutex;
72 static uint64_t segment_pool_memuse = 0;
73 static uint64_t segment_pool_memcnt = 0;
116 BUG_ON(presize > UINT_MAX);
125 BUG_ON(postsize > presize);
149 if (memcapcopy == 0 ||
150 (uint64_t)((uint64_t)size +
SC_ATOMIC_GET(ra_memuse)) <= memcapcopy)
162 if (size == 0 || (uint64_t)
SC_ATOMIC_GET(ra_memuse) < size) {
186 static void *ReassembleMalloc(
size_t size)
200 static void *ReassembleCalloc(
size_t n,
size_t size)
214 static void *ReassembleRealloc(
void *optr,
size_t orig_size,
size_t size)
216 if (size > orig_size) {
224 if (size > orig_size) {
235 static void ReassembleFree(
void *ptr,
size_t size)
242 static void *TcpSegmentPoolAlloc(
void)
256 static int TcpSegmentPoolInit(
void *data,
void *initdata)
271 segment_pool_memcnt++;
272 SCLogDebug(
"segment_pool_memcnt %"PRIu64
"", segment_pool_memcnt);
281 static void TcpSegmentPoolCleanup(
void *ptr)
291 segment_pool_memcnt--;
292 SCLogDebug(
"segment_pool_memcnt %"PRIu64
"", segment_pool_memcnt);
362 static int StreamTcpReassemblyConfig(
char quiet)
364 uint32_t segment_prealloc = 2048;
367 uint32_t prealloc = 0;
371 "%s is invalid", seg->
val);
374 segment_prealloc = prealloc;
377 SCLogConfig(
"stream.reassembly \"segment-prealloc\": %u", segment_prealloc);
380 int overlap_diff_data = 0;
381 ConfGetBool(
"stream.reassembly.check-overlap-different-data", &overlap_diff_data);
382 if (overlap_diff_data) {
404 if (StreamTcpReassemblyConfig(quiet) < 0)
418 if (segment_thread_pool != NULL) {
420 segment_thread_pool = NULL;
426 if (segment_pool_memuse > 0)
427 SCLogInfo(
"segment_pool_memuse %"PRIu64
"", segment_pool_memuse);
428 if (segment_pool_memcnt > 0)
429 SCLogInfo(
"segment_pool_memcnt %"PRIu64
"", segment_pool_memcnt);
446 if (segment_thread_pool == NULL) {
452 TcpSegmentPoolInit, NULL,
453 TcpSegmentPoolCleanup, NULL);
455 SCLogDebug(
"pool size %d, thread segment_thread_pool_id %d",
461 SCLogDebug(
"pool size %d, thread segment_thread_pool_id %d",
522 uint32_t
seq, uint32_t size)
540 SCLogDebug(
"segment entirely before base_seq, weird: base %u, seq %u, re %u",
554 SCLogDebug(
"seq + size %u, base %u, seg_depth %"PRIu64
" limit %u", (
seq + size),
559 SCLogDebug(
"STREAMTCP_STREAM_FLAG_DEPTH_REACHED");
563 SCLogDebug(
"NOT STREAMTCP_STREAM_FLAG_DEPTH_REACHED");
566 SCLogDebug(
"full depth not yet reached: %"PRIu64
" <= %"PRIu32,
567 (stream->base_seq_offset + stream->
base_seq + size),
620 SCLogDebug(
"ssn %p: both app and raw reassembly disabled, not reassembling", ssn);
627 SCLogDebug(
"ssn %p: check depth returned %"PRIu32, ssn, size);
634 SCLogDebug(
"ssn %p: depth reached, not reassembling", ssn);
665 SCLogDebug(
"StreamTcpReassembleInsertSegment failed");
692 if (&ssn->
client == stream) {
709 static int StreamTcpReassembleRawCheckLimit(
const TcpSession *ssn,
715 #define STREAMTCP_STREAM_FLAG_FLUSH_FLAGS \
716 ( STREAMTCP_STREAM_FLAG_DEPTH_REACHED \
717 | STREAMTCP_STREAM_FLAG_TRIGGER_RAW \
718 | STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED)
722 SCLogDebug(
"reassembling now as STREAMTCP_STREAM_FLAG_DEPTH_REACHED "
723 "is set, so not expecting any new data segments");
726 SCLogDebug(
"reassembling now as STREAMTCP_STREAM_FLAG_TRIGGER_RAW is set");
729 SCLogDebug(
"reassembling now as STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED is set, "
730 "so no new segments will be considered");
734 #undef STREAMTCP_STREAM_FLAG_FLUSH_FLAGS
745 if (STREAM_LASTACK_GT_BASESEQ(stream)) {
754 SCLogDebug(
"toserver min chunk len not yet reached: "
755 "last_ack %"PRIu32
", ra_raw_base_seq %"PRIu32
", %"PRIu32
" < "
763 if (STREAM_LASTACK_GT_BASESEQ(stream)) {
773 SCLogDebug(
"toclient min chunk len not yet reached: "
774 "last_ack %"PRIu32
", base_seq %"PRIu32
", %"PRIu32
" < "
793 const char *dirstr = NULL;
822 SCLogDebug(
"%s: app %"PRIu64
" (use: %s), raw %"PRIu64
" (use: %s). Stream right edge: %"PRIu64,
829 SCLogDebug(
"%s: STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION", dirstr);
835 SCLogDebug(
"%s: STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION", dirstr);
840 SCLogDebug(
"%s: STREAM_HAS_UNPROCESSED_SEGMENTS_NONE", dirstr);
845 static uint64_t GetStreamSize(
TcpStream *stream)
857 SCLogDebug(
"size %"PRIu64
", cnt %"PRIu32, size, cnt);
867 size = GetStreamSize(&ssn->
client);
868 size += GetStreamSize(&ssn->
server);
883 for ( ; blk != NULL; blk = SBB_RB_NEXT(blk)) {
893 static inline uint64_t GetAbsLastAck(
const TcpStream *stream)
895 if (STREAM_LASTACK_GT_BASESEQ(stream)) {
907 GetAbsLastAck(stream) >= (cur_blk->
offset + cur_blk->
len)) {
922 static bool GetAppBuffer(
TcpStream *stream,
const uint8_t **data, uint32_t *data_len,
923 uint64_t
offset,
const bool check_for_gap)
925 const uint8_t *mydata;
927 bool gap_ahead =
false;
935 *data_len = mydata_len;
949 gap_ahead = check_for_gap && GapAhead(stream, blk);
953 SCLogDebug(
"gap, want data at offset %"PRIu64
", "
954 "got data at %"PRIu64
". GAP of size %"PRIu64,
961 SCLogDebug(
"get data from offset %"PRIu64
". SBB %"PRIu64
"/%u",
964 SCLogDebug(
"data %p, data_len %u", *data, *data_len);
966 gap_ahead = check_for_gap && GapAhead(stream, blk);
986 if (STREAM_LASTACK_GT_BASESEQ(stream)) {
990 last_ack_abs += delta;
993 last_ack_abs -= ackadded;
1000 if (last_ack_abs > app_progress) {
1007 "next_seq %u < last_ack %u, but no data in list",
1013 if (blk->
offset > next_seq_abs && blk->
offset < last_ack_abs) {
1016 "next_seq %u < last_ack %u, but ACK'd data beyond gap.",
1024 "last_ack_abs %"PRIu64
" > app_progress %"PRIu64
", "
1025 "but we have no data.",
1026 p->
pcap_cnt, last_ack_abs, app_progress);
1031 "last_ack_abs %"PRIu64
" <= app_progress %"PRIu64,
1032 p->
pcap_cnt, last_ack_abs, app_progress);
1036 static inline uint32_t AdjustToAcked(
const Packet *p,
1038 const uint64_t app_progress,
const uint32_t data_len)
1040 uint32_t adjusted = data_len;
1052 if (STREAM_LASTACK_GT_BASESEQ(stream)) {
1056 last_ack_abs += delta;
1061 if (app_progress <= last_ack_abs && app_progress + data_len > last_ack_abs) {
1062 uint32_t check = data_len;
1063 adjusted = last_ack_abs - app_progress;
1064 BUG_ON(adjusted > check);
1065 SCLogDebug(
"data len adjusted to %u to make sure only ACK'd "
1066 "data is considered", adjusted);
1085 SCLogDebug(
"app progress %"PRIu64, app_progress);
1086 SCLogDebug(
"last_ack %u, base_seq %u", (*stream)->last_ack, (*stream)->base_seq);
1088 const uint8_t *mydata;
1089 uint32_t mydata_len;
1090 bool gap_ahead =
false;
1091 bool last_was_gap =
false;
1094 const uint8_t
flags = StreamGetAppLayerFlags(ssn, *stream, p);
1095 bool check_for_gap_ahead = ((*stream)->data_required > 0);
1096 gap_ahead = GetAppBuffer(*stream, &mydata, &mydata_len,
1097 app_progress, check_for_gap_ahead);
1098 if (last_was_gap && mydata_len == 0) {
1101 last_was_gap =
false;
1104 mydata_len = AdjustToAcked(p, ssn, *stream, app_progress, mydata_len);
1106 if (mydata == NULL && mydata_len > 0 && CheckGap(ssn, *stream, p)) {
1107 SCLogDebug(
"sending GAP to app-layer (size: %u)", mydata_len);
1111 StreamGetAppLayerFlags(ssn, *stream, p)|
STREAM_GAP);
1112 AppLayerProfilingStore(ra_ctx->
app_tctx, p);
1123 if ((*stream)->data_required > 0) {
1124 if ((*stream)->data_required > mydata_len) {
1125 (*stream)->data_required -= mydata_len;
1127 (*stream)->data_required = 0;
1132 if (no_progress_update)
1134 last_was_gap =
true;
1140 }
else if (mydata == NULL || (mydata_len == 0 && ((
flags &
STREAM_EOF) == 0))) {
1151 SCLogDebug(
"stream %p data in buffer %p of len %u and offset %"PRIu64,
1152 *stream, &(*stream)->sb, mydata_len, app_progress);
1155 if (mydata_len < (*stream)->data_required) {
1157 SCLogDebug(
"GAP while expecting more data (expect %u, gap size %u)",
1158 (*stream)->data_required, mydata_len);
1159 (*stream)->app_progress_rel += mydata_len;
1160 (*stream)->data_required -= mydata_len;
1170 (*stream)->data_required = 0;
1174 (uint8_t *)mydata, mydata_len,
flags);
1175 AppLayerProfilingStore(ra_ctx->
app_tctx, p);
1179 app_progress = new_app_progress;
1209 SCLogDebug(
"stream no reassembly flag set or app-layer disabled.");
1215 GetSessionSize(ssn, p);
1228 StreamGetAppLayerFlags(ssn, stream, p));
1229 AppLayerProfilingStore(ra_ctx->
app_tctx, p);
1236 return ReassembleUpdateAppLayer(
tv, ra_ctx, ssn, &stream, p, dir);
1242 static int GetRawBuffer(
TcpStream *stream,
const uint8_t **data, uint32_t *data_len,
1245 const uint8_t *mydata;
1246 uint32_t mydata_len;
1250 uint64_t roffset =
offset;
1258 *data_len = mydata_len;
1259 *data_offset = roffset;
1261 SCLogDebug(
"multiblob %s. Want offset %"PRIu64,
1262 *iter == NULL ?
"starting" :
"continuing",
offset);
1263 if (*iter == NULL) {
1268 if (*iter == NULL) {
1275 SCLogDebug(
"getting multiple blobs. Iter %p, %"PRIu64
"/%u", *iter, (*iter)->offset, (*iter)->len);
1280 if ((*iter)->offset <
offset) {
1281 uint64_t delta =
offset - (*iter)->offset;
1282 if (delta < mydata_len) {
1283 *data = mydata + delta;
1284 *data_len = mydata_len - delta;
1295 *data_len = mydata_len;
1296 *data_offset = (*iter)->offset;
1299 *iter = SBB_RB_NEXT(*iter);
1333 if (StreamTcpReassembleRawCheckLimit(ssn, stream, p) == 1) {
1382 uint64_t tcp_window = stream->
window;
1392 }
else if (progress == 0) {
1393 uint64_t tcp_window = stream->
window;
1395 if (tcp_window < stream_right_edge) {
1396 uint64_t new_raw = stream_right_edge - tcp_window;
1405 SCLogDebug(
"p->pcap_cnt %"PRIu64
": progress %"PRIu64
" app %"PRIu64
" raw %"PRIu64
" tcp win %"PRIu32,
1414 SCLogDebug(
"ssn %p: STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED set, "
1415 "now that detect ran also set STREAMTCP_STREAM_FLAG_DISABLE_RAW", ssn);
1461 SCLogDebug(
"packet payload len %u, so chunk_size adjusted to %u",
1463 }
else if (((chunk_size / 3 ) * 2) < p->
payload_len) {
1465 SCLogDebug(
"packet payload len %u, so chunk_size adjusted to %u",
1470 uint64_t packet_rightedge_abs = packet_leftedge_abs + p->
payload_len;
1471 SCLogDebug(
"packet_leftedge_abs %"PRIu64
", rightedge %"PRIu64,
1472 packet_leftedge_abs, packet_rightedge_abs);
1474 const uint8_t *mydata = NULL;
1475 uint32_t mydata_len = 0;
1476 uint64_t mydata_offset = 0;
1478 bool return_progress =
false;
1483 return_progress =
true;
1486 SCLogDebug(
"finding our SBB from offset %"PRIu64, packet_leftedge_abs);
1493 mydata_offset = sbb->
offset;
1498 uint64_t mydata_rightedge_abs = mydata_offset + mydata_len;
1499 if ((mydata == NULL || mydata_len == 0) ||
1500 (mydata_offset >= packet_rightedge_abs ||
1501 packet_leftedge_abs >= mydata_rightedge_abs) ||
1502 (packet_leftedge_abs < mydata_offset ||
1503 packet_rightedge_abs > mydata_rightedge_abs))
1508 mydata_offset = packet_leftedge_abs;
1512 SCLogDebug(
"chunk_size %u mydata_len %u", chunk_size, mydata_len);
1513 if (mydata_len > chunk_size) {
1514 uint32_t excess = mydata_len - chunk_size;
1515 SCLogDebug(
"chunk_size %u mydata_len %u excess %u", chunk_size, mydata_len, excess);
1517 if (mydata_rightedge_abs == packet_rightedge_abs) {
1519 mydata_len -= excess;
1520 mydata_offset += excess;
1521 SCLogDebug(
"cutting front of the buffer with %u", excess);
1522 }
else if (mydata_offset == packet_leftedge_abs) {
1523 mydata_len -= excess;
1524 SCLogDebug(
"cutting tail of the buffer with %u", excess);
1526 uint32_t before = (uint32_t)(packet_leftedge_abs - mydata_offset);
1527 uint32_t after = (uint32_t)(mydata_rightedge_abs - packet_rightedge_abs);
1528 SCLogDebug(
"before %u after %u", before, after);
1533 if (before >= (chunk_size - p->
payload_len) / 2) {
1535 before = after = (chunk_size - p->
payload_len) / 2;
1544 if (before >= (chunk_size - p->
payload_len) / 2) {
1552 uint32_t skip = (uint32_t)(packet_leftedge_abs - mydata_offset) - before;
1553 uint32_t cut = (uint32_t)(mydata_rightedge_abs - packet_rightedge_abs) - after;
1558 mydata_len -= (skip + cut);
1559 mydata_offset += skip;
1565 r = Callback(cb_data, mydata, mydata_len);
1568 if (return_progress) {
1569 *progress_out = (mydata_offset + mydata_len);
1577 if (STREAM_LASTACK_GT_BASESEQ(stream)) {
1580 last_ack_abs += delta;
1582 SCLogDebug(
"last_ack_abs %"PRIu64, last_ack_abs);
1585 if (mydata_offset > last_ack_abs) {
1587 *progress_out = last_ack_abs;
1589 *progress_out = (mydata_offset + mydata_len);
1631 const uint64_t progress_in,
1632 uint64_t *progress_out,
bool eof,
1633 bool respect_inspect_depth)
1639 uint64_t progress = progress_in;
1647 SCLogDebug(
"respect_inspect_depth %s STREAMTCP_STREAM_FLAG_TRIGGER_RAW %s stream->min_inspect_depth %u",
1648 respect_inspect_depth ?
"true" :
"false",
1652 if (respect_inspect_depth &&
1666 SCLogDebug(
"applied min inspect depth due to STREAMTCP_STREAM_FLAG_TRIGGER_RAW: progress %"PRIu64, progress);
1672 if (STREAM_LASTACK_GT_BASESEQ(stream)) {
1676 last_ack_abs += delta;
1677 SCLogDebug(
"last_ack_abs %"PRIu64, last_ack_abs);
1683 const uint8_t *mydata;
1684 uint32_t mydata_len;
1685 uint64_t mydata_offset = 0;
1687 GetRawBuffer(stream, &mydata, &mydata_len, &iter, progress, &mydata_offset);
1688 if (mydata_len == 0) {
1694 SCLogDebug(
"raw progress %"PRIu64, progress);
1695 SCLogDebug(
"stream %p data in buffer %p of len %u and offset %"PRIu64,
1696 stream, &stream->
sb, mydata_len, progress);
1701 if (last_ack_abs < progress) {
1706 SCLogDebug(
"last_ack_abs %"PRIu64
", raw_progress %"PRIu64, last_ack_abs, progress);
1707 SCLogDebug(
"raw_progress + mydata_len %"PRIu64
", last_ack_abs %"PRIu64, progress + mydata_len, last_ack_abs);
1710 if (progress + mydata_len > last_ack_abs) {
1711 uint32_t check = mydata_len;
1712 mydata_len = last_ack_abs - progress;
1713 BUG_ON(check < mydata_len);
1714 SCLogDebug(
"data len adjusted to %u to make sure only ACK'd "
1715 "data is considered", mydata_len);
1719 if (mydata_len == 0)
1722 SCLogDebug(
"data %p len %u", mydata, mydata_len);
1725 r = Callback(cb_data, mydata, mydata_len);
1728 if (mydata_offset == progress) {
1729 SCLogDebug(
"progress %"PRIu64
" increasing with data len %u to %"PRIu64,
1730 progress, mydata_len, progress_in + mydata_len);
1732 progress += mydata_len;
1733 SCLogDebug(
"raw progress now %"PRIu64, progress);
1736 }
else if (mydata_offset > progress && mydata_offset < last_ack_abs) {
1737 SCLogDebug(
"GAP: data is missing from %"PRIu64
" (%u bytes), setting to first data we have: %"PRIu64, progress, (uint32_t)(mydata_offset - progress), mydata_offset);
1738 SCLogDebug(
"last_ack_abs %"PRIu64, last_ack_abs);
1739 progress = mydata_offset;
1740 SCLogDebug(
"raw progress now %"PRIu64, progress);
1743 SCLogDebug(
"not increasing progress, data gap => mydata_offset "
1744 "%"PRIu64
" != progress %"PRIu64, mydata_offset, progress);
1747 if (iter == NULL || r == 1)
1751 *progress_out = progress;
1757 uint64_t *progress_out,
bool respect_inspect_depth)
1761 return StreamReassembleRawInline(ssn, p, Callback, cb_data, progress_out);
1772 StreamTcpReassembleRawCheckLimit(ssn, stream, p) == 0)
1778 return StreamReassembleRawDo(ssn, stream, Callback, cb_data,
1785 uint64_t progress_in,
1786 uint64_t *progress_out,
bool eof)
1791 return StreamReassembleRawDo(ssn, stream, Callback, cb_data,
1792 progress_in, progress_out, eof,
false);
1800 static int StreamTcpReassembleHandleSegmentUpdateACK (
ThreadVars *
tv,
1819 SCLogDebug(
"ssn %p, stream %p, p %p, p->payload_len %"PRIu16
"",
1842 if (stream == &ssn->
client) {
1843 opposing_stream = &ssn->
server;
1845 opposing_stream = &ssn->
client;
1850 if (StreamTcpReassembleHandleSegmentUpdateACK(
tv, ra_ctx, ssn, opposing_stream, p) != 0) {
1851 SCLogDebug(
"StreamTcpReassembleHandleSegmentUpdateACK error");
1859 if (reversed_before_ack_handling != reversed_after_ack_handling) {
1861 stream = opposing_stream;
1866 SCLogDebug(
"calling StreamTcpReassembleHandleSegmentHandleData");
1869 SCLogDebug(
"StreamTcpReassembleHandleSegmentHandleData error");
1876 SCLogDebug(
"ssn %p / stream %p: not calling StreamTcpReassembleHandleSegmentHandleData:"
1877 " p->payload_len %u, STREAMTCP_STREAM_FLAG_NOREASSEMBLY %s",
1888 if ((stream->
flags &
1892 SCLogDebug(
"STREAMTCP_STREAM_FLAG_DEPTH_REACHED, truncate applayer");
1894 SCLogDebug(
"override: direction now UPDATE_DIR_PACKET so we "
1895 "can trigger Truncate");
1903 SCLogDebug(
"inline (%s) or PKT_PSEUDO_STREAM_END (%s)",
1959 SCLogDebug(
"flagged ssn %p for immediate raw reassembly", ssn);
1972 SCLogDebug(
"ssn %p: set client.min_inspect_depth to %u", ssn, depth);
1975 SCLogDebug(
"ssn %p: set server.min_inspect_depth to %u", ssn, depth);
1983 #define SET_ISN(stream, setseq) \
1984 (stream)->isn = (setseq); \
1985 (stream)->base_seq = (setseq) + 1
2003 for (; i <
len; i++)
2024 static int VALIDATE(
TcpStream *stream, uint8_t *data, uint32_t data_len)
2027 data, data_len) == 0)
2036 #define MISSED_START(isn) \
2037 TcpReassemblyThreadCtx *ra_ctx = NULL; \
2040 memset(&tv, 0, sizeof(tv)); \
2042 StreamTcpUTInit(&ra_ctx); \
2044 StreamTcpUTSetupSession(&ssn); \
2045 StreamTcpUTSetupStream(&ssn.server, (isn)); \
2046 StreamTcpUTSetupStream(&ssn.client, (isn)); \
2048 TcpStream *stream = &ssn.client;
2050 #define MISSED_END \
2051 StreamTcpUTClearSession(&ssn); \
2052 StreamTcpUTDeinit(ra_ctx); \
2055 #define MISSED_STEP(seq, seg, seglen, buf, buflen) \
2056 StreamTcpUTAddPayload(&tv, ra_ctx, &ssn, stream, (seq), (uint8_t *)(seg), (seglen)); \
2057 FAIL_IF(!(VALIDATE(stream, (uint8_t *)(buf), (buflen))));
2066 static int StreamTcpReassembleTest25 (
void)
2082 static int StreamTcpReassembleTest26 (
void)
2098 static int StreamTcpReassembleTest27 (
void)
2115 static int StreamTcpReassembleTest28 (
void)
2133 static int StreamTcpReassembleTest29 (
void)
2142 static int StreamTcpReassembleTest33(
void)
2151 uint8_t packet[1460] =
"";
2158 memset(&f, 0,
sizeof (
Flow));
2159 memset(&tcph, 0,
sizeof (TCPHdr));
2164 f.
proto = IPPROTO_TCP;
2167 p->
proto = IPPROTO_TCP;
2175 p->
tcph->th_seq = htonl(10);
2176 p->
tcph->th_ack = htonl(31);
2181 p->
tcph->th_seq = htonl(20);
2182 p->
tcph->th_ack = htonl(31);
2187 p->
tcph->th_seq = htonl(40);
2188 p->
tcph->th_ack = htonl(31);
2193 p->
tcph->th_seq = htonl(5);
2194 p->
tcph->th_ack = htonl(31);
2205 static int StreamTcpReassembleTest34(
void)
2214 uint8_t packet[1460] =
"";
2220 memset(&f, 0,
sizeof (
Flow));
2221 memset(&tcph, 0,
sizeof (TCPHdr));
2226 f.
proto = IPPROTO_TCP;
2229 p->
proto = IPPROTO_TCP;
2238 p->
tcph->th_seq = htonl(857961230);
2239 p->
tcph->th_ack = htonl(31);
2244 p->
tcph->th_seq = htonl(857961534);
2245 p->
tcph->th_ack = htonl(31);
2250 p->
tcph->th_seq = htonl(857963582);
2251 p->
tcph->th_ack = htonl(31);
2256 p->
tcph->th_seq = htonl(857960946);
2257 p->
tcph->th_ack = htonl(31);
2269 static int StreamTcpReassembleTest37(
void)
2275 uint8_t packet[1460] =
"";
2286 memset(&f, 0,
sizeof (
Flow));
2287 memset(&tcph, 0,
sizeof (TCPHdr));
2292 f.
proto = IPPROTO_TCP;
2295 p->
proto = IPPROTO_TCP;
2304 p->
tcph->th_seq = htonl(3061088537UL);
2305 p->
tcph->th_ack = htonl(1729548549UL);
2313 p->
tcph->th_seq = htonl(3061089928UL);
2314 p->
tcph->th_ack = htonl(1729548549UL);
2320 p->
tcph->th_seq = htonl(3061091319UL);
2321 p->
tcph->th_ack = htonl(1729548549UL);
2341 static int StreamTcpReassembleTest39 (
void)
2351 memset (&f, 0,
sizeof(
Flow));
2353 memset(&stt, 0,
sizeof (stt));
2354 memset(&tcph, 0,
sizeof (TCPHdr));
2358 f.
proto = IPPROTO_TCP;
2365 tcph.th_win = htons(5480);
2390 p->
tcph->th_ack = htonl(1);
2411 p->
tcph->th_ack = htonl(1);
2412 p->
tcph->th_seq = htonl(1);
2433 uint8_t request1[] = { 0x47, 0x45, };
2434 p->
tcph->th_ack = htonl(1);
2435 p->
tcph->th_seq = htonl(1);
2457 p->
tcph->th_ack = htonl(3);
2458 p->
tcph->th_seq = htonl(1);
2480 uint8_t request2[] = {
2481 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2482 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2483 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2484 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2485 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2486 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2487 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2488 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2489 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2490 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2491 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2492 p->
tcph->th_ack = htonl(1);
2493 p->
tcph->th_seq = htonl(3);
2516 uint8_t response[] = {
2517 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2518 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2519 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2520 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2521 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2522 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2523 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2524 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2525 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2526 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2527 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2528 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2529 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2530 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2531 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2532 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2533 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2534 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2535 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2536 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2537 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2538 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2539 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2540 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2541 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2542 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2543 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2544 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2545 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2546 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2547 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2548 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2549 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2550 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2551 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2552 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2553 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2554 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2555 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2556 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2557 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2558 p->
tcph->th_ack = htonl(88);
2559 p->
tcph->th_seq = htonl(1);
2583 p->
tcph->th_ack = htonl(328);
2584 p->
tcph->th_seq = htonl(88);
2608 p->
tcph->th_ack = htonl(88);
2609 p->
tcph->th_seq = htonl(328);
2633 p->
tcph->th_ack = htonl(328);
2634 p->
tcph->th_seq = htonl(88);
2657 p->
tcph->th_ack = htonl(88);
2658 p->
tcph->th_seq = htonl(328);
2683 p->
tcph->th_ack = htonl(328);
2684 p->
tcph->th_seq = htonl(88);
2708 p->
tcph->th_ack = htonl(90);
2709 p->
tcph->th_seq = htonl(328);
2734 p->
tcph->th_ack = htonl(328);
2735 p->
tcph->th_seq = htonl(90);
2760 p->
tcph->th_ack = htonl(175);
2761 p->
tcph->th_seq = htonl(328);
2787 p->
tcph->th_ack = htonl(175);
2788 p->
tcph->th_seq = htonl(328);
2804 p->
tcph->th_ack = htonl(328);
2805 p->
tcph->th_seq = htonl(175);
2825 static int StreamTcpReassembleTest40 (
void)
2834 memset(&tcph, 0,
sizeof (TCPHdr));
2844 uint8_t httpbuf1[] =
"P";
2845 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2846 uint8_t httpbuf3[] =
"O";
2847 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
2848 uint8_t httpbuf4[] =
"S";
2849 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
2850 uint8_t httpbuf5[] =
"T \r\n";
2851 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
2853 uint8_t httpbuf2[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
2854 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
2861 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 200, 220);
2864 f->
proto = IPPROTO_TCP;
2867 tcph.th_win = htons(5480);
2868 tcph.th_seq = htonl(10);
2869 tcph.th_ack = htonl(10);
2883 tcph.th_seq = htonl(10);
2884 tcph.th_ack = htonl(11);
2893 tcph.th_seq = htonl(11);
2894 tcph.th_ack = htonl(55);
2903 tcph.th_seq = htonl(55);
2904 tcph.th_ack = htonl(12);
2918 tcph.th_seq = htonl(12);
2919 tcph.th_ack = htonl(100);
2928 tcph.th_seq = htonl(100);
2929 tcph.th_ack = htonl(13);
2938 tcph.th_seq = htonl(13);
2939 tcph.th_ack = htonl(145);
2948 tcph.th_seq = htonl(145);
2949 tcph.th_ack = htonl(16);
2965 static int StreamTcpReassembleTest44(
void)
2986 static int StreamTcpReassembleTest45 (
void)
2991 memset(&
tv, 0,
sizeof(
tv));
2992 uint8_t payload[100] = {0};
2993 uint16_t payload_size = 100;
3024 static int StreamTcpReassembleTest46 (
void)
3030 memset(&
tv, 0,
sizeof(
tv));
3031 uint8_t payload[100] = {0};
3032 uint16_t payload_size = 100;
3045 printf(
"STREAMTCP_STREAM_FLAG_NOREASSEMBLY set: ");
3053 printf(
"STREAMTCP_STREAM_FLAG_NOREASSEMBLY set: ");
3073 static int StreamTcpReassembleTest47 (
void)
3083 memset(&tcph, 0,
sizeof (TCPHdr));
3089 uint8_t httpbuf1[] =
"GET /EVILSUFF HTTP/1.1\r\n\r\n";
3090 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3098 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 200, 220);
3101 f->
proto = IPPROTO_TCP;
3104 tcph.th_win = htons(5480);
3109 for (cnt=0; cnt < httplen1; cnt++) {
3110 tcph.th_seq = htonl(ssn.
client.
isn + 1 + cnt);
3111 tcph.th_ack = htonl(572799782UL);
3124 tcph.th_seq = htonl(572799782UL);
3125 tcph.th_ack = htonl(ssn.
client.
isn + 1 + cnt);
3144 static int StreamTcpReassembleInlineTest01(
void)
3152 memset(&
tv, 0x00,
sizeof(
tv));
3160 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3163 printf(
"couldn't get a packet: ");
3166 p->
tcph->th_seq = htonl(12);
3171 printf(
"failed to add segment 1: ");
3175 printf(
"failed to add segment 2: ");
3179 printf(
"failed to add segment 3: ");
3196 static int StreamTcpReassembleInlineTest02(
void)
3204 memset(&
tv, 0x00,
sizeof(
tv));
3212 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3215 printf(
"couldn't get a packet: ");
3218 p->
tcph->th_seq = htonl(12);
3223 printf(
"failed to add segment 1: ");
3227 printf(
"failed to add segment 2: ");
3231 printf(
"failed to add segment 3: ");
3236 printf(
"failed to add segment 4: ");
3254 static int StreamTcpReassembleInlineTest03(
void)
3262 memset(&
tv, 0x00,
sizeof(
tv));
3272 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3275 printf(
"couldn't get a packet: ");
3278 p->
tcph->th_seq = htonl(12);
3284 printf(
"failed to add segment 1: ");
3288 printf(
"failed to add segment 2: ");
3292 printf(
"failed to add segment 3: ");
3297 printf(
"failed to add segment 4: ");
3302 p->
tcph->th_seq = htonl(17);
3317 static int StreamTcpReassembleInlineTest04(
void)
3325 memset(&
tv, 0x00,
sizeof(
tv));
3335 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3338 printf(
"couldn't get a packet: ");
3341 p->
tcph->th_seq = htonl(12);
3347 printf(
"failed to add segment 1: ");
3351 printf(
"failed to add segment 2: ");
3355 printf(
"failed to add segment 3: ");
3360 printf(
"failed to add segment 4: ");
3365 p->
tcph->th_seq = htonl(17);
3381 static int StreamTcpReassembleInlineTest08(
void)
3385 memset(&
tv, 0x00,
sizeof(
tv));
3397 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3400 p->
tcph->th_seq = htonl(12);
3410 p->
tcph->th_seq = htonl(17);
3429 static int StreamTcpReassembleInlineTest09(
void)
3437 memset(&
tv, 0x00,
sizeof(
tv));
3447 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3450 printf(
"couldn't get a packet: ");
3453 p->
tcph->th_seq = htonl(17);
3459 printf(
"failed to add segment 1: ");
3463 printf(
"failed to add segment 2: ");
3467 printf(
"failed to add segment 3: ");
3475 printf(
"failed to add segment 4: ");
3480 p->
tcph->th_seq = htonl(12);
3498 static int StreamTcpReassembleInlineTest10(
void)
3507 memset(&
tv, 0x00,
sizeof(
tv));
3518 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3522 f->
proto = IPPROTO_TCP;
3524 uint8_t stream_payload1[] =
"GE";
3525 uint8_t stream_payload2[] =
"T /";
3526 uint8_t stream_payload3[] =
"HTTP/1.0\r\n\r\n";
3528 p =
UTHBuildPacketReal(stream_payload3, 12, IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3530 printf(
"couldn't get a packet: ");
3533 p->
tcph->th_seq = htonl(7);
3539 printf(
"failed to add segment 1: ");
3546 printf(
"StreamTcpReassembleAppLayer failed: ");
3552 printf(
"expected ra_app_base_seq 1, got %u: ", ssn.
client.
base_seq);
3557 printf(
"failed to add segment 2: ");
3561 printf(
"failed to add segment 3: ");
3568 printf(
"StreamTcpReassembleAppLayer failed: ");
3586 static int StreamTcpReassembleInsertTest01(
void)
3593 memset(&
tv, 0x00,
sizeof(
tv));
3601 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3604 p->
tcph->th_seq = htonl(12);
3623 static int StreamTcpReassembleInsertTest02(
void)
3630 memset(&
tv, 0x00,
sizeof(
tv));
3637 for (i = 2; i < 10; i++) {
3648 printf(
"failed to add segment 1: ");
3653 printf(
"failed to add segment 2: ");
3666 static int StreamTcpReassembleInsertTest03(
void)
3673 memset(&
tv, 0x00,
sizeof(
tv));
3680 printf(
"failed to add segment 2: ");
3685 for (i = 2; i < 10; i++) {
3696 printf(
"failed to add segment 2: ");
3717 UtRegisterTest(
"StreamTcpReassembleTest25 -- Gap at Start Reassembly Test",
3718 StreamTcpReassembleTest25);
3719 UtRegisterTest(
"StreamTcpReassembleTest26 -- Gap at middle Reassembly Test",
3720 StreamTcpReassembleTest26);
3721 UtRegisterTest(
"StreamTcpReassembleTest27 -- Gap at after Reassembly Test",
3722 StreamTcpReassembleTest27);
3723 UtRegisterTest(
"StreamTcpReassembleTest28 -- Gap at Start IDS missed packet Reassembly Test",
3724 StreamTcpReassembleTest28);
3725 UtRegisterTest(
"StreamTcpReassembleTest29 -- Gap at Middle IDS missed packet Reassembly Test",
3726 StreamTcpReassembleTest29);
3728 StreamTcpReassembleTest33);
3730 StreamTcpReassembleTest34);
3732 StreamTcpReassembleTest37);
3734 StreamTcpReassembleTest39);
3736 StreamTcpReassembleTest40);
3738 StreamTcpReassembleTest44);
3740 StreamTcpReassembleTest45);
3742 StreamTcpReassembleTest46);
3743 UtRegisterTest(
"StreamTcpReassembleTest47 -- TCP Sequence Wraparound Test",
3744 StreamTcpReassembleTest47);
3746 UtRegisterTest(
"StreamTcpReassembleInlineTest01 -- inline RAW ra",
3747 StreamTcpReassembleInlineTest01);
3748 UtRegisterTest(
"StreamTcpReassembleInlineTest02 -- inline RAW ra 2",
3749 StreamTcpReassembleInlineTest02);
3750 UtRegisterTest(
"StreamTcpReassembleInlineTest03 -- inline RAW ra 3",
3751 StreamTcpReassembleInlineTest03);
3752 UtRegisterTest(
"StreamTcpReassembleInlineTest04 -- inline RAW ra 4",
3753 StreamTcpReassembleInlineTest04);
3754 UtRegisterTest(
"StreamTcpReassembleInlineTest08 -- inline RAW ra 8 cleanup",
3755 StreamTcpReassembleInlineTest08);
3756 UtRegisterTest(
"StreamTcpReassembleInlineTest09 -- inline RAW ra 9 GAP cleanup",
3757 StreamTcpReassembleInlineTest09);
3759 UtRegisterTest(
"StreamTcpReassembleInlineTest10 -- inline APP ra 10",
3760 StreamTcpReassembleInlineTest10);
3762 UtRegisterTest(
"StreamTcpReassembleInsertTest01 -- insert with overlap",
3763 StreamTcpReassembleInsertTest01);
3764 UtRegisterTest(
"StreamTcpReassembleInsertTest02 -- insert with overlap",
3765 StreamTcpReassembleInsertTest02);
3766 UtRegisterTest(
"StreamTcpReassembleInsertTest03 -- insert with overlap",
3767 StreamTcpReassembleInsertTest03);
3772 StreamTcpReassembleRawRegisterTests();