Annotation of embedaddon/bird/lib/ip.c, revision 1.1.1.1
1.1 misho 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: int
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 < 0)
71: return j;
72: n += j;
73: while (++i < 4)
74: if (a->addr[i])
75: return -1;
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
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>