void	fr_makefrip(hlen, ip, fin) int hlen; ip_t *ip; fr_info_t *fin;
fr_makefrip(hlen, ip, fin) int hlen; ip_t *ip; fr_info_t *fin;
void	fr_makefrip(hlen, ip, fin)int hlen;ip_t *ip;fr_info_t *fin;{	struct optlist *op;	tcphdr_t *tcp;	fr_ip_t *fi = &fin->fin_fi;	u_short optmsk = 0, secmsk = 0, auth = 0;	int i, mv, ol, off;	u_char *s, opt;	fin->fin_fr = NULL;	fin->fin_tcpf = 0;	fin->fin_data[0] = 0;	fin->fin_data[1] = 0;	fin->fin_rule = -1;#ifdef	_KERNEL	fin->fin_icode = ipl_unreach;#endif	fi->fi_v = ip->ip_v;	fi->fi_tos = ip->ip_tos;	fin->fin_hlen = hlen;	fin->fin_dlen = ip->ip_len - hlen;	tcp = (tcphdr_t *)((char *)ip + hlen);	fin->fin_dp = (void *)tcp;	(*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));	(*(((u_long *)fi) + 1)) = (*(((u_long *)ip) + 3));	(*(((u_long *)fi) + 2)) = (*(((u_long *)ip) + 4));	fi->fi_fl = (hlen > sizeof(struct ip)) ? FI_OPTIONS : 0;	off = (ip->ip_off & 0x1fff) << 3;	if (ip->ip_off & 0x3fff)		fi->fi_fl |= FI_FRAG;	switch (ip->ip_p)	{	case IPPROTO_ICMP :		if ((!IPMINLEN(ip, icmp) && !off) ||		    (off && off < sizeof(struct icmp)))			fi->fi_fl |= FI_SHORT;		if (fin->fin_dlen > 1)			fin->fin_data[0] = *(u_short *)tcp;		break;	case IPPROTO_TCP :		fi->fi_fl |= FI_TCPUDP;		if ((!IPMINLEN(ip, tcphdr) && !off) ||		    (off && off < sizeof(struct tcphdr)))			fi->fi_fl |= FI_SHORT;		if (!(fi->fi_fl & FI_SHORT) && !off)			fin->fin_tcpf = tcp->th_flags;		goto getports;	case IPPROTO_UDP :		fi->fi_fl |= FI_TCPUDP;		if ((!IPMINLEN(ip, udphdr) && !off) ||		    (off && off < sizeof(struct udphdr)))			fi->fi_fl |= FI_SHORT;getports:		if (!off && (fin->fin_dlen > 3)) {			fin->fin_data[0] = ntohs(tcp->th_sport);			fin->fin_data[1] = ntohs(tcp->th_dport);		}		break;	default :		break;	}	for (s = (u_char *)(ip + 1), hlen -= sizeof(*ip); hlen; ) {		if (!(opt = *s))			break;		ol = (opt == IPOPT_NOP) ? 1 : (int)*(s+1);		if (opt > 1 && (ol < 2 || ol > hlen))			break;		for (i = 9, mv = 4; mv >= 0; ) {			op = ipopts + i;			if (opt == (u_char)op->ol_val) {				optmsk |= op->ol_bit;				if (opt == IPOPT_SECURITY) {					struct optlist *sp;					u_char	sec;					int j, m;					sec = *(s + 2);	/* classification */					for (j = 3, m = 2; m >= 0; ) {						sp = secopt + j;						if (sec == sp->ol_val) {							secmsk |= sp->ol_bit;							auth = *(s + 3);							auth *= 256;							auth += *(s + 4);							break;						}						if (sec < sp->ol_val)							j -= m--;						else							j += m--;					}				}				break;			}			if (opt < op->ol_val)				i -= mv--;			else				i += mv--;		}		hlen -= ol;		s += ol;	}	if (auth && !(auth & 0x0100))		auth &= 0xff00;	fi->fi_optmsk = optmsk;	fi->fi_secmsk = secmsk;	fi->fi_auth = auth;}