suricata
stream-tcp.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2021 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "../suricata-common.h"
19#include "../stream-tcp-private.h"
20#include "../stream-tcp.h"
21#include "../stream-tcp-reassemble.h"
22#include "../stream-tcp-inline.h"
23#include "../stream-tcp-list.h"
24#include "../stream-tcp-util.h"
25#include "../util-streaming-buffer.h"
26#include "../util-print.h"
27#include "../util-unittest.h"
28#include "../util-unittest-helper.h"
29
30#define SET_ISN(stream, setseq) \
31 (stream)->isn = (setseq); \
32 (stream)->base_seq = (setseq) + 1
33
34/**
35 * \test Test the allocation of TCP session for a given packet from the
36 * ssn_pool.
37 *
38 * \retval On success it returns 1 and on failure 0.
39 */
40
41static int StreamTcpTest01(void)
42{
44 TCPHdr tcph;
45 memset(&tcph, 0, sizeof(TCPHdr));
47 FAIL_IF_NULL(p);
48 UTHSetTCPHdr(p, &tcph);
49 Flow f;
50 memset(&f, 0, sizeof(Flow));
52 p->flow = &f;
54 TcpSession *ssn = StreamTcpNewSession(NULL, &stt, p, 0);
55 FAIL_IF_NULL(ssn);
56 f.protoctx = ssn;
58 FAIL_IF_NOT(ssn->state == 0);
60 SCFree(p);
61 FLOW_DESTROY(&f);
63 PASS;
64}
65
66/**
67 * \test Test the deallocation of TCP session for a given packet and return
68 * the memory back to ssn_pool and corresponding segments to segment
69 * pool.
70 *
71 * \retval On success it returns 1 and on failure 0.
72 */
73
74static int StreamTcpTest02(void)
75{
77 FAIL_IF(unlikely(p == NULL));
78 Flow f;
81 uint8_t payload[4];
82 TCPHdr tcph;
84 memset(&pq, 0, sizeof(pq));
85 memset(&f, 0, sizeof(Flow));
86 memset(&tv, 0, sizeof(ThreadVars));
87 memset(&stt, 0, sizeof(StreamTcpThread));
88 memset(&tcph, 0, sizeof(TCPHdr));
89
91 p->flow = &f;
92 tcph.th_win = htons(5480);
93 tcph.th_flags = TH_SYN;
94 UTHSetTCPHdr(p, &tcph);
96
98
99 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
100
101 tcph.th_ack = htonl(1);
102 tcph.th_flags = TH_SYN | TH_ACK;
104
105 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
106
107 tcph.th_ack = htonl(1);
108 tcph.th_seq = htonl(1);
109 tcph.th_flags = TH_ACK;
111
112 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
113
114 tcph.th_ack = htonl(1);
115 tcph.th_seq = htonl(2);
116 tcph.th_flags = TH_PUSH | TH_ACK;
118
119 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
120 p->payload = payload;
121 p->payload_len = 3;
122
123 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
124
126 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
127
128 tcph.th_ack = htonl(1);
129 tcph.th_seq = htonl(6);
130 tcph.th_flags = TH_PUSH | TH_ACK;
132
133 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
134 p->payload = payload;
135 p->payload_len = 3;
136
137 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
138
140 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
141
143 // StreamTcpUTClearSession(p->flow->protoctx);
144
145 SCFree(p);
146 FLOW_DESTROY(&f);
148 PASS;
149}
150
151/**
152 * \test Test the setting up a TCP session when we missed the initial
153 * SYN packet of the session. The session is setup only if midstream
154 * sessions are allowed to setup.
155 *
156 * \retval On success it returns 1 and on failure 0.
157 */
158
159static int StreamTcpTest03(void)
160{
162 FAIL_IF_NULL(p);
163 Flow f;
165 StreamTcpThread stt;
166 TCPHdr tcph;
168 memset(&pq, 0, sizeof(pq));
169 memset(&f, 0, sizeof(Flow));
170 memset(&tv, 0, sizeof(ThreadVars));
171 memset(&stt, 0, sizeof(StreamTcpThread));
172 memset(&tcph, 0, sizeof(TCPHdr));
173 FLOW_INITIALIZE(&f);
174 p->flow = &f;
175
177
178 tcph.th_win = htons(5480);
179 tcph.th_seq = htonl(10);
180 tcph.th_ack = htonl(20);
181 tcph.th_flags = TH_SYN | TH_ACK;
182 UTHSetTCPHdr(p, &tcph);
183 int ret = 0;
184
185 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
186 goto end;
187
188 tcph.th_seq = htonl(20);
189 tcph.th_ack = htonl(11);
190 tcph.th_flags = TH_ACK;
192
193 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
194 goto end;
195
196 tcph.th_seq = htonl(19);
197 tcph.th_ack = htonl(11);
198 tcph.th_flags = TH_ACK | TH_PUSH;
200
201 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
202 goto end;
203
205 ret = 1;
206 goto end;
207 }
208 if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
209 goto end;
210
211 if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 20 &&
212 ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11)
213 goto end;
214
216
217 ret = 1;
218end:
219 SCFree(p);
220 FLOW_DESTROY(&f);
222 return ret;
223}
224
225/**
226 * \test Test the setting up a TCP session when we missed the initial
227 * SYN/ACK packet of the session. The session is setup only if
228 * midstream sessions are allowed to setup.
229 *
230 * \retval On success it returns 1 and on failure 0.
231 */
232
233static int StreamTcpTest04(void)
234{
236 FAIL_IF_NULL(p);
237 Flow f;
239 StreamTcpThread stt;
240 TCPHdr tcph;
242 memset(&pq, 0, sizeof(pq));
243 memset(&f, 0, sizeof(Flow));
244 memset(&tv, 0, sizeof(ThreadVars));
245 memset(&stt, 0, sizeof(StreamTcpThread));
246 memset(&tcph, 0, sizeof(TCPHdr));
247 FLOW_INITIALIZE(&f);
248 p->flow = &f;
249
251
252 tcph.th_win = htons(5480);
253 tcph.th_seq = htonl(10);
254 tcph.th_ack = htonl(20);
255 tcph.th_flags = TH_ACK;
256 UTHSetTCPHdr(p, &tcph);
257
258 int ret = 0;
259
260 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
261 goto end;
262
263 tcph.th_seq = htonl(9);
264 tcph.th_ack = htonl(19);
265 tcph.th_flags = TH_ACK | TH_PUSH;
267
268 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
269 goto end;
270
272 ret = 1;
273 goto end;
274 }
275 if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
276 goto end;
277
278 if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 10 &&
279 ((TcpSession *)(p->flow->protoctx))->server.next_seq != 20)
280 goto end;
281
283
284 ret = 1;
285end:
286 SCFree(p);
287 FLOW_DESTROY(&f);
289 return ret;
290}
291
292/**
293 * \test Test the setting up a TCP session when we missed the initial
294 * 3WHS packet of the session. The session is setup only if
295 * midstream sessions are allowed to setup.
296 *
297 * \retval On success it returns 1 and on failure 0.
298 */
299
300static int StreamTcpTest05(void)
301{
303 FAIL_IF_NULL(p);
304 Flow f;
306 StreamTcpThread stt;
307 TCPHdr tcph;
308 uint8_t payload[4];
310 memset(&pq, 0, sizeof(PacketQueueNoLock));
311 memset(&f, 0, sizeof(Flow));
312 memset(&tv, 0, sizeof(ThreadVars));
313 memset(&stt, 0, sizeof(StreamTcpThread));
314 memset(&tcph, 0, sizeof(TCPHdr));
315 FLOW_INITIALIZE(&f);
316 p->flow = &f;
317 int ret = 0;
318
320 tcph.th_win = htons(5480);
321 tcph.th_seq = htonl(10);
322 tcph.th_ack = htonl(20);
323 tcph.th_flags = TH_ACK | TH_PUSH;
324 UTHSetTCPHdr(p, &tcph);
325
326 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
327 p->payload = payload;
328 p->payload_len = 3;
329
330 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
331 goto end;
332
333 tcph.th_seq = htonl(20);
334 tcph.th_ack = htonl(13);
335 tcph.th_flags = TH_ACK | TH_PUSH;
337
338 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
339 p->payload = payload;
340 p->payload_len = 3;
341
342 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
343 goto end;
344
345 tcph.th_seq = htonl(13);
346 tcph.th_ack = htonl(23);
347 tcph.th_flags = TH_ACK | TH_PUSH;
349
350 StreamTcpCreateTestPacket(payload, 0x43, 3, 4); /*CCC*/
351 p->payload = payload;
352 p->payload_len = 3;
353
354 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
355 goto end;
356
357 tcph.th_seq = htonl(19);
358 tcph.th_ack = htonl(16);
359 tcph.th_flags = TH_ACK | TH_PUSH;
361
362 StreamTcpCreateTestPacket(payload, 0x44, 3, 4); /*DDD*/
363 p->payload = payload;
364 p->payload_len = 3;
365
366 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
367 goto end;
368
370 ret = 1;
371 goto end;
372 }
373 if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
374 goto end;
375
376 if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 16 &&
377 ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23)
378 goto end;
379
381
382 ret = 1;
383end:
384 SCFree(p);
385 FLOW_DESTROY(&f);
387 return ret;
388}
389
390/**
391 * \test Test the setting up a TCP session when we have seen only the
392 * FIN, RST packets packet of the session. The session is setup only if
393 * midstream sessions are allowed to setup.
394 *
395 * \retval On success it returns 1 and on failure 0.
396 */
397
398static int StreamTcpTest06(void)
399{
401 FAIL_IF_NULL(p);
402 Flow f;
403 TcpSession ssn;
405 StreamTcpThread stt;
406 TCPHdr tcph;
408 memset(&pq, 0, sizeof(PacketQueueNoLock));
409 memset(&f, 0, sizeof(Flow));
410 memset(&ssn, 0, sizeof(TcpSession));
411 memset(&tv, 0, sizeof(ThreadVars));
412 memset(&stt, 0, sizeof(StreamTcpThread));
413 memset(&tcph, 0, sizeof(TCPHdr));
414 FLOW_INITIALIZE(&f);
415 p->flow = &f;
416 int ret = 0;
417
419
420 tcph.th_flags = TH_FIN;
421 UTHSetTCPHdr(p, &tcph);
422
423 /* StreamTcpPacket returns -1 on unsolicited FIN */
424 if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) {
425 printf("StreamTcpPacket failed: ");
426 goto end;
427 }
428
429 if (((TcpSession *)(p->flow->protoctx)) != NULL) {
430 printf("we have a ssn while we shouldn't: ");
431 goto end;
432 }
433
434 tcph.th_flags = TH_RST;
435 /* StreamTcpPacket returns -1 on unsolicited RST */
436 if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) {
437 printf("StreamTcpPacket failed (2): ");
438 goto end;
439 }
440
441 if (((TcpSession *)(p->flow->protoctx)) != NULL) {
442 printf("we have a ssn while we shouldn't (2): ");
443 goto end;
444 }
445
446 ret = 1;
447end:
448 SCFree(p);
449 FLOW_DESTROY(&f);
451 return ret;
452}
453
454/**
455 * \test Test the working on PAWS. The packet will be dropped by stream, as
456 * its timestamp is old, although the segment is in the window.
457 */
458
459static int StreamTcpTest07(void)
460{
462 FAIL_IF(unlikely(p == NULL));
463 Flow f;
465 StreamTcpThread stt;
466 TCPHdr tcph;
467 uint8_t payload[1] = { 0x42 };
469
470 memset(&pq, 0, sizeof(PacketQueueNoLock));
471 memset(&f, 0, sizeof(Flow));
472 memset(&tv, 0, sizeof(ThreadVars));
473 memset(&stt, 0, sizeof(StreamTcpThread));
474 memset(&tcph, 0, sizeof(TCPHdr));
475
476 FLOW_INITIALIZE(&f);
477 p->flow = &f;
478
481
482 tcph.th_win = htons(5480);
483 tcph.th_seq = htonl(10);
484 tcph.th_ack = htonl(20);
485 tcph.th_flags = TH_ACK | TH_PUSH;
486 UTHSetTCPHdr(p, &tcph);
487
488 p->l4.vars.tcp.ts_set = true;
489 p->l4.vars.tcp.ts_val = 10;
490 p->l4.vars.tcp.ts_ecr = 11;
491
492 p->payload = payload;
493 p->payload_len = 1;
494
495 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
496
497 tcph.th_seq = htonl(11);
498 tcph.th_ack = htonl(23);
499 tcph.th_flags = TH_ACK | TH_PUSH;
501
502 p->l4.vars.tcp.ts_val = 2;
503
504 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) != -1);
505
506 FAIL_IF(((TcpSession *)(p->flow->protoctx))->client.next_seq != 11);
507
509 SCFree(p);
510 FLOW_DESTROY(&f);
512 PASS;
513}
514
515/**
516 * \test Test the working on PAWS. The packet will be accepted by engine as
517 * the timestamp is valid and it is in window.
518 */
519
520static int StreamTcpTest08(void)
521{
523 FAIL_IF(unlikely(p == NULL));
524 Flow f;
526 StreamTcpThread stt;
527 TCPHdr tcph;
528 uint8_t payload[1] = { 0x42 };
529
531 memset(&pq, 0, sizeof(PacketQueueNoLock));
532 memset(&f, 0, sizeof(Flow));
533 memset(&tv, 0, sizeof(ThreadVars));
534 memset(&stt, 0, sizeof(StreamTcpThread));
535 memset(&tcph, 0, sizeof(TCPHdr));
536
537 FLOW_INITIALIZE(&f);
538 p->flow = &f;
539
542
543 tcph.th_win = htons(5480);
544 tcph.th_seq = htonl(10);
545 tcph.th_ack = htonl(20);
546 tcph.th_flags = TH_ACK | TH_PUSH;
547 UTHSetTCPHdr(p, &tcph);
548
549 p->l4.vars.tcp.ts_set = true;
550 p->l4.vars.tcp.ts_val = 10;
551 p->l4.vars.tcp.ts_ecr = 11;
552
553 p->payload = payload;
554 p->payload_len = 1;
555
556 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
557
558 tcph.th_seq = htonl(11);
559 tcph.th_ack = htonl(20);
560 tcph.th_flags = TH_ACK | TH_PUSH;
562
563 p->l4.vars.tcp.ts_val = 12;
564
565 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
566
567 FAIL_IF(((TcpSession *)(p->flow->protoctx))->client.next_seq != 12);
568
570
571 SCFree(p);
572 FLOW_DESTROY(&f);
574 PASS;
575}
576
577/**
578 * \test Test the working of No stream reassembly flag. The stream will not
579 * reassemble the segment if the flag is set.
580 */
581
582static int StreamTcpTest09(void)
583{
585 FAIL_IF(unlikely(p == NULL));
586 Flow f;
588 StreamTcpThread stt;
589 TCPHdr tcph;
590 uint8_t payload[1] = { 0x42 };
591
593 memset(&pq, 0, sizeof(PacketQueueNoLock));
594 memset(&f, 0, sizeof(Flow));
595 memset(&tv, 0, sizeof(ThreadVars));
596 memset(&stt, 0, sizeof(StreamTcpThread));
597 memset(&tcph, 0, sizeof(TCPHdr));
598
599 FLOW_INITIALIZE(&f);
600 p->flow = &f;
601
604
605 tcph.th_win = htons(5480);
606 tcph.th_seq = htonl(10);
607 tcph.th_ack = htonl(20);
608 tcph.th_flags = TH_ACK | TH_PUSH;
609 UTHSetTCPHdr(p, &tcph);
610
611 p->payload = payload;
612 p->payload_len = 1;
613
614 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
615
616 tcph.th_seq = htonl(12);
617 tcph.th_ack = htonl(23);
618 tcph.th_flags = TH_ACK | TH_PUSH;
620
621 FAIL_IF(p->flow->protoctx == NULL);
622
624
625 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
626
627 tcph.th_seq = htonl(11);
628 tcph.th_ack = htonl(23);
629 tcph.th_flags = TH_ACK | TH_PUSH;
631
632 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
633
634 TcpSession *ssn = p->flow->protoctx;
635 FAIL_IF_NULL(ssn);
636 TcpSegment *seg = RB_MIN(TCPSEG, &ssn->client.seg_tree);
637 FAIL_IF_NULL(seg);
638 FAIL_IF(TCPSEG_RB_NEXT(seg) != NULL);
639
641 SCFree(p);
642 FLOW_DESTROY(&f);
644 PASS;
645}
646
647/**
648 * \test Test the setting up a TCP session when we are seeing asynchronous
649 * stream, while we see all the packets in that stream from start.
650 */
651
652static int StreamTcpTest10(void)
653{
655 FAIL_IF(unlikely(p == NULL));
656 Flow f;
658 StreamTcpThread stt;
659 TCPHdr tcph;
660 uint8_t payload[4];
662 memset(&pq, 0, sizeof(PacketQueueNoLock));
663 memset(&f, 0, sizeof(Flow));
664 memset(&tv, 0, sizeof(ThreadVars));
665 memset(&stt, 0, sizeof(StreamTcpThread));
666 memset(&tcph, 0, sizeof(TCPHdr));
667 FLOW_INITIALIZE(&f);
668 p->flow = &f;
669
672
673 tcph.th_win = htons(5480);
674 tcph.th_seq = htonl(10);
675 tcph.th_ack = 0;
676 tcph.th_flags = TH_SYN;
677 UTHSetTCPHdr(p, &tcph);
678
679 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
680
681 tcph.th_seq = htonl(11);
682 tcph.th_ack = htonl(11);
683 tcph.th_flags = TH_ACK;
685
686 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
687
688 tcph.th_seq = htonl(11);
689 tcph.th_ack = htonl(11);
690 tcph.th_flags = TH_ACK | TH_PUSH;
692
693 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
694 p->payload = payload;
695 p->payload_len = 3;
696
697 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
698
699 tcph.th_seq = htonl(6);
700 tcph.th_ack = htonl(11);
701 tcph.th_flags = TH_ACK | TH_PUSH;
703
704 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
705 p->payload = payload;
706 p->payload_len = 3;
707
708 /* spurious retransmission */
709 FAIL_IF_NOT(StreamTcpPacket(&tv, p, &stt, &pq) == 0);
710
711 FAIL_IF(((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED);
712
713 FAIL_IF(!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC));
714
715 FAIL_IF(((TcpSession *)(p->flow->protoctx))->client.last_ack != 6 &&
716 ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11);
717
719
720 SCFree(p);
721 FLOW_DESTROY(&f);
723 PASS;
724}
725
726/**
727 * \test Test the setting up a TCP session when we are seeing asynchronous
728 * stream, while we missed the SYN packet of that stream.
729 */
730
731static int StreamTcpTest11(void)
732{
734 FAIL_IF(unlikely(p == NULL));
735 Flow f;
737 StreamTcpThread stt;
738 TCPHdr tcph;
739 uint8_t payload[4];
741 memset(&pq, 0, sizeof(PacketQueueNoLock));
742 memset(&f, 0, sizeof(Flow));
743 memset(&tv, 0, sizeof(ThreadVars));
744 memset(&stt, 0, sizeof(StreamTcpThread));
745 memset(&tcph, 0, sizeof(TCPHdr));
746 FLOW_INITIALIZE(&f);
747 p->flow = &f;
748
751
752 tcph.th_win = htons(5480);
753 tcph.th_seq = htonl(10);
754 tcph.th_ack = htonl(1);
755 tcph.th_flags = TH_SYN | TH_ACK;
756 UTHSetTCPHdr(p, &tcph);
757
758 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
759
760 tcph.th_seq = htonl(11);
761 tcph.th_ack = htonl(1);
762 tcph.th_flags = TH_ACK;
764
765 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
766
767 tcph.th_seq = htonl(11);
768 tcph.th_ack = htonl(1);
769 tcph.th_flags = TH_ACK | TH_PUSH;
771
772 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
773 p->payload = payload;
774 p->payload_len = 3;
775
776 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
777
778 tcph.th_seq = htonl(2);
779 tcph.th_ack = htonl(1);
780 tcph.th_flags = TH_ACK | TH_PUSH;
782
783 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
784 p->payload = payload;
785 p->payload_len = 3;
786
787 FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
788
789 TcpSession *ssn = p->flow->protoctx;
790 FAIL_IF((ssn->flags & STREAMTCP_FLAG_ASYNC) == 0);
792
793 FAIL_IF(ssn->server.last_ack != 11);
794 FAIL_IF(ssn->client.next_seq != 14);
795
797 SCFree(p);
798 FLOW_DESTROY(&f);
800 PASS;
801}
802
803/**
804 * \test Test the setting up a TCP session when we are seeing asynchronous
805 * stream, while we missed the SYN and SYN/ACK packets in that stream.
806 *
807 * \retval On success it returns 1 and on failure 0.
808 */
809
810static int StreamTcpTest12(void)
811{
813 FAIL_IF_NULL(p);
814 Flow f;
816 StreamTcpThread stt;
817 TCPHdr tcph;
818 uint8_t payload[4];
820 memset(&pq, 0, sizeof(PacketQueueNoLock));
821 memset(&f, 0, sizeof(Flow));
822 memset(&tv, 0, sizeof(ThreadVars));
823 memset(&stt, 0, sizeof(StreamTcpThread));
824 memset(&tcph, 0, sizeof(TCPHdr));
825 FLOW_INITIALIZE(&f);
826 p->flow = &f;
827
829
830 tcph.th_win = htons(5480);
831 tcph.th_seq = htonl(10);
832 tcph.th_ack = htonl(11);
833 tcph.th_flags = TH_ACK;
834 UTHSetTCPHdr(p, &tcph);
835 int ret = 0;
836
837 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
838 goto end;
839
840 tcph.th_seq = htonl(10);
841 tcph.th_ack = htonl(11);
842 tcph.th_flags = TH_ACK | TH_PUSH;
844
845 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
846 p->payload = payload;
847 p->payload_len = 3;
848
849 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
850 goto end;
851
852 tcph.th_seq = htonl(6);
853 tcph.th_ack = htonl(11);
854 tcph.th_flags = TH_ACK | TH_PUSH;
856
857 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
858 p->payload = payload;
859 p->payload_len = 3;
860
861 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
862 goto end;
863
865 ret = 1;
866 goto end;
867 }
868
869 if (!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC)) {
870 printf("failed in setting asynchronous session\n");
871 goto end;
872 }
873
874 if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
875 printf("failed in setting state\n");
876 goto end;
877 }
878
879 if (((TcpSession *)(p->flow->protoctx))->client.last_ack != 6 &&
880 ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11) {
881 printf("failed in seq %" PRIu32 " match\n",
882 ((TcpSession *)(p->flow->protoctx))->client.last_ack);
883 goto end;
884 }
885
887
888 ret = 1;
889end:
890 SCFree(p);
891 FLOW_DESTROY(&f);
893 return ret;
894}
895
896/**
897 * \test Test the setting up a TCP session when we are seeing asynchronous
898 * stream, while we missed the SYN and SYN/ACK packets in that stream.
899 * Later, we start to receive the packet from other end stream too.
900 *
901 * \retval On success it returns 1 and on failure 0.
902 */
903
904static int StreamTcpTest13(void)
905{
907 FAIL_IF_NULL(p);
908 Flow f;
910 StreamTcpThread stt;
911 TCPHdr tcph;
912 uint8_t payload[4];
914 memset(&pq, 0, sizeof(PacketQueueNoLock));
915 memset(&f, 0, sizeof(Flow));
916 memset(&tv, 0, sizeof(ThreadVars));
917 memset(&stt, 0, sizeof(StreamTcpThread));
918 memset(&tcph, 0, sizeof(TCPHdr));
919 FLOW_INITIALIZE(&f);
920 p->flow = &f;
921
923
924 tcph.th_win = htons(5480);
925 tcph.th_seq = htonl(10);
926 tcph.th_ack = htonl(11);
927 tcph.th_flags = TH_ACK;
928 UTHSetTCPHdr(p, &tcph);
929 int ret = 0;
930
931 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
932 goto end;
933
934 tcph.th_seq = htonl(10);
935 tcph.th_ack = htonl(11);
936 tcph.th_flags = TH_ACK | TH_PUSH;
938
939 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
940 p->payload = payload;
941 p->payload_len = 3;
942
943 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
944 goto end;
945
946 tcph.th_seq = htonl(6);
947 tcph.th_ack = htonl(11);
948 tcph.th_flags = TH_ACK | TH_PUSH;
950
951 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
952 p->payload = payload;
953 p->payload_len = 3;
954
955 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
956 goto end;
957
959 ret = 1;
960 goto end;
961 }
962
963 if (!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC)) {
964 printf("failed in setting asynchronous session\n");
965 goto end;
966 }
967
968 if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
969 printf("failed in setting state\n");
970 goto end;
971 }
972
973 tcph.th_seq = htonl(11);
974 tcph.th_ack = htonl(9);
975 tcph.th_flags = TH_ACK | TH_PUSH;
977
978 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
979 p->payload = payload;
980 p->payload_len = 3;
981
982 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
983 goto end;
984
985 if (((TcpSession *)(p->flow->protoctx))->client.last_ack != 9 &&
986 ((TcpSession *)(p->flow->protoctx))->server.next_seq != 14) {
987 printf("failed in seq %" PRIu32 " match\n",
988 ((TcpSession *)(p->flow->protoctx))->client.last_ack);
989 goto end;
990 }
991
993
994 ret = 1;
995end:
996 SCFree(p);
997 FLOW_DESTROY(&f);
999 return ret;
1000}
1001
1002/* Dummy conf string to setup the OS policy for unit testing */
1003static const char *dummy_conf_string = "%YAML 1.1\n"
1004 "---\n"
1005 "\n"
1006 "default-log-dir: /var/log/eidps\n"
1007 "\n"
1008 "logging:\n"
1009 "\n"
1010 " default-log-level: debug\n"
1011 "\n"
1012 " default-format: \"<%t> - <%l>\"\n"
1013 "\n"
1014 " default-startup-message: Your IDS has started.\n"
1015 "\n"
1016 " default-output-filter:\n"
1017 "\n"
1018 "host-os-policy:\n"
1019 "\n"
1020 " windows: 192.168.0.1\n"
1021 "\n"
1022 " linux: 192.168.0.2\n"
1023 "\n";
1024/* Dummy conf string to setup the OS policy for unit testing */
1025static const char *dummy_conf_string1 = "%YAML 1.1\n"
1026 "---\n"
1027 "\n"
1028 "default-log-dir: /var/log/eidps\n"
1029 "\n"
1030 "logging:\n"
1031 "\n"
1032 " default-log-level: debug\n"
1033 "\n"
1034 " default-format: \"<%t> - <%l>\"\n"
1035 "\n"
1036 " default-startup-message: Your IDS has started.\n"
1037 "\n"
1038 " default-output-filter:\n"
1039 "\n"
1040 "host-os-policy:\n"
1041 "\n"
1042 " windows: 192.168.0.0/24,"
1043 "192.168.1.1\n"
1044 "\n"
1045 " linux: 192.168.1.0/24,"
1046 "192.168.0.1\n"
1047 "\n";
1048
1049/**
1050 * \brief Function to parse the dummy conf string and get the value of IP
1051 * address for the corresponding OS policy type.
1052 *
1053 * \param conf_val_name Name of the OS policy type
1054 * \retval returns IP address as string on success and NULL on failure
1055 */
1056static const char *StreamTcpParseOSPolicy(char *conf_var_name)
1057{
1058 SCEnter();
1059 char conf_var_type_name[15] = "host-os-policy";
1060 char *conf_var_full_name = NULL;
1061 const char *conf_var_value = NULL;
1062
1063 if (conf_var_name == NULL)
1064 goto end;
1065
1066 /* the + 2 is for the '.' and the string termination character '\0' */
1067 conf_var_full_name = (char *)SCMalloc(strlen(conf_var_type_name) + strlen(conf_var_name) + 2);
1068 if (conf_var_full_name == NULL)
1069 goto end;
1070
1071 if (snprintf(conf_var_full_name, strlen(conf_var_type_name) + strlen(conf_var_name) + 2,
1072 "%s.%s", conf_var_type_name, conf_var_name) < 0) {
1073 SCLogError("Error in making the conf full name");
1074 goto end;
1075 }
1076
1077 if (SCConfGet(conf_var_full_name, &conf_var_value) != 1) {
1078 SCLogError("Error in getting conf value for conf name %s", conf_var_full_name);
1079 goto end;
1080 }
1081
1082 SCLogDebug("Value obtained from the yaml conf file, for the var "
1083 "\"%s\" is \"%s\"",
1084 conf_var_name, conf_var_value);
1085
1086end:
1087 if (conf_var_full_name != NULL)
1088 SCFree(conf_var_full_name);
1089 SCReturnCharPtr(conf_var_value);
1090}
1091/**
1092 * \test Test the setting up a OS policy. Te OS policy values are defined in
1093 * the config string "dummy_conf_string"
1094 *
1095 * \retval On success it returns 1 and on failure 0
1096 */
1097
1098static int StreamTcpTest14(void)
1099{
1101 FAIL_IF_NULL(p);
1102 Flow f;
1103 ThreadVars tv;
1104 StreamTcpThread stt;
1105 TCPHdr tcph;
1106 uint8_t payload[4];
1107 struct in_addr addr;
1108 IPV4Hdr ipv4h;
1109 char os_policy_name[10] = "windows";
1110 const char *ip_addr;
1112 memset(&pq, 0, sizeof(PacketQueueNoLock));
1113
1114 memset(&f, 0, sizeof(Flow));
1115 memset(&tv, 0, sizeof(ThreadVars));
1116 memset(&stt, 0, sizeof(StreamTcpThread));
1117 memset(&tcph, 0, sizeof(TCPHdr));
1118 memset(&addr, 0, sizeof(addr));
1119 memset(&ipv4h, 0, sizeof(ipv4h));
1120 FLOW_INITIALIZE(&f);
1121 p->flow = &f;
1122 int ret = 0;
1123
1124 StreamTcpUTInit(&stt.ra_ctx);
1125
1126 /* Load the config string into parser */
1128 SCConfInit();
1129 SCConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string));
1130
1131 /* Get the IP address as string and add it to Host info tree for lookups */
1132 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1133 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1134 strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1135 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1136 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1137 addr.s_addr = inet_addr("192.168.0.1");
1138 tcph.th_win = htons(5480);
1139 tcph.th_seq = htonl(10);
1140 tcph.th_ack = htonl(20);
1141 tcph.th_flags = TH_ACK | TH_PUSH;
1142 UTHSetTCPHdr(p, &tcph);
1143 p->dst.family = AF_INET;
1144 p->dst.address.address_un_data32[0] = addr.s_addr;
1145 UTHSetIPV4Hdr(p, &ipv4h);
1146
1147 StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1148 p->payload = payload;
1149 p->payload_len = 3;
1150
1151 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1152 goto end;
1153
1154 tcph.th_seq = htonl(20);
1155 tcph.th_ack = htonl(13);
1156 tcph.th_flags = TH_ACK | TH_PUSH;
1158
1159 StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1160 p->payload = payload;
1161 p->payload_len = 3;
1162
1163 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1164 goto end;
1165
1166 tcph.th_seq = htonl(15);
1167 tcph.th_ack = htonl(23);
1168 tcph.th_flags = TH_ACK | TH_PUSH;
1170
1171 StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1172 p->payload = payload;
1173 p->payload_len = 3;
1174
1175 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1176 goto end;
1177
1178 tcph.th_seq = htonl(14);
1179 tcph.th_ack = htonl(23);
1180 tcph.th_flags = TH_ACK | TH_PUSH;
1182
1183 StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1184 p->payload = payload;
1185 p->payload_len = 3;
1186
1187 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1188 goto end;
1189
1190 addr.s_addr = inet_addr("192.168.0.2");
1191 tcph.th_seq = htonl(25);
1192 tcph.th_ack = htonl(13);
1193 tcph.th_flags = TH_ACK | TH_PUSH;
1195 p->dst.address.address_un_data32[0] = addr.s_addr;
1196
1197 StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1198 p->payload = payload;
1199 p->payload_len = 3;
1200
1201 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1202 goto end;
1203
1204 tcph.th_seq = htonl(24);
1205 tcph.th_ack = htonl(13);
1206 tcph.th_flags = TH_ACK | TH_PUSH;
1208
1209 StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1210 p->payload = payload;
1211 p->payload_len = 3;
1212
1213 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1214 goto end;
1215
1216 if (!stream_config.midstream) {
1217 ret = 1;
1218 goto end;
1219 }
1220 if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1221 goto end;
1222
1223 if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1224 ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1225 printf("failed in next_seq match client.next_seq %" PRIu32 ""
1226 " server.next_seq %" PRIu32 "\n",
1227 ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1228 ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1229 goto end;
1230 }
1231
1232 if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_WINDOWS &&
1233 ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_LINUX) {
1234 printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1235 " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1236 " should be %" PRIu8 "\n",
1237 ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_WINDOWS,
1238 ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_LINUX);
1239 goto end;
1240 }
1242
1243 ret = 1;
1244end:
1245 SCConfDeInit();
1247 SCFree(p);
1248 FLOW_DESTROY(&f);
1250 return ret;
1251}
1252
1253/**
1254 * \test Test the setting up a TCP session using the 4WHS:
1255 * SYN, SYN, SYN/ACK, ACK
1256 *
1257 * \retval On success it returns 1 and on failure 0.
1258 */
1259
1260static int StreamTcp4WHSTest01(void)
1261{
1262 int ret = 0;
1264 FAIL_IF_NULL(p);
1265 Flow f;
1266 ThreadVars tv;
1267 StreamTcpThread stt;
1268 TCPHdr tcph;
1270 memset(&pq, 0, sizeof(PacketQueueNoLock));
1271 memset(&f, 0, sizeof(Flow));
1272 memset(&tv, 0, sizeof(ThreadVars));
1273 memset(&stt, 0, sizeof(StreamTcpThread));
1274 memset(&tcph, 0, sizeof(TCPHdr));
1275 FLOW_INITIALIZE(&f);
1276 p->flow = &f;
1277
1278 StreamTcpUTInit(&stt.ra_ctx);
1279
1280 tcph.th_win = htons(5480);
1281 tcph.th_seq = htonl(10);
1282 tcph.th_ack = 0;
1283 tcph.th_flags = TH_SYN;
1284 UTHSetTCPHdr(p, &tcph);
1285
1286 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1287 goto end;
1288
1289 tcph.th_seq = htonl(20);
1290 tcph.th_ack = 0;
1291 tcph.th_flags = TH_SYN;
1293
1294 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1295 goto end;
1296
1297 if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) {
1298 printf("STREAMTCP_FLAG_4WHS flag not set: ");
1299 goto end;
1300 }
1301
1302 tcph.th_seq = htonl(10);
1303 tcph.th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */
1304 tcph.th_flags = TH_SYN | TH_ACK;
1306
1307 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1308 goto end;
1309
1310 tcph.th_seq = htonl(21);
1311 tcph.th_ack = htonl(10);
1312 tcph.th_flags = TH_ACK;
1314
1315 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1316 goto end;
1317
1318 if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
1319 printf("state is not ESTABLISHED: ");
1320 goto end;
1321 }
1322
1323 ret = 1;
1324end:
1326 SCFree(p);
1327 FLOW_DESTROY(&f);
1329 return ret;
1330}
1331
1332/**
1333 * \test set up a TCP session using the 4WHS:
1334 * SYN, SYN, SYN/ACK, ACK, but the SYN/ACK does
1335 * not have the right SEQ
1336 *
1337 * \retval On success it returns 1 and on failure 0.
1338 */
1339
1340static int StreamTcp4WHSTest02(void)
1341{
1342 int ret = 0;
1344 FAIL_IF_NULL(p);
1345 Flow f;
1346 ThreadVars tv;
1347 StreamTcpThread stt;
1348 TCPHdr tcph;
1350 memset(&pq, 0, sizeof(PacketQueueNoLock));
1351 memset(&f, 0, sizeof(Flow));
1352 memset(&tv, 0, sizeof(ThreadVars));
1353 memset(&stt, 0, sizeof(StreamTcpThread));
1354 memset(&tcph, 0, sizeof(TCPHdr));
1355 FLOW_INITIALIZE(&f);
1356 p->flow = &f;
1357
1358 StreamTcpUTInit(&stt.ra_ctx);
1359
1360 tcph.th_win = htons(5480);
1361 tcph.th_seq = htonl(10);
1362 tcph.th_ack = 0;
1363 tcph.th_flags = TH_SYN;
1364 UTHSetTCPHdr(p, &tcph);
1365
1366 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1367 goto end;
1368
1369 tcph.th_seq = htonl(20);
1370 tcph.th_ack = 0;
1371 tcph.th_flags = TH_SYN;
1373
1374 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1375 goto end;
1376
1377 if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) {
1378 printf("STREAMTCP_FLAG_4WHS flag not set: ");
1379 goto end;
1380 }
1381
1382 tcph.th_seq = htonl(30);
1383 tcph.th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */
1384 tcph.th_flags = TH_SYN | TH_ACK;
1386
1387 if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) {
1388 printf("SYN/ACK pkt not rejected but it should have: ");
1389 goto end;
1390 }
1391
1392 ret = 1;
1393end:
1395 SCFree(p);
1396 FLOW_DESTROY(&f);
1398 return ret;
1399}
1400
1401/**
1402 * \test set up a TCP session using the 4WHS:
1403 * SYN, SYN, SYN/ACK, ACK: however the SYN/ACK and ACK
1404 * are part of a normal 3WHS
1405 *
1406 * \retval On success it returns 1 and on failure 0.
1407 */
1408
1409static int StreamTcp4WHSTest03(void)
1410{
1411 int ret = 0;
1413 FAIL_IF(unlikely(p == NULL));
1414 Flow f;
1415 ThreadVars tv;
1416 StreamTcpThread stt;
1417 TCPHdr tcph;
1419 memset(&pq, 0, sizeof(PacketQueueNoLock));
1420 memset(&f, 0, sizeof(Flow));
1421 memset(&tv, 0, sizeof(ThreadVars));
1422 memset(&stt, 0, sizeof(StreamTcpThread));
1423 memset(&tcph, 0, sizeof(TCPHdr));
1424 FLOW_INITIALIZE(&f);
1425 p->flow = &f;
1426
1427 StreamTcpUTInit(&stt.ra_ctx);
1428
1429 tcph.th_win = htons(5480);
1430 tcph.th_seq = htonl(10);
1431 tcph.th_ack = 0;
1432 tcph.th_flags = TH_SYN;
1433 UTHSetTCPHdr(p, &tcph);
1434
1435 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1436 goto end;
1437
1438 tcph.th_seq = htonl(20);
1439 tcph.th_ack = 0;
1440 tcph.th_flags = TH_SYN;
1442
1443 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1444 goto end;
1445
1446 if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) {
1447 printf("STREAMTCP_FLAG_4WHS flag not set: ");
1448 goto end;
1449 }
1450
1451 tcph.th_seq = htonl(30);
1452 tcph.th_ack = htonl(11);
1453 tcph.th_flags = TH_SYN | TH_ACK;
1455
1456 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1457 goto end;
1458
1459 tcph.th_seq = htonl(11);
1460 tcph.th_ack = htonl(31);
1461 tcph.th_flags = TH_ACK;
1463
1464 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1465 goto end;
1466
1467 if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
1468 printf("state is not ESTABLISHED: ");
1469 goto end;
1470 }
1471
1472 ret = 1;
1473end:
1475 SCFree(p);
1476 FLOW_DESTROY(&f);
1478 return ret;
1479}
1480
1481/**
1482 * \test Test the setting up a OS policy. Te OS policy values are defined in
1483 * the config string "dummy_conf_string1"
1484 *
1485 * \retval On success it returns 1 and on failure 0
1486 */
1487
1488static int StreamTcpTest15(void)
1489{
1491 FAIL_IF_NULL(p);
1492 Flow f;
1493 ThreadVars tv;
1494 StreamTcpThread stt;
1495 TCPHdr tcph;
1496 uint8_t payload[4];
1497 struct in_addr addr;
1498 IPV4Hdr ipv4h;
1499 char os_policy_name[10] = "windows";
1500 const char *ip_addr;
1502 memset(&pq, 0, sizeof(PacketQueueNoLock));
1503
1504 memset(&f, 0, sizeof(Flow));
1505 memset(&tv, 0, sizeof(ThreadVars));
1506 memset(&stt, 0, sizeof(StreamTcpThread));
1507 memset(&tcph, 0, sizeof(TCPHdr));
1508 memset(&addr, 0, sizeof(addr));
1509 memset(&ipv4h, 0, sizeof(ipv4h));
1510 FLOW_INITIALIZE(&f);
1511 p->flow = &f;
1512 int ret = 0;
1513
1514 StreamTcpUTInit(&stt.ra_ctx);
1515
1516 /* Load the config string into parser */
1518 SCConfInit();
1519 SCConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
1520
1521 /* Get the IP address as string and add it to Host info tree for lookups */
1522 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1523 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1524 strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1525 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1526 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1527 addr.s_addr = inet_addr("192.168.0.20");
1528 tcph.th_win = htons(5480);
1529 tcph.th_seq = htonl(10);
1530 tcph.th_ack = htonl(20);
1531 tcph.th_flags = TH_ACK | TH_PUSH;
1532 UTHSetTCPHdr(p, &tcph);
1533 p->dst.family = AF_INET;
1534 p->dst.address.address_un_data32[0] = addr.s_addr;
1535 UTHSetIPV4Hdr(p, &ipv4h);
1536
1537 StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1538 p->payload = payload;
1539 p->payload_len = 3;
1540
1541 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1542 goto end;
1543
1544 tcph.th_seq = htonl(20);
1545 tcph.th_ack = htonl(13);
1546 tcph.th_flags = TH_ACK | TH_PUSH;
1548
1549 StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1550 p->payload = payload;
1551 p->payload_len = 3;
1552
1553 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1554 goto end;
1555
1556 tcph.th_seq = htonl(15);
1557 tcph.th_ack = htonl(23);
1558 tcph.th_flags = TH_ACK | TH_PUSH;
1560
1561 StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1562 p->payload = payload;
1563 p->payload_len = 3;
1564
1565 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1566 goto end;
1567
1568 tcph.th_seq = htonl(14);
1569 tcph.th_ack = htonl(23);
1570 tcph.th_flags = TH_ACK | TH_PUSH;
1572
1573 StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1574 p->payload = payload;
1575 p->payload_len = 3;
1576
1577 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1578 goto end;
1579
1580 addr.s_addr = inet_addr("192.168.1.20");
1581 tcph.th_seq = htonl(25);
1582 tcph.th_ack = htonl(13);
1583 tcph.th_flags = TH_ACK | TH_PUSH;
1585 p->dst.address.address_un_data32[0] = addr.s_addr;
1586
1587 StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1588 p->payload = payload;
1589 p->payload_len = 3;
1590
1591 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1592 goto end;
1593
1594 tcph.th_seq = htonl(24);
1595 tcph.th_ack = htonl(13);
1596 tcph.th_flags = TH_ACK | TH_PUSH;
1598
1599 StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1600 p->payload = payload;
1601 p->payload_len = 3;
1602
1603 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1604 goto end;
1605
1606 if (!stream_config.midstream) {
1607 ret = 1;
1608 goto end;
1609 }
1610 if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1611 goto end;
1612
1613 if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1614 ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1615 printf("failed in next_seq match client.next_seq %" PRIu32 ""
1616 " server.next_seq %" PRIu32 "\n",
1617 ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1618 ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1619 goto end;
1620 }
1621
1622 if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_WINDOWS &&
1623 ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_LINUX) {
1624 printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1625 " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1626 " should be %" PRIu8 "\n",
1627 ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_WINDOWS,
1628 ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_LINUX);
1629 goto end;
1630 }
1632
1633 ret = 1;
1634end:
1635 SCConfDeInit();
1637 SCFree(p);
1638 FLOW_DESTROY(&f);
1640 return ret;
1641}
1642
1643/**
1644 * \test Test the setting up a OS policy. Te OS policy values are defined in
1645 * the config string "dummy_conf_string1"
1646 *
1647 * \retval On success it returns 1 and on failure 0
1648 */
1649
1650static int StreamTcpTest16(void)
1651{
1653 FAIL_IF_NULL(p);
1654 Flow f;
1655 ThreadVars tv;
1656 StreamTcpThread stt;
1657 TCPHdr tcph;
1658 uint8_t payload[4];
1659 struct in_addr addr;
1660 IPV4Hdr ipv4h;
1661 char os_policy_name[10] = "windows";
1662 const char *ip_addr;
1664 memset(&pq, 0, sizeof(PacketQueueNoLock));
1665
1666 memset(&f, 0, sizeof(Flow));
1667 memset(&tv, 0, sizeof(ThreadVars));
1668 memset(&stt, 0, sizeof(StreamTcpThread));
1669 memset(&tcph, 0, sizeof(TCPHdr));
1670 memset(&addr, 0, sizeof(addr));
1671 memset(&ipv4h, 0, sizeof(ipv4h));
1672 FLOW_INITIALIZE(&f);
1673 p->flow = &f;
1674 int ret = 0;
1675
1676 StreamTcpUTInit(&stt.ra_ctx);
1677
1678 /* Load the config string into parser */
1680 SCConfInit();
1681 SCConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
1682
1683 /* Get the IP address as string and add it to Host info tree for lookups */
1684 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1685 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1686 strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1687 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1688 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1689 addr.s_addr = inet_addr("192.168.0.1");
1690 tcph.th_win = htons(5480);
1691 tcph.th_seq = htonl(10);
1692 tcph.th_ack = htonl(20);
1693 tcph.th_flags = TH_ACK | TH_PUSH;
1694 UTHSetTCPHdr(p, &tcph);
1695 p->dst.family = AF_INET;
1696 p->dst.address.address_un_data32[0] = addr.s_addr;
1697 UTHSetIPV4Hdr(p, &ipv4h);
1698
1699 StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1700 p->payload = payload;
1701 p->payload_len = 3;
1702
1703 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1704 goto end;
1705
1706 tcph.th_seq = htonl(20);
1707 tcph.th_ack = htonl(13);
1708 tcph.th_flags = TH_ACK | TH_PUSH;
1710
1711 StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1712 p->payload = payload;
1713 p->payload_len = 3;
1714
1715 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1716 goto end;
1717
1718 tcph.th_seq = htonl(15);
1719 tcph.th_ack = htonl(23);
1720 tcph.th_flags = TH_ACK | TH_PUSH;
1722
1723 StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1724 p->payload = payload;
1725 p->payload_len = 3;
1726
1727 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1728 goto end;
1729
1730 tcph.th_seq = htonl(14);
1731 tcph.th_ack = htonl(23);
1732 tcph.th_flags = TH_ACK | TH_PUSH;
1734
1735 StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1736 p->payload = payload;
1737 p->payload_len = 3;
1738
1739 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1740 goto end;
1741
1742 addr.s_addr = inet_addr("192.168.1.1");
1743 tcph.th_seq = htonl(25);
1744 tcph.th_ack = htonl(13);
1745 tcph.th_flags = TH_ACK | TH_PUSH;
1747 p->dst.address.address_un_data32[0] = addr.s_addr;
1748
1749 StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1750 p->payload = payload;
1751 p->payload_len = 3;
1752
1753 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1754 goto end;
1755
1756 tcph.th_seq = htonl(24);
1757 tcph.th_ack = htonl(13);
1758 tcph.th_flags = TH_ACK | TH_PUSH;
1760
1761 StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1762 p->payload = payload;
1763 p->payload_len = 3;
1764
1765 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1766 goto end;
1767
1768 if (!stream_config.midstream) {
1769 ret = 1;
1770 goto end;
1771 }
1772 if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1773 goto end;
1774
1775 if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1776 ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1777 printf("failed in next_seq match client.next_seq %" PRIu32 ""
1778 " server.next_seq %" PRIu32 "\n",
1779 ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1780 ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1781 goto end;
1782 }
1783
1784 if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_LINUX &&
1785 ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_WINDOWS) {
1786 printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1787 " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1788 " should be %" PRIu8 "\n",
1789 ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_LINUX,
1790 ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_WINDOWS);
1791 goto end;
1792 }
1794
1795 ret = 1;
1796end:
1797 SCConfDeInit();
1799 SCFree(p);
1800 FLOW_DESTROY(&f);
1802 return ret;
1803}
1804
1805/**
1806 * \test Test the setting up a OS policy. Te OS policy values are defined in
1807 * the config string "dummy_conf_string1". To check the setting of
1808 * Default os policy
1809 *
1810 * \retval On success it returns 1 and on failure 0
1811 */
1812
1813static int StreamTcpTest17(void)
1814{
1816 FAIL_IF_NULL(p);
1817 Flow f;
1818 ThreadVars tv;
1819 StreamTcpThread stt;
1820 TCPHdr tcph;
1821 uint8_t payload[4];
1822 struct in_addr addr;
1823 IPV4Hdr ipv4h;
1824 char os_policy_name[10] = "windows";
1825 const char *ip_addr;
1827 memset(&pq, 0, sizeof(PacketQueueNoLock));
1828
1829 memset(&f, 0, sizeof(Flow));
1830 memset(&tv, 0, sizeof(ThreadVars));
1831 memset(&stt, 0, sizeof(StreamTcpThread));
1832 memset(&tcph, 0, sizeof(TCPHdr));
1833 memset(&addr, 0, sizeof(addr));
1834 memset(&ipv4h, 0, sizeof(ipv4h));
1835 FLOW_INITIALIZE(&f);
1836 p->flow = &f;
1837 int ret = 0;
1838
1839 StreamTcpUTInit(&stt.ra_ctx);
1840
1841 /* Load the config string into parser */
1843 SCConfInit();
1844 SCConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
1845
1846 /* Get the IP address as string and add it to Host info tree for lookups */
1847 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1848 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1849 strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1850 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1851 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1852 addr.s_addr = inet_addr("192.168.0.1");
1853 tcph.th_win = htons(5480);
1854 tcph.th_seq = htonl(10);
1855 tcph.th_ack = htonl(20);
1856 tcph.th_flags = TH_ACK | TH_PUSH;
1857 UTHSetTCPHdr(p, &tcph);
1858 p->dst.family = AF_INET;
1859 p->dst.address.address_un_data32[0] = addr.s_addr;
1860 UTHSetIPV4Hdr(p, &ipv4h);
1861
1862 StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1863 p->payload = payload;
1864 p->payload_len = 3;
1865
1866 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1867 goto end;
1868
1869 tcph.th_seq = htonl(20);
1870 tcph.th_ack = htonl(13);
1871 tcph.th_flags = TH_ACK | TH_PUSH;
1873
1874 StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1875 p->payload = payload;
1876 p->payload_len = 3;
1877
1878 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1879 goto end;
1880
1881 tcph.th_seq = htonl(15);
1882 tcph.th_ack = htonl(23);
1883 tcph.th_flags = TH_ACK | TH_PUSH;
1885
1886 StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1887 p->payload = payload;
1888 p->payload_len = 3;
1889
1890 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1891 goto end;
1892
1893 tcph.th_seq = htonl(14);
1894 tcph.th_ack = htonl(23);
1895 tcph.th_flags = TH_ACK | TH_PUSH;
1897
1898 StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1899 p->payload = payload;
1900 p->payload_len = 3;
1901
1902 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1903 goto end;
1904
1905 addr.s_addr = inet_addr("10.1.1.1");
1906 tcph.th_seq = htonl(25);
1907 tcph.th_ack = htonl(13);
1908 tcph.th_flags = TH_ACK | TH_PUSH;
1910 p->dst.address.address_un_data32[0] = addr.s_addr;
1911
1912 StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1913 p->payload = payload;
1914 p->payload_len = 3;
1915
1916 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1917 goto end;
1918
1919 tcph.th_seq = htonl(24);
1920 tcph.th_ack = htonl(13);
1921 tcph.th_flags = TH_ACK | TH_PUSH;
1923
1924 StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1925 p->payload = payload;
1926 p->payload_len = 3;
1927
1928 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1929 goto end;
1930
1931 if (!stream_config.midstream) {
1932 ret = 1;
1933 goto end;
1934 }
1935 if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1936 goto end;
1937
1938 if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1939 ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1940 printf("failed in next_seq match client.next_seq %" PRIu32 ""
1941 " server.next_seq %" PRIu32 "\n",
1942 ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1943 ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1944 goto end;
1945 }
1946
1947 if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_LINUX &&
1948 ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_DEFAULT) {
1949 printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1950 " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1951 " should be %" PRIu8 "\n",
1952 ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_LINUX,
1953 ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_DEFAULT);
1954 goto end;
1955 }
1957
1958 ret = 1;
1959end:
1960 SCConfDeInit();
1962 SCFree(p);
1963 FLOW_DESTROY(&f);
1965 return ret;
1966}
1967
1968/** \test Test the various OS policies based on different IP addresses from
1969 configuration defined in 'dummy_conf_string1' */
1970static int StreamTcpTest18(void)
1971{
1972 StreamTcpThread stt;
1973 struct in_addr addr;
1974 char os_policy_name[10] = "windows";
1975 const char *ip_addr;
1976 TcpStream stream;
1978 FAIL_IF_NULL(p);
1979 IPV4Hdr ipv4h;
1980 int ret = 0;
1981
1982 memset(&addr, 0, sizeof(addr));
1983 memset(&stream, 0, sizeof(stream));
1984 memset(&ipv4h, 0, sizeof(ipv4h));
1985
1986 StreamTcpUTInit(&stt.ra_ctx);
1988
1989 /* Load the config string into parser */
1991 SCConfInit();
1992 SCConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
1993
1994 /* Get the IP address as string and add it to Host info tree for lookups */
1995 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1996 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1997
1998 p->dst.family = AF_INET;
1999 UTHSetIPV4Hdr(p, &ipv4h);
2000 addr.s_addr = inet_addr("192.168.1.1");
2001 p->dst.address.address_un_data32[0] = addr.s_addr;
2002 StreamTcpSetOSPolicy(&stream, p);
2003
2004 if (stream.os_policy != OS_POLICY_WINDOWS)
2005 goto end;
2006
2007 ret = 1;
2008end:
2009 SCConfDeInit();
2011 SCFree(p);
2013 return ret;
2014}
2015/** \test Test the various OS policies based on different IP addresses from
2016 configuration defined in 'dummy_conf_string1' */
2017static int StreamTcpTest19(void)
2018{
2019 StreamTcpThread stt;
2020 struct in_addr addr;
2021 char os_policy_name[10] = "windows";
2022 const char *ip_addr;
2023 TcpStream stream;
2025 FAIL_IF_NULL(p);
2026 IPV4Hdr ipv4h;
2027 int ret = 0;
2028
2029 memset(&addr, 0, sizeof(addr));
2030 memset(&stream, 0, sizeof(stream));
2031 memset(&ipv4h, 0, sizeof(ipv4h));
2032
2033 StreamTcpUTInit(&stt.ra_ctx);
2035
2036 /* Load the config string into parser */
2038 SCConfInit();
2039 SCConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2040
2041 /* Get the IP address as string and add it to Host info tree for lookups */
2042 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2043 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2044
2045 p->dst.family = AF_INET;
2046 UTHSetIPV4Hdr(p, &ipv4h);
2047 addr.s_addr = inet_addr("192.168.0.30");
2048 p->dst.address.address_un_data32[0] = addr.s_addr;
2049 StreamTcpSetOSPolicy(&stream, p);
2050
2051 if (stream.os_policy != OS_POLICY_WINDOWS) {
2052 printf("expected os_policy: %" PRIu8 " but received %" PRIu8 ": ",
2053 (uint8_t)OS_POLICY_WINDOWS, stream.os_policy);
2054 goto end;
2055 }
2056
2057 ret = 1;
2058end:
2059 SCConfDeInit();
2061 SCFree(p);
2063 return ret;
2064}
2065/** \test Test the various OS policies based on different IP addresses from
2066 configuration defined in 'dummy_conf_string1' */
2067static int StreamTcpTest20(void)
2068{
2069 StreamTcpThread stt;
2070 struct in_addr addr;
2071 char os_policy_name[10] = "linux";
2072 const char *ip_addr;
2073 TcpStream stream;
2075 FAIL_IF_NULL(p);
2076 IPV4Hdr ipv4h;
2077 int ret = 0;
2078
2079 memset(&addr, 0, sizeof(addr));
2080 memset(&stream, 0, sizeof(stream));
2081 memset(&ipv4h, 0, sizeof(ipv4h));
2082
2083 StreamTcpUTInit(&stt.ra_ctx);
2085
2086 /* Load the config string into parser */
2088 SCConfInit();
2089 SCConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2090
2091 /* Get the IP address as string and add it to Host info tree for lookups */
2092 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2093 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2094
2095 p->dst.family = AF_INET;
2096 UTHSetIPV4Hdr(p, &ipv4h);
2097 addr.s_addr = inet_addr("192.168.0.1");
2098 p->dst.address.address_un_data32[0] = addr.s_addr;
2099 StreamTcpSetOSPolicy(&stream, p);
2100
2101 if (stream.os_policy != OS_POLICY_LINUX) {
2102 printf("expected os_policy: %" PRIu8 " but received %" PRIu8 "\n", (uint8_t)OS_POLICY_LINUX,
2103 stream.os_policy);
2104 goto end;
2105 }
2106
2107 ret = 1;
2108end:
2109 SCConfDeInit();
2111 SCFree(p);
2113 return ret;
2114}
2115/** \test Test the various OS policies based on different IP addresses from
2116 configuration defined in 'dummy_conf_string1' */
2117static int StreamTcpTest21(void)
2118{
2119 StreamTcpThread stt;
2120 struct in_addr addr;
2121 char os_policy_name[10] = "linux";
2122 const char *ip_addr;
2123 TcpStream stream;
2125 FAIL_IF_NULL(p);
2126 IPV4Hdr ipv4h;
2127 int ret = 0;
2128
2129 memset(&addr, 0, sizeof(addr));
2130 memset(&stream, 0, sizeof(stream));
2131 memset(&ipv4h, 0, sizeof(ipv4h));
2132
2133 StreamTcpUTInit(&stt.ra_ctx);
2135
2136 /* Load the config string into parser */
2138 SCConfInit();
2139 SCConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2140
2141 /* Get the IP address as string and add it to Host info tree for lookups */
2142 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2143 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2144
2145 p->dst.family = AF_INET;
2146 UTHSetIPV4Hdr(p, &ipv4h);
2147 addr.s_addr = inet_addr("192.168.1.30");
2148 p->dst.address.address_un_data32[0] = addr.s_addr;
2149 StreamTcpSetOSPolicy(&stream, p);
2150
2151 if (stream.os_policy != OS_POLICY_LINUX) {
2152 printf("expected os_policy: %" PRIu8 " but received %" PRIu8 "\n", (uint8_t)OS_POLICY_LINUX,
2153 stream.os_policy);
2154 goto end;
2155 }
2156
2157 ret = 1;
2158end:
2159 SCConfDeInit();
2161 SCFree(p);
2163 return ret;
2164}
2165/** \test Test the various OS policies based on different IP addresses from
2166 configuration defined in 'dummy_conf_string1' */
2167static int StreamTcpTest22(void)
2168{
2169 StreamTcpThread stt;
2170 struct in_addr addr;
2171 char os_policy_name[10] = "windows";
2172 const char *ip_addr;
2173 TcpStream stream;
2175 FAIL_IF_NULL(p);
2176 IPV4Hdr ipv4h;
2177 int ret = 0;
2178
2179 memset(&addr, 0, sizeof(addr));
2180 memset(&stream, 0, sizeof(stream));
2181 memset(&ipv4h, 0, sizeof(ipv4h));
2182
2183 StreamTcpUTInit(&stt.ra_ctx);
2185
2186 /* Load the config string into parser */
2188 SCConfInit();
2189 SCConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2190
2191 /* Get the IP address as string and add it to Host info tree for lookups */
2192 ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2193 SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2194
2195 p->dst.family = AF_INET;
2196 UTHSetIPV4Hdr(p, &ipv4h);
2197 addr.s_addr = inet_addr("123.231.2.1");
2198 p->dst.address.address_un_data32[0] = addr.s_addr;
2199 StreamTcpSetOSPolicy(&stream, p);
2200
2201 if (stream.os_policy != OS_POLICY_DEFAULT) {
2202 printf("expected os_policy: %" PRIu8 " but received %" PRIu8 "\n",
2203 (uint8_t)OS_POLICY_DEFAULT, stream.os_policy);
2204 goto end;
2205 }
2206
2207 ret = 1;
2208end:
2209 SCConfDeInit();
2211 SCFree(p);
2213 return ret;
2214}
2215
2216/** \test Test the stream mem leaks conditions. */
2217static int StreamTcpTest23(void)
2218{
2219 StreamTcpThread stt;
2220 TcpSession ssn;
2221 Flow f;
2222 TCPHdr tcph;
2223 uint8_t packet[1460] = "";
2224 ThreadVars tv;
2225
2227 FAIL_IF(p == NULL);
2228
2229 memset(&f, 0, sizeof(Flow));
2230 memset(&tcph, 0, sizeof(TCPHdr));
2231 memset(&tv, 0, sizeof(ThreadVars));
2232
2233 StreamTcpUTInit(&stt.ra_ctx);
2235 FLOW_INITIALIZE(&f);
2237 f.protoctx = &ssn;
2238 p->src.family = AF_INET;
2239 p->dst.family = AF_INET;
2240 p->proto = IPPROTO_TCP;
2241 p->flow = &f;
2242 tcph.th_win = 5480;
2243 tcph.th_flags = TH_PUSH | TH_ACK;
2244 UTHSetTCPHdr(p, &tcph);
2246 p->payload = packet;
2247 SET_ISN(&ssn.client, 3184324452UL);
2248
2249 tcph.th_seq = htonl(3184324453UL);
2250 tcph.th_ack = htonl(3373419609UL);
2251 p->payload_len = 2;
2252
2253 FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2254
2255 tcph.th_seq = htonl(3184324455UL);
2256 tcph.th_ack = htonl(3373419621UL);
2257 p->payload_len = 2;
2258
2259 FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2260
2261 tcph.th_seq = htonl(3184324453UL);
2262 tcph.th_ack = htonl(3373419621UL);
2263 p->payload_len = 6;
2264
2265 FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2266
2267 TcpSegment *seg = RB_MAX(TCPSEG, &ssn.client.seg_tree);
2268 FAIL_IF_NULL(seg);
2269 FAIL_IF(TCP_SEG_LEN(seg) != 2);
2270
2272 SCFree(p);
2273 FLOW_DESTROY(&f);
2275 FAIL_IF(SC_ATOMIC_GET(st_memuse) > 0);
2276 PASS;
2277}
2278
2279/** \test Test the stream mem leaks conditions. */
2280static int StreamTcpTest24(void)
2281{
2282 StreamTcpThread stt;
2283 TcpSession ssn;
2285 FAIL_IF(p == NULL);
2286 Flow f;
2287 TCPHdr tcph;
2288 uint8_t packet[1460] = "";
2289 ThreadVars tv;
2290 memset(&tv, 0, sizeof(ThreadVars));
2291
2292 StreamTcpUTInit(&stt.ra_ctx);
2294
2295 memset(&f, 0, sizeof(Flow));
2296 memset(&tcph, 0, sizeof(TCPHdr));
2297 FLOW_INITIALIZE(&f);
2299 f.protoctx = &ssn;
2300 p->src.family = AF_INET;
2301 p->dst.family = AF_INET;
2302 p->proto = IPPROTO_TCP;
2303 p->flow = &f;
2304 tcph.th_win = 5480;
2305 tcph.th_flags = TH_PUSH | TH_ACK;
2306 UTHSetTCPHdr(p, &tcph);
2308 p->payload = packet;
2309 // ssn.client.ra_app_base_seq = ssn.client.ra_raw_base_seq = ssn.client.last_ack = 3184324453UL;
2310 SET_ISN(&ssn.client, 3184324453UL);
2311
2312 tcph.th_seq = htonl(3184324455UL);
2313 tcph.th_ack = htonl(3373419621UL);
2314 p->payload_len = 4;
2315
2316 FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2317
2318 tcph.th_seq = htonl(3184324459UL);
2319 tcph.th_ack = htonl(3373419633UL);
2320 p->payload_len = 2;
2321
2322 FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2323
2324 tcph.th_seq = htonl(3184324459UL);
2325 tcph.th_ack = htonl(3373419657UL);
2326 p->payload_len = 4;
2327
2328 FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2329
2330 TcpSegment *seg = RB_MAX(TCPSEG, &ssn.client.seg_tree);
2331 FAIL_IF_NULL(seg);
2332 FAIL_IF(TCP_SEG_LEN(seg) != 4);
2333
2335 SCFree(p);
2336 FLOW_DESTROY(&f);
2338 FAIL_IF(SC_ATOMIC_GET(st_memuse) > 0);
2339 PASS;
2340}
2341
2342/**
2343 * \test Test the initialization of tcp streams with congestion flags
2344 *
2345 * \retval On success it returns 1 and on failure 0.
2346 */
2347static int StreamTcpTest25(void)
2348{
2350 FAIL_IF_NULL(p);
2351 Flow f;
2352 ThreadVars tv;
2353 StreamTcpThread stt;
2354 uint8_t payload[4];
2355 TCPHdr tcph;
2356 int ret = 0;
2358 memset(&pq, 0, sizeof(PacketQueueNoLock));
2359
2360 memset(&f, 0, sizeof(Flow));
2361 memset(&tv, 0, sizeof(ThreadVars));
2362 memset(&stt, 0, sizeof(StreamTcpThread));
2363 memset(&tcph, 0, sizeof(TCPHdr));
2364
2365 FLOW_INITIALIZE(&f);
2366 p->flow = &f;
2367 tcph.th_win = htons(5480);
2368 tcph.th_flags = TH_SYN | TH_CWR;
2369 UTHSetTCPHdr(p, &tcph);
2371 StreamTcpUTInit(&stt.ra_ctx);
2372
2373 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
2374 goto end;
2375
2376 tcph.th_ack = htonl(1);
2377 tcph.th_flags = TH_SYN | TH_ACK;
2379
2380 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2381 goto end;
2382
2383 tcph.th_ack = htonl(1);
2384 tcph.th_seq = htonl(1);
2385 tcph.th_flags = TH_ACK;
2387
2388 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2389 goto end;
2390
2391 tcph.th_ack = htonl(1);
2392 tcph.th_seq = htonl(2);
2393 tcph.th_flags = TH_PUSH | TH_ACK;
2395
2396 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2397 p->payload = payload;
2398 p->payload_len = 3;
2399
2400 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2401 goto end;
2402
2404 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2405 goto end;
2406
2407 tcph.th_ack = htonl(1);
2408 tcph.th_seq = htonl(6);
2409 tcph.th_flags = TH_PUSH | TH_ACK;
2411
2412 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
2413 p->payload = payload;
2414 p->payload_len = 3;
2415
2416 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2417 goto end;
2418
2420 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2421 goto end;
2422
2424
2425 ret = 1;
2426end:
2427 SCFree(p);
2428 FLOW_DESTROY(&f);
2430 return ret;
2431}
2432
2433/**
2434 * \test Test the initialization of tcp streams with congestion flags
2435 *
2436 * \retval On success it returns 1 and on failure 0.
2437 */
2438static int StreamTcpTest26(void)
2439{
2441 FAIL_IF_NULL(p);
2442 Flow f;
2443 ThreadVars tv;
2444 StreamTcpThread stt;
2445 uint8_t payload[4];
2446 TCPHdr tcph;
2447 int ret = 0;
2449 memset(&pq, 0, sizeof(PacketQueueNoLock));
2450
2451 memset(&f, 0, sizeof(Flow));
2452 memset(&tv, 0, sizeof(ThreadVars));
2453 memset(&stt, 0, sizeof(StreamTcpThread));
2454 memset(&tcph, 0, sizeof(TCPHdr));
2455
2456 FLOW_INITIALIZE(&f);
2457 p->flow = &f;
2458 tcph.th_win = htons(5480);
2459 tcph.th_flags = TH_SYN | TH_ECN;
2460 UTHSetTCPHdr(p, &tcph);
2462
2463 StreamTcpUTInit(&stt.ra_ctx);
2464
2465 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
2466 goto end;
2467
2468 tcph.th_ack = htonl(1);
2469 tcph.th_flags = TH_SYN | TH_ACK;
2471
2472 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2473 goto end;
2474
2475 tcph.th_ack = htonl(1);
2476 tcph.th_seq = htonl(1);
2477 tcph.th_flags = TH_ACK;
2479
2480 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2481 goto end;
2482
2483 tcph.th_ack = htonl(1);
2484 tcph.th_seq = htonl(2);
2485 tcph.th_flags = TH_PUSH | TH_ACK;
2487
2488 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2489 p->payload = payload;
2490 p->payload_len = 3;
2491
2492 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2493 goto end;
2494
2496 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2497 goto end;
2498
2499 tcph.th_ack = htonl(1);
2500 tcph.th_seq = htonl(6);
2501 tcph.th_flags = TH_PUSH | TH_ACK;
2503
2504 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
2505 p->payload = payload;
2506 p->payload_len = 3;
2507
2508 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2509 goto end;
2510
2512 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2513 goto end;
2514
2516
2517 ret = 1;
2518end:
2519 SCFree(p);
2520 FLOW_DESTROY(&f);
2522 return ret;
2523}
2524
2525/**
2526 * \test Test the initialization of tcp streams with congestion flags
2527 *
2528 * \retval On success it returns 1 and on failure 0.
2529 */
2530static int StreamTcpTest27(void)
2531{
2533 FAIL_IF_NULL(p);
2534 Flow f;
2535 ThreadVars tv;
2536 StreamTcpThread stt;
2537 uint8_t payload[4];
2538 TCPHdr tcph;
2539 int ret = 0;
2541 memset(&pq, 0, sizeof(PacketQueueNoLock));
2542
2543 memset(&f, 0, sizeof(Flow));
2544 memset(&tv, 0, sizeof(ThreadVars));
2545 memset(&stt, 0, sizeof(StreamTcpThread));
2546 memset(&tcph, 0, sizeof(TCPHdr));
2547
2548 FLOW_INITIALIZE(&f);
2549 p->flow = &f;
2550 tcph.th_win = htons(5480);
2551 tcph.th_flags = TH_SYN | TH_CWR | TH_ECN;
2552 UTHSetTCPHdr(p, &tcph);
2554
2555 StreamTcpUTInit(&stt.ra_ctx);
2556
2557 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
2558 goto end;
2559
2560 tcph.th_ack = htonl(1);
2561 tcph.th_flags = TH_SYN | TH_ACK;
2563
2564 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2565 goto end;
2566
2567 tcph.th_ack = htonl(1);
2568 tcph.th_seq = htonl(1);
2569 tcph.th_flags = TH_ACK;
2571
2572 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2573 goto end;
2574
2575 tcph.th_ack = htonl(1);
2576 tcph.th_seq = htonl(2);
2577 tcph.th_flags = TH_PUSH | TH_ACK;
2579
2580 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2581 p->payload = payload;
2582 p->payload_len = 3;
2583
2584 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2585 goto end;
2586
2588 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2589 goto end;
2590
2591 tcph.th_ack = htonl(1);
2592 tcph.th_seq = htonl(6);
2593 tcph.th_flags = TH_PUSH | TH_ACK;
2595
2596 StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
2597 p->payload = payload;
2598 p->payload_len = 3;
2599
2600 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2601 goto end;
2602
2604 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2605 goto end;
2606
2608
2609 ret = 1;
2610end:
2611 SCFree(p);
2612 FLOW_DESTROY(&f);
2614 return ret;
2615}
2616
2617/** \test Test the memcap incrementing/decrementing and memcap check */
2618static int StreamTcpTest28(void)
2619{
2620 StreamTcpThread stt;
2621 StreamTcpUTInit(&stt.ra_ctx);
2622
2623 uint32_t memuse = SC_ATOMIC_GET(st_memuse);
2624
2626 FAIL_IF(SC_ATOMIC_GET(st_memuse) != (memuse + 500));
2627
2629 FAIL_IF(SC_ATOMIC_GET(st_memuse) != memuse);
2630
2631 FAIL_IF(StreamTcpCheckMemcap(500) != 1);
2632
2633 FAIL_IF(StreamTcpCheckMemcap((memuse + SC_ATOMIC_GET(stream_config.memcap))) != 0);
2634
2636
2637 FAIL_IF(SC_ATOMIC_GET(st_memuse) != 0);
2638 PASS;
2639}
2640
2641/**
2642 * \test Test the processing of out of order FIN packets in tcp session.
2643 *
2644 * \retval On success it returns 1 and on failure 0.
2645 */
2646static int StreamTcpTest37(void)
2647{
2649 FAIL_IF_NULL(p);
2650 Flow f;
2651 ThreadVars tv;
2652 StreamTcpThread stt;
2653 uint8_t payload[4];
2654 TCPHdr tcph;
2655 int ret = 0;
2657 memset(&pq, 0, sizeof(PacketQueueNoLock));
2658
2659 memset(&f, 0, sizeof(Flow));
2660 memset(&tv, 0, sizeof(ThreadVars));
2661 memset(&stt, 0, sizeof(StreamTcpThread));
2662 memset(&tcph, 0, sizeof(TCPHdr));
2663
2664 FLOW_INITIALIZE(&f);
2665
2666 p->flow = &f;
2667 tcph.th_win = htons(5480);
2668 tcph.th_flags = TH_SYN;
2669 UTHSetTCPHdr(p, &tcph);
2671
2672 StreamTcpUTInit(&stt.ra_ctx);
2673
2674 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2675 printf("failed in processing packet\n");
2676 goto end;
2677 }
2678
2679 tcph.th_ack = htonl(1);
2680 tcph.th_flags = TH_SYN | TH_ACK;
2682
2683 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
2684 printf("failed in processing packet\n");
2685 goto end;
2686 }
2687
2688 tcph.th_ack = htonl(1);
2689 tcph.th_seq = htonl(1);
2690 tcph.th_flags = TH_ACK;
2692
2693 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
2694 printf("failed in processing packet\n");
2695 goto end;
2696 }
2697
2698 if (((TcpSession *)p->flow->protoctx)->state != TCP_ESTABLISHED) {
2699 printf("the TCP state should be TCP_ESTABLISHED\n");
2700 goto end;
2701 }
2702
2703 tcph.th_ack = htonl(2);
2704 tcph.th_seq = htonl(4);
2705 tcph.th_flags = TH_ACK | TH_FIN;
2707
2708 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
2709 printf("failed in processing packet\n");
2710 goto end;
2711 }
2712
2713 if (((TcpSession *)p->flow->protoctx)->state != TCP_CLOSE_WAIT) {
2714 printf("the TCP state should be TCP_CLOSE_WAIT\n");
2715 goto end;
2716 }
2717
2718 tcph.th_ack = htonl(1);
2719 tcph.th_seq = htonl(1);
2720 tcph.th_flags = TH_PUSH | TH_ACK;
2722
2723 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2724 p->payload = payload;
2725 p->payload_len = 3;
2726
2727 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
2728 printf("failed in processing packet\n");
2729 goto end;
2730 }
2731
2732 tcph.th_ack = htonl(4);
2733 tcph.th_seq = htonl(2);
2734 tcph.th_flags = TH_ACK;
2735 p->payload_len = 0;
2737
2738 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
2739 printf("failed in processing packet\n");
2740 goto end;
2741 }
2742
2743 TcpStream *stream = &(((TcpSession *)p->flow->protoctx)->client);
2744 FAIL_IF(STREAM_RAW_PROGRESS(stream) != 0); // no detect no progress update
2745
2747
2748 ret = 1;
2749end:
2750 SCFree(p);
2751 FLOW_DESTROY(&f);
2753 return ret;
2754}
2755
2756/**
2757 * \test Test the validation of the ACK number before setting up the
2758 * stream.last_ack.
2759 *
2760 * \retval On success it returns 1 and on failure 0.
2761 */
2762
2763static int StreamTcpTest38(void)
2764{
2765 int ret = 0;
2766 Flow f;
2767 ThreadVars tv;
2768 StreamTcpThread stt;
2769 uint8_t payload[128];
2770 TCPHdr tcph;
2772
2773 memset(&f, 0, sizeof(Flow));
2774 memset(&tv, 0, sizeof(ThreadVars));
2775 memset(&stt, 0, sizeof(StreamTcpThread));
2776 memset(&tcph, 0, sizeof(TCPHdr));
2777 memset(&pq, 0, sizeof(PacketQueueNoLock));
2778
2780 FAIL_IF_NULL(p);
2781
2782 FLOW_INITIALIZE(&f);
2783 p->flow = &f;
2784 tcph.th_win = htons(5480);
2785 tcph.th_flags = TH_SYN;
2786 UTHSetTCPHdr(p, &tcph);
2788
2789 StreamTcpUTInit(&stt.ra_ctx);
2790 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2791 printf("failed in processing packet in StreamTcpPacket\n");
2792 goto end;
2793 }
2794
2795 tcph.th_ack = htonl(1);
2796 tcph.th_flags = TH_SYN | TH_ACK;
2798
2799 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2800 printf("failed in processing packet in StreamTcpPacket\n");
2801 goto end;
2802 }
2803
2804 tcph.th_ack = htonl(1);
2805 tcph.th_seq = htonl(1);
2806 tcph.th_flags = TH_ACK;
2808
2809 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2810 printf("failed in processing packet in StreamTcpPacket\n");
2811 goto end;
2812 }
2813
2814 tcph.th_ack = htonl(29847);
2815 tcph.th_seq = htonl(2);
2816 tcph.th_flags = TH_PUSH | TH_ACK;
2818
2819 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2820 p->payload = payload;
2821 p->payload_len = 3;
2822
2823 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2824 printf("failed in processing packet in StreamTcpPacket\n");
2825 goto end;
2826 }
2827
2828 /* last_ack value should be 1 as the previous sent ACK value is out of
2829 window */
2830 if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 1) {
2831 printf("the server.last_ack should be 1, but it is %" PRIu32 "\n",
2832 ((TcpSession *)(p->flow->protoctx))->server.last_ack);
2833 goto end;
2834 }
2835
2836 tcph.th_ack = htonl(1);
2837 tcph.th_seq = htonl(1);
2838 tcph.th_flags = TH_PUSH | TH_ACK;
2840
2841 StreamTcpCreateTestPacket(payload, 0x41, 127, 128); /*AAA*/
2842 p->payload = payload;
2843 p->payload_len = 127;
2844
2845 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2846 printf("failed in processing packet in StreamTcpPacket\n");
2847 goto end;
2848 }
2849
2850 if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 128) {
2851 printf("the server.next_seq should be 128, but it is %" PRIu32 "\n",
2852 ((TcpSession *)(p->flow->protoctx))->server.next_seq);
2853 goto end;
2854 }
2855
2856 tcph.th_ack = htonl(256); // in window, but beyond next_seq
2857 tcph.th_seq = htonl(5);
2858 tcph.th_flags = TH_PUSH | TH_ACK;
2860
2861 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2862 p->payload = payload;
2863 p->payload_len = 3;
2864
2865 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2866 printf("failed in processing packet in StreamTcpPacket\n");
2867 goto end;
2868 }
2869
2870 /* last_ack value should be 256, as the previous sent ACK value
2871 is inside window */
2872 if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 256) {
2873 printf("the server.last_ack should be 1, but it is %" PRIu32 "\n",
2874 ((TcpSession *)(p->flow->protoctx))->server.last_ack);
2875 goto end;
2876 }
2877
2878 tcph.th_ack = htonl(128);
2879 tcph.th_seq = htonl(8);
2880 tcph.th_flags = TH_PUSH | TH_ACK;
2882
2883 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2884 p->payload = payload;
2885 p->payload_len = 3;
2886
2887 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2888 printf("failed in processing packet in StreamTcpPacket\n");
2889 goto end;
2890 }
2891
2892 /* last_ack value should be 256 as the previous sent ACK value is inside
2893 window */
2894 if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 256) {
2895 printf("the server.last_ack should be 256, but it is %" PRIu32 "\n",
2896 ((TcpSession *)(p->flow->protoctx))->server.last_ack);
2897 goto end;
2898 }
2899
2900 ret = 1;
2901
2902end:
2904 SCFree(p);
2905 FLOW_DESTROY(&f);
2907 return ret;
2908}
2909
2910/**
2911 * \test Test the validation of the ACK number before setting up the
2912 * stream.last_ack and update the next_seq after loosing the .
2913 *
2914 * \retval On success it returns 1 and on failure 0.
2915 */
2916
2917static int StreamTcpTest39(void)
2918{
2919 Flow f;
2920 ThreadVars tv;
2921 StreamTcpThread stt;
2922 uint8_t payload[4];
2923 TCPHdr tcph;
2925
2926 memset(&f, 0, sizeof(Flow));
2927 memset(&tv, 0, sizeof(ThreadVars));
2928 memset(&stt, 0, sizeof(StreamTcpThread));
2929 memset(&tcph, 0, sizeof(TCPHdr));
2930 memset(&pq, 0, sizeof(PacketQueueNoLock));
2931
2933 FAIL_IF_NULL(p);
2934
2935 FLOW_INITIALIZE(&f);
2936 p->flow = &f;
2937 tcph.th_win = htons(5480);
2938 tcph.th_flags = TH_SYN;
2939 UTHSetTCPHdr(p, &tcph);
2941 int ret = 0;
2942
2943 StreamTcpUTInit(&stt.ra_ctx);
2944
2945 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2946 printf("failed in processing packet in StreamTcpPacket\n");
2947 goto end;
2948 }
2949
2950 tcph.th_ack = htonl(1);
2951 tcph.th_flags = TH_SYN | TH_ACK;
2953
2954 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2955 printf("failed in processing packet in StreamTcpPacket\n");
2956 goto end;
2957 }
2958
2959 tcph.th_ack = htonl(1);
2960 tcph.th_seq = htonl(1);
2961 tcph.th_flags = TH_ACK;
2963
2964 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2965 printf("failed in processing packet in StreamTcpPacket\n");
2966 goto end;
2967 }
2968
2969 tcph.th_ack = htonl(1);
2970 tcph.th_seq = htonl(1);
2971 tcph.th_flags = TH_PUSH | TH_ACK;
2973
2974 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2975 p->payload = payload;
2976 p->payload_len = 3;
2977
2978 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2979 printf("failed in processing packet in StreamTcpPacket\n");
2980 goto end;
2981 }
2982
2983 if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 4) {
2984 printf("the server.next_seq should be 4, but it is %" PRIu32 "\n",
2985 ((TcpSession *)(p->flow->protoctx))->server.next_seq);
2986 goto end;
2987 }
2988
2989 tcph.th_ack = htonl(4);
2990 tcph.th_seq = htonl(2);
2991 tcph.th_flags = TH_PUSH | TH_ACK;
2993
2994 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2995 p->payload = payload;
2996 p->payload_len = 3;
2997
2998 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2999 printf("failed in processing packet in StreamTcpPacket\n");
3000 goto end;
3001 }
3002
3003 /* last_ack value should be 4 as the previous sent ACK value is inside
3004 window */
3005 if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 4) {
3006 printf("the server.last_ack should be 4, but it is %" PRIu32 "\n",
3007 ((TcpSession *)(p->flow->protoctx))->server.last_ack);
3008 goto end;
3009 }
3010
3011 tcph.th_seq = htonl(4);
3012 tcph.th_ack = htonl(5);
3013 tcph.th_flags = TH_PUSH | TH_ACK;
3015
3016 StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
3017 p->payload = payload;
3018 p->payload_len = 3;
3019
3020 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3021 printf("failed in processing packet in StreamTcpPacket\n");
3022 goto end;
3023 }
3024
3025 /* next_seq value should be 2987 as the previous sent ACK value is inside
3026 window */
3027 if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 7) {
3028 printf("the server.next_seq should be 7, but it is %" PRIu32 "\n",
3029 ((TcpSession *)(p->flow->protoctx))->server.next_seq);
3030 goto end;
3031 }
3032
3033 ret = 1;
3034
3035end:
3037 SCFree(p);
3038 FLOW_DESTROY(&f);
3040 return ret;
3041}
3042
3043/** \test multiple different SYN/ACK, pick first */
3044static int StreamTcpTest42(void)
3045{
3046 int ret = 0;
3047 Flow f;
3048 ThreadVars tv;
3049 StreamTcpThread stt;
3050 TCPHdr tcph;
3053 FAIL_IF_NULL(p);
3054 TcpSession *ssn;
3055
3056 memset(&pq, 0, sizeof(PacketQueueNoLock));
3057 memset(&f, 0, sizeof(Flow));
3058 memset(&tv, 0, sizeof(ThreadVars));
3059 memset(&stt, 0, sizeof(StreamTcpThread));
3060 memset(&tcph, 0, sizeof(TCPHdr));
3061
3062 StreamTcpUTInit(&stt.ra_ctx);
3063
3064 FLOW_INITIALIZE(&f);
3065 UTHSetTCPHdr(p, &tcph);
3066 tcph.th_win = htons(5480);
3067 p->flow = &f;
3068
3069 /* SYN pkt */
3070 tcph.th_flags = TH_SYN;
3071 tcph.th_seq = htonl(100);
3073
3074 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3075 goto end;
3076
3077 /* SYN/ACK */
3078 tcph.th_seq = htonl(500);
3079 tcph.th_ack = htonl(101);
3080 tcph.th_flags = TH_SYN | TH_ACK;
3082
3083 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3084 goto end;
3085
3086 /* SYN/ACK */
3087 tcph.th_seq = htonl(1000);
3088 tcph.th_ack = htonl(101);
3089 tcph.th_flags = TH_SYN | TH_ACK;
3091
3092 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3093 goto end;
3094
3095 /* ACK */
3096 tcph.th_ack = htonl(501);
3097 tcph.th_seq = htonl(101);
3098 tcph.th_flags = TH_ACK;
3100
3101 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3102 goto end;
3103
3104 ssn = p->flow->protoctx;
3105
3106 if (ssn->state != TCP_ESTABLISHED) {
3107 printf("state not TCP_ESTABLISHED: ");
3108 goto end;
3109 }
3110
3111 if (ssn->server.isn != 500) {
3112 SCLogDebug("ssn->server.isn %" PRIu32 " != %" PRIu32 "", ssn->server.isn, 500);
3113 goto end;
3114 }
3115 if (ssn->client.isn != 100) {
3116 SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
3117 goto end;
3118 }
3119
3121
3122 ret = 1;
3123end:
3124 SCFree(p);
3125 FLOW_DESTROY(&f);
3127 return ret;
3128}
3129
3130/** \test multiple different SYN/ACK, pick second */
3131static int StreamTcpTest43(void)
3132{
3133 int ret = 0;
3134 Flow f;
3135 ThreadVars tv;
3136 StreamTcpThread stt;
3137 TCPHdr tcph;
3140 FAIL_IF_NULL(p);
3141 TcpSession *ssn;
3142
3143 memset(&pq, 0, sizeof(PacketQueueNoLock));
3144 memset(&f, 0, sizeof(Flow));
3145 memset(&tv, 0, sizeof(ThreadVars));
3146 memset(&stt, 0, sizeof(StreamTcpThread));
3147 memset(&tcph, 0, sizeof(TCPHdr));
3148
3149 StreamTcpUTInit(&stt.ra_ctx);
3150
3151 FLOW_INITIALIZE(&f);
3152 UTHSetTCPHdr(p, &tcph);
3153 tcph.th_win = htons(5480);
3154 p->flow = &f;
3155
3156 /* SYN pkt */
3157 tcph.th_flags = TH_SYN;
3158 tcph.th_seq = htonl(100);
3160
3161 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3162 goto end;
3163
3164 /* SYN/ACK */
3165 tcph.th_seq = htonl(500);
3166 tcph.th_ack = htonl(101);
3167 tcph.th_flags = TH_SYN | TH_ACK;
3169
3170 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3171 goto end;
3172
3173 /* SYN/ACK */
3174 tcph.th_seq = htonl(1000);
3175 tcph.th_ack = htonl(101);
3176 tcph.th_flags = TH_SYN | TH_ACK;
3178
3179 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3180 goto end;
3181
3182 /* ACK */
3183 tcph.th_ack = htonl(1001);
3184 tcph.th_seq = htonl(101);
3185 tcph.th_flags = TH_ACK;
3187
3188 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3189 goto end;
3190
3191 ssn = p->flow->protoctx;
3192
3193 if (ssn->state != TCP_ESTABLISHED) {
3194 printf("state not TCP_ESTABLISHED: ");
3195 goto end;
3196 }
3197
3198 if (ssn->server.isn != 1000) {
3199 SCLogDebug("ssn->server.isn %" PRIu32 " != %" PRIu32 "", ssn->server.isn, 1000);
3200 goto end;
3201 }
3202 if (ssn->client.isn != 100) {
3203 SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
3204 goto end;
3205 }
3206
3208
3209 ret = 1;
3210end:
3211 SCFree(p);
3212 FLOW_DESTROY(&f);
3214 return ret;
3215}
3216
3217/** \test multiple different SYN/ACK, pick neither */
3218static int StreamTcpTest44(void)
3219{
3220 int ret = 0;
3221 Flow f;
3222 ThreadVars tv;
3223 StreamTcpThread stt;
3224 TCPHdr tcph;
3227 FAIL_IF_NULL(p);
3228 TcpSession *ssn;
3229
3230 memset(&pq, 0, sizeof(PacketQueueNoLock));
3231 memset(&f, 0, sizeof(Flow));
3232 memset(&tv, 0, sizeof(ThreadVars));
3233 memset(&stt, 0, sizeof(StreamTcpThread));
3234 memset(&tcph, 0, sizeof(TCPHdr));
3235
3236 StreamTcpUTInit(&stt.ra_ctx);
3237
3238 FLOW_INITIALIZE(&f);
3239 UTHSetTCPHdr(p, &tcph);
3240 tcph.th_win = htons(5480);
3241 p->flow = &f;
3242
3243 /* SYN pkt */
3244 tcph.th_flags = TH_SYN;
3245 tcph.th_seq = htonl(100);
3247
3248 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3249 goto end;
3250
3251 /* SYN/ACK */
3252 tcph.th_seq = htonl(500);
3253 tcph.th_ack = htonl(101);
3254 tcph.th_flags = TH_SYN | TH_ACK;
3256
3257 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3258 goto end;
3259
3260 /* SYN/ACK */
3261 tcph.th_seq = htonl(1000);
3262 tcph.th_ack = htonl(101);
3263 tcph.th_flags = TH_SYN | TH_ACK;
3265
3266 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3267 goto end;
3268
3269 /* ACK */
3270 tcph.th_ack = htonl(3001);
3271 tcph.th_seq = htonl(101);
3272 tcph.th_flags = TH_ACK;
3274
3275 if (StreamTcpPacket(&tv, p, &stt, &pq) != -1)
3276 goto end;
3277
3278 ssn = p->flow->protoctx;
3279
3280 if (ssn->state != TCP_SYN_RECV) {
3281 SCLogDebug("state not TCP_SYN_RECV");
3282 goto end;
3283 }
3284
3285 if (ssn->client.isn != 100) {
3286 SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
3287 goto end;
3288 }
3289
3291
3292 ret = 1;
3293end:
3294 SCFree(p);
3295 FLOW_DESTROY(&f);
3297 return ret;
3298}
3299
3300/** \test multiple different SYN/ACK, over the limit */
3301static int StreamTcpTest45(void)
3302{
3303 int ret = 0;
3304 Flow f;
3305 ThreadVars tv;
3306 StreamTcpThread stt;
3307 TCPHdr tcph;
3310 FAIL_IF_NULL(p);
3311 TcpSession *ssn;
3312
3313 memset(&pq, 0, sizeof(PacketQueueNoLock));
3314 memset(&f, 0, sizeof(Flow));
3315 memset(&tv, 0, sizeof(ThreadVars));
3316 memset(&stt, 0, sizeof(StreamTcpThread));
3317 memset(&tcph, 0, sizeof(TCPHdr));
3318
3319 StreamTcpUTInit(&stt.ra_ctx);
3321
3322 FLOW_INITIALIZE(&f);
3323 UTHSetTCPHdr(p, &tcph);
3324 tcph.th_win = htons(5480);
3325 p->flow = &f;
3326
3327 /* SYN pkt */
3328 tcph.th_flags = TH_SYN;
3329 tcph.th_seq = htonl(100);
3331
3332 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3333 goto end;
3334
3335 /* SYN/ACK */
3336 tcph.th_seq = htonl(500);
3337 tcph.th_ack = htonl(101);
3338 tcph.th_flags = TH_SYN | TH_ACK;
3340
3341 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3342 goto end;
3343
3344 /* SYN/ACK */
3345 tcph.th_seq = htonl(1000);
3346 tcph.th_ack = htonl(101);
3347 tcph.th_flags = TH_SYN | TH_ACK;
3349
3350 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3351 goto end;
3352
3353 /* SYN/ACK */
3354 tcph.th_seq = htonl(2000);
3355 tcph.th_ack = htonl(101);
3356 tcph.th_flags = TH_SYN | TH_ACK;
3358
3359 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3360 goto end;
3361
3362 /* SYN/ACK */
3363 tcph.th_seq = htonl(3000);
3364 tcph.th_ack = htonl(101);
3365 tcph.th_flags = TH_SYN | TH_ACK;
3367
3368 if (StreamTcpPacket(&tv, p, &stt, &pq) != -1)
3369 goto end;
3370
3371 /* ACK */
3372 tcph.th_ack = htonl(1001);
3373 tcph.th_seq = htonl(101);
3374 tcph.th_flags = TH_ACK;
3376
3377 if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3378 goto end;
3379
3380 ssn = p->flow->protoctx;
3381
3382 if (ssn->state != TCP_ESTABLISHED) {
3383 printf("state not TCP_ESTABLISHED: ");
3384 goto end;
3385 }
3386
3387 if (ssn->server.isn != 1000) {
3388 SCLogDebug("ssn->server.isn %" PRIu32 " != %" PRIu32 "", ssn->server.isn, 1000);
3389 goto end;
3390 }
3391 if (ssn->client.isn != 100) {
3392 SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
3393 goto end;
3394 }
3395
3397
3398 ret = 1;
3399end:
3400 SCFree(p);
3402 return ret;
3403}
3404
3406{
3407 UtRegisterTest("StreamTcpTest01 -- TCP session allocation", StreamTcpTest01);
3408 UtRegisterTest("StreamTcpTest02 -- TCP session deallocation", StreamTcpTest02);
3409 UtRegisterTest("StreamTcpTest03 -- SYN missed MidStream session", StreamTcpTest03);
3410 UtRegisterTest("StreamTcpTest04 -- SYN/ACK missed MidStream session", StreamTcpTest04);
3411 UtRegisterTest("StreamTcpTest05 -- 3WHS missed MidStream session", StreamTcpTest05);
3412 UtRegisterTest("StreamTcpTest06 -- FIN, RST message MidStream session", StreamTcpTest06);
3413 UtRegisterTest("StreamTcpTest07 -- PAWS invalid timestamp", StreamTcpTest07);
3414 UtRegisterTest("StreamTcpTest08 -- PAWS valid timestamp", StreamTcpTest08);
3415 UtRegisterTest("StreamTcpTest09 -- No Client Reassembly", StreamTcpTest09);
3416 UtRegisterTest("StreamTcpTest10 -- No missed packet Async stream", StreamTcpTest10);
3417 UtRegisterTest("StreamTcpTest11 -- SYN missed Async stream", StreamTcpTest11);
3418 UtRegisterTest("StreamTcpTest12 -- SYN/ACK missed Async stream", StreamTcpTest12);
3419 UtRegisterTest("StreamTcpTest13 -- opposite stream packets for Async "
3420 "stream",
3421 StreamTcpTest13);
3422 UtRegisterTest("StreamTcp4WHSTest01", StreamTcp4WHSTest01);
3423 UtRegisterTest("StreamTcp4WHSTest02", StreamTcp4WHSTest02);
3424 UtRegisterTest("StreamTcp4WHSTest03", StreamTcp4WHSTest03);
3425 UtRegisterTest("StreamTcpTest14 -- setup OS policy", StreamTcpTest14);
3426 UtRegisterTest("StreamTcpTest15 -- setup OS policy", StreamTcpTest15);
3427 UtRegisterTest("StreamTcpTest16 -- setup OS policy", StreamTcpTest16);
3428 UtRegisterTest("StreamTcpTest17 -- setup OS policy", StreamTcpTest17);
3429 UtRegisterTest("StreamTcpTest18 -- setup OS policy", StreamTcpTest18);
3430 UtRegisterTest("StreamTcpTest19 -- setup OS policy", StreamTcpTest19);
3431 UtRegisterTest("StreamTcpTest20 -- setup OS policy", StreamTcpTest20);
3432 UtRegisterTest("StreamTcpTest21 -- setup OS policy", StreamTcpTest21);
3433 UtRegisterTest("StreamTcpTest22 -- setup OS policy", StreamTcpTest22);
3434 UtRegisterTest("StreamTcpTest23 -- stream memory leaks", StreamTcpTest23);
3435 UtRegisterTest("StreamTcpTest24 -- stream memory leaks", StreamTcpTest24);
3436 UtRegisterTest("StreamTcpTest25 -- test ecn/cwr sessions", StreamTcpTest25);
3437 UtRegisterTest("StreamTcpTest26 -- test ecn/cwr sessions", StreamTcpTest26);
3438 UtRegisterTest("StreamTcpTest27 -- test ecn/cwr sessions", StreamTcpTest27);
3439 UtRegisterTest("StreamTcpTest28 -- Memcap Test", StreamTcpTest28);
3440
3441#if 0 /* VJ 2010/09/01 disabled since they blow up on Fedora and Fedora is \
3442 * right about blowing up. The checksum functions are not used properly \
3443 * in the tests. */
3444 UtRegisterTest("StreamTcpTest29 -- Badchecksum Reset Test", StreamTcpTest29, 1);
3445 UtRegisterTest("StreamTcpTest30 -- Badchecksum Overlap Test", StreamTcpTest30, 1);
3446 UtRegisterTest("StreamTcpTest31 -- MultipleSyns Test", StreamTcpTest31, 1);
3447 UtRegisterTest("StreamTcpTest32 -- Bogus CWR Test", StreamTcpTest32, 1);
3448 UtRegisterTest("StreamTcpTest33 -- RST-SYN Again Test", StreamTcpTest33, 1);
3449 UtRegisterTest("StreamTcpTest34 -- SYN-PUSH Test", StreamTcpTest34, 1);
3450 UtRegisterTest("StreamTcpTest35 -- SYN-URG Test", StreamTcpTest35, 1);
3451 UtRegisterTest("StreamTcpTest36 -- PUSH-URG Test", StreamTcpTest36, 1);
3452#endif
3453 UtRegisterTest("StreamTcpTest37 -- Out of order FIN Test", StreamTcpTest37);
3454
3455 UtRegisterTest("StreamTcpTest38 -- validate ACK", StreamTcpTest38);
3456 UtRegisterTest("StreamTcpTest39 -- update next_seq", StreamTcpTest39);
3457
3458 UtRegisterTest("StreamTcpTest42 -- SYN/ACK queue", StreamTcpTest42);
3459 UtRegisterTest("StreamTcpTest43 -- SYN/ACK queue", StreamTcpTest43);
3460 UtRegisterTest("StreamTcpTest44 -- SYN/ACK queue", StreamTcpTest44);
3461 UtRegisterTest("StreamTcpTest45 -- SYN/ACK queue", StreamTcpTest45);
3462
3463 /* set up the reassembly tests as well */
3465
3467}
int SCConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
void SCConfInit(void)
Initialize the configuration system.
Definition conf.c:120
void SCConfDeInit(void)
De-initializes the configuration system.
Definition conf.c:703
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition conf.c:350
void SCConfCreateContextBackup(void)
Creates a backup of the conf_hash hash_table used by the conf API.
Definition conf.c:684
void SCConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition conf.c:694
#define TH_FIN
Definition decode-tcp.h:34
#define TH_ACK
Definition decode-tcp.h:38
#define TH_CWR
Definition decode-tcp.h:43
#define TH_PUSH
Definition decode-tcp.h:37
#define TH_RST
Definition decode-tcp.h:36
#define TH_SYN
Definition decode-tcp.h:35
#define TH_ECN
Definition decode-tcp.h:41
#define FLOW_INITIALIZE(f)
Definition flow-util.h:38
#define FLOW_DESTROY(f)
Definition flow-util.h:119
#define FLOW_PKT_TOSERVER
Definition flow.h:233
#define FLOW_PKT_TOCLIENT
Definition flow.h:234
ThreadVars * tv
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition decode.c:258
#define STREAMTCP_FLAG_ASYNC
#define TCP_SEG_LEN(seg)
@ TCP_ESTABLISHED
@ TCP_SYN_RECV
@ TCP_CLOSE_WAIT
#define STREAMTCP_FLAG_4WHS
#define STREAM_RAW_PROGRESS(stream)
void StreamTcpReassembleRegisterTests(void)
The Function Register the Unit tests to test the reassembly engine for various OS policies.
int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p)
void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t)
The Function to create the packet with given payload, which is used to test the reassembly of the eng...
@ OS_POLICY_WINDOWS
@ OS_POLICY_LINUX
@ OS_POLICY_BSD
#define OS_POLICY_DEFAULT
void StreamTcpSackRegisterTests(void)
void StreamTcpUTSetupSession(TcpSession *ssn)
void StreamTcpUTClearSession(TcpSession *ssn)
void StreamTcpUTInit(TcpReassemblyThreadCtx **ra_ctx)
void StreamTcpUTDeinit(TcpReassemblyThreadCtx *ra_ctx)
void StreamTcpSetOSPolicy(TcpStream *, Packet *)
Function to set the OS policy for the given stream based on the destination of the received packet.
void StreamTcpIncrMemuse(uint64_t size)
Definition stream-tcp.c:228
void StreamTcpDecrMemuse(uint64_t size)
Definition stream-tcp.c:234
int StreamTcpCheckMemcap(uint64_t size)
Check if alloc'ing "size" would mean we're over memcap.
Definition stream-tcp.c:266
void StreamTcpSetSessionNoReassemblyFlag(TcpSession *ssn, char direction)
disable reassembly
TcpStreamCnf stream_config
Definition stream-tcp.c:219
int StreamTcpPacket(ThreadVars *tv, Packet *p, StreamTcpThread *stt, PacketQueueNoLock *pq)
void StreamTcpSessionClear(void *ssnptr)
Function to return the stream back to the pool. It returns the segments in the stream to the segment ...
Definition stream-tcp.c:351
void StreamTcpSessionPktFree(Packet *p)
Function to return the stream segments back to the pool.
Definition stream-tcp.c:380
uint32_t address_un_data32[4]
Definition decode.h:115
union Address_::@30 address
char family
Definition decode.h:113
Flow data structure.
Definition flow.h:356
void * protoctx
Definition flow.h:441
AppLayerParserState * alparser
Definition flow.h:478
union PacketL4::L4Vars vars
simple fifo queue for packets
struct PacketL4 l4
Definition decode.h:601
uint8_t flowflags
Definition decode.h:532
Address src
Definition decode.h:505
struct Flow_ * flow
Definition decode.h:546
uint8_t * payload
Definition decode.h:605
uint16_t payload_len
Definition decode.h:606
Address dst
Definition decode.h:506
uint8_t proto
Definition decode.h:523
TcpReassemblyThreadCtx * ra_ctx
Definition stream-tcp.h:117
uint16_t th_win
Definition decode-tcp.h:156
uint32_t th_seq
Definition decode-tcp.h:152
uint32_t th_ack
Definition decode-tcp.h:153
uint8_t th_flags
Definition decode-tcp.h:155
uint32_t ts_val
Definition decode-tcp.h:176
uint32_t ts_ecr
Definition decode-tcp.h:177
uint8_t ts_set
Definition decode-tcp.h:166
bool async_oneside
Definition stream-tcp.h:71
uint8_t max_synack_queued
Definition stream-tcp.h:66
struct TCPSEG seg_tree
Per thread variable structure.
Definition threadvars.h:58
size_t strlcpy(char *dst, const char *src, size_t siz)
#define SET_ISN(stream, setseq)
Definition stream-tcp.c:30
void StreamTcpRegisterTests(void)
#define RB_MIN(name, x)
Definition tree.h:778
#define RB_MAX(name, x)
Definition tree.h:779
TCPVars tcp
Definition decode.h:478
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnCharPtr(x)
Definition util-debug.h:289
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
int SCHInfoAddHostOSInfo(const char *host_os, const char *host_os_ip_range, int is_ipv4)
Used to add the host-os-info data obtained from the conf.
void SCHInfoCleanResources(void)
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define unlikely(expr)
void UTHSetIPV4Hdr(Packet *p, IPV4Hdr *ip4h)
void UTHSetTCPHdr(Packet *p, TCPHdr *tcph)