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
ip6_compare(ip6_addr a,ip6_addr b)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
ip6_mkmask(uint n)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
ip6_masklen(ip6_addr * a)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
ip4_classify(ip4_addr ad)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
ip6_classify(ip6_addr * a)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 *
ip4_ntop(ip4_addr a,char * b)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 *
ip6_ntop(ip6_addr a,char * b)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
ip4_pton(const char * a,ip4_addr * o)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
ip6_pton(const char * a,ip6_addr * o)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 *
ip_scope_text(uint scope)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
ip4_class_mask(ip4_addr ad)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
583