Coverage Report

Created: 2026-02-14 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/util-print.c
Line
Count
Source
1
/* Copyright (C) 2007-2010 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
 * Print utility functions
24
 */
25
26
#include "suricata-common.h"
27
#include "util-print.h"
28
#include "util-error.h"
29
#include "util-debug.h"
30
#include "util-validate.h"
31
#include "rust.h"
32
33
/**
34
 *  \brief print a buffer as hex on a single line
35
 *
36
 *  Prints in the format "00 AA BB"
37
 *
38
 *  \param nbuf buffer into which the output is written
39
 *  \param offset of where to start writing into the buffer
40
 *  \param max_size the size of the output buffer
41
 *  \param buf buffer to print from
42
 *  \param buflen length of the input buffer
43
 */
44
void PrintBufferRawLineHex(char *nbuf, int *offset, int max_size, const uint8_t *buf, uint32_t buflen)
45
1.15k
{
46
1.15k
    uint32_t u = 0;
47
48
36.2k
    for (u = 0; u < buflen; u++) {
49
35.0k
        PrintBufferData(nbuf, offset, max_size, "%02X ", buf[u]);
50
35.0k
    }
51
1.15k
}
52
53
/**
54
 *  \brief print a buffer as hex on a single line into retbuf buffer
55
 *
56
 *  Prints in the format "00 AA BB"
57
 *
58
 *  \param retbuf pointer to the buffer which will have the result
59
 *  \param rebuflen length of the buffer
60
 *  \param buf buffer to print from
61
 *  \param buflen length of the input buffer
62
 */
63
void PrintRawLineHexBuf(char *retbuf, uint32_t retbuflen, const uint8_t *buf, uint32_t buflen)
64
0
{
65
0
    uint32_t offset = 0;
66
0
    uint32_t u = 0;
67
68
0
    for (u = 0; u < buflen; u++) {
69
0
        PrintBufferData(retbuf, &offset, retbuflen, "%02X ", buf[u]);
70
0
    }
71
0
}
72
73
void PrintRawJsonFp(FILE *fp, uint8_t *buf, uint32_t buflen)
74
0
{
75
0
#define BUFFER_LENGTH 2048
76
0
    char nbuf[BUFFER_LENGTH] = "";
77
0
    uint32_t offset = 0;
78
0
    uint32_t u = 0;
79
80
0
    for (u = 0; u < buflen; u++) {
81
0
        if (buf[u] == '\\' || buf[u] == '/' || buf[u] == '\"') {
82
0
            PrintBufferData(nbuf, &offset, BUFFER_LENGTH,
83
0
                             "\\%c", buf[u]);
84
0
        } else if (isprint(buf[u])) {
85
0
            PrintBufferData(nbuf, &offset, BUFFER_LENGTH,
86
0
                             "%c", buf[u]);
87
0
        } else {
88
0
            PrintBufferData(nbuf, &offset, BUFFER_LENGTH,
89
0
                            "\\\\x%02X", buf[u]);
90
0
        }
91
0
    }
92
0
    fprintf(fp, "%s", nbuf);
93
0
}
94
95
void PrintRawUriFp(FILE *fp, uint8_t *buf, uint32_t buflen)
96
0
{
97
0
#define BUFFER_LENGTH 2048
98
0
    char nbuf[BUFFER_LENGTH] = "";
99
0
    uint32_t offset = 0;
100
0
    uint32_t u = 0;
101
102
0
    for (u = 0; u < buflen; u++) {
103
0
        if (isprint(buf[u]) && buf[u] != '\"') {
104
0
            if (buf[u] == '\\') {
105
0
                PrintBufferData(nbuf, &offset, BUFFER_LENGTH,
106
0
                                "\\\\");
107
0
            } else {
108
0
                PrintBufferData(nbuf, &offset, BUFFER_LENGTH,
109
0
                                "%c", buf[u]);
110
0
            }
111
0
        } else {
112
0
            PrintBufferData(nbuf, &offset, BUFFER_LENGTH,
113
0
                            "\\x%02X", buf[u]);
114
0
        }
115
0
    }
116
117
0
    fprintf(fp, "%s", nbuf);
118
0
}
119
120
void PrintRawUriBuf(char *retbuf, uint32_t *offset, uint32_t retbuflen,
121
                    uint8_t *buf, uint32_t buflen)
122
195k
{
123
195k
    uint32_t u = 0;
124
125
10.4M
    for (u = 0; u < buflen; u++) {
126
10.2M
        if (isprint(buf[u]) && buf[u] != '\"') {
127
5.26M
            if (buf[u] == '\\') {
128
19.0k
                PrintBufferData(retbuf, offset, retbuflen,
129
19.0k
                                "\\\\");
130
5.24M
            } else {
131
5.24M
                PrintBufferData(retbuf, offset, retbuflen,
132
5.24M
                                "%c", buf[u]);
133
5.24M
            }
134
5.26M
        } else {
135
5.03M
            PrintBufferData(retbuf, offset, retbuflen,
136
5.03M
                            "\\x%02X", buf[u]);
137
5.03M
        }
138
10.2M
    }
139
140
195k
    return;
141
195k
}
142
143
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
144
0
{
145
0
    int ch = 0;
146
0
    uint32_t u = 0;
147
148
0
    if (buf == NULL) {
149
0
        fprintf(fp, " (null)\n");
150
0
        return;
151
0
    }
152
0
    for (u = 0; u < buflen; u+=16) {
153
0
        fprintf(fp ," %04X  ", u);
154
0
        for (ch = 0; (u+ch) < buflen && ch < 16; ch++) {
155
0
             fprintf(fp, "%02X ", (uint8_t)buf[u+ch]);
156
157
0
             if (ch == 7) fprintf(fp, " ");
158
0
        }
159
0
        if (ch == 16) fprintf(fp, "  ");
160
0
        else if (ch < 8) {
161
0
            int spaces = (16 - ch) * 3 + 2 + 1;
162
0
            int s = 0;
163
0
            for ( ; s < spaces; s++) fprintf(fp, " ");
164
0
        } else if(ch < 16) {
165
0
            int spaces = (16 - ch) * 3 + 2;
166
0
            int s = 0;
167
0
            for ( ; s < spaces; s++) fprintf(fp, " ");
168
0
        }
169
170
0
        for (ch = 0; (u+ch) < buflen && ch < 16; ch++) {
171
0
             fprintf(fp, "%c", isprint((uint8_t)buf[u+ch]) ? (uint8_t)buf[u+ch] : '.');
172
173
0
             if (ch == 7)  fprintf(fp, " ");
174
0
             if (ch == 15) fprintf(fp, "\n");
175
0
        }
176
0
    }
177
0
    if (ch != 16)
178
0
        fprintf(fp, "\n");
179
0
}
180
181
void PrintRawDataToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size,
182
                          const uint8_t *src_buf, uint32_t src_buf_len)
183
0
{
184
0
    int ch = 0;
185
0
    uint32_t u = 0;
186
187
0
    for (u = 0; u < src_buf_len; u+=16) {
188
0
        PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size,
189
0
                        " %04X  ", u);
190
0
        for (ch = 0; (u + ch) < src_buf_len && ch < 16; ch++) {
191
0
            PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size,
192
0
                            "%02X ", (uint8_t)src_buf[u + ch]);
193
194
0
            if (ch == 7) {
195
0
                PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size,
196
0
                                " ");
197
0
            }
198
0
        }
199
0
        if (ch == 16) {
200
0
            PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, "  ");
201
0
        } else if (ch < 8) {
202
0
            int spaces = (16 - ch) * 3 + 2 + 1;
203
0
            int s = 0;
204
0
            for ( ; s < spaces; s++)
205
0
                PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " ");
206
0
        } else if(ch < 16) {
207
0
            int spaces = (16 - ch) * 3 + 2;
208
0
            int s = 0;
209
0
            for ( ; s < spaces; s++)
210
0
                PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " ");
211
0
        }
212
213
0
        for (ch = 0; (u+ch) < src_buf_len && ch < 16; ch++) {
214
0
            PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size,
215
0
                            "%c",
216
0
                            isprint((uint8_t)src_buf[u + ch]) ? (uint8_t)src_buf[u + ch] : '.');
217
218
0
             if (ch == 7)
219
0
                 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " ");
220
0
             if (ch == 15)
221
0
                 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, "\n");
222
0
        }
223
0
    }
224
0
    if (ch != 16)
225
0
        PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, "\n");
226
227
0
    return;
228
0
}
229
230
void PrintStringsToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size,
231
                          const uint8_t *src_buf, const uint32_t src_buf_len)
232
0
{
233
0
    uint32_t ch = 0;
234
0
    for (ch = 0; ch < src_buf_len && *dst_buf_offset_ptr < dst_buf_size;
235
0
            ch++, (*dst_buf_offset_ptr)++) {
236
0
        if (isprint((uint8_t)src_buf[ch]) || src_buf[ch] == '\n' || src_buf[ch] == '\r') {
237
0
            dst_buf[*dst_buf_offset_ptr] = src_buf[ch];
238
0
        } else {
239
0
            dst_buf[*dst_buf_offset_ptr] = '.';
240
0
        }
241
0
    }
242
0
    dst_buf[dst_buf_size - 1] = 0;
243
244
0
    return;
245
0
}
246
247
#ifndef s6_addr16
248
# define s6_addr16 __u6_addr.__u6_addr16
249
#endif
250
251
static const char *PrintInetIPv6(const void *src, char *dst, socklen_t size)
252
5.23M
{
253
5.23M
    int i;
254
5.23M
    char s_part[6];
255
5.23M
    uint16_t x[8];
256
5.23M
    memcpy(&x, src, 16);
257
258
    /* current IPv6 format is fixed size */
259
5.23M
    if (size < 8 * 5) {
260
0
        SCLogWarning("Too small buffer to write IPv6 address");
261
0
        return NULL;
262
0
    }
263
5.23M
    memset(dst, 0, size);
264
47.0M
    for(i = 0; i < 8; i++) {
265
41.8M
        snprintf(s_part, sizeof(s_part), "%04x:", htons(x[i]));
266
41.8M
        strlcat(dst, s_part, size);
267
41.8M
    }
268
    /* suppress last ':' */
269
5.23M
    dst[strlen(dst) - 1] = 0;
270
271
5.23M
    return dst;
272
5.23M
}
273
274
const char *PrintInet(int af, const void *src, char *dst, socklen_t size)
275
25.8M
{
276
25.8M
    switch (af) {
277
20.6M
        case AF_INET:
278
#if defined(OS_WIN32) && NTDDI_VERSION >= NTDDI_VISTA
279
{
280
            // because Windows has to provide a non-conformant inet_ntop, of
281
            // course!
282
            struct in_addr _src;
283
            memcpy(&_src, src, sizeof(struct in_addr));
284
            return inet_ntop(af, &_src, dst, size);
285
}
286
#else
287
20.6M
            return inet_ntop(af, src, dst, size);
288
0
#endif
289
5.23M
        case AF_INET6:
290
            /* Format IPv6 without deleting zeroes */
291
5.23M
            return PrintInetIPv6(src, dst, size);
292
0
        default:
293
0
            SCLogError("Unsupported protocol: %d", af);
294
25.8M
    }
295
0
    return NULL;
296
25.8M
}
297
298
void PrintHexString(char *str, size_t size, uint8_t *buf, size_t buf_len)
299
167k
{
300
167k
    DEBUG_VALIDATE_BUG_ON(size < 2 * buf_len);
301
167k
    rs_to_hex((uint8_t *)str, size, buf, buf_len);
302
167k
}