int fr_addstate(ip, fin, pass) ip_t *ip; fr_info_t *fin; u_int pass;
fr_addstate(ip, fin, pass) ip_t *ip; fr_info_t *fin; u_int pass;
int fr_addstate(ip, fin, pass)ip_t *ip;fr_info_t *fin;u_int pass;{	ipstate_t ips;	register ipstate_t *is = &ips;	register u_int hv;	if (ips_num == IPSTATE_MAX) {		ips_stats.iss_max++;		return -1;	}	/*	 * Copy and calculate...	 */	hv = (is->is_p = ip->ip_p);	hv += (is->is_src.s_addr = ip->ip_src.s_addr);	hv += (is->is_dst.s_addr = ip->ip_dst.s_addr);	switch (ip->ip_p)	{	case IPPROTO_ICMP :	    {		struct icmp *ic = (struct icmp *)fin->fin_dp;		switch (ic->icmp_type)		{		case ICMP_ECHO :			is->is_icmp.ics_type = 0;			hv += (is->is_icmp.ics_id = ic->icmp_id);			hv += (is->is_icmp.ics_seq = ic->icmp_seq);			break;		case ICMP_TSTAMP :		case ICMP_IREQ :		case ICMP_MASKREQ :			is->is_icmp.ics_type = ic->icmp_type + 1;			break;		default :			return -1;		}		ips_stats.iss_icmp++;		is->is_age = 120;		break;	    }	case IPPROTO_TCP :	    {		register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;		/*		 * The endian of the ports doesn't matter, but the ack and		 * sequence numbers do as we do mathematics on them later.		 */		hv += (is->is_dport = tcp->th_dport);		hv += (is->is_sport = tcp->th_sport);		is->is_seq = ntohl(tcp->th_seq);		is->is_ack = ntohl(tcp->th_ack);		is->is_win = ntohs(tcp->th_win);		ips_stats.iss_tcp++;		/*		 * If we're creating state for a starting connectoin, start the		 * timer on it as we'll never see an error if it fails to		 * connect.		 */		if ((tcp->th_flags & (TH_SYN|TH_ACK)) == TH_SYN)			is->is_age = 120;		else			is->is_age = 0;		break;	    }	case IPPROTO_UDP :	    {		register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;		hv += (is->is_dport = tcp->th_dport);		hv += (is->is_sport = tcp->th_sport);		ips_stats.iss_udp++;		is->is_age = 120;		break;	    }	default :		return -1;	}	if (!(is = (ipstate_t *)KMALLOC(sizeof(*is)))) {		ips_stats.iss_nomem++;		return -1;	}	bcopy((char *)&ips, (char *)is, sizeof(*is));	hv %= IPSTATE_SIZE;	MUTEX_ENTER(&ipf_state);	is->is_next = ips_table[hv];	ips_table[hv] = is;	is->is_pass = pass;	if (pass & FR_LOGFIRST)		is->is_pass &= ~(FR_LOGFIRST|FR_LOG);	ips_num++;	MUTEX_EXIT(&ipf_state);	return 0;}