1 /* $NetBSD: printnat.c,v 1.1.1.1 2012/03/23 21:20:10 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2009 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 proto; 31 32 if (np->in_flags & IPN_NO) 33 PRINTF("no "); 34 35 switch (np->in_redir) 36 { 37 case NAT_REDIRECT|NAT_ENCAP : 38 PRINTF("encap in on"); 39 proto = np->in_pr[0]; 40 break; 41 case NAT_MAP|NAT_ENCAP : 42 PRINTF("encap out on"); 43 proto = np->in_pr[1]; 44 break; 45 case NAT_REDIRECT|NAT_DIVERTUDP : 46 PRINTF("divert in on"); 47 proto = np->in_pr[0]; 48 break; 49 case NAT_MAP|NAT_DIVERTUDP : 50 PRINTF("divert out on"); 51 proto = np->in_pr[1]; 52 break; 53 case NAT_REDIRECT|NAT_REWRITE : 54 PRINTF("rewrite in on"); 55 proto = np->in_pr[0]; 56 break; 57 case NAT_MAP|NAT_REWRITE : 58 PRINTF("rewrite out on"); 59 proto = np->in_pr[1]; 60 break; 61 case NAT_REDIRECT : 62 PRINTF("rdr"); 63 proto = np->in_pr[0]; 64 break; 65 case NAT_MAP : 66 PRINTF("map"); 67 proto = np->in_pr[1]; 68 break; 69 case NAT_MAPBLK : 70 PRINTF("map-block"); 71 proto = np->in_pr[1]; 72 break; 73 case NAT_BIMAP : 74 PRINTF("bimap"); 75 proto = np->in_pr[0]; 76 break; 77 default : 78 FPRINTF(stderr, "unknown value for in_redir: %#x\n", 79 np->in_redir); 80 proto = np->in_pr[0]; 81 break; 82 } 83 84 pr = getprotobynumber(proto); 85 86 base = np->in_names; 87 if (!strcmp(base + np->in_ifnames[0], "-")) 88 PRINTF(" \"%s\"", base + np->in_ifnames[0]); 89 else 90 PRINTF(" %s", base + np->in_ifnames[0]); 91 if ((np->in_ifnames[1] != -1) && 92 (strcmp(base + np->in_ifnames[0], base + np->in_ifnames[1]) != 0)) { 93 if (!strcmp(base + np->in_ifnames[1], "-")) 94 PRINTF(",\"%s\"", base + np->in_ifnames[1]); 95 else 96 PRINTF(",%s", base + np->in_ifnames[1]); 97 } 98 putchar(' '); 99 100 if (np->in_redir & (NAT_REWRITE|NAT_ENCAP|NAT_DIVERTUDP)) { 101 if ((proto != 0) || (np->in_flags & IPN_TCPUDP)) { 102 PRINTF("proto "); 103 printproto(pr, proto, np); 104 putchar(' '); 105 } 106 } 107 108 if (np->in_flags & IPN_FILTER) { 109 if (np->in_flags & IPN_NOTSRC) 110 PRINTF("! "); 111 PRINTF("from "); 112 printnataddr(np->in_v[0], np->in_names, &np->in_osrc, 113 np->in_ifnames[0]); 114 if (np->in_scmp) 115 printportcmp(proto, &np->in_tuc.ftu_src); 116 117 if (np->in_flags & IPN_NOTDST) 118 PRINTF(" !"); 119 PRINTF(" to "); 120 printnataddr(np->in_v[0], np->in_names, &np->in_odst, 121 np->in_ifnames[0]); 122 if (np->in_dcmp) 123 printportcmp(proto, &np->in_tuc.ftu_dst); 124 } 125 126 if (np->in_redir & (NAT_ENCAP|NAT_DIVERTUDP)) { 127 PRINTF(" -> src "); 128 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, 129 np->in_ifnames[0]); 130 if ((np->in_redir & NAT_DIVERTUDP) != 0) 131 PRINTF(",%u", np->in_spmin); 132 PRINTF(" dst "); 133 printnataddr(np->in_v[1], np->in_names, &np->in_ndst, 134 np->in_ifnames[0]); 135 if ((np->in_redir & NAT_DIVERTUDP) != 0) 136 PRINTF(",%u udp", np->in_dpmin); 137 PRINTF(";\n"); 138 139 } else if (np->in_redir & NAT_REWRITE) { 140 PRINTF(" -> src "); 141 if (np->in_nsrc.na_type == IPLT_DSTLIST) { 142 PRINTF("dstlist/"); 143 if (np->in_nsrc.na_subtype == 0) 144 PRINTF("%d", np->in_nsrc.na_num); 145 else 146 PRINTF("%s", base + np->in_nsrc.na_num); 147 } else { 148 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, 149 np->in_ifnames[0]); 150 } 151 if ((((np->in_flags & IPN_TCPUDP) != 0)) && 152 (np->in_spmin != 0)) { 153 if ((np->in_flags & IPN_FIXEDSPORT) != 0) { 154 PRINTF(",port = %u", np->in_spmin); 155 } else { 156 PRINTF(",%u", np->in_spmin); 157 if (np->in_spmax != np->in_spmin) 158 PRINTF("-%u", np->in_spmax); 159 } 160 } 161 PRINTF(" dst "); 162 if (np->in_ndst.na_type == IPLT_DSTLIST) { 163 PRINTF("dstlist/"); 164 if (np->in_ndst.na_subtype == 0) 165 PRINTF("%d", np->in_nsrc.na_num); 166 else 167 PRINTF("%s", base + np->in_ndst.na_num); 168 } else { 169 printnataddr(np->in_v[1], np->in_names, &np->in_ndst, 170 np->in_ifnames[0]); 171 } 172 if ((((np->in_flags & IPN_TCPUDP) != 0)) && 173 (np->in_dpmin != 0)) { 174 if ((np->in_flags & IPN_FIXEDDPORT) != 0) { 175 PRINTF(",port = %u", np->in_dpmin); 176 } else { 177 PRINTF(",%u", np->in_dpmin); 178 if (np->in_dpmax != np->in_dpmin) 179 PRINTF("-%u", np->in_dpmax); 180 } 181 } 182 PRINTF(";\n"); 183 184 } else if (np->in_redir == NAT_REDIRECT) { 185 if (!(np->in_flags & IPN_FILTER)) { 186 printnataddr(np->in_v[0], np->in_names, &np->in_odst, 187 np->in_ifnames[0]); 188 if (np->in_flags & IPN_TCPUDP) { 189 PRINTF(" port %d", np->in_odport); 190 if (np->in_odport != np->in_dtop) 191 PRINTF("-%d", np->in_dtop); 192 } 193 } 194 if (np->in_flags & IPN_NO) { 195 putchar(' '); 196 printproto(pr, proto, np); 197 PRINTF(";\n"); 198 return; 199 } 200 PRINTF(" -> "); 201 printnataddr(np->in_v[1], np->in_names, &np->in_ndst, 202 np->in_ifnames[0]); 203 if (np->in_flags & IPN_TCPUDP) { 204 if ((np->in_flags & IPN_FIXEDDPORT) != 0) 205 PRINTF(" port = %d", np->in_dpmin); 206 else { 207 PRINTF(" port %d", np->in_dpmin); 208 if (np->in_dpmin != np->in_dpmax) 209 PRINTF("-%d", np->in_dpmax); 210 } 211 } 212 putchar(' '); 213 printproto(pr, proto, np); 214 if (np->in_flags & IPN_ROUNDR) 215 PRINTF(" round-robin"); 216 if (np->in_flags & IPN_FRAG) 217 PRINTF(" frag"); 218 if (np->in_age[0] != 0 || np->in_age[1] != 0) { 219 PRINTF(" age %d/%d", np->in_age[0], np->in_age[1]); 220 } 221 if (np->in_flags & IPN_STICKY) 222 PRINTF(" sticky"); 223 if (np->in_mssclamp != 0) 224 PRINTF(" mssclamp %d", np->in_mssclamp); 225 if (np->in_plabel != -1) 226 PRINTF(" proxy %s", np->in_names + np->in_plabel); 227 if (np->in_tag.ipt_tag[0] != '\0') 228 PRINTF(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag); 229 PRINTF("\n"); 230 if (opts & OPT_DEBUG) 231 PRINTF("\tpmax %u\n", np->in_dpmax); 232 233 } else { 234 int protoprinted = 0; 235 236 if (!(np->in_flags & IPN_FILTER)) { 237 printnataddr(np->in_v[0], np->in_names, &np->in_osrc, 238 np->in_ifnames[0]); 239 } 240 if (np->in_flags & IPN_NO) { 241 putchar(' '); 242 printproto(pr, proto, np); 243 PRINTF(";\n"); 244 return; 245 } 246 PRINTF(" -> "); 247 if (np->in_flags & IPN_SIPRANGE) { 248 PRINTF("range "); 249 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, 250 np->in_ifnames[0]); 251 } else { 252 printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, 253 np->in_ifnames[0]); 254 } 255 if (np->in_plabel != -1) { 256 PRINTF(" proxy port "); 257 if (np->in_odport != 0) { 258 char *s; 259 260 s = portname(proto, np->in_odport); 261 if (s != NULL) 262 fputs(s, stdout); 263 else 264 fputs("???", stdout); 265 } 266 PRINTF(" %s/", np->in_names + np->in_plabel); 267 printproto(pr, proto, NULL); 268 protoprinted = 1; 269 } else if (np->in_redir == NAT_MAPBLK) { 270 if ((np->in_spmin == 0) && 271 (np->in_flags & IPN_AUTOPORTMAP)) 272 PRINTF(" ports auto"); 273 else 274 PRINTF(" ports %d", np->in_spmin); 275 if (opts & OPT_DEBUG) 276 PRINTF("\n\tip modulous %d", np->in_spmax); 277 278 } else if (np->in_spmin || np->in_spmax) { 279 if (np->in_flags & IPN_ICMPQUERY) { 280 PRINTF(" icmpidmap "); 281 } else { 282 PRINTF(" portmap "); 283 } 284 printproto(pr, proto, np); 285 protoprinted = 1; 286 if (np->in_flags & IPN_AUTOPORTMAP) { 287 PRINTF(" auto"); 288 if (opts & OPT_DEBUG) 289 PRINTF(" [%d:%d %d %d]", 290 np->in_spmin, np->in_spmax, 291 np->in_ippip, np->in_ppip); 292 } else { 293 PRINTF(" %d:%d", np->in_spmin, np->in_spmax); 294 } 295 } 296 297 if (np->in_flags & IPN_FRAG) 298 PRINTF(" frag"); 299 if (np->in_age[0] != 0 || np->in_age[1] != 0) { 300 PRINTF(" age %d/%d", np->in_age[0], np->in_age[1]); 301 } 302 if (np->in_mssclamp != 0) 303 PRINTF(" mssclamp %d", np->in_mssclamp); 304 if (np->in_tag.ipt_tag[0] != '\0') 305 PRINTF(" tag %s", np->in_tag.ipt_tag); 306 if (!protoprinted && (np->in_flags & IPN_TCPUDP || proto)) { 307 putchar(' '); 308 printproto(pr, proto, np); 309 } 310 PRINTF("\n"); 311 if (opts & OPT_DEBUG) { 312 struct in_addr nip; 313 314 nip.s_addr = htonl(np->in_snip); 315 316 PRINTF("\tnextip %s pnext %d\n", 317 inet_ntoa(nip), np->in_spnext); 318 } 319 } 320 321 if (opts & OPT_DEBUG) { 322 PRINTF("\tspace %lu use %u hits %lu flags %#x proto %d/%d", 323 np->in_space, np->in_use, np->in_hits, 324 np->in_flags, np->in_pr[0], np->in_pr[1]); 325 PRINTF(" hv %u/%u\n", np->in_hv[0], np->in_hv[1]); 326 PRINTF("\tifp[0] %p ifp[1] %p apr %p\n", 327 np->in_ifps[0], np->in_ifps[1], np->in_apr); 328 PRINTF("\ttqehead %p/%p comment %p\n", 329 np->in_tqehead[0], np->in_tqehead[1], np->in_comment); 330 } 331 } 332