Annotation of embedaddon/quagga/isisd/isis_misc.c, revision 1.1.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>