-/* $OpenBSD: dest6.c,v 1.18 2022/02/22 01:15:02 guenther Exp $ */
+/* $OpenBSD: dest6.c,v 1.19 2022/06/29 22:45:24 bluhm Exp $ */
/* $KAME: dest6.c,v 1.25 2001/02/22 01:39:16 itojun Exp $ */
/*
int
dest6_input(struct mbuf **mp, int *offp, int proto, int af)
{
- struct mbuf *m = *mp;
int off = *offp, dstoptlen, optlen;
struct ip6_dest *dstopts;
u_int8_t *opt;
/* validation of the length of the header */
- IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, sizeof(*dstopts));
+ IP6_EXTHDR_GET(dstopts, struct ip6_dest *, *mp, off, sizeof(*dstopts));
if (dstopts == NULL)
return IPPROTO_DONE;
dstoptlen = (dstopts->ip6d_len + 1) << 3;
- IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, dstoptlen);
+ IP6_EXTHDR_GET(dstopts, struct ip6_dest *, *mp, off, dstoptlen);
if (dstopts == NULL)
return IPPROTO_DONE;
off += dstoptlen;
optlen = *(opt + 1) + 2;
break;
default: /* unknown option */
- optlen = ip6_unknown_opt(opt, m,
- opt - mtod(m, u_int8_t *));
+ optlen = ip6_unknown_opt(mp, opt,
+ opt - mtod(*mp, u_int8_t *));
if (optlen == -1)
return (IPPROTO_DONE);
optlen += 2;
return (dstopts->ip6d_nxt);
bad:
- m_freem(m);
+ m_freemp(mp);
return (IPPROTO_DONE);
}
-/* $OpenBSD: ip6_input.c,v 1.247 2022/06/29 11:22:10 bluhm Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.248 2022/06/29 22:45:24 bluhm Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
int ip6_local(struct mbuf **, int *, int, int);
int ip6_check_rh0hdr(struct mbuf *, int *);
int ip6_hbhchcheck(struct mbuf **, int *, int *);
-int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
+int ip6_hopopts_input(struct mbuf **, int *, u_int32_t *, u_int32_t *);
struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
int ip6_sysctl_soiikey(void *, size_t *, void *, size_t);
if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
struct ip6_hbh *hbh;
- if (ip6_hopopts_input(&plen, &rtalert, mp, offp))
+ if (ip6_hopopts_input(mp, offp, &plen, &rtalert))
goto bad; /* m have already been freed */
/* adjust pointer */
* rtalertp - XXX: should be stored in a more smart way
*/
int
-ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, struct mbuf **mp,
- int *offp)
+ip6_hopopts_input(struct mbuf **mp, int *offp, u_int32_t *plenp,
+ u_int32_t *rtalertp)
{
int off = *offp, hbhlen;
struct ip6_hbh *hbh;
off += hbhlen;
hbhlen -= sizeof(struct ip6_hbh);
- if (ip6_process_hopopts(*mp, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
+ if (ip6_process_hopopts(mp, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
hbhlen, rtalertp, plenp) < 0)
return (-1);
* This function is separate from ip6_hopopts_input() in order to
* handle a case where the sending node itself process its hop-by-hop
* options header. In such a case, the function is called from ip6_output().
+ * On error free mbuf and return -1.
*
* The function assumes that hbh header is located right after the IPv6 header
* (RFC2460 p7), opthead is pointer into data content in m, and opthead to
* opthead + hbhlen is located in continuous memory region.
*/
int
-ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen,
+ip6_process_hopopts(struct mbuf **mp, u_int8_t *opthead, int hbhlen,
u_int32_t *rtalertp, u_int32_t *plenp)
{
struct ip6_hdr *ip6;
}
if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) {
/* XXX stat */
- icmp6_error(m, ICMP6_PARAM_PROB,
+ icmp6_error(*mp, ICMP6_PARAM_PROB,
ICMP6_PARAMPROB_HEADER,
erroff + opt + 1 - opthead);
return (-1);
}
if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) {
/* XXX stat */
- icmp6_error(m, ICMP6_PARAM_PROB,
+ icmp6_error(*mp, ICMP6_PARAM_PROB,
ICMP6_PARAMPROB_HEADER,
erroff + opt + 1 - opthead);
return (-1);
* IPv6 packets that have non 0 payload length
* must not contain a jumbo payload option.
*/
- ip6 = mtod(m, struct ip6_hdr *);
+ ip6 = mtod(*mp, struct ip6_hdr *);
if (ip6->ip6_plen) {
ip6stat_inc(ip6s_badoptions);
- icmp6_error(m, ICMP6_PARAM_PROB,
+ icmp6_error(*mp, ICMP6_PARAM_PROB,
ICMP6_PARAMPROB_HEADER,
erroff + opt - opthead);
return (-1);
*/
if (*plenp != 0) {
ip6stat_inc(ip6s_badoptions);
- icmp6_error(m, ICMP6_PARAM_PROB,
+ icmp6_error(*mp, ICMP6_PARAM_PROB,
ICMP6_PARAMPROB_HEADER,
erroff + opt + 2 - opthead);
return (-1);
*/
if (jumboplen <= IPV6_MAXPACKET) {
ip6stat_inc(ip6s_badoptions);
- icmp6_error(m, ICMP6_PARAM_PROB,
+ icmp6_error(*mp, ICMP6_PARAM_PROB,
ICMP6_PARAMPROB_HEADER,
erroff + opt + 2 - opthead);
return (-1);
ip6stat_inc(ip6s_toosmall);
goto bad;
}
- optlen = ip6_unknown_opt(opt, m,
+ optlen = ip6_unknown_opt(mp, opt,
erroff + opt - opthead);
if (optlen == -1)
return (-1);
return (0);
bad:
- m_freem(m);
+ m_freemp(mp);
return (-1);
}
* The third argument `off' is the offset from the IPv6 header to the option,
* which allows returning an ICMPv6 error even if the IPv6 header and the
* option header are not continuous.
+ * On error free mbuf and return -1.
*/
int
-ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off)
+ip6_unknown_opt(struct mbuf **mp, u_int8_t *optp, int off)
{
struct ip6_hdr *ip6;
case IP6OPT_TYPE_SKIP: /* ignore the option */
return ((int)*(optp + 1));
case IP6OPT_TYPE_DISCARD: /* silently discard */
- m_freem(m);
+ m_freemp(mp);
return (-1);
case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */
ip6stat_inc(ip6s_badoptions);
- icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off);
+ icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off);
return (-1);
case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */
ip6stat_inc(ip6s_badoptions);
- ip6 = mtod(m, struct ip6_hdr *);
+ ip6 = mtod(*mp, struct ip6_hdr *);
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
- (m->m_flags & (M_BCAST|M_MCAST)))
- m_freem(m);
+ ((*mp)->m_flags & (M_BCAST|M_MCAST)))
+ m_freemp(mp);
else
- icmp6_error(m, ICMP6_PARAM_PROB,
+ icmp6_error(*mp, ICMP6_PARAM_PROB,
ICMP6_PARAMPROB_OPTION, off);
return (-1);
}
- m_freem(m); /* XXX: NOTREACHED */
+ m_freemp(mp); /* XXX: NOTREACHED */
return (-1);
}
-/* $OpenBSD: ip6_var.h,v 1.92 2022/05/05 13:57:41 claudio Exp $ */
+/* $OpenBSD: ip6_var.h,v 1.93 2022/06/29 22:45:24 bluhm Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
int ip6_input_if(struct mbuf **, int *, int, int, struct ifnet *);
void ip6_freepcbopts(struct ip6_pktopts *);
void ip6_freemoptions(struct ip6_moptions *);
-int ip6_unknown_opt(u_int8_t *, struct mbuf *, int);
+int ip6_unknown_opt(struct mbuf **, u_int8_t *, int);
int ip6_get_prevhdr(struct mbuf *, int);
int ip6_nexthdr(struct mbuf *, int, int, int *);
int ip6_lasthdr(struct mbuf *, int, int, int *);
int ip6_mforward(struct ip6_hdr *, struct ifnet *, struct mbuf *);
-int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *,
+int ip6_process_hopopts(struct mbuf **, u_int8_t *, int, u_int32_t *,
u_int32_t *);
void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **);
int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t);