More strict ip options parsing.

Reviewed by:	bde (style), silence on -audit
MFC after:	2 months
This commit is contained in:
Maxim Konovalov 2002-07-05 11:47:33 +00:00
parent f00abca0c4
commit 301207dffe
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=99446

View File

@ -96,6 +96,7 @@ static const char rcsid[] =
#include <netinet6/ipsec.h> #include <netinet6/ipsec.h>
#endif /*IPSEC*/ #endif /*IPSEC*/
#define INADDR_LEN ((int)sizeof(in_addr_t))
#define PHDR_LEN ((int)sizeof(struct timeval)) #define PHDR_LEN ((int)sizeof(struct timeval))
#define DEFDATALEN (64 - PHDR_LEN) /* default data length */ #define DEFDATALEN (64 - PHDR_LEN) /* default data length */
#define FLOOD_BACKOFF 20000 /* usecs to back off if F_FLOOD mode */ #define FLOOD_BACKOFF 20000 /* usecs to back off if F_FLOOD mode */
@ -801,10 +802,10 @@ pr_pack(buf, cc, from, tv)
{ {
struct icmp *icp; struct icmp *icp;
struct ip *ip; struct ip *ip;
struct in_addr ina;
struct timeval *tp; struct timeval *tp;
u_char *cp, *dp; u_char *cp, *dp;
double triptime; double triptime;
u_long l;
int dupflag, hlen, i, j, seq; int dupflag, hlen, i, j, seq;
static int old_rrlen; static int old_rrlen;
static char old_rr[MAX_IPOPTLEN]; static char old_rr[MAX_IPOPTLEN];
@ -940,80 +941,70 @@ pr_pack(buf, cc, from, tv)
break; break;
case IPOPT_LSRR: case IPOPT_LSRR:
(void)printf("\nLSRR: "); (void)printf("\nLSRR: ");
j = cp[IPOPT_OLEN] - IPOPT_MINOFF + 1;
hlen -= 2; hlen -= 2;
j = *++cp; cp += 2;
++cp; if (j >= INADDR_LEN && j <= hlen - INADDR_LEN) {
if (j > IPOPT_MINOFF)
for (;;) { for (;;) {
l = *++cp; bcopy(++cp, &ina.s_addr, INADDR_LEN);
l = (l<<8) + *++cp; if (ina.s_addr == 0)
l = (l<<8) + *++cp;
l = (l<<8) + *++cp;
if (l == 0) {
(void)printf("\t0.0.0.0"); (void)printf("\t0.0.0.0");
} else { else
struct in_addr ina;
ina.s_addr = ntohl(l);
(void)printf("\t%s", (void)printf("\t%s",
pr_addr(ina)); pr_addr(ina));
} hlen -= INADDR_LEN;
hlen -= 4; cp += INADDR_LEN - 1;
j -= 4; j -= INADDR_LEN;
if (j <= IPOPT_MINOFF) if (j < INADDR_LEN)
break; break;
(void)putchar('\n'); (void)putchar('\n');
} }
} else
(void)printf("\t(truncated route)\n");
break; break;
case IPOPT_RR: case IPOPT_RR:
j = *++cp; /* get length */ j = cp[IPOPT_OLEN]; /* get length */
i = *++cp; /* and pointer */ i = cp[IPOPT_OFFSET]; /* and pointer */
hlen -= 2; hlen -= 2;
cp += 2;
if (i > j) if (i > j)
i = j; i = j;
i -= IPOPT_MINOFF; i = i - IPOPT_MINOFF + 1;
if (i <= 0) if (i < 0 || i > (hlen - (int)sizeof(struct ip))) {
old_rrlen = 0;
continue; continue;
}
if (i == old_rrlen if (i == old_rrlen
&& cp == (u_char *)buf + sizeof(struct ip) + 2
&& !bcmp((char *)cp, old_rr, i) && !bcmp((char *)cp, old_rr, i)
&& !(options & F_FLOOD)) { && !(options & F_FLOOD)) {
(void)printf("\t(same route)"); (void)printf("\t(same route)");
i = ((i + 3) / 4) * 4;
hlen -= i; hlen -= i;
cp += i; cp += i;
break; break;
} }
if (i < MAX_IPOPTLEN) { old_rrlen = i;
old_rrlen = i; bcopy((char *)cp, old_rr, i);
bcopy((char *)cp, old_rr, i);
} else
old_rrlen = 0;
(void)printf("\nRR: "); (void)printf("\nRR: ");
j = 0;
for (;;) { if (i >= INADDR_LEN &&
l = *++cp; i <= hlen - (int)sizeof(struct ip)) {
l = (l<<8) + *++cp; for (;;) {
l = (l<<8) + *++cp; bcopy(++cp, &ina.s_addr, INADDR_LEN);
l = (l<<8) + *++cp; if (ina.s_addr == 0)
if (l == 0) { (void)printf("\t0.0.0.0");
(void)printf("\t0.0.0.0"); else
} else { (void)printf("\t%s",
struct in_addr ina; pr_addr(ina));
ina.s_addr = ntohl(l); hlen -= INADDR_LEN;
(void)printf("\t%s", pr_addr(ina)); cp += INADDR_LEN - 1;
i -= INADDR_LEN;
if (i < INADDR_LEN)
break;
(void)putchar('\n');
} }
hlen -= 4; } else
i -= 4; (void)printf("\t(truncated route)");
j += 4;
if (i <= 0)
break;
if (j >= MAX_IPOPTLEN) {
(void)printf("\t(truncated route)");
break;
}
(void)putchar('\n');
}
break; break;
case IPOPT_NOP: case IPOPT_NOP:
(void)printf("\nNOP"); (void)printf("\nNOP");