Deleted Added
full compact
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}