xref: /illumos-gate/usr/src/cmd/ipf/lib/common/printnat.c (revision d6c23f6f)
1 /*
2  * Copyright (C) 2002-2005 by Darren Reed.
3  *
4  * See the IPFILTER.LICENCE file for details on licencing.
5  *
6  * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
7  *
8  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
9  * Use is subject to license terms.
10  */
11 
12 #pragma ident	"%Z%%M%	%I%	%E% SMI"
13 
14 #include "ipf.h"
15 #include "kmem.h"
16 
17 
18 #if !defined(lint)
19 static const char rcsid[] = "@(#)$Id: printnat.c,v 1.22.2.9 2005/06/12 07:18:43 darrenr Exp $";
20 #endif
21 
22 /*
23  * Print out a NAT rule
24  */
25 void printnat(np, opts)
26 ipnat_t *np;
27 int opts;
28 {
29 	struct	protoent	*pr;
30 	int	bits, af;
31 	char	ipbuf[INET6_ADDRSTRLEN];
32 	void	*ptr;
33 
34 	pr = getprotobynumber(np->in_p);
35 
36 	switch (np->in_redir)
37 	{
38 	case NAT_REDIRECT :
39 		printf("rdr");
40 		break;
41 	case NAT_MAP :
42 		printf("map");
43 		break;
44 	case NAT_MAPBLK :
45 		printf("map-block");
46 		break;
47 	case NAT_BIMAP :
48 		printf("bimap");
49 		break;
50 	default :
51 		fprintf(stderr, "unknown value for in_redir: %#x\n",
52 			np->in_redir);
53 		break;
54 	}
55 
56 	printf(" %s", np->in_ifnames[0]);
57 	if ((np->in_ifnames[1][0] != '\0') &&
58 	    (strncmp(np->in_ifnames[0], np->in_ifnames[1], LIFNAMSIZ) != 0)) {
59 		printf(",%s ", np->in_ifnames[1]);
60 	}
61 	putchar(' ');
62 
63 	if (np->in_flags & IPN_FILTER) {
64 		if (np->in_flags & IPN_NOTSRC)
65 			printf("! ");
66 		printf("from ");
67 		if (np->in_redir == NAT_REDIRECT) {
68 			printhostmask(np->in_v, (u_32_t *)&np->in_src[0],
69 				      (u_32_t *)&np->in_src[1]);
70 		} else {
71 			printhostmask(np->in_v, (u_32_t *)&np->in_in[0],
72 				      (u_32_t *)&np->in_in[1]);
73 		}
74 		if (np->in_scmp)
75 			printportcmp(np->in_p, &np->in_tuc.ftu_src);
76 
77 		if (np->in_flags & IPN_NOTDST)
78 			printf(" !");
79 		printf(" to ");
80 		if (np->in_redir == NAT_REDIRECT) {
81 			printhostmask(np->in_v, (u_32_t *)&np->in_out[0],
82 				      (u_32_t *)&np->in_out[1]);
83 		} else {
84 			printhostmask(np->in_v, (u_32_t *)&np->in_src[0],
85 				      (u_32_t *)&np->in_src[1]);
86 		}
87 		if (np->in_dcmp)
88 			printportcmp(np->in_p, &np->in_tuc.ftu_dst);
89 	}
90 
91 	if (np->in_v == 4)
92 		af = AF_INET;
93 	else if (np->in_v == 6)
94 		af = AF_INET6;
95 	else
96 		af = 0;
97 
98 	if (np->in_redir == NAT_REDIRECT) {
99 		if (!(np->in_flags & IPN_FILTER)) {
100 			ptr = (void *)(u_32_t *)&np->in_out[0];
101 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
102 			printmask(np->in_v, (u_32_t *)&np->in_out[1]);
103 			if (np->in_flags & IPN_TCPUDP) {
104 				printf(" port %d", ntohs(np->in_pmin));
105 				if (np->in_pmax != np->in_pmin)
106 					printf("-%d", ntohs(np->in_pmax));
107 			}
108 		}
109 		printf(" -> ");
110 		ptr = (void *)(u_32_t *)&np->in_in[0];
111 		printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
112 		if (np->in_flags & IPN_SPLIT) {
113 			printf(",");
114 			ptr = (void *)(u_32_t *)&np->in_in[1];
115 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
116 		}
117 		if (((np->in_v == 4) && (np->in_inip == 0)) ||
118 		    ((np->in_v == 6) && IP6_ISZERO(&np->in_in[0])))
119 			printmask(np->in_v, (u_32_t *)&np->in_in[1]);
120 
121 		if (np->in_flags & IPN_TCPUDP) {
122 			if ((np->in_flags & IPN_FIXEDDPORT) != 0)
123 				printf(" port = %d", ntohs(np->in_pnext));
124 			else
125 				printf(" port %d", ntohs(np->in_pnext));
126 		}
127 		putchar(' ');
128 		printproto(pr, np->in_p, np);
129 		if (np->in_flags & IPN_ROUNDR)
130 			printf(" round-robin");
131 		if (np->in_flags & IPN_FRAG)
132 			printf(" frag");
133 		if (np->in_age[0] != 0 || np->in_age[1] != 0) {
134 			printf(" age %d/%d", np->in_age[0], np->in_age[1]);
135 		}
136 		if (np->in_flags & IPN_STICKY)
137 			printf(" sticky");
138 		if (np->in_mssclamp != 0)
139 			printf(" mssclamp %d", np->in_mssclamp);
140 		if (*np->in_plabel != '\0')
141 			printf(" proxy %.*s", (int)sizeof (np->in_plabel),
142 				np->in_plabel);
143 		if (np->in_tag.ipt_tag[0] != '\0')
144 			printf(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag);
145 		printf("\n");
146 		if (opts & OPT_DEBUG)
147 			printf("\tpmax %u\n", np->in_pmax);
148 	} else {
149 		if (!(np->in_flags & IPN_FILTER)) {
150 			ptr = (void *)(u_32_t *)&np->in_in[0];
151 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
152 			printmask(np->in_v, (u_32_t *)&np->in_in[1]);
153 		}
154 		printf(" -> ");
155 		if (np->in_flags & IPN_IPRANGE) {
156 			printf("range ");
157 			ptr = (void *)(u_32_t *)&np->in_out[0];
158 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
159 			printf("-");
160 			ptr = (void *)(u_32_t *)&np->in_out[1];
161 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
162 		} else {
163 			ptr = (void *)(u_32_t *)&np->in_out[0];
164 			printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf)));
165 			printmask(np->in_v, (u_32_t *)&np->in_out[1]);
166 		}
167 		if (*np->in_plabel != '\0') {
168 			printf(" proxy port ");
169 			if (np->in_dcmp != 0)
170 				np->in_dport = htons(np->in_dport);
171 			if (np->in_dport != 0) {
172 				char *s;
173 
174 				s = portname(np->in_p, ntohs(np->in_dport));
175 				if (s != NULL)
176 					fputs(s, stdout);
177 				else
178 					fputs("???", stdout);
179 			}
180 			printf(" %.*s/", (int)sizeof (np->in_plabel),
181 				np->in_plabel);
182 			printproto(pr, np->in_p, NULL);
183 		} else if (np->in_redir == NAT_MAPBLK) {
184 			if ((np->in_pmin == 0) &&
185 			    (np->in_flags & IPN_AUTOPORTMAP))
186 				printf(" ports auto");
187 			else
188 				printf(" ports %d", np->in_pmin);
189 			if (opts & OPT_DEBUG)
190 				printf("\n\tip modulous %d", np->in_pmax);
191 		} else if (np->in_pmin || np->in_pmax) {
192 			if (np->in_flags & IPN_ICMPQUERY) {
193 				printf(" icmpidmap ");
194 			} else {
195 				printf(" portmap ");
196 			}
197 			printproto(pr, np->in_p, np);
198 			if (np->in_flags & IPN_AUTOPORTMAP) {
199 				printf(" auto");
200 				if (opts & OPT_DEBUG)
201 					printf(" [%d:%d %d %d]",
202 					       ntohs(np->in_pmin),
203 					       ntohs(np->in_pmax),
204 					       np->in_ippip, np->in_ppip);
205 			} else {
206 				printf(" %d:%d", ntohs(np->in_pmin),
207 				       ntohs(np->in_pmax));
208 			}
209 		} else if (np->in_flags & IPN_TCPUDP || np->in_p) {
210 			putchar(' ');
211 			printproto(pr, np->in_p, np);
212 		}
213 
214 		if (np->in_flags & IPN_FRAG)
215 			printf(" frag");
216 		if (np->in_age[0] != 0 || np->in_age[1] != 0) {
217 			printf(" age %d/%d", np->in_age[0], np->in_age[1]);
218 		}
219 		if (np->in_mssclamp != 0)
220 			printf(" mssclamp %d", np->in_mssclamp);
221 		if (np->in_tag.ipt_tag[0] != '\0')
222 			printf(" tag %s", np->in_tag.ipt_tag);
223 		printf("\n");
224 		if (opts & OPT_DEBUG) {
225 			struct in_addr nip;
226 
227 			nip.s_addr = htonl(np->in_nextip.s_addr);
228 
229 			printf("\tnextip %s pnext %d\n",
230 			       inet_ntoa(nip), np->in_pnext);
231 		}
232 	}
233 
234 	if (opts & OPT_DEBUG) {
235 		printf("\tspace %lu use %u hits %lu flags %#x proto %d hv %d\n",
236 			np->in_space, np->in_use, np->in_hits,
237 			np->in_flags, np->in_p, np->in_hv);
238 		printf("\tifp[0] %p ifp[1] %p apr %p\n",
239 			np->in_ifps[0], np->in_ifps[1], np->in_apr);
240 		printf("\ttqehead %p/%p comment %p\n",
241 			np->in_tqehead[0], np->in_tqehead[1], np->in_comment);
242 	}
243 }
244