1 /* 2 * Copyright (C) 2002-2005 by Darren Reed. 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 * 6 * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) 7 * 8 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 9 * Use is subject to license terms. 10 */ 11 12 #include "ipf.h" 13 #include "kmem.h" 14 15 16 #if !defined(lint) 17 static const char rcsid[] = "@(#)$Id: printnat.c,v 1.22.2.9 2005/06/12 07:18:43 darrenr Exp $"; 18 #endif 19 20 /* 21 * Print out a NAT rule 22 */ 23 void printnat(np, opts) 24 ipnat_t *np; 25 int opts; 26 { 27 struct protoent *pr; 28 int bits, af; 29 char ipbuf[INET6_ADDRSTRLEN]; 30 void *ptr; 31 32 pr = getprotobynumber(np->in_p); 33 34 switch (np->in_redir) 35 { 36 case NAT_REDIRECT : 37 printf("rdr"); 38 break; 39 case NAT_MAP : 40 printf("map"); 41 break; 42 case NAT_MAPBLK : 43 printf("map-block"); 44 break; 45 case NAT_BIMAP : 46 printf("bimap"); 47 break; 48 default : 49 fprintf(stderr, "unknown value for in_redir: %#x\n", 50 np->in_redir); 51 break; 52 } 53 54 printf(" %s", np->in_ifnames[0]); 55 if ((np->in_ifnames[1][0] != '\0') && 56 (strncmp(np->in_ifnames[0], np->in_ifnames[1], LIFNAMSIZ) != 0)) { 57 printf(",%s ", np->in_ifnames[1]); 58 } 59 putchar(' '); 60 61 if (np->in_flags & IPN_FILTER) { 62 if (np->in_flags & IPN_NOTSRC) 63 printf("! "); 64 printf("from "); 65 if (np->in_redir == NAT_REDIRECT) { 66 printhostmask(np->in_v, (u_32_t *)&np->in_src[0], 67 (u_32_t *)&np->in_src[1]); 68 } else { 69 printhostmask(np->in_v, (u_32_t *)&np->in_in[0], 70 (u_32_t *)&np->in_in[1]); 71 } 72 if (np->in_scmp) 73 printportcmp(np->in_p, &np->in_tuc.ftu_src); 74 75 if (np->in_flags & IPN_NOTDST) 76 printf(" !"); 77 printf(" to "); 78 if (np->in_redir == NAT_REDIRECT) { 79 printhostmask(np->in_v, (u_32_t *)&np->in_out[0], 80 (u_32_t *)&np->in_out[1]); 81 } else { 82 printhostmask(np->in_v, (u_32_t *)&np->in_src[0], 83 (u_32_t *)&np->in_src[1]); 84 } 85 if (np->in_dcmp) 86 printportcmp(np->in_p, &np->in_tuc.ftu_dst); 87 } 88 89 if (np->in_v == 4) 90 af = AF_INET; 91 else if (np->in_v == 6) 92 af = AF_INET6; 93 else 94 af = 0; 95 96 if (np->in_redir == NAT_REDIRECT) { 97 if (!(np->in_flags & IPN_FILTER)) { 98 ptr = (void *)(u_32_t *)&np->in_out[0]; 99 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 100 printmask(np->in_v, (u_32_t *)&np->in_out[1]); 101 if (np->in_flags & IPN_TCPUDP) { 102 printf(" port %d", ntohs(np->in_pmin)); 103 if (np->in_pmax != np->in_pmin) 104 printf("-%d", ntohs(np->in_pmax)); 105 } 106 } 107 printf(" -> "); 108 ptr = (void *)(u_32_t *)&np->in_in[0]; 109 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 110 if (np->in_flags & IPN_SPLIT) { 111 printf(","); 112 ptr = (void *)(u_32_t *)&np->in_in[1]; 113 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 114 } 115 if (((np->in_v == 4) && (np->in_inip == 0)) || 116 ((np->in_v == 6) && IP6_ISZERO(&np->in_in[0]))) 117 printmask(np->in_v, (u_32_t *)&np->in_in[1]); 118 119 if (np->in_flags & IPN_TCPUDP) { 120 if ((np->in_flags & IPN_FIXEDDPORT) != 0) 121 printf(" port = %d", ntohs(np->in_pnext)); 122 else 123 printf(" port %d", ntohs(np->in_pnext)); 124 } 125 putchar(' '); 126 printproto(pr, np->in_p, np); 127 if (np->in_flags & IPN_ROUNDR) 128 printf(" round-robin"); 129 if (np->in_flags & IPN_FRAG) 130 printf(" frag"); 131 if (np->in_age[0] != 0 || np->in_age[1] != 0) { 132 printf(" age %d/%d", np->in_age[0], np->in_age[1]); 133 } 134 if (np->in_flags & IPN_STICKY) 135 printf(" sticky"); 136 if (np->in_mssclamp != 0) 137 printf(" mssclamp %d", np->in_mssclamp); 138 if (*np->in_plabel != '\0') 139 printf(" proxy %.*s", (int)sizeof (np->in_plabel), 140 np->in_plabel); 141 if (np->in_tag.ipt_tag[0] != '\0') 142 printf(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag); 143 printf("\n"); 144 if (opts & OPT_DEBUG) 145 printf("\tpmax %u\n", np->in_pmax); 146 } else { 147 if (!(np->in_flags & IPN_FILTER)) { 148 ptr = (void *)(u_32_t *)&np->in_in[0]; 149 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 150 printmask(np->in_v, (u_32_t *)&np->in_in[1]); 151 } 152 printf(" -> "); 153 if (np->in_flags & IPN_IPRANGE) { 154 printf("range "); 155 ptr = (void *)(u_32_t *)&np->in_out[0]; 156 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 157 printf("-"); 158 ptr = (void *)(u_32_t *)&np->in_out[1]; 159 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 160 } else { 161 ptr = (void *)(u_32_t *)&np->in_out[0]; 162 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 163 printmask(np->in_v, (u_32_t *)&np->in_out[1]); 164 } 165 if (*np->in_plabel != '\0') { 166 printf(" proxy port "); 167 if (np->in_dcmp != 0) 168 np->in_dport = htons(np->in_dport); 169 if (np->in_dport != 0) { 170 char *s; 171 172 s = portname(np->in_p, ntohs(np->in_dport)); 173 if (s != NULL) 174 fputs(s, stdout); 175 else 176 fputs("???", stdout); 177 } 178 printf(" %.*s/", (int)sizeof (np->in_plabel), 179 np->in_plabel); 180 printproto(pr, np->in_p, NULL); 181 } else if (np->in_redir == NAT_MAPBLK) { 182 if ((np->in_pmin == 0) && 183 (np->in_flags & IPN_AUTOPORTMAP)) 184 printf(" ports auto"); 185 else 186 printf(" ports %d", np->in_pmin); 187 if (opts & OPT_DEBUG) 188 printf("\n\tip modulous %d", np->in_pmax); 189 } else if (np->in_pmin || np->in_pmax) { 190 if (np->in_flags & IPN_ICMPQUERY) { 191 printf(" icmpidmap "); 192 } else { 193 printf(" portmap "); 194 } 195 printproto(pr, np->in_p, np); 196 if (np->in_flags & IPN_AUTOPORTMAP) { 197 printf(" auto"); 198 if (opts & OPT_DEBUG) 199 printf(" [%d:%d %d %d]", 200 ntohs(np->in_pmin), 201 ntohs(np->in_pmax), 202 np->in_ippip, np->in_ppip); 203 } else { 204 printf(" %d:%d", ntohs(np->in_pmin), 205 ntohs(np->in_pmax)); 206 } 207 } else if (np->in_flags & IPN_TCPUDP || np->in_p) { 208 putchar(' '); 209 printproto(pr, np->in_p, np); 210 } 211 212 if (np->in_flags & IPN_FRAG) 213 printf(" frag"); 214 if (np->in_age[0] != 0 || np->in_age[1] != 0) { 215 printf(" age %d/%d", np->in_age[0], np->in_age[1]); 216 } 217 if (np->in_mssclamp != 0) 218 printf(" mssclamp %d", np->in_mssclamp); 219 if (np->in_tag.ipt_tag[0] != '\0') 220 printf(" tag %s", np->in_tag.ipt_tag); 221 if (np->in_flags & IPN_SEQUENTIAL) 222 printf(" sequential"); 223 printf("\n"); 224 if (opts & OPT_DEBUG) { 225 struct in_addr nip; 226 227 nip.s_addr = htonl(np->in_nextip.s_addr); 228 229 printf("\tnextip %s pnext %d\n", 230 inet_ntoa(nip), np->in_pnext); 231 } 232 } 233 234 if (opts & OPT_DEBUG) { 235 printf("\tspace %lu use %u hits %lu flags %#x proto %d hv %d\n", 236 np->in_space, np->in_use, np->in_hits, 237 np->in_flags, np->in_p, np->in_hv); 238 printf("\tifp[0] %p ifp[1] %p apr %p\n", 239 np->in_ifps[0], np->in_ifps[1], np->in_apr); 240 printf("\ttqehead %p/%p comment %p\n", 241 np->in_tqehead[0], np->in_tqehead[1], np->in_comment); 242 } 243 } 244