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  return;
86 }
87 
88 void MemBufferPrintToFP(MemBuffer *buffer, FILE *fp)
89 {
90  for (uint32_t i = 0; i < buffer->offset; i++) {
91  if (isprint(buffer->buffer[i]))
92  fprintf(fp, "%c", buffer->buffer[i]);
93  else
94  fprintf(fp, "|%02X|", buffer->buffer[i]);
95  }
96 }
97 
99 {
100  return fwrite(MEMBUFFER_BUFFER(b), sizeof(uint8_t), MEMBUFFER_OFFSET(b), fp);
101 }
102 
104 {
105  for (uint32_t i = 0; i < MEMBUFFER_OFFSET(b); i++) {
106  if (MEMBUFFER_OFFSET(b) % 8 == 0)
107  fprintf(fp, "\n");
108  fprintf(fp, " %02X", b->buffer[i]);
109  }
110 }
111 
112 uint32_t MemBufferWriteRaw(MemBuffer *dst, const uint8_t *raw, const uint32_t raw_len)
113 {
114  uint32_t write_len;
115  if (raw_len >= dst->size - dst->offset) {
116  SCLogDebug("Truncating data write since it exceeded buffer limit of %" PRIu32, dst->size);
117  write_len = dst->size - dst->offset - 1;
118  } else {
119  write_len = raw_len;
120  }
121  memcpy(dst->buffer + dst->offset, raw, write_len);
122  dst->offset += write_len;
123  dst->buffer[dst->offset] = '\0';
124  return write_len;
125 }
126 
127 void MemBufferWriteString(MemBuffer *dst, const char *fmt, ...)
128 {
129  uint32_t available = dst->size - dst->offset;
130  uint32_t max_string_size = MIN(available, 2048);
131  va_list ap;
132  char string[max_string_size];
133  va_start(ap, fmt);
134  int written = vsnprintf(string, sizeof(string), fmt, ap);
135  va_end(ap);
136  if (written < 0) {
137  return;
138  } else if ((uint32_t)written > max_string_size) {
139  SCLogDebug("Truncating data write since it exceeded buffer "
140  "limit of %" PRIu32,
141  dst->size);
142  }
143  size_t string_size = strlen(string);
144  memcpy(dst->buffer + dst->offset, string, string_size);
145  dst->offset += string_size;
146  dst->buffer[dst->offset] = '\0';
147 }
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:88
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:103
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:112
MemBufferWriteString
void MemBufferWriteString(MemBuffer *dst, const char *fmt,...)
Definition: util-buffer.c:127
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:98
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