]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ipfilter/lib/printnat.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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_type == IPLT_DSTLIST) {
157                         PRINTF("dstlist/");
158                         if (np->in_nsrc.na_subtype == 0)
159                                 PRINTF("%d", np->in_nsrc.na_num);
160                         else
161                                 PRINTF("%s", base + np->in_nsrc.na_num);
162                 } else {
163                         printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
164                                      np->in_ifnames[0]);
165                 }
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);
170                         } else {
171                                 PRINTF(",%u", np->in_spmin);
172                                 if (np->in_spmax != np->in_spmin)
173                                         PRINTF("-%u", np->in_spmax);
174                         }
175                 }
176                 PRINTF(" dst ");
177                 if (np->in_ndst.na_type == IPLT_DSTLIST) {
178                         PRINTF("dstlist/");
179                         if (np->in_ndst.na_subtype == 0)
180                                 PRINTF("%d", np->in_nsrc.na_num);
181                         else
182                                 PRINTF("%s", base + np->in_ndst.na_num);
183                 } else {
184                         printnataddr(np->in_v[1], np->in_names, &np->in_ndst,
185                                      np->in_ifnames[0]);
186                 }
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);
191                         } else {
192                                 PRINTF(",%u", np->in_dpmin);
193                                 if (np->in_dpmax != np->in_dpmin)
194                                         PRINTF("-%u", np->in_dpmax);
195                         }
196                 }
197                 if ((np->in_flags & IPN_PURGE) != 0)
198                         PRINTF(" purge");
199                 PRINTF(";\n");
200
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,
204                                      np->in_ifnames[0]);
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);
209                         }
210                 }
211                 if (np->in_flags & IPN_NO) {
212                         putchar(' ');
213                         printproto(pr, proto, np);
214                         PRINTF(";\n");
215                         return;
216                 }
217                 PRINTF(" -> ");
218                 printnataddr(np->in_v[1], np->in_names, &np->in_ndst,
219                              np->in_ifnames[0]);
220                 if (np->in_flags & IPN_TCPUDP) {
221                         if ((np->in_flags & IPN_FIXEDDPORT) != 0)
222                                 PRINTF(" port = %d", np->in_dpmin);
223                         else {
224                                 PRINTF(" port %d", np->in_dpmin);
225                                 if (np->in_dpmin != np->in_dpmax)
226                                         PRINTF("-%d", np->in_dpmax);
227                         }
228                 }
229                 putchar(' ');
230                 printproto(pr, proto, np);
231                 if (np->in_flags & IPN_ROUNDR)
232                         PRINTF(" round-robin");
233                 if (np->in_flags & IPN_FRAG)
234                         PRINTF(" 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]);
237                 }
238                 if (np->in_flags & IPN_STICKY)
239                         PRINTF(" 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)
247                         PRINTF(" purge");
248                 PRINTF("\n");
249                 if (opts & OPT_DEBUG)
250                         PRINTF("\tpmax %u\n", np->in_dpmax);
251
252         } else {
253                 int protoprinted = 0;
254
255                 if (!(np->in_flags & IPN_FILTER)) {
256                         printnataddr(np->in_v[0], np->in_names, &np->in_osrc,
257                                      np->in_ifnames[0]);
258                 }
259                 if (np->in_flags & IPN_NO) {
260                         putchar(' ');
261                         printproto(pr, proto, np);
262                         PRINTF(";\n");
263                         return;
264                 }
265                 PRINTF(" -> ");
266                 if (np->in_flags & IPN_SIPRANGE) {
267                         PRINTF("range ");
268                         printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
269                                      np->in_ifnames[0]);
270                 } else {
271                         printnataddr(np->in_v[1], np->in_names, &np->in_nsrc,
272                                      np->in_ifnames[0]);
273                 }
274                 if (np->in_plabel != -1) {
275                         PRINTF(" proxy port ");
276                         if (np->in_odport != 0) {
277                                 char *s;
278
279                                 s = portname(proto, np->in_odport);
280                                 if (s != NULL)
281                                         fputs(s, stdout);
282                                 else
283                                         fputs("???", stdout);
284                         }
285                         PRINTF(" %s/", np->in_names + np->in_plabel);
286                         printproto(pr, proto, NULL);
287                         protoprinted = 1;
288                 } else if (np->in_redir == NAT_MAPBLK) {
289                         if ((np->in_spmin == 0) &&
290                             (np->in_flags & IPN_AUTOPORTMAP))
291                                 PRINTF(" ports auto");
292                         else
293                                 PRINTF(" ports %d", np->in_spmin);
294                         if (opts & OPT_DEBUG)
295                                 PRINTF("\n\tip modulous %d", np->in_spmax);
296
297                 } else if (np->in_spmin || np->in_spmax) {
298                         if (np->in_flags & IPN_ICMPQUERY) {
299                                 PRINTF(" icmpidmap ");
300                         } else {
301                                 PRINTF(" portmap ");
302                         }
303                         printproto(pr, proto, np);
304                         protoprinted = 1;
305                         if (np->in_flags & IPN_AUTOPORTMAP) {
306                                 PRINTF(" auto");
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);
311                         } else {
312                                 PRINTF(" %d:%d", np->in_spmin, np->in_spmax);
313                         }
314                         if (np->in_flags & IPN_SEQUENTIAL)
315                                 PRINTF(" sequential");
316                 }
317
318                 if (np->in_flags & IPN_FRAG)
319                         PRINTF(" 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]);
322                 }
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)) {
328                         putchar(' ');
329                         printproto(pr, proto, np);
330                 }
331                 if ((np->in_flags & IPN_PURGE) != 0)
332                         PRINTF(" purge");
333                 PRINTF("\n");
334                 if (opts & OPT_DEBUG) {
335                         PRINTF("\tnextip ");
336                         printip(family, &np->in_snip);
337                         PRINTF(" pnext %d\n", np->in_spnext);
338                 }
339         }
340
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);
350         }
351 }