]>
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)) |
77506349 | 34 | #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) |
cf3527e2 | 35 | |
70945cb6 OZ |
36 | #define BIT32_VAL(p) (((u32) 1) << ((p) % 32)) |
37 | #define BIT32_TEST(b,p) ((b)[(p)/32] & BIT32_VAL(p)) | |
38 | #define BIT32_SET(b,p) ((b)[(p)/32] |= BIT32_VAL(p)) | |
39 | #define BIT32_CLR(b,p) ((b)[(p)/32] &= ~BIT32_VAL(p)) | |
40 | #define BIT32_ZERO(b,l) memset((b), 0, (l)/8) | |
41 | ||
61340248 MM |
42 | #ifndef NULL |
43 | #define NULL ((void *) 0) | |
44 | #endif | |
45 | ||
b655596d OZ |
46 | #ifndef IPV6 |
47 | #define IP_VERSION 4 | |
48 | #else | |
49 | #define IP_VERSION 6 | |
50 | #endif | |
51 | ||
0e175f9f | 52 | |
5da8f82f | 53 | /* Macros for gcc attributes */ |
18c8241a MM |
54 | |
55 | #define NORET __attribute__((noreturn)) | |
206f59df | 56 | #define UNUSED __attribute__((unused)) |
58ef912c | 57 | |
0e175f9f OZ |
58 | |
59 | /* Microsecond time */ | |
60 | ||
61 | typedef s64 btime; | |
62 | ||
41f8bf57 OZ |
63 | #define S_ *1000000 |
64 | #define MS_ *1000 | |
65 | #define US_ *1 | |
0e175f9f OZ |
66 | #define TO_S /1000000 |
67 | #define TO_MS /1000 | |
68 | #define TO_US /1 | |
69 | ||
70 | #ifndef PARSER | |
41f8bf57 OZ |
71 | #define S S_ |
72 | #define MS MS_ | |
73 | #define US US_ | |
0e175f9f OZ |
74 | #endif |
75 | ||
76 | ||
1123e707 OZ |
77 | /* Rate limiting */ |
78 | ||
79 | struct tbf { | |
80 | bird_clock_t timestamp; /* Last update */ | |
81 | u16 count; /* Available tokens */ | |
82 | u16 burst; /* Max number of tokens */ | |
83 | u16 rate; /* Rate of replenishment */ | |
84 | u16 mark; /* Whether last op was limited */ | |
85 | }; | |
86 | ||
87 | /* Default TBF values for rate limiting log messages */ | |
88 | #define TBF_DEFAULT_LOG_LIMITS { .rate = 1, .burst = 5 } | |
89 | ||
90 | void tbf_update(struct tbf *f); | |
91 | ||
92 | static inline int | |
93 | tbf_limit(struct tbf *f) | |
94 | { | |
95 | tbf_update(f); | |
96 | ||
97 | if (!f->count) | |
98 | { | |
99 | f->mark = 1; | |
100 | return 1; | |
101 | } | |
102 | ||
103 | f->count--; | |
104 | f->mark = 0; | |
105 | return 0; | |
106 | } | |
107 | ||
108 | ||
c40e05a0 MM |
109 | /* Logging and dying */ |
110 | ||
0e175f9f OZ |
111 | typedef struct buffer { |
112 | byte *start; | |
113 | byte *pos; | |
114 | byte *end; | |
115 | } buffer; | |
116 | ||
117 | #define STACK_BUFFER_INIT(buf,size) \ | |
118 | do { \ | |
119 | buf.start = alloca(size); \ | |
120 | buf.pos = buf.start; \ | |
121 | buf.end = buf.start + size; \ | |
122 | } while(0) | |
123 | ||
124 | #define LOG_BUFFER_INIT(buf) \ | |
125 | STACK_BUFFER_INIT(buf, LOG_BUFFER_SIZE) | |
126 | ||
127 | #define LOG_BUFFER_SIZE 1024 | |
128 | ||
e98bc2ea | 129 | #define log log_msg |
0e175f9f | 130 | void log_commit(int class, buffer *buf); |
e98bc2ea | 131 | void log_msg(char *msg, ...); |
1123e707 | 132 | void log_rl(struct tbf *rl, char *msg, ...); |
1be52eea | 133 | void die(char *msg, ...) NORET; |
98e87c86 | 134 | void bug(char *msg, ...) NORET; |
c40e05a0 MM |
135 | |
136 | #define L_DEBUG "\001" /* Debugging messages */ | |
98e87c86 MM |
137 | #define L_TRACE "\002" /* Protocol tracing */ |
138 | #define L_INFO "\003" /* Informational messages */ | |
139 | #define L_REMOTE "\004" /* Remote protocol errors */ | |
27e993fb MM |
140 | #define L_WARN "\005" /* Local warnings */ |
141 | #define L_ERR "\006" /* Local errors */ | |
142 | #define L_AUTH "\007" /* Authorization failed etc. */ | |
143 | #define L_FATAL "\010" /* Fatal errors */ | |
144 | #define L_BUG "\011" /* BIRD bugs */ | |
18c8241a | 145 | |
18c8241a | 146 | void debug(char *msg, ...); /* Printf to debug output */ |
c40e05a0 MM |
147 | |
148 | /* Debugging */ | |
149 | ||
3cbfcafe | 150 | #if defined(LOCAL_DEBUG) || defined(GLOBAL_DEBUG) |
5222c46c | 151 | #define DBG(x, y...) debug(x, ##y) |
c40e05a0 | 152 | #else |
e68dd11c | 153 | #define DBG(x, y...) do { } while(0) |
c40e05a0 MM |
154 | #endif |
155 | ||
98e87c86 MM |
156 | #ifdef DEBUGGING |
157 | #define ASSERT(x) do { if (!(x)) bug("Assertion `%s' failed at %s:%d", #x, __FILE__, __LINE__); } while(0) | |
158 | #else | |
159 | #define ASSERT(x) do { } while(0) | |
160 | #endif | |
161 | ||
f6519414 MM |
162 | /* Pseudorandom numbers */ |
163 | ||
164 | u32 random_u32(void); | |
165 | ||
58ef912c | 166 | #endif |