10Sstevel@tonic-gate /* 27176Syx160601 * Copyright (C) 2002-2005 by Darren Reed. 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 50Sstevel@tonic-gate * 60Sstevel@tonic-gate * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) 7570Syx160601 * 87176Syx160601 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 9570Syx160601 * Use is subject to license terms. 100Sstevel@tonic-gate */ 110Sstevel@tonic-gate 12570Syx160601 #pragma ident "%Z%%M% %I% %E% SMI" 13570Syx160601 140Sstevel@tonic-gate #include "ipf.h" 150Sstevel@tonic-gate #include "kmem.h" 160Sstevel@tonic-gate 170Sstevel@tonic-gate 180Sstevel@tonic-gate #if !defined(lint) 192393Syz155240 static const char rcsid[] = "@(#)$Id: printnat.c,v 1.22.2.9 2005/06/12 07:18:43 darrenr Exp $"; 200Sstevel@tonic-gate #endif 210Sstevel@tonic-gate 220Sstevel@tonic-gate /* 230Sstevel@tonic-gate * Print out a NAT rule 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate void printnat(np, opts) 260Sstevel@tonic-gate ipnat_t *np; 270Sstevel@tonic-gate int opts; 280Sstevel@tonic-gate { 290Sstevel@tonic-gate struct protoent *pr; 307176Syx160601 int bits, af; 317176Syx160601 char ipbuf[INET6_ADDRSTRLEN]; 327176Syx160601 void *ptr; 330Sstevel@tonic-gate 340Sstevel@tonic-gate pr = getprotobynumber(np->in_p); 350Sstevel@tonic-gate 360Sstevel@tonic-gate switch (np->in_redir) 370Sstevel@tonic-gate { 380Sstevel@tonic-gate case NAT_REDIRECT : 390Sstevel@tonic-gate printf("rdr"); 400Sstevel@tonic-gate break; 410Sstevel@tonic-gate case NAT_MAP : 420Sstevel@tonic-gate printf("map"); 430Sstevel@tonic-gate break; 440Sstevel@tonic-gate case NAT_MAPBLK : 450Sstevel@tonic-gate printf("map-block"); 460Sstevel@tonic-gate break; 470Sstevel@tonic-gate case NAT_BIMAP : 480Sstevel@tonic-gate printf("bimap"); 490Sstevel@tonic-gate break; 500Sstevel@tonic-gate default : 510Sstevel@tonic-gate fprintf(stderr, "unknown value for in_redir: %#x\n", 520Sstevel@tonic-gate np->in_redir); 530Sstevel@tonic-gate break; 540Sstevel@tonic-gate } 550Sstevel@tonic-gate 560Sstevel@tonic-gate printf(" %s", np->in_ifnames[0]); 570Sstevel@tonic-gate if ((np->in_ifnames[1][0] != '\0') && 580Sstevel@tonic-gate (strncmp(np->in_ifnames[0], np->in_ifnames[1], LIFNAMSIZ) != 0)) { 590Sstevel@tonic-gate printf(",%s ", np->in_ifnames[1]); 600Sstevel@tonic-gate } 610Sstevel@tonic-gate putchar(' '); 620Sstevel@tonic-gate 630Sstevel@tonic-gate if (np->in_flags & IPN_FILTER) { 640Sstevel@tonic-gate if (np->in_flags & IPN_NOTSRC) 650Sstevel@tonic-gate printf("! "); 660Sstevel@tonic-gate printf("from "); 670Sstevel@tonic-gate if (np->in_redir == NAT_REDIRECT) { 687176Syx160601 printhostmask(np->in_v, (u_32_t *)&np->in_src[0], 697176Syx160601 (u_32_t *)&np->in_src[1]); 700Sstevel@tonic-gate } else { 717176Syx160601 printhostmask(np->in_v, (u_32_t *)&np->in_in[0], 727176Syx160601 (u_32_t *)&np->in_in[1]); 730Sstevel@tonic-gate } 740Sstevel@tonic-gate if (np->in_scmp) 750Sstevel@tonic-gate printportcmp(np->in_p, &np->in_tuc.ftu_src); 760Sstevel@tonic-gate 770Sstevel@tonic-gate if (np->in_flags & IPN_NOTDST) 780Sstevel@tonic-gate printf(" !"); 790Sstevel@tonic-gate printf(" to "); 800Sstevel@tonic-gate if (np->in_redir == NAT_REDIRECT) { 817176Syx160601 printhostmask(np->in_v, (u_32_t *)&np->in_out[0], 827176Syx160601 (u_32_t *)&np->in_out[1]); 830Sstevel@tonic-gate } else { 847176Syx160601 printhostmask(np->in_v, (u_32_t *)&np->in_src[0], 857176Syx160601 (u_32_t *)&np->in_src[1]); 860Sstevel@tonic-gate } 870Sstevel@tonic-gate if (np->in_dcmp) 880Sstevel@tonic-gate printportcmp(np->in_p, &np->in_tuc.ftu_dst); 890Sstevel@tonic-gate } 900Sstevel@tonic-gate 917176Syx160601 if (np->in_v == 4) 927176Syx160601 af = AF_INET; 937176Syx160601 else if (np->in_v == 6) 947176Syx160601 af = AF_INET6; 957176Syx160601 else 967176Syx160601 af = 0; 977176Syx160601 980Sstevel@tonic-gate if (np->in_redir == NAT_REDIRECT) { 990Sstevel@tonic-gate if (!(np->in_flags & IPN_FILTER)) { 1007176Syx160601 ptr = (void *)(u_32_t *)&np->in_out[0]; 1017176Syx160601 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 1027176Syx160601 printmask(np->in_v, (u_32_t *)&np->in_out[1]); 1032393Syz155240 if (np->in_flags & IPN_TCPUDP) { 1042393Syz155240 printf(" port %d", ntohs(np->in_pmin)); 1052393Syz155240 if (np->in_pmax != np->in_pmin) 1062393Syz155240 printf("-%d", ntohs(np->in_pmax)); 1072393Syz155240 } 1080Sstevel@tonic-gate } 1097176Syx160601 printf(" -> "); 1107176Syx160601 ptr = (void *)(u_32_t *)&np->in_in[0]; 1117176Syx160601 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 1127176Syx160601 if (np->in_flags & IPN_SPLIT) { 1137176Syx160601 printf(","); 1147176Syx160601 ptr = (void *)(u_32_t *)&np->in_in[1]; 1157176Syx160601 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 1162873Sjojemann } 1177176Syx160601 if (((np->in_v == 4) && (np->in_inip == 0)) || 1187176Syx160601 ((np->in_v == 6) && IP6_ISZERO(&np->in_in[0]))) 1197176Syx160601 printmask(np->in_v, (u_32_t *)&np->in_in[1]); 1207176Syx160601 1212393Syz155240 if (np->in_flags & IPN_TCPUDP) { 1222393Syz155240 if ((np->in_flags & IPN_FIXEDDPORT) != 0) 1232393Syz155240 printf(" port = %d", ntohs(np->in_pnext)); 1242393Syz155240 else 1252393Syz155240 printf(" port %d", ntohs(np->in_pnext)); 126570Syx160601 } 1272393Syz155240 putchar(' '); 1282393Syz155240 printproto(pr, np->in_p, np); 1290Sstevel@tonic-gate if (np->in_flags & IPN_ROUNDR) 1300Sstevel@tonic-gate printf(" round-robin"); 1310Sstevel@tonic-gate if (np->in_flags & IPN_FRAG) 1320Sstevel@tonic-gate printf(" frag"); 1330Sstevel@tonic-gate if (np->in_age[0] != 0 || np->in_age[1] != 0) { 1340Sstevel@tonic-gate printf(" age %d/%d", np->in_age[0], np->in_age[1]); 1350Sstevel@tonic-gate } 1360Sstevel@tonic-gate if (np->in_flags & IPN_STICKY) 1370Sstevel@tonic-gate printf(" sticky"); 1380Sstevel@tonic-gate if (np->in_mssclamp != 0) 1390Sstevel@tonic-gate printf(" mssclamp %d", np->in_mssclamp); 1402393Syz155240 if (*np->in_plabel != '\0') 1417176Syx160601 printf(" proxy %.*s", (int)sizeof (np->in_plabel), 1420Sstevel@tonic-gate np->in_plabel); 1432393Syz155240 if (np->in_tag.ipt_tag[0] != '\0') 1442393Syz155240 printf(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag); 1450Sstevel@tonic-gate printf("\n"); 1460Sstevel@tonic-gate if (opts & OPT_DEBUG) 1472393Syz155240 printf("\tpmax %u\n", np->in_pmax); 1480Sstevel@tonic-gate } else { 1490Sstevel@tonic-gate if (!(np->in_flags & IPN_FILTER)) { 1507176Syx160601 ptr = (void *)(u_32_t *)&np->in_in[0]; 1517176Syx160601 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 1527176Syx160601 printmask(np->in_v, (u_32_t *)&np->in_in[1]); 1530Sstevel@tonic-gate } 1540Sstevel@tonic-gate printf(" -> "); 1550Sstevel@tonic-gate if (np->in_flags & IPN_IPRANGE) { 1567176Syx160601 printf("range "); 1577176Syx160601 ptr = (void *)(u_32_t *)&np->in_out[0]; 1587176Syx160601 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 1597176Syx160601 printf("-"); 1607176Syx160601 ptr = (void *)(u_32_t *)&np->in_out[1]; 1617176Syx160601 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 1620Sstevel@tonic-gate } else { 1637176Syx160601 ptr = (void *)(u_32_t *)&np->in_out[0]; 1647176Syx160601 printf("%s", inet_ntop(af, ptr, ipbuf, sizeof (ipbuf))); 1657176Syx160601 printmask(np->in_v, (u_32_t *)&np->in_out[1]); 1660Sstevel@tonic-gate } 1670Sstevel@tonic-gate if (*np->in_plabel != '\0') { 1682393Syz155240 printf(" proxy port "); 1690Sstevel@tonic-gate if (np->in_dcmp != 0) 1700Sstevel@tonic-gate np->in_dport = htons(np->in_dport); 1710Sstevel@tonic-gate if (np->in_dport != 0) { 1722393Syz155240 char *s; 1732393Syz155240 1742393Syz155240 s = portname(np->in_p, ntohs(np->in_dport)); 1752393Syz155240 if (s != NULL) 1762393Syz155240 fputs(s, stdout); 1770Sstevel@tonic-gate else 1782393Syz155240 fputs("???", stdout); 1790Sstevel@tonic-gate } 1807176Syx160601 printf(" %.*s/", (int)sizeof (np->in_plabel), 1810Sstevel@tonic-gate np->in_plabel); 1822393Syz155240 printproto(pr, np->in_p, NULL); 1830Sstevel@tonic-gate } else if (np->in_redir == NAT_MAPBLK) { 1840Sstevel@tonic-gate if ((np->in_pmin == 0) && 1850Sstevel@tonic-gate (np->in_flags & IPN_AUTOPORTMAP)) 1860Sstevel@tonic-gate printf(" ports auto"); 1870Sstevel@tonic-gate else 1880Sstevel@tonic-gate printf(" ports %d", np->in_pmin); 1890Sstevel@tonic-gate if (opts & OPT_DEBUG) 1900Sstevel@tonic-gate printf("\n\tip modulous %d", np->in_pmax); 1910Sstevel@tonic-gate } else if (np->in_pmin || np->in_pmax) { 1922393Syz155240 if (np->in_flags & IPN_ICMPQUERY) { 1932393Syz155240 printf(" icmpidmap "); 1942393Syz155240 } else { 1952393Syz155240 printf(" portmap "); 1962393Syz155240 } 1972393Syz155240 printproto(pr, np->in_p, np); 1980Sstevel@tonic-gate if (np->in_flags & IPN_AUTOPORTMAP) { 1990Sstevel@tonic-gate printf(" auto"); 2000Sstevel@tonic-gate if (opts & OPT_DEBUG) 2010Sstevel@tonic-gate printf(" [%d:%d %d %d]", 2020Sstevel@tonic-gate ntohs(np->in_pmin), 2030Sstevel@tonic-gate ntohs(np->in_pmax), 2040Sstevel@tonic-gate np->in_ippip, np->in_ppip); 2050Sstevel@tonic-gate } else { 2060Sstevel@tonic-gate printf(" %d:%d", ntohs(np->in_pmin), 2070Sstevel@tonic-gate ntohs(np->in_pmax)); 2080Sstevel@tonic-gate } 2092393Syz155240 } else if (np->in_flags & IPN_TCPUDP || np->in_p) { 2102393Syz155240 putchar(' '); 2112393Syz155240 printproto(pr, np->in_p, np); 2120Sstevel@tonic-gate } 2132393Syz155240 2140Sstevel@tonic-gate if (np->in_flags & IPN_FRAG) 2150Sstevel@tonic-gate printf(" frag"); 2160Sstevel@tonic-gate if (np->in_age[0] != 0 || np->in_age[1] != 0) { 2170Sstevel@tonic-gate printf(" age %d/%d", np->in_age[0], np->in_age[1]); 2180Sstevel@tonic-gate } 2190Sstevel@tonic-gate if (np->in_mssclamp != 0) 2200Sstevel@tonic-gate printf(" mssclamp %d", np->in_mssclamp); 2212393Syz155240 if (np->in_tag.ipt_tag[0] != '\0') 2222393Syz155240 printf(" tag %s", np->in_tag.ipt_tag); 223*7259Sdr146992 if (np->in_flags & IPN_SEQUENTIAL) 224*7259Sdr146992 printf(" sequential"); 2250Sstevel@tonic-gate printf("\n"); 2260Sstevel@tonic-gate if (opts & OPT_DEBUG) { 2270Sstevel@tonic-gate struct in_addr nip; 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate nip.s_addr = htonl(np->in_nextip.s_addr); 2300Sstevel@tonic-gate 2312393Syz155240 printf("\tnextip %s pnext %d\n", 2320Sstevel@tonic-gate inet_ntoa(nip), np->in_pnext); 2330Sstevel@tonic-gate } 2340Sstevel@tonic-gate } 2352393Syz155240 2362393Syz155240 if (opts & OPT_DEBUG) { 2372393Syz155240 printf("\tspace %lu use %u hits %lu flags %#x proto %d hv %d\n", 2382393Syz155240 np->in_space, np->in_use, np->in_hits, 2392393Syz155240 np->in_flags, np->in_p, np->in_hv); 2402393Syz155240 printf("\tifp[0] %p ifp[1] %p apr %p\n", 2412393Syz155240 np->in_ifps[0], np->in_ifps[1], np->in_apr); 2422393Syz155240 printf("\ttqehead %p/%p comment %p\n", 2432393Syz155240 np->in_tqehead[0], np->in_tqehead[1], np->in_comment); 2442393Syz155240 } 2450Sstevel@tonic-gate } 246