~ubuntu-branches/ubuntu/warty/quagga/warty

« back to all changes in this revision

Viewing changes to isisd/isis_misc.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio M. Di Nitto
  • Date: 2004-06-29 09:50:59 UTC
  • Revision ID: james.westby@ubuntu.com-20040629095059-px1m2m108z4qw1mr
Tags: upstream-0.96.5
ImportĀ upstreamĀ versionĀ 0.96.5

Show diffs side-by-side

added added

removed removed

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