1 /* $FreeBSD$ */ 2 3 /* 4 * Copyright (C) 2012 by Darren Reed. 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 */ 8 9 #include "ipf.h" 10 #include "kmem.h" 11 12 13 ipstate_t * 14 printstate(ipstate_t *sp, int opts, u_long now) 15 { 16 struct protoent *pr; 17 synclist_t ipsync; 18 19 if ((opts & OPT_NORESOLVE) == 0) 20 pr = getprotobynumber(sp->is_p); 21 else 22 pr = NULL; 23 24 PRINTF("%d:", sp->is_v); 25 if (pr != NULL) 26 PRINTF("%s", pr->p_name); 27 else 28 PRINTF("%d", sp->is_p); 29 30 PRINTF(" src:%s", hostname(sp->is_family, &sp->is_src.in4)); 31 if (sp->is_p == IPPROTO_UDP || sp->is_p == IPPROTO_TCP) { 32 if (sp->is_flags & IS_WSPORT) 33 PRINTF(",*"); 34 else 35 PRINTF(",%d", ntohs(sp->is_sport)); 36 } 37 38 PRINTF(" dst:%s", hostname(sp->is_family, &sp->is_dst.in4)); 39 if (sp->is_p == IPPROTO_UDP || sp->is_p == IPPROTO_TCP) { 40 if (sp->is_flags & IS_WDPORT) 41 PRINTF(",*"); 42 else 43 PRINTF(",%d", ntohs(sp->is_dport)); 44 } 45 46 if (sp->is_p == IPPROTO_TCP) { 47 PRINTF(" state:%d/%d", sp->is_state[0], sp->is_state[1]); 48 } 49 50 PRINTF(" %ld", sp->is_die - now); 51 if (sp->is_phnext == NULL) 52 PRINTF(" ORPHAN"); 53 if (sp->is_flags & IS_CLONE) 54 PRINTF(" CLONE"); 55 putchar('\n'); 56 57 if (sp->is_p == IPPROTO_TCP) { 58 PRINTF("\t%x:%x %hu<<%d:%hu<<%d\n", 59 sp->is_send, sp->is_dend, 60 sp->is_maxswin, sp->is_swinscale, 61 sp->is_maxdwin, sp->is_dwinscale); 62 if ((opts & OPT_VERBOSE) != 0) { 63 PRINTF("\tcmsk %04x smsk %04x isc %p s0 %08x/%08x\n", 64 sp->is_smsk[0], sp->is_smsk[1], sp->is_isc, 65 sp->is_s0[0], sp->is_s0[1]); 66 PRINTF("\tFWD: ISN inc %x sumd %x\n", 67 sp->is_isninc[0], sp->is_sumd[0]); 68 PRINTF("\tREV: ISN inc %x sumd %x\n", 69 sp->is_isninc[1], sp->is_sumd[1]); 70 #ifdef IPFILTER_SCAN 71 PRINTF("\tsbuf[0] ["); 72 printsbuf(sp->is_sbuf[0]); 73 PRINTF("] sbuf[1] ["); 74 printsbuf(sp->is_sbuf[1]); 75 PRINTF("]\n"); 76 #endif 77 } 78 } else if (sp->is_p == IPPROTO_GRE) { 79 PRINTF("\tcall %hx/%hx\n", ntohs(sp->is_gre.gs_call[0]), 80 ntohs(sp->is_gre.gs_call[1])); 81 } else if (sp->is_p == IPPROTO_ICMP 82 #ifdef USE_INET6 83 || sp->is_p == IPPROTO_ICMPV6 84 #endif 85 ) { 86 PRINTF("\tid %hu seq %hu type %d\n", sp->is_icmp.ici_id, 87 sp->is_icmp.ici_seq, sp->is_icmp.ici_type); 88 } 89 90 #ifdef USE_QUAD_T 91 PRINTF("\tFWD: IN pkts %"PRIu64" bytes %"PRIu64" OUT pkts %"PRIu64" bytes %"PRIu64"\n\tREV: IN pkts %"PRIu64" bytes %"PRIu64" OUT pkts %"PRIu64" bytes %"PRIu64"\n", 92 sp->is_pkts[0], sp->is_bytes[0], 93 sp->is_pkts[1], sp->is_bytes[1], 94 sp->is_pkts[2], sp->is_bytes[2], 95 sp->is_pkts[3], sp->is_bytes[3]); 96 #else 97 PRINTF("\tFWD: IN pkts %lu bytes %lu OUT pkts %lu bytes %lu\n\tREV: IN pkts %lu bytes %lu OUT pkts %lu bytes %lu\n", 98 sp->is_pkts[0], sp->is_bytes[0], 99 sp->is_pkts[1], sp->is_bytes[1], 100 sp->is_pkts[2], sp->is_bytes[2], 101 sp->is_pkts[3], sp->is_bytes[3]); 102 #endif 103 104 PRINTF("\ttag %u pass %#x = ", sp->is_tag, sp->is_pass); 105 106 /* 107 * Print out bits set in the result code for the state being 108 * kept as they would for a rule. 109 */ 110 if (FR_ISPASS(sp->is_pass)) { 111 PRINTF("pass"); 112 } else if (FR_ISBLOCK(sp->is_pass)) { 113 PRINTF("block"); 114 switch (sp->is_pass & FR_RETMASK) 115 { 116 case FR_RETICMP : 117 PRINTF(" return-icmp"); 118 break; 119 case FR_FAKEICMP : 120 PRINTF(" return-icmp-as-dest"); 121 break; 122 case FR_RETRST : 123 PRINTF(" return-rst"); 124 break; 125 default : 126 break; 127 } 128 } else if ((sp->is_pass & FR_LOGMASK) == FR_LOG) { 129 PRINTF("log"); 130 if (sp->is_pass & FR_LOGBODY) 131 PRINTF(" body"); 132 if (sp->is_pass & FR_LOGFIRST) 133 PRINTF(" first"); 134 } else if (FR_ISACCOUNT(sp->is_pass)) { 135 PRINTF("count"); 136 } else if (FR_ISPREAUTH(sp->is_pass)) { 137 PRINTF("preauth"); 138 } else if (FR_ISAUTH(sp->is_pass)) 139 PRINTF("auth"); 140 141 if (sp->is_pass & FR_OUTQUE) 142 PRINTF(" out"); 143 else 144 PRINTF(" in"); 145 146 if ((sp->is_pass & FR_LOG) != 0) { 147 PRINTF(" log"); 148 if (sp->is_pass & FR_LOGBODY) 149 PRINTF(" body"); 150 if (sp->is_pass & FR_LOGFIRST) 151 PRINTF(" first"); 152 if (sp->is_pass & FR_LOGORBLOCK) 153 PRINTF(" or-block"); 154 } 155 if (sp->is_pass & FR_QUICK) 156 PRINTF(" quick"); 157 if (sp->is_pass & FR_KEEPFRAG) 158 PRINTF(" keep frags"); 159 /* a given; no? */ 160 if (sp->is_pass & FR_KEEPSTATE) { 161 PRINTF(" keep state"); 162 if (sp->is_pass & (FR_STATESYNC|FR_STSTRICT|FR_STLOOSE)) { 163 PRINTF(" ("); 164 if (sp->is_pass & FR_STATESYNC) 165 PRINTF(" sync"); 166 if (sp->is_pass & FR_STSTRICT) 167 PRINTF(" strict"); 168 if (sp->is_pass & FR_STLOOSE) 169 PRINTF(" loose"); 170 PRINTF(" )"); 171 } 172 } 173 PRINTF("\n"); 174 175 if ((opts & OPT_VERBOSE) != 0) { 176 PRINTF("\tref %d", sp->is_ref); 177 PRINTF(" pkt_flags & %x(%x) = %x\n", 178 sp->is_flags & 0xf, sp->is_flags, sp->is_flags >> 4); 179 PRINTF("\tpkt_options & %x = %x, %x = %x \n", sp->is_optmsk[0], 180 sp->is_opt[0], sp->is_optmsk[1], sp->is_opt[1]); 181 PRINTF("\tpkt_security & %x = %x, pkt_auth & %x = %x\n", 182 sp->is_secmsk, sp->is_sec, sp->is_authmsk, 183 sp->is_auth); 184 PRINTF("\tis_flx %#x %#x %#x %#x\n", sp->is_flx[0][0], 185 sp->is_flx[0][1], sp->is_flx[1][0], sp->is_flx[1][1]); 186 } 187 PRINTF("\tinterfaces: in %s", FORMAT_IF(sp->is_ifname[0])); 188 if (opts & OPT_DEBUG) 189 PRINTF("/%p", sp->is_ifp[0]); 190 PRINTF(",%s", FORMAT_IF(sp->is_ifname[1])); 191 if (opts & OPT_DEBUG) 192 PRINTF("/%p", sp->is_ifp[1]); 193 PRINTF(" out %s", FORMAT_IF(sp->is_ifname[2])); 194 if (opts & OPT_DEBUG) 195 PRINTF("/%p", sp->is_ifp[2]); 196 PRINTF(",%s", FORMAT_IF(sp->is_ifname[3])); 197 if (opts & OPT_DEBUG) 198 PRINTF("/%p", sp->is_ifp[3]); 199 PRINTF("\n"); 200 201 PRINTF("\tSync status: "); 202 if (sp->is_sync != NULL) { 203 if (kmemcpy((char *)&ipsync, (u_long)sp->is_sync, 204 sizeof(ipsync))) { 205 PRINTF("status could not be retrieved\n"); 206 return (NULL); 207 } 208 209 PRINTF("idx %d num %d v %d pr %d rev %d\n", 210 ipsync.sl_idx, ipsync.sl_num, ipsync.sl_v, 211 ipsync.sl_p, ipsync.sl_rev); 212 } else { 213 PRINTF("not synchronized\n"); 214 } 215 216 return (sp->is_next); 217 } 218