]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/ipfilter/lib/printnat.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / ipfilter / lib / printnat.c
1 /*      $FreeBSD$       */
2
3 /*
4  * Copyright (C) 2012 by Darren Reed.
5  *
6  * See the IPFILTER.LICENCE file for details on licencing.
7  *
8  * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
9  */
10
11 #include "ipf.h"
12 #include "kmem.h"
13
14
15 #if !defined(lint)
16 static const char rcsid[] = "@(#)$Id$";
17 #endif
18
19
20 /*
21  * Print out a NAT rule
22  */
23 void
24 printnat(np, opts)
25         ipnat_t *np;
26         int opts;
27 {
28         struct protoent *pr;
29         char *base;
30         int family;
31         int proto;
32
33         if (np->in_v[0] == 4)
34                 family = AF_INET;
35 #ifdef USE_INET6
36         else if (np->in_v[0] == 6)
37                 family = AF_INET6;
38 #endif
39         else
40                 family = AF_UNSPEC;
41
42         if (np->in_flags & IPN_NO)
43                 PRINTF("no ");
44
45         switch (np->in_redir)
46         {
47         case NAT_REDIRECT|NAT_ENCAP :
48                 PRINTF("encap in on");
49                 proto = np->in_pr[0];
50                 break;
51         case NAT_MAP|NAT_ENCAP :
52                 PRINTF("encap out on");
53                 proto = np->in_pr[1];
54                 break;
55         case NAT_REDIRECT|NAT_DIVERTUDP :
56                 PRINTF("divert in on");
57                 proto = np->in_pr[0];
58                 break;
59         case NAT_MAP|NAT_DIVERTUDP :
60                 PRINTF("divert out on");
61                 proto = np->in_pr[1];
62                 break;
63         case NAT_REDIRECT|NAT_REWRITE :
64                 PRINTF("rewrite in on");
65                 proto = np->in_pr[0];
66                 break;
67         case NAT_MAP|NAT_REWRITE :
68                 PRINTF("rewrite out on");
69                 proto = np->in_pr[1];
70                 break;
71         case NAT_REDIRECT :
72                 PRINTF("rdr");
73                 proto = np->in_pr[0];
74                 break;
75         case NAT_MAP :
76                 PRINTF("map");
77                 proto = np->in_pr[1];
78                 break;
79         case NAT_MAPBLK :
80                 PRINTF("map-block");
81                 proto = np->in_pr[1];
82                 break;
83         case NAT_BIMAP :
84                 PRINTF("bimap");
85                 proto = np->in_pr[0];
86                 break;
87         default :
88                 FPRINTF(stderr, "unknown value for in_redir: %#x\n",
89                         np->in_redir);
90                 proto = np->in_pr[0];
91                 break;
92         }
93
94         pr = getprotobynumber(proto);
95
96         base = np->in_names;
97         if (!strcmp(base + np->in_ifnames[0], "-"))
98                 PRINTF(" \"%s\"", base + np->in_ifnames[0]);
99         else
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]);
105                 else
106                         PRINTF(",%s", base + np->in_ifnames[1]);
107         }
108         putchar(' ');
109
110         if (family == AF_INET6)
111                 PRINTF("inet6 ");
112
113         if (np->in_redir & (NAT_REWRITE|NAT_ENCAP|NAT_DIVERTUDP)) {
114                 if ((proto != 0) || (np->in_flags & IPN_TCPUDP)) {
115                         PRINTF("proto ");
116                         printproto(pr, proto, np);
117                         putchar(' ');
118                 }
119         }
120
121         if (np->in_flags & IPN_FILTER) {
122                 if (np->in_flags & IPN_NOTSRC)
123                         PRINTF("! ");
124                 PRINTF("from ");
125                 printnataddr(np->in_v[0], np->in_names, &np->in_osrc,
126                              np->in_ifnames[0]);
127                 if (np->in_scmp)
128                         printportcmp(proto, &np->in_tuc.ftu_src);
129
130                 if (np->in_flags & IPN_NOTDST)
131                         PRINTF(" !");
132                 PRINTF(" to ");
133                 printnataddr(np->in_v[0], np->in_names, &np->in_odst,
134                              np->in_ifnames[0]);
135                 if (np->in_dcmp)
136                         printportcmp(proto, &np->in_tuc.ftu_dst);
137         }
138
139         if (np->in_redir & (NAT_ENCAP|NAT_DIVERTUDP)) {
140                 PRINTF(" -> src ");
141                 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
142                              np->in_ifnames[0]);
143                 if ((np->in_redir & NAT_DIVERTUDP) != 0)
144                         PRINTF(",%u", np->in_spmin);
145                 PRINTF(" dst ");
146                 printnataddr(np->in_v[1], np->in_names, &np->in_ndst,
147                              np->in_ifnames[0]);
148                 if ((np->in_redir & NAT_DIVERTUDP) != 0)
149                         PRINTF(",%u udp", np->in_dpmin);
150                 if ((np->in_flags & IPN_PURGE) != 0)
151                         PRINTF(" purge");
152                 PRINTF(";\n");
153
154         } else if (np->in_redir & NAT_REWRITE) {
155                 PRINTF(" -> src ");
156                 if (np->in_nsrc.na_atype == FRI_LOOKUP &&
157                     np->in_nsrc.na_type == IPLT_DSTLIST) {
158                         PRINTF("dstlist/");
159                         if (np->in_nsrc.na_subtype == 0)
160                                 PRINTF("%d", np->in_nsrc.na_num);
161                         else
162                                 PRINTF("%s", base + np->in_nsrc.na_num);
163                 } else {
164                         printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
165                                      np->in_ifnames[0]);
166                 }
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);
171                         } else {
172                                 PRINTF(",%u", np->in_spmin);
173                                 if (np->in_spmax != np->in_spmin)
174                                         PRINTF("-%u", np->in_spmax);
175                         }
176                 }
177                 PRINTF(" dst ");
178                 if (np->in_ndst.na_atype == FRI_LOOKUP &&
179                     np->in_ndst.na_type == IPLT_DSTLIST) {
180                         PRINTF("dstlist/");
181                         if (np->in_ndst.na_subtype == 0)
182                                 PRINTF("%d", np->in_nsrc.na_num);
183                         else
184                                 PRINTF("%s", base + np->in_ndst.na_num);
185                 } else {
186                         printnataddr(np->in_v[1], np->in_names, &np->in_ndst,
187                                      np->in_ifnames[0]);
188                 }
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);
193                         } else {
194                                 PRINTF(",%u", np->in_dpmin);
195                                 if (np->in_dpmax != np->in_dpmin)
196                                         PRINTF("-%u", np->in_dpmax);
197                         }
198                 }
199                 if ((np->in_flags & IPN_PURGE) != 0)
200                         PRINTF(" purge");
201                 PRINTF(";\n");
202
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,
206                                      np->in_ifnames[0]);
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);
211                         }
212                 }
213                 if (np->in_flags & IPN_NO) {
214                         putchar(' ');
215                         printproto(pr, proto, np);
216                         PRINTF(";\n");
217                         return;
218                 }
219                 PRINTF(" -> ");
220                 printnataddr(np->in_v[1], np->in_names, &np->in_ndst,
221                              np->in_ifnames[0]);
222                 if (np->in_flags & IPN_TCPUDP) {
223                         if ((np->in_flags & IPN_FIXEDDPORT) != 0)
224                                 PRINTF(" port = %d", np->in_dpmin);
225                         else {
226                                 PRINTF(" port %d", np->in_dpmin);
227                                 if (np->in_dpmin != np->in_dpmax)
228                                         PRINTF("-%d", np->in_dpmax);
229                         }
230                 }
231                 putchar(' ');
232                 printproto(pr, proto, np);
233                 if (np->in_flags & IPN_ROUNDR)
234                         PRINTF(" round-robin");
235                 if (np->in_flags & IPN_FRAG)
236                         PRINTF(" 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]);
239                 }
240                 if (np->in_flags & IPN_STICKY)
241                         PRINTF(" 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)
249                         PRINTF(" purge");
250                 PRINTF("\n");
251                 if (opts & OPT_DEBUG)
252                         PRINTF("\tpmax %u\n", np->in_dpmax);
253
254         } else {
255                 int protoprinted = 0;
256
257                 if (!(np->in_flags & IPN_FILTER)) {
258                         printnataddr(np->in_v[0], np->in_names, &np->in_osrc,
259                                      np->in_ifnames[0]);
260                 }
261                 if (np->in_flags & IPN_NO) {
262                         putchar(' ');
263                         printproto(pr, proto, np);
264                         PRINTF(";\n");
265                         return;
266                 }
267                 PRINTF(" -> ");
268                 if (np->in_flags & IPN_SIPRANGE) {
269                         PRINTF("range ");
270                         printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
271                                      np->in_ifnames[0]);
272                 } else {
273                         printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
274                                      np->in_ifnames[0]);
275                 }
276                 if (np->in_plabel != -1) {
277                         PRINTF(" proxy port ");
278                         if (np->in_odport != 0) {
279                                 char *s;
280
281                                 s = portname(proto, np->in_odport);
282                                 if (s != NULL)
283                                         fputs(s, stdout);
284                                 else
285                                         fputs("???", stdout);
286                         }
287                         PRINTF(" %s/", np->in_names + np->in_plabel);
288                         printproto(pr, proto, NULL);
289                         protoprinted = 1;
290                 } else if (np->in_redir == NAT_MAPBLK) {
291                         if ((np->in_spmin == 0) &&
292                             (np->in_flags & IPN_AUTOPORTMAP))
293                                 PRINTF(" ports auto");
294                         else
295                                 PRINTF(" ports %d", np->in_spmin);
296                         if (opts & OPT_DEBUG)
297                                 PRINTF("\n\tip modulous %d", np->in_spmax);
298
299                 } else if (np->in_spmin || np->in_spmax) {
300                         if (np->in_flags & IPN_ICMPQUERY) {
301                                 PRINTF(" icmpidmap ");
302                         } else {
303                                 PRINTF(" portmap ");
304                         }
305                         printproto(pr, proto, np);
306                         protoprinted = 1;
307                         if (np->in_flags & IPN_AUTOPORTMAP) {
308                                 PRINTF(" auto");
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);
313                         } else {
314                                 PRINTF(" %d:%d", np->in_spmin, np->in_spmax);
315                         }
316                         if (np->in_flags & IPN_SEQUENTIAL)
317                                 PRINTF(" sequential");
318                 }
319
320                 if (np->in_flags & IPN_FRAG)
321                         PRINTF(" 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]);
324                 }
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)) {
330                         putchar(' ');
331                         printproto(pr, proto, np);
332                 }
333                 if ((np->in_flags & IPN_PURGE) != 0)
334                         PRINTF(" purge");
335                 PRINTF("\n");
336                 if (opts & OPT_DEBUG) {
337                         PRINTF("\tnextip ");
338                         printip(family, &np->in_snip);
339                         PRINTF(" pnext %d\n", np->in_spnext);
340                 }
341         }
342
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);
352         }
353 }