xref: /illumos-gate/usr/src/cmd/ipf/lib/common/printnat.c (revision ab073b32)
17c478bd9Sstevel@tonic-gate /*
2d6c23f6fSyx  * Copyright (C) 2002-2005 by Darren Reed.
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
57c478bd9Sstevel@tonic-gate  *
67c478bd9Sstevel@tonic-gate  * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
76aed92a9Syx  *
8d6c23f6fSyx  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
96aed92a9Syx  * Use is subject to license terms.
107c478bd9Sstevel@tonic-gate  */
117c478bd9Sstevel@tonic-gate 
126aed92a9Syx #pragma ident	"%Z%%M%	%I%	%E% SMI"
136aed92a9Syx 
147c478bd9Sstevel@tonic-gate #include "ipf.h"
157c478bd9Sstevel@tonic-gate #include "kmem.h"
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate 
187c478bd9Sstevel@tonic-gate #if !defined(lint)
19ab25eeb5Syz static const char rcsid[] = "@(#)$Id: printnat.c,v 1.22.2.9 2005/06/12 07:18:43 darrenr Exp $";
207c478bd9Sstevel@tonic-gate #endif
217c478bd9Sstevel@tonic-gate 
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Print out a NAT rule
247c478bd9Sstevel@tonic-gate  */
printnat(np,opts)257c478bd9Sstevel@tonic-gate void printnat(np, opts)
267c478bd9Sstevel@tonic-gate ipnat_t *np;
277c478bd9Sstevel@tonic-gate int opts;
287c478bd9Sstevel@tonic-gate {
297c478bd9Sstevel@tonic-gate 	struct	protoent	*pr;
30d6c23f6fSyx 	int	bits, af;
31d6c23f6fSyx 	char	ipbuf[INET6_ADDRSTRLEN];
32d6c23f6fSyx 	void	*ptr;
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate 	pr = getprotobynumber(np->in_p);
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate 	switch (np->in_redir)
377c478bd9Sstevel@tonic-gate 	{
387c478bd9Sstevel@tonic-gate 	case NAT_REDIRECT :
397c478bd9Sstevel@tonic-gate 		printf("rdr");
407c478bd9Sstevel@tonic-gate 		break;
417c478bd9Sstevel@tonic-gate 	case NAT_MAP :
427c478bd9Sstevel@tonic-gate 		printf("map");
437c478bd9Sstevel@tonic-gate 		break;
447c478bd9Sstevel@tonic-gate 	case NAT_MAPBLK :
457c478bd9Sstevel@tonic-gate 		printf("map-block");
467c478bd9Sstevel@tonic-gate 		break;
477c478bd9Sstevel@tonic-gate 	case NAT_BIMAP :
487c478bd9Sstevel@tonic-gate 		printf("bimap");
497c478bd9Sstevel@tonic-gate 		break;
507c478bd9Sstevel@tonic-gate 	default :
517c478bd9Sstevel@tonic-gate 		fprintf(stderr, "unknown value for in_redir: %#x\n",
527c478bd9Sstevel@tonic-gate 			np->in_redir);
537c478bd9Sstevel@tonic-gate 		break;
547c478bd9Sstevel@tonic-gate 	}
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate 	printf(" %s", np->in_ifnames[0]);
577c478bd9Sstevel@tonic-gate 	if ((np->in_ifnames[1][0] != '\0') &&
587c478bd9Sstevel@tonic-gate 	    (strncmp(np->in_ifnames[0], np->in_ifnames[1], LIFNAMSIZ) != 0)) {
597c478bd9Sstevel@tonic-gate 		printf(",%s ", np->in_ifnames[1]);
607c478bd9Sstevel@tonic-gate 	}
617c478bd9Sstevel@tonic-gate 	putchar(' ');
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate 	if (np->in_flags & IPN_FILTER) {
647c478bd9Sstevel@tonic-gate 		if (np->in_flags & IPN_NOTSRC)
657c478bd9Sstevel@tonic-gate 			printf("! ");
667c478bd9Sstevel@tonic-gate 		printf("from ");
677c478bd9Sstevel@tonic-gate 		if (np->in_redir == NAT_REDIRECT) {
68d6c23f6fSyx 			printhostmask(np->in_v, (u_32_t *)&np->in_src[0],
69d6c23f6fSyx 				      (u_32_t *)&np->in_src[1]);
707c478bd9Sstevel@tonic-gate 		} else {
71d6c23f6fSyx 			printhostmask(np->in_v, (u_32_t *)&np->in_in[0],
72d6c23f6fSyx 				      (u_32_t *)&np->in_in[1]);
737c478bd9Sstevel@tonic-gate 		}
747c478bd9Sstevel@tonic-gate 		if (np->in_scmp)
757c478bd9Sstevel@tonic-gate 			printportcmp(np->in_p, &np->in_tuc.ftu_src);
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 		if (np->in_flags & IPN_NOTDST)
787c478bd9Sstevel@tonic-gate 			printf(" !");
797c478bd9Sstevel@tonic-gate 		printf(" to ");
807c478bd9Sstevel@tonic-gate 		if (np->in_redir == NAT_REDIRECT) {
81d6c23f6fSyx 			printhostmask(np->in_v, (u_32_t *)&np->in_out[0],
82d6c23f6fSyx 				      (u_32_t *)&np->in_out[1]);
837c478bd9Sstevel@tonic-gate 		} else {
84d6c23f6fSyx 			printhostmask(np->in_v, (u_32_t *)&np->in_src[0],
85d6c23f6fSyx 				      (u_32_t *)&np->in_src[1]);
867c478bd9Sstevel@tonic-gate 		}
877c478bd9Sstevel@tonic-gate 		if (np->in_dcmp)
887c478bd9Sstevel@tonic-gate 			printportcmp(np->in_p, &np->in_tuc.ftu_dst);
897c478bd9Sstevel@tonic-gate 	}
907c478bd9Sstevel@tonic-gate 
91d6c23f6fSyx 	if (np->in_v == 4)
92d6c23f6fSyx 		af = AF_INET;
93d6c23f6fSyx 	else if (np->in_v == 6)
94d6c23f6fSyx 		af = AF_INET6;
95d6c23f6fSyx 	else
96d6c23f6fSyx 		af = 0;
97d6c23f6fSyx 
987c478bd9Sstevel@tonic-gate 	if (np->in_redir == NAT_REDIRECT) {
997c478bd9Sstevel@tonic-gate 		if (!(np->in_flags & IPN_FILTER)) {
100d6c23f6fSyx 			ptr = (void *)(u_32_t *)&np->in_out[0];
101d6c23f6fSyx 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
102d6c23f6fSyx 			printmask(np->in_v, (u_32_t *)&np->in_out[1]);
103ab25eeb5Syz 			if (np->in_flags & IPN_TCPUDP) {
104ab25eeb5Syz 				printf(" port %d", ntohs(np->in_pmin));
105ab25eeb5Syz 				if (np->in_pmax != np->in_pmin)
106ab25eeb5Syz 					printf("-%d", ntohs(np->in_pmax));
107ab25eeb5Syz 			}
1087c478bd9Sstevel@tonic-gate 		}
109d6c23f6fSyx 		printf(" -> ");
110d6c23f6fSyx 		ptr = (void *)(u_32_t *)&np->in_in[0];
111d6c23f6fSyx 		printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
112d6c23f6fSyx 		if (np->in_flags & IPN_SPLIT) {
113d6c23f6fSyx 			printf(",");
114d6c23f6fSyx 			ptr = (void *)(u_32_t *)&np->in_in[1];
115d6c23f6fSyx 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
116ef292b7fSjojemann 		}
117d6c23f6fSyx 		if (((np->in_v == 4) && (np->in_inip == 0)) ||
118d6c23f6fSyx 		    ((np->in_v == 6) && IP6_ISZERO(&np->in_in[0])))
119d6c23f6fSyx 			printmask(np->in_v, (u_32_t *)&np->in_in[1]);
120d6c23f6fSyx 
121ab25eeb5Syz 		if (np->in_flags & IPN_TCPUDP) {
122ab25eeb5Syz 			if ((np->in_flags & IPN_FIXEDDPORT) != 0)
123ab25eeb5Syz 				printf(" port = %d", ntohs(np->in_pnext));
124ab25eeb5Syz 			else
125ab25eeb5Syz 				printf(" port %d", ntohs(np->in_pnext));
1266aed92a9Syx 		}
127ab25eeb5Syz 		putchar(' ');
128ab25eeb5Syz 		printproto(pr, np->in_p, np);
1297c478bd9Sstevel@tonic-gate 		if (np->in_flags & IPN_ROUNDR)
1307c478bd9Sstevel@tonic-gate 			printf(" round-robin");
1317c478bd9Sstevel@tonic-gate 		if (np->in_flags & IPN_FRAG)
1327c478bd9Sstevel@tonic-gate 			printf(" frag");
1337c478bd9Sstevel@tonic-gate 		if (np->in_age[0] != 0 || np->in_age[1] != 0) {
1347c478bd9Sstevel@tonic-gate 			printf(" age %d/%d", np->in_age[0], np->in_age[1]);
1357c478bd9Sstevel@tonic-gate 		}
1367c478bd9Sstevel@tonic-gate 		if (np->in_flags & IPN_STICKY)
1377c478bd9Sstevel@tonic-gate 			printf(" sticky");
1387c478bd9Sstevel@tonic-gate 		if (np->in_mssclamp != 0)
1397c478bd9Sstevel@tonic-gate 			printf(" mssclamp %d", np->in_mssclamp);
140ab25eeb5Syz 		if (*np->in_plabel != '\0')
141d6c23f6fSyx 			printf(" proxy %.*s", (int)sizeof (np->in_plabel),
1427c478bd9Sstevel@tonic-gate 				np->in_plabel);
143ab25eeb5Syz 		if (np->in_tag.ipt_tag[0] != '\0')
144ab25eeb5Syz 			printf(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag);
1457c478bd9Sstevel@tonic-gate 		printf("\n");
1467c478bd9Sstevel@tonic-gate 		if (opts & OPT_DEBUG)
147ab25eeb5Syz 			printf("\tpmax %u\n", np->in_pmax);
1487c478bd9Sstevel@tonic-gate 	} else {
1497c478bd9Sstevel@tonic-gate 		if (!(np->in_flags & IPN_FILTER)) {
150d6c23f6fSyx 			ptr = (void *)(u_32_t *)&np->in_in[0];
151d6c23f6fSyx 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
152d6c23f6fSyx 			printmask(np->in_v, (u_32_t *)&np->in_in[1]);
1537c478bd9Sstevel@tonic-gate 		}
1547c478bd9Sstevel@tonic-gate 		printf(" -> ");
1557c478bd9Sstevel@tonic-gate 		if (np->in_flags & IPN_IPRANGE) {
156d6c23f6fSyx 			printf("range ");
157d6c23f6fSyx 			ptr = (void *)(u_32_t *)&np->in_out[0];
158d6c23f6fSyx 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
159d6c23f6fSyx 			printf("-");
160d6c23f6fSyx 			ptr = (void *)(u_32_t *)&np->in_out[1];
161d6c23f6fSyx 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
1627c478bd9Sstevel@tonic-gate 		} else {
163d6c23f6fSyx 			ptr = (void *)(u_32_t *)&np->in_out[0];
164d6c23f6fSyx 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
165d6c23f6fSyx 			printmask(np->in_v, (u_32_t *)&np->in_out[1]);
1667c478bd9Sstevel@tonic-gate 		}
1677c478bd9Sstevel@tonic-gate 		if (*np->in_plabel != '\0') {
168ab25eeb5Syz 			printf(" proxy port ");
1697c478bd9Sstevel@tonic-gate 			if (np->in_dcmp != 0)
1707c478bd9Sstevel@tonic-gate 				np->in_dport = htons(np->in_dport);
1717c478bd9Sstevel@tonic-gate 			if (np->in_dport != 0) {
172ab25eeb5Syz 				char *s;
173ab25eeb5Syz 
174ab25eeb5Syz 				s = portname(np->in_p, ntohs(np->in_dport));
175ab25eeb5Syz 				if (s != NULL)
176ab25eeb5Syz 					fputs(s, stdout);
1777c478bd9Sstevel@tonic-gate 				else
178ab25eeb5Syz 					fputs("???", stdout);
1797c478bd9Sstevel@tonic-gate 			}
180d6c23f6fSyx 			printf(" %.*s/", (int)sizeof (np->in_plabel),
1817c478bd9Sstevel@tonic-gate 				np->in_plabel);
182ab25eeb5Syz 			printproto(pr, np->in_p, NULL);
1837c478bd9Sstevel@tonic-gate 		} else if (np->in_redir == NAT_MAPBLK) {
1847c478bd9Sstevel@tonic-gate 			if ((np->in_pmin == 0) &&
1857c478bd9Sstevel@tonic-gate 			    (np->in_flags & IPN_AUTOPORTMAP))
1867c478bd9Sstevel@tonic-gate 				printf(" ports auto");
1877c478bd9Sstevel@tonic-gate 			else
1887c478bd9Sstevel@tonic-gate 				printf(" ports %d", np->in_pmin);
1897c478bd9Sstevel@tonic-gate 			if (opts & OPT_DEBUG)
1907c478bd9Sstevel@tonic-gate 				printf("\n\tip modulous %d", np->in_pmax);
1917c478bd9Sstevel@tonic-gate 		} else if (np->in_pmin || np->in_pmax) {
192ab25eeb5Syz 			if (np->in_flags & IPN_ICMPQUERY) {
193ab25eeb5Syz 				printf(" icmpidmap ");
194ab25eeb5Syz 			} else {
195ab25eeb5Syz 				printf(" portmap ");
196ab25eeb5Syz 			}
197ab25eeb5Syz 			printproto(pr, np->in_p, np);
1987c478bd9Sstevel@tonic-gate 			if (np->in_flags & IPN_AUTOPORTMAP) {
1997c478bd9Sstevel@tonic-gate 				printf(" auto");
2007c478bd9Sstevel@tonic-gate 				if (opts & OPT_DEBUG)
2017c478bd9Sstevel@tonic-gate 					printf(" [%d:%d %d %d]",
2027c478bd9Sstevel@tonic-gate 					       ntohs(np->in_pmin),
2037c478bd9Sstevel@tonic-gate 					       ntohs(np->in_pmax),
2047c478bd9Sstevel@tonic-gate 					       np->in_ippip, np->in_ppip);
2057c478bd9Sstevel@tonic-gate 			} else {
2067c478bd9Sstevel@tonic-gate 				printf(" %d:%d", ntohs(np->in_pmin),
2077c478bd9Sstevel@tonic-gate 				       ntohs(np->in_pmax));
2087c478bd9Sstevel@tonic-gate 			}
209ab25eeb5Syz 		} else if (np->in_flags & IPN_TCPUDP || np->in_p) {
210ab25eeb5Syz 			putchar(' ');
211ab25eeb5Syz 			printproto(pr, np->in_p, np);
2127c478bd9Sstevel@tonic-gate 		}
213ab25eeb5Syz 
2147c478bd9Sstevel@tonic-gate 		if (np->in_flags & IPN_FRAG)
2157c478bd9Sstevel@tonic-gate 			printf(" frag");
2167c478bd9Sstevel@tonic-gate 		if (np->in_age[0] != 0 || np->in_age[1] != 0) {
2177c478bd9Sstevel@tonic-gate 			printf(" age %d/%d", np->in_age[0], np->in_age[1]);
2187c478bd9Sstevel@tonic-gate 		}
2197c478bd9Sstevel@tonic-gate 		if (np->in_mssclamp != 0)
2207c478bd9Sstevel@tonic-gate 			printf(" mssclamp %d", np->in_mssclamp);
221ab25eeb5Syz 		if (np->in_tag.ipt_tag[0] != '\0')
222ab25eeb5Syz 			printf(" tag %s", np->in_tag.ipt_tag);
223*ab073b32Sdr 		if (np->in_flags & IPN_SEQUENTIAL)
224*ab073b32Sdr 			printf(" sequential");
2257c478bd9Sstevel@tonic-gate 		printf("\n");
2267c478bd9Sstevel@tonic-gate 		if (opts & OPT_DEBUG) {
2277c478bd9Sstevel@tonic-gate 			struct in_addr nip;
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 			nip.s_addr = htonl(np->in_nextip.s_addr);
2307c478bd9Sstevel@tonic-gate 
231ab25eeb5Syz 			printf("\tnextip %s pnext %d\n",
2327c478bd9Sstevel@tonic-gate 			       inet_ntoa(nip), np->in_pnext);
2337c478bd9Sstevel@tonic-gate 		}
2347c478bd9Sstevel@tonic-gate 	}
235ab25eeb5Syz 
236ab25eeb5Syz 	if (opts & OPT_DEBUG) {
237ab25eeb5Syz 		printf("\tspace %lu use %u hits %lu flags %#x proto %d hv %d\n",
238ab25eeb5Syz 			np->in_space, np->in_use, np->in_hits,
239ab25eeb5Syz 			np->in_flags, np->in_p, np->in_hv);
240ab25eeb5Syz 		printf("\tifp[0] %p ifp[1] %p apr %p\n",
241ab25eeb5Syz 			np->in_ifps[0], np->in_ifps[1], np->in_apr);
242ab25eeb5Syz 		printf("\ttqehead %p/%p comment %p\n",
243ab25eeb5Syz 			np->in_tqehead[0], np->in_tqehead[1], np->in_comment);
244ab25eeb5Syz 	}
2457c478bd9Sstevel@tonic-gate }
246