xref: /titanic_52/usr/src/cmd/ipf/tools/ipnat_y.y (revision ab073b324433ebc8947d28ade932d29d0e809795)
17c478bd9Sstevel@tonic-gate %{
26aed92a9Syx160601 /*
3d6c23f6fSyx160601  * Copyright (C) 2001-2008 by Darren Reed.
46aed92a9Syx160601  *
56aed92a9Syx160601  * See the IPFILTER.LICENCE file for details on licencing.
66aed92a9Syx160601  *
7d6c23f6fSyx160601  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
86aed92a9Syx160601  * Use is subject to license terms.
96aed92a9Syx160601  */
109b4c7145Sjojemann 
116aed92a9Syx160601 #pragma ident	"%Z%%M%	%I%	%E% SMI"
126aed92a9Syx160601 
137c478bd9Sstevel@tonic-gate #ifdef  __FreeBSD__
147c478bd9Sstevel@tonic-gate # ifndef __FreeBSD_cc_version
157c478bd9Sstevel@tonic-gate #  include <osreldate.h>
167c478bd9Sstevel@tonic-gate # else
177c478bd9Sstevel@tonic-gate #  if __FreeBSD_cc_version < 430000
187c478bd9Sstevel@tonic-gate #   include <osreldate.h>
197c478bd9Sstevel@tonic-gate #  endif
207c478bd9Sstevel@tonic-gate # endif
217c478bd9Sstevel@tonic-gate #endif
227c478bd9Sstevel@tonic-gate #include <stdio.h>
237c478bd9Sstevel@tonic-gate #include <unistd.h>
247c478bd9Sstevel@tonic-gate #include <string.h>
257c478bd9Sstevel@tonic-gate #include <fcntl.h>
267c478bd9Sstevel@tonic-gate #include <errno.h>
277c478bd9Sstevel@tonic-gate #if !defined(__SVR4) && !defined(__GNUC__)
287c478bd9Sstevel@tonic-gate #include <strings.h>
297c478bd9Sstevel@tonic-gate #endif
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/param.h>
327c478bd9Sstevel@tonic-gate #include <sys/file.h>
337c478bd9Sstevel@tonic-gate #include <stdlib.h>
347c478bd9Sstevel@tonic-gate #include <stddef.h>
357c478bd9Sstevel@tonic-gate #include <sys/socket.h>
367c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
377c478bd9Sstevel@tonic-gate #include <netinet/in.h>
387c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h>
397c478bd9Sstevel@tonic-gate #include <sys/time.h>
407c478bd9Sstevel@tonic-gate #include <syslog.h>
417c478bd9Sstevel@tonic-gate #include <net/if.h>
427c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 300000
437c478bd9Sstevel@tonic-gate # include <net/if_var.h>
447c478bd9Sstevel@tonic-gate #endif
457c478bd9Sstevel@tonic-gate #include <netdb.h>
467c478bd9Sstevel@tonic-gate #include <arpa/nameser.h>
477c478bd9Sstevel@tonic-gate #include <resolv.h>
487c478bd9Sstevel@tonic-gate #include "ipf.h"
497c478bd9Sstevel@tonic-gate #include "netinet/ipl.h"
507c478bd9Sstevel@tonic-gate #include "ipnat_l.h"
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #define	YYDEBUG	1
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate extern	void	yyerror __P((char *));
557c478bd9Sstevel@tonic-gate extern	int	yyparse __P((void));
567c478bd9Sstevel@tonic-gate extern	int	yylex __P((void));
577c478bd9Sstevel@tonic-gate extern	int	yydebug;
587c478bd9Sstevel@tonic-gate extern	FILE	*yyin;
597c478bd9Sstevel@tonic-gate extern	int	yylineNum;
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate static	ipnat_t		*nattop = NULL;
627c478bd9Sstevel@tonic-gate static	ipnat_t		*nat = NULL;
637c478bd9Sstevel@tonic-gate static	int		natfd = -1;
647c478bd9Sstevel@tonic-gate static	ioctlfunc_t	natioctlfunc = NULL;
657c478bd9Sstevel@tonic-gate static	addfunc_t	nataddfunc = NULL;
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate static	void	newnatrule __P((void));
687c478bd9Sstevel@tonic-gate static	void	setnatproto __P((int));
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate %}
717c478bd9Sstevel@tonic-gate %union	{
727c478bd9Sstevel@tonic-gate 	char	*str;
737c478bd9Sstevel@tonic-gate 	u_32_t	num;
74d6c23f6fSyx160601 	struct	{
75d6c23f6fSyx160601 		i6addr_t	a;
76d6c23f6fSyx160601 		int		v;
77d6c23f6fSyx160601 	} ipa;
787c478bd9Sstevel@tonic-gate 	frentry_t	fr;
797c478bd9Sstevel@tonic-gate 	frtuc_t	*frt;
80ab25eeb5Syz155240 	u_short	port;
817c478bd9Sstevel@tonic-gate 	struct	{
827c478bd9Sstevel@tonic-gate 		u_short	p1;
837c478bd9Sstevel@tonic-gate 		u_short	p2;
847c478bd9Sstevel@tonic-gate 		int	pc;
857c478bd9Sstevel@tonic-gate 	} pc;
867c478bd9Sstevel@tonic-gate 	struct	{
87d6c23f6fSyx160601 		i6addr_t	a;
88d6c23f6fSyx160601 		i6addr_t	m;
89d6c23f6fSyx160601 		int	v;
907c478bd9Sstevel@tonic-gate 	} ipp;
917c478bd9Sstevel@tonic-gate 	union	i6addr	ip6;
927c478bd9Sstevel@tonic-gate };
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate %token  <num>   YY_NUMBER YY_HEX
957c478bd9Sstevel@tonic-gate %token  <str>   YY_STR
967c478bd9Sstevel@tonic-gate %token	  YY_COMMENT
977c478bd9Sstevel@tonic-gate %token	  YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
987c478bd9Sstevel@tonic-gate %token	  YY_RANGE_OUT YY_RANGE_IN
997c478bd9Sstevel@tonic-gate %token  <ip6>   YY_IPV6
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate %token	IPNY_MAPBLOCK IPNY_RDR IPNY_PORT IPNY_PORTS IPNY_AUTO IPNY_RANGE
1027c478bd9Sstevel@tonic-gate %token	IPNY_MAP IPNY_BIMAP IPNY_FROM IPNY_TO IPNY_MASK IPNY_PORTMAP IPNY_ANY
1037c478bd9Sstevel@tonic-gate %token	IPNY_ROUNDROBIN IPNY_FRAG IPNY_AGE IPNY_ICMPIDMAP IPNY_PROXY
1047c478bd9Sstevel@tonic-gate %token	IPNY_TCP IPNY_UDP IPNY_TCPUDP IPNY_STICKY IPNY_MSSCLAMP IPNY_TAG
105*ab073b32Sdr146992 %token	IPNY_TLATE IPNY_SEQUENTIAL
106ab25eeb5Syz155240 %type	<port> portspec
107ab25eeb5Syz155240 %type	<num> hexnumber compare range proto
108d6c23f6fSyx160601 %type	<num> saddr daddr sobject dobject mapfrom rdrfrom dip
109d6c23f6fSyx160601 %type	<ipa> hostname ipv4 ipaddr
110d6c23f6fSyx160601 %type	<ipp> addr rhaddr
1117c478bd9Sstevel@tonic-gate %type	<pc> portstuff
1127c478bd9Sstevel@tonic-gate %%
1137c478bd9Sstevel@tonic-gate file:	line
1147c478bd9Sstevel@tonic-gate 	| assign
1157c478bd9Sstevel@tonic-gate 	| file line
1167c478bd9Sstevel@tonic-gate 	| file assign
1177c478bd9Sstevel@tonic-gate 	;
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate line:	xx rule		{ while ((nat = nattop) != NULL) {
120d6c23f6fSyx160601 				if (nat->in_v == 0)
121d6c23f6fSyx160601 					nat->in_v = 4;
1227c478bd9Sstevel@tonic-gate 				nattop = nat->in_next;
1237c478bd9Sstevel@tonic-gate 				(*nataddfunc)(natfd, natioctlfunc, nat);
1247c478bd9Sstevel@tonic-gate 				free(nat);
1257c478bd9Sstevel@tonic-gate 			  }
1267c478bd9Sstevel@tonic-gate 			  resetlexer();
1277c478bd9Sstevel@tonic-gate 			}
1287c478bd9Sstevel@tonic-gate 	| YY_COMMENT
1297c478bd9Sstevel@tonic-gate 	;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate assign:	YY_STR assigning YY_STR ';'	{ set_variable($1, $3);
1327c478bd9Sstevel@tonic-gate 					  resetlexer();
1337c478bd9Sstevel@tonic-gate 					  free($1);
1347c478bd9Sstevel@tonic-gate 					  free($3);
1357c478bd9Sstevel@tonic-gate 					}
1367c478bd9Sstevel@tonic-gate 	;
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate assigning:
1397c478bd9Sstevel@tonic-gate 	'='				{ yyvarnext = 1; }
1407c478bd9Sstevel@tonic-gate 	;
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate xx:					{ newnatrule(); }
1437c478bd9Sstevel@tonic-gate 	;
1447c478bd9Sstevel@tonic-gate 
145ab25eeb5Syz155240 rule:	map eol
146ab25eeb5Syz155240 	| mapblock eol
147ab25eeb5Syz155240 	| redir eol
148ab25eeb5Syz155240 	;
149ab25eeb5Syz155240 
150ab25eeb5Syz155240 eol:	| ';'
1517c478bd9Sstevel@tonic-gate 	;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate map:	mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions
154d6c23f6fSyx160601 				{ if ($3.v != 0 && $3.v != $5.v && $5.v != 0)
155d6c23f6fSyx160601 					yyerror("1.address family mismatch");
156d6c23f6fSyx160601 				  bcopy(&$3.a, &nat->in_in[0], sizeof($3.a));
157d6c23f6fSyx160601 				  bcopy(&$3.m, &nat->in_in[1], sizeof($3.a));
158d6c23f6fSyx160601 				  bcopy(&$5.a, &nat->in_out[0], sizeof($5.a));
159d6c23f6fSyx160601 				  bcopy(&$5.m, &nat->in_out[1], sizeof($5.a));
1607c478bd9Sstevel@tonic-gate 				  if (nat->in_ifnames[1][0] == '\0')
1617c478bd9Sstevel@tonic-gate 					strncpy(nat->in_ifnames[1],
1627c478bd9Sstevel@tonic-gate 						nat->in_ifnames[0],
1637c478bd9Sstevel@tonic-gate 						sizeof(nat->in_ifnames[0]));
1647c478bd9Sstevel@tonic-gate 				  if ((nat->in_flags & IPN_TCPUDP) == 0)
1657c478bd9Sstevel@tonic-gate 					setnatproto(nat->in_p);
1667c478bd9Sstevel@tonic-gate 				  if (((nat->in_redir & NAT_MAPBLK) != 0) ||
1677c478bd9Sstevel@tonic-gate 				      ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
1687c478bd9Sstevel@tonic-gate 					nat_setgroupmap(nat);
1697c478bd9Sstevel@tonic-gate 				}
1707c478bd9Sstevel@tonic-gate 	| mapit ifnames addr IPNY_TLATE rhaddr mapport mapoptions
171d6c23f6fSyx160601 				{ if ($3.v != 0 && $3.v != $5.v && $5.v != 0)
172d6c23f6fSyx160601 					yyerror("2.address family mismatch");
173d6c23f6fSyx160601 				  bcopy(&$3.a, &nat->in_in[0], sizeof($3.a));
174d6c23f6fSyx160601 				  bcopy(&$3.m, &nat->in_in[1], sizeof($3.a));
175d6c23f6fSyx160601 				  bcopy(&$5.a, &nat->in_out[0], sizeof($5.a));
176d6c23f6fSyx160601 				  bcopy(&$5.m, &nat->in_out[1], sizeof($5.a));
1777c478bd9Sstevel@tonic-gate 				  if (nat->in_ifnames[1][0] == '\0')
1787c478bd9Sstevel@tonic-gate 					strncpy(nat->in_ifnames[1],
1797c478bd9Sstevel@tonic-gate 						nat->in_ifnames[0],
1807c478bd9Sstevel@tonic-gate 						sizeof(nat->in_ifnames[0]));
181ab25eeb5Syz155240 				  if ((nat->in_flags & IPN_TCPUDPICMPQ) == 0)
1827c478bd9Sstevel@tonic-gate 					setnatproto(nat->in_p);
1837c478bd9Sstevel@tonic-gate 				  if (((nat->in_redir & NAT_MAPBLK) != 0) ||
1847c478bd9Sstevel@tonic-gate 				      ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
1857c478bd9Sstevel@tonic-gate 					nat_setgroupmap(nat);
1867c478bd9Sstevel@tonic-gate 				}
1877c478bd9Sstevel@tonic-gate 	| mapit ifnames mapfrom IPNY_TLATE rhaddr proxy mapoptions
188d6c23f6fSyx160601 				{ if ($3 != 0 && $3 != $5.v && $5.v != 0)
189d6c23f6fSyx160601 					yyerror("3.address family mismatch");
190d6c23f6fSyx160601 				  bcopy(&$5.a, &nat->in_out[0], sizeof($5.a));
191d6c23f6fSyx160601 				  bcopy(&$5.m, &nat->in_out[1], sizeof($5.a));
1927c478bd9Sstevel@tonic-gate 				  if (nat->in_ifnames[1][0] == '\0')
1937c478bd9Sstevel@tonic-gate 					strncpy(nat->in_ifnames[1],
1947c478bd9Sstevel@tonic-gate 						nat->in_ifnames[0],
1957c478bd9Sstevel@tonic-gate 						sizeof(nat->in_ifnames[0]));
1967c478bd9Sstevel@tonic-gate 				  if ((nat->in_flags & IPN_TCPUDP) == 0)
1977c478bd9Sstevel@tonic-gate 					setnatproto(nat->in_p);
1987c478bd9Sstevel@tonic-gate 				  if (((nat->in_redir & NAT_MAPBLK) != 0) ||
1997c478bd9Sstevel@tonic-gate 				      ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
2007c478bd9Sstevel@tonic-gate 					nat_setgroupmap(nat);
2017c478bd9Sstevel@tonic-gate 				}
2027c478bd9Sstevel@tonic-gate 	| mapit ifnames mapfrom IPNY_TLATE rhaddr mapport mapoptions
203d6c23f6fSyx160601 				{ if ($3 != 0 && $3 != $5.v && $5.v != 0)
204d6c23f6fSyx160601 					yyerror("4.address family mismatch");
205d6c23f6fSyx160601 				  bcopy(&$5.a, &nat->in_out[0], sizeof($5.a));
206d6c23f6fSyx160601 				  bcopy(&$5.m, &nat->in_out[1], sizeof($5.a));
2077c478bd9Sstevel@tonic-gate 				  if (nat->in_ifnames[1][0] == '\0')
2087c478bd9Sstevel@tonic-gate 					strncpy(nat->in_ifnames[1],
2097c478bd9Sstevel@tonic-gate 						nat->in_ifnames[0],
2107c478bd9Sstevel@tonic-gate 						sizeof(nat->in_ifnames[0]));
211ab25eeb5Syz155240 				  if ((nat->in_flags & IPN_TCPUDPICMPQ) == 0)
2127c478bd9Sstevel@tonic-gate 					setnatproto(nat->in_p);
2137c478bd9Sstevel@tonic-gate 				  if (((nat->in_redir & NAT_MAPBLK) != 0) ||
2147c478bd9Sstevel@tonic-gate 				      ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
2157c478bd9Sstevel@tonic-gate 					nat_setgroupmap(nat);
2167c478bd9Sstevel@tonic-gate 				}
2177c478bd9Sstevel@tonic-gate 	;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate mapblock:
2207c478bd9Sstevel@tonic-gate 	mapblockit ifnames addr IPNY_TLATE addr ports mapoptions
221d6c23f6fSyx160601 				{ if ($3.v != 0 && $3.v != $5.v && $5.v != 0)
222d6c23f6fSyx160601 					yyerror("5.address family mismatch");
223d6c23f6fSyx160601 				  bcopy(&$3.a, &nat->in_in[0], sizeof($3.a));
224d6c23f6fSyx160601 				  bcopy(&$3.m, &nat->in_in[1], sizeof($3.a));
225d6c23f6fSyx160601 				  bcopy(&$5.a, &nat->in_out[0], sizeof($5.a));
226d6c23f6fSyx160601 				  bcopy(&$5.m, &nat->in_out[1], sizeof($5.a));
2277c478bd9Sstevel@tonic-gate 				  if (nat->in_ifnames[1][0] == '\0')
2287c478bd9Sstevel@tonic-gate 					strncpy(nat->in_ifnames[1],
2297c478bd9Sstevel@tonic-gate 						nat->in_ifnames[0],
2307c478bd9Sstevel@tonic-gate 						sizeof(nat->in_ifnames[0]));
2317c478bd9Sstevel@tonic-gate 				  if ((nat->in_flags & IPN_TCPUDP) == 0)
2327c478bd9Sstevel@tonic-gate 					setnatproto(nat->in_p);
2337c478bd9Sstevel@tonic-gate 				  if (((nat->in_redir & NAT_MAPBLK) != 0) ||
2347c478bd9Sstevel@tonic-gate 				      ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
2357c478bd9Sstevel@tonic-gate 					nat_setgroupmap(nat);
2367c478bd9Sstevel@tonic-gate 				}
2377c478bd9Sstevel@tonic-gate 	;
2387c478bd9Sstevel@tonic-gate 
239ab25eeb5Syz155240 redir:	rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions
240d6c23f6fSyx160601 				{ if ($6 != 0 && $3.v != 0 && $6 != $3.v)
241d6c23f6fSyx160601 					yyerror("6.address family mismatch");
242d6c23f6fSyx160601 				  bcopy(&$3.a, &nat->in_out[0], sizeof($3.a));
243d6c23f6fSyx160601 				  bcopy(&$3.m, &nat->in_out[1], sizeof($3.a));
2447c478bd9Sstevel@tonic-gate 				  if (nat->in_ifnames[1][0] == '\0')
2457c478bd9Sstevel@tonic-gate 					strncpy(nat->in_ifnames[1],
2467c478bd9Sstevel@tonic-gate 						nat->in_ifnames[0],
2477c478bd9Sstevel@tonic-gate 						sizeof(nat->in_ifnames[0]));
2487c478bd9Sstevel@tonic-gate 				  if ((nat->in_p == 0) &&
2497c478bd9Sstevel@tonic-gate 				      ((nat->in_flags & IPN_TCPUDP) == 0) &&
2507c478bd9Sstevel@tonic-gate 				      (nat->in_pmin != 0 ||
2517c478bd9Sstevel@tonic-gate 				       nat->in_pmax != 0 ||
2527c478bd9Sstevel@tonic-gate 				       nat->in_pnext != 0))
2537c478bd9Sstevel@tonic-gate 						setnatproto(IPPROTO_TCP);
2547c478bd9Sstevel@tonic-gate 				}
255ab25eeb5Syz155240 	| rdrit ifnames rdrfrom IPNY_TLATE dip nport setproto rdroptions
256d6c23f6fSyx160601 				{ if ($5 != 0 && $3 != 0 && $5 != $3)
257d6c23f6fSyx160601 					yyerror("7.address family mismatch");
258ab25eeb5Syz155240 				  if ((nat->in_p == 0) &&
2597c478bd9Sstevel@tonic-gate 				      ((nat->in_flags & IPN_TCPUDP) == 0) &&
2607c478bd9Sstevel@tonic-gate 				      (nat->in_pmin != 0 ||
2617c478bd9Sstevel@tonic-gate 				       nat->in_pmax != 0 ||
2627c478bd9Sstevel@tonic-gate 				       nat->in_pnext != 0))
2637c478bd9Sstevel@tonic-gate 					setnatproto(IPPROTO_TCP);
2647c478bd9Sstevel@tonic-gate 				  if (nat->in_ifnames[1][0] == '\0')
2657c478bd9Sstevel@tonic-gate 					strncpy(nat->in_ifnames[1],
2667c478bd9Sstevel@tonic-gate 						nat->in_ifnames[0],
2677c478bd9Sstevel@tonic-gate 						sizeof(nat->in_ifnames[0]));
2687c478bd9Sstevel@tonic-gate 				}
269ab25eeb5Syz155240 	| rdrit ifnames addr IPNY_TLATE dip setproto rdroptions
270d6c23f6fSyx160601 				{ if ($5 != 0 && $3.v != 0 && $5 != $3.v)
271d6c23f6fSyx160601 					yyerror("8.address family mismatch");
272d6c23f6fSyx160601 				  bcopy(&$3.a, &nat->in_out[0], sizeof($3.a));
273d6c23f6fSyx160601 				  bcopy(&$3.m, &nat->in_out[1], sizeof($3.a));
2747c478bd9Sstevel@tonic-gate 				  if (nat->in_ifnames[1][0] == '\0')
2757c478bd9Sstevel@tonic-gate 					strncpy(nat->in_ifnames[1],
2767c478bd9Sstevel@tonic-gate 						nat->in_ifnames[0],
2777c478bd9Sstevel@tonic-gate 						sizeof(nat->in_ifnames[0]));
2787c478bd9Sstevel@tonic-gate 				}
2797c478bd9Sstevel@tonic-gate 	;
2807c478bd9Sstevel@tonic-gate 
281ab25eeb5Syz155240 proxy:	| IPNY_PROXY IPNY_PORT portspec YY_STR '/' proto
2827c478bd9Sstevel@tonic-gate 			{ strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
2837c478bd9Sstevel@tonic-gate 			  if (nat->in_dcmp == 0) {
2847c478bd9Sstevel@tonic-gate 				nat->in_dport = htons($3);
2857c478bd9Sstevel@tonic-gate 			  } else if ($3 != nat->in_dport) {
2867c478bd9Sstevel@tonic-gate 				yyerror("proxy port numbers not consistant");
2877c478bd9Sstevel@tonic-gate 			  }
2887c478bd9Sstevel@tonic-gate 			  setnatproto($6);
2897c478bd9Sstevel@tonic-gate 			  free($4);
2907c478bd9Sstevel@tonic-gate 			}
2917c478bd9Sstevel@tonic-gate 	| IPNY_PROXY IPNY_PORT YY_STR YY_STR '/' proto
292ab25eeb5Syz155240 			{ int pnum;
293ab25eeb5Syz155240 			  strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
294ab25eeb5Syz155240 			  pnum = getportproto($3, $6);
295ab25eeb5Syz155240 			  if (pnum == -1)
296ab25eeb5Syz155240 				yyerror("invalid port number");
297ab25eeb5Syz155240 			  nat->in_dport = pnum;
2987c478bd9Sstevel@tonic-gate 			  setnatproto($6);
2997c478bd9Sstevel@tonic-gate 			  free($3);
3007c478bd9Sstevel@tonic-gate 			  free($4);
3017c478bd9Sstevel@tonic-gate 			}
3027c478bd9Sstevel@tonic-gate 	;
3037c478bd9Sstevel@tonic-gate 
304ab25eeb5Syz155240 setproto:
305ab25eeb5Syz155240 	| proto				{ if (nat->in_p != 0 ||
306ab25eeb5Syz155240 					      nat->in_flags & IPN_TCPUDP)
307ab25eeb5Syz155240 						yyerror("protocol set twice");
308ab25eeb5Syz155240 					  setnatproto($1);
309ab25eeb5Syz155240 					}
310ab25eeb5Syz155240 	| IPNY_TCPUDP			{ if (nat->in_p != 0 ||
311ab25eeb5Syz155240 					      nat->in_flags & IPN_TCPUDP)
312ab25eeb5Syz155240 						yyerror("protocol set twice");
313ab25eeb5Syz155240 					  nat->in_flags |= IPN_TCPUDP;
314ab25eeb5Syz155240 					  nat->in_p = 0;
315ab25eeb5Syz155240 					}
316ab25eeb5Syz155240 	| IPNY_TCP '/' IPNY_UDP		{ if (nat->in_p != 0 ||
317ab25eeb5Syz155240 					      nat->in_flags & IPN_TCPUDP)
318ab25eeb5Syz155240 						yyerror("protocol set twice");
319ab25eeb5Syz155240 					  nat->in_flags |= IPN_TCPUDP;
320ab25eeb5Syz155240 					  nat->in_p = 0;
3217c478bd9Sstevel@tonic-gate 					}
3227c478bd9Sstevel@tonic-gate 	;
3237c478bd9Sstevel@tonic-gate 
324d6c23f6fSyx160601 rhaddr:	addr				{ $$.a = $1.a;
325d6c23f6fSyx160601 					  $$.m = $1.m;
326d6c23f6fSyx160601 					  $$.v = $1.v;
327d6c23f6fSyx160601 					  if ($$.v == 0)
328d6c23f6fSyx160601 						$$.v = nat->in_v;
329d6c23f6fSyx160601 					  yyexpectaddr = 0; }
330d6c23f6fSyx160601 	| IPNY_RANGE hostname '-' hostname
331d6c23f6fSyx160601 					{ if ($2.v != 0 && $4.v != 0 && $4.v != $2.v)
332d6c23f6fSyx160601 						yyerror("9.address family "
333d6c23f6fSyx160601 							"mismatch");
334d6c23f6fSyx160601 					  $$.v = $2.v;
335d6c23f6fSyx160601 					  $$.a = $2.a;
336d6c23f6fSyx160601 					  $$.m = $4.a;
337d6c23f6fSyx160601 					  nat->in_flags |= IPN_IPRANGE;
338d6c23f6fSyx160601 					  yyexpectaddr = 0; }
339ab25eeb5Syz155240 	;
340ab25eeb5Syz155240 
3417c478bd9Sstevel@tonic-gate dip:
342d6c23f6fSyx160601 	hostname			{ bcopy(&$1.a, &nat->in_in[0],
343d6c23f6fSyx160601 						sizeof($1.a));
344d6c23f6fSyx160601 					  if ($1.v == 0)
345d6c23f6fSyx160601 						$1.v = nat->in_v;
346d6c23f6fSyx160601 					  if ($1.v == 4) {
347d6c23f6fSyx160601 						nat->in_inmsk = 0xffffffff;
348d6c23f6fSyx160601 					  } else {
349d6c23f6fSyx160601 						nat->in_in[1].i6[0] = 0xffffffff;
350d6c23f6fSyx160601 						nat->in_in[1].i6[1] = 0xffffffff;
351d6c23f6fSyx160601 						nat->in_in[1].i6[2] = 0xffffffff;
352d6c23f6fSyx160601 						nat->in_in[1].i6[3] = 0xffffffff;
353d6c23f6fSyx160601 					  }
354d6c23f6fSyx160601 					  $$ = $1.v;
355d6c23f6fSyx160601 					}
356d6c23f6fSyx160601 	| hostname '/' YY_NUMBER        { if ($1.v == 0)
357d6c23f6fSyx160601 						$1.v = nat->in_v;
358d6c23f6fSyx160601 					  if ($1.v == 4 &&
359d6c23f6fSyx160601 					      ($1.a.in4.s_addr != 0 ||
360d6c23f6fSyx160601 					      ($3 != 0 && $3 != 32)))
361ef292b7fSjojemann 						yyerror("Invalid mask for dip");
362d6c23f6fSyx160601 					  else if ($1.v == 6 &&
363d6c23f6fSyx160601 					      ($1.a.in4.s_addr != 0 ||
364d6c23f6fSyx160601 					      ($3 != 0 && $3 != 128)))
365d6c23f6fSyx160601 						yyerror("Invalid mask for dip");
366d6c23f6fSyx160601 					  else if ($1.v == 0 ) {
367d6c23f6fSyx160601 						if ($1.a.in4.s_addr == 0 &&
368d6c23f6fSyx160601 						    ($3 == 32 || $3 == 0))
369d6c23f6fSyx160601 							$1.v = 4;
370d6c23f6fSyx160601 						else if ($3 == 128)
371d6c23f6fSyx160601 							$1.v = 6;
372d6c23f6fSyx160601 					  }
373d6c23f6fSyx160601 					  bcopy(&$1.a, &nat->in_in[0],
374d6c23f6fSyx160601 						sizeof($1.a));
375d6c23f6fSyx160601 					  ntomask($1.v, $3,
376d6c23f6fSyx160601 						(u_32_t *)&nat->in_in[1]);
377d6c23f6fSyx160601 					  nat->in_in[0].i6[0] &= nat->in_in[1].i6[0];
378d6c23f6fSyx160601 					  nat->in_in[0].i6[0] &= nat->in_in[1].i6[1];
379d6c23f6fSyx160601 					  nat->in_in[0].i6[0] &= nat->in_in[1].i6[2];
380d6c23f6fSyx160601 					  nat->in_in[0].i6[0] &= nat->in_in[1].i6[3];
381d6c23f6fSyx160601 					  nat->in_v = $1.v;
382d6c23f6fSyx160601 					  $$ = $1.v;
383d6c23f6fSyx160601 					}
384d6c23f6fSyx160601 	| hostname ',' { yyexpectaddr = 1; } hostname
385d6c23f6fSyx160601 					{ if ($1.v != $4.v)
386d6c23f6fSyx160601 						yyerror("10.address family "
387d6c23f6fSyx160601 							"mismatch");
388d6c23f6fSyx160601 					  $$ = $1.v;
389d6c23f6fSyx160601 					  nat->in_flags |= IPN_SPLIT;
390d6c23f6fSyx160601 					  bcopy(&$1.a, &nat->in_in[0],
391d6c23f6fSyx160601 						sizeof($1.a));
392d6c23f6fSyx160601 					  bcopy(&$4.a, &nat->in_in[1],
393d6c23f6fSyx160601 						sizeof($4.a));
394d6c23f6fSyx160601 					  yyexpectaddr = 0; }
3957c478bd9Sstevel@tonic-gate 	;
3967c478bd9Sstevel@tonic-gate 
397ab25eeb5Syz155240 portspec:
398ab25eeb5Syz155240 	YY_NUMBER			{ if ($1 > 65535)	/* Unsigned */
399ab25eeb5Syz155240 						yyerror("invalid port number");
400ab25eeb5Syz155240 					  else
401ab25eeb5Syz155240 						$$ = $1;
402ab25eeb5Syz155240 					}
403ab25eeb5Syz155240 	| YY_STR			{ if (getport(NULL, $1, &($$)) == -1)
404ab25eeb5Syz155240 						yyerror("invalid port number");
405ab25eeb5Syz155240 					  $$ = ntohs($$);
406ab25eeb5Syz155240 					}
407ab25eeb5Syz155240 	;
408ab25eeb5Syz155240 
409ab25eeb5Syz155240 dport:	| IPNY_PORT portspec			{ nat->in_pmin = htons($2);
4107c478bd9Sstevel@tonic-gate 						  nat->in_pmax = htons($2); }
411ab25eeb5Syz155240 	| IPNY_PORT portspec '-' portspec	{ nat->in_pmin = htons($2);
412ab25eeb5Syz155240 						  nat->in_pmax = htons($4); }
413ab25eeb5Syz155240 	| IPNY_PORT portspec ':' portspec	{ nat->in_pmin = htons($2);
4147c478bd9Sstevel@tonic-gate 						  nat->in_pmax = htons($4); }
4157c478bd9Sstevel@tonic-gate 	;
4167c478bd9Sstevel@tonic-gate 
417ab25eeb5Syz155240 nport:	IPNY_PORT portspec		{ nat->in_pnext = htons($2); }
418ab25eeb5Syz155240 	| IPNY_PORT '=' portspec	{ nat->in_pnext = htons($3);
419ab25eeb5Syz155240 					  nat->in_flags |= IPN_FIXEDDPORT;
420ab25eeb5Syz155240 					}
4217c478bd9Sstevel@tonic-gate 	;
4227c478bd9Sstevel@tonic-gate 
423ab25eeb5Syz155240 ports:	| IPNY_PORTS YY_NUMBER		{ nat->in_pmin = $2; }
4247c478bd9Sstevel@tonic-gate 	| IPNY_PORTS IPNY_AUTO		{ nat->in_flags |= IPN_AUTOPORTMAP; }
4257c478bd9Sstevel@tonic-gate 	;
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate mapit:	IPNY_MAP			{ nat->in_redir = NAT_MAP; }
4287c478bd9Sstevel@tonic-gate 	| IPNY_BIMAP			{ nat->in_redir = NAT_BIMAP; }
4297c478bd9Sstevel@tonic-gate 	;
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate rdrit:	IPNY_RDR			{ nat->in_redir = NAT_REDIRECT; }
4327c478bd9Sstevel@tonic-gate 	;
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate mapblockit:
4357c478bd9Sstevel@tonic-gate 	IPNY_MAPBLOCK			{ nat->in_redir = NAT_MAPBLK; }
4367c478bd9Sstevel@tonic-gate 	;
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate mapfrom:
439d6c23f6fSyx160601 	from sobject IPNY_TO dobject	{ if ($2 != 0 && $4 != 0 && $2 != $4)
440d6c23f6fSyx160601 						yyerror("11.address family "
441d6c23f6fSyx160601 							"mismatch");
442d6c23f6fSyx160601 					  $$ = $2;
443d6c23f6fSyx160601 					}
4447c478bd9Sstevel@tonic-gate 	| from sobject '!' IPNY_TO dobject
445d6c23f6fSyx160601 					{ if ($2 != 0 && $5 != 0 && $2 != $5)
446d6c23f6fSyx160601 						yyerror("12.address family "
447d6c23f6fSyx160601 							"mismatch");
448d6c23f6fSyx160601 					  nat->in_flags |= IPN_NOTDST;
449d6c23f6fSyx160601 					  $$ = $2;
450d6c23f6fSyx160601 					}
4517c478bd9Sstevel@tonic-gate 	;
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate rdrfrom:
454d6c23f6fSyx160601 	from sobject IPNY_TO dobject	{ if ($2 != 0 && $4 != 0 && $2 != $4)
455d6c23f6fSyx160601 						yyerror("13.address family "
456d6c23f6fSyx160601 							"mismatch");
457d6c23f6fSyx160601 					  $$ = $2;
458d6c23f6fSyx160601 					}
4597c478bd9Sstevel@tonic-gate 	| '!' from sobject IPNY_TO dobject
460d6c23f6fSyx160601 					{ if ($3 != 0 && $5 != 0 && $3 != $5)
461d6c23f6fSyx160601 						yyerror("14.address family "
462d6c23f6fSyx160601 							"mismatch");
463d6c23f6fSyx160601 					  nat->in_flags |= IPN_NOTSRC;
464d6c23f6fSyx160601 					  $$ = $3;
465d6c23f6fSyx160601 					}
4667c478bd9Sstevel@tonic-gate 	;
4677c478bd9Sstevel@tonic-gate 
468d6c23f6fSyx160601 from:	IPNY_FROM			{ nat->in_flags |= IPN_FILTER;
469d6c23f6fSyx160601 					  yyexpectaddr = 1; }
4707c478bd9Sstevel@tonic-gate 	;
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate ifnames:
473d6c23f6fSyx160601 	ifname				{ yyexpectaddr = 1; }
474d6c23f6fSyx160601 	| ifname ',' otherifname	{ yyexpectaddr = 1; }
4757c478bd9Sstevel@tonic-gate 	;
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate ifname:	YY_STR			{ strncpy(nat->in_ifnames[0], $1,
4787c478bd9Sstevel@tonic-gate 					  sizeof(nat->in_ifnames[0]));
479ab25eeb5Syz155240 				  nat->in_ifnames[0][LIFNAMSIZ - 1] = '\0';
4807c478bd9Sstevel@tonic-gate 				  free($1);
4817c478bd9Sstevel@tonic-gate 				}
4827c478bd9Sstevel@tonic-gate 	;
4837c478bd9Sstevel@tonic-gate 
4847c478bd9Sstevel@tonic-gate otherifname:
4857c478bd9Sstevel@tonic-gate 	YY_STR			{ strncpy(nat->in_ifnames[1], $1,
4867c478bd9Sstevel@tonic-gate 					  sizeof(nat->in_ifnames[1]));
487ab25eeb5Syz155240 				  nat->in_ifnames[1][LIFNAMSIZ - 1] = '\0';
4887c478bd9Sstevel@tonic-gate 				  free($1);
4897c478bd9Sstevel@tonic-gate 				}
4907c478bd9Sstevel@tonic-gate 	;
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate mapport:
493*ab073b32Sdr146992 	IPNY_PORTMAP tcpudp portspec ':' portspec randport
4947c478bd9Sstevel@tonic-gate 			{ nat->in_pmin = htons($3);
495ab25eeb5Syz155240 			  nat->in_pmax = htons($5);
496ab25eeb5Syz155240 			}
497*ab073b32Sdr146992 	| IPNY_PORTMAP tcpudp IPNY_AUTO randport
498ab25eeb5Syz155240 			{ nat->in_flags |= IPN_AUTOPORTMAP;
4997c478bd9Sstevel@tonic-gate 			  nat->in_pmin = htons(1024);
500ab25eeb5Syz155240 			  nat->in_pmax = htons(65535);
501ab25eeb5Syz155240 			}
502ab25eeb5Syz155240 	| IPNY_ICMPIDMAP YY_STR YY_NUMBER ':' YY_NUMBER
503ab25eeb5Syz155240 			{ if (strcmp($2, "icmp") != 0) {
504ab25eeb5Syz155240 				yyerror("icmpidmap not followed by icmp");
505ab25eeb5Syz155240 			  }
506ab25eeb5Syz155240 			  free($2);
507ab25eeb5Syz155240 			  if ($3 < 0 || $3 > 65535)
508ab25eeb5Syz155240 				yyerror("invalid ICMP Id number");
509ab25eeb5Syz155240 			  if ($5 < 0 || $5 > 65535)
510ab25eeb5Syz155240 				yyerror("invalid ICMP Id number");
511ab25eeb5Syz155240 			  nat->in_flags = IPN_ICMPQUERY;
512ab25eeb5Syz155240 			  nat->in_pmin = htons($3);
513ab25eeb5Syz155240 			  nat->in_pmax = htons($5);
514ab25eeb5Syz155240 			}
5157c478bd9Sstevel@tonic-gate 	;
5167c478bd9Sstevel@tonic-gate 
517*ab073b32Sdr146992 randport:
518*ab073b32Sdr146992 	| IPNY_SEQUENTIAL	{ nat->in_flags |= IPN_SEQUENTIAL; }
519*ab073b32Sdr146992 	;
520*ab073b32Sdr146992 
5217c478bd9Sstevel@tonic-gate sobject:
522d6c23f6fSyx160601 	saddr				{ $$ = $1; }
5237c478bd9Sstevel@tonic-gate 	| saddr IPNY_PORT portstuff	{ nat->in_sport = $3.p1;
5247c478bd9Sstevel@tonic-gate 					  nat->in_stop = $3.p2;
525d6c23f6fSyx160601 					  nat->in_scmp = $3.pc;
526d6c23f6fSyx160601 					  $$ = $1;
527d6c23f6fSyx160601 					}
5287c478bd9Sstevel@tonic-gate 	;
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate saddr:	addr				{ if (nat->in_redir == NAT_REDIRECT) {
531d6c23f6fSyx160601 						bcopy(&$1.a, &nat->in_src[0],
532d6c23f6fSyx160601 							sizeof($1.a));
533d6c23f6fSyx160601 						bcopy(&$1.m, &nat->in_src[1],
534d6c23f6fSyx160601 							sizeof($1.a));
5357c478bd9Sstevel@tonic-gate 					  } else {
536d6c23f6fSyx160601 						bcopy(&$1.a, &nat->in_in[0],
537d6c23f6fSyx160601 							sizeof($1.a));
538d6c23f6fSyx160601 						bcopy(&$1.m, &nat->in_in[1],
539d6c23f6fSyx160601 							sizeof($1.a));
5407c478bd9Sstevel@tonic-gate 					  }
541d6c23f6fSyx160601 					  $$ = $1.v;
5427c478bd9Sstevel@tonic-gate 					}
5437c478bd9Sstevel@tonic-gate 	;
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate dobject:
546d6c23f6fSyx160601 	daddr				{ $$ = $1; }
5477c478bd9Sstevel@tonic-gate 	| daddr IPNY_PORT portstuff	{ nat->in_dport = $3.p1;
5487c478bd9Sstevel@tonic-gate 					  nat->in_dtop = $3.p2;
5497c478bd9Sstevel@tonic-gate 					  nat->in_dcmp = $3.pc;
5507c478bd9Sstevel@tonic-gate 					  if (nat->in_redir == NAT_REDIRECT)
5517c478bd9Sstevel@tonic-gate 						nat->in_pmin = htons($3.p1);
5527c478bd9Sstevel@tonic-gate 					}
5537c478bd9Sstevel@tonic-gate 	;
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate daddr:	addr				{ if (nat->in_redir == NAT_REDIRECT) {
556d6c23f6fSyx160601 						bcopy(&$1.a, &nat->in_out[0],
557d6c23f6fSyx160601 							sizeof($1.a));
558d6c23f6fSyx160601 						bcopy(&$1.m, &nat->in_out[1],
559d6c23f6fSyx160601 							sizeof($1.a));
5607c478bd9Sstevel@tonic-gate 					  } else {
561d6c23f6fSyx160601 						bcopy(&$1.a, &nat->in_src[0],
562d6c23f6fSyx160601 							sizeof($1.a));
563d6c23f6fSyx160601 						bcopy(&$1.m, &nat->in_src[1],
564d6c23f6fSyx160601 							sizeof($1.a));
5657c478bd9Sstevel@tonic-gate 					  }
566d6c23f6fSyx160601 					  $$ = $1.v;
5677c478bd9Sstevel@tonic-gate 					}
5687c478bd9Sstevel@tonic-gate 	;
5697c478bd9Sstevel@tonic-gate 
570d6c23f6fSyx160601 addr:	IPNY_ANY			{ yyexpectaddr = 0;
571d6c23f6fSyx160601 					  bzero(&$$.a, sizeof($$.a));
572d6c23f6fSyx160601 					  bzero(&$$.m, sizeof($$.a));
573d6c23f6fSyx160601 					  $$.v = nat->in_v;
574d6c23f6fSyx160601 					}
575d6c23f6fSyx160601 	| hostname			{ $$.a = $1.a;
576d6c23f6fSyx160601 					  $$.v = $1.v;
577d6c23f6fSyx160601 					  if ($$.v == 4) {
578d6c23f6fSyx160601 						$$.m.in4.s_addr = 0xffffffff;
579d6c23f6fSyx160601 					  } else {
580d6c23f6fSyx160601 						$$.m.i6[0] = 0xffffffff;
581d6c23f6fSyx160601 						$$.m.i6[1] = 0xffffffff;
582d6c23f6fSyx160601 						$$.m.i6[2] = 0xffffffff;
583d6c23f6fSyx160601 						$$.m.i6[3] = 0xffffffff;
584d6c23f6fSyx160601 					  }
585d6c23f6fSyx160601 					  yyexpectaddr = 0;
586d6c23f6fSyx160601 					}
587d6c23f6fSyx160601 	| hostname '/' YY_NUMBER	{ $$.a = $1.a;
588d6c23f6fSyx160601 					  if ($1.v == 0) {
589d6c23f6fSyx160601 						if ($1.a.in4.s_addr != 0)
590d6c23f6fSyx160601 							yyerror("invalid addr");
591d6c23f6fSyx160601 						if ($3 == 0 || $3 == 32)
592d6c23f6fSyx160601 							$1.v = 4;
593d6c23f6fSyx160601 						else if ($3 == 128)
594d6c23f6fSyx160601 							$1.v = 6;
595d6c23f6fSyx160601 						else
596d6c23f6fSyx160601 							yyerror("invalid mask");
597d6c23f6fSyx160601 						nat->in_v = $1.v;
598d6c23f6fSyx160601 					  }
599d6c23f6fSyx160601 					  ntomask($1.v, $3, (u_32_t *)&$$.m);
600d6c23f6fSyx160601 					  $$.a.i6[0] &= $$.m.i6[0];
601d6c23f6fSyx160601 					  $$.a.i6[1] &= $$.m.i6[1];
602d6c23f6fSyx160601 					  $$.a.i6[2] &= $$.m.i6[2];
603d6c23f6fSyx160601 					  $$.a.i6[3] &= $$.m.i6[3];
604d6c23f6fSyx160601 					  $$.v = $1.v;
605d6c23f6fSyx160601 					  yyexpectaddr = 0;
606d6c23f6fSyx160601 					}
607d6c23f6fSyx160601 	| hostname '/' ipaddr		{ if ($1.v != $3.v) {
608d6c23f6fSyx160601 						yyerror("1.address family "
609d6c23f6fSyx160601 							"mismatch");
610d6c23f6fSyx160601 					  }
611d6c23f6fSyx160601 					  $$.a = $1.a;
612d6c23f6fSyx160601 					  $$.m = $3.a;
613d6c23f6fSyx160601 					  $$.a.i6[0] &= $$.m.i6[0];
614d6c23f6fSyx160601 					  $$.a.i6[1] &= $$.m.i6[1];
615d6c23f6fSyx160601 					  $$.a.i6[2] &= $$.m.i6[2];
616d6c23f6fSyx160601 					  $$.a.i6[3] &= $$.m.i6[3];
617d6c23f6fSyx160601 					  $$.v = $1.v;
618d6c23f6fSyx160601 					  yyexpectaddr = 0;
619d6c23f6fSyx160601 					}
620d6c23f6fSyx160601 	| hostname '/' hexnumber	{ $$.a = $1.a;
621d6c23f6fSyx160601 					  $$.m.in4.s_addr = htonl($3);
622d6c23f6fSyx160601 					  $$.a.in4.s_addr &= $$.m.in4.s_addr;
623d6c23f6fSyx160601 					  $$.v = 4;
624d6c23f6fSyx160601 					}
625d6c23f6fSyx160601 	| hostname IPNY_MASK ipaddr	{ if ($1.v != $3.v) {
626d6c23f6fSyx160601 						yyerror("2.address family "
627d6c23f6fSyx160601 							"mismatch");
628d6c23f6fSyx160601 					  }
629d6c23f6fSyx160601 					  $$.a = $1.a;
630d6c23f6fSyx160601 					  $$.m = $3.a;
631d6c23f6fSyx160601 					  $$.a.i6[0] &= $$.m.i6[0];
632d6c23f6fSyx160601 					  $$.a.i6[1] &= $$.m.i6[1];
633d6c23f6fSyx160601 					  $$.a.i6[2] &= $$.m.i6[2];
634d6c23f6fSyx160601 					  $$.a.i6[3] &= $$.m.i6[3];
635d6c23f6fSyx160601 					  $$.v = $1.v;
636d6c23f6fSyx160601 					  yyexpectaddr = 0;
637d6c23f6fSyx160601 					}
638d6c23f6fSyx160601 	| hostname IPNY_MASK hexnumber	{ $$.a = $1.a;
639d6c23f6fSyx160601 					  $$.m.in4.s_addr = htonl($3);
640d6c23f6fSyx160601 					  $$.a.in4.s_addr &= $$.m.in4.s_addr;
641d6c23f6fSyx160601 					  $$.v = 4;
642d6c23f6fSyx160601 					}
6437c478bd9Sstevel@tonic-gate 	;
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate portstuff:
646ab25eeb5Syz155240 	compare portspec		{ $$.pc = $1; $$.p1 = $2; }
647ef292b7fSjojemann 	| portspec range portspec	{ $$.pc = $2; $$.p1 = $1; $$.p2 = $3; }
6487c478bd9Sstevel@tonic-gate 	;
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate mapoptions:
651ab25eeb5Syz155240 	rr frag age mssclamp nattag setproto
6527c478bd9Sstevel@tonic-gate 	;
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate rdroptions:
6557c478bd9Sstevel@tonic-gate 	rr frag age sticky mssclamp rdrproxy nattag
6567c478bd9Sstevel@tonic-gate 	;
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate nattag:	| IPNY_TAG YY_STR		{ strncpy(nat->in_tag.ipt_tag, $2,
6597c478bd9Sstevel@tonic-gate 						  sizeof(nat->in_tag.ipt_tag));
6607c478bd9Sstevel@tonic-gate 					}
661*ab073b32Sdr146992 
6627c478bd9Sstevel@tonic-gate rr:	| IPNY_ROUNDROBIN		{ nat->in_flags |= IPN_ROUNDR; }
6637c478bd9Sstevel@tonic-gate 	;
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate frag:	| IPNY_FRAG			{ nat->in_flags |= IPN_FRAG; }
6667c478bd9Sstevel@tonic-gate 	;
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate age:	| IPNY_AGE YY_NUMBER			{ nat->in_age[0] = $2;
6697c478bd9Sstevel@tonic-gate 						  nat->in_age[1] = $2; }
6707c478bd9Sstevel@tonic-gate 	| IPNY_AGE YY_NUMBER '/' YY_NUMBER	{ nat->in_age[0] = $2;
6717c478bd9Sstevel@tonic-gate 						  nat->in_age[1] = $4; }
6727c478bd9Sstevel@tonic-gate 	;
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate sticky:	| IPNY_STICKY			{ if (!(nat->in_flags & IPN_ROUNDR) &&
6757c478bd9Sstevel@tonic-gate 					      !(nat->in_flags & IPN_SPLIT)) {
6767c478bd9Sstevel@tonic-gate 						fprintf(stderr,
6777c478bd9Sstevel@tonic-gate 		"'sticky' for use with round-robin/IP splitting only\n");
6787c478bd9Sstevel@tonic-gate 					  } else
6797c478bd9Sstevel@tonic-gate 						nat->in_flags |= IPN_STICKY;
6807c478bd9Sstevel@tonic-gate 					}
6817c478bd9Sstevel@tonic-gate 	;
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate mssclamp:
6847c478bd9Sstevel@tonic-gate 	| IPNY_MSSCLAMP YY_NUMBER		{ nat->in_mssclamp = $2; }
6857c478bd9Sstevel@tonic-gate 	;
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate tcpudp:	| IPNY_TCP			{ setnatproto(IPPROTO_TCP); }
6887c478bd9Sstevel@tonic-gate 	| IPNY_UDP			{ setnatproto(IPPROTO_UDP); }
6897c478bd9Sstevel@tonic-gate 	| IPNY_TCPUDP			{ nat->in_flags |= IPN_TCPUDP;
6907c478bd9Sstevel@tonic-gate 					  nat->in_p = 0;
6917c478bd9Sstevel@tonic-gate 					}
6927c478bd9Sstevel@tonic-gate 	| IPNY_TCP '/' IPNY_UDP		{ nat->in_flags |= IPN_TCPUDP;
6937c478bd9Sstevel@tonic-gate 					  nat->in_p = 0;
6947c478bd9Sstevel@tonic-gate 					}
6957c478bd9Sstevel@tonic-gate 	;
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate rdrproxy:
698ab25eeb5Syz155240 	IPNY_PROXY YY_STR
6997c478bd9Sstevel@tonic-gate 					{ strncpy(nat->in_plabel, $2,
7007c478bd9Sstevel@tonic-gate 						  sizeof(nat->in_plabel));
7017c478bd9Sstevel@tonic-gate 					  nat->in_dport = nat->in_pnext;
702ab25eeb5Syz155240 					  nat->in_dport = htons(nat->in_dport);
7037c478bd9Sstevel@tonic-gate 					  free($2);
7047c478bd9Sstevel@tonic-gate 					}
7057c478bd9Sstevel@tonic-gate 	| proxy				{ if (nat->in_plabel[0] != '\0') {
7067c478bd9Sstevel@tonic-gate 						  nat->in_pmin = nat->in_dport;
7077c478bd9Sstevel@tonic-gate 						  nat->in_pmax = nat->in_pmin;
7087c478bd9Sstevel@tonic-gate 						  nat->in_pnext = nat->in_pmin;
7097c478bd9Sstevel@tonic-gate 					  }
7107c478bd9Sstevel@tonic-gate 					}
7117c478bd9Sstevel@tonic-gate 	;
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate proto:	YY_NUMBER			{ $$ = $1; }
7147c478bd9Sstevel@tonic-gate 	| IPNY_TCP			{ $$ = IPPROTO_TCP; }
7157c478bd9Sstevel@tonic-gate 	| IPNY_UDP			{ $$ = IPPROTO_UDP; }
7167c478bd9Sstevel@tonic-gate 	| YY_STR			{ $$ = getproto($1); free($1); }
7177c478bd9Sstevel@tonic-gate 	;
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate hexnumber:
7207c478bd9Sstevel@tonic-gate 	YY_HEX				{ $$ = $1; }
7217c478bd9Sstevel@tonic-gate 	;
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate hostname:
724d6c23f6fSyx160601 	YY_STR				{ i6addr_t addr;
725d6c23f6fSyx160601 					  if (gethost($1, &addr, 0) == 0) {
726d6c23f6fSyx160601 						$$.a = addr;
727d6c23f6fSyx160601 						$$.v = 4;
728d6c23f6fSyx160601 					  } else
729d6c23f6fSyx160601 					  if (gethost($1, &addr, 1) == 0) {
730d6c23f6fSyx160601 						$$.a = addr;
731d6c23f6fSyx160601 						$$.v = 6;
732d6c23f6fSyx160601 					  } else {
7339b4c7145Sjojemann 						yyerror("Unknown hostname");
7347c478bd9Sstevel@tonic-gate 					  }
735d6c23f6fSyx160601 					  if ($$.v != 0)
736d6c23f6fSyx160601 						nat->in_v = $$.v;
737d6c23f6fSyx160601 					  free($1);
738d6c23f6fSyx160601 					}
739d6c23f6fSyx160601 	| YY_NUMBER			{ bzero(&$$.a, sizeof($$.a));
740d6c23f6fSyx160601 					  $$.a.in4.s_addr = htonl($1);
741d6c23f6fSyx160601 					  if ($$.a.in4.s_addr != 0)
742d6c23f6fSyx160601 						$$.v = 4;
743d6c23f6fSyx160601 					  else
744d6c23f6fSyx160601 						$$.v = nat->in_v;
745d6c23f6fSyx160601 					  if ($$.v != 0)
746d6c23f6fSyx160601 						nat->in_v = $$.v;
747d6c23f6fSyx160601 					}
748d6c23f6fSyx160601 	| ipv4				{ $$ = $1;
749d6c23f6fSyx160601 					  nat->in_v = 4;
750d6c23f6fSyx160601 					}
751d6c23f6fSyx160601 	| YY_IPV6			{ $$.a = $1;
752d6c23f6fSyx160601 					  $$.v = 6;
753d6c23f6fSyx160601 					  nat->in_v = 6;
754d6c23f6fSyx160601 					}
755d6c23f6fSyx160601 	| YY_NUMBER YY_IPV6		{ $$.a = $2;
756d6c23f6fSyx160601 					  $$.v = 6;
757d6c23f6fSyx160601 					}
7587c478bd9Sstevel@tonic-gate 	;
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate compare:
7617c478bd9Sstevel@tonic-gate 	'='				{ $$ = FR_EQUAL; }
7627c478bd9Sstevel@tonic-gate 	| YY_CMP_EQ			{ $$ = FR_EQUAL; }
7637c478bd9Sstevel@tonic-gate 	| YY_CMP_NE			{ $$ = FR_NEQUAL; }
7647c478bd9Sstevel@tonic-gate 	| YY_CMP_LT			{ $$ = FR_LESST; }
7657c478bd9Sstevel@tonic-gate 	| YY_CMP_LE			{ $$ = FR_LESSTE; }
7667c478bd9Sstevel@tonic-gate 	| YY_CMP_GT			{ $$ = FR_GREATERT; }
7677c478bd9Sstevel@tonic-gate 	| YY_CMP_GE			{ $$ = FR_GREATERTE; }
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate range:
7707c478bd9Sstevel@tonic-gate 	YY_RANGE_OUT			{ $$ = FR_OUTRANGE; }
7717c478bd9Sstevel@tonic-gate 	| YY_RANGE_IN			{ $$ = FR_INRANGE; }
7727c478bd9Sstevel@tonic-gate 	;
7737c478bd9Sstevel@tonic-gate 
774d6c23f6fSyx160601 ipaddr:	ipv4				{ $$ = $1; }
775d6c23f6fSyx160601 	| YY_IPV6			{ $$.a = $1;
776d6c23f6fSyx160601 					  $$.v = 6;
777d6c23f6fSyx160601 					}
778d6c23f6fSyx160601 	;
779d6c23f6fSyx160601 
7807c478bd9Sstevel@tonic-gate ipv4:	YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
7817c478bd9Sstevel@tonic-gate 		{ if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
7827c478bd9Sstevel@tonic-gate 			yyerror("Invalid octet string for IP address");
7837c478bd9Sstevel@tonic-gate 			return 0;
7847c478bd9Sstevel@tonic-gate 		  }
785d6c23f6fSyx160601 		  $$.a.in4.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
786d6c23f6fSyx160601 		  $$.a.in4.s_addr = htonl($$.a.in4.s_addr);
787d6c23f6fSyx160601 		  $$.v = 4;
7887c478bd9Sstevel@tonic-gate 		}
7897c478bd9Sstevel@tonic-gate 	;
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate %%
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate 
7947c478bd9Sstevel@tonic-gate static	wordtab_t	yywords[] = {
7957c478bd9Sstevel@tonic-gate 	{ "age",	IPNY_AGE },
7967c478bd9Sstevel@tonic-gate 	{ "any",	IPNY_ANY },
7977c478bd9Sstevel@tonic-gate 	{ "auto",	IPNY_AUTO },
7987c478bd9Sstevel@tonic-gate 	{ "bimap",	IPNY_BIMAP },
7997c478bd9Sstevel@tonic-gate 	{ "frag",	IPNY_FRAG },
8007c478bd9Sstevel@tonic-gate 	{ "from",	IPNY_FROM },
8017c478bd9Sstevel@tonic-gate 	{ "icmpidmap",	IPNY_ICMPIDMAP },
8027c478bd9Sstevel@tonic-gate 	{ "mask",	IPNY_MASK },
8037c478bd9Sstevel@tonic-gate 	{ "map",	IPNY_MAP },
8047c478bd9Sstevel@tonic-gate 	{ "map-block",	IPNY_MAPBLOCK },
8057c478bd9Sstevel@tonic-gate 	{ "mssclamp",	IPNY_MSSCLAMP },
806ab25eeb5Syz155240 	{ "netmask",	IPNY_MASK },
8077c478bd9Sstevel@tonic-gate 	{ "port",	IPNY_PORT },
8087c478bd9Sstevel@tonic-gate 	{ "portmap",	IPNY_PORTMAP },
8097c478bd9Sstevel@tonic-gate 	{ "ports",	IPNY_PORTS },
8107c478bd9Sstevel@tonic-gate 	{ "proxy",	IPNY_PROXY },
8117c478bd9Sstevel@tonic-gate 	{ "range",	IPNY_RANGE },
8127c478bd9Sstevel@tonic-gate 	{ "rdr",	IPNY_RDR },
8137c478bd9Sstevel@tonic-gate 	{ "round-robin",IPNY_ROUNDROBIN },
814*ab073b32Sdr146992 	{ "sequential",	IPNY_SEQUENTIAL },
8157c478bd9Sstevel@tonic-gate 	{ "sticky",	IPNY_STICKY },
8167c478bd9Sstevel@tonic-gate 	{ "tag",	IPNY_TAG },
8177c478bd9Sstevel@tonic-gate 	{ "tcp",	IPNY_TCP },
818ab25eeb5Syz155240 	{ "tcpudp",	IPNY_TCPUDP },
8197c478bd9Sstevel@tonic-gate 	{ "to",		IPNY_TO },
8207c478bd9Sstevel@tonic-gate 	{ "udp",	IPNY_UDP },
8217c478bd9Sstevel@tonic-gate 	{ "-",		'-' },
8227c478bd9Sstevel@tonic-gate 	{ "->",		IPNY_TLATE },
8237c478bd9Sstevel@tonic-gate 	{ "eq",		YY_CMP_EQ },
8247c478bd9Sstevel@tonic-gate 	{ "ne",		YY_CMP_NE },
8257c478bd9Sstevel@tonic-gate 	{ "lt",		YY_CMP_LT },
8267c478bd9Sstevel@tonic-gate 	{ "gt",		YY_CMP_GT },
8277c478bd9Sstevel@tonic-gate 	{ "le",		YY_CMP_LE },
8287c478bd9Sstevel@tonic-gate 	{ "ge",		YY_CMP_GE },
8297c478bd9Sstevel@tonic-gate 	{ NULL,		0 }
8307c478bd9Sstevel@tonic-gate };
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate int ipnat_parsefile(fd, addfunc, ioctlfunc, filename)
8347c478bd9Sstevel@tonic-gate int fd;
8357c478bd9Sstevel@tonic-gate addfunc_t addfunc;
8367c478bd9Sstevel@tonic-gate ioctlfunc_t ioctlfunc;
8377c478bd9Sstevel@tonic-gate char *filename;
8387c478bd9Sstevel@tonic-gate {
8397c478bd9Sstevel@tonic-gate 	FILE *fp = NULL;
8407c478bd9Sstevel@tonic-gate 	char *s;
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate 	(void) yysettab(yywords);
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate 	s = getenv("YYDEBUG");
8457c478bd9Sstevel@tonic-gate 	if (s)
8467c478bd9Sstevel@tonic-gate 		yydebug = atoi(s);
8477c478bd9Sstevel@tonic-gate 	else
8487c478bd9Sstevel@tonic-gate 		yydebug = 0;
8497c478bd9Sstevel@tonic-gate 
8507c478bd9Sstevel@tonic-gate 	if (strcmp(filename, "-")) {
8517c478bd9Sstevel@tonic-gate 		fp = fopen(filename, "r");
8527c478bd9Sstevel@tonic-gate 		if (!fp) {
8537c478bd9Sstevel@tonic-gate 			fprintf(stderr, "fopen(%s) failed: %s\n", filename,
8547c478bd9Sstevel@tonic-gate 				STRERROR(errno));
8557c478bd9Sstevel@tonic-gate 			return -1;
8567c478bd9Sstevel@tonic-gate 		}
8577c478bd9Sstevel@tonic-gate 	} else
8587c478bd9Sstevel@tonic-gate 		fp = stdin;
8597c478bd9Sstevel@tonic-gate 
8607c478bd9Sstevel@tonic-gate 	while (ipnat_parsesome(fd, addfunc, ioctlfunc, fp) == 1)
8617c478bd9Sstevel@tonic-gate 		;
8627c478bd9Sstevel@tonic-gate 	if (fp != NULL)
8637c478bd9Sstevel@tonic-gate 		fclose(fp);
8647c478bd9Sstevel@tonic-gate 	return 0;
8657c478bd9Sstevel@tonic-gate }
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate 
8687c478bd9Sstevel@tonic-gate int ipnat_parsesome(fd, addfunc, ioctlfunc, fp)
8697c478bd9Sstevel@tonic-gate int fd;
8707c478bd9Sstevel@tonic-gate addfunc_t addfunc;
8717c478bd9Sstevel@tonic-gate ioctlfunc_t ioctlfunc;
8727c478bd9Sstevel@tonic-gate FILE *fp;
8737c478bd9Sstevel@tonic-gate {
8747c478bd9Sstevel@tonic-gate 	char *s;
8757c478bd9Sstevel@tonic-gate 	int i;
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate 	yylineNum = 1;
8787c478bd9Sstevel@tonic-gate 
8797c478bd9Sstevel@tonic-gate 	natfd = fd;
8807c478bd9Sstevel@tonic-gate 	nataddfunc = addfunc;
8817c478bd9Sstevel@tonic-gate 	natioctlfunc = ioctlfunc;
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate 	if (feof(fp))
8847c478bd9Sstevel@tonic-gate 		return 0;
8857c478bd9Sstevel@tonic-gate 	i = fgetc(fp);
8867c478bd9Sstevel@tonic-gate 	if (i == EOF)
8877c478bd9Sstevel@tonic-gate 		return 0;
8887c478bd9Sstevel@tonic-gate 	if (ungetc(i, fp) == EOF)
8897c478bd9Sstevel@tonic-gate 		return 0;
8907c478bd9Sstevel@tonic-gate 	if (feof(fp))
8917c478bd9Sstevel@tonic-gate 		return 0;
8927c478bd9Sstevel@tonic-gate 	s = getenv("YYDEBUG");
8937c478bd9Sstevel@tonic-gate 	if (s)
8947c478bd9Sstevel@tonic-gate 		yydebug = atoi(s);
8957c478bd9Sstevel@tonic-gate 	else
8967c478bd9Sstevel@tonic-gate 		yydebug = 0;
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 	yyin = fp;
8997c478bd9Sstevel@tonic-gate 	yyparse();
9007c478bd9Sstevel@tonic-gate 	return 1;
9017c478bd9Sstevel@tonic-gate }
9027c478bd9Sstevel@tonic-gate 
9037c478bd9Sstevel@tonic-gate 
9047c478bd9Sstevel@tonic-gate static void newnatrule()
9057c478bd9Sstevel@tonic-gate {
9067c478bd9Sstevel@tonic-gate 	ipnat_t *n;
9077c478bd9Sstevel@tonic-gate 
9087c478bd9Sstevel@tonic-gate 	n = calloc(1, sizeof(*n));
9097c478bd9Sstevel@tonic-gate 	if (n == NULL)
9107c478bd9Sstevel@tonic-gate 		return;
9117c478bd9Sstevel@tonic-gate 
9127c478bd9Sstevel@tonic-gate 	if (nat == NULL)
9137c478bd9Sstevel@tonic-gate 		nattop = nat = n;
9147c478bd9Sstevel@tonic-gate 	else {
9157c478bd9Sstevel@tonic-gate 		nat->in_next = n;
9167c478bd9Sstevel@tonic-gate 		nat = n;
9177c478bd9Sstevel@tonic-gate 	}
9187c478bd9Sstevel@tonic-gate }
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate static void setnatproto(p)
9227c478bd9Sstevel@tonic-gate int p;
9237c478bd9Sstevel@tonic-gate {
9247c478bd9Sstevel@tonic-gate 	nat->in_p = p;
9257c478bd9Sstevel@tonic-gate 
9267c478bd9Sstevel@tonic-gate 	switch (p)
9277c478bd9Sstevel@tonic-gate 	{
9287c478bd9Sstevel@tonic-gate 	case IPPROTO_TCP :
9297c478bd9Sstevel@tonic-gate 		nat->in_flags |= IPN_TCP;
9307c478bd9Sstevel@tonic-gate 		nat->in_flags &= ~IPN_UDP;
9317c478bd9Sstevel@tonic-gate 		break;
9327c478bd9Sstevel@tonic-gate 	case IPPROTO_UDP :
9337c478bd9Sstevel@tonic-gate 		nat->in_flags |= IPN_UDP;
9347c478bd9Sstevel@tonic-gate 		nat->in_flags &= ~IPN_TCP;
9357c478bd9Sstevel@tonic-gate 		break;
936ab25eeb5Syz155240 	case IPPROTO_ICMP :
937ab25eeb5Syz155240 		nat->in_flags &= ~IPN_TCPUDP;
938ab25eeb5Syz155240 		if (!(nat->in_flags & IPN_ICMPQUERY)) {
939ab25eeb5Syz155240 			nat->in_dcmp = 0;
940ab25eeb5Syz155240 			nat->in_scmp = 0;
941ab25eeb5Syz155240 			nat->in_pmin = 0;
942ab25eeb5Syz155240 			nat->in_pmax = 0;
943ab25eeb5Syz155240 			nat->in_pnext = 0;
944ab25eeb5Syz155240 		}
945ab25eeb5Syz155240 		break;
9467c478bd9Sstevel@tonic-gate 	default :
9477c478bd9Sstevel@tonic-gate 		if ((nat->in_redir & NAT_MAPBLK) == 0) {
948ab25eeb5Syz155240 			/* Only reset dcmp/scmp in case dport/sport not set */
949ab25eeb5Syz155240 			if (0 == nat->in_tuc.ftu_dport)
950ab25eeb5Syz155240 				nat->in_dcmp = 0;
951ab25eeb5Syz155240 			if (0 == nat->in_tuc.ftu_sport)
952ab25eeb5Syz155240 				nat->in_scmp = 0;
9537c478bd9Sstevel@tonic-gate 			nat->in_pmin = 0;
9547c478bd9Sstevel@tonic-gate 			nat->in_pmax = 0;
9557c478bd9Sstevel@tonic-gate 			nat->in_pnext = 0;
9567c478bd9Sstevel@tonic-gate 			nat->in_flags &= ~IPN_TCPUDP;
9577c478bd9Sstevel@tonic-gate 		}
9587c478bd9Sstevel@tonic-gate 		break;
9597c478bd9Sstevel@tonic-gate 	}
960ab25eeb5Syz155240 
961ab25eeb5Syz155240 	if ((nat->in_flags & (IPN_TCPUDP|IPN_FIXEDDPORT)) == IPN_FIXEDDPORT)
962ab25eeb5Syz155240 		nat->in_flags &= ~IPN_FIXEDDPORT;
9637c478bd9Sstevel@tonic-gate }
9647c478bd9Sstevel@tonic-gate 
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate void ipnat_addrule(fd, ioctlfunc, ptr)
9677c478bd9Sstevel@tonic-gate int fd;
9687c478bd9Sstevel@tonic-gate ioctlfunc_t ioctlfunc;
9697c478bd9Sstevel@tonic-gate void *ptr;
9707c478bd9Sstevel@tonic-gate {
971ab25eeb5Syz155240 	ioctlcmd_t add, del;
9727c478bd9Sstevel@tonic-gate 	ipfobj_t obj;
9737c478bd9Sstevel@tonic-gate 	ipnat_t *ipn;
9747c478bd9Sstevel@tonic-gate 
9757c478bd9Sstevel@tonic-gate 	ipn = ptr;
9767c478bd9Sstevel@tonic-gate 	bzero((char *)&obj, sizeof(obj));
9777c478bd9Sstevel@tonic-gate 	obj.ipfo_rev = IPFILTER_VERSION;
9787c478bd9Sstevel@tonic-gate 	obj.ipfo_size = sizeof(ipnat_t);
9797c478bd9Sstevel@tonic-gate 	obj.ipfo_type = IPFOBJ_IPNAT;
9807c478bd9Sstevel@tonic-gate 	obj.ipfo_ptr = ptr;
9817c478bd9Sstevel@tonic-gate 	add = 0;
9827c478bd9Sstevel@tonic-gate 	del = 0;
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate 	if ((opts & OPT_DONOTHING) != 0)
9857c478bd9Sstevel@tonic-gate 		fd = -1;
9867c478bd9Sstevel@tonic-gate 
9877c478bd9Sstevel@tonic-gate 	if (opts & OPT_ZERORULEST) {
9887c478bd9Sstevel@tonic-gate 		add = SIOCZRLST;
9897c478bd9Sstevel@tonic-gate 	} else if (opts & OPT_INACTIVE) {
9907c478bd9Sstevel@tonic-gate 		add = SIOCADNAT;
9917c478bd9Sstevel@tonic-gate 		del = SIOCRMNAT;
9927c478bd9Sstevel@tonic-gate 	} else {
9937c478bd9Sstevel@tonic-gate 		add = SIOCADNAT;
9947c478bd9Sstevel@tonic-gate 		del = SIOCRMNAT;
9957c478bd9Sstevel@tonic-gate 	}
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate 	if (ipn && (opts & OPT_VERBOSE))
9987c478bd9Sstevel@tonic-gate 		printnat(ipn, opts);
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate 	if (opts & OPT_DEBUG)
10017c478bd9Sstevel@tonic-gate 		binprint(ipn, sizeof(*ipn));
10027c478bd9Sstevel@tonic-gate 
10037c478bd9Sstevel@tonic-gate 	if ((opts & OPT_ZERORULEST) != 0) {
10047c478bd9Sstevel@tonic-gate 		if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
10057c478bd9Sstevel@tonic-gate 			if ((opts & OPT_DONOTHING) == 0) {
10067c478bd9Sstevel@tonic-gate 				fprintf(stderr, "%d:", yylineNum);
10077c478bd9Sstevel@tonic-gate 				perror("ioctl(SIOCZRLST)");
10087c478bd9Sstevel@tonic-gate 			}
10097c478bd9Sstevel@tonic-gate 		} else {
10107c478bd9Sstevel@tonic-gate #ifdef	USE_QUAD_T
10117c478bd9Sstevel@tonic-gate /*
10127c478bd9Sstevel@tonic-gate 			printf("hits %qd bytes %qd ",
10137c478bd9Sstevel@tonic-gate 				(long long)fr->fr_hits,
10147c478bd9Sstevel@tonic-gate 				(long long)fr->fr_bytes);
10157c478bd9Sstevel@tonic-gate */
10167c478bd9Sstevel@tonic-gate #else
10177c478bd9Sstevel@tonic-gate /*
10187c478bd9Sstevel@tonic-gate 			printf("hits %ld bytes %ld ",
10197c478bd9Sstevel@tonic-gate 				fr->fr_hits, fr->fr_bytes);
10207c478bd9Sstevel@tonic-gate */
10217c478bd9Sstevel@tonic-gate #endif
10227c478bd9Sstevel@tonic-gate 			printnat(ipn, opts);
10237c478bd9Sstevel@tonic-gate 		}
10247c478bd9Sstevel@tonic-gate 	} else if ((opts & OPT_REMOVE) != 0) {
10257c478bd9Sstevel@tonic-gate 		if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) {
10267c478bd9Sstevel@tonic-gate 			if ((opts & OPT_DONOTHING) == 0) {
10277c478bd9Sstevel@tonic-gate 				fprintf(stderr, "%d:", yylineNum);
10287c478bd9Sstevel@tonic-gate 				perror("ioctl(delete nat rule)");
10297c478bd9Sstevel@tonic-gate 			}
10307c478bd9Sstevel@tonic-gate 		}
10317c478bd9Sstevel@tonic-gate 	} else {
10327c478bd9Sstevel@tonic-gate 		if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
10337c478bd9Sstevel@tonic-gate 			if ((opts & OPT_DONOTHING) == 0) {
10347c478bd9Sstevel@tonic-gate 				fprintf(stderr, "%d:", yylineNum);
10357c478bd9Sstevel@tonic-gate 				perror("ioctl(add/insert nat rule)");
10367c478bd9Sstevel@tonic-gate 			}
10377c478bd9Sstevel@tonic-gate 		}
10387c478bd9Sstevel@tonic-gate 	}
10397c478bd9Sstevel@tonic-gate }
10409b4c7145Sjojemann 
1041