Date: Wed, 4 Mar 2009 02:51:22 +0000 (UTC) From: Bruce M Simpson <bms@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r189343 - head/sys/netinet Message-ID: <200903040251.n242pMtM029146@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bms Date: Wed Mar 4 02:51:22 2009 New Revision: 189343 URL: http://svn.freebsd.org/changeset/base/189343 Log: 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. Modified: head/sys/netinet/ip_options.c head/sys/netinet/ip_options.h Modified: head/sys/netinet/ip_options.c ============================================================================== --- head/sys/netinet/ip_options.c Wed Mar 4 02:38:38 2009 (r189342) +++ head/sys/netinet/ip_options.c Wed Mar 4 02:51:22 2009 (r189343) @@ -683,3 +683,64 @@ bad: (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); +} Modified: head/sys/netinet/ip_options.h ============================================================================== --- head/sys/netinet/ip_options.h Wed Mar 4 02:38:38 2009 (r189342) +++ head/sys/netinet/ip_options.h Wed Mar 4 02:51:22 2009 (r189343) @@ -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 *);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903040251.n242pMtM029146>