Example #1
0
/*
 * Modify the packet so that it includes the authentication data.
 * The mbuf passed must start with IPv4 header.
 *
 * assumes that the first mbuf contains IPv4 header + option only.
 * the function does not modify m.
 */
int
ah4_output(struct mbuf *m, struct ipsecrequest *isr)
{
	struct secasvar *sav = isr->sav;
	const struct ah_algorithm *algo;
	u_int32_t spi;
	u_char *ahdrpos;
	u_int8_t *ahsumpos = NULL;
	size_t hlen = 0;	/* IP header+option in bytes */
	size_t plen = 0;	/* AH payload size in bytes */
	size_t ahlen = 0;	/* plen + sizeof(ah) */
	struct ip *ip;
	struct in_addr dst;
	struct in_addr *finaldst;
	int error;
	dst.s_addr = 0;		/* XXX: GCC */

	/* sanity checks */
	if ((sav->flags & SADB_X_EXT_OLD) == 0 && !sav->replay) {
		ip = mtod(m, struct ip *);
		ipseclog((LOG_DEBUG, "ah4_output: internal error: "
			"sav->replay is null: %x->%x, SPI=%u\n",
			(u_int32_t)ntohl(ip->ip_src.s_addr),
			(u_int32_t)ntohl(ip->ip_dst.s_addr),
			(u_int32_t)ntohl(sav->spi)));
		IPSEC_STATINC(IPSEC_STAT_OUT_INVAL);
		error = EINVAL;
		goto fail;
	}
Example #2
0
/*
 * Create a writable copy of the mbuf chain.  While doing this
 * we compact the chain with a goal of producing a chain with
 * at most two mbufs.  The second mbuf in this chain is likely
 * to be a cluster.  The primary purpose of this work is to create
 * a writable packet for encryption, compression, etc.  The
 * secondary goal is to linearize the data so the data can be
 * passed to crypto hardware in the most efficient manner possible.
 */
struct mbuf *
m_clone(struct mbuf *m0)
{
	struct mbuf *m, *mprev;
	struct mbuf *n, *mfirst, *mlast;
	int len, off;

	IPSEC_ASSERT(m0 != NULL, ("m_clone: null mbuf"));

	mprev = NULL;
	for (m = m0; m != NULL; m = mprev->m_next) {
		/*
		 * Regular mbufs are ignored unless there's a cluster
		 * in front of it that we can use to coalesce.  We do
		 * the latter mainly so later clusters can be coalesced
		 * also w/o having to handle them specially (i.e. convert
		 * mbuf+cluster -> cluster).  This optimization is heavily
		 * influenced by the assumption that we're running over
		 * Ethernet where MCLBYTES is large enough that the max
		 * packet size will permit lots of coalescing into a
		 * single cluster.  This in turn permits efficient
		 * crypto operations, especially when using hardware.
		 */
		if ((m->m_flags & M_EXT) == 0) {
			if (mprev && (mprev->m_flags & M_EXT) &&
			    m->m_len <= M_TRAILINGSPACE(mprev)) {
				/* XXX: this ignores mbuf types */
				memcpy(mtod(mprev, char *) + mprev->m_len,
				       mtod(m, char *), m->m_len);
				mprev->m_len += m->m_len;
				mprev->m_next = m->m_next;	/* unlink from chain */
				m_free(m);			/* reclaim mbuf */
				IPSEC_STATINC(IPSEC_STAT_MBCOALESCED);
			} else {
				mprev = m;
			}
			continue;
		}