suricata
util-print.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2023 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 */
44void PrintBufferRawLineHex(char *nbuf, int *offset, int max_size, const uint8_t *buf, uint32_t buflen)
45{
46 for (uint32_t u = 0; u < buflen; u++) {
47 PrintBufferData(nbuf, offset, max_size, "%02X ", buf[u]);
48 }
49}
50
51/**
52 * \brief print a buffer as hex on a single line into retbuf buffer
53 *
54 * Prints in the format "00 AA BB"
55 *
56 * \param retbuf pointer to the buffer which will have the result
57 * \param rebuflen length of the buffer
58 * \param buf buffer to print from
59 * \param buflen length of the input buffer
60 */
61void PrintRawLineHexBuf(char *retbuf, uint32_t retbuflen, const uint8_t *buf, uint32_t buflen)
62{
63 uint32_t offset = 0;
64 for (uint32_t u = 0; u < buflen; u++) {
65 PrintBufferData(retbuf, &offset, retbuflen, "%02X ", buf[u]);
66 }
67}
68
69void PrintRawUriFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
70{
71#define BUFFER_LENGTH 2048
72 char nbuf[BUFFER_LENGTH] = "";
73 uint32_t offset = 0;
74
75 for (uint32_t u = 0; u < buflen; u++) {
76 if (isprint(buf[u]) && buf[u] != '\"') {
77 if (buf[u] == '\\') {
79 "\\\\");
80 } else {
82 "%c", buf[u]);
83 }
84 } else {
86 "\\x%02X", buf[u]);
87 }
88 }
89
90 fprintf(fp, "%s", nbuf);
91}
92
94 char *retbuf, uint32_t *offset, uint32_t retbuflen, const uint8_t *buf, size_t buflen)
95{
96 for (size_t u = 0; u < buflen; u++) {
97 if (isprint(buf[u]) && buf[u] != '\"') {
98 if (buf[u] == '\\') {
99 PrintBufferData(retbuf, offset, retbuflen,
100 "\\\\");
101 } else {
102 PrintBufferData(retbuf, offset, retbuflen,
103 "%c", buf[u]);
104 }
105 } else {
106 PrintBufferData(retbuf, offset, retbuflen,
107 "\\x%02X", buf[u]);
108 }
109 }
110}
111
112void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
113{
114 int ch = 0;
115
116 if (buf == NULL) {
117 fprintf(fp, " (null)\n");
118 return;
119 }
120 for (uint32_t u = 0; u < buflen; u += 16) {
121 fprintf(fp ," %04X ", u);
122 for (ch = 0; (u+ch) < buflen && ch < 16; ch++) {
123 fprintf(fp, "%02X ", (uint8_t)buf[u+ch]);
124
125 if (ch == 7) fprintf(fp, " ");
126 }
127 if (ch == 16) fprintf(fp, " ");
128 else if (ch < 8) {
129 int spaces = (16 - ch) * 3 + 2 + 1;
130 int s = 0;
131 for ( ; s < spaces; s++) fprintf(fp, " ");
132 } else if(ch < 16) {
133 int spaces = (16 - ch) * 3 + 2;
134 int s = 0;
135 for ( ; s < spaces; s++) fprintf(fp, " ");
136 }
137
138 for (ch = 0; (u+ch) < buflen && ch < 16; ch++) {
139 fprintf(fp, "%c", isprint((uint8_t)buf[u+ch]) ? (uint8_t)buf[u+ch] : '.');
140
141 if (ch == 7) fprintf(fp, " ");
142 if (ch == 15) fprintf(fp, "\n");
143 }
144 }
145 if (ch != 16)
146 fprintf(fp, "\n");
147}
148
149void PrintRawDataToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size,
150 const uint8_t *src_buf, uint32_t src_buf_len)
151{
152 int ch = 0;
153
154 for (uint32_t u = 0; u < src_buf_len; u += 16) {
155 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size,
156 " %04X ", u);
157 for (ch = 0; (u + ch) < src_buf_len && ch < 16; ch++) {
158 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size,
159 "%02X ", (uint8_t)src_buf[u + ch]);
160
161 if (ch == 7) {
162 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size,
163 " ");
164 }
165 }
166 if (ch == 16) {
167 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " ");
168 } else if (ch < 8) {
169 int spaces = (16 - ch) * 3 + 2 + 1;
170 int s = 0;
171 for ( ; s < spaces; s++)
172 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " ");
173 } else if(ch < 16) {
174 int spaces = (16 - ch) * 3 + 2;
175 int s = 0;
176 for ( ; s < spaces; s++)
177 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " ");
178 }
179
180 for (ch = 0; (u+ch) < src_buf_len && ch < 16; ch++) {
181 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size,
182 "%c",
183 isprint((uint8_t)src_buf[u + ch]) ? (uint8_t)src_buf[u + ch] : '.');
184
185 if (ch == 7)
186 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " ");
187 if (ch == 15)
188 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, "\n");
189 }
190 }
191 if (ch != 16)
192 PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, "\n");
193}
194
195void PrintStringsToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size,
196 const uint8_t *src_buf, const uint32_t src_buf_len)
197{
198 for (uint32_t ch = 0; ch < src_buf_len && *dst_buf_offset_ptr < dst_buf_size;
199 ch++, (*dst_buf_offset_ptr)++) {
200 if (isprint((uint8_t)src_buf[ch]) || src_buf[ch] == '\n' || src_buf[ch] == '\r') {
201 dst_buf[*dst_buf_offset_ptr] = src_buf[ch];
202 } else {
203 dst_buf[*dst_buf_offset_ptr] = '.';
204 }
205 }
206 dst_buf[dst_buf_size - 1] = 0;
207}
208
209static const char *PrintInetIPv6(const void *src, char *dst, socklen_t size)
210{
211 char s_part[6];
212 uint16_t x[8];
213 memcpy(&x, src, 16);
214
215 /* current IPv6 format is fixed size */
216 if (size < 8 * 5) {
217 SCLogWarning("Too small buffer to write IPv6 address");
218 return NULL;
219 }
220 memset(dst, 0, size);
221 for (int i = 0; i < 8; i++) {
222 snprintf(s_part, sizeof(s_part), "%04x:", htons(x[i]));
223 strlcat(dst, s_part, size);
224 }
225 /* suppress last ':' */
226 dst[strlen(dst) - 1] = 0;
227
228 return dst;
229}
230
231const char *PrintInet(int af, const void *src, char *dst, socklen_t size)
232{
233 switch (af) {
234 case AF_INET:
235#if defined(OS_WIN32) && NTDDI_VERSION >= NTDDI_VISTA
236{
237 // because Windows has to provide a non-conformant inet_ntop, of
238 // course!
239 struct in_addr _src;
240 memcpy(&_src, src, sizeof(struct in_addr));
241 return inet_ntop(af, &_src, dst, size);
242}
243#else
244 return inet_ntop(af, src, dst, size);
245#endif
246 case AF_INET6:
247 /* Format IPv6 without deleting zeroes */
248 return PrintInetIPv6(src, dst, size);
249 default:
250 SCLogError("Unsupported protocol: %d", af);
251 }
252 return NULL;
253}
254
255void PrintHexString(char *str, size_t size, uint8_t *buf, size_t buf_len)
256{
257 DEBUG_VALIDATE_BUG_ON(size < 2 * buf_len);
258 SCToHex((uint8_t *)str, size, buf, buf_len);
259}
uint16_t dst
uint16_t src
uint16_t af
Definition decode-gre.h:0
size_t strlcat(char *, const char *src, size_t siz)
#define str(s)
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
void PrintRawLineHexBuf(char *retbuf, uint32_t retbuflen, const uint8_t *buf, uint32_t buflen)
print a buffer as hex on a single line into retbuf buffer
Definition util-print.c:61
void PrintBufferRawLineHex(char *nbuf, int *offset, int max_size, const uint8_t *buf, uint32_t buflen)
print a buffer as hex on a single line
Definition util-print.c:44
void PrintRawDataToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size, const uint8_t *src_buf, uint32_t src_buf_len)
Definition util-print.c:149
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition util-print.c:231
void PrintStringsToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size, const uint8_t *src_buf, const uint32_t src_buf_len)
Definition util-print.c:195
void PrintRawUriFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
Definition util-print.c:69
void PrintRawUriBuf(char *retbuf, uint32_t *offset, uint32_t retbuflen, const uint8_t *buf, size_t buflen)
Definition util-print.c:93
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
Definition util-print.c:112
void PrintHexString(char *str, size_t size, uint8_t *buf, size_t buf_len)
Definition util-print.c:255
#define BUFFER_LENGTH
#define PrintBufferData(buf, buf_offset_ptr, buf_size,...)
Definition util-print.h:27
uint64_t offset
#define DEBUG_VALIDATE_BUG_ON(exp)