Branch data Line data Source code
1 : : // $Id: util.h 6782 2009-06-28 02:19:03Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #ifndef util_h
6 : : #define util_h
7 : :
8 : : #include <stdio.h>
9 : : #include <stdlib.h>
10 : : #include <string.h>
11 : : #include <stdarg.h>
12 : : #include "config.h"
13 : :
14 : : #if __STDC__
15 : : #define myattribute __attribute__
16 : : #else
17 : : #define myattribute(x)
18 : : #endif
19 : :
20 : : #ifdef DEBUG
21 : :
22 : : #include <assert.h>
23 : :
24 : : #define ASSERT(x) assert(x)
25 : : #define DEBUG_MSG(x...) fprintf(stderr, x)
26 : : #define DEBUG_fputs fputs
27 : :
28 : : #else
29 : :
30 : : #define ASSERT(x)
31 : : #define DEBUG_MSG(x...)
32 : : #define DEBUG_fputs(x...)
33 : :
34 : : #endif
35 : :
36 : : #ifdef USE_PERFTOOLS
37 : : #include <google/heap-checker.h>
38 : : #include <google/heap-profiler.h>
39 : : extern HeapLeakChecker* heap_checker;
40 : : #endif
41 : :
42 : : typedef unsigned long long int uint64;
43 : : typedef unsigned int uint32;
44 : : typedef unsigned short uint16;
45 : : typedef unsigned char uint8;
46 : : typedef long long int int64;
47 : : typedef int64 bro_int_t;
48 : : typedef uint64 bro_uint_t;
49 : :
50 : : #if SIZEOF_LONG_LONG == 8
51 : : typedef unsigned long long uint64;
52 : : typedef long long int64;
53 : : #elif SIZEOF_LONG_INT == 8
54 : : typedef unsigned long int uint64;
55 : : typedef long int int64;
56 : : #else
57 : : # error "Couldn't reliably identify 64-bit type. Please report to bro@bro-ids.org."
58 : : #endif
59 : :
60 : : // "ptr_compat_uint" and "ptr_compat_int" are (un)signed integers of
61 : : // pointer size. They can be cast safely to a pointer, e.g. in Lists,
62 : : // which represent their entities as void* pointers.
63 : : //
64 : : #if SIZEOF_VOID_P == 8
65 : : typedef uint64 ptr_compat_uint;
66 : : typedef int64 ptr_compat_int;
67 : : #elif SIZEOF_VOID_P == 4
68 : : typedef uint32 ptr_compat_uint;
69 : : typedef int ptr_compat_int;
70 : : #else
71 : : # error "Unusual pointer size. Please report to bro@bro-ids.org."
72 : : #endif
73 : :
74 : : template <class T>
75 : 0 : void delete_each(T* t)
76 : : {
77 : : typedef typename T::iterator iterator;
78 [ # # ]: 0 : for ( iterator it = t->begin(); it != t->end(); ++it )
79 [ # # ]: 0 : delete *it;
80 : : }
81 : :
82 : : extern char* copy_string(const char* s);
83 : : extern int streq(const char* s1, const char* s2);
84 : :
85 : : // Returns the character corresponding to the given escape sequence (s points
86 : : // just past the '\'), and updates s to point just beyond the last character
87 : : // of the sequence.
88 : : extern int expand_escape(const char*& s);
89 : :
90 : : extern char* skip_whitespace(char* s);
91 : : extern const char* skip_whitespace(const char* s);
92 : : extern char* skip_whitespace(char* s, char* end_of_s);
93 : : extern const char* skip_whitespace(const char* s, const char* end_of_s);
94 : : extern char* skip_digits(char* s);
95 : : extern char* get_word(char*& s);
96 : : extern void get_word(int length, const char* s, int& pwlen, const char*& pw);
97 : : extern void to_upper(char* s);
98 : : extern const char* strchr_n(const char* s, const char* end_of_s, char ch);
99 : : extern const char* strrchr_n(const char* s, const char* end_of_s, char ch);
100 : : extern int decode_hex(char ch);
101 : : extern unsigned char encode_hex(int h);
102 : : extern int strcasecmp_n(int s_len, const char* s, const char* t);
103 : : #ifndef HAVE_STRCASESTR
104 : : extern char* strcasestr(const char* s, const char* find);
105 : : #endif
106 : : extern const char* strpbrk_n(size_t len, const char* s, const char* charset);
107 : : extern int atoi_n(int len, const char* s, const char** end,
108 : : int base, int& result);
109 : : int strstr_n(const int big_len, const unsigned char* big,
110 : : const int little_len, const unsigned char* little);
111 : : extern int fputs(int len, const char* s, FILE* fp);
112 : : extern bool is_printable(const char* s, int len);
113 : :
114 : : extern const char* fmt_bytes(const char* data, int len);
115 : :
116 : : // Note: returns a pointer into a shared buffer.
117 : : extern const char* fmt(const char* format, ...)
118 : : myattribute((format (printf, 1, 2)));
119 : : extern const char* fmt_access_time(double time);
120 : :
121 : : extern bool ensure_dir(const char *dirname);
122 : :
123 : : // Returns true if path exists and is a directory.
124 : : bool is_dir(const char* path);
125 : :
126 : : extern uint8 shared_hmac_md5_key[16];
127 : : extern void hash_md5(size_t size, const unsigned char* bytes,
128 : : unsigned char digest[16]);
129 : :
130 : : extern int hmac_key_set;
131 : : extern unsigned char shared_hmac_md5_key[16];
132 : : extern void hmac_md5(size_t size, const unsigned char* bytes,
133 : : unsigned char digest[16]);
134 : :
135 : : extern const char* md5_digest_print(const unsigned char digest[16]);
136 : :
137 : : // Initializes RNGs for random() and MD5 usage. If seed is given, then
138 : : // it is used (to provide determinism). If load_file is given, the seeds
139 : : // (both random & MD5) are loaded from that file. This takes precedence
140 : : // over the "seed" argument. If write_file is given, the seeds are written
141 : : // to that file.
142 : : //
143 : : extern void init_random_seed(uint32 seed, const char* load_file,
144 : : const char* write_file);
145 : :
146 : : extern uint64 rand64bit();
147 : :
148 : : #define UHASH_KEY_SIZE 32
149 : : extern uint8 uhash_key[UHASH_KEY_SIZE];
150 : :
151 : : // Each event source that may generate events gets an internally unique ID.
152 : : // This is always LOCAL for a local Bro. For remote event sources, it gets
153 : : // assigned by the RemoteSerializer.
154 : : //
155 : : // FIXME: Find a nicer place for this type definition.
156 : : // Unfortunately, it introduces circular dependencies when defined in one of
157 : : // the obvious places (like Event.h or RemoteSerializer.h)
158 : :
159 : : typedef ptr_compat_uint SourceID;
160 : : static const SourceID SOURCE_LOCAL = 0;
161 : :
162 : : class BroObj;
163 : : extern void message(const char* msg);
164 : : extern void warn(const char* msg);
165 : : extern void warn(const char* msg, const char* addl);
166 : : extern void error(const char* msg);
167 : : extern void error(const char* msg, const char* addl);
168 : : extern void error(const char* msg, uint32 addl);
169 : : extern void run_time(const char* msg);
170 : : extern void run_time(const char* fmt, BroObj* obj);
171 : : extern void run_time(const char* fmt, const char* arg);
172 : : extern void run_time(const char* fmt, const char* arg1, const char* arg2);
173 : : extern void internal_error(const char* fmt, ...)
174 : : myattribute((volatile, format (printf, 1, 2)));
175 : : extern void pinpoint();
176 : : extern int int_list_cmp(const void* v1, const void* v2);
177 : :
178 : : extern const char* bro_path();
179 : : extern const char* bro_prefixes();
180 : : extern FILE* search_for_file(const char* filename, const char* ext,
181 : : const char** full_filename);
182 : :
183 : : // Renames the given file to a new temporary name, and opens a new file with
184 : : // the original name. Returns new file or NULL on error. Inits rotate_info if
185 : : // given (open time is set network time).
186 : : class RecordVal;
187 : : extern FILE* rotate_file(const char* name, RecordVal* rotate_info);
188 : :
189 : : // This mimics the script-level function with the same name.
190 : : const char* log_file_name(const char* tag);
191 : :
192 : : // Calculate the duration until the next time a file is to be rotated, based
193 : : // on the given rotate_interval and rotate_base_time.
194 : : double calc_next_rotate(double rotate_interval, const char* rotate_base_time);
195 : :
196 : : // Terminates processing gracefully, similar to pressing CTRL-C.
197 : : void terminate_processing();
198 : :
199 : : // Sets the current status of the Bro process to the given string.
200 : : // If the option --status-file has been set, this is written into
201 : : // the the corresponding file. Otherwise, the function is a no-op.
202 : : #define set_processing_status(status, location) \
203 : : _set_processing_status(status " [" location "]\n");
204 : : void _set_processing_status(const char* status);
205 : :
206 : : // Current timestamp, from a networking perspective, not a wall-clock
207 : : // perspective. In particular, if we're reading from a savefile this
208 : : // is the time of the most recent packet, not the time returned by
209 : : // gettimeofday().
210 : : extern double network_time;
211 : :
212 : : // Returns the current time.
213 : : // (In pseudo-realtime mode this is faked to be the start time of the
214 : : // trace plus the time interval Bro has been running. To avoid this,
215 : : // call with real=true).
216 : : extern double current_time(bool real=false);
217 : :
218 : : // Convert a time represented as a double to a timeval struct.
219 : : extern struct timeval double_to_timeval(double t);
220 : :
221 : : // Return > 0 if tv_a > tv_b, 0 if equal, < 0 if tv_a < tv_b.
222 : : extern int time_compare(struct timeval* tv_a, struct timeval* tv_b);
223 : :
224 : 101641 : inline int min(int a, int b)
225 : : {
226 [ + + ]: 101641 : return a < b ? a : b;
227 : : }
228 : :
229 : 2568 : inline int max(int a, int b)
230 : : {
231 [ + + ]: 2568 : return a > b ? a : b;
232 : : }
233 : :
234 : : // For now, don't use hash_maps - they're not fully portable.
235 : : #if 0
236 : : // Use for hash_map's string keys.
237 : : struct eqstr {
238 : : bool operator()(const char* s1, const char* s2) const
239 : : {
240 : : return strcmp(s1, s2) == 0;
241 : : }
242 : : };
243 : : #endif
244 : :
245 : : // Use for map's string keys.
246 : : struct ltstr {
247 : 7372 : bool operator()(const char* s1, const char* s2) const
248 : : {
249 : 7372 : return strcmp(s1, s2) < 0;
250 : : }
251 : : };
252 : :
253 : : // Versions of realloc/malloc which abort() on out of memory
254 : :
255 : 32812 : inline size_t pad_size(size_t size)
256 : : {
257 : : // We emulate glibc here (values measured on Linux i386).
258 : : // FIXME: We should better copy the portable value definitions from glibc.
259 [ - + ]: 32812 : if ( size == 0 )
260 : 0 : return 0; // glibc allocated 16 bytes anyway.
261 : :
262 : 32812 : const int pad = 8;
263 [ + + ]: 32812 : if ( size < 12 )
264 : 380 : return 2 * pad;
265 : :
266 : 32812 : return ((size+3) / pad + 1) * pad;
267 : : }
268 : :
269 : : #define padded_sizeof(x) (pad_size(sizeof(x)))
270 : :
271 : : extern void out_of_memory(const char* where);
272 : :
273 : 9907 : inline void* safe_realloc(void* ptr, size_t size)
274 : : {
275 : 9907 : ptr = realloc(ptr, size);
276 [ + + - + ]: 9907 : if ( size && ! ptr )
277 : 0 : out_of_memory("realloc");
278 : :
279 : 9907 : return ptr;
280 : : }
281 : :
282 : 914881 : inline void* safe_malloc(size_t size)
283 : : {
284 : 914881 : void* ptr = malloc(size);
285 [ - + ]: 914881 : if ( ! ptr )
286 : 0 : out_of_memory("malloc");
287 : :
288 : 914881 : return ptr;
289 : : }
290 : :
291 : 353 : inline char* safe_strncpy(char* dest, const char* src, size_t n)
292 : : {
293 : 353 : char* result = strncpy(dest, src, n);
294 : 353 : dest[n-1] = '\0';
295 : 353 : return result;
296 : : }
297 : :
298 : 25558 : inline int safe_snprintf(char* str, size_t size, const char* format, ...)
299 : : {
300 : : va_list al;
301 : 25558 : va_start(al, format);
302 : 25558 : int result = vsnprintf(str, size, format, al);
303 : 25558 : va_end(al);
304 : 25558 : str[size-1] = '\0';
305 : :
306 : 25558 : return result;
307 : : }
308 : :
309 : 71980 : inline int safe_vsnprintf(char* str, size_t size, const char* format, va_list al)
310 : : {
311 : 71980 : int result = vsnprintf(str, size, format, al);
312 : 71980 : str[size-1] = '\0';
313 : 71980 : return result;
314 : : }
315 : :
316 : : // Returns total memory allocations and (if available) amount actually
317 : : // handed out by malloc.
318 : : extern void get_memory_usage(unsigned int* total,
319 : : unsigned int* malloced);
320 : : #endif
|