src/sys/netipsec/key.c
/* m will not be freed nor modified */
m will not be freed nor modified
m will not be freed nor modified
static struct mbuf *
key_gather_mbuf(struct mbuf *m, const struct sadb_msghdr *mhp,
    int ndeep, int nitem, ...)
{
	va_list ap;
	int idx;
	int i;
	struct mbuf *result = NULL, *n;
	int len;
	IPSEC_ASSERT(m != NULL, ("null mbuf"));
	IPSEC_ASSERT(mhp != NULL, ("null msghdr"));
	va_start(ap, nitem);
	for (i = 0; i < nitem; i++) {
		idx = va_arg(ap, int);
		if (idx < 0 || idx > SADB_EXT_MAX)
			goto fail;
		if (idx == SADB_EXT_RESERVED && mhp->msg == NULL)
			continue;
		if (idx != SADB_EXT_RESERVED  &&
		    (mhp->ext[idx] == NULL || mhp->extlen[idx] == 0))
			continue;
		if (idx == SADB_EXT_RESERVED) {
			len = PFKEY_ALIGN8(sizeof(struct sadb_msg));
			IPSEC_ASSERT(len <= MHLEN, ("header too big %u", len));
			MGETHDR(n, M_NOWAIT, MT_DATA);
			if (!n)
				goto fail;
			n->m_len = len;
			n->m_next = NULL;
			m_copydata(m, 0, sizeof(struct sadb_msg),
			    mtod(n, caddr_t));
		} else if (i < ndeep) {
			len = mhp->extlen[idx];
			n = m_get2(len, M_NOWAIT, MT_DATA, 0);
			if (n == NULL)
				goto fail;
			m_align(n, len);
			n->m_len = len;
			m_copydata(m, mhp->extoff[idx], mhp->extlen[idx],
			    mtod(n, caddr_t));
		} else {
			n = m_copym(m, mhp->extoff[idx], mhp->extlen[idx],
			    M_NOWAIT);
		}
		if (n == NULL)
			goto fail;
		if (result)
			m_cat(result, n);
		else
			result = n;
	}
	va_end(ap);
	if ((result->m_flags & M_PKTHDR) != 0) {
		result->m_pkthdr.len = 0;
		for (n = result; n; n = n->m_next)
			result->m_pkthdr.len += n->m_len;
	}
	return result;
fail:
	m_freem(result);
	va_end(ap);
	return NULL;
}
static struct mbuf * key_gather_mbuf ( struct mbuf * m , const struct sadb_msghdr * mhp , int ndeep , int nitem , ... ) { va_list ap ; int idx ; int i ; struct mbuf * result = NULL , * n ; int len ; IPSEC_ASSERT ( m != NULL , ( " " ) ) ; IPSEC_ASSERT ( mhp != NULL , ( " " ) ) ; va_start ( ap , nitem ) ; for ( i = 0 ; i < nitem ; i ++ ) { idx = va_arg ( ap , int ) ; if ( idx < 0 || idx > SADB_EXT_MAX ) goto fail ; if ( idx == SADB_EXT_RESERVED && mhp -> msg == NULL ) continue ; if ( idx != SADB_EXT_RESERVED && ( mhp -> ext [ idx ] == NULL || mhp -> extlen [ idx ] == 0 ) ) continue ; if ( idx == SADB_EXT_RESERVED ) { len = PFKEY_ALIGN8 ( sizeof ( struct sadb_msg ) ) ; IPSEC_ASSERT ( len <= MHLEN , ( " " , len ) ) ; MGETHDR ( n , M_NOWAIT , MT_DATA ) ; if ( ! n ) goto fail ; n -> m_len = len ; n -> m_next = NULL ; m_copydata ( m , 0 , sizeof ( struct sadb_msg ) , mtod ( n , caddr_t ) ) ; } else if ( i < ndeep ) { len = mhp -> extlen [ idx ] ; n = m_get2 ( len , M_NOWAIT , MT_DATA , 0 ) ; if ( n == NULL ) goto fail ; m_align ( n , len ) ; n -> m_len = len ; m_copydata ( m , mhp -> extoff [ idx ] , mhp -> extlen [ idx ] , mtod ( n , caddr_t ) ) ; } else { n = m_copym ( m , mhp -> extoff [ idx ] , mhp -> extlen [ idx ] , M_NOWAIT ) ; } if ( n == NULL ) goto fail ; if ( result ) m_cat ( result , n ) ; else result = n ; } va_end ( ap ) ; if ( ( result -> m_flags & M_PKTHDR ) != 0 ) { result -> m_pkthdr . len = 0 ; for ( n = result ; n ; n = n -> m_next ) result -> m_pkthdr . len += n -> m_len ; } return result ; fail : m_freem ( result ) ; va_end ( ap ) ; return NULL ; }
m will not be freed nor modified
m will not be freed nor modified
/* don't attempt to pull empty extension */