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_circuit.h"
36 #include "isisd/isisd.h"
37 #include "isisd/isis_misc.h"
39 #include "isisd/isis_tlv.h"
40 #include "isisd/isis_lsp.h"
41 #include "isisd/isis_constants.h"
42 #include "isisd/isis_adjacency.h"
44 /* staticly assigned vars for printing purposes */
45 struct in_addr new_prefix
;
46 /* len of xxxx.xxxx.xxxx + place for #0 termination */
48 /* len of xxxx.xxxx.xxxx + place for #0 termination */
50 /* len of xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx */
52 /* + place for #0 termination */
53 /* len of xxxx.xxxx.xxxx.xx.xx + place for #0 termination */
55 /* len of xxYxxMxWxdxxhxxmxxs + place for #0 termination */
60 * This converts the isonet to its printable format
63 isonet_print (u_char
* from
, int len
)
75 sprintf (pos
, "%02x", *(from
+ i
));
81 { /* No dot at the end of address */
82 sprintf (pos
, "%02x", *(from
+ i
));
87 sprintf (pos
, "%02x.", *(from
+ i
));
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
102 dotformat2buff (u_char
* buff
, const u_char
* dotted
)
105 const u_char
*pos
= dotted
;
110 dotlen
= strlen(dotted
);
113 /* this can't be an iso net, its too long */
117 while ((pos
- dotted
) < dotlen
&& len
< 20)
121 /* we expect the . at 2, and than every 5 */
122 if ((pos
- dotted
) != nextdotpos
)
131 /* we must have at least two chars left here */
132 if (dotlen
- (pos
- dotted
) < 2)
138 if ((isxdigit ((int) *pos
)) && (isxdigit ((int) *(pos
+ 1))))
140 memcpy (number
, pos
, 2);
149 *(buff
+ len
) = (char) strtol ((char *)number
, NULL
, 16);
157 * conversion of XXXX.XXXX.XXXX to memory
160 sysid2buff (u_char
* buff
, const u_char
* dotted
)
163 const u_char
*pos
= dotted
;
167 // surely not a sysid_string if not 14 length
168 if (strlen (dotted
) != 14)
173 while (len
< ISIS_SYS_ID_LEN
)
177 /* the . is not positioned correctly */
178 if (((pos
- dotted
) != 4) && ((pos
- dotted
) != 9))
186 if ((isxdigit ((int) *pos
)) && (isxdigit ((int) *(pos
+ 1))))
188 memcpy (number
, pos
, 2);
197 *(buff
+ len
) = (char) strtol ((char *)number
, NULL
, 16);
206 * converts the nlpids struct (filled by TLV #129)
211 nlpid2string (struct nlpids
*nlpids
)
213 char *pos
= nlpidstring
;
216 for (i
= 0; i
< nlpids
->count
; i
++)
218 switch (nlpids
->nlpids
[i
])
221 pos
+= sprintf (pos
, "IPv4");
224 pos
+= sprintf (pos
, "IPv6");
227 pos
+= sprintf (pos
, "SNAP");
230 pos
+= sprintf (pos
, "CLNP");
233 pos
+= sprintf (pos
, "ES-IS");
236 pos
+= sprintf (pos
, "unknown");
239 if (nlpids
->count
- i
> 1)
240 pos
+= sprintf (pos
, ", ");
250 * supports the given af ?
253 speaks (struct nlpids
*nlpids
, int family
)
257 if (nlpids
== (struct nlpids
*) NULL
)
259 for (i
= 0; i
< nlpids
->count
; i
++)
261 if (family
== AF_INET
&& nlpids
->nlpids
[i
] == NLPID_IP
)
263 if (family
== AF_INET6
&& nlpids
->nlpids
[i
] == NLPID_IPV6
)
271 * Returns 0 on error, IS-IS Circuit Type on ok
274 string2circuit_t (const u_char
* str
)
280 if (!strcmp (str
, "level-1"))
283 if (!strcmp (str
, "level-2-only") || !strcmp (str
, "level-2"))
286 if (!strcmp (str
, "level-1-2"))
287 return IS_LEVEL_1_AND_2
;
293 circuit_t2string (int circuit_t
)
301 case IS_LEVEL_1_AND_2
:
307 return NULL
; /* not reached */
311 syst2string (int type
)
315 case ISIS_SYSTYPE_ES
:
317 case ISIS_SYSTYPE_IS
:
319 case ISIS_SYSTYPE_L1_IS
:
321 case ISIS_SYSTYPE_L2_IS
:
327 return NULL
; /* not reached */
331 * Print functions - we print to static vars
334 snpa_print (u_char
* from
)
337 u_char
*pos
= (u_char
*)snpa
;
342 while (i
< ETH_ALEN
- 1)
346 sprintf ((char *)pos
, "%02x.", *(from
+ i
));
351 sprintf ((char *)pos
, "%02x", *(from
+ i
));
358 sprintf ((char *)pos
, "%02x", *(from
+ (ISIS_SYS_ID_LEN
- 1)));
366 sysid_print (u_char
* from
)
374 while (i
< ISIS_SYS_ID_LEN
- 1)
378 sprintf (pos
, "%02x.", *(from
+ i
));
383 sprintf (pos
, "%02x", *(from
+ i
));
390 sprintf (pos
, "%02x", *(from
+ (ISIS_SYS_ID_LEN
- 1)));
398 rawlspid_print (u_char
* from
)
403 memcpy (pos
, sysid_print (from
), 15);
405 sprintf (pos
, ".%02x", LSP_PSEUDO_ID (from
));
407 sprintf (pos
, "-%02x", LSP_FRAGMENT (from
));
416 time2string (u_int32_t time
)
418 char *pos
= datestring
;
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
;
443 pos
+= sprintf (pos
, "%us", rest
);
451 * routine to decrement a timer by a random
454 * first argument is the timer and the second is
458 isis_jitter (unsigned long timer
, unsigned long jitter
)
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
474 j
= 1 + (int) ((RANDOM_SPREAD
* rand ()) / (RAND_MAX
+ 1.0));
476 k
= timer
- (timer
* (100 - jitter
)) / 100;
478 timer
= timer
- (k
* j
/ RANDOM_SPREAD
);
484 newprefix2inaddr (u_char
* prefix_start
, u_char prefix_masklen
)
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);
493 * Returns host.name if any, otherwise
494 * it returns the system hostname.
499 static struct utsname names
;
500 const char *hostname
;
501 extern struct host host
;
503 hostname
= host
.name
;
507 hostname
= names
.nodename
;