]>
git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_misc.c
2 * IS-IS Rout(e)ing protocol - isis_misc.h
3 * Miscellanous routines
5 * Copyright (C) 2001,2002 Sampo Saaristo
6 * Tampere University of Technology
7 * Institute of Communications Engineering
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)
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
19 * You should have received a copy of the GNU General Public License along
20 * with this program; see the file COPYING; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 #include "isisd/dict.h"
33 #include "isisd/isis_constants.h"
34 #include "isisd/isis_common.h"
35 #include "isisd/isis_flags.h"
36 #include "isisd/isis_circuit.h"
37 #include "isisd/isis_csm.h"
38 #include "isisd/isisd.h"
39 #include "isisd/isis_misc.h"
41 #include "isisd/isis_tlv.h"
42 #include "isisd/isis_lsp.h"
43 #include "isisd/isis_constants.h"
44 #include "isisd/isis_adjacency.h"
45 #include "isisd/isis_dynhn.h"
47 /* staticly assigned vars for printing purposes */
48 struct in_addr new_prefix
;
49 /* len of xxxx.xxxx.xxxx + place for #0 termination */
51 /* len of xxxx.xxxx.xxxx + place for #0 termination */
53 /* len of xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx */
55 /* + place for #0 termination */
56 /* len of xxxx.xxxx.xxxx.xx.xx + place for #0 termination */
58 /* len of xxYxxMxWxdxxhxxmxxs + place for #0 termination */
63 * This converts the isonet to its printable format
66 isonet_print (const u_char
* from
, int len
)
78 sprintf (pos
, "%02x", *(from
+ i
));
84 { /* No dot at the end of address */
85 sprintf (pos
, "%02x", *(from
+ i
));
90 sprintf (pos
, "%02x.", *(from
+ i
));
101 * Returns 0 on error, length of buff on ok
102 * extract dot from the dotted str, and insert all the number in a buff
105 dotformat2buff (u_char
* buff
, const char * dotted
)
108 const char *pos
= dotted
;
113 dotlen
= strlen(dotted
);
116 /* this can't be an iso net, its too long */
120 while ((pos
- dotted
) < dotlen
&& len
< 20)
124 /* we expect the . at 2, and than every 5 */
125 if ((pos
- dotted
) != nextdotpos
)
134 /* we must have at least two chars left here */
135 if (dotlen
- (pos
- dotted
) < 2)
141 if ((isxdigit ((int) *pos
)) && (isxdigit ((int) *(pos
+ 1))))
143 memcpy (number
, pos
, 2);
152 *(buff
+ len
) = (char) strtol ((char *)number
, NULL
, 16);
160 * conversion of XXXX.XXXX.XXXX to memory
163 sysid2buff (u_char
* buff
, const char * dotted
)
166 const char *pos
= dotted
;
170 // surely not a sysid_string if not 14 length
171 if (strlen (dotted
) != 14)
176 while (len
< ISIS_SYS_ID_LEN
)
180 /* the . is not positioned correctly */
181 if (((pos
- dotted
) != 4) && ((pos
- dotted
) != 9))
189 if ((isxdigit ((int) *pos
)) && (isxdigit ((int) *(pos
+ 1))))
191 memcpy (number
, pos
, 2);
200 *(buff
+ len
) = (char) strtol ((char *)number
, NULL
, 16);
209 * converts the nlpids struct (filled by TLV #129)
214 nlpid2string (struct nlpids
*nlpids
)
216 char *pos
= nlpidstring
;
219 for (i
= 0; i
< nlpids
->count
; i
++)
221 switch (nlpids
->nlpids
[i
])
224 pos
+= sprintf (pos
, "IPv4");
227 pos
+= sprintf (pos
, "IPv6");
230 pos
+= sprintf (pos
, "SNAP");
233 pos
+= sprintf (pos
, "CLNP");
236 pos
+= sprintf (pos
, "ES-IS");
239 pos
+= sprintf (pos
, "unknown");
242 if (nlpids
->count
- i
> 1)
243 pos
+= sprintf (pos
, ", ");
253 * supports the given af ?
256 speaks (struct nlpids
*nlpids
, int family
)
260 if (nlpids
== (struct nlpids
*) NULL
)
262 for (i
= 0; i
< nlpids
->count
; i
++)
264 if (family
== AF_INET
&& nlpids
->nlpids
[i
] == NLPID_IP
)
266 if (family
== AF_INET6
&& nlpids
->nlpids
[i
] == NLPID_IPV6
)
274 * Returns 0 on error, IS-IS Circuit Type on ok
277 string2circuit_t (const char * str
)
283 if (!strcmp (str
, "level-1"))
286 if (!strcmp (str
, "level-2-only") || !strcmp (str
, "level-2"))
289 if (!strcmp (str
, "level-1-2"))
290 return IS_LEVEL_1_AND_2
;
296 circuit_state2string (int state
)
314 circuit_type2string (int type
)
321 case CIRCUIT_T_BROADCAST
:
323 case CIRCUIT_T_LOOPBACK
:
332 circuit_t2string (int circuit_t
)
340 case IS_LEVEL_1_AND_2
:
346 return NULL
; /* not reached */
350 syst2string (int type
)
354 case ISIS_SYSTYPE_ES
:
356 case ISIS_SYSTYPE_IS
:
358 case ISIS_SYSTYPE_L1_IS
:
360 case ISIS_SYSTYPE_L2_IS
:
366 return NULL
; /* not reached */
370 * Print functions - we print to static vars
373 snpa_print (const u_char
* from
)
376 u_char
*pos
= (u_char
*)snpa
;
381 while (i
< ETH_ALEN
- 1)
385 sprintf ((char *)pos
, "%02x.", *(from
+ i
));
390 sprintf ((char *)pos
, "%02x", *(from
+ i
));
397 sprintf ((char *)pos
, "%02x", *(from
+ (ISIS_SYS_ID_LEN
- 1)));
405 sysid_print (const u_char
* from
)
413 while (i
< ISIS_SYS_ID_LEN
- 1)
417 sprintf (pos
, "%02x.", *(from
+ i
));
422 sprintf (pos
, "%02x", *(from
+ i
));
429 sprintf (pos
, "%02x", *(from
+ (ISIS_SYS_ID_LEN
- 1)));
437 rawlspid_print (const u_char
* from
)
442 memcpy (pos
, sysid_print (from
), 15);
444 sprintf (pos
, ".%02x", LSP_PSEUDO_ID (from
));
446 sprintf (pos
, "-%02x", LSP_FRAGMENT (from
));
455 time2string (u_int32_t time
)
457 char *pos
= datestring
;
463 if (time
/ SECS_PER_YEAR
)
464 pos
+= sprintf (pos
, "%uY", time
/ SECS_PER_YEAR
);
465 rest
= time
% SECS_PER_YEAR
;
466 if (rest
/ SECS_PER_MONTH
)
467 pos
+= sprintf (pos
, "%uM", rest
/ SECS_PER_MONTH
);
468 rest
= rest
% SECS_PER_MONTH
;
469 if (rest
/ SECS_PER_WEEK
)
470 pos
+= sprintf (pos
, "%uw", rest
/ SECS_PER_WEEK
);
471 rest
= rest
% SECS_PER_WEEK
;
472 if (rest
/ SECS_PER_DAY
)
473 pos
+= sprintf (pos
, "%ud", rest
/ SECS_PER_DAY
);
474 rest
= rest
% SECS_PER_DAY
;
475 if (rest
/ SECS_PER_HOUR
)
476 pos
+= sprintf (pos
, "%uh", rest
/ SECS_PER_HOUR
);
477 rest
= rest
% SECS_PER_HOUR
;
478 if (rest
/ SECS_PER_MINUTE
)
479 pos
+= sprintf (pos
, "%um", rest
/ SECS_PER_MINUTE
);
480 rest
= rest
% SECS_PER_MINUTE
;
482 pos
+= sprintf (pos
, "%us", rest
);
490 * routine to decrement a timer by a random
493 * first argument is the timer and the second is
497 isis_jitter (unsigned long timer
, unsigned long jitter
)
507 * randomizing just the percent value provides
508 * no good random numbers - hence the spread
509 * to RANDOM_SPREAD (100000), which is ok as
510 * most IS-IS timers are no longer than 16 bit
513 j
= 1 + (int) ((RANDOM_SPREAD
* random ()) / (RAND_MAX
+ 1.0));
515 k
= timer
- (timer
* (100 - jitter
)) / 100;
517 timer
= timer
- (k
* j
/ RANDOM_SPREAD
);
523 newprefix2inaddr (u_char
* prefix_start
, u_char prefix_masklen
)
525 memset (&new_prefix
, 0, sizeof (new_prefix
));
526 memcpy (&new_prefix
, prefix_start
, (prefix_masklen
& 0x3F) ?
527 ((((prefix_masklen
& 0x3F) - 1) >> 3) + 1) : 0);
532 * Returns host.name if any, otherwise
533 * it returns the system hostname.
538 static struct utsname names
;
539 const char *hostname
;
541 hostname
= host
.name
;
545 hostname
= names
.nodename
;
552 * Returns the dynamic hostname associated with the passed system ID.
553 * If no dynamic hostname found then returns formatted system ID.
556 print_sys_hostname (const u_char
*sysid
)
558 struct isis_dynhn
*dyn
;
563 /* For our system ID return our host name */
564 if (memcmp(sysid
, isis
->sysid
, ISIS_SYS_ID_LEN
) == 0)
565 return unix_hostname();
567 dyn
= dynhn_find_by_id (sysid
);
569 return (const char *)dyn
->name
.name
;
571 return sysid_print (sysid
);
575 * This function is a generic utility that logs data of given length.
576 * Move this to a shared lib so that any protocol can use it.
579 zlog_dump_data (void *data
, int len
)
586 char hexstr
[ 16*3 + 5];
587 char charstr
[16*1 + 5];
590 memset (bytestr
, 0, sizeof(bytestr
));
591 memset (addrstr
, 0, sizeof(addrstr
));
592 memset (hexstr
, 0, sizeof(hexstr
));
593 memset (charstr
, 0, sizeof(charstr
));
595 for (i
= 1; i
<= len
; i
++)
598 if (isalnum (c
) == 0)
601 /* store address for this line */
603 snprintf (addrstr
, sizeof(addrstr
), "%p", p
);
605 /* store hex str (for left side) */
606 snprintf (bytestr
, sizeof (bytestr
), "%02X ", *p
);
607 strncat (hexstr
, bytestr
, sizeof (hexstr
) - strlen (hexstr
) - 1);
609 /* store char str (for right side) */
610 snprintf (bytestr
, sizeof (bytestr
), "%c", c
);
611 strncat (charstr
, bytestr
, sizeof (charstr
) - strlen (charstr
) - 1);
616 zlog_debug ("[%8.8s] %-50.50s %s", addrstr
, hexstr
, charstr
);
620 else if ((i
% 8) == 0)
622 /* half line: add whitespaces */
623 strncat (hexstr
, " ", sizeof (hexstr
) - strlen (hexstr
) - 1);
624 strncat (charstr
, " ", sizeof (charstr
) - strlen (charstr
) - 1);
629 /* print rest of buffer if not empty */
630 if (strlen (hexstr
) > 0)
631 zlog_debug ("[%8.8s] %-50.50s %s", addrstr
, hexstr
, charstr
);