int ipfr_knownfrag(ip, fin) ip_t *ip; fr_info_t *fin;
ipfr_knownfrag(ip, fin) ip_t *ip; fr_info_t *fin;
int ipfr_knownfrag(ip, fin)ip_t *ip;fr_info_t *fin;{	ipfr_t	*f, frag;	u_int	idx;	int	ret;	/*	 * For fragments, we record protocol, packet id, TOS and both IP#'s	 * (these should all be the same for all fragments of a packet).	 */	frag.ipfr_p = ip->ip_p;	idx = ip->ip_p;	frag.ipfr_id = ip->ip_id;	idx += ip->ip_id;	frag.ipfr_tos = ip->ip_tos;	frag.ipfr_src.s_addr = ip->ip_src.s_addr;	idx += ip->ip_src.s_addr;	frag.ipfr_dst.s_addr = ip->ip_dst.s_addr;	idx += ip->ip_dst.s_addr;	idx *= 127;	idx %= IPFT_SIZE;	MUTEX_ENTER(&ipf_frag);	for (f = ipfr_heads[idx]; f; f = f->ipfr_next)		if (!bcmp((char *)&frag.ipfr_src, (char *)&f->ipfr_src,			  IPFR_CMPSZ)) {			u_short	atoff, off;			if (f != ipfr_heads[idx]) {				/*				 * move fragment info. to the top of the list				 * to speed up searches.				 */				if ((f->ipfr_prev->ipfr_next = f->ipfr_next))					f->ipfr_next->ipfr_prev = f->ipfr_prev;				f->ipfr_next = ipfr_heads[idx];				ipfr_heads[idx]->ipfr_prev = f;				f->ipfr_prev = NULL;				ipfr_heads[idx] = f;			}			ret = f->ipfr_pass;			off = ip->ip_off;			atoff = (off & 0x1fff) - (fin->fin_dlen >> 3);			/*			 * If we've follwed the fragments, and this is the			 * last (in order), shrink expiration time.			 */			if (atoff == f->ipfr_off) {				if (!(off & IP_MF))					f->ipfr_ttl = 1;				else					f->ipfr_off = off;			}			ipfr_stats.ifs_hits++;			MUTEX_EXIT(&ipf_frag);			return ret;		}	MUTEX_EXIT(&ipf_frag);	return 0;}