10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * Copyright (C) 1993-2001 by Darren Reed.
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
50Sstevel@tonic-gate  *
60Sstevel@tonic-gate  * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
7570Syx160601  *
8*2393Syz155240  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
9570Syx160601  * Use is subject to license terms.
100Sstevel@tonic-gate  */
110Sstevel@tonic-gate 
12570Syx160601 #pragma ident	"%Z%%M%	%I%	%E% SMI"
13570Syx160601 
140Sstevel@tonic-gate #include "ipf.h"
150Sstevel@tonic-gate #include "kmem.h"
160Sstevel@tonic-gate 
170Sstevel@tonic-gate 
180Sstevel@tonic-gate #if !defined(lint)
19*2393Syz155240 static const char rcsid[] = "@(#)$Id: printnat.c,v 1.22.2.9 2005/06/12 07:18:43 darrenr Exp $";
200Sstevel@tonic-gate #endif
210Sstevel@tonic-gate 
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Print out a NAT rule
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate void printnat(np, opts)
260Sstevel@tonic-gate ipnat_t *np;
270Sstevel@tonic-gate int opts;
280Sstevel@tonic-gate {
290Sstevel@tonic-gate 	struct	protoent	*pr;
300Sstevel@tonic-gate 	int	bits;
310Sstevel@tonic-gate 
320Sstevel@tonic-gate 	pr = getprotobynumber(np->in_p);
330Sstevel@tonic-gate 
340Sstevel@tonic-gate 	switch (np->in_redir)
350Sstevel@tonic-gate 	{
360Sstevel@tonic-gate 	case NAT_REDIRECT :
370Sstevel@tonic-gate 		printf("rdr");
380Sstevel@tonic-gate 		break;
390Sstevel@tonic-gate 	case NAT_MAP :
400Sstevel@tonic-gate 		printf("map");
410Sstevel@tonic-gate 		break;
420Sstevel@tonic-gate 	case NAT_MAPBLK :
430Sstevel@tonic-gate 		printf("map-block");
440Sstevel@tonic-gate 		break;
450Sstevel@tonic-gate 	case NAT_BIMAP :
460Sstevel@tonic-gate 		printf("bimap");
470Sstevel@tonic-gate 		break;
480Sstevel@tonic-gate 	default :
490Sstevel@tonic-gate 		fprintf(stderr, "unknown value for in_redir: %#x\n",
500Sstevel@tonic-gate 			np->in_redir);
510Sstevel@tonic-gate 		break;
520Sstevel@tonic-gate 	}
530Sstevel@tonic-gate 
540Sstevel@tonic-gate 	printf(" %s", np->in_ifnames[0]);
550Sstevel@tonic-gate 	if ((np->in_ifnames[1][0] != '\0') &&
560Sstevel@tonic-gate 	    (strncmp(np->in_ifnames[0], np->in_ifnames[1], LIFNAMSIZ) != 0)) {
570Sstevel@tonic-gate 		printf(",%s ", np->in_ifnames[1]);
580Sstevel@tonic-gate 	}
590Sstevel@tonic-gate 	putchar(' ');
600Sstevel@tonic-gate 
610Sstevel@tonic-gate 	if (np->in_flags & IPN_FILTER) {
620Sstevel@tonic-gate 		if (np->in_flags & IPN_NOTSRC)
630Sstevel@tonic-gate 			printf("! ");
640Sstevel@tonic-gate 		printf("from ");
650Sstevel@tonic-gate 		if (np->in_redir == NAT_REDIRECT) {
660Sstevel@tonic-gate 			printhostmask(4, (u_32_t *)&np->in_srcip,
670Sstevel@tonic-gate 				      (u_32_t *)&np->in_srcmsk);
680Sstevel@tonic-gate 		} else {
690Sstevel@tonic-gate 			printhostmask(4, (u_32_t *)&np->in_inip,
700Sstevel@tonic-gate 				      (u_32_t *)&np->in_inmsk);
710Sstevel@tonic-gate 		}
720Sstevel@tonic-gate 		if (np->in_scmp)
730Sstevel@tonic-gate 			printportcmp(np->in_p, &np->in_tuc.ftu_src);
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 		if (np->in_flags & IPN_NOTDST)
760Sstevel@tonic-gate 			printf(" !");
770Sstevel@tonic-gate 		printf(" to ");
780Sstevel@tonic-gate 		if (np->in_redir == NAT_REDIRECT) {
790Sstevel@tonic-gate 			printhostmask(4, (u_32_t *)&np->in_outip,
800Sstevel@tonic-gate 				      (u_32_t *)&np->in_outmsk);
810Sstevel@tonic-gate 		} else {
820Sstevel@tonic-gate 			printhostmask(4, (u_32_t *)&np->in_srcip,
830Sstevel@tonic-gate 				      (u_32_t *)&np->in_srcmsk);
840Sstevel@tonic-gate 		}
850Sstevel@tonic-gate 		if (np->in_dcmp)
860Sstevel@tonic-gate 			printportcmp(np->in_p, &np->in_tuc.ftu_dst);
870Sstevel@tonic-gate 	}
880Sstevel@tonic-gate 
890Sstevel@tonic-gate 	if (np->in_redir == NAT_REDIRECT) {
900Sstevel@tonic-gate 		if (!(np->in_flags & IPN_FILTER)) {
910Sstevel@tonic-gate 			printf("%s", inet_ntoa(np->in_out[0].in4));
920Sstevel@tonic-gate 			bits = count4bits(np->in_outmsk);
930Sstevel@tonic-gate 			if (bits != -1)
94*2393Syz155240 				printf("/%d", bits);
950Sstevel@tonic-gate 			else
96*2393Syz155240 				printf("/%s", inet_ntoa(np->in_out[1].in4));
97*2393Syz155240 			if (np->in_flags & IPN_TCPUDP) {
98*2393Syz155240 				printf(" port %d", ntohs(np->in_pmin));
99*2393Syz155240 				if (np->in_pmax != np->in_pmin)
100*2393Syz155240 					printf("-%d", ntohs(np->in_pmax));
101*2393Syz155240 			}
1020Sstevel@tonic-gate 		}
1030Sstevel@tonic-gate 		printf(" -> %s", inet_ntoa(np->in_in[0].in4));
1040Sstevel@tonic-gate 		if (np->in_flags & IPN_SPLIT)
1050Sstevel@tonic-gate 			printf(",%s", inet_ntoa(np->in_in[1].in4));
106*2393Syz155240 		if (np->in_flags & IPN_TCPUDP) {
107*2393Syz155240 			if ((np->in_flags & IPN_FIXEDDPORT) != 0)
108*2393Syz155240 				printf(" port = %d", ntohs(np->in_pnext));
109*2393Syz155240 			else
110*2393Syz155240 				printf(" port %d", ntohs(np->in_pnext));
111570Syx160601 		}
112*2393Syz155240 		putchar(' ');
113*2393Syz155240 		printproto(pr, np->in_p, np);
1140Sstevel@tonic-gate 		if (np->in_flags & IPN_ROUNDR)
1150Sstevel@tonic-gate 			printf(" round-robin");
1160Sstevel@tonic-gate 		if (np->in_flags & IPN_FRAG)
1170Sstevel@tonic-gate 			printf(" frag");
1180Sstevel@tonic-gate 		if (np->in_age[0] != 0 || np->in_age[1] != 0) {
1190Sstevel@tonic-gate 			printf(" age %d/%d", np->in_age[0], np->in_age[1]);
1200Sstevel@tonic-gate 		}
1210Sstevel@tonic-gate 		if (np->in_flags & IPN_STICKY)
1220Sstevel@tonic-gate 			printf(" sticky");
1230Sstevel@tonic-gate 		if (np->in_mssclamp != 0)
1240Sstevel@tonic-gate 			printf(" mssclamp %d", np->in_mssclamp);
125*2393Syz155240 		if (*np->in_plabel != '\0')
126*2393Syz155240 			printf(" proxy %.*s", (int)sizeof(np->in_plabel),
1270Sstevel@tonic-gate 				np->in_plabel);
128*2393Syz155240 		if (np->in_tag.ipt_tag[0] != '\0')
129*2393Syz155240 			printf(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag);
1300Sstevel@tonic-gate 		printf("\n");
1310Sstevel@tonic-gate 		if (opts & OPT_DEBUG)
132*2393Syz155240 			printf("\tpmax %u\n", np->in_pmax);
1330Sstevel@tonic-gate 	} else {
1340Sstevel@tonic-gate 		if (!(np->in_flags & IPN_FILTER)) {
1350Sstevel@tonic-gate 			printf("%s/", inet_ntoa(np->in_in[0].in4));
1360Sstevel@tonic-gate 			bits = count4bits(np->in_inmsk);
1370Sstevel@tonic-gate 			if (bits != -1)
1380Sstevel@tonic-gate 				printf("%d", bits);
1390Sstevel@tonic-gate 			else
1400Sstevel@tonic-gate 				printf("%s", inet_ntoa(np->in_in[1].in4));
1410Sstevel@tonic-gate 		}
1420Sstevel@tonic-gate 		printf(" -> ");
1430Sstevel@tonic-gate 		if (np->in_flags & IPN_IPRANGE) {
1440Sstevel@tonic-gate 			printf("range %s-", inet_ntoa(np->in_out[0].in4));
1450Sstevel@tonic-gate 			printf("%s", inet_ntoa(np->in_out[1].in4));
1460Sstevel@tonic-gate 		} else {
1470Sstevel@tonic-gate 			printf("%s/", inet_ntoa(np->in_out[0].in4));
1480Sstevel@tonic-gate 			bits = count4bits(np->in_outmsk);
1490Sstevel@tonic-gate 			if (bits != -1)
1500Sstevel@tonic-gate 				printf("%d", bits);
1510Sstevel@tonic-gate 			else
1520Sstevel@tonic-gate 				printf("%s", inet_ntoa(np->in_out[1].in4));
1530Sstevel@tonic-gate 		}
1540Sstevel@tonic-gate 		if (*np->in_plabel != '\0') {
155*2393Syz155240 			printf(" proxy port ");
1560Sstevel@tonic-gate 			if (np->in_dcmp != 0)
1570Sstevel@tonic-gate 				np->in_dport = htons(np->in_dport);
1580Sstevel@tonic-gate 			if (np->in_dport != 0) {
159*2393Syz155240 				char *s;
160*2393Syz155240 
161*2393Syz155240 				s = portname(np->in_p, ntohs(np->in_dport));
162*2393Syz155240 				if (s != NULL)
163*2393Syz155240 					fputs(s, stdout);
1640Sstevel@tonic-gate 				else
165*2393Syz155240 					fputs("???", stdout);
1660Sstevel@tonic-gate 			}
1670Sstevel@tonic-gate 			printf(" %.*s/", (int)sizeof(np->in_plabel),
1680Sstevel@tonic-gate 				np->in_plabel);
169*2393Syz155240 			printproto(pr, np->in_p, NULL);
1700Sstevel@tonic-gate 		} else if (np->in_redir == NAT_MAPBLK) {
1710Sstevel@tonic-gate 			if ((np->in_pmin == 0) &&
1720Sstevel@tonic-gate 			    (np->in_flags & IPN_AUTOPORTMAP))
1730Sstevel@tonic-gate 				printf(" ports auto");
1740Sstevel@tonic-gate 			else
1750Sstevel@tonic-gate 				printf(" ports %d", np->in_pmin);
1760Sstevel@tonic-gate 			if (opts & OPT_DEBUG)
1770Sstevel@tonic-gate 				printf("\n\tip modulous %d", np->in_pmax);
1780Sstevel@tonic-gate 		} else if (np->in_pmin || np->in_pmax) {
179*2393Syz155240 			if (np->in_flags & IPN_ICMPQUERY) {
180*2393Syz155240 				printf(" icmpidmap ");
181*2393Syz155240 			} else {
182*2393Syz155240 				printf(" portmap ");
183*2393Syz155240 			}
184*2393Syz155240 			printproto(pr, np->in_p, np);
1850Sstevel@tonic-gate 			if (np->in_flags & IPN_AUTOPORTMAP) {
1860Sstevel@tonic-gate 				printf(" auto");
1870Sstevel@tonic-gate 				if (opts & OPT_DEBUG)
1880Sstevel@tonic-gate 					printf(" [%d:%d %d %d]",
1890Sstevel@tonic-gate 					       ntohs(np->in_pmin),
1900Sstevel@tonic-gate 					       ntohs(np->in_pmax),
1910Sstevel@tonic-gate 					       np->in_ippip, np->in_ppip);
1920Sstevel@tonic-gate 			} else {
1930Sstevel@tonic-gate 				printf(" %d:%d", ntohs(np->in_pmin),
1940Sstevel@tonic-gate 				       ntohs(np->in_pmax));
1950Sstevel@tonic-gate 			}
196*2393Syz155240 		} else if (np->in_flags & IPN_TCPUDP || np->in_p) {
197*2393Syz155240 			putchar(' ');
198*2393Syz155240 			printproto(pr, np->in_p, np);
1990Sstevel@tonic-gate 		}
200*2393Syz155240 
2010Sstevel@tonic-gate 		if (np->in_flags & IPN_FRAG)
2020Sstevel@tonic-gate 			printf(" frag");
2030Sstevel@tonic-gate 		if (np->in_age[0] != 0 || np->in_age[1] != 0) {
2040Sstevel@tonic-gate 			printf(" age %d/%d", np->in_age[0], np->in_age[1]);
2050Sstevel@tonic-gate 		}
2060Sstevel@tonic-gate 		if (np->in_mssclamp != 0)
2070Sstevel@tonic-gate 			printf(" mssclamp %d", np->in_mssclamp);
208*2393Syz155240 		if (np->in_tag.ipt_tag[0] != '\0')
209*2393Syz155240 			printf(" tag %s", np->in_tag.ipt_tag);
2100Sstevel@tonic-gate 		printf("\n");
2110Sstevel@tonic-gate 		if (opts & OPT_DEBUG) {
2120Sstevel@tonic-gate 			struct in_addr nip;
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 			nip.s_addr = htonl(np->in_nextip.s_addr);
2150Sstevel@tonic-gate 
216*2393Syz155240 			printf("\tnextip %s pnext %d\n",
2170Sstevel@tonic-gate 			       inet_ntoa(nip), np->in_pnext);
2180Sstevel@tonic-gate 		}
2190Sstevel@tonic-gate 	}
220*2393Syz155240 
221*2393Syz155240 	if (opts & OPT_DEBUG) {
222*2393Syz155240 		printf("\tspace %lu use %u hits %lu flags %#x proto %d hv %d\n",
223*2393Syz155240 			np->in_space, np->in_use, np->in_hits,
224*2393Syz155240 			np->in_flags, np->in_p, np->in_hv);
225*2393Syz155240 		printf("\tifp[0] %p ifp[1] %p apr %p\n",
226*2393Syz155240 			np->in_ifps[0], np->in_ifps[1], np->in_apr);
227*2393Syz155240 		printf("\ttqehead %p/%p comment %p\n",
228*2393Syz155240 			np->in_tqehead[0], np->in_tqehead[1], np->in_comment);
229*2393Syz155240 	}
2300Sstevel@tonic-gate }
231