input.c (19880) | input.c (20339) |
---|---|
1/* 2 * Copyright (c) 1983, 1988, 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 --- 22 unchanged lines hidden (view full) --- 31 * SUCH DAMAGE. 32 */ 33 34#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) 35static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93"; 36#elif defined(__NetBSD__) 37static char rcsid[] = "$NetBSD$"; 38#endif | 1/* 2 * Copyright (c) 1983, 1988, 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 --- 22 unchanged lines hidden (view full) --- 31 * SUCH DAMAGE. 32 */ 33 34#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) 35static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93"; 36#elif defined(__NetBSD__) 37static char rcsid[] = "$NetBSD$"; 38#endif |
39#ident "$Revision: 1.17 $" | 39#ident "$Revision: 1.19 $" |
40 41#include "defs.h" 42 43static void input(struct sockaddr_in *, struct interface *, struct interface *, 44 struct rip *, int); 45static void input_route(struct interface *, naddr, 46 naddr, naddr, naddr, struct netinfo *); 47static int ck_passwd(struct interface *, struct rip *, void *, 48 naddr, struct msg_limit *); 49 50 51/* process RIP input 52 */ 53void 54read_rip(int sock, 55 struct interface *sifp) 56{ | 40 41#include "defs.h" 42 43static void input(struct sockaddr_in *, struct interface *, struct interface *, 44 struct rip *, int); 45static void input_route(struct interface *, naddr, 46 naddr, naddr, naddr, struct netinfo *); 47static int ck_passwd(struct interface *, struct rip *, void *, 48 naddr, struct msg_limit *); 49 50 51/* process RIP input 52 */ 53void 54read_rip(int sock, 55 struct interface *sifp) 56{ |
57 static struct msg_limit bad_name; | |
58 struct sockaddr_in from; 59 struct interface *aifp; 60 int fromlen, cc; | 57 struct sockaddr_in from; 58 struct interface *aifp; 59 int fromlen, cc; |
61 struct { | |
62#ifdef USE_PASSIFNAME | 60#ifdef USE_PASSIFNAME |
61 static struct msg_limit bad_name; 62 struct { |
|
63 char ifname[IFNAMSIZ]; | 63 char ifname[IFNAMSIZ]; |
64#endif | |
65 union pkt_buf pbuf; 66 } inbuf; | 64 union pkt_buf pbuf; 65 } inbuf; |
66#else 67 struct { 68 union pkt_buf pbuf; 69 } inbuf; 70#endif |
|
67 68 69 for (;;) { 70 fromlen = sizeof(from); 71 cc = recvfrom(sock, &inbuf, sizeof(inbuf), 0, 72 (struct sockaddr*)&from, &fromlen); 73 if (cc <= 0) { 74 if (cc < 0 && errno != EWOULDBLOCK) --- 68 unchanged lines hidden (view full) --- 143# define FROM_NADDR from->sin_addr.s_addr 144 static struct msg_limit use_auth, bad_len, bad_mask; 145 static struct msg_limit unk_router, bad_router, bad_nhop; 146 147 struct rt_entry *rt; 148 struct netinfo *n, *lim; 149 struct interface *ifp1; 150 naddr gate, mask, v1_mask, dst, ddst_h; | 71 72 73 for (;;) { 74 fromlen = sizeof(from); 75 cc = recvfrom(sock, &inbuf, sizeof(inbuf), 0, 76 (struct sockaddr*)&from, &fromlen); 77 if (cc <= 0) { 78 if (cc < 0 && errno != EWOULDBLOCK) --- 68 unchanged lines hidden (view full) --- 147# define FROM_NADDR from->sin_addr.s_addr 148 static struct msg_limit use_auth, bad_len, bad_mask; 149 static struct msg_limit unk_router, bad_router, bad_nhop; 150 151 struct rt_entry *rt; 152 struct netinfo *n, *lim; 153 struct interface *ifp1; 154 naddr gate, mask, v1_mask, dst, ddst_h; |
151 struct auth_key *ap; | 155 struct auth *ap; |
152 int i; 153 154 /* Notice when we hear from a remote gateway 155 */ 156 if (aifp != 0 157 && (aifp->int_state & IS_REMOTE)) 158 aifp->int_act_time = now.tv_sec; 159 --- 97 unchanged lines hidden (view full) --- 257 258 if (rip->rip_vers == RIPv2 259 && (aifp == 0 || (aifp->int_state & IS_NO_RIPV1_OUT))) { 260 v12buf.buf->rip_vers = RIPv2; 261 /* If we have a secret but it is a cleartext secret, 262 * do not disclose our secret unless the other guy 263 * already knows it. 264 */ | 156 int i; 157 158 /* Notice when we hear from a remote gateway 159 */ 160 if (aifp != 0 161 && (aifp->int_state & IS_REMOTE)) 162 aifp->int_act_time = now.tv_sec; 163 --- 97 unchanged lines hidden (view full) --- 261 262 if (rip->rip_vers == RIPv2 263 && (aifp == 0 || (aifp->int_state & IS_NO_RIPV1_OUT))) { 264 v12buf.buf->rip_vers = RIPv2; 265 /* If we have a secret but it is a cleartext secret, 266 * do not disclose our secret unless the other guy 267 * already knows it. 268 */ |
265 if (aifp != 0 266 && aifp->int_auth.type == RIP_AUTH_PW | 269 ap = find_auth(aifp); 270 if (aifp == 0 && ap->type == RIP_AUTH_PW 271 && n->n_family == RIP_AF_AUTH |
267 && !ck_passwd(aifp,rip,lim,FROM_NADDR,&use_auth)) 268 ap = 0; | 272 && !ck_passwd(aifp,rip,lim,FROM_NADDR,&use_auth)) 273 ap = 0; |
269 else 270 ap = find_auth(aifp); | |
271 } else { 272 v12buf.buf->rip_vers = RIPv1; 273 ap = 0; 274 } | 274 } else { 275 v12buf.buf->rip_vers = RIPv1; 276 ap = 0; 277 } |
275 clr_ws_buf(&v12buf, ap, aifp); | 278 clr_ws_buf(&v12buf, ap); |
276 277 do { 278 NTOHL(n->n_metric); 279 280 /* A single entry with family RIP_AF_UNSPEC and 281 * metric HOPCNT_INFINITY means "all routes". 282 * We respond to routers only if we are acting 283 * as a supplier, or to anyone other than a router --- 108 unchanged lines hidden (view full) --- 392 /* Stop paying attention if we fill the output buffer. 393 */ 394 if (++v12buf.n >= v12buf.lim) 395 break; 396 } while (++n < lim); 397 398 /* Send the answer about specific routes. 399 */ | 279 280 do { 281 NTOHL(n->n_metric); 282 283 /* A single entry with family RIP_AF_UNSPEC and 284 * metric HOPCNT_INFINITY means "all routes". 285 * We respond to routers only if we are acting 286 * as a supplier, or to anyone other than a router --- 108 unchanged lines hidden (view full) --- 395 /* Stop paying attention if we fill the output buffer. 396 */ 397 if (++v12buf.n >= v12buf.lim) 398 break; 399 } while (++n < lim); 400 401 /* Send the answer about specific routes. 402 */ |
400 if (ap != 0 && aifp->int_auth.type == RIP_AUTH_MD5) | 403 if (ap != 0 && ap->type == RIP_AUTH_MD5) |
401 end_md5_auth(&v12buf, ap); 402 403 if (from->sin_port != htons(RIP_PORT)) { 404 /* query */ 405 (void)output(OUT_QUERY, from, aifp, 406 v12buf.buf, 407 ((char *)v12buf.n - (char*)v12buf.buf)); 408 } else if (supplier) { --- 19 unchanged lines hidden (view full) --- 428 } 429 if (aifp == 0) { 430 msglog("trace command from unknown router %s", 431 naddr_ntoa(FROM_NADDR)); 432 return; 433 } 434 if (rip->rip_cmd == RIPCMD_TRACEON) { 435 rip->rip_tracefile[cc-4] = '\0'; | 404 end_md5_auth(&v12buf, ap); 405 406 if (from->sin_port != htons(RIP_PORT)) { 407 /* query */ 408 (void)output(OUT_QUERY, from, aifp, 409 v12buf.buf, 410 ((char *)v12buf.n - (char*)v12buf.buf)); 411 } else if (supplier) { --- 19 unchanged lines hidden (view full) --- 431 } 432 if (aifp == 0) { 433 msglog("trace command from unknown router %s", 434 naddr_ntoa(FROM_NADDR)); 435 return; 436 } 437 if (rip->rip_cmd == RIPCMD_TRACEON) { 438 rip->rip_tracefile[cc-4] = '\0'; |
436 trace_on((char*)rip->rip_tracefile, 0); | 439 set_tracefile((char*)rip->rip_tracefile, 440 "trace command: %s\n", 0); |
437 } else { 438 trace_off("tracing turned off by %s\n", 439 naddr_ntoa(FROM_NADDR)); 440 } 441 return; 442 443 case RIPCMD_RESPONSE: 444 if (cc%sizeof(*n) != sizeof(struct rip)%sizeof(*n)) { --- 69 unchanged lines hidden (view full) --- 514 */ 515 if (aifp->int_state & IS_BROKE) { 516 trace_pkt("%sdiscard response via broken interface %s", 517 aifp->int_name); 518 return; 519 } 520 521 /* If the interface cares, ignore bad routers. | 441 } else { 442 trace_off("tracing turned off by %s\n", 443 naddr_ntoa(FROM_NADDR)); 444 } 445 return; 446 447 case RIPCMD_RESPONSE: 448 if (cc%sizeof(*n) != sizeof(struct rip)%sizeof(*n)) { --- 69 unchanged lines hidden (view full) --- 518 */ 519 if (aifp->int_state & IS_BROKE) { 520 trace_pkt("%sdiscard response via broken interface %s", 521 aifp->int_name); 522 return; 523 } 524 525 /* If the interface cares, ignore bad routers. |
522 * Trace but do not log this problem because when it 523 * happens it happens a lot. | 526 * Trace but do not log this problem, because where it 527 * happens, it happens frequently. |
524 */ 525 if (aifp->int_state & IS_DISTRUST) { 526 struct tgate *tg = tgates; 527 while (tg->tgate_addr != FROM_NADDR) { 528 tg = tg->tgate_next; 529 if (tg == 0) { 530 trace_pkt(" discard RIP response" 531 " from untrusted router %s", 532 naddr_ntoa(FROM_NADDR)); 533 return; 534 } 535 } 536 } 537 538 /* Authenticate the packet if we have a secret. | 528 */ 529 if (aifp->int_state & IS_DISTRUST) { 530 struct tgate *tg = tgates; 531 while (tg->tgate_addr != FROM_NADDR) { 532 tg = tg->tgate_next; 533 if (tg == 0) { 534 trace_pkt(" discard RIP response" 535 " from untrusted router %s", 536 naddr_ntoa(FROM_NADDR)); 537 return; 538 } 539 } 540 } 541 542 /* Authenticate the packet if we have a secret. |
539 * If we do not, ignore the silliness in RFC 1723 540 * and accept it regardless. | 543 * If we do not have any secrets, ignore the error in 544 * RFC 1723 and accept it regardless. |
541 */ | 545 */ |
542 if (aifp->int_auth.type != RIP_AUTH_NONE 543 && rip->rip_vers != RIPv1) { 544 if (!ck_passwd(aifp,rip,lim,FROM_NADDR,&use_auth)) 545 return; 546 } | 546 if (aifp->int_auth[0].type != RIP_AUTH_NONE 547 && rip->rip_vers != RIPv1 548 && !ck_passwd(aifp,rip,lim,FROM_NADDR,&use_auth)) 549 return; |
547 548 do { 549 if (n->n_family == RIP_AF_AUTH) 550 continue; 551 552 NTOHL(n->n_metric); 553 dst = n->n_dst; 554 if (n->n_family != RIP_AF_INET --- 300 unchanged lines hidden (view full) --- 855static int /* 0 if bad */ 856ck_passwd(struct interface *aifp, 857 struct rip *rip, 858 void *lim, 859 naddr from, 860 struct msg_limit *use_authp) 861{ 862# define NA (rip->rip_auths) | 550 551 do { 552 if (n->n_family == RIP_AF_AUTH) 553 continue; 554 555 NTOHL(n->n_metric); 556 dst = n->n_dst; 557 if (n->n_family != RIP_AF_INET --- 300 unchanged lines hidden (view full) --- 858static int /* 0 if bad */ 859ck_passwd(struct interface *aifp, 860 struct rip *rip, 861 void *lim, 862 naddr from, 863 struct msg_limit *use_authp) 864{ 865# define NA (rip->rip_auths) |
863# define DAY (24*60*60) | |
864 struct netauth *na2; | 866 struct netauth *na2; |
865 struct auth_key *akp = aifp->int_auth.keys; | 867 struct auth *ap; |
866 MD5_CTX md5_ctx; 867 u_char hash[RIP_AUTH_PW_LEN]; 868 int i; 869 870 871 if ((void *)NA >= lim || NA->a_family != RIP_AF_AUTH) { 872 msglim(use_authp, from, "missing password from %s", 873 naddr_ntoa(from)); 874 return 0; 875 } 876 | 868 MD5_CTX md5_ctx; 869 u_char hash[RIP_AUTH_PW_LEN]; 870 int i; 871 872 873 if ((void *)NA >= lim || NA->a_family != RIP_AF_AUTH) { 874 msglim(use_authp, from, "missing password from %s", 875 naddr_ntoa(from)); 876 return 0; 877 } 878 |
877 if (NA->a_type != aifp->int_auth.type) { 878 msglim(use_authp, from, "wrong type of password from %s", 879 naddr_ntoa(from)); 880 return 0; 881 } | 879 /* accept any current (+/- 24 hours) password 880 */ 881 for (ap = aifp->int_auth, i = 0; i < MAX_AUTH_KEYS; i++, ap++) { 882 if (ap->type != NA->a_type 883 || (u_long)ap->start > (u_long)clk.tv_sec+DAY 884 || (u_long)ap->end+DAY < (u_long)clk.tv_sec) 885 continue; |
882 | 886 |
883 if (NA->a_type == RIP_AUTH_PW) { 884 /* accept any current cleartext password 885 */ 886 for (i = 0; i < MAX_AUTH_KEYS; i++, akp++) { 887 if ((u_long)akp->start-DAY > (u_long)clk.tv_sec 888 || (u_long)akp->end+DAY < (u_long)clk.tv_sec) 889 continue; 890 891 if (!bcmp(NA->au.au_pw, akp->key, RIP_AUTH_PW_LEN)) | 887 if (NA->a_type == RIP_AUTH_PW) { 888 if (!bcmp(NA->au.au_pw, ap->key, RIP_AUTH_PW_LEN)) |
892 return 1; | 889 return 1; |
893 } | |
894 | 890 |
895 } else { 896 /* accept any current MD5 secret with the right key ID 897 */ 898 for (i = 0; i < MAX_AUTH_KEYS; i++, akp++) { 899 if (NA->au.a_md5.md5_keyid == akp->keyid 900 && (u_long)akp->start-DAY <= (u_long)clk.tv_sec 901 && (u_long)akp->end+DAY >= (u_long)clk.tv_sec) 902 break; 903 } | 891 } else { 892 /* accept MD5 secret with the right key ID 893 */ 894 if (NA->au.a_md5.md5_keyid != ap->keyid) 895 continue; |
904 | 896 |
905 if (i < MAX_AUTH_KEYS) { | |
906 na2 = (struct netauth *)((char *)(NA+1) 907 + NA->au.a_md5.md5_pkt_len); 908 if (NA->au.a_md5.md5_pkt_len % sizeof(*NA) != 0 909 || lim < (void *)(na2+1)) { 910 msglim(use_authp, from, 911 "bad MD5 RIP-II pkt length %d from %s", 912 NA->au.a_md5.md5_pkt_len, 913 naddr_ntoa(from)); 914 return 0; 915 } 916 MD5Init(&md5_ctx); 917 MD5Update(&md5_ctx, (u_char *)NA, 918 (char *)na2->au.au_pw - (char *)NA); 919 MD5Update(&md5_ctx, | 897 na2 = (struct netauth *)((char *)(NA+1) 898 + NA->au.a_md5.md5_pkt_len); 899 if (NA->au.a_md5.md5_pkt_len % sizeof(*NA) != 0 900 || lim < (void *)(na2+1)) { 901 msglim(use_authp, from, 902 "bad MD5 RIP-II pkt length %d from %s", 903 NA->au.a_md5.md5_pkt_len, 904 naddr_ntoa(from)); 905 return 0; 906 } 907 MD5Init(&md5_ctx); 908 MD5Update(&md5_ctx, (u_char *)NA, 909 (char *)na2->au.au_pw - (char *)NA); 910 MD5Update(&md5_ctx, |
920 (u_char *)akp->key, sizeof(akp->key)); | 911 (u_char *)ap->key, sizeof(ap->key)); |
921 MD5Final(hash, &md5_ctx); | 912 MD5Final(hash, &md5_ctx); |
922 if (na2->a_family == RIP_AF_AUTH 923 && na2->a_type == 1 924 && NA->au.a_md5.md5_auth_len == RIP_AUTH_PW_LEN 925 && !bcmp(hash, na2->au.au_pw, sizeof(hash))) 926 return 1; | 913 if (na2->a_family != RIP_AF_AUTH 914 || na2->a_type != 1 915 || NA->au.a_md5.md5_auth_len != RIP_AUTH_PW_LEN 916 || bcmp(hash, na2->au.au_pw, sizeof(hash))) 917 return 0; 918 return 1; |
927 } 928 } 929 930 msglim(use_authp, from, "bad password from %s", 931 naddr_ntoa(from)); 932 return 0; 933#undef NA 934} | 919 } 920 } 921 922 msglim(use_authp, from, "bad password from %s", 923 naddr_ntoa(from)); 924 return 0; 925#undef NA 926} |