17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright 2001, QNX Software Systems Ltd. All Rights Reserved
3ab25eeb5Syz  *
47c478bd9Sstevel@tonic-gate  * This source code has been published by QNX Software Systems Ltd. (QSSL).
57c478bd9Sstevel@tonic-gate  * However, any use, reproduction, modification, distribution or transfer of
67c478bd9Sstevel@tonic-gate  * this software, or any software which includes or is based upon any of this
77c478bd9Sstevel@tonic-gate  * code, is only permitted under the terms of the QNX Open Community License
87c478bd9Sstevel@tonic-gate  * version 1.0 (see licensing.qnx.com for details) or as otherwise expressly
97c478bd9Sstevel@tonic-gate  * authorized by a written license agreement from QSSL. For more information,
107c478bd9Sstevel@tonic-gate  * please email licensing@qnx.com.
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  * For more details, see QNX_OCL.txt provided with this distribution.
13f4b3ec61Sdh  *
14f4b3ec61Sdh  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
15f4b3ec61Sdh  * Use is subject to license terms.
167c478bd9Sstevel@tonic-gate  */
177c478bd9Sstevel@tonic-gate 
187c478bd9Sstevel@tonic-gate /*
197c478bd9Sstevel@tonic-gate  * Simple H.323 proxy
20ab25eeb5Syz  *
217c478bd9Sstevel@tonic-gate  *      by xtang@canada.com
227c478bd9Sstevel@tonic-gate  *	ported to ipfilter 3.4.20 by Michael Grant mg-ipf@grant.org
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 220000 && defined(_KERNEL)
267c478bd9Sstevel@tonic-gate # include <sys/fcntl.h>
277c478bd9Sstevel@tonic-gate # include <sys/filio.h>
287c478bd9Sstevel@tonic-gate #else
29ab25eeb5Syz # ifndef linux
30ab25eeb5Syz #  include <sys/ioctl.h>
31ab25eeb5Syz # endif
327c478bd9Sstevel@tonic-gate #endif
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #define IPF_H323_PROXY
357c478bd9Sstevel@tonic-gate 
36f4b3ec61Sdh typedef struct ifs_h323pxy {
37f4b3ec61Sdh 	frentry_t	h323_fr;
38f4b3ec61Sdh 	int		h323_proxy_init;
39f4b3ec61Sdh } ifs_h323pxy_t;
407c478bd9Sstevel@tonic-gate 
41f4b3ec61Sdh int  ippr_h323_init __P((void **, ipf_stack_t *));
42f4b3ec61Sdh void  ippr_h323_fini __P((void **, ipf_stack_t *));
43f4b3ec61Sdh int  ippr_h323_new __P((fr_info_t *, ap_session_t *, nat_t *, void *));
44f4b3ec61Sdh void ippr_h323_del __P((ap_session_t *, void *, ipf_stack_t *));
45f4b3ec61Sdh int  ippr_h323_out __P((fr_info_t *, ap_session_t *, nat_t *, void *));
46f4b3ec61Sdh int  ippr_h323_in __P((fr_info_t *, ap_session_t *, nat_t *, void *));
477c478bd9Sstevel@tonic-gate 
48f4b3ec61Sdh int  ippr_h245_new __P((fr_info_t *, ap_session_t *, nat_t *, void *));
49f4b3ec61Sdh int  ippr_h245_out __P((fr_info_t *, ap_session_t *, nat_t *, void *));
50f4b3ec61Sdh int  ippr_h245_in __P((fr_info_t *, ap_session_t *, nat_t *, void *));
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate static int find_port __P((int, caddr_t, int datlen, int *, u_short *));
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate 
find_port(ipaddr,data,datlen,off,port)557c478bd9Sstevel@tonic-gate static int find_port(ipaddr, data, datlen, off, port)
567c478bd9Sstevel@tonic-gate int ipaddr;
577c478bd9Sstevel@tonic-gate caddr_t data;
587c478bd9Sstevel@tonic-gate int datlen, *off;
597c478bd9Sstevel@tonic-gate unsigned short *port;
607c478bd9Sstevel@tonic-gate {
617c478bd9Sstevel@tonic-gate 	u_32_t addr, netaddr;
627c478bd9Sstevel@tonic-gate 	u_char *dp;
637c478bd9Sstevel@tonic-gate 	int offset;
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate 	if (datlen < 6)
667c478bd9Sstevel@tonic-gate 		return -1;
67*2d6eb4a5SToomas Soome 
687c478bd9Sstevel@tonic-gate 	*port = 0;
697c478bd9Sstevel@tonic-gate 	offset = *off;
707c478bd9Sstevel@tonic-gate 	dp = (u_char *)data;
717c478bd9Sstevel@tonic-gate 	netaddr = ntohl(ipaddr);
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate 	for (offset = 0; offset <= datlen - 6; offset++, dp++) {
747c478bd9Sstevel@tonic-gate 		addr = (dp[0] << 24) | (dp[1] << 16) | (dp[2] << 8) | dp[3];
757c478bd9Sstevel@tonic-gate 		if (netaddr == addr)
767c478bd9Sstevel@tonic-gate 		{
777c478bd9Sstevel@tonic-gate 			*port = (*(dp + 4) << 8) | *(dp + 5);
787c478bd9Sstevel@tonic-gate 			break;
797c478bd9Sstevel@tonic-gate 		}
807c478bd9Sstevel@tonic-gate 	}
817c478bd9Sstevel@tonic-gate 	*off = offset;
827c478bd9Sstevel@tonic-gate   	return (offset > datlen - 6) ? -1 : 0;
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate /*
867c478bd9Sstevel@tonic-gate  * Initialize local structures.
877c478bd9Sstevel@tonic-gate  */
88f4b3ec61Sdh /*ARGSUSED*/
ippr_h323_init(private,ifs)89f4b3ec61Sdh int ippr_h323_init(private, ifs)
90f4b3ec61Sdh void **private;
91f4b3ec61Sdh ipf_stack_t *ifs;
927c478bd9Sstevel@tonic-gate {
93f4b3ec61Sdh 	ifs_h323pxy_t *ifsh323;
94f4b3ec61Sdh 
95f4b3ec61Sdh 	KMALLOC(ifsh323, ifs_h323pxy_t *);
96f4b3ec61Sdh 	if (ifsh323 == NULL)
97f4b3ec61Sdh 		return -1;
98f4b3ec61Sdh 
99f4b3ec61Sdh 	ifsh323->h323_fr.fr_ref = 1;
100f4b3ec61Sdh 	ifsh323->h323_fr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
101f4b3ec61Sdh 	MUTEX_INIT(&ifsh323->h323_fr.fr_lock, "H323 proxy rule lock");
102f4b3ec61Sdh 	ifsh323->h323_proxy_init = 1;
103f4b3ec61Sdh 
104f4b3ec61Sdh 	*private = (void *)ifsh323;
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 	return 0;
1077c478bd9Sstevel@tonic-gate }
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 
110f4b3ec61Sdh /*ARGSUSED*/
ippr_h323_fini(private,ifs)111f4b3ec61Sdh void ippr_h323_fini(private, ifs)
112f4b3ec61Sdh void **private;
113f4b3ec61Sdh ipf_stack_t *ifs;
1147c478bd9Sstevel@tonic-gate {
115f4b3ec61Sdh 	ifs_h323pxy_t *ifsh323 = *((ifs_h323pxy_t **)private);
116f4b3ec61Sdh 
117f4b3ec61Sdh 	if (ifsh323->h323_proxy_init == 1) {
118f4b3ec61Sdh 		MUTEX_DESTROY(&ifsh323->h323_fr.fr_lock);
119f4b3ec61Sdh 		ifsh323->h323_proxy_init = 0;
1207c478bd9Sstevel@tonic-gate 	}
1217c478bd9Sstevel@tonic-gate 
122f4b3ec61Sdh 	KFREE(ifsh323);
123f4b3ec61Sdh 	*private = NULL;
124f4b3ec61Sdh }
1257c478bd9Sstevel@tonic-gate 
126f4b3ec61Sdh /*ARGSUSED*/
ippr_h323_new(fin,aps,nat,private)127f4b3ec61Sdh int ippr_h323_new(fin, aps, nat, private)
1287c478bd9Sstevel@tonic-gate fr_info_t *fin;
1297c478bd9Sstevel@tonic-gate ap_session_t *aps;
1307c478bd9Sstevel@tonic-gate nat_t *nat;
131f4b3ec61Sdh void *private;
1327c478bd9Sstevel@tonic-gate {
1337c478bd9Sstevel@tonic-gate 	fin = fin;	/* LINT */
1347c478bd9Sstevel@tonic-gate 	nat = nat;	/* LINT */
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	aps->aps_data = NULL;
1377c478bd9Sstevel@tonic-gate 	aps->aps_psiz = 0;
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	return 0;
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate 
142f4b3ec61Sdh /*ARGSUSED*/
ippr_h323_del(aps,private,ifs)143f4b3ec61Sdh void ippr_h323_del(aps, private, ifs)
1447c478bd9Sstevel@tonic-gate ap_session_t *aps;
145f4b3ec61Sdh void *private;
146f4b3ec61Sdh ipf_stack_t *ifs;
1477c478bd9Sstevel@tonic-gate {
1487c478bd9Sstevel@tonic-gate 	int i;
1497c478bd9Sstevel@tonic-gate 	ipnat_t *ipn;
150*2d6eb4a5SToomas Soome 
1517c478bd9Sstevel@tonic-gate 	if (aps->aps_data) {
1527c478bd9Sstevel@tonic-gate 		for (i = 0, ipn = aps->aps_data;
153ab25eeb5Syz 		     i < (aps->aps_psiz / sizeof(ipnat_t));
1547c478bd9Sstevel@tonic-gate 		     i++, ipn = (ipnat_t *)((char *)ipn + sizeof(*ipn)))
1557c478bd9Sstevel@tonic-gate 		{
156ab25eeb5Syz 			/*
1577c478bd9Sstevel@tonic-gate 			 * Check the comment in ippr_h323_in() function,
1587c478bd9Sstevel@tonic-gate 			 * just above fr_nat_ioctl() call.
1597c478bd9Sstevel@tonic-gate 			 * We are lucky here because this function is not
1607c478bd9Sstevel@tonic-gate 			 * called with ipf_nat locked.
1617c478bd9Sstevel@tonic-gate 			 */
1627c478bd9Sstevel@tonic-gate 			if (fr_nat_ioctl((caddr_t)ipn, SIOCRMNAT, NAT_SYSSPACE|
163f4b3ec61Sdh 				         NAT_LOCKHELD|FWRITE, 0, NULL, ifs) == -1) {
1647c478bd9Sstevel@tonic-gate 				/*EMPTY*/;
1657c478bd9Sstevel@tonic-gate 				/* log the error */
1667c478bd9Sstevel@tonic-gate 			}
1677c478bd9Sstevel@tonic-gate 		}
1687c478bd9Sstevel@tonic-gate 		KFREES(aps->aps_data, aps->aps_psiz);
1697c478bd9Sstevel@tonic-gate 		/* avoid double free */
1707c478bd9Sstevel@tonic-gate 		aps->aps_data = NULL;
1717c478bd9Sstevel@tonic-gate 		aps->aps_psiz = 0;
1727c478bd9Sstevel@tonic-gate 	}
1737c478bd9Sstevel@tonic-gate 	return;
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 
177f4b3ec61Sdh /*ARGSUSED*/
ippr_h323_in(fin,aps,nat,private)178f4b3ec61Sdh int ippr_h323_in(fin, aps, nat, private)
1797c478bd9Sstevel@tonic-gate fr_info_t *fin;
1807c478bd9Sstevel@tonic-gate ap_session_t *aps;
1817c478bd9Sstevel@tonic-gate nat_t *nat;
182f4b3ec61Sdh void *private;
1837c478bd9Sstevel@tonic-gate {
1847c478bd9Sstevel@tonic-gate 	int ipaddr, off, datlen;
1857c478bd9Sstevel@tonic-gate 	unsigned short port;
1867c478bd9Sstevel@tonic-gate 	caddr_t data;
1877c478bd9Sstevel@tonic-gate 	tcphdr_t *tcp;
1887c478bd9Sstevel@tonic-gate 	ip_t *ip;
189f4b3ec61Sdh 	ipf_stack_t *ifs = fin->fin_ifs;
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 	ip = fin->fin_ip;
1927c478bd9Sstevel@tonic-gate 	tcp = (tcphdr_t *)fin->fin_dp;
1937c478bd9Sstevel@tonic-gate 	ipaddr = ip->ip_src.s_addr;
194*2d6eb4a5SToomas Soome 
1957c478bd9Sstevel@tonic-gate 	data = (caddr_t)tcp + (TCP_OFF(tcp) << 2);
1967c478bd9Sstevel@tonic-gate 	datlen = fin->fin_dlen - (TCP_OFF(tcp) << 2);
1977c478bd9Sstevel@tonic-gate 	if (find_port(ipaddr, data, datlen, &off, &port) == 0) {
1987c478bd9Sstevel@tonic-gate 		ipnat_t *ipn;
1997c478bd9Sstevel@tonic-gate 		char *newarray;
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 		/* setup a nat rule to set a h245 proxy on tcp-port "port"
2027c478bd9Sstevel@tonic-gate 		 * it's like:
2037c478bd9Sstevel@tonic-gate 		 *   map <if> <inter_ip>/<mask> -> <gate_ip>/<mask> proxy port <port> <port>/tcp
2047c478bd9Sstevel@tonic-gate 		 */
2057c478bd9Sstevel@tonic-gate 		KMALLOCS(newarray, char *, aps->aps_psiz + sizeof(*ipn));
2067c478bd9Sstevel@tonic-gate 		if (newarray == NULL) {
2077c478bd9Sstevel@tonic-gate 			return -1;
2087c478bd9Sstevel@tonic-gate 		}
2097c478bd9Sstevel@tonic-gate 		ipn = (ipnat_t *)&newarray[aps->aps_psiz];
2107c478bd9Sstevel@tonic-gate 		bcopy((caddr_t)nat->nat_ptr, (caddr_t)ipn, sizeof(ipnat_t));
2117c478bd9Sstevel@tonic-gate 		(void) strncpy(ipn->in_plabel, "h245", APR_LABELLEN);
212*2d6eb4a5SToomas Soome 
2137c478bd9Sstevel@tonic-gate 		ipn->in_inip = nat->nat_inip.s_addr;
2147c478bd9Sstevel@tonic-gate 		ipn->in_inmsk = 0xffffffff;
2157c478bd9Sstevel@tonic-gate 		ipn->in_dport = htons(port);
216ab25eeb5Syz 		/*
2177c478bd9Sstevel@tonic-gate 		 * we got a problem here. we need to call fr_nat_ioctl() to add
2187c478bd9Sstevel@tonic-gate 		 * the h245 proxy rule, but since we already hold (READ locked)
2197c478bd9Sstevel@tonic-gate 		 * the nat table rwlock (ipf_nat), if we go into fr_nat_ioctl(),
2207c478bd9Sstevel@tonic-gate 		 * it will try to WRITE lock it. This will causing dead lock
2217c478bd9Sstevel@tonic-gate 		 * on RTP.
222ab25eeb5Syz 		 *
2237c478bd9Sstevel@tonic-gate 		 * The quick & dirty solution here is release the read lock,
2247c478bd9Sstevel@tonic-gate 		 * call fr_nat_ioctl() and re-lock it.
2257c478bd9Sstevel@tonic-gate 		 * A (maybe better) solution is do a UPGRADE(), and instead
2267c478bd9Sstevel@tonic-gate 		 * of calling fr_nat_ioctl(), we add the nat rule ourself.
2277c478bd9Sstevel@tonic-gate 		 */
228f4b3ec61Sdh 		RWLOCK_EXIT(&ifs->ifs_ipf_nat);
2297c478bd9Sstevel@tonic-gate 		if (fr_nat_ioctl((caddr_t)ipn, SIOCADNAT,
230f4b3ec61Sdh 				 NAT_SYSSPACE|FWRITE, 0, NULL, ifs) == -1) {
231f4b3ec61Sdh 			READ_ENTER(&ifs->ifs_ipf_nat);
2327c478bd9Sstevel@tonic-gate 			return -1;
2337c478bd9Sstevel@tonic-gate 		}
234f4b3ec61Sdh 		READ_ENTER(&ifs->ifs_ipf_nat);
2357c478bd9Sstevel@tonic-gate 		if (aps->aps_data != NULL && aps->aps_psiz > 0) {
2367c478bd9Sstevel@tonic-gate 			bcopy(aps->aps_data, newarray, aps->aps_psiz);
2377c478bd9Sstevel@tonic-gate 			KFREES(aps->aps_data, aps->aps_psiz);
2387c478bd9Sstevel@tonic-gate 		}
2397c478bd9Sstevel@tonic-gate 		aps->aps_data = newarray;
2407c478bd9Sstevel@tonic-gate 		aps->aps_psiz += sizeof(*ipn);
2417c478bd9Sstevel@tonic-gate 	}
2427c478bd9Sstevel@tonic-gate 	return 0;
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 
246f4b3ec61Sdh /*ARGSUSED*/
ippr_h245_new(fin,aps,nat,private)247f4b3ec61Sdh int ippr_h245_new(fin, aps, nat, private)
2487c478bd9Sstevel@tonic-gate fr_info_t *fin;
2497c478bd9Sstevel@tonic-gate ap_session_t *aps;
2507c478bd9Sstevel@tonic-gate nat_t *nat;
251f4b3ec61Sdh void *private;
2527c478bd9Sstevel@tonic-gate {
2537c478bd9Sstevel@tonic-gate 	fin = fin;	/* LINT */
2547c478bd9Sstevel@tonic-gate 	nat = nat;	/* LINT */
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	aps->aps_data = NULL;
2577c478bd9Sstevel@tonic-gate 	aps->aps_psiz = 0;
2587c478bd9Sstevel@tonic-gate 	return 0;
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 
262f4b3ec61Sdh /*ARGSUSED*/
ippr_h245_out(fin,aps,nat,private)263f4b3ec61Sdh int ippr_h245_out(fin, aps, nat, private)
2647c478bd9Sstevel@tonic-gate fr_info_t *fin;
2657c478bd9Sstevel@tonic-gate ap_session_t *aps;
2667c478bd9Sstevel@tonic-gate nat_t *nat;
267f4b3ec61Sdh void *private;
2687c478bd9Sstevel@tonic-gate {
2697c478bd9Sstevel@tonic-gate 	int ipaddr, off, datlen;
2707c478bd9Sstevel@tonic-gate 	tcphdr_t *tcp;
2717c478bd9Sstevel@tonic-gate 	caddr_t data;
2727c478bd9Sstevel@tonic-gate 	u_short port;
2737c478bd9Sstevel@tonic-gate 	ip_t *ip;
274f4b3ec61Sdh 	ipf_stack_t *ifs = fin->fin_ifs;
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate 	aps = aps;	/* LINT */
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 	ip = fin->fin_ip;
2797c478bd9Sstevel@tonic-gate 	tcp = (tcphdr_t *)fin->fin_dp;
2807c478bd9Sstevel@tonic-gate 	ipaddr = nat->nat_inip.s_addr;
2817c478bd9Sstevel@tonic-gate 	data = (caddr_t)tcp + (TCP_OFF(tcp) << 2);
282ab25eeb5Syz 	datlen = fin->fin_dlen - (TCP_OFF(tcp) << 2);
2837c478bd9Sstevel@tonic-gate 	if (find_port(ipaddr, data, datlen, &off, &port) == 0) {
2847c478bd9Sstevel@tonic-gate 		fr_info_t fi;
2857c478bd9Sstevel@tonic-gate 		nat_t     *nat2;
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate /*		port = htons(port); */
2887c478bd9Sstevel@tonic-gate 		nat2 = nat_outlookup(fin->fin_ifp, IPN_UDP, IPPROTO_UDP,
2897c478bd9Sstevel@tonic-gate 				    ip->ip_src, ip->ip_dst);
2907c478bd9Sstevel@tonic-gate 		if (nat2 == NULL) {
2917c478bd9Sstevel@tonic-gate 			struct ip newip;
2927c478bd9Sstevel@tonic-gate 			struct udphdr udp;
293*2d6eb4a5SToomas Soome 
2947c478bd9Sstevel@tonic-gate 			bcopy((caddr_t)ip, (caddr_t)&newip, sizeof(newip));
2957c478bd9Sstevel@tonic-gate 			newip.ip_len = fin->fin_hlen + sizeof(udp);
2967c478bd9Sstevel@tonic-gate 			newip.ip_p = IPPROTO_UDP;
2977c478bd9Sstevel@tonic-gate 			newip.ip_src = nat->nat_inip;
298*2d6eb4a5SToomas Soome 
2997c478bd9Sstevel@tonic-gate 			bzero((char *)&udp, sizeof(udp));
3007c478bd9Sstevel@tonic-gate 			udp.uh_sport = port;
301*2d6eb4a5SToomas Soome 
3027c478bd9Sstevel@tonic-gate 			bcopy((caddr_t)fin, (caddr_t)&fi, sizeof(fi));
3037c478bd9Sstevel@tonic-gate 			fi.fin_fi.fi_p = IPPROTO_UDP;
3047c478bd9Sstevel@tonic-gate 			fi.fin_data[0] = port;
3057c478bd9Sstevel@tonic-gate 			fi.fin_data[1] = 0;
3067c478bd9Sstevel@tonic-gate 			fi.fin_dp = (char *)&udp;
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 			nat2 = nat_new(&fi, nat->nat_ptr, NULL,
3097c478bd9Sstevel@tonic-gate 				       NAT_SLAVE|IPN_UDP|SI_W_DPORT,
3107c478bd9Sstevel@tonic-gate 				       NAT_OUTBOUND);
3117c478bd9Sstevel@tonic-gate 			if (nat2 != NULL) {
3127c478bd9Sstevel@tonic-gate 				(void) nat_proto(&fi, nat2, IPN_UDP);
3137c478bd9Sstevel@tonic-gate 				nat_update(&fi, nat2, nat2->nat_ptr);
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 				nat2->nat_ptr->in_hits++;
3167c478bd9Sstevel@tonic-gate #ifdef	IPFILTER_LOG
317f4b3ec61Sdh 				nat_log(nat2, (u_int)(nat->nat_ptr->in_redir),
318f4b3ec61Sdh 					ifs);
3197c478bd9Sstevel@tonic-gate #endif
3207c478bd9Sstevel@tonic-gate 				bcopy((caddr_t)&ip->ip_src.s_addr,
3217c478bd9Sstevel@tonic-gate 				      data + off, 4);
3227c478bd9Sstevel@tonic-gate 				bcopy((caddr_t)&nat2->nat_outport,
3237c478bd9Sstevel@tonic-gate 				      data + off + 4, 2);
3247c478bd9Sstevel@tonic-gate 			}
3257c478bd9Sstevel@tonic-gate 		}
3267c478bd9Sstevel@tonic-gate 	}
3277c478bd9Sstevel@tonic-gate 	return 0;
3287c478bd9Sstevel@tonic-gate }
329