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
ipnat_parsefile(fd,addfunc,ioctlfunc,filename)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
ipnat_parsesome(fd,addfunc,ioctlfunc,fp)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
newnatrule()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
setnatproto(p)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
ipnat_addrule(fd,ioctlfunc,ptr)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