From d6c23f6fbecbcca8ddd2b74c6e10f37095f9fd46 Mon Sep 17 00:00:00 2001 From: yx160601 Date: Wed, 23 Jul 2008 19:59:47 -0700 Subject: PSARC 2008/250 ipv6 NAT for IPFilter 6600474 RFE: Need ipv6 support on NAT --- usr/src/cmd/ipf/lib/Makefile.com | 6 +- usr/src/cmd/ipf/lib/common/printactiveaddr.c | 37 +++ usr/src/cmd/ipf/lib/common/printactivenat.c | 19 +- usr/src/cmd/ipf/lib/common/printaddr.c | 63 +++++ usr/src/cmd/ipf/lib/common/printfr.c | 82 +----- usr/src/cmd/ipf/lib/common/printhostmask.c | 17 +- usr/src/cmd/ipf/lib/common/printlookup.c | 34 +++ usr/src/cmd/ipf/lib/common/printnat.c | 87 +++--- usr/src/cmd/ipf/tools/Makefile.tools | 6 +- usr/src/cmd/ipf/tools/ip_fil.c | 5 +- usr/src/cmd/ipf/tools/ipmon.c | 53 ++-- usr/src/cmd/ipf/tools/ipnat_y.y | 382 ++++++++++++++++++++------- usr/src/cmd/ipf/tools/lexer.c | 6 +- 13 files changed, 521 insertions(+), 276 deletions(-) create mode 100644 usr/src/cmd/ipf/lib/common/printactiveaddr.c create mode 100644 usr/src/cmd/ipf/lib/common/printaddr.c create mode 100644 usr/src/cmd/ipf/lib/common/printlookup.c (limited to 'usr/src/cmd/ipf') diff --git a/usr/src/cmd/ipf/lib/Makefile.com b/usr/src/cmd/ipf/lib/Makefile.com index 8019bb8e9c..2d582dc3b4 100644 --- a/usr/src/cmd/ipf/lib/Makefile.com +++ b/usr/src/cmd/ipf/lib/Makefile.com @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -49,7 +49,7 @@ OBJECTS= addicmp.o addipopt.o bcopywrap.o \ printhashnode.o printip.o printpool.o \ printpoolnode.o printfr.o printfraginfo.o \ printhostmap.o printifname.o printhostmask.o \ - printlog.o printmask.o printnat.o printpacket.o \ + printlog.o printlookup.o printmask.o printnat.o printpacket.o \ printpacket6.o printportcmp.o printproto.o \ printsbuf.o printstate.o printtunable.o ratoi.o \ remove_pool.o remove_poolnode.o remove_hash.o \ @@ -57,7 +57,7 @@ OBJECTS= addicmp.o addipopt.o bcopywrap.o \ tcpflags.o var.o verbose.o \ v6ionames.o v6optvalue.o printpool_live.o \ printpooldata.o printhash_live.o printhashdata.o \ - printactivenat.o + printactiveaddr.o printactivenat.o printaddr.o include $(SRC)/lib/Makefile.lib include ../../Makefile.ipf diff --git a/usr/src/cmd/ipf/lib/common/printactiveaddr.c b/usr/src/cmd/ipf/lib/common/printactiveaddr.c new file mode 100644 index 0000000000..f3ec165d7f --- /dev/null +++ b/usr/src/cmd/ipf/lib/common/printactiveaddr.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2002-2004 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ + +#include "ipf.h" + +#pragma ident "%Z%%M% %I% %E% SMI" + +#if !defined(lint) +static const char rcsid[] = "@(#)$Id: printactiveaddr.c,v 1.1 2008/02/12 16:11:49 darren_r Exp $"; +#endif + +void +printactiveaddress(v, fmt, addr, ifname) + int v; + char *fmt; + i6addr_t *addr; + char *ifname; +{ + switch (v) + { + case 4 : + printf(fmt, inet_ntoa(addr->in4)); + break; +#ifdef USE_INET6 + case 6 : + printaddr(v, FRI_NORMAL, ifname, (u_32_t *)&addr->in6, NULL); + break; +#endif + default : + break; + } +} diff --git a/usr/src/cmd/ipf/lib/common/printactivenat.c b/usr/src/cmd/ipf/lib/common/printactivenat.c index ace6b6cfe3..54d86f96f4 100644 --- a/usr/src/cmd/ipf/lib/common/printactivenat.c +++ b/usr/src/cmd/ipf/lib/common/printactivenat.c @@ -1,12 +1,7 @@ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2002-2004 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. - * - * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) - * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -29,17 +24,23 @@ int opts, alive; if (nat->nat_flags & SI_CLONE) printf(" CLONE"); - printf(" %-15s", inet_ntoa(nat->nat_inip)); + printactiveaddress(nat->nat_v, " %-15s", &nat->nat_inip6, + nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) printf(" %-5hu", ntohs(nat->nat_inport)); - printf(" <- -> %-15s",inet_ntoa(nat->nat_outip)); + printf(" <- -> "); + printactiveaddress(nat->nat_v, "%-15s", &nat->nat_outip6, + nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) printf(" %-5hu", ntohs(nat->nat_outport)); - printf(" [%s", inet_ntoa(nat->nat_oip)); + printf(" ["); + printactiveaddress(nat->nat_v, "%s", &nat->nat_oip6, + nat->nat_ifnames[0]); + if ((nat->nat_flags & IPN_TCPUDP) != 0) printf(" %hu", ntohs(nat->nat_oport)); printf("]"); diff --git a/usr/src/cmd/ipf/lib/common/printaddr.c b/usr/src/cmd/ipf/lib/common/printaddr.c new file mode 100644 index 0000000000..914ec3c663 --- /dev/null +++ b/usr/src/cmd/ipf/lib/common/printaddr.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2005 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "ipf.h" + + +void printaddr(v, type, ifname, addr, mask) +int v, type; +char *ifname; +u_32_t *addr, *mask; +{ + char *suffix; + + switch (type) + { + case FRI_BROADCAST : + suffix = "/bcast"; + break; + + case FRI_DYNAMIC : + printf("%s", ifname); + printmask(v, mask); + suffix = NULL; + break; + + case FRI_NETWORK : + suffix = "/net"; + break; + + case FRI_NETMASKED : + suffix = "/netmasked"; + break; + + case FRI_PEERADDR : + suffix = "/peer"; + break; + + case FRI_LOOKUP : + suffix = NULL; + printlookup((i6addr_t *)addr, (i6addr_t *)mask); + break; + + case FRI_NORMAL : + printhostmask(v, addr, mask); + suffix = NULL; + break; + default : + printf("<%d>", type); + printmask(v, mask); + suffix = NULL; + break; + } + + if (suffix != NULL) { + printf("%s/%s", ifname, suffix); + } +} diff --git a/usr/src/cmd/ipf/lib/common/printfr.c b/usr/src/cmd/ipf/lib/common/printfr.c index 5a77998948..063eb87c07 100644 --- a/usr/src/cmd/ipf/lib/common/printfr.c +++ b/usr/src/cmd/ipf/lib/common/printfr.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2000-2005 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -13,86 +13,6 @@ #include "ipf.h" -static void printaddr(int, int, char *, u_32_t *, u_32_t *); - -static void printaddr(v, type, ifname, addr, mask) -int v, type; -char *ifname; -u_32_t *addr, *mask; -{ - char *suffix; - - switch (type) - { - case FRI_BROADCAST : - suffix = "/bcast"; - break; - - case FRI_DYNAMIC : - printf("%s", ifname); - printmask(v, mask); - suffix = NULL; - break; - - case FRI_NETWORK : - suffix = "/net"; - break; - - case FRI_NETMASKED : - suffix = "/netmasked"; - break; - - case FRI_PEERADDR : - suffix = "/peer"; - break; - - case FRI_LOOKUP : - suffix = NULL; - printlookup((i6addr_t *)addr, (i6addr_t *)mask); - break; - - case FRI_NORMAL : - printhostmask(v, addr, mask); - suffix = NULL; - break; - default : - printf("<%d>", type); - printmask(v, mask); - suffix = NULL; - break; - } - - if (suffix != NULL) { - printf("%s/%s", ifname, suffix); - } -} - - -void printlookup(addr, mask) -i6addr_t *addr, *mask; -{ - switch (addr->iplookuptype) - { - case IPLT_POOL : - printf("pool/"); - break; - case IPLT_HASH : - printf("hash/"); - break; - default : - printf("lookup(%x)=", addr->iplookuptype); - break; - } - - printf("%u", addr->iplookupnum); - if (opts & OPT_UNDEF) { - if (mask->iplookupptr == NULL) { - printf("(!)"); - } - } -} - - /* * print the filter structure in a useful way */ diff --git a/usr/src/cmd/ipf/lib/common/printhostmask.c b/usr/src/cmd/ipf/lib/common/printhostmask.c index 2afe5c0400..bd8a798b9f 100644 --- a/usr/src/cmd/ipf/lib/common/printhostmask.c +++ b/usr/src/cmd/ipf/lib/common/printhostmask.c @@ -1,11 +1,11 @@ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2000-2005 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: printhostmask.c,v 1.8 2002/04/11 15:01:19 darrenr Exp $ * - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -24,26 +24,25 @@ u_32_t *addr, *mask; struct in_addr ipa; #endif - if (!*addr && !*mask) + if ((v == 4) && (!*addr) && (!*mask)) printf("any"); else { #ifdef USE_INET6 void *ptr = addr; int af; - if (v == 4) { - ptr = addr; + if (v == 4) af = AF_INET; - } else if (v == 6) { - ptr = addr; + else if (v == 6) af = AF_INET6; - } else + else af = 0; printf("%s", inet_ntop(af, ptr, ipbuf, sizeof(ipbuf))); #else ipa.s_addr = *addr; printf("%s", inet_ntoa(ipa)); #endif - printmask(v, mask); + if (mask != NULL) + printmask(v, mask); } } diff --git a/usr/src/cmd/ipf/lib/common/printlookup.c b/usr/src/cmd/ipf/lib/common/printlookup.c new file mode 100644 index 0000000000..ffc822e595 --- /dev/null +++ b/usr/src/cmd/ipf/lib/common/printlookup.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2005 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "ipf.h" + + +void printlookup(addr, mask) + i6addr_t *addr, *mask; +{ + switch (addr->iplookuptype) + { + case IPLT_POOL : + printf("pool/"); + break; + case IPLT_HASH : + printf("hash/"); + break; + default : + printf("lookup(%x)=", addr->iplookuptype); + break; + } + + printf("%u", addr->iplookupnum); + if (opts & OPT_UNDEF) { + if (mask->iplookupptr == NULL) + printf("(!)"); + } +} diff --git a/usr/src/cmd/ipf/lib/common/printnat.c b/usr/src/cmd/ipf/lib/common/printnat.c index 521d057f1e..ea8bd72fb0 100644 --- a/usr/src/cmd/ipf/lib/common/printnat.c +++ b/usr/src/cmd/ipf/lib/common/printnat.c @@ -1,11 +1,11 @@ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2002-2005 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -27,7 +27,9 @@ ipnat_t *np; int opts; { struct protoent *pr; - int bits; + int bits, af; + char ipbuf[INET6_ADDRSTRLEN]; + void *ptr; pr = getprotobynumber(np->in_p); @@ -63,11 +65,11 @@ int opts; printf("! "); printf("from "); if (np->in_redir == NAT_REDIRECT) { - printhostmask(4, (u_32_t *)&np->in_srcip, - (u_32_t *)&np->in_srcmsk); + printhostmask(np->in_v, (u_32_t *)&np->in_src[0], + (u_32_t *)&np->in_src[1]); } else { - printhostmask(4, (u_32_t *)&np->in_inip, - (u_32_t *)&np->in_inmsk); + printhostmask(np->in_v, (u_32_t *)&np->in_in[0], + (u_32_t *)&np->in_in[1]); } if (np->in_scmp) printportcmp(np->in_p, &np->in_tuc.ftu_src); @@ -76,37 +78,46 @@ int opts; printf(" !"); printf(" to "); if (np->in_redir == NAT_REDIRECT) { - printhostmask(4, (u_32_t *)&np->in_outip, - (u_32_t *)&np->in_outmsk); + printhostmask(np->in_v, (u_32_t *)&np->in_out[0], + (u_32_t *)&np->in_out[1]); } else { - printhostmask(4, (u_32_t *)&np->in_srcip, - (u_32_t *)&np->in_srcmsk); + printhostmask(np->in_v, (u_32_t *)&np->in_src[0], + (u_32_t *)&np->in_src[1]); } if (np->in_dcmp) printportcmp(np->in_p, &np->in_tuc.ftu_dst); } + if (np->in_v == 4) + af = AF_INET; + else if (np->in_v == 6) + af = AF_INET6; + else + af = 0; + if (np->in_redir == NAT_REDIRECT) { if (!(np->in_flags & IPN_FILTER)) { - printf("%s", inet_ntoa(np->in_out[0].in4)); - bits = count4bits(np->in_outmsk); - if (bits != -1) - printf("/%d", bits); - else - printf("/%s", inet_ntoa(np->in_out[1].in4)); + ptr = (void *)(u_32_t *)&np->in_out[0]; + printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); + printmask(np->in_v, (u_32_t *)&np->in_out[1]); if (np->in_flags & IPN_TCPUDP) { printf(" port %d", ntohs(np->in_pmin)); if (np->in_pmax != np->in_pmin) printf("-%d", ntohs(np->in_pmax)); } } - printf(" -> %s", inet_ntoa(np->in_in[0].in4)); - if (np->in_flags & IPN_SPLIT) - printf(",%s", inet_ntoa(np->in_in[1].in4)); - if (np->in_inip == 0) { - bits = count4bits(np->in_inmsk); - printf("/%d", bits); + printf(" -> "); + ptr = (void *)(u_32_t *)&np->in_in[0]; + printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); + if (np->in_flags & IPN_SPLIT) { + printf(","); + ptr = (void *)(u_32_t *)&np->in_in[1]; + printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); } + if (((np->in_v == 4) && (np->in_inip == 0)) || + ((np->in_v == 6) && IP6_ISZERO(&np->in_in[0]))) + printmask(np->in_v, (u_32_t *)&np->in_in[1]); + if (np->in_flags & IPN_TCPUDP) { if ((np->in_flags & IPN_FIXEDDPORT) != 0) printf(" port = %d", ntohs(np->in_pnext)); @@ -127,7 +138,7 @@ int opts; if (np->in_mssclamp != 0) printf(" mssclamp %d", np->in_mssclamp); if (*np->in_plabel != '\0') - printf(" proxy %.*s", (int)sizeof(np->in_plabel), + printf(" proxy %.*s", (int)sizeof (np->in_plabel), np->in_plabel); if (np->in_tag.ipt_tag[0] != '\0') printf(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag); @@ -136,24 +147,22 @@ int opts; printf("\tpmax %u\n", np->in_pmax); } else { if (!(np->in_flags & IPN_FILTER)) { - printf("%s/", inet_ntoa(np->in_in[0].in4)); - bits = count4bits(np->in_inmsk); - if (bits != -1) - printf("%d", bits); - else - printf("%s", inet_ntoa(np->in_in[1].in4)); + ptr = (void *)(u_32_t *)&np->in_in[0]; + printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); + printmask(np->in_v, (u_32_t *)&np->in_in[1]); } printf(" -> "); if (np->in_flags & IPN_IPRANGE) { - printf("range %s-", inet_ntoa(np->in_out[0].in4)); - printf("%s", inet_ntoa(np->in_out[1].in4)); + printf("range "); + ptr = (void *)(u_32_t *)&np->in_out[0]; + printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); + printf("-"); + ptr = (void *)(u_32_t *)&np->in_out[1]; + printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); } else { - printf("%s/", inet_ntoa(np->in_out[0].in4)); - bits = count4bits(np->in_outmsk); - if (bits != -1) - printf("%d", bits); - else - printf("%s", inet_ntoa(np->in_out[1].in4)); + ptr = (void *)(u_32_t *)&np->in_out[0]; + printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); + printmask(np->in_v, (u_32_t *)&np->in_out[1]); } if (*np->in_plabel != '\0') { printf(" proxy port "); @@ -168,7 +177,7 @@ int opts; else fputs("???", stdout); } - printf(" %.*s/", (int)sizeof(np->in_plabel), + printf(" %.*s/", (int)sizeof (np->in_plabel), np->in_plabel); printproto(pr, np->in_p, NULL); } else if (np->in_redir == NAT_MAPBLK) { diff --git a/usr/src/cmd/ipf/tools/Makefile.tools b/usr/src/cmd/ipf/tools/Makefile.tools index 65d3eb211b..4b171b1b6a 100644 --- a/usr/src/cmd/ipf/tools/Makefile.tools +++ b/usr/src/cmd/ipf/tools/Makefile.tools @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # @@ -36,8 +36,8 @@ IPMON_OBJS= ipmon.o ipmon_y.o ipmon_l.o IPNAT_OBJS= ipnat.o ipnat_y.o ipnat_l.o IPPOOL_OBJS= ippool.o ippool_y.o ippool_l.o IPFTEST_OBJS= ipftest.o \ - ip_fil.o ip_state.o \ - ip_frag.o ip_nat.o fil.o \ + ip_fil.o ip_state.o ip_compat.o \ + ip_frag.o ip_nat.o ip_nat6.o fil.o \ ip_htable.o ip_lookup.o \ ip_proxy.o ip_auth.o ip_log.o \ ipf_y.o ipf_l.o \ diff --git a/usr/src/cmd/ipf/tools/ip_fil.c b/usr/src/cmd/ipf/tools/ip_fil.c index 52fa867504..bbdb57802a 100644 --- a/usr/src/cmd/ipf/tools/ip_fil.c +++ b/usr/src/cmd/ipf/tools/ip_fil.c @@ -3,7 +3,7 @@ * * See the IPFILTER.LICENCE file for details on licencing. * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -479,7 +479,8 @@ ipf_stack_t *ifs; f->fr_ifa = (void *)-1; #endif RWLOCK_EXIT(&ifs->ifs_ipf_mutex); - fr_natifpsync(IPFSYNC_OLDIFP, ifp, NULL, ifs); + fr_natifpsync(IPFSYNC_OLDIFP, 4, ifp, NULL, ifs); + fr_natifpsync(IPFSYNC_OLDIFP, 6, ifp, NULL, ifs); } diff --git a/usr/src/cmd/ipf/tools/ipmon.c b/usr/src/cmd/ipf/tools/ipmon.c index 0cacc6ce54..e9d37720ef 100644 --- a/usr/src/cmd/ipf/tools/ipmon.c +++ b/usr/src/cmd/ipf/tools/ipmon.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 1993-2001, 2003 by Darren Reed. + * Copyright (C) 2001-2008 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -737,49 +737,52 @@ int blen; } (void) strftime(t, len, "%T", tm); t += strlen(t); - (void) sprintf(t, ".%-.6ld @%hd ", ipl->ipl_usec, nl->nl_rule + 1); + (void) sprintf(t, ".%-.6ld @%hd ", ipl->ipl_usec, nl->nlg_rule + 1); t += strlen(t); - if (nl->nl_type == NL_NEWMAP) + if (nl->nlg_type == NL_NEWMAP) strcpy(t, "NAT:MAP "); - else if (nl->nl_type == NL_NEWRDR) + else if (nl->nlg_type == NL_NEWRDR) strcpy(t, "NAT:RDR "); - else if (nl->nl_type == NL_FLUSH) + else if (nl->nlg_type == NL_FLUSH) strcpy(t, "NAT:FLUSH "); - else if (nl->nl_type == NL_EXPIRE) + else if (nl->nlg_type == NL_EXPIRE) strcpy(t, "NAT:EXPIRE "); - else if (nl->nl_type == NL_NEWBIMAP) + else if (nl->nlg_type == NL_NEWBIMAP) strcpy(t, "NAT:BIMAP "); - else if (nl->nl_type == NL_NEWBLOCK) + else if (nl->nlg_type == NL_NEWBLOCK) strcpy(t, "NAT:MAPBLOCK "); - else if (nl->nl_type == NL_CLONE) + else if (nl->nlg_type == NL_CLONE) strcpy(t, "NAT:CLONE "); else - sprintf(t, "Type: %d ", nl->nl_type); + sprintf(t, "Type: %d ", nl->nlg_type); t += strlen(t); - proto = getproto(nl->nl_p); + proto = getproto(nl->nlg_p); - (void) sprintf(t, "%s,%s <- -> ", HOSTNAME_V4(res, nl->nl_inip), - portname(res, proto, (u_int)nl->nl_inport)); + (void) sprintf(t, "%s,%s <- -> ", hostname(res, nl->nlg_v, + (u_32_t *)&nl->nlg_inip), + portname(res, proto, (u_int)nl->nlg_inport)); t += strlen(t); - (void) sprintf(t, "%s,%s ", HOSTNAME_V4(res, nl->nl_outip), - portname(res, proto, (u_int)nl->nl_outport)); + (void) sprintf(t, "%s,%s ", hostname(res, nl->nlg_v, + (u_32_t *)&nl->nlg_outip), + portname(res, proto, (u_int)nl->nlg_outport)); t += strlen(t); - (void) sprintf(t, "[%s,%s]", HOSTNAME_V4(res, nl->nl_origip), - portname(res, proto, (u_int)nl->nl_origport)); + (void) sprintf(t, "[%s,%s]", hostname(res, nl->nlg_v, + (u_32_t *)&nl->nlg_origip), + portname(res, proto, (u_int)nl->nlg_origport)); t += strlen(t); - if (nl->nl_type == NL_EXPIRE) { + if (nl->nlg_type == NL_EXPIRE) { #ifdef USE_QUAD_T (void) sprintf(t, " Pkts %qd/%qd Bytes %qd/%qd", - (long long)nl->nl_pkts[0], - (long long)nl->nl_pkts[1], - (long long)nl->nl_bytes[0], - (long long)nl->nl_bytes[1]); + (long long)nl->nlg_pkts[0], + (long long)nl->nlg_pkts[1], + (long long)nl->nlg_bytes[0], + (long long)nl->nlg_bytes[1]); #else (void) sprintf(t, " Pkts %ld/%ld Bytes %ld/%ld", - nl->nl_pkts[0], nl->nl_pkts[1], - nl->nl_bytes[0], nl->nl_bytes[1]); + nl->nlg_pkts[0], nl->nlg_pkts[1], + nl->nlg_bytes[0], nl->nlg_bytes[1]); #endif t += strlen(t); } diff --git a/usr/src/cmd/ipf/tools/ipnat_y.y b/usr/src/cmd/ipf/tools/ipnat_y.y index 48ca425c4f..cab9d6d3c5 100644 --- a/usr/src/cmd/ipf/tools/ipnat_y.y +++ b/usr/src/cmd/ipf/tools/ipnat_y.y @@ -1,10 +1,10 @@ %{ /* - * Copyright (C) 2003 by Darren Reed. + * Copyright (C) 2001-2008 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -66,13 +66,15 @@ static addfunc_t nataddfunc = NULL; static void newnatrule __P((void)); static void setnatproto __P((int)); -static u_32_t lookuphost __P((char *)); %} %union { char *str; u_32_t num; - struct in_addr ipa; + struct { + i6addr_t a; + int v; + } ipa; frentry_t fr; frtuc_t *frt; u_short port; @@ -82,8 +84,9 @@ static u_32_t lookuphost __P((char *)); int pc; } pc; struct { - struct in_addr a; - struct in_addr m; + i6addr_t a; + i6addr_t m; + int v; } ipp; union i6addr ip6; }; @@ -102,8 +105,9 @@ static u_32_t lookuphost __P((char *)); %token IPNY_TLATE %type portspec %type hexnumber compare range proto -%type hostname ipv4 -%type addr nummask rhaddr +%type saddr daddr sobject dobject mapfrom rdrfrom dip +%type hostname ipv4 ipaddr +%type addr rhaddr %type portstuff %% file: line @@ -113,6 +117,8 @@ file: line ; line: xx rule { while ((nat = nattop) != NULL) { + if (nat->in_v == 0) + nat->in_v = 4; nattop = nat->in_next; (*nataddfunc)(natfd, natioctlfunc, nat); free(nat); @@ -145,11 +151,12 @@ eol: | ';' ; map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions - { nat->in_v = 4; - nat->in_inip = $3.a.s_addr; - nat->in_inmsk = $3.m.s_addr; - nat->in_outip = $5.a.s_addr; - nat->in_outmsk = $5.m.s_addr; + { if ($3.v != 0 && $3.v != $5.v && $5.v != 0) + yyerror("1.address family mismatch"); + bcopy(&$3.a, &nat->in_in[0], sizeof($3.a)); + bcopy(&$3.m, &nat->in_in[1], sizeof($3.a)); + bcopy(&$5.a, &nat->in_out[0], sizeof($5.a)); + bcopy(&$5.m, &nat->in_out[1], sizeof($5.a)); if (nat->in_ifnames[1][0] == '\0') strncpy(nat->in_ifnames[1], nat->in_ifnames[0], @@ -161,11 +168,12 @@ map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions nat_setgroupmap(nat); } | mapit ifnames addr IPNY_TLATE rhaddr mapport mapoptions - { nat->in_v = 4; - nat->in_inip = $3.a.s_addr; - nat->in_inmsk = $3.m.s_addr; - nat->in_outip = $5.a.s_addr; - nat->in_outmsk = $5.m.s_addr; + { if ($3.v != 0 && $3.v != $5.v && $5.v != 0) + yyerror("2.address family mismatch"); + bcopy(&$3.a, &nat->in_in[0], sizeof($3.a)); + bcopy(&$3.m, &nat->in_in[1], sizeof($3.a)); + bcopy(&$5.a, &nat->in_out[0], sizeof($5.a)); + bcopy(&$5.m, &nat->in_out[1], sizeof($5.a)); if (nat->in_ifnames[1][0] == '\0') strncpy(nat->in_ifnames[1], nat->in_ifnames[0], @@ -177,9 +185,10 @@ map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions nat_setgroupmap(nat); } | mapit ifnames mapfrom IPNY_TLATE rhaddr proxy mapoptions - { nat->in_v = 4; - nat->in_outip = $5.a.s_addr; - nat->in_outmsk = $5.m.s_addr; + { if ($3 != 0 && $3 != $5.v && $5.v != 0) + yyerror("3.address family mismatch"); + bcopy(&$5.a, &nat->in_out[0], sizeof($5.a)); + bcopy(&$5.m, &nat->in_out[1], sizeof($5.a)); if (nat->in_ifnames[1][0] == '\0') strncpy(nat->in_ifnames[1], nat->in_ifnames[0], @@ -191,9 +200,10 @@ map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions nat_setgroupmap(nat); } | mapit ifnames mapfrom IPNY_TLATE rhaddr mapport mapoptions - { nat->in_v = 4; - nat->in_outip = $5.a.s_addr; - nat->in_outmsk = $5.m.s_addr; + { if ($3 != 0 && $3 != $5.v && $5.v != 0) + yyerror("4.address family mismatch"); + bcopy(&$5.a, &nat->in_out[0], sizeof($5.a)); + bcopy(&$5.m, &nat->in_out[1], sizeof($5.a)); if (nat->in_ifnames[1][0] == '\0') strncpy(nat->in_ifnames[1], nat->in_ifnames[0], @@ -208,11 +218,12 @@ map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions mapblock: mapblockit ifnames addr IPNY_TLATE addr ports mapoptions - { nat->in_v = 4; - nat->in_inip = $3.a.s_addr; - nat->in_inmsk = $3.m.s_addr; - nat->in_outip = $5.a.s_addr; - nat->in_outmsk = $5.m.s_addr; + { if ($3.v != 0 && $3.v != $5.v && $5.v != 0) + yyerror("5.address family mismatch"); + bcopy(&$3.a, &nat->in_in[0], sizeof($3.a)); + bcopy(&$3.m, &nat->in_in[1], sizeof($3.a)); + bcopy(&$5.a, &nat->in_out[0], sizeof($5.a)); + bcopy(&$5.m, &nat->in_out[1], sizeof($5.a)); if (nat->in_ifnames[1][0] == '\0') strncpy(nat->in_ifnames[1], nat->in_ifnames[0], @@ -226,9 +237,10 @@ mapblock: ; redir: rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions - { nat->in_v = 4; - nat->in_outip = $3.a.s_addr; - nat->in_outmsk = $3.m.s_addr; + { if ($6 != 0 && $3.v != 0 && $6 != $3.v) + yyerror("6.address family mismatch"); + bcopy(&$3.a, &nat->in_out[0], sizeof($3.a)); + bcopy(&$3.m, &nat->in_out[1], sizeof($3.a)); if (nat->in_ifnames[1][0] == '\0') strncpy(nat->in_ifnames[1], nat->in_ifnames[0], @@ -241,7 +253,8 @@ redir: rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions setnatproto(IPPROTO_TCP); } | rdrit ifnames rdrfrom IPNY_TLATE dip nport setproto rdroptions - { nat->in_v = 4; + { if ($5 != 0 && $3 != 0 && $5 != $3) + yyerror("7.address family mismatch"); if ((nat->in_p == 0) && ((nat->in_flags & IPN_TCPUDP) == 0) && (nat->in_pmin != 0 || @@ -254,9 +267,10 @@ redir: rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions sizeof(nat->in_ifnames[0])); } | rdrit ifnames addr IPNY_TLATE dip setproto rdroptions - { nat->in_v = 4; - nat->in_outip = $3.a.s_addr; - nat->in_outmsk = $3.m.s_addr; + { if ($5 != 0 && $3.v != 0 && $5 != $3.v) + yyerror("8.address family mismatch"); + bcopy(&$3.a, &nat->in_out[0], sizeof($3.a)); + bcopy(&$3.m, &nat->in_out[1], sizeof($3.a)); if (nat->in_ifnames[1][0] == '\0') strncpy(nat->in_ifnames[1], nat->in_ifnames[0], @@ -307,23 +321,77 @@ setproto: } ; -rhaddr: addr { $$.a = $1.a; $$.m = $1.m; } - | IPNY_RANGE ipv4 '-' ipv4 - { $$.a = $2; $$.m = $4; - nat->in_flags |= IPN_IPRANGE; } +rhaddr: addr { $$.a = $1.a; + $$.m = $1.m; + $$.v = $1.v; + if ($$.v == 0) + $$.v = nat->in_v; + yyexpectaddr = 0; } + | IPNY_RANGE hostname '-' hostname + { if ($2.v != 0 && $4.v != 0 && $4.v != $2.v) + yyerror("9.address family " + "mismatch"); + $$.v = $2.v; + $$.a = $2.a; + $$.m = $4.a; + nat->in_flags |= IPN_IPRANGE; + yyexpectaddr = 0; } ; dip: - hostname { nat->in_inip = $1.s_addr; - nat->in_inmsk = 0xffffffff; } - | hostname '/' YY_NUMBER { nat->in_inip = $1.s_addr; - if (nat->in_inip != 0 || - ($3 != 0 && $3 != 32)) + hostname { bcopy(&$1.a, &nat->in_in[0], + sizeof($1.a)); + if ($1.v == 0) + $1.v = nat->in_v; + if ($1.v == 4) { + nat->in_inmsk = 0xffffffff; + } else { + nat->in_in[1].i6[0] = 0xffffffff; + nat->in_in[1].i6[1] = 0xffffffff; + nat->in_in[1].i6[2] = 0xffffffff; + nat->in_in[1].i6[3] = 0xffffffff; + } + $$ = $1.v; + } + | hostname '/' YY_NUMBER { if ($1.v == 0) + $1.v = nat->in_v; + if ($1.v == 4 && + ($1.a.in4.s_addr != 0 || + ($3 != 0 && $3 != 32))) + yyerror("Invalid mask for dip"); + else if ($1.v == 6 && + ($1.a.in4.s_addr != 0 || + ($3 != 0 && $3 != 128))) yyerror("Invalid mask for dip"); - ntomask(4, $3, &nat->in_inmsk); } - | hostname ',' hostname { nat->in_flags |= IPN_SPLIT; - nat->in_inip = $1.s_addr; - nat->in_inmsk = $3.s_addr; } + else if ($1.v == 0 ) { + if ($1.a.in4.s_addr == 0 && + ($3 == 32 || $3 == 0)) + $1.v = 4; + else if ($3 == 128) + $1.v = 6; + } + bcopy(&$1.a, &nat->in_in[0], + sizeof($1.a)); + ntomask($1.v, $3, + (u_32_t *)&nat->in_in[1]); + nat->in_in[0].i6[0] &= nat->in_in[1].i6[0]; + nat->in_in[0].i6[0] &= nat->in_in[1].i6[1]; + nat->in_in[0].i6[0] &= nat->in_in[1].i6[2]; + nat->in_in[0].i6[0] &= nat->in_in[1].i6[3]; + nat->in_v = $1.v; + $$ = $1.v; + } + | hostname ',' { yyexpectaddr = 1; } hostname + { if ($1.v != $4.v) + yyerror("10.address family " + "mismatch"); + $$ = $1.v; + nat->in_flags |= IPN_SPLIT; + bcopy(&$1.a, &nat->in_in[0], + sizeof($1.a)); + bcopy(&$4.a, &nat->in_in[1], + sizeof($4.a)); + yyexpectaddr = 0; } ; portspec: @@ -368,23 +436,42 @@ mapblockit: ; mapfrom: - from sobject IPNY_TO dobject + from sobject IPNY_TO dobject { if ($2 != 0 && $4 != 0 && $2 != $4) + yyerror("11.address family " + "mismatch"); + $$ = $2; + } | from sobject '!' IPNY_TO dobject - { nat->in_flags |= IPN_NOTDST; } + { if ($2 != 0 && $5 != 0 && $2 != $5) + yyerror("12.address family " + "mismatch"); + nat->in_flags |= IPN_NOTDST; + $$ = $2; + } ; rdrfrom: - from sobject IPNY_TO dobject + from sobject IPNY_TO dobject { if ($2 != 0 && $4 != 0 && $2 != $4) + yyerror("13.address family " + "mismatch"); + $$ = $2; + } | '!' from sobject IPNY_TO dobject - { nat->in_flags |= IPN_NOTSRC; } + { if ($3 != 0 && $5 != 0 && $3 != $5) + yyerror("14.address family " + "mismatch"); + nat->in_flags |= IPN_NOTSRC; + $$ = $3; + } ; -from: IPNY_FROM { nat->in_flags |= IPN_FILTER; } +from: IPNY_FROM { nat->in_flags |= IPN_FILTER; + yyexpectaddr = 1; } ; ifnames: - ifname - | ifname ',' otherifname + ifname { yyexpectaddr = 1; } + | ifname ',' otherifname { yyexpectaddr = 1; } ; ifname: YY_STR { strncpy(nat->in_ifnames[0], $1, @@ -428,24 +515,31 @@ mapport: ; sobject: - saddr + saddr { $$ = $1; } | saddr IPNY_PORT portstuff { nat->in_sport = $3.p1; nat->in_stop = $3.p2; - nat->in_scmp = $3.pc; } + nat->in_scmp = $3.pc; + $$ = $1; + } ; saddr: addr { if (nat->in_redir == NAT_REDIRECT) { - nat->in_srcip = $1.a.s_addr; - nat->in_srcmsk = $1.m.s_addr; + bcopy(&$1.a, &nat->in_src[0], + sizeof($1.a)); + bcopy(&$1.m, &nat->in_src[1], + sizeof($1.a)); } else { - nat->in_inip = $1.a.s_addr; - nat->in_inmsk = $1.m.s_addr; + bcopy(&$1.a, &nat->in_in[0], + sizeof($1.a)); + bcopy(&$1.m, &nat->in_in[1], + sizeof($1.a)); } + $$ = $1.v; } ; dobject: - daddr + daddr { $$ = $1; } | daddr IPNY_PORT portstuff { nat->in_dport = $3.p1; nat->in_dtop = $3.p2; nat->in_dcmp = $3.pc; @@ -455,33 +549,93 @@ dobject: ; daddr: addr { if (nat->in_redir == NAT_REDIRECT) { - nat->in_outip = $1.a.s_addr; - nat->in_outmsk = $1.m.s_addr; + bcopy(&$1.a, &nat->in_out[0], + sizeof($1.a)); + bcopy(&$1.m, &nat->in_out[1], + sizeof($1.a)); } else { - nat->in_srcip = $1.a.s_addr; - nat->in_srcmsk = $1.m.s_addr; + bcopy(&$1.a, &nat->in_src[0], + sizeof($1.a)); + bcopy(&$1.m, &nat->in_src[1], + sizeof($1.a)); } + $$ = $1.v; } ; -addr: IPNY_ANY { $$.a.s_addr = 0; $$.m.s_addr = 0; } - | nummask { $$.a = $1.a; $$.m = $1.m; - $$.a.s_addr &= $$.m.s_addr; } - | hostname '/' ipv4 { $$.a = $1; $$.m = $3; - $$.a.s_addr &= $$.m.s_addr; } - | hostname '/' hexnumber { $$.a = $1; $$.m.s_addr = $3; - $$.a.s_addr &= $$.m.s_addr; } - | hostname IPNY_MASK ipv4 { $$.a = $1; $$.m = $3; - $$.a.s_addr &= $$.m.s_addr; } - | hostname IPNY_MASK hexnumber { $$.a = $1; $$.m.s_addr = $3; - $$.a.s_addr &= $$.m.s_addr; } - ; - -nummask: - hostname { $$.a = $1; - $$.m.s_addr = 0xffffffff; } - | hostname '/' YY_NUMBER { $$.a = $1; - ntomask(4, $3, &$$.m.s_addr); } +addr: IPNY_ANY { yyexpectaddr = 0; + bzero(&$$.a, sizeof($$.a)); + bzero(&$$.m, sizeof($$.a)); + $$.v = nat->in_v; + } + | hostname { $$.a = $1.a; + $$.v = $1.v; + if ($$.v == 4) { + $$.m.in4.s_addr = 0xffffffff; + } else { + $$.m.i6[0] = 0xffffffff; + $$.m.i6[1] = 0xffffffff; + $$.m.i6[2] = 0xffffffff; + $$.m.i6[3] = 0xffffffff; + } + yyexpectaddr = 0; + } + | hostname '/' YY_NUMBER { $$.a = $1.a; + if ($1.v == 0) { + if ($1.a.in4.s_addr != 0) + yyerror("invalid addr"); + if ($3 == 0 || $3 == 32) + $1.v = 4; + else if ($3 == 128) + $1.v = 6; + else + yyerror("invalid mask"); + nat->in_v = $1.v; + } + ntomask($1.v, $3, (u_32_t *)&$$.m); + $$.a.i6[0] &= $$.m.i6[0]; + $$.a.i6[1] &= $$.m.i6[1]; + $$.a.i6[2] &= $$.m.i6[2]; + $$.a.i6[3] &= $$.m.i6[3]; + $$.v = $1.v; + yyexpectaddr = 0; + } + | hostname '/' ipaddr { if ($1.v != $3.v) { + yyerror("1.address family " + "mismatch"); + } + $$.a = $1.a; + $$.m = $3.a; + $$.a.i6[0] &= $$.m.i6[0]; + $$.a.i6[1] &= $$.m.i6[1]; + $$.a.i6[2] &= $$.m.i6[2]; + $$.a.i6[3] &= $$.m.i6[3]; + $$.v = $1.v; + yyexpectaddr = 0; + } + | hostname '/' hexnumber { $$.a = $1.a; + $$.m.in4.s_addr = htonl($3); + $$.a.in4.s_addr &= $$.m.in4.s_addr; + $$.v = 4; + } + | hostname IPNY_MASK ipaddr { if ($1.v != $3.v) { + yyerror("2.address family " + "mismatch"); + } + $$.a = $1.a; + $$.m = $3.a; + $$.a.i6[0] &= $$.m.i6[0]; + $$.a.i6[1] &= $$.m.i6[1]; + $$.a.i6[2] &= $$.m.i6[2]; + $$.a.i6[3] &= $$.m.i6[3]; + $$.v = $1.v; + yyexpectaddr = 0; + } + | hostname IPNY_MASK hexnumber { $$.a = $1.a; + $$.m.in4.s_addr = htonl($3); + $$.a.in4.s_addr &= $$.m.in4.s_addr; + $$.v = 4; + } ; portstuff: @@ -562,13 +716,40 @@ hexnumber: ; hostname: - YY_STR { $$.s_addr = lookuphost($1); - free($1); - if ($$.s_addr == 0) + YY_STR { i6addr_t addr; + if (gethost($1, &addr, 0) == 0) { + $$.a = addr; + $$.v = 4; + } else + if (gethost($1, &addr, 1) == 0) { + $$.a = addr; + $$.v = 6; + } else { yyerror("Unknown hostname"); + } + if ($$.v != 0) + nat->in_v = $$.v; + free($1); + } + | YY_NUMBER { bzero(&$$.a, sizeof($$.a)); + $$.a.in4.s_addr = htonl($1); + if ($$.a.in4.s_addr != 0) + $$.v = 4; + else + $$.v = nat->in_v; + if ($$.v != 0) + nat->in_v = $$.v; + } + | ipv4 { $$ = $1; + nat->in_v = 4; + } + | YY_IPV6 { $$.a = $1; + $$.v = 6; + nat->in_v = 6; + } + | YY_NUMBER YY_IPV6 { $$.a = $2; + $$.v = 6; } - | YY_NUMBER { $$.s_addr = htonl($1); } - | ipv4 { $$.s_addr = $1.s_addr; } ; compare: @@ -585,13 +766,20 @@ range: | YY_RANGE_IN { $$ = FR_INRANGE; } ; +ipaddr: ipv4 { $$ = $1; } + | YY_IPV6 { $$.a = $1; + $$.v = 6; + } + ; + ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { yyerror("Invalid octet string for IP address"); return 0; } - $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; - $$.s_addr = htonl($$.s_addr); + $$.a.in4.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; + $$.a.in4.s_addr = htonl($$.a.in4.s_addr); + $$.v = 4; } ; @@ -844,13 +1032,3 @@ void *ptr; } } -static u_32_t lookuphost(name) -char *name; -{ - i6addr_t addr; - - if (gethost(name, &addr, 0) == -1) { - return 0; - } - return addr.in4_addr; -} diff --git a/usr/src/cmd/ipf/tools/lexer.c b/usr/src/cmd/ipf/tools/lexer.c index 39975a55ce..3b74edee90 100644 --- a/usr/src/cmd/ipf/tools/lexer.c +++ b/usr/src/cmd/ipf/tools/lexer.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004 by Darren Reed. + * Copyright (C) 2002-2008 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -398,7 +398,7 @@ nextchar: * 0000:0000:0000:0000:0000:0000:0000:0000 */ #ifdef USE_INET6 - if (yyexpectaddr == 1 && isbuilding == 0 && (ishex(c) || c == ':')) { + if (isbuilding == 0 && (ishex(c) || c == ':')) { char ipv6buf[45 + 1], *s, oc; int start; -- cgit v1.2.3