pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
ah_old_input(struct mbuf *m, struct tdb *tdb){    struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform;    struct ip *ip, ipo;    struct ah_old *ah, *aho;    int ohlen, len, count, off, alen;    struct mbuf *m0;    union {	 MD5_CTX md5ctx; 	 SHA1_CTX sha1ctx;    } ctx;    u_int8_t optval;    u_char buffer[40];    aho = (struct ah_old *) buffer;    alen = ahx->hashsize;    ohlen = sizeof(struct ip) + AH_OLD_FLENGTH + alen;    if (m->m_len < ohlen)    {	if ((m = m_pullup(m, ohlen)) == NULL)	{	    DPRINTF(("ah_old_input(): m_pullup() failed\n"));	    ahstat.ahs_hdrops++;	    return NULL;	}    }    ip = mtod(m, struct ip *);    if ((ip->ip_hl << 2) > sizeof(struct ip))    {	if ((m = m_pullup(m, ohlen - sizeof (struct ip) +			  (ip->ip_hl << 2))) == NULL)	{	    DPRINTF(("ah_old_input(): m_pullup() failed\n"));	    ahstat.ahs_hdrops++;	    return NULL;	}		ip = mtod(m, struct ip *);	ah = (struct ah_old *)((u_int8_t *) ip + (ip->ip_hl << 2));	ohlen += ((ip->ip_hl << 2) - sizeof(struct ip));    }    else      ah = (struct ah_old *) (ip + 1);    /* Update the counters */    tdb->tdb_cur_bytes += ip->ip_len - (ip->ip_hl << 2);    ahstat.ahs_ibytes += ip->ip_len - (ip->ip_hl << 2);    /* Hard expiration */    if ((tdb->tdb_flags & TDBF_BYTES) &&	(tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes))      {/* XXX   encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL);*/	  m_freem(m);	  tdb_delete(tdb, 0);	  return NULL;      }    /* Notify on expiration */    if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&	(tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes))      {/* XXX   encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL);*/	  tdb->tdb_flags &= ~TDBF_SOFT_BYTES;   /* Turn off checking */      }    ipo = *ip;    ipo.ip_tos = 0;    ipo.ip_len += (ip->ip_hl << 2);	/* adjusted in ip_intr() */    HTONS(ipo.ip_len);    HTONS(ipo.ip_id);    ipo.ip_off = htons(ipo.ip_off & IP_DF);	/* XXX -- and the C bit? */    ipo.ip_ttl = 0;    ipo.ip_sum = 0;    bcopy(tdb->tdb_ictx, &ctx, ahx->ctxsize);    ahx->Update(&ctx, (unsigned char *) &ipo, sizeof(struct ip));    /* Options */    if ((ip->ip_hl << 2) > sizeof(struct ip))      for (off = sizeof(struct ip); off < (ip->ip_hl << 2);)      {	  optval = ((u_int8_t *) ip)[off];	  switch (optval)	  {	      case IPOPT_EOL:		  ahx->Update(&ctx, ipseczeroes, 1);		  off = ip->ip_hl << 2;		  break;	      case IPOPT_NOP:		  ahx->Update(&ctx, ipseczeroes, 1);		  off++;		  break;	      case IPOPT_SECURITY:	      case 133:	      case 134:		  optval = ((u_int8_t *) ip)[off + 1];		  ahx->Update(&ctx, (u_int8_t *) ip + off, optval);		  off += optval;		  break;	      default:		  optval = ((u_int8_t *) ip)[off + 1];		  ahx->Update(&ctx, ipseczeroes, optval);		  off += optval;		  break;	  }      }            ahx->Update(&ctx, (unsigned char *) ah, AH_OLD_FLENGTH);    ahx->Update(&ctx, ipseczeroes, alen);    /*     * Code shamelessly stolen from m_copydata     */    off = ohlen;    len = m->m_pkthdr.len - off;    m0 = m;	    while (off > 0)    {	if (m0 == 0)	{	    DPRINTF(("ah_old_input(): bad mbuf chain for packet from %s to %s, spi %08x\n", inet_ntoa4(ipo.ip_src), inet_ntoa4(ipo.ip_dst), ntohl(tdb->tdb_spi)));	    ahstat.ahs_hdrops++;	    m_freem(m);	    return NULL;	}	if (off < m0->m_len)	  break;	off -= m0->m_len;	m0 = m0->m_next;    }    while (len > 0)    {	if (m0 == 0)	{	    DPRINTF(("ah_old_input(): bad mbuf chain for packet from %s to %s, spi %08x\n", inet_ntoa4(ipo.ip_src), inet_ntoa4(ipo.ip_dst), ntohl(tdb->tdb_spi)));	    ahstat.ahs_hdrops++;	    m_freem(m);	    return NULL;	}		count = min(m0->m_len - off, len);	ahx->Update(&ctx, mtod(m0, unsigned char *) + off, count);	len -= count;	off = 0;	m0 = m0->m_next;    }    ahx->Update(&ctx, (unsigned char *) tdb->tdb_amxkey, tdb->tdb_amxkeylen);    ahx->Final((unsigned char *) (aho->ah_data), &ctx);    if (bcmp(aho->ah_data, ah->ah_data, alen))    {	ahstat.ahs_badauth++;	m_freem(m);	return NULL;    }	    ipo = *ip;    ipo.ip_p = ah->ah_nh;    /* Save options */    m_copydata(m, sizeof(struct ip), (ip->ip_hl << 2) - sizeof(struct ip),	       (caddr_t) buffer);    m->m_len -= (AH_OLD_FLENGTH + alen);    m->m_data += (AH_OLD_FLENGTH + alen);    m->m_pkthdr.len -= (AH_OLD_FLENGTH + alen);    ip = mtod(m, struct ip *);    *ip = ipo;    ip->ip_len = htons(ip->ip_len - AH_OLD_FLENGTH - alen + (ip->ip_hl << 2));    HTONS(ip->ip_id);    HTONS(ip->ip_off);    ip->ip_sum = 0;    /* Copy the options back */    m_copyback(m, sizeof(struct ip), (ip->ip_hl << 2) - sizeof(struct ip),	       (caddr_t) buffer);    ip->ip_sum = in_cksum(m, (ip->ip_hl << 2));    return m;}