void ip_natin(ip, hlen, fin) ip_t *ip; int hlen; fr_info_t *fin;
ip_natin(ip, hlen, fin) ip_t *ip; int hlen; fr_info_t *fin;
void ip_natin(ip, hlen, fin)ip_t *ip;int hlen;fr_info_t *fin;{	register ipnat_t *np;	register struct in_addr in;	register u_long sum1;	struct ifnet *ifp = fin->fin_ifp;	tcphdr_t *tcp;	u_short port = 0, nflags;	nat_t *nat;	if (!(ip->ip_off & 0x1fff) && !(fin->fin_fi.fi_fl & FI_SHORT)) {		if (ip->ip_p == IPPROTO_TCP)			nflags = IPN_TCP;		else if (ip->ip_p == IPPROTO_UDP)			nflags = IPN_UDP;	}	if (nflags) {		tcp = (tcphdr_t *)((char *)ip + hlen);		port = tcp->th_dport;	}	in = ip->ip_dst;	MUTEX_ENTER(&ipf_nat);	for (np = nat_list; np; np = np->in_next)		if ((np->in_ifp == ifp) &&		    (!np->in_flags || (nflags & np->in_flags)) &&		    ((in.s_addr & np->in_outmsk) == np->in_outip) &&		    (np->in_redir == NAT_MAP || np->in_pmin == port)) {			if (!(nat = nat_lookupoutip(np, ip, tcp))) {				if (np->in_redir == NAT_MAP)					continue;				else {					/*					 * If this rule (np) is a redirection,					 * rather than a mapping, then do a					 * nat_new. Otherwise, if it's just a					 * mapping, do a continue;					 */					nflags &= np->in_flags;					if (!(nat = nat_new(np, ip, hlen,							    nflags,							    NAT_INBOUND)))						break;				}			}			nat->nat_age = 1200;			ip->ip_dst = nat->nat_inip;			/*			 * Fix up checksums, not by recalculating them, but			 * simply computing adjustments.			 */			if (nflags && !(ip->ip_off & 0x1fff) &&			    !(fin->fin_fi.fi_fl & FI_SHORT)) {				u_short	*sp;				u_short sumshort;				if (nat->nat_inport)					tcp->th_dport = nat->nat_inport;				if (ip->ip_p == IPPROTO_TCP) {					sp = &tcp->th_sum;					sum1 = (~ntohs(*sp)) & 0xffff;					sum1 += ~nat->nat_sumd & 0xffff;					sum1 = (sum1 >> 16) + (sum1 & 0xffff);					/* Again */					sum1 = (sum1 >> 16) + (sum1 & 0xffff);					sumshort = ~(u_short)sum1;					*sp = htons(sumshort);				} else if (ip->ip_p == IPPROTO_UDP) {					udphdr_t *udp = (udphdr_t *)tcp;					sp = &udp->uh_sum;					if (udp->uh_sum) {						sum1 = (~ntohs(*sp)) & 0xffff;						sum1+= ~nat->nat_sumd & 0xffff;						sum1 = (sum1 >> 16) +						       (sum1 & 0xffff);						/* Again */						sum1 = (sum1 >> 16) +						       (sum1 & 0xffff);						sumshort = ~(u_short)sum1;						*sp = htons(sumshort);					}				}			}			nat_stats.ns_mapped[0]++;			MUTEX_EXIT(&ipf_nat);			return;		}	MUTEX_EXIT(&ipf_nat);	return;}