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_type == IPLT_DSTLIST) {
158 if (np->in_nsrc.na_subtype == 0)
159 PRINTF("%d", np->in_nsrc.na_num);
161 PRINTF("%s", base + np->in_nsrc.na_num);
163 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
166 if ((((np->in_flags & IPN_TCPUDP) != 0)) &&
167 (np->in_spmin != 0)) {
168 if ((np->in_flags & IPN_FIXEDSPORT) != 0) {
169 PRINTF(",port = %u", np->in_spmin);
171 PRINTF(",%u", np->in_spmin);
172 if (np->in_spmax != np->in_spmin)
173 PRINTF("-%u", np->in_spmax);
177 if (np->in_ndst.na_type == IPLT_DSTLIST) {
179 if (np->in_ndst.na_subtype == 0)
180 PRINTF("%d", np->in_nsrc.na_num);
182 PRINTF("%s", base + np->in_ndst.na_num);
184 printnataddr(np->in_v[1], np->in_names, &np->in_ndst,
187 if ((((np->in_flags & IPN_TCPUDP) != 0)) &&
188 (np->in_dpmin != 0)) {
189 if ((np->in_flags & IPN_FIXEDDPORT) != 0) {
190 PRINTF(",port = %u", np->in_dpmin);
192 PRINTF(",%u", np->in_dpmin);
193 if (np->in_dpmax != np->in_dpmin)
194 PRINTF("-%u", np->in_dpmax);
197 if ((np->in_flags & IPN_PURGE) != 0)
201 } else if (np->in_redir == NAT_REDIRECT) {
202 if (!(np->in_flags & IPN_FILTER)) {
203 printnataddr(np->in_v[0], np->in_names, &np->in_odst,
205 if (np->in_flags & IPN_TCPUDP) {
206 PRINTF(" port %d", np->in_odport);
207 if (np->in_odport != np->in_dtop)
208 PRINTF("-%d", np->in_dtop);
211 if (np->in_flags & IPN_NO) {
213 printproto(pr, proto, np);
218 printnataddr(np->in_v[1], np->in_names, &np->in_ndst,
220 if (np->in_flags & IPN_TCPUDP) {
221 if ((np->in_flags & IPN_FIXEDDPORT) != 0)
222 PRINTF(" port = %d", np->in_dpmin);
224 PRINTF(" port %d", np->in_dpmin);
225 if (np->in_dpmin != np->in_dpmax)
226 PRINTF("-%d", np->in_dpmax);
230 printproto(pr, proto, np);
231 if (np->in_flags & IPN_ROUNDR)
232 PRINTF(" round-robin");
233 if (np->in_flags & IPN_FRAG)
235 if (np->in_age[0] != 0 || np->in_age[1] != 0) {
236 PRINTF(" age %d/%d", np->in_age[0], np->in_age[1]);
238 if (np->in_flags & IPN_STICKY)
240 if (np->in_mssclamp != 0)
241 PRINTF(" mssclamp %d", np->in_mssclamp);
242 if (np->in_plabel != -1)
243 PRINTF(" proxy %s", np->in_names + np->in_plabel);
244 if (np->in_tag.ipt_tag[0] != '\0')
245 PRINTF(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag);
246 if ((np->in_flags & IPN_PURGE) != 0)
249 if (opts & OPT_DEBUG)
250 PRINTF("\tpmax %u\n", np->in_dpmax);
253 int protoprinted = 0;
255 if (!(np->in_flags & IPN_FILTER)) {
256 printnataddr(np->in_v[0], np->in_names, &np->in_osrc,
259 if (np->in_flags & IPN_NO) {
261 printproto(pr, proto, np);
266 if (np->in_flags & IPN_SIPRANGE) {
268 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
271 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
274 if (np->in_plabel != -1) {
275 PRINTF(" proxy port ");
276 if (np->in_odport != 0) {
279 s = portname(proto, np->in_odport);
283 fputs("???", stdout);
285 PRINTF(" %s/", np->in_names + np->in_plabel);
286 printproto(pr, proto, NULL);
288 } else if (np->in_redir == NAT_MAPBLK) {
289 if ((np->in_spmin == 0) &&
290 (np->in_flags & IPN_AUTOPORTMAP))
291 PRINTF(" ports auto");
293 PRINTF(" ports %d", np->in_spmin);
294 if (opts & OPT_DEBUG)
295 PRINTF("\n\tip modulous %d", np->in_spmax);
297 } else if (np->in_spmin || np->in_spmax) {
298 if (np->in_flags & IPN_ICMPQUERY) {
299 PRINTF(" icmpidmap ");
303 printproto(pr, proto, np);
305 if (np->in_flags & IPN_AUTOPORTMAP) {
307 if (opts & OPT_DEBUG)
308 PRINTF(" [%d:%d %d %d]",
309 np->in_spmin, np->in_spmax,
310 np->in_ippip, np->in_ppip);
312 PRINTF(" %d:%d", np->in_spmin, np->in_spmax);
314 if (np->in_flags & IPN_SEQUENTIAL)
315 PRINTF(" sequential");
318 if (np->in_flags & IPN_FRAG)
320 if (np->in_age[0] != 0 || np->in_age[1] != 0) {
321 PRINTF(" age %d/%d", np->in_age[0], np->in_age[1]);
323 if (np->in_mssclamp != 0)
324 PRINTF(" mssclamp %d", np->in_mssclamp);
325 if (np->in_tag.ipt_tag[0] != '\0')
326 PRINTF(" tag %s", np->in_tag.ipt_tag);
327 if (!protoprinted && (np->in_flags & IPN_TCPUDP || proto)) {
329 printproto(pr, proto, np);
331 if ((np->in_flags & IPN_PURGE) != 0)
334 if (opts & OPT_DEBUG) {
336 printip(family, &np->in_snip);
337 PRINTF(" pnext %d\n", np->in_spnext);
341 if (opts & OPT_DEBUG) {
342 PRINTF("\tspace %lu use %u hits %lu flags %#x proto %d/%d",
343 np->in_space, np->in_use, np->in_hits,
344 np->in_flags, np->in_pr[0], np->in_pr[1]);
345 PRINTF(" hv %u/%u\n", np->in_hv[0], np->in_hv[1]);
346 PRINTF("\tifp[0] %p ifp[1] %p apr %p\n",
347 np->in_ifps[0], np->in_ifps[1], np->in_apr);
348 PRINTF("\ttqehead %p/%p comment %p\n",
349 np->in_tqehead[0], np->in_tqehead[1], np->in_comment);