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 {
34  sc_errno = SC_OK;
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  */
60 int 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 
86 void MemBufferFree(MemBuffer *buffer)
87 {
88  SCFree(buffer);
89 }
90 
91 void 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 
115 uint32_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 
130 void 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 }
MemBuffer_::buffer
uint8_t buffer[]
Definition: util-buffer.h:30
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
MemBufferExpand
int MemBufferExpand(MemBuffer **buffer, uint32_t expand_by)
expand membuffer by size of 'expand_by'
Definition: util-buffer.c:60
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
SC_EINVAL
@ SC_EINVAL
Definition: util-error.h:30
MIN
#define MIN(x, y)
Definition: suricata-common.h:391
MemBuffer_::offset
uint32_t offset
Definition: util-buffer.h:29
SC_ENOMEM
@ SC_ENOMEM
Definition: util-error.h:29
util-debug.h
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
MAX_LIMIT
#define MAX_LIMIT
Definition: util-buffer.c:30
SC_OK
@ SC_OK
Definition: util-error.h:27
MemBuffer_
Definition: util-buffer.h:27
SCRealloc
#define SCRealloc(ptr, sz)
Definition: util-mem.h:50
suricata-common.h
MemBufferFree
void MemBufferFree(MemBuffer *buffer)
Definition: util-buffer.c:86
MemBufferPrintToFP
void MemBufferPrintToFP(MemBuffer *buffer, FILE *fp)
Write a buffer to the file pointer.
Definition: util-buffer.c:91
MemBuffer
struct MemBuffer_ MemBuffer
SCFree
#define SCFree(p)
Definition: util-mem.h:61
MemBufferPrintToFPAsHex
void MemBufferPrintToFPAsHex(MemBuffer *b, FILE *fp)
Write a buffer in hex format.
Definition: util-buffer.c:106
util-buffer.h
sc_errno
thread_local SCError sc_errno
Definition: util-error.c:31
suricata.h
MemBufferWriteRaw
uint32_t MemBufferWriteRaw(MemBuffer *dst, const uint8_t *raw, const uint32_t raw_len)
Write a raw buffer to the MemBuffer dst.
Definition: util-buffer.c:115
MemBufferWriteString
void MemBufferWriteString(MemBuffer *dst, const char *fmt,...)
Definition: util-buffer.c:130
MemBuffer_::size
uint32_t size
Definition: util-buffer.h:28
MEMBUFFER_BUFFER
#define MEMBUFFER_BUFFER(mem_buffer)
Get the MemBuffers underlying buffer.
Definition: util-buffer.h:51
dst
uint16_t dst
Definition: app-layer-dnp3.h:4
MemBufferPrintToFPAsString
size_t MemBufferPrintToFPAsString(MemBuffer *b, FILE *fp)
Write a buffer to the file pointer as a printable char string.
Definition: util-buffer.c:101
MEMBUFFER_OFFSET
#define MEMBUFFER_OFFSET(mem_buffer)
Get the MemBuffers current offset.
Definition: util-buffer.h:56
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
MemBufferCreateNew
MemBuffer * MemBufferCreateNew(uint32_t size)
Definition: util-buffer.c:32