printnat.c revision 256281
1/* $FreeBSD: stable/10/contrib/ipfilter/lib/printnat.c 255332 2013-09-06 23:11:19Z cy $ */ 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) 16static const char rcsid[] = "@(#)$Id$"; 17#endif 18 19 20/* 21 * Print out a NAT rule 22 */ 23void 24printnat(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} 352