Add function ip_checkrouteralert(), which will be used

by IGMPv3 to check for the IPv4 Router Alert [RFC2113]
option in a pulled-up IP mbuf chain.
This commit is contained in:
Bruce M Simpson 2009-03-04 02:51:22 +00:00
parent 3c0f8ff528
commit f0dcb78326
2 changed files with 62 additions and 0 deletions

View File

@ -683,3 +683,64 @@ ip_pcbopts(struct inpcb *inp, int optname, struct mbuf *m)
(void)m_free(m);
return (EINVAL);
}
/*
* Check for the presence of the IP Router Alert option [RFC2113]
* in the header of an IPv4 datagram.
*
* This call is not intended for use from the forwarding path; it is here
* so that protocol domains may check for the presence of the option.
* Given how FreeBSD's IPv4 stack is currently structured, the Router Alert
* option does not have much relevance to the implementation, though this
* may change in future.
* Router alert options SHOULD be passed if running in IPSTEALTH mode and
* we are not the endpoint.
* Length checks on individual options should already have been peformed
* by ip_dooptions() therefore they are folded under INVARIANTS here.
*
* Return zero if not present or options are invalid, non-zero if present.
*/
int
ip_checkrouteralert(struct mbuf *m)
{
struct ip *ip = mtod(m, struct ip *);
u_char *cp;
int opt, optlen, cnt, found_ra;
found_ra = 0;
cp = (u_char *)(ip + 1);
cnt = (ip->ip_hl << 2) - sizeof (struct ip);
for (; cnt > 0; cnt -= optlen, cp += optlen) {
opt = cp[IPOPT_OPTVAL];
if (opt == IPOPT_EOL)
break;
if (opt == IPOPT_NOP)
optlen = 1;
else {
#ifdef INVARIANTS
if (cnt < IPOPT_OLEN + sizeof(*cp))
break;
#endif
optlen = cp[IPOPT_OLEN];
#ifdef INVARIANTS
if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt)
break;
#endif
}
switch (opt) {
case IPOPT_RA:
#ifdef INVARIANTS
if (optlen != IPOPT_OFFSET + sizeof(uint16_t) ||
(*((uint16_t *)&cp[IPOPT_OFFSET]) != 0))
break;
else
#endif
found_ra = 1;
break;
default:
break;
}
}
return (found_ra);
}

View File

@ -49,6 +49,7 @@ struct ipopt_tag {
extern int ip_doopts; /* process or ignore IP options */
int ip_checkrouteralert(struct mbuf *);
int ip_dooptions(struct mbuf *, int);
struct mbuf *ip_insertoptions(struct mbuf *, struct mbuf *, int *);
int ip_optcopy(struct ip *, struct ip *);