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  */
44 void 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  */
61 void 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 
69 void PrintRawJsonFp(FILE *fp, 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 (buf[u] == '\\' || buf[u] == '/' || buf[u] == '\"') {
78  "\\%c", buf[u]);
79  } else if (isprint(buf[u])) {
81  "%c", buf[u]);
82  } else {
84  "\\\\x%02X", buf[u]);
85  }
86  }
87  fprintf(fp, "%s", nbuf);
88 }
89 
90 void PrintRawUriFp(FILE *fp, uint8_t *buf, uint32_t buflen)
91 {
92 #define BUFFER_LENGTH 2048
93  char nbuf[BUFFER_LENGTH] = "";
94  uint32_t offset = 0;
95 
96  for (uint32_t u = 0; u < buflen; u++) {
97  if (isprint(buf[u]) && buf[u] != '\"') {
98  if (buf[u] == '\\') {
100  "\\\\");
101  } else {
103  "%c", buf[u]);
104  }
105  } else {
107  "\\x%02X", buf[u]);
108  }
109  }
110 
111  fprintf(fp, "%s", nbuf);
112 }
113 
114 void PrintRawUriBuf(char *retbuf, uint32_t *offset, uint32_t retbuflen,
115  uint8_t *buf, uint32_t buflen)
116 {
117  for (uint32_t u = 0; u < buflen; u++) {
118  if (isprint(buf[u]) && buf[u] != '\"') {
119  if (buf[u] == '\\') {
120  PrintBufferData(retbuf, offset, retbuflen,
121  "\\\\");
122  } else {
123  PrintBufferData(retbuf, offset, retbuflen,
124  "%c", buf[u]);
125  }
126  } else {
127  PrintBufferData(retbuf, offset, retbuflen,
128  "\\x%02X", buf[u]);
129  }
130  }
131 
132  return;
133 }
134 
135 void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
136 {
137  int ch = 0;
138 
139  if (buf == NULL) {
140  fprintf(fp, " (null)\n");
141  return;
142  }
143  for (uint32_t u = 0; u < buflen; u += 16) {
144  fprintf(fp ," %04X ", u);
145  for (ch = 0; (u+ch) < buflen && ch < 16; ch++) {
146  fprintf(fp, "%02X ", (uint8_t)buf[u+ch]);
147 
148  if (ch == 7) fprintf(fp, " ");
149  }
150  if (ch == 16) fprintf(fp, " ");
151  else if (ch < 8) {
152  int spaces = (16 - ch) * 3 + 2 + 1;
153  int s = 0;
154  for ( ; s < spaces; s++) fprintf(fp, " ");
155  } else if(ch < 16) {
156  int spaces = (16 - ch) * 3 + 2;
157  int s = 0;
158  for ( ; s < spaces; s++) fprintf(fp, " ");
159  }
160 
161  for (ch = 0; (u+ch) < buflen && ch < 16; ch++) {
162  fprintf(fp, "%c", isprint((uint8_t)buf[u+ch]) ? (uint8_t)buf[u+ch] : '.');
163 
164  if (ch == 7) fprintf(fp, " ");
165  if (ch == 15) fprintf(fp, "\n");
166  }
167  }
168  if (ch != 16)
169  fprintf(fp, "\n");
170 }
171 
172 void PrintRawDataToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size,
173  const uint8_t *src_buf, uint32_t src_buf_len)
174 {
175  int ch = 0;
176 
177  for (uint32_t u = 0; u < src_buf_len; u += 16) {
178  PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size,
179  " %04X ", u);
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  "%02X ", (uint8_t)src_buf[u + ch]);
183 
184  if (ch == 7) {
185  PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size,
186  " ");
187  }
188  }
189  if (ch == 16) {
190  PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " ");
191  } else if (ch < 8) {
192  int spaces = (16 - ch) * 3 + 2 + 1;
193  int s = 0;
194  for ( ; s < spaces; s++)
195  PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " ");
196  } else if(ch < 16) {
197  int spaces = (16 - ch) * 3 + 2;
198  int s = 0;
199  for ( ; s < spaces; s++)
200  PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " ");
201  }
202 
203  for (ch = 0; (u+ch) < src_buf_len && ch < 16; ch++) {
204  PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size,
205  "%c",
206  isprint((uint8_t)src_buf[u + ch]) ? (uint8_t)src_buf[u + ch] : '.');
207 
208  if (ch == 7)
209  PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " ");
210  if (ch == 15)
211  PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, "\n");
212  }
213  }
214  if (ch != 16)
215  PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, "\n");
216 
217  return;
218 }
219 
220 void PrintStringsToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size,
221  const uint8_t *src_buf, const uint32_t src_buf_len)
222 {
223  for (uint32_t ch = 0; ch < src_buf_len && *dst_buf_offset_ptr < dst_buf_size;
224  ch++, (*dst_buf_offset_ptr)++) {
225  if (isprint((uint8_t)src_buf[ch]) || src_buf[ch] == '\n' || src_buf[ch] == '\r') {
226  dst_buf[*dst_buf_offset_ptr] = src_buf[ch];
227  } else {
228  dst_buf[*dst_buf_offset_ptr] = '.';
229  }
230  }
231  dst_buf[dst_buf_size - 1] = 0;
232 
233  return;
234 }
235 
236 #ifndef s6_addr16
237 # define s6_addr16 __u6_addr.__u6_addr16
238 #endif
239 
240 static const char *PrintInetIPv6(const void *src, char *dst, socklen_t size)
241 {
242  char s_part[6];
243  uint16_t x[8];
244  memcpy(&x, src, 16);
245 
246  /* current IPv6 format is fixed size */
247  if (size < 8 * 5) {
248  SCLogWarning("Too small buffer to write IPv6 address");
249  return NULL;
250  }
251  memset(dst, 0, size);
252  for (int i = 0; i < 8; i++) {
253  snprintf(s_part, sizeof(s_part), "%04x:", htons(x[i]));
254  strlcat(dst, s_part, size);
255  }
256  /* suppress last ':' */
257  dst[strlen(dst) - 1] = 0;
258 
259  return dst;
260 }
261 
262 const char *PrintInet(int af, const void *src, char *dst, socklen_t size)
263 {
264  switch (af) {
265  case AF_INET:
266 #if defined(OS_WIN32) && NTDDI_VERSION >= NTDDI_VISTA
267 {
268  // because Windows has to provide a non-conformant inet_ntop, of
269  // course!
270  struct in_addr _src;
271  memcpy(&_src, src, sizeof(struct in_addr));
272  return inet_ntop(af, &_src, dst, size);
273 }
274 #else
275  return inet_ntop(af, src, dst, size);
276 #endif
277  case AF_INET6:
278  /* Format IPv6 without deleting zeroes */
279  return PrintInetIPv6(src, dst, size);
280  default:
281  SCLogError("Unsupported protocol: %d", af);
282  }
283  return NULL;
284 }
285 
286 void PrintHexString(char *str, size_t size, uint8_t *buf, size_t buf_len)
287 {
288  DEBUG_VALIDATE_BUG_ON(size < 2 * buf_len);
289  rs_to_hex((uint8_t *)str, size, buf, buf_len);
290 }
BUFFER_LENGTH
#define BUFFER_LENGTH
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
PrintHexString
void PrintHexString(char *str, size_t size, uint8_t *buf, size_t buf_len)
Definition: util-print.c:286
rust.h
PrintStringsToBuffer
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:220
util-debug.h
util-error.h
PrintRawDataToBuffer
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:172
PrintBufferRawLineHex
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
strlcat
size_t strlcat(char *, const char *src, size_t siz)
Definition: util-strlcatu.c:45
util-print.h
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:262
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
PrintRawDataFp
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
Definition: util-print.c:135
PrintBufferData
#define PrintBufferData(buf, buf_offset_ptr, buf_size,...)
Definition: util-print.h:27
suricata-common.h
util-validate.h
PrintRawUriFp
void PrintRawUriFp(FILE *fp, uint8_t *buf, uint32_t buflen)
Definition: util-print.c:90
str
#define str(s)
Definition: suricata-common.h:291
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
src
uint16_t src
Definition: app-layer-dnp3.h:5
PrintRawJsonFp
void PrintRawJsonFp(FILE *fp, uint8_t *buf, uint32_t buflen)
Definition: util-print.c:69
PrintRawUriBuf
void PrintRawUriBuf(char *retbuf, uint32_t *offset, uint32_t retbuflen, uint8_t *buf, uint32_t buflen)
Definition: util-print.c:114
af
uint16_t af
Definition: decode-gre.h:0
dst
uint16_t dst
Definition: app-layer-dnp3.h:4
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:103
PrintRawLineHexBuf
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