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