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