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