xref: /illumos-gate/usr/src/cmd/ipf/lib/common/printnat.c (revision 6aed92a9)
1 /*
2  * Copyright (C) 1993-2001 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 2005 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.14 2003/04/13 06:39:16 darrenr Exp $";
20 #endif
21 
22 
23 void printactivenat(nat, opts)
24 nat_t *nat;
25 int opts;
26 {
27 	u_int hv1, hv2;
28 
29 	printf("%s", getnattype(nat->nat_ptr));
30 
31 	if (nat->nat_flags & SI_CLONE)
32 		printf(" CLONE");
33 
34 	printf(" %-15s", inet_ntoa(nat->nat_inip));
35 
36 	if ((nat->nat_flags & IPN_TCPUDP) != 0)
37 		printf(" %-5hu", ntohs(nat->nat_inport));
38 
39 	printf(" <- -> %-15s",inet_ntoa(nat->nat_outip));
40 
41 	if ((nat->nat_flags & IPN_TCPUDP) != 0)
42 		printf(" %-5hu", ntohs(nat->nat_outport));
43 
44 	printf(" [%s", inet_ntoa(nat->nat_oip));
45 	if ((nat->nat_flags & IPN_TCPUDP) != 0)
46 		printf(" %hu", ntohs(nat->nat_oport));
47 	printf("]");
48 
49 	if (opts & OPT_VERBOSE) {
50 		printf("\n\tage %lu use %hu sumd %s/",
51 			nat->nat_age, nat->nat_use, getsumd(nat->nat_sumd[0]));
52                 if ((nat->nat_flags & SI_WILDP) == 0) {
53                         hv1 = NAT_HASH_FN(nat->nat_inip.s_addr,
54                                         nat->nat_inport, 0xffffffff);
55                         hv1 = NAT_HASH_FN(nat->nat_oip.s_addr,
56                                         hv1 + nat->nat_oport, NAT_TABLE_SZ);
57                         hv2 = NAT_HASH_FN(nat->nat_outip.s_addr,
58                                         nat->nat_outport, 0xffffffff);
59                         hv2 = NAT_HASH_FN(nat->nat_oip.s_addr,
60                                         hv2 + nat->nat_oport, NAT_TABLE_SZ);
61                 } else {
62                         hv1 = NAT_HASH_FN(nat->nat_inip.s_addr, 0,
63                                         0xffffffff);
64                         hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, hv1,
65                                         NAT_TABLE_SZ);
66                         hv2 = NAT_HASH_FN(nat->nat_outip.s_addr, 0,
67                                         0xffffffff);
68                         hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, hv2,
69                                         NAT_TABLE_SZ);
70                 }
71 		printf("%s pr %u bkt %d/%d flags %x\n",
72 			getsumd(nat->nat_sumd[1]), nat->nat_p,
73 			hv1, hv2, nat->nat_flags);
74 		printf("\tifp %s", getifname(nat->nat_ifps[0]));
75 		printf(",%s ", getifname(nat->nat_ifps[1]));
76 #ifdef	USE_QUAD_T
77 		printf("bytes %qu/%qu pkts %qu/%qu",
78 			(unsigned long long)nat->nat_bytes[0],
79 			(unsigned long long)nat->nat_bytes[1],
80 			(unsigned long long)nat->nat_pkts[0],
81 			(unsigned long long)nat->nat_pkts[1]);
82 #else
83 		printf("bytes %lu/%lu pkts %lu/%lu", nat->nat_bytes[0],
84 			nat->nat_bytes[1], nat->nat_pkts[0], nat->nat_pkts[1]);
85 #endif
86 #if SOLARIS
87 		printf(" %lx", nat->nat_ipsumd);
88 #endif
89 	}
90 
91 	putchar('\n');
92 	if (nat->nat_aps)
93 		printaps(nat->nat_aps, opts);
94 }
95 
96 
97 /*
98  * Print out a NAT rule
99  */
100 void printnat(np, opts)
101 ipnat_t *np;
102 int opts;
103 {
104 	struct	protoent	*pr;
105 	struct	servent	*sv;
106 	int	bits;
107 
108 	pr = getprotobynumber(np->in_p);
109 
110 	switch (np->in_redir)
111 	{
112 	case NAT_REDIRECT :
113 		printf("rdr");
114 		break;
115 	case NAT_MAP :
116 		printf("map");
117 		break;
118 	case NAT_MAPBLK :
119 		printf("map-block");
120 		break;
121 	case NAT_BIMAP :
122 		printf("bimap");
123 		break;
124 	default :
125 		fprintf(stderr, "unknown value for in_redir: %#x\n",
126 			np->in_redir);
127 		break;
128 	}
129 
130 	printf(" %s", np->in_ifnames[0]);
131 	if ((np->in_ifnames[1][0] != '\0') &&
132 	    (strncmp(np->in_ifnames[0], np->in_ifnames[1], LIFNAMSIZ) != 0)) {
133 		printf(",%s ", np->in_ifnames[1]);
134 	}
135 	putchar(' ');
136 
137 	if (np->in_flags & IPN_FILTER) {
138 		if (np->in_flags & IPN_NOTSRC)
139 			printf("! ");
140 		printf("from ");
141 		if (np->in_redir == NAT_REDIRECT) {
142 			printhostmask(4, (u_32_t *)&np->in_srcip,
143 				      (u_32_t *)&np->in_srcmsk);
144 		} else {
145 			printhostmask(4, (u_32_t *)&np->in_inip,
146 				      (u_32_t *)&np->in_inmsk);
147 		}
148 		if (np->in_scmp)
149 			printportcmp(np->in_p, &np->in_tuc.ftu_src);
150 
151 		if (np->in_flags & IPN_NOTDST)
152 			printf(" !");
153 		printf(" to ");
154 		if (np->in_redir == NAT_REDIRECT) {
155 			printhostmask(4, (u_32_t *)&np->in_outip,
156 				      (u_32_t *)&np->in_outmsk);
157 		} else {
158 			printhostmask(4, (u_32_t *)&np->in_srcip,
159 				      (u_32_t *)&np->in_srcmsk);
160 		}
161 		if (np->in_dcmp)
162 			printportcmp(np->in_p, &np->in_tuc.ftu_dst);
163 	}
164 
165 	if (np->in_redir == NAT_REDIRECT) {
166 		if (!(np->in_flags & IPN_FILTER)) {
167 			printf("%s", inet_ntoa(np->in_out[0].in4));
168 			bits = count4bits(np->in_outmsk);
169 			if (bits != -1)
170 				printf("/%d ", bits);
171 			else
172 				printf("/%s ", inet_ntoa(np->in_out[1].in4));
173 			printf("port %d", ntohs(np->in_pmin));
174 			if (np->in_pmax != np->in_pmin)
175 				printf("-%d", ntohs(np->in_pmax));
176 		}
177 		printf(" -> %s", inet_ntoa(np->in_in[0].in4));
178 		if (np->in_flags & IPN_SPLIT)
179 			printf(",%s", inet_ntoa(np->in_in[1].in4));
180 		if (np->in_inip == 0) {
181 			bits = count4bits(np->in_inmsk);
182 			printf("/%d", bits);
183 		}
184 		printf(" port %d", ntohs(np->in_pnext));
185 		if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP)
186 			printf(" tcp/udp");
187 		else if ((np->in_flags & IPN_TCP) == IPN_TCP)
188 			printf(" tcp");
189 		else if ((np->in_flags & IPN_UDP) == IPN_UDP)
190 			printf(" udp");
191 		else if (np->in_p == 0)
192 			printf(" ip");
193 		else if (pr != NULL)
194 			printf(" %s", pr->p_name);
195 		else
196 			printf(" %d", np->in_p);
197 		if (np->in_flags & IPN_ROUNDR)
198 			printf(" round-robin");
199 		if (np->in_flags & IPN_FRAG)
200 			printf(" frag");
201 		if (np->in_age[0] != 0 || np->in_age[1] != 0) {
202 			printf(" age %d/%d", np->in_age[0], np->in_age[1]);
203 		}
204 		if (np->in_flags & IPN_STICKY)
205 			printf(" sticky");
206 		if (np->in_mssclamp != 0)
207 			printf(" mssclamp %d", np->in_mssclamp);
208 		if (*np->in_plabel != '\0') {
209 			printf(" proxy %.*s/", (int)sizeof(np->in_plabel),
210 				np->in_plabel);
211 			if (pr != NULL)
212 				fputs(pr->p_name, stdout);
213 			else
214 				printf("%d", np->in_p);
215 		}
216 		printf("\n");
217 		if (opts & OPT_DEBUG)
218 			printf("\tspc %lu flg %#x max %u use %d\n",
219 			       np->in_space, np->in_flags,
220 			       np->in_pmax, np->in_use);
221 	} else {
222 		if (!(np->in_flags & IPN_FILTER)) {
223 			printf("%s/", inet_ntoa(np->in_in[0].in4));
224 			bits = count4bits(np->in_inmsk);
225 			if (bits != -1)
226 				printf("%d", bits);
227 			else
228 				printf("%s", inet_ntoa(np->in_in[1].in4));
229 		}
230 		printf(" -> ");
231 		if (np->in_flags & IPN_IPRANGE) {
232 			printf("range %s-", inet_ntoa(np->in_out[0].in4));
233 			printf("%s", inet_ntoa(np->in_out[1].in4));
234 		} else {
235 			printf("%s/", inet_ntoa(np->in_out[0].in4));
236 			bits = count4bits(np->in_outmsk);
237 			if (bits != -1)
238 				printf("%d", bits);
239 			else
240 				printf("%s", inet_ntoa(np->in_out[1].in4));
241 		}
242 		if (*np->in_plabel != '\0') {
243 			printf(" proxy port");
244 			if (np->in_dcmp != 0)
245 				np->in_dport = htons(np->in_dport);
246 			if (np->in_dport != 0) {
247 				if (pr != NULL)
248 					sv = getservbyport(np->in_dport,
249 							   pr->p_name);
250 				else
251 					sv = getservbyport(np->in_dport, NULL);
252 				if (sv != NULL)
253 					printf(" %s", sv->s_name);
254 				else
255 					printf(" %hu", ntohs(np->in_dport));
256 			}
257 			printf(" %.*s/", (int)sizeof(np->in_plabel),
258 				np->in_plabel);
259 			if (pr != NULL)
260 				fputs(pr->p_name, stdout);
261 			else
262 				printf("%d", np->in_p);
263 		} else if (np->in_redir == NAT_MAPBLK) {
264 			if ((np->in_pmin == 0) &&
265 			    (np->in_flags & IPN_AUTOPORTMAP))
266 				printf(" ports auto");
267 			else
268 				printf(" ports %d", np->in_pmin);
269 			if (opts & OPT_DEBUG)
270 				printf("\n\tip modulous %d", np->in_pmax);
271 		} else if (np->in_pmin || np->in_pmax) {
272 			printf(" portmap");
273 			if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP)
274 				printf(" tcp/udp");
275 			else if (np->in_flags & IPN_TCP)
276 				printf(" tcp");
277 			else if (np->in_flags & IPN_UDP)
278 				printf(" udp");
279 			if (np->in_flags & IPN_AUTOPORTMAP) {
280 				printf(" auto");
281 				if (opts & OPT_DEBUG)
282 					printf(" [%d:%d %d %d]",
283 					       ntohs(np->in_pmin),
284 					       ntohs(np->in_pmax),
285 					       np->in_ippip, np->in_ppip);
286 			} else {
287 				printf(" %d:%d", ntohs(np->in_pmin),
288 				       ntohs(np->in_pmax));
289 			}
290 		}
291 		if (np->in_flags & IPN_FRAG)
292 			printf(" frag");
293 		if (np->in_age[0] != 0 || np->in_age[1] != 0) {
294 			printf(" age %d/%d", np->in_age[0], np->in_age[1]);
295 		}
296 		if (np->in_mssclamp != 0)
297 			printf(" mssclamp %d", np->in_mssclamp);
298 		printf("\n");
299 		if (opts & OPT_DEBUG) {
300 			struct in_addr nip;
301 
302 			nip.s_addr = htonl(np->in_nextip.s_addr);
303 
304 			printf("\tspace %lu nextip %s pnext %d", np->in_space,
305 			       inet_ntoa(nip), np->in_pnext);
306 			printf(" flags %x use %u\n",
307 			       np->in_flags, np->in_use);
308 		}
309 	}
310 }
311