head	1.2;
access;
symbols
	RELEASE_4_9_0:1.1;
locks; strict;
comment	@# @;


1.2
date	2003.09.28.13.27.06;	author edwin;	state dead;
branches;
next	1.1;

1.1
date	2003.08.29.03.14.03;	author edwin;	state Exp;
branches;
next	;


desc
@@


1.2
log
@Update port: security/pf - OpenBSD 3.4 pf

	Port update after API change in PFIL_HOOKS in -current and
	OpenBSD 3.4 Release.

PR:		 ports/57305
Submitted by:	Max Laier <max@@love2party.net>
@
text
@--- pf/pf_norm.c	Fri Aug 29 03:31:24 2003
+++ pf/pf_norm.c	Fri Aug 29 03:40:58 2003
@@@@ -117,10 +117,10 @@@@
 void			 pf_flush_fragments(void);
 void			 pf_free_fragment(struct pf_fragment *);
 struct pf_fragment	*pf_find_fragment(struct ip *, struct pf_frag_tree *);
-struct mbuf		*pf_reassemble(struct mbuf **, struct pf_fragment *,
+struct mbuf		*pf_reassemble(struct mbuf **, struct pf_fragment **,
 			    struct pf_frent *, int);
 struct mbuf		*pf_fragcache(struct mbuf **, struct ip*,
-			    struct pf_fragment *, int, int, int *);
+			    struct pf_fragment **, int, int, int *);
 u_int16_t		 pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t);
 int			 pf_normalize_tcp(int, struct ifnet *, struct mbuf *,
 			    int, int, void *, struct pf_pdesc *);
@@@@ -385,7 +385,7 @@@@
 }
 
 struct mbuf *
-pf_reassemble(struct mbuf **m0, struct pf_fragment *frag,
+pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
     struct pf_frent *frent, int mff)
 {
 	struct mbuf	*m = *m0, *m2;
@@@@ -397,10 +397,10 @@@@
 	u_int16_t	 max = ip->ip_len + off;
 
 #if defined(__FreeBSD__)
-	KASSERT((frag == NULL || BUFFER_FRAGMENTS(frag)),
-	    ("! (frag == NULL || BUFFER_FRAGMENTS(frag)): %s", __FUNCTION__));
+	KASSERT((*frag == NULL || BUFFER_FRAGMENTS(*frag)),
+	    ("! (*frag == NULL || BUFFER_FRAGMENTS(*frag)): %s", __FUNCTION__));
 #else
-	KASSERT(frag == NULL || BUFFER_FRAGMENTS(frag));
+	KASSERT(*frag == NULL || BUFFER_FRAGMENTS(*frag));
 #endif
 
 	/* Strip off ip header */
@@@@ -408,38 +408,38 @@@@
 	m->m_len -= hlen;
 
 	/* Create a new reassembly queue for this packet */
-	if (frag == NULL) {
+	if (*frag == NULL) {
 #if defined(__FreeBSD__)
-		frag = uma_zalloc(pf_frag_pl, M_NOWAIT);
+		*frag = uma_zalloc(pf_frag_pl, M_NOWAIT);
 #else
-		frag = pool_get(&pf_frag_pl, PR_NOWAIT);
+		*frag = pool_get(&pf_frag_pl, PR_NOWAIT);
 #endif
-		if (frag == NULL) {
+		if (*frag == NULL) {
 			pf_flush_fragments();
 #if defined(__FreeBSD__)
-			frag = uma_zalloc(pf_frag_pl, M_NOWAIT);
+			*frag = uma_zalloc(pf_frag_pl, M_NOWAIT);
 #else
-			frag = pool_get(&pf_frag_pl, PR_NOWAIT);
+			*frag = pool_get(&pf_frag_pl, PR_NOWAIT);
 #endif
-			if (frag == NULL)
+			if (*frag == NULL)
 				goto drop_fragment;
 		}
 
-		frag->fr_flags = 0;
-		frag->fr_max = 0;
-		frag->fr_src = frent->fr_ip->ip_src;
-		frag->fr_dst = frent->fr_ip->ip_dst;
-		frag->fr_p = frent->fr_ip->ip_p;
-		frag->fr_id = frent->fr_ip->ip_id;
+		(*frag)->fr_flags = 0;
+		(*frag)->fr_max = 0;
+		(*frag)->fr_src = frent->fr_ip->ip_src;
+		(*frag)->fr_dst = frent->fr_ip->ip_dst;
+		(*frag)->fr_p = frent->fr_ip->ip_p;
+		(*frag)->fr_id = frent->fr_ip->ip_id;
 #if defined(__FreeBSD__)
-		frag->fr_timeout = time_second;
+		(*frag)->fr_timeout = time_second;
 #else
-		frag->fr_timeout = time.tv_sec;
+		(*frag)->fr_timeout = time.tv_sec;
 #endif
-		LIST_INIT(&frag->fr_queue);
+		LIST_INIT(&(*frag)->fr_queue);
 
-		RB_INSERT(pf_frag_tree, &pf_frag_tree, frag);
-		TAILQ_INSERT_HEAD(&pf_fragqueue, frag, frag_next);
+		RB_INSERT(pf_frag_tree, &pf_frag_tree, *frag);
+		TAILQ_INSERT_HEAD(&pf_fragqueue, *frag, frag_next);
 
 		/* We do not have a previous fragment */
 		frep = NULL;
@@@@ -450,7 +450,7 @@@@
 	 * Find a fragment after the current one:
 	 *  - off contains the real shifted offset.
 	 */
-	LIST_FOREACH(frea, &frag->fr_queue, fr_next) {
+	LIST_FOREACH(frea, &(*frag)->fr_queue, fr_next) {
 		if (frea->fr_ip->ip_off > off)
 			break;
 		frep = frea;
@@@@ -503,41 +503,41 @@@@
 
  insert:
 	/* Update maximum data size */
-	if (frag->fr_max < max)
-		frag->fr_max = max;
+	if ((*frag)->fr_max < max)
+		(*frag)->fr_max = max;
 	/* This is the last segment */
 	if (!mff)
-		frag->fr_flags |= PFFRAG_SEENLAST;
+		(*frag)->fr_flags |= PFFRAG_SEENLAST;
 
 	if (frep == NULL)
-		LIST_INSERT_HEAD(&frag->fr_queue, frent, fr_next);
+		LIST_INSERT_HEAD(&(*frag)->fr_queue, frent, fr_next);
 	else
 		LIST_INSERT_AFTER(frep, frent, fr_next);
 
 	/* Check if we are completely reassembled */
-	if (!(frag->fr_flags & PFFRAG_SEENLAST))
+	if (!((*frag)->fr_flags & PFFRAG_SEENLAST))
 		return (NULL);
 
 	/* Check if we have all the data */
 	off = 0;
-	for (frep = LIST_FIRST(&frag->fr_queue); frep; frep = next) {
+	for (frep = LIST_FIRST(&(*frag)->fr_queue); frep; frep = next) {
 		next = LIST_NEXT(frep, fr_next);
 
 		off += frep->fr_ip->ip_len;
-		if (off < frag->fr_max &&
+		if (off < (*frag)->fr_max &&
 		    (next == NULL || next->fr_ip->ip_off != off)) {
 			DPFPRINTF(("missing fragment at %d, next %d, max %d\n",
 			    off, next == NULL ? -1 : next->fr_ip->ip_off,
-			    frag->fr_max));
+			    (*frag)->fr_max));
 			return (NULL);
 		}
 	}
-	DPFPRINTF(("%d < %d?\n", off, frag->fr_max));
-	if (off < frag->fr_max)
+	DPFPRINTF(("%d < %d?\n", off, (*frag)->fr_max));
+	if (off < (*frag)->fr_max)
 		return (NULL);
 
 	/* We have all the data */
-	frent = LIST_FIRST(&frag->fr_queue);
+	frent = LIST_FIRST(&(*frag)->fr_queue);
 #if defined(__FreeBSD__)
 	KASSERT((frent != NULL), ("frent == NULL: %s", __FUNCTION__));
 #else
@@@@ -545,7 +545,8 @@@@
 #endif
 	if ((frent->fr_ip->ip_hl << 2) + off > IP_MAXPACKET) {
 		DPFPRINTF(("drop: too big: %d\n", off));
-		pf_free_fragment(frag);
+		pf_free_fragment(*frag);
+		*frag = NULL;
 		return (NULL);
 	}
 	next = LIST_NEXT(frent, fr_next);
@@@@ -575,11 +576,12 @@@@
 		m_cat(m, m2);
 	}
 
-	ip->ip_src = frag->fr_src;
-	ip->ip_dst = frag->fr_dst;
+	ip->ip_src = (*frag)->fr_src;
+	ip->ip_dst = (*frag)->fr_dst;
 
 	/* Remove from fragment queue */
-	pf_remove_fragment(frag);
+	pf_remove_fragment(*frag);
+	*frag = NULL;
 
 	hlen = ip->ip_hl << 2;
 	ip->ip_len = off + hlen;
@@@@ -611,7 +613,7 @@@@
 }
 
 struct mbuf *
-pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment *frag, int mff,
+pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
     int drop, int *nomem)
 {
 	struct mbuf		*m = *m0;
@@@@ -622,27 +624,27 @@@@
 	int			 hosed = 0;
 
 #if defined(__FreeBSD__)
-	KASSERT((frag == NULL || !BUFFER_FRAGMENTS(frag)),
-	    ("!(frag == NULL || !BUFFER_FRAGMENTS(frag)): %s", __FUNCTION__));
+	KASSERT((*frag == NULL || !BUFFER_FRAGMENTS(*frag)),
+	    ("!(*frag == NULL || !BUFFER_FRAGMENTS(*frag)): %s", __FUNCTION__));
 #else
-	KASSERT(frag == NULL || !BUFFER_FRAGMENTS(frag));
+	KASSERT(*frag == NULL || !BUFFER_FRAGMENTS(*frag));
 #endif
 
 	/* Create a new range queue for this packet */
-	if (frag == NULL) {
+	if (*frag == NULL) {
 #if defined(__FreeBSD__)
-		frag = uma_zalloc(pf_cache_pl, M_NOWAIT);
+		*frag = uma_zalloc(pf_cache_pl, M_NOWAIT);
 #else
-		frag = pool_get(&pf_cache_pl, PR_NOWAIT);
+		*frag = pool_get(&pf_cache_pl, PR_NOWAIT);
 #endif
-		if (frag == NULL) {
+		if (*frag == NULL) {
 			pf_flush_fragments();
 #if defined(__FreeBSD__)
-			frag = uma_zalloc(pf_cache_pl, M_NOWAIT);
+			*frag = uma_zalloc(pf_cache_pl, M_NOWAIT);
 #else
-			frag = pool_get(&pf_cache_pl, PR_NOWAIT);
+			*frag = pool_get(&pf_cache_pl, PR_NOWAIT);
 #endif
-			if (frag == NULL)
+			if (*frag == NULL)
 				goto no_mem;
 		}
 
@@@@ -654,33 +656,34 @@@@
 #endif
 		if (cur == NULL) {
 #if defined(__FreeBSD__)
-			uma_zfree(pf_cache_pl, frag);
+			uma_zfree(pf_cache_pl, *frag);
 #else
-			pool_put(&pf_cache_pl, frag);
+			pool_put(&pf_cache_pl, *frag);
 #endif
+			*frag = NULL;
 			goto no_mem;
 		}
 		pf_ncache++;
 
-		frag->fr_flags = PFFRAG_NOBUFFER;
-		frag->fr_max = 0;
-		frag->fr_src = h->ip_src;
-		frag->fr_dst = h->ip_dst;
-		frag->fr_p = h->ip_p;
-		frag->fr_id = h->ip_id;
+		(*frag)->fr_flags = PFFRAG_NOBUFFER;
+		(*frag)->fr_max = 0;
+		(*frag)->fr_src = h->ip_src;
+		(*frag)->fr_dst = h->ip_dst;
+		(*frag)->fr_p = h->ip_p;
+		(*frag)->fr_id = h->ip_id;
 #if defined(__FreeBSD__)
-		frag->fr_timeout = time_second;
+		(*frag)->fr_timeout = time_second;
 #else
-		frag->fr_timeout = time.tv_sec;
+		(*frag)->fr_timeout = time.tv_sec;
 #endif
 
 		cur->fr_off = off;
 		cur->fr_end = max;
-		LIST_INIT(&frag->fr_cache);
-		LIST_INSERT_HEAD(&frag->fr_cache, cur, fr_next);
+		LIST_INIT(&(*frag)->fr_cache);
+		LIST_INSERT_HEAD(&(*frag)->fr_cache, cur, fr_next);
 
-		RB_INSERT(pf_frag_tree, &pf_cache_tree, frag);
-		TAILQ_INSERT_HEAD(&pf_cachequeue, frag, frag_next);
+		RB_INSERT(pf_frag_tree, &pf_cache_tree, *frag);
+		TAILQ_INSERT_HEAD(&pf_cachequeue, *frag, frag_next);
 
 		DPFPRINTF(("fragcache[%d]: new %d-%d\n", h->ip_id, off, max));
 
@@@@ -692,7 +695,7 @@@@
 	 *  - off contains the real shifted offset.
 	 */
 	frp = NULL;
-	LIST_FOREACH(fra, &frag->fr_cache, fr_next) {
+	LIST_FOREACH(fra, &(*frag)->fr_cache, fr_next) {
 		if (fra->fr_off > off)
 			break;
 		frp = fra;
@@@@ -929,21 +932,22 @@@@
 
  pass:
 	/* Update maximum data size */
-	if (frag->fr_max < max)
-		frag->fr_max = max;
+	if ((*frag)->fr_max < max)
+		(*frag)->fr_max = max;
 
 	/* This is the last segment */
 	if (!mff)
-		frag->fr_flags |= PFFRAG_SEENLAST;
+		(*frag)->fr_flags |= PFFRAG_SEENLAST;
 
 	/* Check if we are completely reassembled */
-	if ((frag->fr_flags & PFFRAG_SEENLAST) &&
-	    LIST_FIRST(&frag->fr_cache)->fr_off == 0 &&
-	    LIST_FIRST(&frag->fr_cache)->fr_end == frag->fr_max) {
+	if (((*frag)->fr_flags & PFFRAG_SEENLAST) &&
+	    LIST_FIRST(&(*frag)->fr_cache)->fr_off == 0 &&
+	    LIST_FIRST(&(*frag)->fr_cache)->fr_end == (*frag)->fr_max) {
 		/* Remove from fragment queue */
 		DPFPRINTF(("fragcache[%d]: done 0-%d\n", h->ip_id,
-		    frag->fr_max));
-		pf_free_fragment(frag);
+		    (*frag)->fr_max));
+		pf_free_fragment(*frag);
+		*frag = NULL;
 	}
 
 	return (m);
@@@@ -952,8 +956,8 @@@@
 	*nomem = 1;
 
 	/* Still need to pay attention to !IP_MF */
-	if (!mff && frag)
-		frag->fr_flags |= PFFRAG_SEENLAST;
+	if (!mff && *frag != NULL)
+		(*frag)->fr_flags |= PFFRAG_SEENLAST;
 
 	m_freem(m);
 	return (NULL);
@@@@ -961,15 +965,15 @@@@
  drop_fragment:
 
 	/* Still need to pay attention to !IP_MF */
-	if (!mff && frag)
-		frag->fr_flags |= PFFRAG_SEENLAST;
+	if (!mff && *frag != NULL)
+		(*frag)->fr_flags |= PFFRAG_SEENLAST;
 
 	if (drop) {
 		/* This fragment has been deemed bad.  Don't reass */
-		if ((frag->fr_flags & PFFRAG_DROP) == 0)
+		if (((*frag)->fr_flags & PFFRAG_DROP) == 0)
 			DPFPRINTF(("fragcache[%d]: dropping overall fragment\n",
 			    h->ip_id));
-		frag->fr_flags |= PFFRAG_DROP;
+		(*frag)->fr_flags |= PFFRAG_DROP;
 	}
 
 	m_freem(m);
@@@@ -1085,12 +1089,12 @@@@
 
 		/* Might return a completely reassembled mbuf, or NULL */
 		DPFPRINTF(("reass frag %d @@ %d-%d\n", h->ip_id, fragoff, max));
-		*m0 = m = pf_reassemble(m0, frag, frent, mff);
+		*m0 = m = pf_reassemble(m0, &frag, frent, mff);
 
 		if (m == NULL)
 			return (PF_DROP);
 
-		if (frag && (frag->fr_flags & PFFRAG_DROP))
+		if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
 			goto drop;
 
 		h = mtod(m, struct ip *);
@@@@ -1119,7 +1123,7 @@@@
 			goto bad;
 		}
 
-		*m0 = m = pf_fragcache(m0, h, frag, mff,
+		*m0 = m = pf_fragcache(m0, h, &frag, mff,
 		    (r->rule_flag & PFRULE_FRAGDROP) ? 1 : 0, &nomem);
 		if (m == NULL) {
 			if (nomem)
@@@@ -1135,7 +1139,7 @@@@
 				goto no_mem;
 			m_tag_prepend(m, mtag);
 		}
-		if (frag && (frag->fr_flags & PFFRAG_DROP))
+		if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
 			goto drop;
 		goto fragment_pass;
 	}
@


1.1
log
@FIXUP for possible remote DoS w/ scrub rules
http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_norm.c?sortby=date

PR:		-
Submitted by:	mlaier@@#bsdcode
Obtained from:	OpenBSD-Current
@
text
@@

