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:
parent
3c0f8ff528
commit
f0dcb78326
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=189343
@ -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);
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user