17c478bd9Sstevel@tonic-gate %{ 2*6aed92a9Syx /* 3*6aed92a9Syx * Copyright (C) 2003 by Darren Reed. 4*6aed92a9Syx * 5*6aed92a9Syx * See the IPFILTER.LICENCE file for details on licencing. 6*6aed92a9Syx * 7*6aed92a9Syx * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 8*6aed92a9Syx * Use is subject to license terms. 9*6aed92a9Syx */ 10*6aed92a9Syx 11*6aed92a9Syx #pragma ident "%Z%%M% %I% %E% SMI" 12*6aed92a9Syx 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 #ifdef IPFILTER_BPF 387c478bd9Sstevel@tonic-gate # include <net/bpf.h> 397c478bd9Sstevel@tonic-gate # include <pcap-int.h> 407c478bd9Sstevel@tonic-gate # include <pcap.h> 417c478bd9Sstevel@tonic-gate #endif 427c478bd9Sstevel@tonic-gate #include <netinet/in.h> 437c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h> 447c478bd9Sstevel@tonic-gate #include <sys/time.h> 457c478bd9Sstevel@tonic-gate #include <syslog.h> 467c478bd9Sstevel@tonic-gate #include <net/if.h> 477c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 300000 487c478bd9Sstevel@tonic-gate # include <net/if_var.h> 497c478bd9Sstevel@tonic-gate #endif 507c478bd9Sstevel@tonic-gate #include <netinet/ip.h> 517c478bd9Sstevel@tonic-gate #include <netinet/ip_icmp.h> 527c478bd9Sstevel@tonic-gate #include <netdb.h> 537c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 547c478bd9Sstevel@tonic-gate #include <resolv.h> 557c478bd9Sstevel@tonic-gate #include "ipf.h" 567c478bd9Sstevel@tonic-gate #if SOLARIS2 >= 10 577c478bd9Sstevel@tonic-gate #include "ipl.h" 587c478bd9Sstevel@tonic-gate #else 597c478bd9Sstevel@tonic-gate #include "netinet/ipl.h" 607c478bd9Sstevel@tonic-gate #endif 617c478bd9Sstevel@tonic-gate #include "ipnat_l.h" 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate #define YYDEBUG 1 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate extern void yyerror __P((char *)); 667c478bd9Sstevel@tonic-gate extern int yyparse __P((void)); 677c478bd9Sstevel@tonic-gate extern int yylex __P((void)); 687c478bd9Sstevel@tonic-gate extern int yydebug; 697c478bd9Sstevel@tonic-gate extern FILE *yyin; 707c478bd9Sstevel@tonic-gate extern int yylineNum; 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate static ipnat_t *nattop = NULL; 737c478bd9Sstevel@tonic-gate static ipnat_t *nat = NULL; 747c478bd9Sstevel@tonic-gate static int natfd = -1; 757c478bd9Sstevel@tonic-gate static ioctlfunc_t natioctlfunc = NULL; 767c478bd9Sstevel@tonic-gate static addfunc_t nataddfunc = NULL; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate static void newnatrule __P((void)); 797c478bd9Sstevel@tonic-gate static void setnatproto __P((int)); 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate %} 827c478bd9Sstevel@tonic-gate %union { 837c478bd9Sstevel@tonic-gate char *str; 847c478bd9Sstevel@tonic-gate u_32_t num; 857c478bd9Sstevel@tonic-gate struct in_addr ipa; 867c478bd9Sstevel@tonic-gate frentry_t fr; 877c478bd9Sstevel@tonic-gate frtuc_t *frt; 887c478bd9Sstevel@tonic-gate struct { 897c478bd9Sstevel@tonic-gate u_short p1; 907c478bd9Sstevel@tonic-gate u_short p2; 917c478bd9Sstevel@tonic-gate int pc; 927c478bd9Sstevel@tonic-gate } pc; 937c478bd9Sstevel@tonic-gate struct { 947c478bd9Sstevel@tonic-gate struct in_addr a; 957c478bd9Sstevel@tonic-gate struct in_addr m; 967c478bd9Sstevel@tonic-gate } ipp; 977c478bd9Sstevel@tonic-gate union i6addr ip6; 987c478bd9Sstevel@tonic-gate }; 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate %token <num> YY_NUMBER YY_HEX 1017c478bd9Sstevel@tonic-gate %token <str> YY_STR 1027c478bd9Sstevel@tonic-gate %token YY_COMMENT 1037c478bd9Sstevel@tonic-gate %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT 1047c478bd9Sstevel@tonic-gate %token YY_RANGE_OUT YY_RANGE_IN 1057c478bd9Sstevel@tonic-gate %token <ip6> YY_IPV6 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate %token IPNY_MAPBLOCK IPNY_RDR IPNY_PORT IPNY_PORTS IPNY_AUTO IPNY_RANGE 1087c478bd9Sstevel@tonic-gate %token IPNY_MAP IPNY_BIMAP IPNY_FROM IPNY_TO IPNY_MASK IPNY_PORTMAP IPNY_ANY 1097c478bd9Sstevel@tonic-gate %token IPNY_ROUNDROBIN IPNY_FRAG IPNY_AGE IPNY_ICMPIDMAP IPNY_PROXY 1107c478bd9Sstevel@tonic-gate %token IPNY_TCP IPNY_UDP IPNY_TCPUDP IPNY_STICKY IPNY_MSSCLAMP IPNY_TAG 1117c478bd9Sstevel@tonic-gate %token IPNY_TLATE 1127c478bd9Sstevel@tonic-gate %type <num> hexnumber numports compare range proto 1137c478bd9Sstevel@tonic-gate %type <ipa> hostname ipv4 1147c478bd9Sstevel@tonic-gate %type <ipp> addr nummask rhaddr 1157c478bd9Sstevel@tonic-gate %type <pc> portstuff 1167c478bd9Sstevel@tonic-gate %% 1177c478bd9Sstevel@tonic-gate file: line 1187c478bd9Sstevel@tonic-gate | assign 1197c478bd9Sstevel@tonic-gate | file line 1207c478bd9Sstevel@tonic-gate | file assign 1217c478bd9Sstevel@tonic-gate ; 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate line: xx rule { while ((nat = nattop) != NULL) { 1247c478bd9Sstevel@tonic-gate nattop = nat->in_next; 1257c478bd9Sstevel@tonic-gate (*nataddfunc)(natfd, natioctlfunc, nat); 1267c478bd9Sstevel@tonic-gate free(nat); 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate resetlexer(); 1297c478bd9Sstevel@tonic-gate } 1307c478bd9Sstevel@tonic-gate | YY_COMMENT 1317c478bd9Sstevel@tonic-gate ; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); 1347c478bd9Sstevel@tonic-gate resetlexer(); 1357c478bd9Sstevel@tonic-gate free($1); 1367c478bd9Sstevel@tonic-gate free($3); 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate ; 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate assigning: 1417c478bd9Sstevel@tonic-gate '=' { yyvarnext = 1; } 1427c478bd9Sstevel@tonic-gate ; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate xx: { newnatrule(); } 1457c478bd9Sstevel@tonic-gate ; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate rule: map 1487c478bd9Sstevel@tonic-gate | mapblock 1497c478bd9Sstevel@tonic-gate | redir 1507c478bd9Sstevel@tonic-gate ; 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions 1537c478bd9Sstevel@tonic-gate { nat->in_inip = $3.a.s_addr; 1547c478bd9Sstevel@tonic-gate nat->in_inmsk = $3.m.s_addr; 1557c478bd9Sstevel@tonic-gate nat->in_outip = $5.a.s_addr; 1567c478bd9Sstevel@tonic-gate nat->in_outmsk = $5.m.s_addr; 1577c478bd9Sstevel@tonic-gate if (nat->in_ifnames[1][0] == '\0') 1587c478bd9Sstevel@tonic-gate strncpy(nat->in_ifnames[1], 1597c478bd9Sstevel@tonic-gate nat->in_ifnames[0], 1607c478bd9Sstevel@tonic-gate sizeof(nat->in_ifnames[0])); 1617c478bd9Sstevel@tonic-gate if ((nat->in_flags & IPN_TCPUDP) == 0) 1627c478bd9Sstevel@tonic-gate setnatproto(nat->in_p); 1637c478bd9Sstevel@tonic-gate if (((nat->in_redir & NAT_MAPBLK) != 0) || 1647c478bd9Sstevel@tonic-gate ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) 1657c478bd9Sstevel@tonic-gate nat_setgroupmap(nat); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate | mapit ifnames addr IPNY_TLATE rhaddr mapport mapoptions 1687c478bd9Sstevel@tonic-gate { nat->in_inip = $3.a.s_addr; 1697c478bd9Sstevel@tonic-gate nat->in_inmsk = $3.m.s_addr; 1707c478bd9Sstevel@tonic-gate nat->in_outip = $5.a.s_addr; 1717c478bd9Sstevel@tonic-gate nat->in_outmsk = $5.m.s_addr; 1727c478bd9Sstevel@tonic-gate if (nat->in_ifnames[1][0] == '\0') 1737c478bd9Sstevel@tonic-gate strncpy(nat->in_ifnames[1], 1747c478bd9Sstevel@tonic-gate nat->in_ifnames[0], 1757c478bd9Sstevel@tonic-gate sizeof(nat->in_ifnames[0])); 1767c478bd9Sstevel@tonic-gate if ((nat->in_flags & IPN_TCPUDP) == 0) 1777c478bd9Sstevel@tonic-gate setnatproto(nat->in_p); 1787c478bd9Sstevel@tonic-gate if (((nat->in_redir & NAT_MAPBLK) != 0) || 1797c478bd9Sstevel@tonic-gate ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) 1807c478bd9Sstevel@tonic-gate nat_setgroupmap(nat); 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate | mapit ifnames mapfrom IPNY_TLATE rhaddr proxy mapoptions 1837c478bd9Sstevel@tonic-gate { nat->in_outip = $5.a.s_addr; 1847c478bd9Sstevel@tonic-gate nat->in_outmsk = $5.m.s_addr; 1857c478bd9Sstevel@tonic-gate if (nat->in_ifnames[1][0] == '\0') 1867c478bd9Sstevel@tonic-gate strncpy(nat->in_ifnames[1], 1877c478bd9Sstevel@tonic-gate nat->in_ifnames[0], 1887c478bd9Sstevel@tonic-gate sizeof(nat->in_ifnames[0])); 1897c478bd9Sstevel@tonic-gate if ((nat->in_flags & IPN_TCPUDP) == 0) 1907c478bd9Sstevel@tonic-gate setnatproto(nat->in_p); 1917c478bd9Sstevel@tonic-gate if (((nat->in_redir & NAT_MAPBLK) != 0) || 1927c478bd9Sstevel@tonic-gate ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) 1937c478bd9Sstevel@tonic-gate nat_setgroupmap(nat); 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate | mapit ifnames mapfrom IPNY_TLATE rhaddr mapport mapoptions 1967c478bd9Sstevel@tonic-gate { nat->in_outip = $5.a.s_addr; 1977c478bd9Sstevel@tonic-gate nat->in_outmsk = $5.m.s_addr; 1987c478bd9Sstevel@tonic-gate if (nat->in_ifnames[1][0] == '\0') 1997c478bd9Sstevel@tonic-gate strncpy(nat->in_ifnames[1], 2007c478bd9Sstevel@tonic-gate nat->in_ifnames[0], 2017c478bd9Sstevel@tonic-gate sizeof(nat->in_ifnames[0])); 2027c478bd9Sstevel@tonic-gate if ((nat->in_flags & IPN_TCPUDP) == 0) 2037c478bd9Sstevel@tonic-gate setnatproto(nat->in_p); 2047c478bd9Sstevel@tonic-gate if (((nat->in_redir & NAT_MAPBLK) != 0) || 2057c478bd9Sstevel@tonic-gate ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) 2067c478bd9Sstevel@tonic-gate nat_setgroupmap(nat); 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate ; 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate mapblock: 2117c478bd9Sstevel@tonic-gate mapblockit ifnames addr IPNY_TLATE addr ports mapoptions 2127c478bd9Sstevel@tonic-gate { nat->in_inip = $3.a.s_addr; 2137c478bd9Sstevel@tonic-gate nat->in_inmsk = $3.m.s_addr; 2147c478bd9Sstevel@tonic-gate nat->in_outip = $5.a.s_addr; 2157c478bd9Sstevel@tonic-gate nat->in_outmsk = $5.m.s_addr; 2167c478bd9Sstevel@tonic-gate if (nat->in_ifnames[1][0] == '\0') 2177c478bd9Sstevel@tonic-gate strncpy(nat->in_ifnames[1], 2187c478bd9Sstevel@tonic-gate nat->in_ifnames[0], 2197c478bd9Sstevel@tonic-gate sizeof(nat->in_ifnames[0])); 2207c478bd9Sstevel@tonic-gate if ((nat->in_flags & IPN_TCPUDP) == 0) 2217c478bd9Sstevel@tonic-gate setnatproto(nat->in_p); 2227c478bd9Sstevel@tonic-gate if (((nat->in_redir & NAT_MAPBLK) != 0) || 2237c478bd9Sstevel@tonic-gate ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) 2247c478bd9Sstevel@tonic-gate nat_setgroupmap(nat); 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate ; 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate redir: rdrit ifnames addr dport IPNY_TLATE dip nport rdrproto rdroptions 2297c478bd9Sstevel@tonic-gate { nat->in_outip = $3.a.s_addr; 2307c478bd9Sstevel@tonic-gate nat->in_outmsk = $3.m.s_addr; 2317c478bd9Sstevel@tonic-gate if (nat->in_ifnames[1][0] == '\0') 2327c478bd9Sstevel@tonic-gate strncpy(nat->in_ifnames[1], 2337c478bd9Sstevel@tonic-gate nat->in_ifnames[0], 2347c478bd9Sstevel@tonic-gate sizeof(nat->in_ifnames[0])); 2357c478bd9Sstevel@tonic-gate if ((nat->in_p == 0) && 2367c478bd9Sstevel@tonic-gate ((nat->in_flags & IPN_TCPUDP) == 0) && 2377c478bd9Sstevel@tonic-gate (nat->in_pmin != 0 || 2387c478bd9Sstevel@tonic-gate nat->in_pmax != 0 || 2397c478bd9Sstevel@tonic-gate nat->in_pnext != 0)) 2407c478bd9Sstevel@tonic-gate setnatproto(IPPROTO_TCP); 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate | rdrit ifnames rdrfrom IPNY_TLATE dip nport rdrproto rdroptions 2437c478bd9Sstevel@tonic-gate { if ((nat->in_p == 0) && 2447c478bd9Sstevel@tonic-gate ((nat->in_flags & IPN_TCPUDP) == 0) && 2457c478bd9Sstevel@tonic-gate (nat->in_pmin != 0 || 2467c478bd9Sstevel@tonic-gate nat->in_pmax != 0 || 2477c478bd9Sstevel@tonic-gate nat->in_pnext != 0)) 2487c478bd9Sstevel@tonic-gate setnatproto(IPPROTO_TCP); 2497c478bd9Sstevel@tonic-gate if (nat->in_ifnames[1][0] == '\0') 2507c478bd9Sstevel@tonic-gate strncpy(nat->in_ifnames[1], 2517c478bd9Sstevel@tonic-gate nat->in_ifnames[0], 2527c478bd9Sstevel@tonic-gate sizeof(nat->in_ifnames[0])); 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate | rdrit ifnames addr IPNY_TLATE dip rdrproto rdroptions 2557c478bd9Sstevel@tonic-gate { nat->in_outip = $3.a.s_addr; 2567c478bd9Sstevel@tonic-gate nat->in_outmsk = $3.m.s_addr; 2577c478bd9Sstevel@tonic-gate if (nat->in_ifnames[1][0] == '\0') 2587c478bd9Sstevel@tonic-gate strncpy(nat->in_ifnames[1], 2597c478bd9Sstevel@tonic-gate nat->in_ifnames[0], 2607c478bd9Sstevel@tonic-gate sizeof(nat->in_ifnames[0])); 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate ; 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate proxy: | IPNY_PROXY IPNY_PORT YY_NUMBER YY_STR '/' proto 2657c478bd9Sstevel@tonic-gate { strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel)); 2667c478bd9Sstevel@tonic-gate if (nat->in_dcmp == 0) { 2677c478bd9Sstevel@tonic-gate nat->in_dport = htons($3); 2687c478bd9Sstevel@tonic-gate } else if ($3 != nat->in_dport) { 2697c478bd9Sstevel@tonic-gate yyerror("proxy port numbers not consistant"); 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate setnatproto($6); 2727c478bd9Sstevel@tonic-gate free($4); 2737c478bd9Sstevel@tonic-gate } 2747c478bd9Sstevel@tonic-gate | IPNY_PROXY IPNY_PORT YY_STR YY_STR '/' proto 2757c478bd9Sstevel@tonic-gate { strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel)); 2767c478bd9Sstevel@tonic-gate nat->in_dport = getportproto($3, $6); 2777c478bd9Sstevel@tonic-gate setnatproto($6); 2787c478bd9Sstevel@tonic-gate free($3); 2797c478bd9Sstevel@tonic-gate free($4); 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate ; 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate rdrproto: 2847c478bd9Sstevel@tonic-gate | IPNY_TCP { setnatproto(IPPROTO_TCP); } 2857c478bd9Sstevel@tonic-gate | IPNY_UDP { setnatproto(IPPROTO_UDP); } 2867c478bd9Sstevel@tonic-gate | IPNY_TCPUDP { nat->in_flags |= IPN_TCPUDP; 2877c478bd9Sstevel@tonic-gate nat->in_p = 0; } 2887c478bd9Sstevel@tonic-gate | IPNY_TCP '/' IPNY_UDP { nat->in_flags |= IPN_TCPUDP; 2897c478bd9Sstevel@tonic-gate nat->in_p = 0; } 2907c478bd9Sstevel@tonic-gate | YY_NUMBER { setnatproto($1); } 2917c478bd9Sstevel@tonic-gate | YY_STR { setnatproto(getproto($1)); 2927c478bd9Sstevel@tonic-gate free($1); 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate ; 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate rhaddr: addr { $$.a = $1.a; $$.m = $1.m; } 2977c478bd9Sstevel@tonic-gate | IPNY_RANGE ipv4 '-' ipv4 2987c478bd9Sstevel@tonic-gate { $$.a = $2; $$.m = $4; 2997c478bd9Sstevel@tonic-gate nat->in_flags |= IPN_IPRANGE; } 3007c478bd9Sstevel@tonic-gate dip: 3017c478bd9Sstevel@tonic-gate ipv4 { nat->in_inip = $1.s_addr; 3027c478bd9Sstevel@tonic-gate nat->in_inmsk = 0xffffffff; } 303*6aed92a9Syx | ipv4 '/' YY_NUMBER { nat->in_inip = $1.s_addr; 304*6aed92a9Syx if (nat->in_inip != 0 || 305*6aed92a9Syx ($3 != 0 && $3 != 32)) 306*6aed92a9Syx yyerror("Invalid mask for dip"); 307*6aed92a9Syx ntomask(4, $3, &nat->in_inmsk); } 3087c478bd9Sstevel@tonic-gate | ipv4 ',' ipv4 { nat->in_flags |= IPN_SPLIT; 3097c478bd9Sstevel@tonic-gate nat->in_inip = $1.s_addr; 3107c478bd9Sstevel@tonic-gate nat->in_inmsk = $3.s_addr; } 3117c478bd9Sstevel@tonic-gate ; 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate dport: | IPNY_PORT YY_NUMBER { nat->in_pmin = htons($2); 3147c478bd9Sstevel@tonic-gate nat->in_pmax = htons($2); } 3157c478bd9Sstevel@tonic-gate | IPNY_PORT YY_NUMBER '-' YY_NUMBER { nat->in_pmin = htons($2); 3167c478bd9Sstevel@tonic-gate nat->in_pmax = htons($4); } 3177c478bd9Sstevel@tonic-gate ; 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate nport: IPNY_PORT YY_NUMBER { nat->in_pnext = htons($2); } 3207c478bd9Sstevel@tonic-gate ; 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate ports: | IPNY_PORTS numports { nat->in_pmin = $2; } 3237c478bd9Sstevel@tonic-gate | IPNY_PORTS IPNY_AUTO { nat->in_flags |= IPN_AUTOPORTMAP; } 3247c478bd9Sstevel@tonic-gate ; 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate mapit: IPNY_MAP { nat->in_redir = NAT_MAP; } 3277c478bd9Sstevel@tonic-gate | IPNY_BIMAP { nat->in_redir = NAT_BIMAP; } 3287c478bd9Sstevel@tonic-gate ; 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate rdrit: IPNY_RDR { nat->in_redir = NAT_REDIRECT; } 3317c478bd9Sstevel@tonic-gate ; 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate mapblockit: 3347c478bd9Sstevel@tonic-gate IPNY_MAPBLOCK { nat->in_redir = NAT_MAPBLK; } 3357c478bd9Sstevel@tonic-gate ; 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate mapfrom: 3387c478bd9Sstevel@tonic-gate from sobject IPNY_TO dobject 3397c478bd9Sstevel@tonic-gate | from sobject '!' IPNY_TO dobject 3407c478bd9Sstevel@tonic-gate { nat->in_flags |= IPN_NOTDST; } 3417c478bd9Sstevel@tonic-gate ; 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate rdrfrom: 3447c478bd9Sstevel@tonic-gate from sobject IPNY_TO dobject 3457c478bd9Sstevel@tonic-gate | '!' from sobject IPNY_TO dobject 3467c478bd9Sstevel@tonic-gate { nat->in_flags |= IPN_NOTSRC; } 3477c478bd9Sstevel@tonic-gate ; 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate from: IPNY_FROM { nat->in_flags |= IPN_FILTER; } 3507c478bd9Sstevel@tonic-gate ; 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate ifnames: 3537c478bd9Sstevel@tonic-gate ifname 3547c478bd9Sstevel@tonic-gate | ifname ',' otherifname 3557c478bd9Sstevel@tonic-gate ; 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate ifname: YY_STR { strncpy(nat->in_ifnames[0], $1, 3587c478bd9Sstevel@tonic-gate sizeof(nat->in_ifnames[0])); 3597c478bd9Sstevel@tonic-gate free($1); 3607c478bd9Sstevel@tonic-gate } 3617c478bd9Sstevel@tonic-gate ; 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate otherifname: 3647c478bd9Sstevel@tonic-gate YY_STR { strncpy(nat->in_ifnames[1], $1, 3657c478bd9Sstevel@tonic-gate sizeof(nat->in_ifnames[1])); 3667c478bd9Sstevel@tonic-gate free($1); 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate ; 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate mapport: 3717c478bd9Sstevel@tonic-gate IPNY_PORTMAP tcpudp YY_NUMBER ':' YY_NUMBER 3727c478bd9Sstevel@tonic-gate { nat->in_pmin = htons($3); 3737c478bd9Sstevel@tonic-gate nat->in_pmax = htons($5); } 3747c478bd9Sstevel@tonic-gate | IPNY_PORTMAP tcpudp IPNY_AUTO { nat->in_flags |= IPN_AUTOPORTMAP; 3757c478bd9Sstevel@tonic-gate nat->in_pmin = htons(1024); 3767c478bd9Sstevel@tonic-gate nat->in_pmax = htons(65535); } 3777c478bd9Sstevel@tonic-gate ; 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate sobject: 3807c478bd9Sstevel@tonic-gate saddr 3817c478bd9Sstevel@tonic-gate | saddr IPNY_PORT portstuff { nat->in_sport = $3.p1; 3827c478bd9Sstevel@tonic-gate nat->in_stop = $3.p2; 3837c478bd9Sstevel@tonic-gate nat->in_scmp = $3.pc; } 3847c478bd9Sstevel@tonic-gate ; 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate saddr: addr { if (nat->in_redir == NAT_REDIRECT) { 3877c478bd9Sstevel@tonic-gate nat->in_srcip = $1.a.s_addr; 3887c478bd9Sstevel@tonic-gate nat->in_srcmsk = $1.m.s_addr; 3897c478bd9Sstevel@tonic-gate } else { 3907c478bd9Sstevel@tonic-gate nat->in_inip = $1.a.s_addr; 3917c478bd9Sstevel@tonic-gate nat->in_inmsk = $1.m.s_addr; 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate ; 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate dobject: 3977c478bd9Sstevel@tonic-gate daddr 3987c478bd9Sstevel@tonic-gate | daddr IPNY_PORT portstuff { nat->in_dport = $3.p1; 3997c478bd9Sstevel@tonic-gate nat->in_dtop = $3.p2; 4007c478bd9Sstevel@tonic-gate nat->in_dcmp = $3.pc; 4017c478bd9Sstevel@tonic-gate if (nat->in_redir == NAT_REDIRECT) 4027c478bd9Sstevel@tonic-gate nat->in_pmin = htons($3.p1); 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate ; 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate daddr: addr { if (nat->in_redir == NAT_REDIRECT) { 4077c478bd9Sstevel@tonic-gate nat->in_outip = $1.a.s_addr; 4087c478bd9Sstevel@tonic-gate nat->in_outmsk = $1.m.s_addr; 4097c478bd9Sstevel@tonic-gate } else { 4107c478bd9Sstevel@tonic-gate nat->in_srcip = $1.a.s_addr; 4117c478bd9Sstevel@tonic-gate nat->in_srcmsk = $1.m.s_addr; 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate ; 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate addr: IPNY_ANY { $$.a.s_addr = 0; $$.m.s_addr = 0; } 4177c478bd9Sstevel@tonic-gate | nummask { $$.a = $1.a; $$.m = $1.m; 4187c478bd9Sstevel@tonic-gate $$.a.s_addr &= $$.m.s_addr; } 4197c478bd9Sstevel@tonic-gate | hostname '/' ipv4 { $$.a = $1; $$.m = $3; 4207c478bd9Sstevel@tonic-gate $$.a.s_addr &= $$.m.s_addr; } 4217c478bd9Sstevel@tonic-gate | hostname '/' hexnumber { $$.a = $1; $$.m.s_addr = $3; 4227c478bd9Sstevel@tonic-gate $$.a.s_addr &= $$.m.s_addr; } 4237c478bd9Sstevel@tonic-gate | hostname IPNY_MASK ipv4 { $$.a = $1; $$.m = $3; 4247c478bd9Sstevel@tonic-gate $$.a.s_addr &= $$.m.s_addr; } 4257c478bd9Sstevel@tonic-gate | hostname IPNY_MASK hexnumber { $$.a = $1; $$.m.s_addr = $3; 4267c478bd9Sstevel@tonic-gate $$.a.s_addr &= $$.m.s_addr; } 4277c478bd9Sstevel@tonic-gate ; 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate nummask: 4307c478bd9Sstevel@tonic-gate hostname { $$.a = $1; 4317c478bd9Sstevel@tonic-gate $$.m.s_addr = 0xffffffff; } 4327c478bd9Sstevel@tonic-gate | hostname '/' YY_NUMBER { $$.a = $1; 4337c478bd9Sstevel@tonic-gate ntomask(4, $3, &$$.m.s_addr); } 4347c478bd9Sstevel@tonic-gate ; 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate portstuff: 4377c478bd9Sstevel@tonic-gate compare YY_NUMBER { $$.pc = $1; $$.p1 = $2; } 4387c478bd9Sstevel@tonic-gate | YY_NUMBER range YY_NUMBER { $$.pc = $2; $$.p1 = $1; $$.p1 = $3; } 4397c478bd9Sstevel@tonic-gate ; 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate mapoptions: 4427c478bd9Sstevel@tonic-gate rr frag age mssclamp nattag 4437c478bd9Sstevel@tonic-gate ; 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate rdroptions: 4467c478bd9Sstevel@tonic-gate rr frag age sticky mssclamp rdrproxy nattag 4477c478bd9Sstevel@tonic-gate ; 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate nattag: | IPNY_TAG YY_STR { strncpy(nat->in_tag.ipt_tag, $2, 4507c478bd9Sstevel@tonic-gate sizeof(nat->in_tag.ipt_tag)); 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate rr: | IPNY_ROUNDROBIN { nat->in_flags |= IPN_ROUNDR; } 4537c478bd9Sstevel@tonic-gate ; 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate frag: | IPNY_FRAG { nat->in_flags |= IPN_FRAG; } 4567c478bd9Sstevel@tonic-gate ; 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate age: | IPNY_AGE YY_NUMBER { nat->in_age[0] = $2; 4597c478bd9Sstevel@tonic-gate nat->in_age[1] = $2; } 4607c478bd9Sstevel@tonic-gate | IPNY_AGE YY_NUMBER '/' YY_NUMBER { nat->in_age[0] = $2; 4617c478bd9Sstevel@tonic-gate nat->in_age[1] = $4; } 4627c478bd9Sstevel@tonic-gate ; 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate sticky: | IPNY_STICKY { if (!(nat->in_flags & IPN_ROUNDR) && 4657c478bd9Sstevel@tonic-gate !(nat->in_flags & IPN_SPLIT)) { 4667c478bd9Sstevel@tonic-gate fprintf(stderr, 4677c478bd9Sstevel@tonic-gate "'sticky' for use with round-robin/IP splitting only\n"); 4687c478bd9Sstevel@tonic-gate } else 4697c478bd9Sstevel@tonic-gate nat->in_flags |= IPN_STICKY; 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate ; 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate mssclamp: 4747c478bd9Sstevel@tonic-gate | IPNY_MSSCLAMP YY_NUMBER { nat->in_mssclamp = $2; } 4757c478bd9Sstevel@tonic-gate ; 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate tcpudp: | IPNY_TCP { setnatproto(IPPROTO_TCP); } 4787c478bd9Sstevel@tonic-gate | IPNY_UDP { setnatproto(IPPROTO_UDP); } 4797c478bd9Sstevel@tonic-gate | IPNY_TCPUDP { nat->in_flags |= IPN_TCPUDP; 4807c478bd9Sstevel@tonic-gate nat->in_p = 0; 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate | IPNY_TCP '/' IPNY_UDP { nat->in_flags |= IPN_TCPUDP; 4837c478bd9Sstevel@tonic-gate nat->in_p = 0; 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate ; 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate rdrproxy: 4887c478bd9Sstevel@tonic-gate | IPNY_PROXY YY_STR 4897c478bd9Sstevel@tonic-gate { strncpy(nat->in_plabel, $2, 4907c478bd9Sstevel@tonic-gate sizeof(nat->in_plabel)); 4917c478bd9Sstevel@tonic-gate nat->in_dport = nat->in_pnext; 4927c478bd9Sstevel@tonic-gate free($2); 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate | proxy { if (nat->in_plabel[0] != '\0') { 4957c478bd9Sstevel@tonic-gate nat->in_pmin = nat->in_dport; 4967c478bd9Sstevel@tonic-gate nat->in_pmax = nat->in_pmin; 4977c478bd9Sstevel@tonic-gate nat->in_pnext = nat->in_pmin; 4987c478bd9Sstevel@tonic-gate } 4997c478bd9Sstevel@tonic-gate } 5007c478bd9Sstevel@tonic-gate ; 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate numports: 5037c478bd9Sstevel@tonic-gate YY_NUMBER { $$ = $1; } 5047c478bd9Sstevel@tonic-gate ; 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate proto: YY_NUMBER { $$ = $1; } 5077c478bd9Sstevel@tonic-gate | IPNY_TCP { $$ = IPPROTO_TCP; } 5087c478bd9Sstevel@tonic-gate | IPNY_UDP { $$ = IPPROTO_UDP; } 5097c478bd9Sstevel@tonic-gate | YY_STR { $$ = getproto($1); free($1); } 5107c478bd9Sstevel@tonic-gate ; 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate hexnumber: 5137c478bd9Sstevel@tonic-gate YY_HEX { $$ = $1; } 5147c478bd9Sstevel@tonic-gate ; 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate hostname: 5177c478bd9Sstevel@tonic-gate YY_STR { if (gethost($1, &$$.s_addr) == -1) 5187c478bd9Sstevel@tonic-gate fprintf(stderr, 5197c478bd9Sstevel@tonic-gate "Unknown host '%s'\n", 5207c478bd9Sstevel@tonic-gate $1); 5217c478bd9Sstevel@tonic-gate free($1); 5227c478bd9Sstevel@tonic-gate } 5237c478bd9Sstevel@tonic-gate | YY_NUMBER { $$.s_addr = htonl($1); } 5247c478bd9Sstevel@tonic-gate | ipv4 { $$.s_addr = $1.s_addr; } 5257c478bd9Sstevel@tonic-gate ; 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate compare: 5287c478bd9Sstevel@tonic-gate '=' { $$ = FR_EQUAL; } 5297c478bd9Sstevel@tonic-gate | YY_CMP_EQ { $$ = FR_EQUAL; } 5307c478bd9Sstevel@tonic-gate | YY_CMP_NE { $$ = FR_NEQUAL; } 5317c478bd9Sstevel@tonic-gate | YY_CMP_LT { $$ = FR_LESST; } 5327c478bd9Sstevel@tonic-gate | YY_CMP_LE { $$ = FR_LESSTE; } 5337c478bd9Sstevel@tonic-gate | YY_CMP_GT { $$ = FR_GREATERT; } 5347c478bd9Sstevel@tonic-gate | YY_CMP_GE { $$ = FR_GREATERTE; } 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate range: 5377c478bd9Sstevel@tonic-gate YY_RANGE_OUT { $$ = FR_OUTRANGE; } 5387c478bd9Sstevel@tonic-gate | YY_RANGE_IN { $$ = FR_INRANGE; } 5397c478bd9Sstevel@tonic-gate ; 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER 5427c478bd9Sstevel@tonic-gate { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { 5437c478bd9Sstevel@tonic-gate yyerror("Invalid octet string for IP address"); 5447c478bd9Sstevel@tonic-gate return 0; 5457c478bd9Sstevel@tonic-gate } 5467c478bd9Sstevel@tonic-gate $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; 5477c478bd9Sstevel@tonic-gate $$.s_addr = htonl($$.s_addr); 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate ; 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate %% 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate static wordtab_t yywords[] = { 5557c478bd9Sstevel@tonic-gate { "age", IPNY_AGE }, 5567c478bd9Sstevel@tonic-gate { "any", IPNY_ANY }, 5577c478bd9Sstevel@tonic-gate { "auto", IPNY_AUTO }, 5587c478bd9Sstevel@tonic-gate { "bimap", IPNY_BIMAP }, 5597c478bd9Sstevel@tonic-gate { "frag", IPNY_FRAG }, 5607c478bd9Sstevel@tonic-gate { "from", IPNY_FROM }, 5617c478bd9Sstevel@tonic-gate { "icmpidmap", IPNY_ICMPIDMAP }, 5627c478bd9Sstevel@tonic-gate { "mask", IPNY_MASK }, 5637c478bd9Sstevel@tonic-gate { "map", IPNY_MAP }, 5647c478bd9Sstevel@tonic-gate { "map-block", IPNY_MAPBLOCK }, 5657c478bd9Sstevel@tonic-gate { "mssclamp", IPNY_MSSCLAMP }, 5667c478bd9Sstevel@tonic-gate { "port", IPNY_PORT }, 5677c478bd9Sstevel@tonic-gate { "portmap", IPNY_PORTMAP }, 5687c478bd9Sstevel@tonic-gate { "ports", IPNY_PORTS }, 5697c478bd9Sstevel@tonic-gate { "proxy", IPNY_PROXY }, 5707c478bd9Sstevel@tonic-gate { "range", IPNY_RANGE }, 5717c478bd9Sstevel@tonic-gate { "rdr", IPNY_RDR }, 5727c478bd9Sstevel@tonic-gate { "round-robin",IPNY_ROUNDROBIN }, 5737c478bd9Sstevel@tonic-gate { "sticky", IPNY_STICKY }, 5747c478bd9Sstevel@tonic-gate { "tag", IPNY_TAG }, 5757c478bd9Sstevel@tonic-gate { "tcp", IPNY_TCP }, 5767c478bd9Sstevel@tonic-gate { "to", IPNY_TO }, 5777c478bd9Sstevel@tonic-gate { "udp", IPNY_UDP }, 5787c478bd9Sstevel@tonic-gate { "-", '-' }, 5797c478bd9Sstevel@tonic-gate { "->", IPNY_TLATE }, 5807c478bd9Sstevel@tonic-gate { "eq", YY_CMP_EQ }, 5817c478bd9Sstevel@tonic-gate { "ne", YY_CMP_NE }, 5827c478bd9Sstevel@tonic-gate { "lt", YY_CMP_LT }, 5837c478bd9Sstevel@tonic-gate { "gt", YY_CMP_GT }, 5847c478bd9Sstevel@tonic-gate { "le", YY_CMP_LE }, 5857c478bd9Sstevel@tonic-gate { "ge", YY_CMP_GE }, 5867c478bd9Sstevel@tonic-gate { NULL, 0 } 5877c478bd9Sstevel@tonic-gate }; 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate 5907c478bd9Sstevel@tonic-gate int ipnat_parsefile(fd, addfunc, ioctlfunc, filename) 5917c478bd9Sstevel@tonic-gate int fd; 5927c478bd9Sstevel@tonic-gate addfunc_t addfunc; 5937c478bd9Sstevel@tonic-gate ioctlfunc_t ioctlfunc; 5947c478bd9Sstevel@tonic-gate char *filename; 5957c478bd9Sstevel@tonic-gate { 5967c478bd9Sstevel@tonic-gate FILE *fp = NULL; 5977c478bd9Sstevel@tonic-gate char *s; 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate (void) yysettab(yywords); 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate s = getenv("YYDEBUG"); 6027c478bd9Sstevel@tonic-gate if (s) 6037c478bd9Sstevel@tonic-gate yydebug = atoi(s); 6047c478bd9Sstevel@tonic-gate else 6057c478bd9Sstevel@tonic-gate yydebug = 0; 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate if (strcmp(filename, "-")) { 6087c478bd9Sstevel@tonic-gate fp = fopen(filename, "r"); 6097c478bd9Sstevel@tonic-gate if (!fp) { 6107c478bd9Sstevel@tonic-gate fprintf(stderr, "fopen(%s) failed: %s\n", filename, 6117c478bd9Sstevel@tonic-gate STRERROR(errno)); 6127c478bd9Sstevel@tonic-gate return -1; 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate } else 6157c478bd9Sstevel@tonic-gate fp = stdin; 6167c478bd9Sstevel@tonic-gate 6177c478bd9Sstevel@tonic-gate while (ipnat_parsesome(fd, addfunc, ioctlfunc, fp) == 1) 6187c478bd9Sstevel@tonic-gate ; 6197c478bd9Sstevel@tonic-gate if (fp != NULL) 6207c478bd9Sstevel@tonic-gate fclose(fp); 6217c478bd9Sstevel@tonic-gate return 0; 6227c478bd9Sstevel@tonic-gate } 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate int ipnat_parsesome(fd, addfunc, ioctlfunc, fp) 6267c478bd9Sstevel@tonic-gate int fd; 6277c478bd9Sstevel@tonic-gate addfunc_t addfunc; 6287c478bd9Sstevel@tonic-gate ioctlfunc_t ioctlfunc; 6297c478bd9Sstevel@tonic-gate FILE *fp; 6307c478bd9Sstevel@tonic-gate { 6317c478bd9Sstevel@tonic-gate char *s; 6327c478bd9Sstevel@tonic-gate int i; 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate yylineNum = 1; 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate natfd = fd; 6377c478bd9Sstevel@tonic-gate nataddfunc = addfunc; 6387c478bd9Sstevel@tonic-gate natioctlfunc = ioctlfunc; 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate if (feof(fp)) 6417c478bd9Sstevel@tonic-gate return 0; 6427c478bd9Sstevel@tonic-gate i = fgetc(fp); 6437c478bd9Sstevel@tonic-gate if (i == EOF) 6447c478bd9Sstevel@tonic-gate return 0; 6457c478bd9Sstevel@tonic-gate if (ungetc(i, fp) == EOF) 6467c478bd9Sstevel@tonic-gate return 0; 6477c478bd9Sstevel@tonic-gate if (feof(fp)) 6487c478bd9Sstevel@tonic-gate return 0; 6497c478bd9Sstevel@tonic-gate s = getenv("YYDEBUG"); 6507c478bd9Sstevel@tonic-gate if (s) 6517c478bd9Sstevel@tonic-gate yydebug = atoi(s); 6527c478bd9Sstevel@tonic-gate else 6537c478bd9Sstevel@tonic-gate yydebug = 0; 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate yyin = fp; 6567c478bd9Sstevel@tonic-gate yyparse(); 6577c478bd9Sstevel@tonic-gate return 1; 6587c478bd9Sstevel@tonic-gate } 6597c478bd9Sstevel@tonic-gate 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate static void newnatrule() 6627c478bd9Sstevel@tonic-gate { 6637c478bd9Sstevel@tonic-gate ipnat_t *n; 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate n = calloc(1, sizeof(*n)); 6667c478bd9Sstevel@tonic-gate if (n == NULL) 6677c478bd9Sstevel@tonic-gate return; 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate if (nat == NULL) 6707c478bd9Sstevel@tonic-gate nattop = nat = n; 6717c478bd9Sstevel@tonic-gate else { 6727c478bd9Sstevel@tonic-gate nat->in_next = n; 6737c478bd9Sstevel@tonic-gate nat = n; 6747c478bd9Sstevel@tonic-gate } 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate 6777c478bd9Sstevel@tonic-gate 6787c478bd9Sstevel@tonic-gate static void setnatproto(p) 6797c478bd9Sstevel@tonic-gate int p; 6807c478bd9Sstevel@tonic-gate { 6817c478bd9Sstevel@tonic-gate nat->in_p = p; 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate switch (p) 6847c478bd9Sstevel@tonic-gate { 6857c478bd9Sstevel@tonic-gate case IPPROTO_TCP : 6867c478bd9Sstevel@tonic-gate nat->in_flags |= IPN_TCP; 6877c478bd9Sstevel@tonic-gate nat->in_flags &= ~IPN_UDP; 6887c478bd9Sstevel@tonic-gate break; 6897c478bd9Sstevel@tonic-gate case IPPROTO_UDP : 6907c478bd9Sstevel@tonic-gate nat->in_flags |= IPN_UDP; 6917c478bd9Sstevel@tonic-gate nat->in_flags &= ~IPN_TCP; 6927c478bd9Sstevel@tonic-gate break; 6937c478bd9Sstevel@tonic-gate default : 6947c478bd9Sstevel@tonic-gate if ((nat->in_redir & NAT_MAPBLK) == 0) { 6957c478bd9Sstevel@tonic-gate nat->in_pmin = 0; 6967c478bd9Sstevel@tonic-gate nat->in_pmax = 0; 6977c478bd9Sstevel@tonic-gate nat->in_pnext = 0; 6987c478bd9Sstevel@tonic-gate nat->in_flags &= ~IPN_TCPUDP; 6997c478bd9Sstevel@tonic-gate } 7007c478bd9Sstevel@tonic-gate break; 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate } 7037c478bd9Sstevel@tonic-gate 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate void ipnat_addrule(fd, ioctlfunc, ptr) 7067c478bd9Sstevel@tonic-gate int fd; 7077c478bd9Sstevel@tonic-gate ioctlfunc_t ioctlfunc; 7087c478bd9Sstevel@tonic-gate void *ptr; 7097c478bd9Sstevel@tonic-gate { 7107c478bd9Sstevel@tonic-gate ipfobj_t obj; 7117c478bd9Sstevel@tonic-gate int add, del; 7127c478bd9Sstevel@tonic-gate ipnat_t *ipn; 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate ipn = ptr; 7157c478bd9Sstevel@tonic-gate bzero((char *)&obj, sizeof(obj)); 7167c478bd9Sstevel@tonic-gate obj.ipfo_rev = IPFILTER_VERSION; 7177c478bd9Sstevel@tonic-gate obj.ipfo_size = sizeof(ipnat_t); 7187c478bd9Sstevel@tonic-gate obj.ipfo_type = IPFOBJ_IPNAT; 7197c478bd9Sstevel@tonic-gate obj.ipfo_ptr = ptr; 7207c478bd9Sstevel@tonic-gate add = 0; 7217c478bd9Sstevel@tonic-gate del = 0; 7227c478bd9Sstevel@tonic-gate 7237c478bd9Sstevel@tonic-gate if ((opts & OPT_DONOTHING) != 0) 7247c478bd9Sstevel@tonic-gate fd = -1; 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate if (opts & OPT_ZERORULEST) { 7277c478bd9Sstevel@tonic-gate add = SIOCZRLST; 7287c478bd9Sstevel@tonic-gate } else if (opts & OPT_INACTIVE) { 7297c478bd9Sstevel@tonic-gate add = SIOCADNAT; 7307c478bd9Sstevel@tonic-gate del = SIOCRMNAT; 7317c478bd9Sstevel@tonic-gate } else { 7327c478bd9Sstevel@tonic-gate add = SIOCADNAT; 7337c478bd9Sstevel@tonic-gate del = SIOCRMNAT; 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate if (ipn && (opts & OPT_VERBOSE)) 7377c478bd9Sstevel@tonic-gate printnat(ipn, opts); 7387c478bd9Sstevel@tonic-gate 7397c478bd9Sstevel@tonic-gate if (opts & OPT_DEBUG) 7407c478bd9Sstevel@tonic-gate binprint(ipn, sizeof(*ipn)); 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gate if ((opts & OPT_ZERORULEST) != 0) { 7437c478bd9Sstevel@tonic-gate if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { 7447c478bd9Sstevel@tonic-gate if ((opts & OPT_DONOTHING) == 0) { 7457c478bd9Sstevel@tonic-gate fprintf(stderr, "%d:", yylineNum); 7467c478bd9Sstevel@tonic-gate perror("ioctl(SIOCZRLST)"); 7477c478bd9Sstevel@tonic-gate } 7487c478bd9Sstevel@tonic-gate } else { 7497c478bd9Sstevel@tonic-gate #ifdef USE_QUAD_T 7507c478bd9Sstevel@tonic-gate /* 7517c478bd9Sstevel@tonic-gate printf("hits %qd bytes %qd ", 7527c478bd9Sstevel@tonic-gate (long long)fr->fr_hits, 7537c478bd9Sstevel@tonic-gate (long long)fr->fr_bytes); 7547c478bd9Sstevel@tonic-gate */ 7557c478bd9Sstevel@tonic-gate #else 7567c478bd9Sstevel@tonic-gate /* 7577c478bd9Sstevel@tonic-gate printf("hits %ld bytes %ld ", 7587c478bd9Sstevel@tonic-gate fr->fr_hits, fr->fr_bytes); 7597c478bd9Sstevel@tonic-gate */ 7607c478bd9Sstevel@tonic-gate #endif 7617c478bd9Sstevel@tonic-gate printnat(ipn, opts); 7627c478bd9Sstevel@tonic-gate } 7637c478bd9Sstevel@tonic-gate } else if ((opts & OPT_REMOVE) != 0) { 7647c478bd9Sstevel@tonic-gate if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) { 7657c478bd9Sstevel@tonic-gate if ((opts & OPT_DONOTHING) == 0) { 7667c478bd9Sstevel@tonic-gate fprintf(stderr, "%d:", yylineNum); 7677c478bd9Sstevel@tonic-gate perror("ioctl(delete nat rule)"); 7687c478bd9Sstevel@tonic-gate } 7697c478bd9Sstevel@tonic-gate } 7707c478bd9Sstevel@tonic-gate } else { 7717c478bd9Sstevel@tonic-gate if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { 7727c478bd9Sstevel@tonic-gate if ((opts & OPT_DONOTHING) == 0) { 7737c478bd9Sstevel@tonic-gate fprintf(stderr, "%d:", yylineNum); 7747c478bd9Sstevel@tonic-gate perror("ioctl(add/insert nat rule)"); 7757c478bd9Sstevel@tonic-gate } 7767c478bd9Sstevel@tonic-gate } 7777c478bd9Sstevel@tonic-gate } 7787c478bd9Sstevel@tonic-gate } 779