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  size_t total_size = (*buffer)->size + sizeof(MemBuffer) + expand_by;
69 
70  MemBuffer *tbuffer = SCRealloc(*buffer, total_size);
71  if (unlikely(tbuffer == NULL)) {
72  return -1;
73  }
74  *buffer = tbuffer;
75  (*buffer)->size += expand_by;
76 
77  SCLogDebug("expanded buffer by %u, size is now %u", expand_by, (*buffer)->size);
78  return 0;
79 }
80 
81 void MemBufferFree(MemBuffer *buffer)
82 {
83  SCFree(buffer);
84 }
85 
86 void MemBufferPrintToFP(MemBuffer *buffer, FILE *fp)
87 {
88  for (uint32_t i = 0; i < buffer->offset; i++) {
89  if (isprint(buffer->buffer[i]))
90  fprintf(fp, "%c", buffer->buffer[i]);
91  else
92  fprintf(fp, "|%02X|", buffer->buffer[i]);
93  }
94 }
95 
97 {
98  return fwrite(MEMBUFFER_BUFFER(b), sizeof(uint8_t), MEMBUFFER_OFFSET(b), fp);
99 }
100 
102 {
103  for (uint32_t i = 0; i < MEMBUFFER_OFFSET(b); i++) {
104  if (MEMBUFFER_OFFSET(b) % 8 == 0)
105  fprintf(fp, "\n");
106  fprintf(fp, " %02X", b->buffer[i]);
107  }
108 }
109 
110 uint32_t MemBufferWriteRaw(MemBuffer *dst, const uint8_t *raw, const uint32_t raw_len)
111 {
112  uint32_t write_len;
113  if (raw_len >= dst->size - dst->offset) {
114  SCLogDebug("Truncating data write since it exceeded buffer limit of %" PRIu32, dst->size);
115  write_len = dst->size - dst->offset - 1;
116  } else {
117  write_len = raw_len;
118  }
119  memcpy(dst->buffer + dst->offset, raw, write_len);
120  dst->offset += write_len;
121  dst->buffer[dst->offset] = '\0';
122  return write_len;
123 }
124 
125 void MemBufferWriteString(MemBuffer *dst, const char *fmt, ...)
126 {
127  uint32_t available = dst->size - dst->offset;
128  uint32_t max_string_size = MIN(available, 2048);
129  va_list ap;
130  char string[max_string_size];
131  va_start(ap, fmt);
132  int written = vsnprintf(string, sizeof(string), fmt, ap);
133  va_end(ap);
134  if (written < 0) {
135  return;
136  } else if ((uint32_t)written > max_string_size) {
137  SCLogDebug("Truncating data write since it exceeded buffer "
138  "limit of %" PRIu32,
139  dst->size);
140  }
141  size_t string_size = strlen(string);
142  memcpy(dst->buffer + dst->offset, string, string_size);
143  dst->offset += string_size;
144  dst->buffer[dst->offset] = '\0';
145 }
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:81
MemBufferPrintToFP
void MemBufferPrintToFP(MemBuffer *buffer, FILE *fp)
Write a buffer to the file pointer.
Definition: util-buffer.c:86
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:101
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:110
MemBufferWriteString
void MemBufferWriteString(MemBuffer *dst, const char *fmt,...)
Definition: util-buffer.c:125
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:96
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