]> git.ipfire.org Git - thirdparty/bird.git/blob - lib/ip.c
Merge branch 'master' into int-new
[thirdparty/bird.git] / lib / ip.c
1 /*
2 * BIRD Library -- IP address functions
3 *
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9 /**
10 * DOC: IP addresses
11 *
12 * BIRD uses its own abstraction of IP address in order to share the same
13 * code for both IPv4 and IPv6. IP addresses are represented as entities
14 * of type &ip_addr which are never to be treated as numbers and instead
15 * they must be manipulated using the following functions and macros.
16 */
17
18 #include <stdlib.h>
19
20 #include "nest/bird.h"
21 #include "lib/ip.h"
22
23
24 int
25 ip6_compare(ip6_addr a, ip6_addr b)
26 {
27 int i;
28 for (i=0; i<4; i++)
29 if (a.addr[i] > b.addr[i])
30 return 1;
31 else if (a.addr[i] < b.addr[i])
32 return -1;
33 return 0;
34 }
35
36 ip6_addr
37 ip6_mkmask(uint n)
38 {
39 ip6_addr a;
40 int i;
41
42 for (i=0; i<4; i++)
43 {
44 if (!n)
45 a.addr[i] = 0;
46 else if (n >= 32)
47 {
48 a.addr[i] = ~0;
49 n -= 32;
50 }
51 else
52 {
53 a.addr[i] = u32_mkmask(n);
54 n = 0;
55 }
56 }
57
58 return a;
59 }
60
61 uint
62 ip6_masklen(ip6_addr *a)
63 {
64 int i, j, n;
65
66 for (i=0, n=0; i<4; i++, n+=32)
67 if (a->addr[i] != ~0U)
68 {
69 j = u32_masklen(a->addr[i]);
70 if (j == 255)
71 return j;
72 n += j;
73 while (++i < 4)
74 if (a->addr[i])
75 return 255;
76 break;
77 }
78
79 return n;
80 }
81
82 int
83 ip4_classify(ip4_addr ad)
84 {
85 u32 a = _I(ad);
86 u32 b = a >> 24U;
87
88 if (b && b <= 0xdf)
89 {
90 if (b == 0x7f)
91 return IADDR_HOST | SCOPE_HOST;
92 else if ((b == 0x0a) ||
93 ((a & 0xffff0000) == 0xc0a80000) ||
94 ((a & 0xfff00000) == 0xac100000))
95 return IADDR_HOST | SCOPE_SITE;
96 else
97 return IADDR_HOST | SCOPE_UNIVERSE;
98 }
99
100 if (b >= 0xe0 && b <= 0xef)
101 return IADDR_MULTICAST | SCOPE_UNIVERSE;
102
103 if (a == 0xffffffff)
104 return IADDR_BROADCAST | SCOPE_LINK;
105
106 return IADDR_INVALID;
107 }
108
109 int
110 ip6_classify(ip6_addr *a)
111 {
112 u32 x = a->addr[0];
113
114 if ((x & 0xe0000000) == 0x20000000) /* 2000::/3 Aggregatable Global Unicast Address */
115 return IADDR_HOST | SCOPE_UNIVERSE;
116 if ((x & 0xffc00000) == 0xfe800000) /* fe80::/10 Link-Local Address */
117 return IADDR_HOST | SCOPE_LINK;
118 if ((x & 0xffc00000) == 0xfec00000) /* fec0::/10 Site-Local Address */
119 return IADDR_HOST | SCOPE_SITE;
120 if ((x & 0xfe000000) == 0xfc000000) /* fc00::/7 Unique Local Unicast Address (RFC 4193) */
121 return IADDR_HOST | SCOPE_SITE;
122 if ((x & 0xff000000) == 0xff000000) /* ff00::/8 Multicast Address */
123 {
124 uint scope = (x >> 16) & 0x0f;
125 switch (scope)
126 {
127 case 1: return IADDR_MULTICAST | SCOPE_HOST;
128 case 2: return IADDR_MULTICAST | SCOPE_LINK;
129 case 5: return IADDR_MULTICAST | SCOPE_SITE;
130 case 8: return IADDR_MULTICAST | SCOPE_ORGANIZATION;
131 case 14: return IADDR_MULTICAST | SCOPE_UNIVERSE;
132 default: return IADDR_MULTICAST | SCOPE_UNDEFINED;
133 }
134 }
135
136 if (!x && !a->addr[1])
137 {
138 u32 a2 = a->addr[2];
139 u32 a3 = a->addr[3];
140
141 if (a2 == 0 && a3 == 1)
142 return IADDR_HOST | SCOPE_HOST; /* Loopback address */
143 if (a2 == 0)
144 return ip4_classify(_MI4(a3)); /* IPv4 compatible addresses */
145 if (a2 == 0xffff)
146 return ip4_classify(_MI4(a3)); /* IPv4 mapped addresses */
147
148 return IADDR_INVALID;
149 }
150
151 return IADDR_HOST | SCOPE_UNDEFINED;
152 }
153
154
155
156 /*
157 * Conversion of IPv6 address to presentation format and vice versa.
158 * Heavily inspired by routines written by Paul Vixie for the BIND project
159 * and of course by RFC 2373.
160 */
161
162
163 char *
164 ip4_ntop(ip4_addr a, char *b)
165 {
166 u32 x = _I(a);
167 return b + bsprintf(b, "%d.%d.%d.%d", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff);
168 }
169
170
171 char *
172 ip6_ntop(ip6_addr a, char *b)
173 {
174 u16 words[8];
175 int bestpos, bestlen, curpos, curlen, i;
176
177 /* First of all, preprocess the address and find the longest run of zeros */
178 bestlen = bestpos = curpos = curlen = 0;
179 for (i=0; i<8; i++)
180 {
181 u32 x = a.addr[i/2];
182 words[i] = ((i%2) ? x : (x >> 16)) & 0xffff;
183 if (words[i])
184 curlen = 0;
185 else
186 {
187 if (!curlen)
188 curpos = i;
189 curlen++;
190 if (curlen > bestlen)
191 {
192 bestpos = curpos;
193 bestlen = curlen;
194 }
195 }
196 }
197
198 if (bestlen < 2)
199 bestpos = -1;
200
201 /* Is it an encapsulated IPv4 address? */
202 if (!bestpos && ((bestlen == 5 && a.addr[2] == 0xffff) || (bestlen == 6)))
203 {
204 u32 x = a.addr[3];
205 b += bsprintf(b, "::%s%d.%d.%d.%d",
206 a.addr[2] ? "ffff:" : "",
207 (x >> 24) & 0xff,
208 (x >> 16) & 0xff,
209 (x >> 8) & 0xff,
210 x & 0xff);
211 return b;
212 }
213
214 /* Normal IPv6 formatting, compress the largest sequence of zeros */
215 for (i=0; i<8; i++)
216 {
217 if (i == bestpos)
218 {
219 i += bestlen - 1;
220 *b++ = ':';
221 if (i == 7)
222 *b++ = ':';
223 }
224 else
225 {
226 if (i)
227 *b++ = ':';
228 b += bsprintf(b, "%x", words[i]);
229 }
230 }
231 *b = 0;
232 return b;
233 }
234
235 int
236 ip4_pton(const char *a, ip4_addr *o)
237 {
238 int i;
239 unsigned long int l;
240 u32 ia = 0;
241
242 i=4;
243 while (i--)
244 {
245 char *d, *c = strchr(a, '.');
246 if (!c != !i)
247 return 0;
248 l = strtoul(a, &d, 10);
249 if (((d != c) && *d) || (l > 255))
250 return 0;
251 ia = (ia << 8) | l;
252 if (c)
253 c++;
254 a = c;
255 }
256 *o = ip4_from_u32(ia);
257 return 1;
258 }
259
260 int
261 ip6_pton(const char *a, ip6_addr *o)
262 {
263 u16 words[8];
264 int i, j, k, l, hfil;
265 const char *start;
266
267 if (a[0] == ':') /* Leading :: */
268 {
269 if (a[1] != ':')
270 return 0;
271 a++;
272 }
273
274 hfil = -1;
275 i = 0;
276 while (*a)
277 {
278 if (*a == ':') /* :: */
279 {
280 if (hfil >= 0)
281 return 0;
282
283 hfil = i;
284 a++;
285 continue;
286 }
287
288 j = 0;
289 l = 0;
290 start = a;
291 for (;;)
292 {
293 if (*a >= '0' && *a <= '9')
294 k = *a++ - '0';
295 else if (*a >= 'A' && *a <= 'F')
296 k = *a++ - 'A' + 10;
297 else if (*a >= 'a' && *a <= 'f')
298 k = *a++ - 'a' + 10;
299 else
300 break;
301
302 j = (j << 4) + k;
303 if (j >= 0x10000 || ++l > 4)
304 return 0;
305 }
306
307 if (*a == ':' && a[1])
308 a++;
309 else if (*a == '.' && (i == 6 || (i < 6 && hfil >= 0)))
310 { /* Embedded IPv4 address */
311 ip4_addr x;
312 if (!ip4_pton(start, &x))
313 return 0;
314 words[i++] = _I(x) >> 16;
315 words[i++] = _I(x);
316 break;
317 }
318 else if (*a)
319 return 0;
320
321 if (i >= 8)
322 return 0;
323
324 words[i++] = j;
325 }
326
327 /* Replace :: with an appropriate number of zeros */
328 if (hfil >= 0)
329 {
330 j = 8 - i;
331 for (i=7; i-j >= hfil; i--)
332 words[i] = words[i-j];
333 for (; i>=hfil; i--)
334 words[i] = 0;
335 }
336
337 /* Convert the address to ip6_addr format */
338 for (i=0; i<4; i++)
339 o->addr[i] = (words[2*i] << 16) | words[2*i+1];
340
341 return 1;
342 }
343
344
345 /**
346 * ip_scope_text - get textual representation of address scope
347 * @scope: scope (%SCOPE_xxx)
348 *
349 * Returns a pointer to a textual name of the scope given.
350 */
351 char *
352 ip_scope_text(uint scope)
353 {
354 static char *scope_table[] = { "host", "link", "site", "org", "univ", "undef" };
355
356 if (scope > SCOPE_UNDEFINED)
357 return "?";
358 else
359 return scope_table[scope];
360 }
361
362 ip4_addr
363 ip4_class_mask(ip4_addr ad)
364 {
365 u32 m, a = _I(ad);
366
367 if (a == 0x00000000)
368 m = 0x00000000;
369 else if (a < 0x80000000)
370 m = 0xff000000;
371 else if (a < 0xc0000000)
372 m = 0xffff0000;
373 else
374 m = 0xffffff00;
375 if (a & ~m)
376 m = 0xffffffff;
377
378 return _MI4(m);
379 }
380
381 #if 0
382 /**
383 * ipa_equal - compare two IP addresses for equality
384 * @x: IP address
385 * @y: IP address
386 *
387 * ipa_equal() returns 1 if @x and @y represent the same IP address, else 0.
388 */
389 int ipa_equal(ip_addr x, ip_addr y) { DUMMY }
390
391 /**
392 * ipa_nonzero - test if an IP address is defined
393 * @x: IP address
394 *
395 * ipa_nonzero returns 1 if @x is a defined IP address (not all bits are zero),
396 * else 0.
397 *
398 * The undefined all-zero address is reachable as a |IPA_NONE| macro.
399 */
400 int ipa_nonzero(ip_addr x) { DUMMY }
401
402 /**
403 * ipa_and - compute bitwise and of two IP addresses
404 * @x: IP address
405 * @y: IP address
406 *
407 * This function returns a bitwise and of @x and @y. It's primarily
408 * used for network masking.
409 */
410 ip_addr ipa_and(ip_addr x, ip_addr y) { DUMMY }
411
412 /**
413 * ipa_or - compute bitwise or of two IP addresses
414 * @x: IP address
415 * @y: IP address
416 *
417 * This function returns a bitwise or of @x and @y.
418 */
419 ip_addr ipa_or(ip_addr x, ip_addr y) { DUMMY }
420
421 /**
422 * ipa_xor - compute bitwise xor of two IP addresses
423 * @x: IP address
424 * @y: IP address
425 *
426 * This function returns a bitwise xor of @x and @y.
427 */
428 ip_addr ipa_xor(ip_addr x, ip_addr y) { DUMMY }
429
430 /**
431 * ipa_not - compute bitwise negation of two IP addresses
432 * @x: IP address
433 *
434 * This function returns a bitwise negation of @x.
435 */
436 ip_addr ipa_not(ip_addr x) { DUMMY }
437
438 /**
439 * ipa_mkmask - create a netmask
440 * @x: prefix length
441 *
442 * This function returns an &ip_addr corresponding of a netmask
443 * of an address prefix of size @x.
444 */
445 ip_addr ipa_mkmask(int x) { DUMMY }
446
447 /**
448 * ipa_masklen - calculate netmask length
449 * @x: IP address
450 *
451 * This function checks whether @x represents a valid netmask and
452 * returns the size of the associate network prefix or -1 for invalid
453 * mask.
454 */
455 int ipa_masklen(ip_addr x) { DUMMY }
456
457 /**
458 * ipa_hash - hash IP addresses
459 * @x: IP address
460 *
461 * ipa_hash() returns a 16-bit hash value of the IP address @x.
462 */
463 int ipa_hash(ip_addr x) { DUMMY }
464
465 /**
466 * ipa_hton - convert IP address to network order
467 * @x: IP address
468 *
469 * Converts the IP address @x to the network byte order.
470 *
471 * Beware, this is a macro and it alters the argument!
472 */
473 void ipa_hton(ip_addr x) { DUMMY }
474
475 /**
476 * ipa_ntoh - convert IP address to host order
477 * @x: IP address
478 *
479 * Converts the IP address @x from the network byte order.
480 *
481 * Beware, this is a macro and it alters the argument!
482 */
483 void ipa_ntoh(ip_addr x) { DUMMY }
484
485 /**
486 * ipa_classify - classify an IP address
487 * @x: IP address
488 *
489 * ipa_classify() returns an address class of @x, that is a bitwise or
490 * of address type (%IADDR_INVALID, %IADDR_HOST, %IADDR_BROADCAST, %IADDR_MULTICAST)
491 * with address scope (%SCOPE_HOST to %SCOPE_UNIVERSE) or -1 (%IADDR_INVALID)
492 * for an invalid address.
493 */
494 int ipa_classify(ip_addr x) { DUMMY }
495
496 /**
497 * ip4_class_mask - guess netmask according to address class
498 * @x: IPv4 address
499 *
500 * This function (available in IPv4 version only) returns a
501 * network mask according to the address class of @x. Although
502 * classful addressing is nowadays obsolete, there still live
503 * routing protocols transferring no prefix lengths nor netmasks
504 * and this function could be useful to them.
505 */
506 ip4_addr ip4_class_mask(ip4_addr x) { DUMMY }
507
508 /**
509 * ipa_from_u32 - convert IPv4 address to an integer
510 * @x: IP address
511 *
512 * This function takes an IPv4 address and returns its numeric
513 * representation.
514 */
515 u32 ipa_from_u32(ip_addr x) { DUMMY }
516
517 /**
518 * ipa_to_u32 - convert integer to IPv4 address
519 * @x: a 32-bit integer
520 *
521 * ipa_to_u32() takes a numeric representation of an IPv4 address
522 * and converts it to the corresponding &ip_addr.
523 */
524 ip_addr ipa_to_u32(u32 x) { DUMMY }
525
526 /**
527 * ipa_compare - compare two IP addresses for order
528 * @x: IP address
529 * @y: IP address
530 *
531 * The ipa_compare() function takes two IP addresses and returns
532 * -1 if @x is less than @y in canonical ordering (lexicographical
533 * order of the bit strings), 1 if @x is greater than @y and 0
534 * if they are the same.
535 */
536 int ipa_compare(ip_addr x, ip_addr y) { DUMMY }
537
538 /**
539 * ipa_build6 - build an IPv6 address from parts
540 * @a1: part #1
541 * @a2: part #2
542 * @a3: part #3
543 * @a4: part #4
544 *
545 * ipa_build() takes @a1 to @a4 and assembles them to a single IPv6
546 * address. It's used for example when a protocol wants to bind its
547 * socket to a hard-wired multicast address.
548 */
549 ip_addr ipa_build6(u32 a1, u32 a2, u32 a3, u32 a4) { DUMMY }
550
551 /**
552 * ip_ntop - convert IP address to textual representation
553 * @a: IP address
554 * @buf: buffer of size at least %STD_ADDRESS_P_LENGTH
555 *
556 * This function takes an IP address and creates its textual
557 * representation for presenting to the user.
558 */
559 char *ip_ntop(ip_addr a, char *buf) { DUMMY }
560
561 /**
562 * ip_ntox - convert IP address to hexadecimal representation
563 * @a: IP address
564 * @buf: buffer of size at least %STD_ADDRESS_P_LENGTH
565 *
566 * This function takes an IP address and creates its hexadecimal
567 * textual representation. Primary use: debugging dumps.
568 */
569 char *ip_ntox(ip_addr a, char *buf) { DUMMY }
570
571 /**
572 * ip_pton - parse textual representation of IP address
573 * @a: textual representation
574 * @o: where to put the resulting address
575 *
576 * This function parses a textual IP address representation and
577 * stores the decoded address to a variable pointed to by @o.
578 * Returns 0 if a parse error has occurred, else 0.
579 */
580 int ip_pton(char *a, ip_addr *o) { DUMMY }
581
582 #endif