]>
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; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
65 const char *isonet_print(const u_char
*from
, int len
)
75 sprintf(pos
, "%02x", *(from
+ i
));
78 if (i
== (len
- 1)) { /* No dot at the end of address */
79 sprintf(pos
, "%02x", *(from
+ i
));
82 sprintf(pos
, "%02x.", *(from
+ i
));
93 * Returns 0 on error, length of buff on ok
94 * extract dot from the dotted str, and insert all the number in a buff
96 int dotformat2buff(u_char
*buff
, const char *dotted
)
99 const char *pos
= dotted
;
104 dotlen
= strlen(dotted
);
106 /* this can't be an iso net, its too long */
110 while ((pos
- dotted
) < dotlen
&& len
< 20) {
112 /* we expect the . at 2, and than every 5 */
113 if ((pos
- dotted
) != nextdotpos
) {
121 /* we must have at least two chars left here */
122 if (dotlen
- (pos
- dotted
) < 2) {
127 if ((isxdigit((int)*pos
)) && (isxdigit((int)*(pos
+ 1)))) {
128 memcpy(number
, pos
, 2);
135 *(buff
+ len
) = (char)strtol((char *)number
, NULL
, 16);
143 * conversion of XXXX.XXXX.XXXX to memory
145 int sysid2buff(u_char
*buff
, const char *dotted
)
148 const char *pos
= dotted
;
152 // surely not a sysid_string if not 14 length
153 if (strlen(dotted
) != 14) {
157 while (len
< ISIS_SYS_ID_LEN
) {
159 /* the . is not positioned correctly */
160 if (((pos
- dotted
) != 4) && ((pos
- dotted
) != 9)) {
167 if ((isxdigit((int)*pos
)) && (isxdigit((int)*(pos
+ 1)))) {
168 memcpy(number
, pos
, 2);
175 *(buff
+ len
) = (char)strtol((char *)number
, NULL
, 16);
183 * converts the nlpids struct (filled by TLV #129)
187 char *nlpid2string(struct nlpids
*nlpids
)
189 char *pos
= nlpidstring
;
192 for (i
= 0; i
< nlpids
->count
; i
++) {
193 switch (nlpids
->nlpids
[i
]) {
195 pos
+= sprintf(pos
, "IPv4");
198 pos
+= sprintf(pos
, "IPv6");
201 pos
+= sprintf(pos
, "SNAP");
204 pos
+= sprintf(pos
, "CLNP");
207 pos
+= sprintf(pos
, "ES-IS");
210 pos
+= sprintf(pos
, "unknown");
213 if (nlpids
->count
- i
> 1)
214 pos
+= sprintf(pos
, ", ");
223 * supports the given af ?
225 int speaks(struct nlpids
*nlpids
, int family
)
229 if (nlpids
== (struct nlpids
*)NULL
)
231 for (i
= 0; i
< nlpids
->count
; i
++) {
232 if (family
== AF_INET
&& nlpids
->nlpids
[i
] == NLPID_IP
)
234 if (family
== AF_INET6
&& nlpids
->nlpids
[i
] == NLPID_IPV6
)
242 * Returns 0 on error, IS-IS Circuit Type on ok
244 int string2circuit_t(const char *str
)
250 if (!strcmp(str
, "level-1"))
253 if (!strcmp(str
, "level-2-only") || !strcmp(str
, "level-2"))
256 if (!strcmp(str
, "level-1-2"))
257 return IS_LEVEL_1_AND_2
;
262 const char *circuit_state2string(int state
)
278 const char *circuit_type2string(int type
)
284 case CIRCUIT_T_BROADCAST
:
286 case CIRCUIT_T_LOOPBACK
:
294 const char *circuit_t2string(int circuit_t
)
301 case IS_LEVEL_1_AND_2
:
307 return NULL
; /* not reached */
310 const char *syst2string(int type
)
313 case ISIS_SYSTYPE_ES
:
315 case ISIS_SYSTYPE_IS
:
317 case ISIS_SYSTYPE_L1_IS
:
319 case ISIS_SYSTYPE_L2_IS
:
325 return NULL
; /* not reached */
329 * Print functions - we print to static vars
331 const char *snpa_print(const u_char
*from
)
334 u_char
*pos
= (u_char
*)snpa
;
339 while (i
< ETH_ALEN
- 1) {
341 sprintf((char *)pos
, "%02x.", *(from
+ i
));
344 sprintf((char *)pos
, "%02x", *(from
+ i
));
350 sprintf((char *)pos
, "%02x", *(from
+ (ISIS_SYS_ID_LEN
- 1)));
357 const char *sysid_print(const u_char
*from
)
365 while (i
< ISIS_SYS_ID_LEN
- 1) {
367 sprintf(pos
, "%02x.", *(from
+ i
));
370 sprintf(pos
, "%02x", *(from
+ i
));
376 sprintf(pos
, "%02x", *(from
+ (ISIS_SYS_ID_LEN
- 1)));
383 const char *rawlspid_print(const u_char
*from
)
388 memcpy(pos
, sysid_print(from
), 15);
390 sprintf(pos
, ".%02x", LSP_PSEUDO_ID(from
));
392 sprintf(pos
, "-%02x", LSP_FRAGMENT(from
));
400 const char *time2string(u_int32_t time
)
402 char *pos
= datestring
;
408 if (time
/ SECS_PER_YEAR
)
409 pos
+= sprintf(pos
, "%uY", time
/ SECS_PER_YEAR
);
410 rest
= time
% SECS_PER_YEAR
;
411 if (rest
/ SECS_PER_MONTH
)
412 pos
+= sprintf(pos
, "%uM", rest
/ SECS_PER_MONTH
);
413 rest
= rest
% SECS_PER_MONTH
;
414 if (rest
/ SECS_PER_WEEK
)
415 pos
+= sprintf(pos
, "%uw", rest
/ SECS_PER_WEEK
);
416 rest
= rest
% SECS_PER_WEEK
;
417 if (rest
/ SECS_PER_DAY
)
418 pos
+= sprintf(pos
, "%ud", rest
/ SECS_PER_DAY
);
419 rest
= rest
% SECS_PER_DAY
;
420 if (rest
/ SECS_PER_HOUR
)
421 pos
+= sprintf(pos
, "%uh", rest
/ SECS_PER_HOUR
);
422 rest
= rest
% SECS_PER_HOUR
;
423 if (rest
/ SECS_PER_MINUTE
)
424 pos
+= sprintf(pos
, "%um", rest
/ SECS_PER_MINUTE
);
425 rest
= rest
% SECS_PER_MINUTE
;
427 pos
+= sprintf(pos
, "%us", rest
);
435 * routine to decrement a timer by a random
438 * first argument is the timer and the second is
441 unsigned long isis_jitter(unsigned long timer
, unsigned long jitter
)
451 * randomizing just the percent value provides
452 * no good random numbers - hence the spread
453 * to RANDOM_SPREAD (100000), which is ok as
454 * most IS-IS timers are no longer than 16 bit
457 j
= 1 + (int)((RANDOM_SPREAD
* random()) / (RAND_MAX
+ 1.0));
459 k
= timer
- (timer
* (100 - jitter
)) / 100;
461 timer
= timer
- (k
* j
/ RANDOM_SPREAD
);
466 struct in_addr
newprefix2inaddr(u_char
*prefix_start
, u_char prefix_masklen
)
468 memset(&new_prefix
, 0, sizeof(new_prefix
));
469 memcpy(&new_prefix
, prefix_start
,
470 (prefix_masklen
& 0x3F)
471 ? ((((prefix_masklen
& 0x3F) - 1) >> 3) + 1)
477 * Returns host.name if any, otherwise
478 * it returns the system hostname.
480 const char *unix_hostname(void)
482 static struct utsname names
;
483 const char *hostname
;
485 hostname
= host
.name
;
488 hostname
= names
.nodename
;
495 * Returns the dynamic hostname associated with the passed system ID.
496 * If no dynamic hostname found then returns formatted system ID.
498 const char *print_sys_hostname(const u_char
*sysid
)
500 struct isis_dynhn
*dyn
;
505 /* For our system ID return our host name */
506 if (memcmp(sysid
, isis
->sysid
, ISIS_SYS_ID_LEN
) == 0)
507 return unix_hostname();
509 dyn
= dynhn_find_by_id(sysid
);
511 return (const char *)dyn
->name
.name
;
513 return sysid_print(sysid
);
517 * This function is a generic utility that logs data of given length.
518 * Move this to a shared lib so that any protocol can use it.
520 void zlog_dump_data(void *data
, int len
)
527 char hexstr
[16 * 3 + 5];
528 char charstr
[16 * 1 + 5];
531 memset(bytestr
, 0, sizeof(bytestr
));
532 memset(addrstr
, 0, sizeof(addrstr
));
533 memset(hexstr
, 0, sizeof(hexstr
));
534 memset(charstr
, 0, sizeof(charstr
));
536 for (i
= 1; i
<= len
; i
++) {
541 /* store address for this line */
543 snprintf(addrstr
, sizeof(addrstr
), "%p", p
);
545 /* store hex str (for left side) */
546 snprintf(bytestr
, sizeof(bytestr
), "%02X ", *p
);
547 strncat(hexstr
, bytestr
, sizeof(hexstr
) - strlen(hexstr
) - 1);
549 /* store char str (for right side) */
550 snprintf(bytestr
, sizeof(bytestr
), "%c", c
);
551 strncat(charstr
, bytestr
,
552 sizeof(charstr
) - strlen(charstr
) - 1);
556 zlog_debug("[%8.8s] %-50.50s %s", addrstr
, hexstr
,
560 } else if ((i
% 8) == 0) {
561 /* half line: add whitespaces */
563 sizeof(hexstr
) - strlen(hexstr
) - 1);
564 strncat(charstr
, " ",
565 sizeof(charstr
) - strlen(charstr
) - 1);
570 /* print rest of buffer if not empty */
571 if (strlen(hexstr
) > 0)
572 zlog_debug("[%8.8s] %-50.50s %s", addrstr
, hexstr
, charstr
);