4 * Copyright (C) 2012 by Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
8 * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
16 static const char rcsid[] = "@(#)$Id$";
21 * Print out a NAT rule
36 else if (np->in_v[0] == 6)
42 if (np->in_flags & IPN_NO)
47 case NAT_REDIRECT|NAT_ENCAP :
48 PRINTF("encap in on");
51 case NAT_MAP|NAT_ENCAP :
52 PRINTF("encap out on");
55 case NAT_REDIRECT|NAT_DIVERTUDP :
56 PRINTF("divert in on");
59 case NAT_MAP|NAT_DIVERTUDP :
60 PRINTF("divert out on");
63 case NAT_REDIRECT|NAT_REWRITE :
64 PRINTF("rewrite in on");
67 case NAT_MAP|NAT_REWRITE :
68 PRINTF("rewrite out on");
88 FPRINTF(stderr, "unknown value for in_redir: %#x\n",
94 pr = getprotobynumber(proto);
97 if (!strcmp(base + np->in_ifnames[0], "-"))
98 PRINTF(" \"%s\"", base + np->in_ifnames[0]);
100 PRINTF(" %s", base + np->in_ifnames[0]);
101 if ((np->in_ifnames[1] != -1) &&
102 (strcmp(base + np->in_ifnames[0], base + np->in_ifnames[1]) != 0)) {
103 if (!strcmp(base + np->in_ifnames[1], "-"))
104 PRINTF(",\"%s\"", base + np->in_ifnames[1]);
106 PRINTF(",%s", base + np->in_ifnames[1]);
110 if (family == AF_INET6)
113 if (np->in_redir & (NAT_REWRITE|NAT_ENCAP|NAT_DIVERTUDP)) {
114 if ((proto != 0) || (np->in_flags & IPN_TCPUDP)) {
116 printproto(pr, proto, np);
121 if (np->in_flags & IPN_FILTER) {
122 if (np->in_flags & IPN_NOTSRC)
125 printnataddr(np->in_v[0], np->in_names, &np->in_osrc,
128 printportcmp(proto, &np->in_tuc.ftu_src);
130 if (np->in_flags & IPN_NOTDST)
133 printnataddr(np->in_v[0], np->in_names, &np->in_odst,
136 printportcmp(proto, &np->in_tuc.ftu_dst);
139 if (np->in_redir & (NAT_ENCAP|NAT_DIVERTUDP)) {
141 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
143 if ((np->in_redir & NAT_DIVERTUDP) != 0)
144 PRINTF(",%u", np->in_spmin);
146 printnataddr(np->in_v[1], np->in_names, &np->in_ndst,
148 if ((np->in_redir & NAT_DIVERTUDP) != 0)
149 PRINTF(",%u udp", np->in_dpmin);
150 if ((np->in_flags & IPN_PURGE) != 0)
154 } else if (np->in_redir & NAT_REWRITE) {
156 if (np->in_nsrc.na_atype == FRI_LOOKUP &&
157 np->in_nsrc.na_type == IPLT_DSTLIST) {
159 if (np->in_nsrc.na_subtype == 0)
160 PRINTF("%d", np->in_nsrc.na_num);
162 PRINTF("%s", base + np->in_nsrc.na_num);
164 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
167 if ((((np->in_flags & IPN_TCPUDP) != 0)) &&
168 (np->in_spmin != 0)) {
169 if ((np->in_flags & IPN_FIXEDSPORT) != 0) {
170 PRINTF(",port = %u", np->in_spmin);
172 PRINTF(",%u", np->in_spmin);
173 if (np->in_spmax != np->in_spmin)
174 PRINTF("-%u", np->in_spmax);
178 if (np->in_ndst.na_atype == FRI_LOOKUP &&
179 np->in_ndst.na_type == IPLT_DSTLIST) {
181 if (np->in_ndst.na_subtype == 0)
182 PRINTF("%d", np->in_nsrc.na_num);
184 PRINTF("%s", base + np->in_ndst.na_num);
186 printnataddr(np->in_v[1], np->in_names, &np->in_ndst,
189 if ((((np->in_flags & IPN_TCPUDP) != 0)) &&
190 (np->in_dpmin != 0)) {
191 if ((np->in_flags & IPN_FIXEDDPORT) != 0) {
192 PRINTF(",port = %u", np->in_dpmin);
194 PRINTF(",%u", np->in_dpmin);
195 if (np->in_dpmax != np->in_dpmin)
196 PRINTF("-%u", np->in_dpmax);
199 if ((np->in_flags & IPN_PURGE) != 0)
203 } else if (np->in_redir == NAT_REDIRECT) {
204 if (!(np->in_flags & IPN_FILTER)) {
205 printnataddr(np->in_v[0], np->in_names, &np->in_odst,
207 if (np->in_flags & IPN_TCPUDP) {
208 PRINTF(" port %d", np->in_odport);
209 if (np->in_odport != np->in_dtop)
210 PRINTF("-%d", np->in_dtop);
213 if (np->in_flags & IPN_NO) {
215 printproto(pr, proto, np);
220 printnataddr(np->in_v[1], np->in_names, &np->in_ndst,
222 if (np->in_flags & IPN_TCPUDP) {
223 if ((np->in_flags & IPN_FIXEDDPORT) != 0)
224 PRINTF(" port = %d", np->in_dpmin);
226 PRINTF(" port %d", np->in_dpmin);
227 if (np->in_dpmin != np->in_dpmax)
228 PRINTF("-%d", np->in_dpmax);
232 printproto(pr, proto, np);
233 if (np->in_flags & IPN_ROUNDR)
234 PRINTF(" round-robin");
235 if (np->in_flags & IPN_FRAG)
237 if (np->in_age[0] != 0 || np->in_age[1] != 0) {
238 PRINTF(" age %d/%d", np->in_age[0], np->in_age[1]);
240 if (np->in_flags & IPN_STICKY)
242 if (np->in_mssclamp != 0)
243 PRINTF(" mssclamp %d", np->in_mssclamp);
244 if (np->in_plabel != -1)
245 PRINTF(" proxy %s", np->in_names + np->in_plabel);
246 if (np->in_tag.ipt_tag[0] != '\0')
247 PRINTF(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag);
248 if ((np->in_flags & IPN_PURGE) != 0)
251 if (opts & OPT_DEBUG)
252 PRINTF("\tpmax %u\n", np->in_dpmax);
255 int protoprinted = 0;
257 if (!(np->in_flags & IPN_FILTER)) {
258 printnataddr(np->in_v[0], np->in_names, &np->in_osrc,
261 if (np->in_flags & IPN_NO) {
263 printproto(pr, proto, np);
268 if (np->in_flags & IPN_SIPRANGE) {
270 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
273 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
276 if (np->in_plabel != -1) {
277 PRINTF(" proxy port ");
278 if (np->in_odport != 0) {
281 s = portname(proto, np->in_odport);
285 fputs("???", stdout);
287 PRINTF(" %s/", np->in_names + np->in_plabel);
288 printproto(pr, proto, NULL);
290 } else if (np->in_redir == NAT_MAPBLK) {
291 if ((np->in_spmin == 0) &&
292 (np->in_flags & IPN_AUTOPORTMAP))
293 PRINTF(" ports auto");
295 PRINTF(" ports %d", np->in_spmin);
296 if (opts & OPT_DEBUG)
297 PRINTF("\n\tip modulous %d", np->in_spmax);
299 } else if (np->in_spmin || np->in_spmax) {
300 if (np->in_flags & IPN_ICMPQUERY) {
301 PRINTF(" icmpidmap ");
305 printproto(pr, proto, np);
307 if (np->in_flags & IPN_AUTOPORTMAP) {
309 if (opts & OPT_DEBUG)
310 PRINTF(" [%d:%d %d %d]",
311 np->in_spmin, np->in_spmax,
312 np->in_ippip, np->in_ppip);
314 PRINTF(" %d:%d", np->in_spmin, np->in_spmax);
316 if (np->in_flags & IPN_SEQUENTIAL)
317 PRINTF(" sequential");
320 if (np->in_flags & IPN_FRAG)
322 if (np->in_age[0] != 0 || np->in_age[1] != 0) {
323 PRINTF(" age %d/%d", np->in_age[0], np->in_age[1]);
325 if (np->in_mssclamp != 0)
326 PRINTF(" mssclamp %d", np->in_mssclamp);
327 if (np->in_tag.ipt_tag[0] != '\0')
328 PRINTF(" tag %s", np->in_tag.ipt_tag);
329 if (!protoprinted && (np->in_flags & IPN_TCPUDP || proto)) {
331 printproto(pr, proto, np);
333 if ((np->in_flags & IPN_PURGE) != 0)
336 if (opts & OPT_DEBUG) {
338 printip(family, &np->in_snip);
339 PRINTF(" pnext %d\n", np->in_spnext);
343 if (opts & OPT_DEBUG) {
344 PRINTF("\tspace %lu use %u hits %lu flags %#x proto %d/%d",
345 np->in_space, np->in_use, np->in_hits,
346 np->in_flags, np->in_pr[0], np->in_pr[1]);
347 PRINTF(" hv %u/%u\n", np->in_hv[0], np->in_hv[1]);
348 PRINTF("\tifp[0] %p ifp[1] %p apr %p\n",
349 np->in_ifps[0], np->in_ifps[1], np->in_apr);
350 PRINTF("\ttqehead %p/%p comment %p\n",
351 np->in_tqehead[0], np->in_tqehead[1], np->in_comment);