iof-bird-daemon / lib / net.h @ 62e64905
History | View | Annotate | Download (14.2 KB)
1 |
/*
|
---|---|
2 |
* BIRD Internet Routing Daemon -- Network addresses
|
3 |
*
|
4 |
* (c) 2015 Ondrej Zajicek <santiago@crfreenet.org>
|
5 |
* (c) 2015 CZ.NIC z.s.p.o.
|
6 |
*
|
7 |
* Can be freely distributed and used under the terms of the GNU GPL.
|
8 |
*/
|
9 |
|
10 |
#ifndef _BIRD_NET_H_
|
11 |
#define _BIRD_NET_H_
|
12 |
|
13 |
#include "lib/ip.h" |
14 |
|
15 |
|
16 |
#define NET_IP4 1 |
17 |
#define NET_IP6 2 |
18 |
#define NET_VPN4 3 |
19 |
#define NET_VPN6 4 |
20 |
#define NET_ROA4 5 |
21 |
#define NET_ROA6 6 |
22 |
#define NET_FLOW4 7 |
23 |
#define NET_FLOW6 8 |
24 |
#define NET_MPLS 9 |
25 |
#define NET_MAX 10 |
26 |
|
27 |
#define NB_IP4 (1 << NET_IP4) |
28 |
#define NB_IP6 (1 << NET_IP6) |
29 |
#define NB_VPN4 (1 << NET_VPN4) |
30 |
#define NB_VPN6 (1 << NET_VPN6) |
31 |
#define NB_ROA4 (1 << NET_ROA4) |
32 |
#define NB_ROA6 (1 << NET_ROA6) |
33 |
#define NB_FLOW4 (1 << NET_FLOW4) |
34 |
#define NB_FLOW6 (1 << NET_FLOW6) |
35 |
#define NB_MPLS (1 << NET_MPLS) |
36 |
|
37 |
#define NB_IP (NB_IP4 | NB_IP6)
|
38 |
#define NB_ANY 0xffffffff |
39 |
|
40 |
|
41 |
typedef struct net_addr { |
42 |
u8 type; |
43 |
u8 pxlen; |
44 |
u16 length; |
45 |
u8 data[16];
|
46 |
u64 align[0];
|
47 |
} net_addr; |
48 |
|
49 |
typedef struct net_addr_ip4 { |
50 |
u8 type; |
51 |
u8 pxlen; |
52 |
u16 length; |
53 |
ip4_addr prefix; |
54 |
} net_addr_ip4; |
55 |
|
56 |
typedef struct net_addr_ip6 { |
57 |
u8 type; |
58 |
u8 pxlen; |
59 |
u16 length; |
60 |
ip6_addr prefix; |
61 |
} net_addr_ip6; |
62 |
|
63 |
typedef struct net_addr_vpn4 { |
64 |
u8 type; |
65 |
u8 pxlen; |
66 |
u16 length; |
67 |
ip4_addr prefix; |
68 |
u64 rd; |
69 |
} net_addr_vpn4; |
70 |
|
71 |
typedef struct net_addr_vpn6 { |
72 |
u8 type; |
73 |
u8 pxlen; |
74 |
u16 length; |
75 |
ip6_addr prefix; |
76 |
u64 rd; |
77 |
} net_addr_vpn6; |
78 |
|
79 |
typedef struct net_addr_roa4 { |
80 |
u8 type; |
81 |
u8 pxlen; |
82 |
u16 length; |
83 |
ip4_addr prefix; |
84 |
u32 max_pxlen; |
85 |
u32 asn; |
86 |
} net_addr_roa4; |
87 |
|
88 |
typedef struct net_addr_roa6 { |
89 |
u8 type; |
90 |
u8 pxlen; |
91 |
u16 length; |
92 |
ip6_addr prefix; |
93 |
u32 max_pxlen; |
94 |
u32 asn; |
95 |
} net_addr_roa6; |
96 |
|
97 |
typedef struct net_addr_flow4 { |
98 |
u8 type; |
99 |
u8 pxlen; |
100 |
u16 length; |
101 |
ip4_addr prefix; |
102 |
byte data[0];
|
103 |
} net_addr_flow4; |
104 |
|
105 |
typedef struct net_addr_flow6 { |
106 |
u8 type; |
107 |
u8 pxlen; |
108 |
u16 length; |
109 |
ip6_addr prefix; |
110 |
byte data[0];
|
111 |
} net_addr_flow6; |
112 |
|
113 |
typedef struct net_addr_mpls { |
114 |
u8 type; |
115 |
u8 pxlen; |
116 |
u16 length; |
117 |
u32 label; |
118 |
} net_addr_mpls; |
119 |
|
120 |
typedef union net_addr_union { |
121 |
net_addr n; |
122 |
net_addr_ip4 ip4; |
123 |
net_addr_ip6 ip6; |
124 |
net_addr_vpn4 vpn4; |
125 |
net_addr_vpn6 vpn6; |
126 |
net_addr_roa4 roa4; |
127 |
net_addr_roa6 roa6; |
128 |
net_addr_flow4 flow4; |
129 |
net_addr_flow6 flow6; |
130 |
net_addr_mpls mpls; |
131 |
} net_addr_union; |
132 |
|
133 |
|
134 |
extern const char * const net_label[]; |
135 |
extern const u16 net_addr_length[]; |
136 |
extern const u8 net_max_prefix_length[]; |
137 |
extern const u16 net_max_text_length[]; |
138 |
|
139 |
#define NET_MAX_TEXT_LENGTH 256 |
140 |
|
141 |
|
142 |
#define NET_ADDR_IP4(prefix,pxlen) \
|
143 |
((net_addr_ip4) { NET_IP4, pxlen, sizeof(net_addr_ip4), prefix })
|
144 |
|
145 |
#define NET_ADDR_IP6(prefix,pxlen) \
|
146 |
((net_addr_ip6) { NET_IP6, pxlen, sizeof(net_addr_ip6), prefix })
|
147 |
|
148 |
#define NET_ADDR_VPN4(prefix,pxlen,rd) \
|
149 |
((net_addr_vpn4) { NET_VPN4, pxlen, sizeof(net_addr_vpn4), prefix, rd })
|
150 |
|
151 |
#define NET_ADDR_VPN6(prefix,pxlen,rd) \
|
152 |
((net_addr_vpn6) { NET_VPN6, pxlen, sizeof(net_addr_vpn6), prefix, rd })
|
153 |
|
154 |
#define NET_ADDR_ROA4(prefix,pxlen,max_pxlen,asn) \
|
155 |
((net_addr_roa4) { NET_ROA4, pxlen, sizeof(net_addr_roa4), prefix, max_pxlen, asn })
|
156 |
|
157 |
#define NET_ADDR_ROA6(prefix,pxlen,max_pxlen,asn) \
|
158 |
((net_addr_roa6) { NET_ROA6, pxlen, sizeof(net_addr_roa6), prefix, max_pxlen, asn })
|
159 |
|
160 |
#define NET_ADDR_FLOW4(prefix,pxlen,dlen) \
|
161 |
((net_addr_flow4) { NET_FLOW4, pxlen, sizeof(net_addr_ip4) + dlen, prefix })
|
162 |
|
163 |
#define NET_ADDR_FLOW6(prefix,pxlen,dlen) \
|
164 |
((net_addr_flow6) { NET_FLOW6, pxlen, sizeof(net_addr_ip6) + dlen, prefix })
|
165 |
|
166 |
#define NET_ADDR_MPLS(label) \
|
167 |
((net_addr_mpls) { NET_MPLS, 20, sizeof(net_addr_mpls), label }) |
168 |
|
169 |
|
170 |
static inline void net_fill_ip4(net_addr *a, ip4_addr prefix, uint pxlen) |
171 |
{ *(net_addr_ip4 *)a = NET_ADDR_IP4(prefix, pxlen); } |
172 |
|
173 |
static inline void net_fill_ip6(net_addr *a, ip6_addr prefix, uint pxlen) |
174 |
{ *(net_addr_ip6 *)a = NET_ADDR_IP6(prefix, pxlen); } |
175 |
|
176 |
static inline void net_fill_vpn4(net_addr *a, ip4_addr prefix, uint pxlen, u64 rd) |
177 |
{ *(net_addr_vpn4 *)a = NET_ADDR_VPN4(prefix, pxlen, rd); } |
178 |
|
179 |
static inline void net_fill_vpn6(net_addr *a, ip6_addr prefix, uint pxlen, u64 rd) |
180 |
{ *(net_addr_vpn6 *)a = NET_ADDR_VPN6(prefix, pxlen, rd); } |
181 |
|
182 |
static inline void net_fill_roa4(net_addr *a, ip4_addr prefix, uint pxlen, uint max_pxlen, u32 asn) |
183 |
{ *(net_addr_roa4 *)a = NET_ADDR_ROA4(prefix, pxlen, max_pxlen, asn); } |
184 |
|
185 |
static inline void net_fill_roa6(net_addr *a, ip6_addr prefix, uint pxlen, uint max_pxlen, u32 asn) |
186 |
{ *(net_addr_roa6 *)a = NET_ADDR_ROA6(prefix, pxlen, max_pxlen, asn); } |
187 |
|
188 |
static inline void net_fill_mpls(net_addr *a, u32 label) |
189 |
{ *(net_addr_mpls *)a = NET_ADDR_MPLS(label); } |
190 |
|
191 |
static inline void net_fill_ipa(net_addr *a, ip_addr prefix, uint pxlen) |
192 |
{ |
193 |
if (ipa_is_ip4(prefix))
|
194 |
net_fill_ip4(a, ipa_to_ip4(prefix), pxlen); |
195 |
else
|
196 |
net_fill_ip6(a, ipa_to_ip6(prefix), pxlen); |
197 |
} |
198 |
|
199 |
static inline void net_fill_ip_host(net_addr *a, ip_addr prefix) |
200 |
{ |
201 |
if (ipa_is_ip4(prefix))
|
202 |
net_fill_ip4(a, ipa_to_ip4(prefix), IP4_MAX_PREFIX_LENGTH); |
203 |
else
|
204 |
net_fill_ip6(a, ipa_to_ip6(prefix), IP6_MAX_PREFIX_LENGTH); |
205 |
} |
206 |
|
207 |
static inline void net_fill_flow4(net_addr *a, ip4_addr prefix, uint pxlen, byte *data, uint dlen) |
208 |
{ |
209 |
net_addr_flow4 *f = (void *) a;
|
210 |
*f = NET_ADDR_FLOW4(prefix, pxlen, dlen); |
211 |
memcpy(f->data, data, dlen); |
212 |
} |
213 |
|
214 |
static inline void net_fill_flow6(net_addr *a, ip6_addr prefix, uint pxlen, byte *data, uint dlen) |
215 |
{ |
216 |
net_addr_flow6 *f = (void *) a;
|
217 |
*f = NET_ADDR_FLOW6(prefix, pxlen, dlen); |
218 |
memcpy(f->data, data, dlen); |
219 |
} |
220 |
|
221 |
static inline int net_val_match(u8 type, u32 mask) |
222 |
{ return !!((1 << type) & mask); } |
223 |
|
224 |
static inline int net_type_match(const net_addr *a, u32 mask) |
225 |
{ return net_val_match(a->type, mask); }
|
226 |
|
227 |
static inline int net_is_ip(const net_addr *a) |
228 |
{ return (a->type == NET_IP4) || (a->type == NET_IP6); }
|
229 |
|
230 |
static inline int net_is_roa(const net_addr *a) |
231 |
{ return (a->type == NET_ROA4) || (a->type == NET_ROA6); }
|
232 |
|
233 |
|
234 |
static inline ip4_addr net4_prefix(const net_addr *a) |
235 |
{ return ((net_addr_ip4 *) a)->prefix; }
|
236 |
|
237 |
static inline ip6_addr net6_prefix(const net_addr *a) |
238 |
{ return ((net_addr_ip6 *) a)->prefix; }
|
239 |
|
240 |
static inline ip_addr net_prefix(const net_addr *a) |
241 |
{ |
242 |
switch (a->type)
|
243 |
{ |
244 |
case NET_IP4:
|
245 |
case NET_VPN4:
|
246 |
case NET_ROA4:
|
247 |
case NET_FLOW4:
|
248 |
return ipa_from_ip4(net4_prefix(a));
|
249 |
|
250 |
case NET_IP6:
|
251 |
case NET_VPN6:
|
252 |
case NET_ROA6:
|
253 |
case NET_FLOW6:
|
254 |
return ipa_from_ip6(net6_prefix(a));
|
255 |
|
256 |
case NET_MPLS:
|
257 |
default:
|
258 |
return IPA_NONE;
|
259 |
} |
260 |
} |
261 |
|
262 |
static inline u32 net_mpls(const net_addr *a) |
263 |
{ |
264 |
if (a->type == NET_MPLS)
|
265 |
return ((net_addr_mpls *) a)->label;
|
266 |
|
267 |
bug("Can't call net_mpls on non-mpls net_addr");
|
268 |
} |
269 |
|
270 |
static inline uint net4_pxlen(const net_addr *a) |
271 |
{ return a->pxlen; }
|
272 |
|
273 |
static inline uint net6_pxlen(const net_addr *a) |
274 |
{ return a->pxlen; }
|
275 |
|
276 |
static inline uint net_pxlen(const net_addr *a) |
277 |
{ return a->pxlen; }
|
278 |
|
279 |
ip_addr net_pxmask(const net_addr *a);
|
280 |
|
281 |
|
282 |
static inline int net_equal(const net_addr *a, const net_addr *b) |
283 |
{ return (a->length == b->length) && !memcmp(a, b, a->length); }
|
284 |
|
285 |
static inline int net_equal_ip4(const net_addr_ip4 *a, const net_addr_ip4 *b) |
286 |
{ return !memcmp(a, b, sizeof(net_addr_ip4)); } |
287 |
|
288 |
static inline int net_equal_ip6(const net_addr_ip6 *a, const net_addr_ip6 *b) |
289 |
{ return !memcmp(a, b, sizeof(net_addr_ip6)); } |
290 |
|
291 |
static inline int net_equal_vpn4(const net_addr_vpn4 *a, const net_addr_vpn4 *b) |
292 |
{ return !memcmp(a, b, sizeof(net_addr_vpn4)); } |
293 |
|
294 |
static inline int net_equal_vpn6(const net_addr_vpn6 *a, const net_addr_vpn6 *b) |
295 |
{ return !memcmp(a, b, sizeof(net_addr_vpn6)); } |
296 |
|
297 |
static inline int net_equal_roa4(const net_addr_roa4 *a, const net_addr_roa4 *b) |
298 |
{ return !memcmp(a, b, sizeof(net_addr_roa4)); } |
299 |
|
300 |
static inline int net_equal_roa6(const net_addr_roa6 *a, const net_addr_roa6 *b) |
301 |
{ return !memcmp(a, b, sizeof(net_addr_roa6)); } |
302 |
|
303 |
static inline int net_equal_flow4(const net_addr_flow4 *a, const net_addr_flow4 *b) |
304 |
{ return net_equal((const net_addr *) a, (const net_addr *) b); } |
305 |
|
306 |
static inline int net_equal_flow6(const net_addr_flow6 *a, const net_addr_flow6 *b) |
307 |
{ return net_equal((const net_addr *) a, (const net_addr *) b); } |
308 |
|
309 |
static inline int net_equal_mpls(const net_addr_mpls *a, const net_addr_mpls *b) |
310 |
{ return !memcmp(a, b, sizeof(net_addr_mpls)); } |
311 |
|
312 |
|
313 |
static inline int net_equal_prefix_roa4(const net_addr_roa4 *a, const net_addr_roa4 *b) |
314 |
{ return ip4_equal(a->prefix, b->prefix) && (a->pxlen == b->pxlen); }
|
315 |
|
316 |
static inline int net_equal_prefix_roa6(const net_addr_roa6 *a, const net_addr_roa6 *b) |
317 |
{ return ip6_equal(a->prefix, b->prefix) && (a->pxlen == b->pxlen); }
|
318 |
|
319 |
|
320 |
static inline int net_zero_ip4(const net_addr_ip4 *a) |
321 |
{ return !a->pxlen && ip4_zero(a->prefix); }
|
322 |
|
323 |
static inline int net_zero_ip6(const net_addr_ip6 *a) |
324 |
{ return !a->pxlen && ip6_zero(a->prefix); }
|
325 |
|
326 |
static inline int net_zero_vpn4(const net_addr_vpn4 *a) |
327 |
{ return !a->pxlen && ip4_zero(a->prefix) && !a->rd; }
|
328 |
|
329 |
static inline int net_zero_vpn6(const net_addr_vpn6 *a) |
330 |
{ return !a->pxlen && ip6_zero(a->prefix) && !a->rd; }
|
331 |
|
332 |
static inline int net_zero_roa4(const net_addr_roa4 *a) |
333 |
{ return !a->pxlen && ip4_zero(a->prefix) && !a->max_pxlen && !a->asn; }
|
334 |
|
335 |
static inline int net_zero_roa6(const net_addr_roa6 *a) |
336 |
{ return !a->pxlen && ip6_zero(a->prefix) && !a->max_pxlen && !a->asn; }
|
337 |
|
338 |
static inline int net_zero_flow4(const net_addr_flow4 *a) |
339 |
{ return !a->pxlen && ip4_zero(a->prefix) && !a->data; }
|
340 |
|
341 |
static inline int net_zero_flow6(const net_addr_flow6 *a) |
342 |
{ return !a->pxlen && ip6_zero(a->prefix) && !a->data; }
|
343 |
|
344 |
static inline int net_zero_mpls(const net_addr_mpls *a) |
345 |
{ return !a->label; }
|
346 |
|
347 |
|
348 |
static inline int net_compare_ip4(const net_addr_ip4 *a, const net_addr_ip4 *b) |
349 |
{ return ip4_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
|
350 |
|
351 |
static inline int net_compare_ip6(const net_addr_ip6 *a, const net_addr_ip6 *b) |
352 |
{ return ip6_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
|
353 |
|
354 |
static inline int net_compare_vpn4(const net_addr_vpn4 *a, const net_addr_vpn4 *b) |
355 |
{ return u64_cmp(a->rd, b->rd) ?: ip4_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
|
356 |
|
357 |
static inline int net_compare_vpn6(const net_addr_vpn6 *a, const net_addr_vpn6 *b) |
358 |
{ return u64_cmp(a->rd, b->rd) ?: ip6_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
|
359 |
|
360 |
static inline int net_compare_roa4(const net_addr_roa4 *a, const net_addr_roa4 *b) |
361 |
{ return ip4_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen) ?: uint_cmp(a->max_pxlen, b->max_pxlen) ?: uint_cmp(a->asn, b->asn); }
|
362 |
|
363 |
static inline int net_compare_roa6(const net_addr_roa6 *a, const net_addr_roa6 *b) |
364 |
{ return ip6_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen) ?: uint_cmp(a->max_pxlen, b->max_pxlen) ?: uint_cmp(a->asn, b->asn); }
|
365 |
|
366 |
static inline int net_compare_flow4(const net_addr_flow4 *a, const net_addr_flow4 *b) |
367 |
{ return ip4_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen) ?: uint_cmp(a->length, b->length) ?: memcmp(a->data, b->data, a->length - sizeof(net_addr_flow4)); } |
368 |
|
369 |
static inline int net_compare_flow6(const net_addr_flow6 *a, const net_addr_flow6 *b) |
370 |
{ return ip6_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen) ?: uint_cmp(a->length, b->length) ?: memcmp(a->data, b->data, a->length - sizeof(net_addr_flow6)); } |
371 |
|
372 |
static inline int net_compare_mpls(const net_addr_mpls *a, const net_addr_mpls *b) |
373 |
{ return uint_cmp(a->label, b->label); }
|
374 |
|
375 |
int net_compare(const net_addr *a, const net_addr *b); |
376 |
|
377 |
|
378 |
static inline void net_copy(net_addr *dst, const net_addr *src) |
379 |
{ memcpy(dst, src, src->length); } |
380 |
|
381 |
static inline void net_copy_ip4(net_addr_ip4 *dst, const net_addr_ip4 *src) |
382 |
{ memcpy(dst, src, sizeof(net_addr_ip4)); }
|
383 |
|
384 |
static inline void net_copy_ip6(net_addr_ip6 *dst, const net_addr_ip6 *src) |
385 |
{ memcpy(dst, src, sizeof(net_addr_ip6)); }
|
386 |
|
387 |
static inline void net_copy_vpn4(net_addr_vpn4 *dst, const net_addr_vpn4 *src) |
388 |
{ memcpy(dst, src, sizeof(net_addr_vpn4)); }
|
389 |
|
390 |
static inline void net_copy_vpn6(net_addr_vpn6 *dst, const net_addr_vpn6 *src) |
391 |
{ memcpy(dst, src, sizeof(net_addr_vpn6)); }
|
392 |
|
393 |
static inline void net_copy_roa4(net_addr_roa4 *dst, const net_addr_roa4 *src) |
394 |
{ memcpy(dst, src, sizeof(net_addr_roa4)); }
|
395 |
|
396 |
static inline void net_copy_roa6(net_addr_roa6 *dst, const net_addr_roa6 *src) |
397 |
{ memcpy(dst, src, sizeof(net_addr_roa6)); }
|
398 |
|
399 |
static inline void net_copy_flow4(net_addr_flow4 *dst, const net_addr_flow4 *src) |
400 |
{ memcpy(dst, src, src->length); } |
401 |
|
402 |
static inline void net_copy_flow6(net_addr_flow6 *dst, const net_addr_flow6 *src) |
403 |
{ memcpy(dst, src, src->length); } |
404 |
|
405 |
static inline void net_copy_mpls(net_addr_mpls *dst, const net_addr_mpls *src) |
406 |
{ memcpy(dst, src, sizeof(net_addr_mpls)); }
|
407 |
|
408 |
|
409 |
/* XXXX */
|
410 |
static inline u32 u64_hash(u64 a) |
411 |
{ return u32_hash(a); }
|
412 |
|
413 |
static inline u32 net_hash_ip4(const net_addr_ip4 *n) |
414 |
{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); } |
415 |
|
416 |
static inline u32 net_hash_ip6(const net_addr_ip6 *n) |
417 |
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); } |
418 |
|
419 |
static inline u32 net_hash_vpn4(const net_addr_vpn4 *n) |
420 |
{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); } |
421 |
|
422 |
static inline u32 net_hash_vpn6(const net_addr_vpn6 *n) |
423 |
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); } |
424 |
|
425 |
static inline u32 net_hash_roa4(const net_addr_roa4 *n) |
426 |
{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); } |
427 |
|
428 |
static inline u32 net_hash_roa6(const net_addr_roa6 *n) |
429 |
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); } |
430 |
|
431 |
static inline u32 net_hash_flow4(const net_addr_flow4 *n) |
432 |
{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); } |
433 |
|
434 |
static inline u32 net_hash_flow6(const net_addr_flow6 *n) |
435 |
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); } |
436 |
|
437 |
static inline u32 net_hash_mpls(const net_addr_mpls *n) |
438 |
{ return n->label; }
|
439 |
|
440 |
u32 net_hash(const net_addr *a);
|
441 |
|
442 |
|
443 |
static inline int net_validate_ip4(const net_addr_ip4 *n) |
444 |
{ |
445 |
return (n->pxlen <= IP4_MAX_PREFIX_LENGTH) &&
|
446 |
ip4_zero(ip4_and(n->prefix, ip4_not(ip4_mkmask(n->pxlen)))); |
447 |
} |
448 |
|
449 |
static inline int net_validate_ip6(const net_addr_ip6 *n) |
450 |
{ |
451 |
return (n->pxlen <= IP6_MAX_PREFIX_LENGTH) &&
|
452 |
ip6_zero(ip6_and(n->prefix, ip6_not(ip6_mkmask(n->pxlen)))); |
453 |
} |
454 |
|
455 |
static inline int net_validate_mpls(const net_addr_mpls *n) |
456 |
{ |
457 |
return n->label < (1 << 20); |
458 |
} |
459 |
|
460 |
int net_validate(const net_addr *N); |
461 |
|
462 |
|
463 |
static inline void net_normalize_ip4(net_addr_ip4 *n) |
464 |
{ n->prefix = ip4_and(n->prefix, ip4_mkmask(n->pxlen)); } |
465 |
|
466 |
static inline void net_normalize_ip6(net_addr_ip6 *n) |
467 |
{ n->prefix = ip6_and(n->prefix, ip6_mkmask(n->pxlen)); } |
468 |
|
469 |
void net_normalize(net_addr *N);
|
470 |
|
471 |
|
472 |
int net_classify(const net_addr *N); |
473 |
int net_format(const net_addr *N, char *buf, int buflen); |
474 |
|
475 |
|
476 |
int ipa_in_netX(const ip_addr A, const net_addr *N); |
477 |
int net_in_netX(const net_addr *A, const net_addr *N); |
478 |
|
479 |
|
480 |
#endif
|