diff options
author | julian <julian@FreeBSD.org> | 1997-07-18 11:08:35 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 1997-07-18 11:08:35 +0000 |
commit | bb9437716d65e93d956fb96425c754125a6aa4e6 (patch) | |
tree | 9096b7fd297a2cc32fbdff209c2fd19796960983 /sbin/routed | |
parent | 8bdc2de5821f86489ee2b3500d24c78570667f56 (diff) | |
download | FreeBSD-src-bb9437716d65e93d956fb96425c754125a6aa4e6.zip FreeBSD-src-bb9437716d65e93d956fb96425c754125a6aa4e6.tar.gz |
Check if routed had the same problems that route(1) had.
The answer is not really, but almost.
it sent data that was ok, though it was a hack,
but it was bug-compatible with the kernel on receiving them. This also
had been fixed with a hack.. I hacked it better I think.
Diffstat (limited to 'sbin/routed')
-rw-r--r-- | sbin/routed/if.c | 42 | ||||
-rw-r--r-- | sbin/routed/table.c | 12 |
2 files changed, 35 insertions, 19 deletions
diff --git a/sbin/routed/if.c b/sbin/routed/if.c index b68ff52..2b32759 100644 --- a/sbin/routed/if.c +++ b/sbin/routed/if.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93"; #elif defined(__NetBSD__) static char rcsid[] = "$NetBSD$"; #endif -#ident "$Revision: 1.23 $" +#ident "$Revision: 1.1.1.5 $" #include "defs.h" #include "pathnames.h" @@ -596,7 +596,12 @@ if_ok(struct interface *ifp, } -/* disassemble routing message +#ifdef _HAVE_SA_LEN +static struct sockaddr sa_zero = { sizeof(struct sockaddr), AF_INET }; +#endif +/* + * disassemble routing message + * copied bug for bug from the BSD kernel */ void rt_xaddrs(struct rt_addrinfo *info, @@ -604,10 +609,9 @@ rt_xaddrs(struct rt_addrinfo *info, struct sockaddr *lim, int addrs) { + char *sa_limit; /* next byte after the sockaddr */ int i; -#ifdef _HAVE_SA_LEN - static struct sockaddr sa_zero; -#endif + int len; #ifdef sgi #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \ : sizeof(__uint64_t)) @@ -623,14 +627,30 @@ rt_xaddrs(struct rt_addrinfo *info, if ((addrs & (1 << i)) == 0) continue; #ifdef _HAVE_SA_LEN - info->rti_info[i] = (sa->sa_len != 0) ? sa : &sa_zero; - sa = (struct sockaddr *)((char*)(sa) - + ROUNDUP(sa->sa_len)); + len = sa->sa_len; + + /* Check the sockaddr doesn't go past the end of the buffer. */ + /* Cope with buggy (malicious?) sender.*/ + if (len) { + sa_limit = ((char*)sa) + len; + if ( sa_limit > (char *)lim ) /* equal is ok */ + return; + } else { + /* + * We allow the last broken sockaddr + * to be replaced by a good null one + * because some old versions of routing stuff + * would do this (4.4 route(1) for example). + * This should go away eventually. + */ + info->rti_info[i] = &sa_zero; + return; /* this one had unknown length */ + } #else - info->rti_info[i] = sa; - sa = (struct sockaddr *)((char*)(sa) - + ROUNDUP(_FAKE_SA_LEN_DST(sa))); + len = _FAKE_SA_LEN_DST(sa); #endif + info->rti_info[i] = sa; + sa = (struct sockaddr *)((char*)(sa) + ROUNDUP(len)); } } diff --git a/sbin/routed/table.c b/sbin/routed/table.c index a7c2303..e224d41 100644 --- a/sbin/routed/table.c +++ b/sbin/routed/table.c @@ -612,8 +612,8 @@ rtm_type_name(u_char type) /* Trim a mask in a sockaddr - * Produce a length of 0 for an address of 0. - * Otherwise produce the index of the first zero byte. + * Produce the index of the first zero byte. + * i.e. Produce a index of 4 for an mask of 0. (default route) */ void #ifdef _HAVE_SIN_LEN @@ -624,13 +624,11 @@ masktrim(struct sockaddr_in_new *ap) { register char *cp; - if (ap->sin_addr.s_addr == 0) { - ap->sin_len = 0; - return; - } + ap->sin_port = 0xffff; /* buffer zone for default route */ cp = (char *)(&ap->sin_addr.s_addr+1); while (*--cp == 0) continue; + /*ap->sin_port = 0x0;*/ /* may not be needed (who cares?)*/ ap->sin_len = cp - (char*)ap + 1; } @@ -685,8 +683,6 @@ again: w.w_mask.sin_addr.s_addr = htonl(mask); #ifdef _HAVE_SA_LEN masktrim(&w.w_mask); - if (w.w_mask.sin_len == 0) - w.w_mask.sin_len = sizeof(long); w.w_rtm.rtm_msglen -= (sizeof(w.w_mask) - w.w_mask.sin_len); #endif } |