suricata
util-buffer.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 Anoop Saldanha <anoopsaldanha@gmail.com>
22 */
23
24#include "suricata-common.h"
25#include "suricata.h"
26#include "util-debug.h"
27#include "util-buffer.h"
28
29/* 10 mb */
30#define MAX_LIMIT 10485760
31
33{
35 if (size > MAX_LIMIT) {
36 SCLogWarning("Mem buffer asked to create "
37 "buffer with size greater than API limit - %d",
38 MAX_LIMIT);
40 return NULL;
41 }
42
43 size_t total_size = size + sizeof(MemBuffer);
44
45 MemBuffer *buffer = SCCalloc(1, total_size);
46 if (unlikely(buffer == NULL)) {
48 return NULL;
49 }
50 buffer->size = size;
51 return buffer;
52}
53
54/** \brief expand membuffer by size of 'expand_by'
55 *
56 * If expansion failed, buffer will still be valid.
57 *
58 * \retval result 0 ok, -1 expansion failed
59 */
60int MemBufferExpand(MemBuffer **buffer, uint32_t expand_by) {
61 if (((*buffer)->size + expand_by) > MAX_LIMIT) {
62 SCLogWarning("Mem buffer asked to create "
63 "buffer with size greater than API limit - %d",
64 MAX_LIMIT);
65 return -1;
66 }
67
68 /* Adjust expand_by to next multiple of 4k. */
69 if (expand_by % 4096 != 0) {
70 expand_by = expand_by - (expand_by % 4096) + 4096;
71 }
72
73 size_t total_size = (*buffer)->size + sizeof(MemBuffer) + expand_by;
74
75 MemBuffer *tbuffer = SCRealloc(*buffer, total_size);
76 if (unlikely(tbuffer == NULL)) {
77 return -1;
78 }
79 *buffer = tbuffer;
80 (*buffer)->size += expand_by;
81
82 SCLogDebug("expanded buffer by %u, size is now %u", expand_by, (*buffer)->size);
83 return 0;
84}
85
87{
88 SCFree(buffer);
89}
90
91void MemBufferPrintToFP(MemBuffer *buffer, FILE *fp)
92{
93 for (uint32_t i = 0; i < buffer->offset; i++) {
94 if (isprint(buffer->buffer[i]))
95 fprintf(fp, "%c", buffer->buffer[i]);
96 else
97 fprintf(fp, "|%02X|", buffer->buffer[i]);
98 }
99}
100
102{
103 return fwrite(MEMBUFFER_BUFFER(b), sizeof(uint8_t), MEMBUFFER_OFFSET(b), fp);
104}
105
107{
108 for (uint32_t i = 0; i < MEMBUFFER_OFFSET(b); i++) {
109 if (MEMBUFFER_OFFSET(b) % 8 == 0)
110 fprintf(fp, "\n");
111 fprintf(fp, " %02X", b->buffer[i]);
112 }
113}
114
115uint32_t MemBufferWriteRaw(MemBuffer *dst, const uint8_t *raw, const uint32_t raw_len)
116{
117 uint32_t write_len;
118 if (raw_len >= dst->size - dst->offset) {
119 SCLogDebug("Truncating data write since it exceeded buffer limit of %" PRIu32, dst->size);
120 write_len = dst->size - dst->offset - 1;
121 } else {
122 write_len = raw_len;
123 }
124 memcpy(dst->buffer + dst->offset, raw, write_len);
125 dst->offset += write_len;
126 dst->buffer[dst->offset] = '\0';
127 return write_len;
128}
129
130void MemBufferWriteString(MemBuffer *dst, const char *fmt, ...)
131{
132 uint32_t available = dst->size - dst->offset;
133 uint32_t max_string_size = MIN(available, 2048);
134 va_list ap;
135 char string[max_string_size];
136 va_start(ap, fmt);
137 int written = vsnprintf(string, sizeof(string), fmt, ap);
138 va_end(ap);
139 if (written < 0) {
140 return;
141 } else if ((uint32_t)written > max_string_size) {
142 SCLogDebug("Truncating data write since it exceeded buffer "
143 "limit of %" PRIu32,
144 dst->size);
145 }
146 size_t string_size = strlen(string);
147 memcpy(dst->buffer + dst->offset, string, string_size);
148 dst->offset += string_size;
149 dst->buffer[dst->offset] = '\0';
150}
uint16_t dst
uint8_t buffer[]
Definition util-buffer.h:30
uint32_t size
Definition util-buffer.h:28
uint32_t offset
Definition util-buffer.h:29
#define MIN(x, y)
void MemBufferWriteString(MemBuffer *dst, const char *fmt,...)
void MemBufferPrintToFP(MemBuffer *buffer, FILE *fp)
Write a buffer to the file pointer.
Definition util-buffer.c:91
#define MAX_LIMIT
Definition util-buffer.c:30
int MemBufferExpand(MemBuffer **buffer, uint32_t expand_by)
expand membuffer by size of 'expand_by'
Definition util-buffer.c:60
MemBuffer * MemBufferCreateNew(uint32_t size)
Definition util-buffer.c:32
uint32_t MemBufferWriteRaw(MemBuffer *dst, const uint8_t *raw, const uint32_t raw_len)
Write a raw buffer to the MemBuffer dst.
void MemBufferPrintToFPAsHex(MemBuffer *b, FILE *fp)
Write a buffer in hex format.
void MemBufferFree(MemBuffer *buffer)
Definition util-buffer.c:86
size_t MemBufferPrintToFPAsString(MemBuffer *b, FILE *fp)
Write a buffer to the file pointer as a printable char string.
#define MEMBUFFER_BUFFER(mem_buffer)
Get the MemBuffers underlying buffer.
Definition util-buffer.h:51
struct MemBuffer_ MemBuffer
#define MEMBUFFER_OFFSET(mem_buffer)
Get the MemBuffers current offset.
Definition util-buffer.h:56
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
thread_local SCError sc_errno
Definition util-error.c:31
@ SC_EINVAL
Definition util-error.h:30
@ SC_ENOMEM
Definition util-error.h:29
@ SC_OK
Definition util-error.h:27
#define SCFree(p)
Definition util-mem.h:61
#define SCRealloc(ptr, sz)
Definition util-mem.h:50
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define unlikely(expr)