diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:39:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:39:49 +0000 |
commit | a0aa2307322cd47bbf416810ac0292925e03be87 (patch) | |
tree | 37076262a026c4b48c8a0e84f44ff9187556ca35 /src/util-print.c | |
parent | Initial commit. (diff) | |
download | suricata-a0aa2307322cd47bbf416810ac0292925e03be87.tar.xz suricata-a0aa2307322cd47bbf416810ac0292925e03be87.zip |
Adding upstream version 1:7.0.3.upstream/1%7.0.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/util-print.c')
-rw-r--r-- | src/util-print.c | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/src/util-print.c b/src/util-print.c new file mode 100644 index 0000000..ef69efe --- /dev/null +++ b/src/util-print.c @@ -0,0 +1,302 @@ +/* Copyright (C) 2007-2010 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Victor Julien <victor@inliniac.net> + * + * Print utility functions + */ + +#include "suricata-common.h" +#include "util-print.h" +#include "util-error.h" +#include "util-debug.h" +#include "util-validate.h" +#include "rust.h" + +/** + * \brief print a buffer as hex on a single line + * + * Prints in the format "00 AA BB" + * + * \param nbuf buffer into which the output is written + * \param offset of where to start writing into the buffer + * \param max_size the size of the output buffer + * \param buf buffer to print from + * \param buflen length of the input buffer + */ +void PrintBufferRawLineHex(char *nbuf, int *offset, int max_size, const uint8_t *buf, uint32_t buflen) +{ + uint32_t u = 0; + + for (u = 0; u < buflen; u++) { + PrintBufferData(nbuf, offset, max_size, "%02X ", buf[u]); + } +} + +/** + * \brief print a buffer as hex on a single line into retbuf buffer + * + * Prints in the format "00 AA BB" + * + * \param retbuf pointer to the buffer which will have the result + * \param rebuflen length of the buffer + * \param buf buffer to print from + * \param buflen length of the input buffer + */ +void PrintRawLineHexBuf(char *retbuf, uint32_t retbuflen, const uint8_t *buf, uint32_t buflen) +{ + uint32_t offset = 0; + uint32_t u = 0; + + for (u = 0; u < buflen; u++) { + PrintBufferData(retbuf, &offset, retbuflen, "%02X ", buf[u]); + } +} + +void PrintRawJsonFp(FILE *fp, uint8_t *buf, uint32_t buflen) +{ +#define BUFFER_LENGTH 2048 + char nbuf[BUFFER_LENGTH] = ""; + uint32_t offset = 0; + uint32_t u = 0; + + for (u = 0; u < buflen; u++) { + if (buf[u] == '\\' || buf[u] == '/' || buf[u] == '\"') { + PrintBufferData(nbuf, &offset, BUFFER_LENGTH, + "\\%c", buf[u]); + } else if (isprint(buf[u])) { + PrintBufferData(nbuf, &offset, BUFFER_LENGTH, + "%c", buf[u]); + } else { + PrintBufferData(nbuf, &offset, BUFFER_LENGTH, + "\\\\x%02X", buf[u]); + } + } + fprintf(fp, "%s", nbuf); +} + +void PrintRawUriFp(FILE *fp, uint8_t *buf, uint32_t buflen) +{ +#define BUFFER_LENGTH 2048 + char nbuf[BUFFER_LENGTH] = ""; + uint32_t offset = 0; + uint32_t u = 0; + + for (u = 0; u < buflen; u++) { + if (isprint(buf[u]) && buf[u] != '\"') { + if (buf[u] == '\\') { + PrintBufferData(nbuf, &offset, BUFFER_LENGTH, + "\\\\"); + } else { + PrintBufferData(nbuf, &offset, BUFFER_LENGTH, + "%c", buf[u]); + } + } else { + PrintBufferData(nbuf, &offset, BUFFER_LENGTH, + "\\x%02X", buf[u]); + } + } + + fprintf(fp, "%s", nbuf); +} + +void PrintRawUriBuf(char *retbuf, uint32_t *offset, uint32_t retbuflen, + uint8_t *buf, uint32_t buflen) +{ + uint32_t u = 0; + + for (u = 0; u < buflen; u++) { + if (isprint(buf[u]) && buf[u] != '\"') { + if (buf[u] == '\\') { + PrintBufferData(retbuf, offset, retbuflen, + "\\\\"); + } else { + PrintBufferData(retbuf, offset, retbuflen, + "%c", buf[u]); + } + } else { + PrintBufferData(retbuf, offset, retbuflen, + "\\x%02X", buf[u]); + } + } + + return; +} + +void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen) +{ + int ch = 0; + uint32_t u = 0; + + if (buf == NULL) { + fprintf(fp, " (null)\n"); + return; + } + for (u = 0; u < buflen; u+=16) { + fprintf(fp ," %04X ", u); + for (ch = 0; (u+ch) < buflen && ch < 16; ch++) { + fprintf(fp, "%02X ", (uint8_t)buf[u+ch]); + + if (ch == 7) fprintf(fp, " "); + } + if (ch == 16) fprintf(fp, " "); + else if (ch < 8) { + int spaces = (16 - ch) * 3 + 2 + 1; + int s = 0; + for ( ; s < spaces; s++) fprintf(fp, " "); + } else if(ch < 16) { + int spaces = (16 - ch) * 3 + 2; + int s = 0; + for ( ; s < spaces; s++) fprintf(fp, " "); + } + + for (ch = 0; (u+ch) < buflen && ch < 16; ch++) { + fprintf(fp, "%c", isprint((uint8_t)buf[u+ch]) ? (uint8_t)buf[u+ch] : '.'); + + if (ch == 7) fprintf(fp, " "); + if (ch == 15) fprintf(fp, "\n"); + } + } + if (ch != 16) + fprintf(fp, "\n"); +} + +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) +{ + int ch = 0; + uint32_t u = 0; + + for (u = 0; u < src_buf_len; u+=16) { + PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, + " %04X ", u); + for (ch = 0; (u + ch) < src_buf_len && ch < 16; ch++) { + PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, + "%02X ", (uint8_t)src_buf[u + ch]); + + if (ch == 7) { + PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, + " "); + } + } + if (ch == 16) { + PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " "); + } else if (ch < 8) { + int spaces = (16 - ch) * 3 + 2 + 1; + int s = 0; + for ( ; s < spaces; s++) + PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " "); + } else if(ch < 16) { + int spaces = (16 - ch) * 3 + 2; + int s = 0; + for ( ; s < spaces; s++) + PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " "); + } + + for (ch = 0; (u+ch) < src_buf_len && ch < 16; ch++) { + PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, + "%c", + isprint((uint8_t)src_buf[u + ch]) ? (uint8_t)src_buf[u + ch] : '.'); + + if (ch == 7) + PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " "); + if (ch == 15) + PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, "\n"); + } + } + if (ch != 16) + PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, "\n"); + + return; +} + +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) +{ + uint32_t ch = 0; + for (ch = 0; ch < src_buf_len && *dst_buf_offset_ptr < dst_buf_size; + ch++, (*dst_buf_offset_ptr)++) { + if (isprint((uint8_t)src_buf[ch]) || src_buf[ch] == '\n' || src_buf[ch] == '\r') { + dst_buf[*dst_buf_offset_ptr] = src_buf[ch]; + } else { + dst_buf[*dst_buf_offset_ptr] = '.'; + } + } + dst_buf[dst_buf_size - 1] = 0; + + return; +} + +#ifndef s6_addr16 +# define s6_addr16 __u6_addr.__u6_addr16 +#endif + +static const char *PrintInetIPv6(const void *src, char *dst, socklen_t size) +{ + int i; + char s_part[6]; + uint16_t x[8]; + memcpy(&x, src, 16); + + /* current IPv6 format is fixed size */ + if (size < 8 * 5) { + SCLogWarning("Too small buffer to write IPv6 address"); + return NULL; + } + memset(dst, 0, size); + for(i = 0; i < 8; i++) { + snprintf(s_part, sizeof(s_part), "%04x:", htons(x[i])); + strlcat(dst, s_part, size); + } + /* suppress last ':' */ + dst[strlen(dst) - 1] = 0; + + return dst; +} + +const char *PrintInet(int af, const void *src, char *dst, socklen_t size) +{ + switch (af) { + case AF_INET: +#if defined(OS_WIN32) && NTDDI_VERSION >= NTDDI_VISTA +{ + // because Windows has to provide a non-conformant inet_ntop, of + // course! + struct in_addr _src; + memcpy(&_src, src, sizeof(struct in_addr)); + return inet_ntop(af, &_src, dst, size); +} +#else + return inet_ntop(af, src, dst, size); +#endif + case AF_INET6: + /* Format IPv6 without deleting zeroes */ + return PrintInetIPv6(src, dst, size); + default: + SCLogError("Unsupported protocol: %d", af); + } + return NULL; +} + +void PrintHexString(char *str, size_t size, uint8_t *buf, size_t buf_len) +{ + DEBUG_VALIDATE_BUG_ON(size < 2 * buf_len); + rs_to_hex((uint8_t *)str, size, buf, buf_len); +} |