Annotation of embedaddon/quagga/isisd/isis_misc.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * IS-IS Rout(e)ing protocol - isis_misc.h
        !             3:  *                             Miscellanous routines
        !             4:  *
        !             5:  * Copyright (C) 2001,2002   Sampo Saaristo
        !             6:  *                           Tampere University of Technology      
        !             7:  *                           Institute of Communications Engineering
        !             8:  *
        !             9:  * This program is free software; you can redistribute it and/or modify it 
        !            10:  * under the terms of the GNU General Public Licenseas published by the Free 
        !            11:  * Software Foundation; either version 2 of the License, or (at your option) 
        !            12:  * any later version.
        !            13:  *
        !            14:  * This program is distributed in the hope that it will be useful,but WITHOUT 
        !            15:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
        !            17:  * more details.
        !            18: 
        !            19:  * You should have received a copy of the GNU General Public License along 
        !            20:  * with this program; if not, write to the Free Software Foundation, Inc., 
        !            21:  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
        !            22:  */
        !            23: 
        !            24: #include <zebra.h>
        !            25: 
        !            26: #include "stream.h"
        !            27: #include "vty.h"
        !            28: #include "hash.h"
        !            29: #include "if.h"
        !            30: #include "command.h"
        !            31: 
        !            32: #include "isisd/dict.h"
        !            33: #include "isisd/isis_constants.h"
        !            34: #include "isisd/isis_common.h"
        !            35: #include "isisd/isis_circuit.h"
        !            36: #include "isisd/isisd.h"
        !            37: #include "isisd/isis_misc.h"
        !            38: 
        !            39: #include "isisd/isis_tlv.h"
        !            40: #include "isisd/isis_lsp.h"
        !            41: #include "isisd/isis_constants.h"
        !            42: #include "isisd/isis_adjacency.h"
        !            43: 
        !            44: /* staticly assigned vars for printing purposes */
        !            45: struct in_addr new_prefix;
        !            46: /* len of xxxx.xxxx.xxxx + place for #0 termination */
        !            47: char sysid[15];
        !            48: /* len of xxxx.xxxx.xxxx + place for #0 termination */
        !            49: char snpa[15];
        !            50: /* len of xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx */
        !            51: char isonet[51];
        !            52: /* + place for #0 termination */
        !            53: /* len of xxxx.xxxx.xxxx.xx.xx + place for #0 termination */
        !            54: char lspid[21];
        !            55: /* len of xxYxxMxWxdxxhxxmxxs + place for #0 termination */
        !            56: char datestring[20];
        !            57: char nlpidstring[30];
        !            58: 
        !            59: /*
        !            60:  * This converts the isonet to its printable format
        !            61:  */
        !            62: const char *
        !            63: isonet_print (u_char * from, int len)
        !            64: {
        !            65:   int i = 0;
        !            66:   char *pos = isonet;
        !            67: 
        !            68:   if (!from)
        !            69:     return "unknown";
        !            70: 
        !            71:   while (i < len)
        !            72:     {
        !            73:       if (i & 1)
        !            74:        {
        !            75:          sprintf (pos, "%02x", *(from + i));
        !            76:          pos += 2;
        !            77:        }
        !            78:       else
        !            79:        {
        !            80:          if (i == (len - 1))
        !            81:            {                   /* No dot at the end of address */
        !            82:              sprintf (pos, "%02x", *(from + i));
        !            83:              pos += 2;
        !            84:            }
        !            85:          else
        !            86:            {
        !            87:              sprintf (pos, "%02x.", *(from + i));
        !            88:              pos += 3;
        !            89:            }
        !            90:        }
        !            91:       i++;
        !            92:     }
        !            93:   *(pos) = '\0';
        !            94:   return isonet;
        !            95: }
        !            96: 
        !            97: /*
        !            98:  * Returns 0 on error, length of buff on ok
        !            99:  * extract dot from the dotted str, and insert all the number in a buff 
        !           100:  */
        !           101: int
        !           102: dotformat2buff (u_char * buff, const u_char * dotted)
        !           103: {
        !           104:   int dotlen, len = 0;
        !           105:   const u_char *pos = dotted;
        !           106:   u_char number[3];
        !           107:   int nextdotpos = 2;
        !           108: 
        !           109:   number[2] = '\0';
        !           110:   dotlen = strlen(dotted);
        !           111:   if (dotlen > 50)
        !           112:     {
        !           113:       /* this can't be an iso net, its too long */
        !           114:       return 0;
        !           115:     }
        !           116: 
        !           117:   while ((pos - dotted) < dotlen && len < 20)
        !           118:     {
        !           119:       if (*pos == '.')
        !           120:        {
        !           121:          /* we expect the . at 2, and than every 5 */
        !           122:          if ((pos - dotted) != nextdotpos)
        !           123:            {
        !           124:              len = 0;
        !           125:              break;
        !           126:            }
        !           127:          nextdotpos += 5;
        !           128:          pos++;
        !           129:          continue;
        !           130:        }
        !           131:       /* we must have at least two chars left here */
        !           132:       if (dotlen - (pos - dotted) < 2)
        !           133:        {
        !           134:          len = 0;
        !           135:          break;
        !           136:        }
        !           137: 
        !           138:       if ((isxdigit ((int) *pos)) && (isxdigit ((int) *(pos + 1))))
        !           139:        {
        !           140:          memcpy (number, pos, 2);
        !           141:          pos += 2;
        !           142:        }
        !           143:       else
        !           144:        {
        !           145:          len = 0;
        !           146:          break;
        !           147:        }
        !           148: 
        !           149:       *(buff + len) = (char) strtol ((char *)number, NULL, 16);
        !           150:       len++;
        !           151:     }
        !           152: 
        !           153:   return len;
        !           154: }
        !           155: 
        !           156: /*
        !           157:  * conversion of XXXX.XXXX.XXXX to memory
        !           158:  */
        !           159: int
        !           160: sysid2buff (u_char * buff, const u_char * dotted)
        !           161: {
        !           162:   int len = 0;
        !           163:   const u_char *pos = dotted;
        !           164:   u_char number[3];
        !           165: 
        !           166:   number[2] = '\0';
        !           167:   // surely not a sysid_string if not 14 length
        !           168:   if (strlen (dotted) != 14)
        !           169:     {
        !           170:       return 0;
        !           171:     }
        !           172: 
        !           173:   while (len < ISIS_SYS_ID_LEN)
        !           174:     {
        !           175:       if (*pos == '.')
        !           176:        {
        !           177:          /* the . is not positioned correctly */
        !           178:          if (((pos - dotted) != 4) && ((pos - dotted) != 9))
        !           179:            {
        !           180:              len = 0;
        !           181:              break;
        !           182:            }
        !           183:          pos++;
        !           184:          continue;
        !           185:        }
        !           186:       if ((isxdigit ((int) *pos)) && (isxdigit ((int) *(pos + 1))))
        !           187:        {
        !           188:          memcpy (number, pos, 2);
        !           189:          pos += 2;
        !           190:        }
        !           191:       else
        !           192:        {
        !           193:          len = 0;
        !           194:          break;
        !           195:        }
        !           196: 
        !           197:       *(buff + len) = (char) strtol ((char *)number, NULL, 16);
        !           198:       len++;
        !           199:     }
        !           200: 
        !           201:   return len;
        !           202: 
        !           203: }
        !           204: 
        !           205: /*
        !           206:  * converts the nlpids struct (filled by TLV #129)
        !           207:  * into a string
        !           208:  */
        !           209: 
        !           210: char *
        !           211: nlpid2string (struct nlpids *nlpids)
        !           212: {
        !           213:   char *pos = nlpidstring;
        !           214:   int i;
        !           215: 
        !           216:   for (i = 0; i < nlpids->count; i++)
        !           217:     {
        !           218:       switch (nlpids->nlpids[i])
        !           219:        {
        !           220:        case NLPID_IP:
        !           221:          pos += sprintf (pos, "IPv4");
        !           222:          break;
        !           223:        case NLPID_IPV6:
        !           224:          pos += sprintf (pos, "IPv6");
        !           225:          break;
        !           226:        case NLPID_SNAP:
        !           227:          pos += sprintf (pos, "SNAP");
        !           228:          break;
        !           229:        case NLPID_CLNP:
        !           230:          pos += sprintf (pos, "CLNP");
        !           231:          break;
        !           232:        case NLPID_ESIS:
        !           233:          pos += sprintf (pos, "ES-IS");
        !           234:          break;
        !           235:        default:
        !           236:          pos += sprintf (pos, "unknown");
        !           237:          break;
        !           238:        }
        !           239:       if (nlpids->count - i > 1)
        !           240:        pos += sprintf (pos, ", ");
        !           241: 
        !           242:     }
        !           243: 
        !           244:   *(pos) = '\0';
        !           245: 
        !           246:   return nlpidstring;
        !           247: }
        !           248: 
        !           249: /*
        !           250:  *  supports the given af ?
        !           251:  */
        !           252: int
        !           253: speaks (struct nlpids *nlpids, int family)
        !           254: {
        !           255:   int i, speaks = 0;
        !           256: 
        !           257:   if (nlpids == (struct nlpids *) NULL)
        !           258:     return speaks;
        !           259:   for (i = 0; i < nlpids->count; i++)
        !           260:     {
        !           261:       if (family == AF_INET && nlpids->nlpids[i] == NLPID_IP)
        !           262:        speaks = 1;
        !           263:       if (family == AF_INET6 && nlpids->nlpids[i] == NLPID_IPV6)
        !           264:        speaks = 1;
        !           265:     }
        !           266: 
        !           267:   return speaks;
        !           268: }
        !           269: 
        !           270: /*
        !           271:  * Returns 0 on error, IS-IS Circuit Type on ok
        !           272:  */
        !           273: int
        !           274: string2circuit_t (const u_char * str)
        !           275: {
        !           276: 
        !           277:   if (!str)
        !           278:     return 0;
        !           279: 
        !           280:   if (!strcmp (str, "level-1"))
        !           281:     return IS_LEVEL_1;
        !           282: 
        !           283:   if (!strcmp (str, "level-2-only") || !strcmp (str, "level-2"))
        !           284:     return IS_LEVEL_2;
        !           285: 
        !           286:   if (!strcmp (str, "level-1-2"))
        !           287:     return IS_LEVEL_1_AND_2;
        !           288: 
        !           289:   return 0;
        !           290: }
        !           291: 
        !           292: const char *
        !           293: circuit_t2string (int circuit_t)
        !           294: {
        !           295:   switch (circuit_t)
        !           296:     {
        !           297:     case IS_LEVEL_1:
        !           298:       return "L1";
        !           299:     case IS_LEVEL_2:
        !           300:       return "L2";
        !           301:     case IS_LEVEL_1_AND_2:
        !           302:       return "L1L2";
        !           303:     default:
        !           304:       return "??";
        !           305:     }
        !           306: 
        !           307:   return NULL;                 /* not reached */
        !           308: }
        !           309: 
        !           310: const char *
        !           311: syst2string (int type)
        !           312: {
        !           313:   switch (type)
        !           314:     {
        !           315:     case ISIS_SYSTYPE_ES:
        !           316:       return "ES";
        !           317:     case ISIS_SYSTYPE_IS:
        !           318:       return "IS";
        !           319:     case ISIS_SYSTYPE_L1_IS:
        !           320:       return "1";
        !           321:     case ISIS_SYSTYPE_L2_IS:
        !           322:       return "2";
        !           323:     default:
        !           324:       return "??";
        !           325:     }
        !           326: 
        !           327:   return NULL;                 /* not reached */
        !           328: }
        !           329: 
        !           330: /*
        !           331:  * Print functions - we print to static vars
        !           332:  */
        !           333: const char *
        !           334: snpa_print (u_char * from)
        !           335: {
        !           336:   int i = 0;
        !           337:   u_char *pos = (u_char *)snpa;
        !           338: 
        !           339:   if (!from)
        !           340:     return "unknown";
        !           341: 
        !           342:   while (i < ETH_ALEN - 1)
        !           343:     {
        !           344:       if (i & 1)
        !           345:        {
        !           346:          sprintf ((char *)pos, "%02x.", *(from + i));
        !           347:          pos += 3;
        !           348:        }
        !           349:       else
        !           350:        {
        !           351:          sprintf ((char *)pos, "%02x", *(from + i));
        !           352:          pos += 2;
        !           353: 
        !           354:        }
        !           355:       i++;
        !           356:     }
        !           357: 
        !           358:   sprintf ((char *)pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1)));
        !           359:   pos += 2;
        !           360:   *(pos) = '\0';
        !           361: 
        !           362:   return snpa;
        !           363: }
        !           364: 
        !           365: const char *
        !           366: sysid_print (u_char * from)
        !           367: {
        !           368:   int i = 0;
        !           369:   char *pos = sysid;
        !           370: 
        !           371:   if (!from)
        !           372:     return "unknown";
        !           373: 
        !           374:   while (i < ISIS_SYS_ID_LEN - 1)
        !           375:     {
        !           376:       if (i & 1)
        !           377:        {
        !           378:          sprintf (pos, "%02x.", *(from + i));
        !           379:          pos += 3;
        !           380:        }
        !           381:       else
        !           382:        {
        !           383:          sprintf (pos, "%02x", *(from + i));
        !           384:          pos += 2;
        !           385: 
        !           386:        }
        !           387:       i++;
        !           388:     }
        !           389: 
        !           390:   sprintf (pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1)));
        !           391:   pos += 2;
        !           392:   *(pos) = '\0';
        !           393: 
        !           394:   return sysid;
        !           395: }
        !           396: 
        !           397: const char *
        !           398: rawlspid_print (u_char * from)
        !           399: {
        !           400:   char *pos = lspid;
        !           401:   if (!from)
        !           402:     return "unknown";
        !           403:   memcpy (pos, sysid_print (from), 15);
        !           404:   pos += 14;
        !           405:   sprintf (pos, ".%02x", LSP_PSEUDO_ID (from));
        !           406:   pos += 3;
        !           407:   sprintf (pos, "-%02x", LSP_FRAGMENT (from));
        !           408:   pos += 3;
        !           409: 
        !           410:   *(pos) = '\0';
        !           411: 
        !           412:   return lspid;
        !           413: }
        !           414: 
        !           415: const char *
        !           416: time2string (u_int32_t time)
        !           417: {
        !           418:   char *pos = datestring;
        !           419:   u_int32_t rest;
        !           420: 
        !           421:   if (time == 0)
        !           422:     return "-";
        !           423: 
        !           424:   if (time / SECS_PER_YEAR)
        !           425:     pos += sprintf (pos, "%uY", time / SECS_PER_YEAR);
        !           426:   rest = time % SECS_PER_YEAR;
        !           427:   if (rest / SECS_PER_MONTH)
        !           428:     pos += sprintf (pos, "%uM", rest / SECS_PER_MONTH);
        !           429:   rest = rest % SECS_PER_MONTH;
        !           430:   if (rest / SECS_PER_WEEK)
        !           431:     pos += sprintf (pos, "%uw", rest / SECS_PER_WEEK);
        !           432:   rest = rest % SECS_PER_WEEK;
        !           433:   if (rest / SECS_PER_DAY)
        !           434:     pos += sprintf (pos, "%ud", rest / SECS_PER_DAY);
        !           435:   rest = rest % SECS_PER_DAY;
        !           436:   if (rest / SECS_PER_HOUR)
        !           437:     pos += sprintf (pos, "%uh", rest / SECS_PER_HOUR);
        !           438:   rest = rest % SECS_PER_HOUR;
        !           439:   if (rest / SECS_PER_MINUTE)
        !           440:     pos += sprintf (pos, "%um", rest / SECS_PER_MINUTE);
        !           441:   rest = rest % SECS_PER_MINUTE;
        !           442:   if (rest)
        !           443:     pos += sprintf (pos, "%us", rest);
        !           444: 
        !           445:   *(pos) = 0;
        !           446: 
        !           447:   return datestring;
        !           448: }
        !           449: 
        !           450: /*
        !           451:  * routine to decrement a timer by a random
        !           452:  * number
        !           453:  *
        !           454:  * first argument is the timer and the second is
        !           455:  * the jitter
        !           456:  */
        !           457: unsigned long
        !           458: isis_jitter (unsigned long timer, unsigned long jitter)
        !           459: {
        !           460:   int j, k;
        !           461: 
        !           462:   if (jitter >= 100)
        !           463:     return timer;
        !           464: 
        !           465:   if (timer == 1)
        !           466:     return timer;
        !           467:   /* 
        !           468:    * randomizing just the percent value provides
        !           469:    * no good random numbers - hence the spread
        !           470:    * to RANDOM_SPREAD (100000), which is ok as
        !           471:    * most IS-IS timers are no longer than 16 bit
        !           472:    */
        !           473: 
        !           474:   j = 1 + (int) ((RANDOM_SPREAD * rand ()) / (RAND_MAX + 1.0));
        !           475: 
        !           476:   k = timer - (timer * (100 - jitter)) / 100;
        !           477: 
        !           478:   timer = timer - (k * j / RANDOM_SPREAD);
        !           479: 
        !           480:   return timer;
        !           481: }
        !           482: 
        !           483: struct in_addr
        !           484: newprefix2inaddr (u_char * prefix_start, u_char prefix_masklen)
        !           485: {
        !           486:   memset (&new_prefix, 0, sizeof (new_prefix));
        !           487:   memcpy (&new_prefix, prefix_start, (prefix_masklen & 0x3F) ?
        !           488:          ((((prefix_masklen & 0x3F) - 1) >> 3) + 1) : 0);
        !           489:   return new_prefix;
        !           490: }
        !           491: 
        !           492: /*
        !           493:  * Returns host.name if any, otherwise
        !           494:  * it returns the system hostname.
        !           495:  */
        !           496: const char *
        !           497: unix_hostname (void)
        !           498: {
        !           499:   static struct utsname names;
        !           500:   const char *hostname;
        !           501:   extern struct host host;
        !           502: 
        !           503:   hostname = host.name;
        !           504:   if (!hostname)
        !           505:     {
        !           506:       uname (&names);
        !           507:       hostname = names.nodename;
        !           508:     }
        !           509: 
        !           510:   return hostname;
        !           511: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>