]>
Commit | Line | Data |
---|---|---|
58ef912c MM |
1 | /* |
2 | * BIRD Library | |
3 | * | |
206f59df | 4 | * (c) 1998--2004 Martin Mares <mj@ucw.cz> |
58ef912c MM |
5 | * |
6 | * Can be freely distributed and used under the terms of the GNU GPL. | |
7 | */ | |
8 | ||
9 | #ifndef _BIRD_BIRDLIB_H_ | |
10 | #define _BIRD_BIRDLIB_H_ | |
11 | ||
cb530392 | 12 | #include "timer.h" |
0e175f9f | 13 | #include "alloca.h" |
cb530392 | 14 | |
58ef912c MM |
15 | /* Ugly structure offset handling macros */ |
16 | ||
54d70d3e | 17 | #define OFFSETOF(s, i) ((size_t) &((s *)0)->i) |
58ef912c | 18 | #define SKIP_BACK(s, i, p) ((s *)((char *)p - OFFSETOF(s, i))) |
7fdd338c | 19 | #define BIRD_ALIGN(s, a) (((s)+a-1)&~(a-1)) |
18c8241a | 20 | |
c4c63eec MM |
21 | /* Utility macros */ |
22 | ||
41f8bf57 OZ |
23 | #define MIN_(a,b) (((a)<(b))?(a):(b)) |
24 | #define MAX_(a,b) (((a)>(b))?(a):(b)) | |
0e175f9f OZ |
25 | |
26 | #ifndef PARSER | |
1ec52253 OZ |
27 | #undef MIN |
28 | #undef MAX | |
41f8bf57 OZ |
29 | #define MIN(a,b) MIN_(a,b) |
30 | #define MAX(a,b) MAX_(a,b) | |
93e868c7 OZ |
31 | #endif |
32 | ||
47f18ac3 | 33 | #define ABS(a) ((a)>=0 ? (a) : -(a)) |
8d9eef17 | 34 | #define DELTA(a,b) (((a)>=(b))?(a)-(b):(b)-(a)) |
77506349 | 35 | #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) |
cf3527e2 | 36 | |
4e639744 OZ |
37 | |
38 | /* Bitfield macros */ | |
39 | ||
40 | /* b is u32 array (or ptr), l is size of it in bits (multiple of 32), p is 0..(l-1) */ | |
70945cb6 OZ |
41 | #define BIT32_VAL(p) (((u32) 1) << ((p) % 32)) |
42 | #define BIT32_TEST(b,p) ((b)[(p)/32] & BIT32_VAL(p)) | |
43 | #define BIT32_SET(b,p) ((b)[(p)/32] |= BIT32_VAL(p)) | |
44 | #define BIT32_CLR(b,p) ((b)[(p)/32] &= ~BIT32_VAL(p)) | |
45 | #define BIT32_ZERO(b,l) memset((b), 0, (l)/8) | |
46 | ||
61340248 MM |
47 | #ifndef NULL |
48 | #define NULL ((void *) 0) | |
49 | #endif | |
50 | ||
b655596d OZ |
51 | #ifndef IPV6 |
52 | #define IP_VERSION 4 | |
53 | #else | |
54 | #define IP_VERSION 6 | |
55 | #endif | |
56 | ||
0e175f9f | 57 | |
5da8f82f | 58 | /* Macros for gcc attributes */ |
18c8241a MM |
59 | |
60 | #define NORET __attribute__((noreturn)) | |
206f59df | 61 | #define UNUSED __attribute__((unused)) |
58ef912c | 62 | |
0e175f9f OZ |
63 | |
64 | /* Microsecond time */ | |
65 | ||
66 | typedef s64 btime; | |
67 | ||
41f8bf57 OZ |
68 | #define S_ *1000000 |
69 | #define MS_ *1000 | |
70 | #define US_ *1 | |
0e175f9f OZ |
71 | #define TO_S /1000000 |
72 | #define TO_MS /1000 | |
73 | #define TO_US /1 | |
74 | ||
75 | #ifndef PARSER | |
41f8bf57 OZ |
76 | #define S S_ |
77 | #define MS MS_ | |
78 | #define US US_ | |
0e175f9f OZ |
79 | #endif |
80 | ||
81 | ||
1123e707 OZ |
82 | /* Rate limiting */ |
83 | ||
84 | struct tbf { | |
85 | bird_clock_t timestamp; /* Last update */ | |
86 | u16 count; /* Available tokens */ | |
87 | u16 burst; /* Max number of tokens */ | |
88 | u16 rate; /* Rate of replenishment */ | |
89 | u16 mark; /* Whether last op was limited */ | |
90 | }; | |
91 | ||
92 | /* Default TBF values for rate limiting log messages */ | |
93 | #define TBF_DEFAULT_LOG_LIMITS { .rate = 1, .burst = 5 } | |
94 | ||
95 | void tbf_update(struct tbf *f); | |
96 | ||
97 | static inline int | |
98 | tbf_limit(struct tbf *f) | |
99 | { | |
100 | tbf_update(f); | |
101 | ||
102 | if (!f->count) | |
103 | { | |
104 | f->mark = 1; | |
105 | return 1; | |
106 | } | |
107 | ||
108 | f->count--; | |
109 | f->mark = 0; | |
110 | return 0; | |
111 | } | |
112 | ||
113 | ||
c40e05a0 MM |
114 | /* Logging and dying */ |
115 | ||
0e175f9f OZ |
116 | typedef struct buffer { |
117 | byte *start; | |
118 | byte *pos; | |
119 | byte *end; | |
120 | } buffer; | |
121 | ||
122 | #define STACK_BUFFER_INIT(buf,size) \ | |
123 | do { \ | |
124 | buf.start = alloca(size); \ | |
125 | buf.pos = buf.start; \ | |
126 | buf.end = buf.start + size; \ | |
127 | } while(0) | |
128 | ||
129 | #define LOG_BUFFER_INIT(buf) \ | |
130 | STACK_BUFFER_INIT(buf, LOG_BUFFER_SIZE) | |
131 | ||
132 | #define LOG_BUFFER_SIZE 1024 | |
133 | ||
e98bc2ea | 134 | #define log log_msg |
0e175f9f | 135 | void log_commit(int class, buffer *buf); |
e598853e PT |
136 | void log_msg(const char *msg, ...); |
137 | void log_rl(struct tbf *rl, const char *msg, ...); | |
138 | void die(const char *msg, ...) NORET; | |
139 | void bug(const char *msg, ...) NORET; | |
c40e05a0 MM |
140 | |
141 | #define L_DEBUG "\001" /* Debugging messages */ | |
98e87c86 MM |
142 | #define L_TRACE "\002" /* Protocol tracing */ |
143 | #define L_INFO "\003" /* Informational messages */ | |
144 | #define L_REMOTE "\004" /* Remote protocol errors */ | |
27e993fb MM |
145 | #define L_WARN "\005" /* Local warnings */ |
146 | #define L_ERR "\006" /* Local errors */ | |
147 | #define L_AUTH "\007" /* Authorization failed etc. */ | |
148 | #define L_FATAL "\010" /* Fatal errors */ | |
149 | #define L_BUG "\011" /* BIRD bugs */ | |
18c8241a | 150 | |
e598853e | 151 | void debug(const char *msg, ...); /* Printf to debug output */ |
c40e05a0 MM |
152 | |
153 | /* Debugging */ | |
154 | ||
3cbfcafe | 155 | #if defined(LOCAL_DEBUG) || defined(GLOBAL_DEBUG) |
5222c46c | 156 | #define DBG(x, y...) debug(x, ##y) |
c40e05a0 | 157 | #else |
e68dd11c | 158 | #define DBG(x, y...) do { } while(0) |
c40e05a0 MM |
159 | #endif |
160 | ||
98e87c86 MM |
161 | #ifdef DEBUGGING |
162 | #define ASSERT(x) do { if (!(x)) bug("Assertion `%s' failed at %s:%d", #x, __FILE__, __LINE__); } while(0) | |
163 | #else | |
164 | #define ASSERT(x) do { } while(0) | |
165 | #endif | |
166 | ||
f6519414 MM |
167 | /* Pseudorandom numbers */ |
168 | ||
169 | u32 random_u32(void); | |
170 | ||
58ef912c | 171 | #endif |