• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 23374838686

21 Mar 2026 07:29AM UTC coverage: 59.341% (-20.0%) from 79.315%
23374838686

Pull #15075

github

web-flow
Merge 90b4e834f into 6587e363a
Pull Request #15075: Stack 8001 v16.4

38 of 70 new or added lines in 10 files covered. (54.29%)

34165 existing lines in 563 files now uncovered.

119621 of 201584 relevant lines covered (59.34%)

650666.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

54.55
/src/stream-tcp-inline.c
1
/* Copyright (C) 2007-2016 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
/**
19
 * \file
20
 *
21
 * \author Victor Julien <victor@inliniac.net>
22
 *
23
 *  Functions for the "inline mode" of the stream engine.
24
 */
25

26
#include "suricata-common.h"
27
#include "decode.h"
28
#include "stream-tcp-private.h"
29
#include "stream-tcp-inline.h"
30

31
#include "util-memcmp.h"
32
#include "util-print.h"
33

34
#include "util-validate.h"
35
#include "util-unittest.h"
36
#include "util-unittest-helper.h"
37

38
/**
39
 *  \brief Compare the shared data portion of two segments
40
 *
41
 *  If no data is shared, 0 will be returned.
42
 *
43
 *  \param seg1 first segment
44
 *  \param seg2 second segment
45
 *
46
 *  \retval 0 shared data is the same (or no data is shared)
47
 *  \retval 1 shared data is different
48
 */
49
int StreamTcpInlineSegmentCompare(const TcpStream *stream,
50
        const Packet *p, const TcpSegment *seg)
51
{
4,616✔
52
    SCEnter();
4,616✔
53

54
    if (p == NULL || seg == NULL) {
4,616✔
55
        SCReturnInt(0);
×
56
    }
×
57

58
    DEBUG_VALIDATE_BUG_ON(SEQ_LEQ(seg->seq + TCP_SEG_LEN(seg), stream->base_seq));
4,616✔
59

60
    const uint8_t *seg_data;
4,616✔
61
    uint32_t seg_datalen;
4,616✔
62
    StreamingBufferSegmentGetData(&stream->sb, &seg->sbseg, &seg_data, &seg_datalen);
4,616✔
63
    if (seg_data == NULL || seg_datalen == 0)
4,616✔
64
        SCReturnInt(0);
×
65

66
    const TCPHdr *tcph = PacketGetTCP(p);
4,616✔
67
    const uint32_t pkt_seq = TCP_GET_RAW_SEQ(tcph);
4,616✔
68

69
    if (SEQ_EQ(pkt_seq, seg->seq) && p->payload_len == seg_datalen) {
4,616✔
70
        int r = SCMemcmp(p->payload, seg_data, seg_datalen);
2,825✔
71
        SCReturnInt(r);
2,825✔
72
    } else if (SEQ_GT(pkt_seq, (seg->seq + seg_datalen))) {
2,825✔
UNCOV
73
        SCReturnInt(0);
×
74
    } else if (SEQ_GT(seg->seq, (pkt_seq + p->payload_len))) {
1,791✔
75
        SCReturnInt(0);
×
76
    } else {
1,791✔
77
        SCLogDebug("p %u (%u), seg2 %u (%u)", pkt_seq,
1,791✔
78
                p->payload_len, seg->seq, seg_datalen);
1,791✔
79

80
        uint32_t seg_seq = seg->seq;
1,791✔
81
        if (SEQ_LT(seg_seq, stream->base_seq)) {
1,791✔
82
            seg_seq = stream->base_seq;
69✔
83
        }
69✔
84
        uint32_t pkt_end = pkt_seq + p->payload_len;
1,791✔
85
        uint32_t seg_end = seg_seq + seg_datalen;
1,791✔
86
        SCLogDebug("pkt_end %u, seg_end %u", pkt_end, seg_end);
1,791✔
87

88
        /* get the minimal seg*_end */
89
        uint32_t end = SEQ_MIN(seg_end, pkt_end);
1,791✔
90
        /* and the max seq */
91
        uint32_t seq = SEQ_MAX(pkt_seq, seg_seq);
1,791✔
92
        seq = SEQ_MAX(seq, stream->base_seq);
1,791✔
93
        SCLogDebug("seq %u, end %u", seq, end);
1,791✔
94

95
        uint32_t pkt_off = seq - pkt_seq;
1,791✔
96
        uint32_t seg_off = seq - seg_seq;
1,791✔
97
        SCLogDebug("pkt_off %u, seg_off %u", pkt_off, seg_off);
1,791✔
98

99
        uint32_t range = end - seq;
1,791✔
100
        SCLogDebug("range %u", range);
1,791✔
101
        DEBUG_VALIDATE_BUG_ON(range > 65536);
1,791✔
102

103
        if (range) {
1,791✔
104
            int r = SCMemcmp(p->payload + pkt_off, seg_data + seg_off, range);
1,791✔
105
            SCReturnInt(r);
1,791✔
106
        }
1,791✔
107
        SCReturnInt(0);
1,791✔
108
    }
1,791✔
109
}
4,616✔
110

111
/**
112
 *  \brief Replace (part of) the payload portion of a packet by the data
113
 *         in a TCP segment
114
 *
115
 *  \param p Packet
116
 *  \param seg TCP segment
117
 *
118
 *  \todo What about reassembled fragments?
119
 *  \todo What about unwrapped tunnel packets?
120
 */
121
void StreamTcpInlineSegmentReplacePacket(const TcpStream *stream,
122
        Packet *p, const TcpSegment *seg)
UNCOV
123
{
×
UNCOV
124
    SCEnter();
×
125

UNCOV
126
    const TCPHdr *tcph = PacketGetTCP(p);
×
UNCOV
127
    const uint32_t pseq = TCP_GET_RAW_SEQ(tcph);
×
UNCOV
128
    uint32_t tseq = seg->seq;
×
129

130
    /* check if segment is within the packet */
UNCOV
131
    if (tseq + TCP_SEG_LEN(seg) < pseq) {
×
132
        SCReturn;
×
UNCOV
133
    } else if (pseq + p->payload_len < tseq) {
×
134
        SCReturn;
×
135
    }
×
136

UNCOV
137
    const uint8_t *seg_data;
×
UNCOV
138
    uint32_t seg_datalen;
×
UNCOV
139
    StreamingBufferSegmentGetData(&stream->sb, &seg->sbseg, &seg_data, &seg_datalen);
×
140

UNCOV
141
    uint32_t pend = pseq + p->payload_len;
×
UNCOV
142
    uint32_t tend = tseq + seg_datalen;
×
UNCOV
143
    SCLogDebug("pend %u, tend %u", pend, tend);
×
144

145
    /* get the minimal seg*_end */
UNCOV
146
    uint32_t end = (SEQ_GT(pend, tend)) ? tend : pend;
×
147
    /* and the max seq */
UNCOV
148
    uint32_t seq = (SEQ_LT(pseq, tseq)) ? tseq : pseq;
×
UNCOV
149
    SCLogDebug("seq %u, end %u", seq, end);
×
150

UNCOV
151
    uint32_t poff = seq - pseq;
×
UNCOV
152
    uint32_t toff = seq - tseq;
×
UNCOV
153
    SCLogDebug("poff %u, toff %u", poff, toff);
×
154

UNCOV
155
    uint32_t range = end - seq;
×
UNCOV
156
    SCLogDebug("range %u", range);
×
UNCOV
157
    DEBUG_VALIDATE_BUG_ON(range > 65536);
×
158

UNCOV
159
    if (range) {
×
160
        /* update the packets payload. As payload is a ptr to either
161
         * p->pkt or p->ext_pkt that is updated as well */
UNCOV
162
        memcpy(p->payload+poff, seg_data+toff, range);
×
163

164
        /* flag as modified so we can reinject / replace after
165
         * recalculating the checksum */
UNCOV
166
        p->flags |= PKT_STREAM_MODIFIED;
×
UNCOV
167
    }
×
UNCOV
168
}
×
169

170
#ifdef UNITTESTS
171
#include "tests/stream-tcp-inline.c"
172
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc