-/* $OpenBSD: ip_input.c,v 1.373 2022/07/24 22:38:25 bluhm Exp $ */
+/* $OpenBSD: ip_input.c,v 1.374 2022/07/25 23:19:34 bluhm Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
int ip_dooptions(struct mbuf *, struct ifnet *);
int in_ouraddr(struct mbuf *, struct ifnet *, struct rtentry **);
+int ip_fragcheck(struct mbuf **, int *);
+struct mbuf * ip_reass(struct ipqent *, struct ipq *);
+void ip_freef(struct ipq *);
+void ip_flush(void);
+
static void ip_send_dispatch(void *);
static void ip_sendraw_dispatch(void *);
static struct task ipsend_task = TASK_INITIALIZER(ip_send_dispatch, &ipsend_mq);
int
ip_ours(struct mbuf **mp, int *offp, int nxt, int af)
{
+ nxt = ip_fragcheck(mp, offp);
+ if (nxt == IPPROTO_DONE)
+ return IPPROTO_DONE;
+
/* We are already in a IPv4/IPv6 local deliver loop. */
if (af != AF_UNSPEC)
return ip_local(mp, offp, nxt, af);
int
ip_local(struct mbuf **mp, int *offp, int nxt, int af)
{
- struct mbuf *m = *mp;
- struct ip *ip = mtod(m, struct ip *);
+ struct ip *ip;
+
+ ip = mtod(*mp, struct ip *);
+ *offp = ip->ip_hl << 2;
+ nxt = ip->ip_p;
+
+ /* Check whether we are already in a IPv4/IPv6 local deliver loop. */
+ if (af == AF_UNSPEC)
+ nxt = ip_deliver(mp, offp, nxt, AF_INET);
+ return nxt;
+}
+
+int
+ip_fragcheck(struct mbuf **mp, int *offp)
+{
+ struct ip *ip;
struct ipq *fp;
struct ipqent *ipqe;
int mff, hlen;
+ ip = mtod(*mp, struct ip *);
hlen = ip->ip_hl << 2;
/*
* but it's not worth the time; just let them time out.)
*/
if (ip->ip_off &~ htons(IP_DF | IP_RF)) {
- if (m->m_flags & M_EXT) { /* XXX */
- if ((m = *mp = m_pullup(m, hlen)) == NULL) {
+ if ((*mp)->m_flags & M_EXT) { /* XXX */
+ if ((*mp = m_pullup(*mp, hlen)) == NULL) {
ipstat_inc(ips_toosmall);
return IPPROTO_DONE;
}
- ip = mtod(m, struct ip *);
+ ip = mtod(*mp, struct ip *);
}
mtx_enter(&ipq_mutex);
}
ip_frags++;
ipqe->ipqe_mff = mff;
- ipqe->ipqe_m = m;
+ ipqe->ipqe_m = *mp;
ipqe->ipqe_ip = ip;
- m = *mp = ip_reass(ipqe, fp);
- if (m == NULL)
+ *mp = ip_reass(ipqe, fp);
+ if (*mp == NULL)
goto bad;
ipstat_inc(ips_reassembled);
- ip = mtod(m, struct ip *);
+ ip = mtod(*mp, struct ip *);
hlen = ip->ip_hl << 2;
ip->ip_len = htons(ntohs(ip->ip_len) + hlen);
- } else
- if (fp)
+ } else {
+ if (fp != NULL)
ip_freef(fp);
+ }
mtx_leave(&ipq_mutex);
}
*offp = hlen;
- nxt = ip->ip_p;
- /* Check whether we are already in a IPv4/IPv6 local deliver loop. */
- if (af == AF_UNSPEC)
- nxt = ip_deliver(mp, offp, nxt, AF_INET);
- return nxt;
+ return ip->ip_p;
+
bad:
mtx_leave(&ipq_mutex);
m_freemp(mp);
-/* $OpenBSD: ip_var.h,v 1.93 2022/05/05 13:57:40 claudio Exp $ */
+/* $OpenBSD: ip_var.h,v 1.94 2022/07/25 23:19:34 bluhm Exp $ */
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
/*
struct inpcb;
int ip_ctloutput(int, struct socket *, int, int, struct mbuf *);
-void ip_flush(void);
int ip_fragment(struct mbuf *, struct mbuf_list *, struct ifnet *, u_long);
-void ip_freef(struct ipq *);
void ip_freemoptions(struct ip_moptions *);
int ip_getmoptions(int, struct ip_moptions *, struct mbuf *);
void ip_init(void);
int ip_optcopy(struct ip *, struct ip *);
int ip_output(struct mbuf *, struct mbuf *, struct route *, int,
struct ip_moptions *, struct inpcb *, u_int32_t);
-struct mbuf *
- ip_reass(struct ipqent *, struct ipq *);
u_int16_t
ip_randomid(void);
void ip_send(struct mbuf *);