rtquery.c (18316) | rtquery.c (19880) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 51 unchanged lines hidden (view full) --- 60#include <strings.h> 61#include <bstring.h> 62#endif 63 64#ifndef sgi 65#define _HAVE_SIN_LEN 66#endif 67 | 1/*- 2 * Copyright (c) 1982, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 51 unchanged lines hidden (view full) --- 60#include <strings.h> 61#include <bstring.h> 62#endif 63 64#ifndef sgi 65#define _HAVE_SIN_LEN 66#endif 67 |
68#define MD5_DIGEST_LEN 16 69typedef struct { 70 u_int32_t state[4]; /* state (ABCD) */ 71 u_int32_t count[2]; /* # of bits, modulo 2^64 (LSB 1st) */ 72 unsigned char buffer[64]; /* input buffer */ 73} MD5_CTX; 74extern void MD5Init(MD5_CTX*); 75extern void MD5Update(MD5_CTX*, u_char*, u_int); 76extern void MD5Final(u_char[MD5_DIGEST_LEN], MD5_CTX*); 77 78 |
|
68#define WTIME 15 /* Time to wait for all responses */ 69#define STIME (250*1000) /* usec to wait for another response */ 70 71int s; 72 73char *pgmname; 74 75union { --- 9 unchanged lines hidden (view full) --- 85 } imsg_buf; 86#define IMSG imsg_buf.rip 87 88int nflag; /* numbers, no names */ 89int pflag; /* play the `gated` game */ 90int ripv2 = 1; /* use RIP version 2 */ 91int wtime = WTIME; 92int rflag; /* 1=ask about a particular route */ | 79#define WTIME 15 /* Time to wait for all responses */ 80#define STIME (250*1000) /* usec to wait for another response */ 81 82int s; 83 84char *pgmname; 85 86union { --- 9 unchanged lines hidden (view full) --- 96 } imsg_buf; 97#define IMSG imsg_buf.rip 98 99int nflag; /* numbers, no names */ 100int pflag; /* play the `gated` game */ 101int ripv2 = 1; /* use RIP version 2 */ 102int wtime = WTIME; 103int rflag; /* 1=ask about a particular route */ |
93int trace; 94int not_trace; | 104int trace, not_trace; /* send trace command or not */ 105int auth_type = RIP_AUTH_NONE; 106char passwd[RIP_AUTH_PW_LEN]; 107u_long keyid; |
95 96struct timeval sent; /* when query sent */ 97 98static void rip_input(struct sockaddr_in*, int); 99static int out(char *); 100static void trace_loop(char *argv[]); 101static void query_loop(char *argv[], int); 102static int getnet(char *, struct netinfo *); 103static u_int std_mask(u_int); | 108 109struct timeval sent; /* when query sent */ 110 111static void rip_input(struct sockaddr_in*, int); 112static int out(char *); 113static void trace_loop(char *argv[]); 114static void query_loop(char *argv[], int); 115static int getnet(char *, struct netinfo *); 116static u_int std_mask(u_int); |
117static int parse_quote(char **, char *, char *, char *, int); |
|
104 105 106int 107main(int argc, 108 char *argv[]) 109{ 110 int ch, bsize; | 118 119 120int 121main(int argc, 122 char *argv[]) 123{ 124 int ch, bsize; |
111 char *p, *options, *value; | 125 char *p, *options, *value, delim; |
112 113 OMSG.rip_nets[0].n_dst = RIP_DEFAULT; 114 OMSG.rip_nets[0].n_family = RIP_AF_UNSPEC; 115 OMSG.rip_nets[0].n_metric = htonl(HOPCNT_INFINITY); 116 117 pgmname = argv[0]; | 126 127 OMSG.rip_nets[0].n_dst = RIP_DEFAULT; 128 OMSG.rip_nets[0].n_family = RIP_AF_UNSPEC; 129 OMSG.rip_nets[0].n_metric = htonl(HOPCNT_INFINITY); 130 131 pgmname = argv[0]; |
118 while ((ch = getopt(argc, argv, "np1w:r:t:")) != EOF) | 132 while ((ch = getopt(argc, argv, "np1w:r:t:a:")) != EOF) |
119 switch (ch) { 120 case 'n': 121 not_trace = 1; 122 nflag = 1; 123 break; 124 125 case 'p': 126 not_trace = 1; --- 76 unchanged lines hidden (view full) --- 203 default: 204 goto usage; 205 } 206 strcpy((char*)OMSG.rip_tracefile, value); 207 omsg_len += strlen(value) - sizeof(OMSG.ripun); 208 } 209 break; 210 | 133 switch (ch) { 134 case 'n': 135 not_trace = 1; 136 nflag = 1; 137 break; 138 139 case 'p': 140 not_trace = 1; --- 76 unchanged lines hidden (view full) --- 217 default: 218 goto usage; 219 } 220 strcpy((char*)OMSG.rip_tracefile, value); 221 omsg_len += strlen(value) - sizeof(OMSG.ripun); 222 } 223 break; 224 |
225 case 'a': 226 not_trace = 1; 227 p = strchr(optarg,'='); 228 if (!p) 229 goto usage; 230 *p++ = '\0'; 231 if (!strcasecmp("passwd",optarg)) 232 auth_type = RIP_AUTH_PW; 233 else if (!strcasecmp("md5_passwd",optarg)) 234 auth_type = RIP_AUTH_MD5; 235 else 236 goto usage; 237 if (0 > parse_quote(&p,"|",&delim, 238 passwd,sizeof(passwd))) 239 goto usage; 240 if (auth_type == RIP_AUTH_MD5 241 && delim == '|') { 242 keyid = strtoul(p+1,&p,0); 243 if (keyid > 255 || *p != '\0') 244 goto usage; 245 } else if (delim != '\0') { 246 goto usage; 247 } 248 break; 249 |
|
211 default: 212 goto usage; 213 } 214 argv += optind; 215 argc -= optind; 216 if ((not_trace && trace) || argc == 0) { 217usage: fprintf(stderr, "%s: [-np1v] [-r tgt_rt] [-w wtime]" | 250 default: 251 goto usage; 252 } 253 argv += optind; 254 argc -= optind; 255 if ((not_trace && trace) || argc == 0) { 256usage: fprintf(stderr, "%s: [-np1v] [-r tgt_rt] [-w wtime]" |
218 " host1 [host2 ...]\n" 219 "or\t-t {on=filename|more|off} host1 host2 ...\n", | 257 " [-a type=passwd] host1 [host2 ...]\n" 258 "or\t-t {on=filename|more|off|on=dump/../table}" 259 " host1 [host2 ...]\n", |
220 pgmname); 221 exit(1); 222 } 223 224 s = socket(AF_INET, SOCK_DGRAM, 0); 225 if (s < 0) { 226 perror("socket"); 227 exit(2); --- 61 unchanged lines hidden (view full) --- 289} 290 291 292/* query all of the listed hosts 293 */ 294static void 295query_loop(char *argv[], int argc) 296{ | 260 pgmname); 261 exit(1); 262 } 263 264 s = socket(AF_INET, SOCK_DGRAM, 0); 265 if (s < 0) { 266 perror("socket"); 267 exit(2); --- 61 unchanged lines hidden (view full) --- 329} 330 331 332/* query all of the listed hosts 333 */ 334static void 335query_loop(char *argv[], int argc) 336{ |
337# define NA0 (OMSG.rip_auths[0]) 338# define NA2 (OMSG.rip_auths[2]) |
|
297 struct seen { 298 struct seen *next; 299 struct in_addr addr; 300 } *seen, *sp; 301 int answered = 0; 302 int cc; 303 fd_set bits; 304 struct timeval now, delay; 305 struct sockaddr_in from; 306 int fromlen; | 339 struct seen { 340 struct seen *next; 341 struct in_addr addr; 342 } *seen, *sp; 343 int answered = 0; 344 int cc; 345 fd_set bits; 346 struct timeval now, delay; 347 struct sockaddr_in from; 348 int fromlen; |
349 MD5_CTX md5_ctx; |
|
307 308 309 OMSG.rip_cmd = (pflag) ? RIPCMD_POLL : RIPCMD_REQUEST; 310 if (ripv2) { 311 OMSG.rip_vers = RIPv2; | 350 351 352 OMSG.rip_cmd = (pflag) ? RIPCMD_POLL : RIPCMD_REQUEST; 353 if (ripv2) { 354 OMSG.rip_vers = RIPv2; |
355 if (auth_type == RIP_AUTH_PW) { 356 OMSG.rip_nets[1] = OMSG.rip_nets[0]; 357 NA0.a_family = RIP_AF_AUTH; 358 NA0.a_type = RIP_AUTH_PW; 359 bcopy(passwd, NA0.au.au_pw, 360 RIP_AUTH_PW_LEN); 361 omsg_len += sizeof(OMSG.rip_nets[0]); 362 363 } else if (auth_type == RIP_AUTH_MD5) { 364 OMSG.rip_nets[1] = OMSG.rip_nets[0]; 365 NA0.a_family = RIP_AF_AUTH; 366 NA0.a_type = RIP_AUTH_MD5; 367 NA0.au.a_md5.md5_keyid = (int8_t)keyid; 368 NA0.au.a_md5.md5_auth_len = RIP_AUTH_PW_LEN; 369 NA0.au.a_md5.md5_seqno = 0; 370 NA0.au.a_md5.md5_pkt_len = sizeof(OMSG.rip_nets[1]); 371 NA2.a_family = RIP_AF_AUTH; 372 NA2.a_type = 1; 373 bcopy(passwd, NA2.au.au_pw, sizeof(NA2.au.au_pw)); 374 MD5Init(&md5_ctx); 375 MD5Update(&md5_ctx, (u_char *)&NA0, 376 (char *)(&NA2+1) - (char *)&NA0); 377 MD5Final(NA2.au.au_pw, &md5_ctx); 378 omsg_len += 2*sizeof(OMSG.rip_nets[0]); 379 } 380 |
|
312 } else { 313 OMSG.rip_vers = RIPv1; 314 OMSG.rip_nets[0].n_mask = 0; 315 } 316 317 /* ask the first (valid) host */ 318 seen = 0; 319 while (0 > out(*argv++)) { --- 68 unchanged lines hidden (view full) --- 388 break; 389 } 390 391 /* fail if there was no answer */ 392 exit (answered >= argc ? 0 : 1); 393} 394 395 | 381 } else { 382 OMSG.rip_vers = RIPv1; 383 OMSG.rip_nets[0].n_mask = 0; 384 } 385 386 /* ask the first (valid) host */ 387 seen = 0; 388 while (0 > out(*argv++)) { --- 68 unchanged lines hidden (view full) --- 457 break; 458 } 459 460 /* fail if there was no answer */ 461 exit (answered >= argc ? 0 : 1); 462} 463 464 |
396/* sent do one host | 465/* send to one host |
397 */ 398static int 399out(char *host) 400{ 401 struct sockaddr_in router; 402 struct hostent *hp; 403 404 if (gettimeofday(&sent, 0) < 0) { --- 22 unchanged lines hidden (view full) --- 427 return -1; 428 } 429 430 return 0; 431} 432 433 434/* | 466 */ 467static int 468out(char *host) 469{ 470 struct sockaddr_in router; 471 struct hostent *hp; 472 473 if (gettimeofday(&sent, 0) < 0) { --- 22 unchanged lines hidden (view full) --- 496 return -1; 497 } 498 499 return 0; 500} 501 502 503/* |
504 * Convert string to printable characters 505 */ 506static char * 507qstring(u_char *s, int len) 508{ 509 static char buf[8*20+1]; 510 char *p; 511 u_char *s2, c; 512 513 514 for (p = buf; len != 0 && p < &buf[sizeof(buf)-1]; len--) { 515 c = *s++; 516 if (c == '\0') { 517 for (s2 = s+1; s2 < &s[len]; s2++) { 518 if (*s2 != '\0') 519 break; 520 } 521 if (s2 >= &s[len]) 522 goto exit; 523 } 524 525 if (c >= ' ' && c < 0x7f && c != '\\') { 526 *p++ = c; 527 continue; 528 } 529 *p++ = '\\'; 530 switch (c) { 531 case '\\': 532 *p++ = '\\'; 533 break; 534 case '\n': 535 *p++= 'n'; 536 break; 537 case '\r': 538 *p++= 'r'; 539 break; 540 case '\t': 541 *p++ = 't'; 542 break; 543 case '\b': 544 *p++ = 'b'; 545 break; 546 default: 547 p += sprintf(p,"%o",c); 548 break; 549 } 550 } 551exit: 552 *p = '\0'; 553 return buf; 554} 555 556 557/* |
|
435 * Handle an incoming RIP packet. 436 */ 437static void 438rip_input(struct sockaddr_in *from, 439 int size) 440{ 441 struct netinfo *n, *lim; 442 struct in_addr in; 443 char *name; 444 char net_buf[80]; 445 u_int mask, dmask; 446 char *sp; 447 int i; 448 struct hostent *hp; 449 struct netent *np; | 558 * Handle an incoming RIP packet. 559 */ 560static void 561rip_input(struct sockaddr_in *from, 562 int size) 563{ 564 struct netinfo *n, *lim; 565 struct in_addr in; 566 char *name; 567 char net_buf[80]; 568 u_int mask, dmask; 569 char *sp; 570 int i; 571 struct hostent *hp; 572 struct netent *np; |
450 struct netauth *a; | 573 struct netauth *na; |
451 452 453 if (nflag) { 454 printf("%s:", inet_ntoa(from->sin_addr)); 455 } else { 456 hp = gethostbyaddr((char*)&from->sin_addr, 457 sizeof(struct in_addr), AF_INET); 458 if (hp == 0) { --- 80 unchanged lines hidden (view full) --- 539 sizeof(in), 540 AF_INET); 541 if (hp != 0) 542 name = hp->h_name; 543 } 544 } 545 546 } else if (n->n_family == RIP_AF_AUTH) { | 574 575 576 if (nflag) { 577 printf("%s:", inet_ntoa(from->sin_addr)); 578 } else { 579 hp = gethostbyaddr((char*)&from->sin_addr, 580 sizeof(struct in_addr), AF_INET); 581 if (hp == 0) { --- 80 unchanged lines hidden (view full) --- 662 sizeof(in), 663 AF_INET); 664 if (hp != 0) 665 name = hp->h_name; 666 } 667 } 668 669 } else if (n->n_family == RIP_AF_AUTH) { |
547 a = (struct netauth*)n; 548 (void)printf(" authentication type %d: ", 549 a->a_type); 550 for (i = 0; i < sizeof(a->au.au_pw); i++) 551 (void)printf("%02x ", a->au.au_pw[i]); | 670 na = (struct netauth*)n; 671 if (na->a_type == RIP_AUTH_PW 672 && n == IMSG.rip_nets) { 673 (void)printf(" Password Authentication:" 674 " \"%s\"\n", 675 qstring(na->au.au_pw, 676 RIP_AUTH_PW_LEN)); 677 continue; 678 } 679 680 if (na->a_type == RIP_AUTH_MD5 681 && n == IMSG.rip_nets) { 682 (void)printf(" MD5 Authentication" 683 " len=%d KeyID=%d" 684 " seqno=%d" 685 " rsvd=%#x,%#x\n", 686 na->au.a_md5.md5_pkt_len, 687 na->au.a_md5.md5_keyid, 688 na->au.a_md5.md5_seqno, 689 na->au.a_md5.rsvd[0], 690 na->au.a_md5.rsvd[1]); 691 continue; 692 } 693 (void)printf(" Authentication type %d: ", 694 ntohs(na->a_type)); 695 for (i = 0; i < sizeof(na->au.au_pw); i++) 696 (void)printf("%02x ", na->au.au_pw[i]); |
552 putc('\n', stdout); 553 continue; 554 555 } else { 556 (void)sprintf(net_buf, "(af %#x) %d.%d.%d.%d", 557 ntohs(n->n_family), 558 (char)(n->n_dst >> 24), 559 (char)(n->n_dst >> 16), --- 87 unchanged lines hidden (view full) --- 647 mask = 0xffffffff << (32-mask); 648 } 649 650 rt->n_dst = htonl(in.s_addr); 651 rt->n_family = RIP_AF_INET; 652 rt->n_mask = htonl(mask); 653 return 1; 654} | 697 putc('\n', stdout); 698 continue; 699 700 } else { 701 (void)sprintf(net_buf, "(af %#x) %d.%d.%d.%d", 702 ntohs(n->n_family), 703 (char)(n->n_dst >> 24), 704 (char)(n->n_dst >> 16), --- 87 unchanged lines hidden (view full) --- 792 mask = 0xffffffff << (32-mask); 793 } 794 795 rt->n_dst = htonl(in.s_addr); 796 rt->n_family = RIP_AF_INET; 797 rt->n_mask = htonl(mask); 798 return 1; 799} |
800 801 802/* strtok(), but honoring backslash 803 */ 804static int /* -1=bad */ 805parse_quote(char **linep, 806 char *delims, 807 char *delimp, 808 char *buf, 809 int lim) 810{ 811 char c, *pc, *p; 812 813 814 pc = *linep; 815 if (*pc == '\0') 816 return -1; 817 818 for (;;) { 819 if (lim == 0) 820 return -1; 821 c = *pc++; 822 if (c == '\0') 823 break; 824 825 if (c == '\\' && pc != '\0') { 826 if ((c = *pc++) == 'n') { 827 c = '\n'; 828 } else if (c == 'r') { 829 c = '\r'; 830 } else if (c == 't') { 831 c = '\t'; 832 } else if (c == 'b') { 833 c = '\b'; 834 } else if (c >= '0' && c <= '7') { 835 c -= '0'; 836 if (*pc >= '0' && *pc <= '7') { 837 c = (c<<3)+(*pc++ - '0'); 838 if (*pc >= '0' && *pc <= '7') 839 c = (c<<3)+(*pc++ - '0'); 840 } 841 } 842 843 } else { 844 for (p = delims; *p != '\0'; ++p) { 845 if (*p == c) 846 goto exit; 847 } 848 } 849 850 *buf++ = c; 851 --lim; 852 } 853exit: 854 if (delimp != 0) 855 *delimp = c; 856 *linep = pc-1; 857 if (lim != 0) 858 *buf = '\0'; 859 return 0; 860} |
|