big svn cleanup
[anytun.git] / src / openvpn / buffer.h
blob8471683c85b6ef8121c020d559b91ff1c5e391b2
1 /*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
8 * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #ifndef BUFFER_H
26 #define BUFFER_H
28 #include "basic.h"
29 #include "thread.h"
32 * Define verify_align function, otherwise
33 * it will be a noop.
35 /* #define VERIFY_ALIGNMENT */
38 * Keep track of source file/line of buf_init calls
40 #ifdef VERIFY_ALIGNMENT
41 #define BUF_INIT_TRACKING
42 #endif
44 /* basic buffer class for OpenVPN */
46 struct buffer
48 int capacity; /* size of buffer allocated by malloc */
49 int offset; /* data starts at data + offset, offset > 0 to allow for efficient prepending */
50 int len; /* length of data that starts at data + offset */
51 uint8_t *data;
53 #ifdef BUF_INIT_TRACKING
54 const char *debug_file;
55 int debug_line;
56 #endif
59 /* for garbage collection */
61 struct gc_entry
63 struct gc_entry *next;
66 struct gc_arena
68 struct gc_entry *list;
71 #define BPTR(buf) ((buf)->data + (buf)->offset)
72 #define BEND(buf) (BPTR(buf) + (buf)->len)
73 #define BLAST(buf) (((buf)->data && (buf)->len) ? (BPTR(buf) + (buf)->len - 1) : NULL)
74 #define BLEN(buf) ((buf)->len)
75 #define BDEF(buf) ((buf)->data != NULL)
76 #define BSTR(buf) ((char *)BPTR(buf))
77 #define BCAP(buf) (buf_forward_capacity (buf))
79 void buf_clear (struct buffer *buf);
81 struct buffer clear_buf (void);
82 void free_buf (struct buffer *buf);
84 bool buf_assign (struct buffer *dest, const struct buffer *src);
88 /* for dmalloc debugging */
90 #ifdef DMALLOC
92 #define alloc_buf(size) alloc_buf_debug (size, __FILE__, __LINE__)
93 #define alloc_buf_gc(size, gc) alloc_buf_gc_debug (size, gc, __FILE__, __LINE__);
94 #define clone_buf(buf) clone_buf_debug (buf, __FILE__, __LINE__);
95 #define gc_malloc(size, clear, arena) gc_malloc_debug (size, clear, arena, __FILE__, __LINE__)
96 #define string_alloc(str, gc) string_alloc_debug (str, gc, __FILE__, __LINE__)
97 #define string_alloc_buf(str, gc) string_alloc_buf_debug (str, gc, __FILE__, __LINE__)
99 struct buffer alloc_buf_debug (size_t size, const char *file, int line);
100 struct buffer alloc_buf_gc_debug (size_t size, struct gc_arena *gc, const char *file, int line);
101 struct buffer clone_buf_debug (const struct buffer* buf, const char *file, int line);
102 void *gc_malloc_debug (size_t size, bool clear, struct gc_arena *a, const char *file, int line);
103 char *string_alloc_debug (const char *str, struct gc_arena *gc, const char *file, int line);
104 struct buffer string_alloc_buf_debug (const char *str, struct gc_arena *gc, const char *file, int line);
106 #else
108 struct buffer alloc_buf (size_t size);
109 struct buffer alloc_buf_gc (size_t size, struct gc_arena *gc); /* allocate buffer with garbage collection */
110 struct buffer clone_buf (const struct buffer* buf);
111 void *gc_malloc (size_t size, bool clear, struct gc_arena *a);
112 char *string_alloc (const char *str, struct gc_arena *gc);
113 struct buffer string_alloc_buf (const char *str, struct gc_arena *gc);
115 #endif
117 #ifdef BUF_INIT_TRACKING
118 #define buf_init(buf, offset) buf_init_debug (buf, offset, __FILE__, __LINE__)
119 bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line);
120 #else
121 #define buf_init(buf, offset) buf_init_dowork (buf, offset)
122 #endif
125 /* inline functions */
127 static inline void
128 buf_reset (struct buffer *buf)
130 buf->capacity = 0;
131 buf->offset = 0;
132 buf->len = 0;
133 buf->data = NULL;
136 static inline bool
137 buf_init_dowork (struct buffer *buf, int offset)
139 if (offset < 0 || offset > buf->capacity || buf->data == NULL)
140 return false;
141 buf->len = 0;
142 buf->offset = offset;
143 return true;
146 static inline bool
147 buf_defined (struct buffer *buf)
149 return buf->data != NULL;
152 static inline void
153 buf_set_write (struct buffer *buf, uint8_t *data, int size)
155 buf->len = 0;
156 buf->offset = 0;
157 buf->capacity = size;
158 buf->data = data;
159 if (size > 0 && data)
160 *data = 0;
163 static inline void
164 buf_set_read (struct buffer *buf, const uint8_t *data, int size)
166 buf->len = buf->capacity = size;
167 buf->offset = 0;
168 buf->data = (uint8_t *)data;
171 /* Like strncpy but makes sure dest is always null terminated */
172 static inline void
173 strncpynt (char *dest, const char *src, size_t maxlen)
175 strncpy (dest, src, maxlen);
176 if (maxlen > 0)
177 dest[maxlen - 1] = 0;
180 /* return true if string contains at least one numerical digit */
181 static inline bool
182 has_digit (const char* src)
184 char c;
185 while ((c = *src++))
187 if (isdigit(c))
188 return true;
190 return false;
194 * printf append to a buffer with overflow check
196 void buf_printf (struct buffer *buf, const char *format, ...)
197 #ifdef __GNUC__
198 __attribute__ ((format (printf, 2, 3)))
199 #endif
203 * Like snprintf but guarantees null termination for size > 0
205 int openvpn_snprintf(char *str, size_t size, const char *format, ...)
206 #ifdef __GNUC__
207 __attribute__ ((format (printf, 3, 4)))
208 #endif
212 * remove/add trailing characters
215 void buf_null_terminate (struct buffer *buf);
216 void buf_chomp (struct buffer *buf);
217 void buf_rmtail (struct buffer *buf, uint8_t remove);
220 * non-buffer string functions
222 void chomp (char *str);
223 void string_null_terminate (char *str, int len, int capacity);
226 * Write string in buf to file descriptor fd.
227 * NOTE: requires that string be null terminated.
229 void buf_write_string_file (const struct buffer *buf, const char *filename, int fd);
232 * write a string to the end of a buffer that was
233 * truncated by buf_printf
235 void buf_catrunc (struct buffer *buf, const char *str);
238 * convert a multi-line output to one line
240 void convert_to_one_line (struct buffer *buf);
243 * Parse a string based on a given delimiter char
245 bool buf_parse (struct buffer *buf, const int delim, char *line, const int size);
248 * Hex dump -- Output a binary buffer to a hex string and return it.
250 char *
251 format_hex_ex (const uint8_t *data, int size, int maxoutput,
252 int space_break, const char* separator,
253 struct gc_arena *gc);
255 static inline char *
256 format_hex (const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
258 return format_hex_ex (data, size, maxoutput, 4, " ", gc);
262 * Return a buffer that is a subset of another buffer.
264 struct buffer buf_sub (struct buffer *buf, int size, bool prepend);
267 * Check if sufficient space to append to buffer.
270 static inline bool
271 buf_safe (const struct buffer *buf, int len)
273 return len >= 0 && buf->offset + buf->len + len <= buf->capacity;
276 static inline bool
277 buf_safe_bidir (const struct buffer *buf, int len)
279 const int newlen = buf->len + len;
280 return newlen >= 0 && buf->offset + newlen <= buf->capacity;
283 static inline int
284 buf_forward_capacity (const struct buffer *buf)
286 int ret = buf->capacity - (buf->offset + buf->len);
287 if (ret < 0)
288 ret = 0;
289 return ret;
292 static inline int
293 buf_forward_capacity_total (const struct buffer *buf)
295 int ret = buf->capacity - buf->offset;
296 if (ret < 0)
297 ret = 0;
298 return ret;
301 static inline int
302 buf_reverse_capacity (const struct buffer *buf)
304 return buf->offset;
307 static inline bool
308 buf_inc_len (struct buffer *buf, int inc)
310 if (!buf_safe_bidir (buf, inc))
311 return false;
312 buf->len += inc;
313 return true;
317 * Make space to prepend to a buffer.
318 * Return NULL if no space.
321 static inline uint8_t *
322 buf_prepend (struct buffer *buf, int size)
324 if (size < 0 || size > buf->offset)
325 return NULL;
326 buf->offset -= size;
327 buf->len += size;
328 return BPTR (buf);
331 static inline bool
332 buf_advance (struct buffer *buf, int size)
334 if (size < 0 || buf->len < size)
335 return false;
336 buf->offset += size;
337 buf->len -= size;
338 return true;
342 * Return a pointer to allocated space inside a buffer.
343 * Return NULL if no space.
346 static inline uint8_t *
347 buf_write_alloc (struct buffer *buf, int size)
349 uint8_t *ret;
350 if (!buf_safe (buf, size))
351 return NULL;
352 ret = BPTR (buf) + buf->len;
353 buf->len += size;
354 return ret;
357 static inline uint8_t *
358 buf_write_alloc_prepend (struct buffer *buf, int size, bool prepend)
360 return prepend ? buf_prepend (buf, size) : buf_write_alloc (buf, size);
363 static inline uint8_t *
364 buf_read_alloc (struct buffer *buf, int size)
366 uint8_t *ret;
367 if (size < 0 || buf->len < size)
368 return NULL;
369 ret = BPTR (buf);
370 buf->offset += size;
371 buf->len -= size;
372 return ret;
375 static inline bool
376 buf_write (struct buffer *dest, const void *src, int size)
378 uint8_t *cp = buf_write_alloc (dest, size);
379 if (!cp)
380 return false;
381 memcpy (cp, src, size);
382 return true;
385 static inline bool
386 buf_write_prepend (struct buffer *dest, const void *src, int size)
388 uint8_t *cp = buf_prepend (dest, size);
389 if (!cp)
390 return false;
391 memcpy (cp, src, size);
392 return true;
395 static inline bool
396 buf_write_u8 (struct buffer *dest, int data)
398 uint8_t u8 = (uint8_t) data;
399 return buf_write (dest, &u8, sizeof (uint8_t));
402 static inline bool
403 buf_write_u16 (struct buffer *dest, int data)
405 uint16_t u16 = htons ((uint16_t) data);
406 return buf_write (dest, &u16, sizeof (uint16_t));
409 static inline bool
410 buf_write_u32 (struct buffer *dest, int data)
412 uint32_t u32 = htonl ((uint32_t) data);
413 return buf_write (dest, &u32, sizeof (uint32_t));
416 static inline bool
417 buf_copy (struct buffer *dest, const struct buffer *src)
419 return buf_write (dest, BPTR (src), BLEN (src));
422 static inline bool
423 buf_copy_n (struct buffer *dest, struct buffer *src, int n)
425 uint8_t *cp = buf_read_alloc (src, n);
426 if (!cp)
427 return false;
428 return buf_write (dest, cp, n);
431 static inline bool
432 buf_copy_range (struct buffer *dest,
433 int dest_index,
434 const struct buffer *src,
435 int src_index,
436 int src_len)
438 if (src_index < 0
439 || src_len < 0
440 || src_index + src_len > src->len
441 || dest_index < 0
442 || dest->offset + dest_index + src_len > dest->capacity)
443 return false;
444 memcpy (dest->data + dest->offset + dest_index, src->data + src->offset + src_index, src_len);
445 if (dest_index + src_len > dest->len)
446 dest->len = dest_index + src_len;
447 return true;
450 /* truncate src to len, copy excess data beyond len to dest */
451 static inline bool
452 buf_copy_excess (struct buffer *dest,
453 struct buffer *src,
454 int len)
456 if (len < 0)
457 return false;
458 if (src->len > len)
460 struct buffer b = *src;
461 src->len = len;
462 if (!buf_advance (&b, len))
463 return false;
464 return buf_copy (dest, &b);
466 else
468 return true;
472 static inline bool
473 buf_read (struct buffer *src, void *dest, int size)
475 uint8_t *cp = buf_read_alloc (src, size);
476 if (!cp)
477 return false;
478 memcpy (dest, cp, size);
479 return true;
482 static inline int
483 buf_read_u8 (struct buffer *buf)
485 int ret;
486 if (BLEN (buf) < 1)
487 return -1;
488 ret = *BPTR(buf);
489 buf_advance (buf, 1);
490 return ret;
493 static inline int
494 buf_read_u16 (struct buffer *buf)
496 uint16_t ret;
497 if (!buf_read (buf, &ret, sizeof (uint16_t)))
498 return -1;
499 return ntohs (ret);
502 static inline uint32_t
503 buf_read_u32 (struct buffer *buf, bool *good)
505 uint32_t ret;
506 if (!buf_read (buf, &ret, sizeof (uint32_t)))
508 if (good)
509 *good = false;
510 return 0;
512 else
514 if (good)
515 *good = true;
516 return ntohl (ret);
520 static inline bool
521 buf_string_match (const struct buffer *src, const void *match, int size)
523 if (size != src->len)
524 return false;
525 return memcmp (BPTR (src), match, size) == 0;
528 static inline bool
529 buf_string_match_head (const struct buffer *src, const void *match, int size)
531 if (size < 0 || size > src->len)
532 return false;
533 return memcmp (BPTR (src), match, size) == 0;
536 bool buf_string_match_head_str (const struct buffer *src, const char *match);
537 bool buf_string_compare_advance (struct buffer *src, const char *match);
538 int buf_substring_len (const struct buffer *buf, int delim);
541 * Bitwise operations
543 // static inline void
544 // xor (uint8_t *dest, const uint8_t *src, int len)
545 // {
546 // while (len-- > 0)
547 // *dest++ ^= *src++;
548 // }
551 * Classify and mutate strings based on character types.
554 /*#define CHARACTER_CLASS_DEBUG*/
556 /* character classes */
558 #define CC_ANY (1<<0)
559 #define CC_NULL (1<<1)
561 #define CC_ALNUM (1<<2)
562 #define CC_ALPHA (1<<3)
563 #define CC_ASCII (1<<4)
564 #define CC_CNTRL (1<<5)
565 #define CC_DIGIT (1<<6)
566 #define CC_PRINT (1<<7)
567 #define CC_PUNCT (1<<8)
568 #define CC_SPACE (1<<9)
569 #define CC_XDIGIT (1<<10)
571 #define CC_BLANK (1<<11)
572 #define CC_NEWLINE (1<<12)
573 #define CC_CR (1<<13)
575 #define CC_BACKSLASH (1<<14)
576 #define CC_UNDERBAR (1<<15)
577 #define CC_DASH (1<<16)
578 #define CC_DOT (1<<17)
579 #define CC_COMMA (1<<18)
580 #define CC_COLON (1<<19)
581 #define CC_SLASH (1<<20)
582 #define CC_SINGLE_QUOTE (1<<21)
583 #define CC_DOUBLE_QUOTE (1<<22)
584 #define CC_REVERSE_QUOTE (1<<23)
585 #define CC_AT (1<<24)
586 #define CC_EQUAL (1<<25)
588 /* macro classes */
589 #define CC_NAME (CC_ALNUM|CC_UNDERBAR)
590 #define CC_CRLF (CC_CR|CC_NEWLINE)
592 bool char_class (const char c, const unsigned int flags);
593 bool string_class (const char *str, const unsigned int inclusive, const unsigned int exclusive);
594 bool string_mod (char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace);
596 const char *string_mod_const (const char *str,
597 const unsigned int inclusive,
598 const unsigned int exclusive,
599 const char replace,
600 struct gc_arena *gc);
602 #ifdef CHARACTER_CLASS_DEBUG
603 void character_class_debug (void);
604 #endif
607 * Verify that a pointer is correctly aligned
609 #ifdef VERIFY_ALIGNMENT
610 void valign4 (const struct buffer *buf, const char *file, const int line);
611 # define verify_align_4(ptr) valign4(buf, __FILE__, __LINE__)
612 #else
613 # define verify_align_4(ptr)
614 #endif
617 * Very basic garbage collection, mostly for routines that return
618 * char ptrs to malloced strings.
621 void x_gc_free (struct gc_arena *a);
623 static inline void
624 gc_init (struct gc_arena *a)
626 a->list = NULL;
629 static inline void
630 gc_detach (struct gc_arena *a)
632 gc_init (a);
635 static inline struct gc_arena
636 gc_new (void)
638 struct gc_arena ret;
639 ret.list = NULL;
640 return ret;
643 static inline void
644 gc_free (struct gc_arena *a)
646 if (a->list)
647 x_gc_free (a);
650 static inline void
651 gc_reset (struct gc_arena *a)
653 gc_free (a);
657 * Allocate memory to hold a structure
660 void out_of_memory (void);
662 #define ALLOC_OBJ(dptr, type) \
664 check_malloc_return ((dptr) = (type *) malloc (sizeof (type))); \
667 #define ALLOC_OBJ_CLEAR(dptr, type) \
669 ALLOC_OBJ (dptr, type); \
670 memset ((dptr), 0, sizeof(type)); \
673 #define ALLOC_ARRAY(dptr, type, n) \
675 check_malloc_return ((dptr) = (type *) malloc (sizeof (type) * (n))); \
678 #define ALLOC_ARRAY_GC(dptr, type, n, gc) \
680 (dptr) = (type *) gc_malloc (sizeof (type) * (n), false, (gc)); \
683 #define ALLOC_ARRAY_CLEAR(dptr, type, n) \
685 ALLOC_ARRAY (dptr, type, n); \
686 memset ((dptr), 0, (sizeof(type) * (n))); \
689 #define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc) \
691 (dptr) = (type *) gc_malloc (sizeof (type) * (n), true, (gc)); \
694 #define ALLOC_OBJ_GC(dptr, type, gc) \
696 (dptr) = (type *) gc_malloc (sizeof (type), false, (gc)); \
699 #define ALLOC_OBJ_CLEAR_GC(dptr, type, gc) \
701 (dptr) = (type *) gc_malloc (sizeof (type), true, (gc)); \
704 static inline void
705 check_malloc_return (void *p)
707 void out_of_memory (void);
708 if (!p)
709 out_of_memory ();
712 #endif /* BUFFER_H */