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>