| File: | src/usr.bin/systat/pftop.c |
| Warning: | line 1107, column 10 Division by zero |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: pftop.c,v 1.45 2019/10/17 21:54:29 millert Exp $ */ | |||
| 2 | /* | |||
| 3 | * Copyright (c) 2001, 2007 Can Erkin Acar | |||
| 4 | * Copyright (c) 2001 Daniel Hartmeier | |||
| 5 | * All rights reserved. | |||
| 6 | * | |||
| 7 | * Redistribution and use in source and binary forms, with or without | |||
| 8 | * modification, are permitted provided that the following conditions | |||
| 9 | * are met: | |||
| 10 | * | |||
| 11 | * - Redistributions of source code must retain the above copyright | |||
| 12 | * notice, this list of conditions and the following disclaimer. | |||
| 13 | * - Redistributions in binary form must reproduce the above | |||
| 14 | * copyright notice, this list of conditions and the following | |||
| 15 | * disclaimer in the documentation and/or other materials provided | |||
| 16 | * with the distribution. | |||
| 17 | * | |||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |||
| 22 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | |||
| 30 | * | |||
| 31 | */ | |||
| 32 | ||||
| 33 | #include <sys/types.h> | |||
| 34 | #include <sys/ioctl.h> | |||
| 35 | #include <sys/socket.h> | |||
| 36 | ||||
| 37 | #include <net/if.h> | |||
| 38 | #include <netinet/in.h> | |||
| 39 | #include <netinet/tcp.h> | |||
| 40 | #include <netinet/tcp_fsm.h> | |||
| 41 | #include <net/pfvar.h> | |||
| 42 | #include <arpa/inet.h> | |||
| 43 | ||||
| 44 | #include <net/hfsc.h> | |||
| 45 | ||||
| 46 | #include <ctype.h> | |||
| 47 | #include <curses.h> | |||
| 48 | #include <err.h> | |||
| 49 | #include <errno(*__errno()).h> | |||
| 50 | #include <fcntl.h> | |||
| 51 | #include <netdb.h> | |||
| 52 | #include <signal.h> | |||
| 53 | #include <stdio.h> | |||
| 54 | #include <stdlib.h> | |||
| 55 | #include <string.h> | |||
| 56 | #include <unistd.h> | |||
| 57 | #include <limits.h> | |||
| 58 | #include <stdarg.h> | |||
| 59 | ||||
| 60 | #include "systat.h" | |||
| 61 | #include "engine.h" | |||
| 62 | #include "cache.h" | |||
| 63 | ||||
| 64 | extern const char *tcpstates[]; | |||
| 65 | ||||
| 66 | #define MIN_NUM_STATES1024 1024 | |||
| 67 | #define NUM_STATE_INC1024 1024 | |||
| 68 | ||||
| 69 | #define DEFAULT_CACHE_SIZE10000 10000 | |||
| 70 | ||||
| 71 | /* XXX must also check type before use */ | |||
| 72 | #define PT_ADDR(x)(&(x)->addr.v.a.addr) (&(x)->addr.v.a.addr) | |||
| 73 | ||||
| 74 | /* XXX must also check type before use */ | |||
| 75 | #define PT_MASK(x)(&(x)->addr.v.a.mask) (&(x)->addr.v.a.mask) | |||
| 76 | ||||
| 77 | #define PT_NOROUTE(x)((x)->addr.type == PF_ADDR_NOROUTE) ((x)->addr.type == PF_ADDR_NOROUTE) | |||
| 78 | ||||
| 79 | /* view management */ | |||
| 80 | int select_states(void); | |||
| 81 | int read_states(void); | |||
| 82 | void sort_states(void); | |||
| 83 | void print_states(void); | |||
| 84 | ||||
| 85 | int select_rules(void); | |||
| 86 | int read_rules(void); | |||
| 87 | void print_rules(void); | |||
| 88 | ||||
| 89 | int select_queues(void); | |||
| 90 | int read_queues(void); | |||
| 91 | void print_queues(void); | |||
| 92 | ||||
| 93 | void update_cache(void); | |||
| 94 | ||||
| 95 | /* qsort callbacks */ | |||
| 96 | int sort_size_callback(const void *s1, const void *s2); | |||
| 97 | int sort_exp_callback(const void *s1, const void *s2); | |||
| 98 | int sort_pkt_callback(const void *s1, const void *s2); | |||
| 99 | int sort_age_callback(const void *s1, const void *s2); | |||
| 100 | int sort_sa_callback(const void *s1, const void *s2); | |||
| 101 | int sort_sp_callback(const void *s1, const void *s2); | |||
| 102 | int sort_da_callback(const void *s1, const void *s2); | |||
| 103 | int sort_dp_callback(const void *s1, const void *s2); | |||
| 104 | int sort_rate_callback(const void *s1, const void *s2); | |||
| 105 | int sort_peak_callback(const void *s1, const void *s2); | |||
| 106 | int pf_dev = -1; | |||
| 107 | ||||
| 108 | struct sc_ent **state_cache = NULL((void *)0); | |||
| 109 | struct pfsync_state *state_buf = NULL((void *)0); | |||
| 110 | size_t state_buf_len = 0; | |||
| 111 | size_t *state_ord = NULL((void *)0); | |||
| 112 | size_t num_states = 0; | |||
| 113 | size_t num_states_all = 0; | |||
| 114 | u_int32_t num_rules = 0; | |||
| 115 | u_int32_t num_queues = 0; | |||
| 116 | int cachestates = 0; | |||
| 117 | ||||
| 118 | char *filter_string = NULL((void *)0); | |||
| 119 | ||||
| 120 | #define MIN_LABEL_SIZE5 5 | |||
| 121 | #define ANCHOR_FLD_SIZE12 12 | |||
| 122 | ||||
| 123 | /* Define fields */ | |||
| 124 | field_def fields[] = { | |||
| 125 | {"SRC", 20, 45, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 126 | {"DEST", 20, 45, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 127 | {"GW", 20, 45, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 128 | {"STATE", 5, 23, 18, FLD_ALIGN_COLUMN3, -1, 0, 0, 0}, | |||
| 129 | {"AGE", 5, 9, 4, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 130 | {"EXP", 5, 9, 4, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 131 | {"PR ", 4, 9, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 132 | {"DIR", 1, 3, 2, FLD_ALIGN_CENTER2, -1, 0, 0, 0}, | |||
| 133 | {"PKTS", 5, 8, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 134 | {"BYTES", 5, 8, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 135 | {"RULE", 2, 4, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 136 | {"LABEL", MIN_LABEL_SIZE5, MIN_LABEL_SIZE5, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 137 | {"STATES", 5, 8, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 138 | {"EVAL", 5, 8, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 139 | {"ACTION", 1, 8, 4, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 140 | {"LOG", 1, 3, 2, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 141 | {"QUICK", 1, 1, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 142 | {"KS", 1, 1, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 143 | {"IF", 4, 7, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 144 | {"INFO", 40, 80, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 145 | {"MAX", 3, 5, 2, FLD_ALIGN_RIGHT1, -1, 0, 0}, | |||
| 146 | {"RATE", 5, 8, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 147 | {"AVG", 5, 8, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 148 | {"PEAK", 5, 8, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 149 | {"ANCHOR", 6, 16, 1, FLD_ALIGN_LEFT0, -1, 0, 0}, | |||
| 150 | {"QUEUE", 15, 30, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 151 | {"BW/FL", 4, 5, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 152 | {"SCH", 3, 4, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0}, | |||
| 153 | {"DROP_P", 6, 8, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 154 | {"DROP_B", 6, 8, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 155 | {"QLEN", 4, 4, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 156 | {"BORROW", 4, 6, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 157 | {"SUSPENDS", 4, 6, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 158 | {"P/S", 3, 7, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0}, | |||
| 159 | {"B/S", 4, 7, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0} | |||
| 160 | }; | |||
| 161 | ||||
| 162 | ||||
| 163 | /* for states */ | |||
| 164 | #define FLD_SRC(&fields[0]) FIELD_ADDR(fields,0)(&fields[0]) | |||
| 165 | #define FLD_DEST(&fields[1]) FIELD_ADDR(fields,1)(&fields[1]) | |||
| 166 | #define FLD_GW(&fields[2]) FIELD_ADDR(fields,2)(&fields[2]) | |||
| 167 | #define FLD_STATE(&fields[3]) FIELD_ADDR(fields,3)(&fields[3]) | |||
| 168 | #define FLD_AGE(&fields[4]) FIELD_ADDR(fields,4)(&fields[4]) | |||
| 169 | #define FLD_EXP(&fields[5]) FIELD_ADDR(fields,5)(&fields[5]) | |||
| 170 | /* common */ | |||
| 171 | #define FLD_PROTO(&fields[6]) FIELD_ADDR(fields,6)(&fields[6]) | |||
| 172 | #define FLD_DIR(&fields[7]) FIELD_ADDR(fields,7)(&fields[7]) | |||
| 173 | #define FLD_PKTS(&fields[8]) FIELD_ADDR(fields,8)(&fields[8]) | |||
| 174 | #define FLD_BYTES(&fields[9]) FIELD_ADDR(fields,9)(&fields[9]) | |||
| 175 | #define FLD_RULE(&fields[10]) FIELD_ADDR(fields,10)(&fields[10]) | |||
| 176 | /* for rules */ | |||
| 177 | #define FLD_LABEL(&fields[11]) FIELD_ADDR(fields,11)(&fields[11]) | |||
| 178 | #define FLD_STATS(&fields[12]) FIELD_ADDR(fields,12)(&fields[12]) | |||
| 179 | #define FLD_EVAL(&fields[13]) FIELD_ADDR(fields,13)(&fields[13]) | |||
| 180 | #define FLD_ACTION(&fields[14]) FIELD_ADDR(fields,14)(&fields[14]) | |||
| 181 | #define FLD_LOG(&fields[15]) FIELD_ADDR(fields,15)(&fields[15]) | |||
| 182 | #define FLD_QUICK(&fields[16]) FIELD_ADDR(fields,16)(&fields[16]) | |||
| 183 | #define FLD_KST(&fields[17]) FIELD_ADDR(fields,17)(&fields[17]) | |||
| 184 | #define FLD_IF(&fields[18]) FIELD_ADDR(fields,18)(&fields[18]) | |||
| 185 | #define FLD_RINFO(&fields[19]) FIELD_ADDR(fields,19)(&fields[19]) | |||
| 186 | #define FLD_STMAX(&fields[20]) FIELD_ADDR(fields,20)(&fields[20]) | |||
| 187 | /* other */ | |||
| 188 | #define FLD_SI(&fields[21]) FIELD_ADDR(fields,21)(&fields[21]) /* instantaneous speed */ | |||
| 189 | #define FLD_SA(&fields[22]) FIELD_ADDR(fields,22)(&fields[22]) /* average speed */ | |||
| 190 | #define FLD_SP(&fields[23]) FIELD_ADDR(fields,23)(&fields[23]) /* peak speed */ | |||
| 191 | #define FLD_ANCHOR(&fields[24]) FIELD_ADDR(fields,24)(&fields[24]) | |||
| 192 | /* for queues */ | |||
| 193 | #define FLD_QUEUE(&fields[25]) FIELD_ADDR(fields,25)(&fields[25]) | |||
| 194 | #define FLD_BANDW(&fields[26]) FIELD_ADDR(fields,26)(&fields[26]) | |||
| 195 | #define FLD_SCHED(&fields[27]) FIELD_ADDR(fields,27)(&fields[27]) | |||
| 196 | #define FLD_DROPP(&fields[28]) FIELD_ADDR(fields,28)(&fields[28]) | |||
| 197 | #define FLD_DROPB(&fields[29]) FIELD_ADDR(fields,29)(&fields[29]) | |||
| 198 | #define FLD_QLEN(&fields[30]) FIELD_ADDR(fields,30)(&fields[30]) | |||
| 199 | #define FLD_BORR(&fields[31]) FIELD_ADDR(fields,31)(&fields[31]) | |||
| 200 | #define FLD_SUSP(&fields[32]) FIELD_ADDR(fields,32)(&fields[32]) | |||
| 201 | #define FLD_PKTSPS(&fields[33]) FIELD_ADDR(fields,33)(&fields[33]) | |||
| 202 | #define FLD_BYTESPS(&fields[34]) FIELD_ADDR(fields,34)(&fields[34]) | |||
| 203 | ||||
| 204 | /* Define views */ | |||
| 205 | field_def *view0[] = { | |||
| 206 | FLD_PROTO(&fields[6]), FLD_DIR(&fields[7]), FLD_SRC(&fields[0]), FLD_DEST(&fields[1]), FLD_STATE(&fields[3]), | |||
| 207 | FLD_AGE(&fields[4]), FLD_EXP(&fields[5]), FLD_PKTS(&fields[8]), FLD_BYTES(&fields[9]), NULL((void *)0) | |||
| 208 | }; | |||
| 209 | ||||
| 210 | field_def *view1[] = { | |||
| 211 | FLD_PROTO(&fields[6]), FLD_DIR(&fields[7]), FLD_SRC(&fields[0]), FLD_DEST(&fields[1]), FLD_GW(&fields[2]), FLD_STATE(&fields[3]), FLD_AGE(&fields[4]), | |||
| 212 | FLD_EXP(&fields[5]), FLD_PKTS(&fields[8]), FLD_BYTES(&fields[9]), FLD_SI(&fields[21]), FLD_SP(&fields[23]), FLD_SA(&fields[22]), FLD_RULE(&fields[10]), NULL((void *)0) | |||
| 213 | }; | |||
| 214 | ||||
| 215 | field_def *view2[] = { | |||
| 216 | FLD_PROTO(&fields[6]), FLD_DIR(&fields[7]), FLD_SRC(&fields[0]), FLD_DEST(&fields[1]), FLD_STATE(&fields[3]), FLD_AGE(&fields[4]), FLD_EXP(&fields[5]), | |||
| 217 | FLD_PKTS(&fields[8]), FLD_BYTES(&fields[9]), FLD_SI(&fields[21]), FLD_SP(&fields[23]), FLD_SA(&fields[22]), FLD_RULE(&fields[10]), FLD_GW(&fields[2]), NULL((void *)0) | |||
| 218 | }; | |||
| 219 | ||||
| 220 | field_def *view3[] = { | |||
| 221 | FLD_PROTO(&fields[6]), FLD_DIR(&fields[7]), FLD_SRC(&fields[0]), FLD_DEST(&fields[1]), FLD_AGE(&fields[4]), FLD_EXP(&fields[5]), FLD_PKTS(&fields[8]), | |||
| 222 | FLD_BYTES(&fields[9]), FLD_STATE(&fields[3]), FLD_SI(&fields[21]), FLD_SP(&fields[23]), FLD_SA(&fields[22]), FLD_RULE(&fields[10]), FLD_GW(&fields[2]), NULL((void *)0) | |||
| 223 | }; | |||
| 224 | ||||
| 225 | field_def *view4[] = { | |||
| 226 | FLD_PROTO(&fields[6]), FLD_DIR(&fields[7]), FLD_SRC(&fields[0]), FLD_DEST(&fields[1]), FLD_PKTS(&fields[8]), FLD_BYTES(&fields[9]), FLD_STATE(&fields[3]), | |||
| 227 | FLD_AGE(&fields[4]), FLD_EXP(&fields[5]), FLD_SI(&fields[21]), FLD_SP(&fields[23]), FLD_SA(&fields[22]), FLD_RULE(&fields[10]), FLD_GW(&fields[2]), NULL((void *)0) | |||
| 228 | }; | |||
| 229 | ||||
| 230 | field_def *view5[] = { | |||
| 231 | FLD_RULE(&fields[10]), FLD_ANCHOR(&fields[24]), FLD_ACTION(&fields[14]), FLD_DIR(&fields[7]), FLD_LOG(&fields[15]), FLD_QUICK(&fields[16]), FLD_IF(&fields[18]), | |||
| 232 | FLD_PROTO(&fields[6]), FLD_KST(&fields[17]), FLD_PKTS(&fields[8]), FLD_BYTES(&fields[9]), FLD_STATS(&fields[12]), FLD_STMAX(&fields[20]), | |||
| 233 | FLD_RINFO(&fields[19]), NULL((void *)0) | |||
| 234 | }; | |||
| 235 | ||||
| 236 | field_def *view6[] = { | |||
| 237 | FLD_RULE(&fields[10]), FLD_LABEL(&fields[11]), FLD_PKTS(&fields[8]), FLD_BYTES(&fields[9]), FLD_STATS(&fields[12]), FLD_STMAX(&fields[20]), | |||
| 238 | FLD_ACTION(&fields[14]), FLD_DIR(&fields[7]), FLD_LOG(&fields[15]), FLD_QUICK(&fields[16]), FLD_IF(&fields[18]), FLD_PROTO(&fields[6]), | |||
| 239 | FLD_ANCHOR(&fields[24]), FLD_KST(&fields[17]), NULL((void *)0) | |||
| 240 | }; | |||
| 241 | ||||
| 242 | field_def *view7[] = { | |||
| 243 | FLD_PROTO(&fields[6]), FLD_DIR(&fields[7]), FLD_SRC(&fields[0]), FLD_DEST(&fields[1]), FLD_SI(&fields[21]), FLD_SP(&fields[23]), FLD_SA(&fields[22]), | |||
| 244 | FLD_BYTES(&fields[9]), FLD_STATE(&fields[3]), FLD_PKTS(&fields[8]), FLD_AGE(&fields[4]), FLD_EXP(&fields[5]), FLD_RULE(&fields[10]), FLD_GW(&fields[2]), NULL((void *)0) | |||
| 245 | }; | |||
| 246 | ||||
| 247 | field_def *view8[] = { | |||
| 248 | FLD_QUEUE(&fields[25]), FLD_BANDW(&fields[26]), FLD_SCHED(&fields[27]), FLD_PKTS(&fields[8]), FLD_BYTES(&fields[9]), | |||
| 249 | FLD_DROPP(&fields[28]), FLD_DROPB(&fields[29]), FLD_QLEN(&fields[30]), FLD_BORR(&fields[31]), FLD_SUSP(&fields[32]), FLD_PKTSPS(&fields[33]), | |||
| 250 | FLD_BYTESPS(&fields[34]), NULL((void *)0) | |||
| 251 | }; | |||
| 252 | ||||
| 253 | /* Define orderings */ | |||
| 254 | order_type order_list[] = { | |||
| 255 | {"none", "none", 'N', NULL((void *)0)}, | |||
| 256 | {"bytes", "bytes", 'B', sort_size_callback}, | |||
| 257 | {"expiry", "exp", 'E', sort_exp_callback}, | |||
| 258 | {"packets", "pkt", 'P', sort_pkt_callback}, | |||
| 259 | {"age", "age", 'A', sort_age_callback}, | |||
| 260 | {"source addr", "src", 'F', sort_sa_callback}, | |||
| 261 | {"dest. addr", "dest", 'T', sort_da_callback}, | |||
| 262 | {"source port", "sport", 'S', sort_sp_callback}, | |||
| 263 | {"dest. port", "dport", 'D', sort_dp_callback}, | |||
| 264 | {"rate", "rate", 'R', sort_rate_callback}, | |||
| 265 | {"peak", "peak", 'K', sort_peak_callback}, | |||
| 266 | {NULL((void *)0), NULL((void *)0), 0, NULL((void *)0)} | |||
| 267 | }; | |||
| 268 | ||||
| 269 | /* Define view managers */ | |||
| 270 | struct view_manager state_mgr = { | |||
| 271 | "States", select_states, read_states, sort_states, print_header, | |||
| 272 | print_states, keyboard_callback, order_list, order_list | |||
| 273 | }; | |||
| 274 | ||||
| 275 | struct view_manager rule_mgr = { | |||
| 276 | "Rules", select_rules, read_rules, NULL((void *)0), print_header, | |||
| 277 | print_rules, keyboard_callback, NULL((void *)0), NULL((void *)0) | |||
| 278 | }; | |||
| 279 | ||||
| 280 | struct view_manager queue_mgr = { | |||
| 281 | "Queues", select_queues, read_queues, NULL((void *)0), print_header, | |||
| 282 | print_queues, keyboard_callback, NULL((void *)0), NULL((void *)0) | |||
| 283 | }; | |||
| 284 | ||||
| 285 | field_view views[] = { | |||
| 286 | {view2, "states", '8', &state_mgr}, | |||
| 287 | {view5, "rules", '9', &rule_mgr}, | |||
| 288 | {view8, "queues", 'Q', &queue_mgr}, | |||
| 289 | {NULL((void *)0), NULL((void *)0), 0, NULL((void *)0)} | |||
| 290 | }; | |||
| 291 | ||||
| 292 | /* queue structures from pfctl */ | |||
| 293 | ||||
| 294 | struct queue_stats { | |||
| 295 | struct hfsc_class_stats data; | |||
| 296 | int valid; | |||
| 297 | struct timeval timestamp; | |||
| 298 | }; | |||
| 299 | ||||
| 300 | struct pfctl_queue_node { | |||
| 301 | TAILQ_ENTRY(pfctl_queue_node)struct { struct pfctl_queue_node *tqe_next; struct pfctl_queue_node **tqe_prev; } entries; | |||
| 302 | struct pf_queuespec qs; | |||
| 303 | struct queue_stats qstats; | |||
| 304 | struct queue_stats qstats_last; | |||
| 305 | int depth; | |||
| 306 | }; | |||
| 307 | TAILQ_HEAD(qnodes, pfctl_queue_node)struct qnodes { struct pfctl_queue_node *tqh_first; struct pfctl_queue_node **tqh_last; } qnodes = TAILQ_HEAD_INITIALIZER(qnodes){ ((void *)0), &(qnodes).tqh_first }; | |||
| 308 | ||||
| 309 | /* ordering functions */ | |||
| 310 | ||||
| 311 | int | |||
| 312 | sort_size_callback(const void *s1, const void *s2) | |||
| 313 | { | |||
| 314 | u_int64_t b1 = COUNTER(state_buf[* (size_t *) s1].bytes[0])((((u_int64_t) (__uint32_t)(__builtin_constant_p(state_buf[* ( size_t *) s1].bytes[0][0]) ? (__uint32_t)(((__uint32_t)(state_buf [* (size_t *) s1].bytes[0][0]) & 0xff) << 24 | ((__uint32_t )(state_buf[* (size_t *) s1].bytes[0][0]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s1].bytes[0][0]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s1 ].bytes[0][0]) & 0xff000000) >> 24) : __swap32md(state_buf [* (size_t *) s1].bytes[0][0])))<<32) + (__uint32_t)(__builtin_constant_p (state_buf[* (size_t *) s1].bytes[0][1]) ? (__uint32_t)(((__uint32_t )(state_buf[* (size_t *) s1].bytes[0][1]) & 0xff) << 24 | ((__uint32_t)(state_buf[* (size_t *) s1].bytes[0][1]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s1 ].bytes[0][1]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf [* (size_t *) s1].bytes[0][1]) & 0xff000000) >> 24) : __swap32md(state_buf[* (size_t *) s1].bytes[0][1]))) + | |||
| 315 | COUNTER(state_buf[* (size_t *) s1].bytes[1])((((u_int64_t) (__uint32_t)(__builtin_constant_p(state_buf[* ( size_t *) s1].bytes[1][0]) ? (__uint32_t)(((__uint32_t)(state_buf [* (size_t *) s1].bytes[1][0]) & 0xff) << 24 | ((__uint32_t )(state_buf[* (size_t *) s1].bytes[1][0]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s1].bytes[1][0]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s1 ].bytes[1][0]) & 0xff000000) >> 24) : __swap32md(state_buf [* (size_t *) s1].bytes[1][0])))<<32) + (__uint32_t)(__builtin_constant_p (state_buf[* (size_t *) s1].bytes[1][1]) ? (__uint32_t)(((__uint32_t )(state_buf[* (size_t *) s1].bytes[1][1]) & 0xff) << 24 | ((__uint32_t)(state_buf[* (size_t *) s1].bytes[1][1]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s1 ].bytes[1][1]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf [* (size_t *) s1].bytes[1][1]) & 0xff000000) >> 24) : __swap32md(state_buf[* (size_t *) s1].bytes[1][1]))); | |||
| 316 | u_int64_t b2 = COUNTER(state_buf[* (size_t *) s2].bytes[0])((((u_int64_t) (__uint32_t)(__builtin_constant_p(state_buf[* ( size_t *) s2].bytes[0][0]) ? (__uint32_t)(((__uint32_t)(state_buf [* (size_t *) s2].bytes[0][0]) & 0xff) << 24 | ((__uint32_t )(state_buf[* (size_t *) s2].bytes[0][0]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s2].bytes[0][0]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s2 ].bytes[0][0]) & 0xff000000) >> 24) : __swap32md(state_buf [* (size_t *) s2].bytes[0][0])))<<32) + (__uint32_t)(__builtin_constant_p (state_buf[* (size_t *) s2].bytes[0][1]) ? (__uint32_t)(((__uint32_t )(state_buf[* (size_t *) s2].bytes[0][1]) & 0xff) << 24 | ((__uint32_t)(state_buf[* (size_t *) s2].bytes[0][1]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s2 ].bytes[0][1]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf [* (size_t *) s2].bytes[0][1]) & 0xff000000) >> 24) : __swap32md(state_buf[* (size_t *) s2].bytes[0][1]))) + | |||
| 317 | COUNTER(state_buf[* (size_t *) s2].bytes[1])((((u_int64_t) (__uint32_t)(__builtin_constant_p(state_buf[* ( size_t *) s2].bytes[1][0]) ? (__uint32_t)(((__uint32_t)(state_buf [* (size_t *) s2].bytes[1][0]) & 0xff) << 24 | ((__uint32_t )(state_buf[* (size_t *) s2].bytes[1][0]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s2].bytes[1][0]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s2 ].bytes[1][0]) & 0xff000000) >> 24) : __swap32md(state_buf [* (size_t *) s2].bytes[1][0])))<<32) + (__uint32_t)(__builtin_constant_p (state_buf[* (size_t *) s2].bytes[1][1]) ? (__uint32_t)(((__uint32_t )(state_buf[* (size_t *) s2].bytes[1][1]) & 0xff) << 24 | ((__uint32_t)(state_buf[* (size_t *) s2].bytes[1][1]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s2 ].bytes[1][1]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf [* (size_t *) s2].bytes[1][1]) & 0xff000000) >> 24) : __swap32md(state_buf[* (size_t *) s2].bytes[1][1]))); | |||
| 318 | if (b2 > b1) | |||
| 319 | return sortdir; | |||
| 320 | if (b2 < b1) | |||
| 321 | return -sortdir; | |||
| 322 | return 0; | |||
| 323 | } | |||
| 324 | ||||
| 325 | int | |||
| 326 | sort_pkt_callback(const void *s1, const void *s2) | |||
| 327 | { | |||
| 328 | u_int64_t p1 = COUNTER(state_buf[* (size_t *) s1].packets[0])((((u_int64_t) (__uint32_t)(__builtin_constant_p(state_buf[* ( size_t *) s1].packets[0][0]) ? (__uint32_t)(((__uint32_t)(state_buf [* (size_t *) s1].packets[0][0]) & 0xff) << 24 | (( __uint32_t)(state_buf[* (size_t *) s1].packets[0][0]) & 0xff00 ) << 8 | ((__uint32_t)(state_buf[* (size_t *) s1].packets [0][0]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[ * (size_t *) s1].packets[0][0]) & 0xff000000) >> 24 ) : __swap32md(state_buf[* (size_t *) s1].packets[0][0])))<< 32) + (__uint32_t)(__builtin_constant_p(state_buf[* (size_t * ) s1].packets[0][1]) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s1].packets[0][1]) & 0xff) << 24 | ((__uint32_t )(state_buf[* (size_t *) s1].packets[0][1]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s1].packets[0][1]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s1 ].packets[0][1]) & 0xff000000) >> 24) : __swap32md( state_buf[* (size_t *) s1].packets[0][1]))) + | |||
| 329 | COUNTER(state_buf[* (size_t *) s1].packets[1])((((u_int64_t) (__uint32_t)(__builtin_constant_p(state_buf[* ( size_t *) s1].packets[1][0]) ? (__uint32_t)(((__uint32_t)(state_buf [* (size_t *) s1].packets[1][0]) & 0xff) << 24 | (( __uint32_t)(state_buf[* (size_t *) s1].packets[1][0]) & 0xff00 ) << 8 | ((__uint32_t)(state_buf[* (size_t *) s1].packets [1][0]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[ * (size_t *) s1].packets[1][0]) & 0xff000000) >> 24 ) : __swap32md(state_buf[* (size_t *) s1].packets[1][0])))<< 32) + (__uint32_t)(__builtin_constant_p(state_buf[* (size_t * ) s1].packets[1][1]) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s1].packets[1][1]) & 0xff) << 24 | ((__uint32_t )(state_buf[* (size_t *) s1].packets[1][1]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s1].packets[1][1]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s1 ].packets[1][1]) & 0xff000000) >> 24) : __swap32md( state_buf[* (size_t *) s1].packets[1][1]))); | |||
| 330 | u_int64_t p2 = COUNTER(state_buf[* (size_t *) s2].packets[0])((((u_int64_t) (__uint32_t)(__builtin_constant_p(state_buf[* ( size_t *) s2].packets[0][0]) ? (__uint32_t)(((__uint32_t)(state_buf [* (size_t *) s2].packets[0][0]) & 0xff) << 24 | (( __uint32_t)(state_buf[* (size_t *) s2].packets[0][0]) & 0xff00 ) << 8 | ((__uint32_t)(state_buf[* (size_t *) s2].packets [0][0]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[ * (size_t *) s2].packets[0][0]) & 0xff000000) >> 24 ) : __swap32md(state_buf[* (size_t *) s2].packets[0][0])))<< 32) + (__uint32_t)(__builtin_constant_p(state_buf[* (size_t * ) s2].packets[0][1]) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s2].packets[0][1]) & 0xff) << 24 | ((__uint32_t )(state_buf[* (size_t *) s2].packets[0][1]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s2].packets[0][1]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s2 ].packets[0][1]) & 0xff000000) >> 24) : __swap32md( state_buf[* (size_t *) s2].packets[0][1]))) + | |||
| 331 | COUNTER(state_buf[* (size_t *) s2].packets[1])((((u_int64_t) (__uint32_t)(__builtin_constant_p(state_buf[* ( size_t *) s2].packets[1][0]) ? (__uint32_t)(((__uint32_t)(state_buf [* (size_t *) s2].packets[1][0]) & 0xff) << 24 | (( __uint32_t)(state_buf[* (size_t *) s2].packets[1][0]) & 0xff00 ) << 8 | ((__uint32_t)(state_buf[* (size_t *) s2].packets [1][0]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[ * (size_t *) s2].packets[1][0]) & 0xff000000) >> 24 ) : __swap32md(state_buf[* (size_t *) s2].packets[1][0])))<< 32) + (__uint32_t)(__builtin_constant_p(state_buf[* (size_t * ) s2].packets[1][1]) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s2].packets[1][1]) & 0xff) << 24 | ((__uint32_t )(state_buf[* (size_t *) s2].packets[1][1]) & 0xff00) << 8 | ((__uint32_t)(state_buf[* (size_t *) s2].packets[1][1]) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s2 ].packets[1][1]) & 0xff000000) >> 24) : __swap32md( state_buf[* (size_t *) s2].packets[1][1]))); | |||
| 332 | if (p2 > p1) | |||
| 333 | return sortdir; | |||
| 334 | if (p2 < p1) | |||
| 335 | return -sortdir; | |||
| 336 | return 0; | |||
| 337 | } | |||
| 338 | ||||
| 339 | int | |||
| 340 | sort_age_callback(const void *s1, const void *s2) | |||
| 341 | { | |||
| 342 | if (ntohl(state_buf[* (size_t *) s2].creation)(__uint32_t)(__builtin_constant_p(state_buf[* (size_t *) s2]. creation) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s2].creation) & 0xff) << 24 | ((__uint32_t)(state_buf [* (size_t *) s2].creation) & 0xff00) << 8 | ((__uint32_t )(state_buf[* (size_t *) s2].creation) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s2].creation) & 0xff000000) >> 24) : __swap32md(state_buf[* (size_t *) s2].creation)) > | |||
| 343 | ntohl(state_buf[* (size_t *) s1].creation)(__uint32_t)(__builtin_constant_p(state_buf[* (size_t *) s1]. creation) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s1].creation) & 0xff) << 24 | ((__uint32_t)(state_buf [* (size_t *) s1].creation) & 0xff00) << 8 | ((__uint32_t )(state_buf[* (size_t *) s1].creation) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s1].creation) & 0xff000000) >> 24) : __swap32md(state_buf[* (size_t *) s1].creation))) | |||
| 344 | return sortdir; | |||
| 345 | if (ntohl(state_buf[* (size_t *) s2].creation)(__uint32_t)(__builtin_constant_p(state_buf[* (size_t *) s2]. creation) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s2].creation) & 0xff) << 24 | ((__uint32_t)(state_buf [* (size_t *) s2].creation) & 0xff00) << 8 | ((__uint32_t )(state_buf[* (size_t *) s2].creation) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s2].creation) & 0xff000000) >> 24) : __swap32md(state_buf[* (size_t *) s2].creation)) < | |||
| 346 | ntohl(state_buf[* (size_t *) s1].creation)(__uint32_t)(__builtin_constant_p(state_buf[* (size_t *) s1]. creation) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s1].creation) & 0xff) << 24 | ((__uint32_t)(state_buf [* (size_t *) s1].creation) & 0xff00) << 8 | ((__uint32_t )(state_buf[* (size_t *) s1].creation) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s1].creation) & 0xff000000) >> 24) : __swap32md(state_buf[* (size_t *) s1].creation))) | |||
| 347 | return -sortdir; | |||
| 348 | return 0; | |||
| 349 | } | |||
| 350 | ||||
| 351 | int | |||
| 352 | sort_exp_callback(const void *s1, const void *s2) | |||
| 353 | { | |||
| 354 | if (ntohl(state_buf[* (size_t *) s2].expire)(__uint32_t)(__builtin_constant_p(state_buf[* (size_t *) s2]. expire) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s2 ].expire) & 0xff) << 24 | ((__uint32_t)(state_buf[* (size_t *) s2].expire) & 0xff00) << 8 | ((__uint32_t )(state_buf[* (size_t *) s2].expire) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s2].expire) & 0xff000000 ) >> 24) : __swap32md(state_buf[* (size_t *) s2].expire )) > | |||
| 355 | ntohl(state_buf[* (size_t *) s1].expire)(__uint32_t)(__builtin_constant_p(state_buf[* (size_t *) s1]. expire) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s1 ].expire) & 0xff) << 24 | ((__uint32_t)(state_buf[* (size_t *) s1].expire) & 0xff00) << 8 | ((__uint32_t )(state_buf[* (size_t *) s1].expire) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s1].expire) & 0xff000000 ) >> 24) : __swap32md(state_buf[* (size_t *) s1].expire ))) | |||
| 356 | return sortdir; | |||
| 357 | if (ntohl(state_buf[* (size_t *) s2].expire)(__uint32_t)(__builtin_constant_p(state_buf[* (size_t *) s2]. expire) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s2 ].expire) & 0xff) << 24 | ((__uint32_t)(state_buf[* (size_t *) s2].expire) & 0xff00) << 8 | ((__uint32_t )(state_buf[* (size_t *) s2].expire) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s2].expire) & 0xff000000 ) >> 24) : __swap32md(state_buf[* (size_t *) s2].expire )) < | |||
| 358 | ntohl(state_buf[* (size_t *) s1].expire)(__uint32_t)(__builtin_constant_p(state_buf[* (size_t *) s1]. expire) ? (__uint32_t)(((__uint32_t)(state_buf[* (size_t *) s1 ].expire) & 0xff) << 24 | ((__uint32_t)(state_buf[* (size_t *) s1].expire) & 0xff00) << 8 | ((__uint32_t )(state_buf[* (size_t *) s1].expire) & 0xff0000) >> 8 | ((__uint32_t)(state_buf[* (size_t *) s1].expire) & 0xff000000 ) >> 24) : __swap32md(state_buf[* (size_t *) s1].expire ))) | |||
| 359 | return -sortdir; | |||
| 360 | return 0; | |||
| 361 | } | |||
| 362 | ||||
| 363 | int | |||
| 364 | sort_rate_callback(const void *s1, const void *s2) | |||
| 365 | { | |||
| 366 | struct sc_ent *e1 = state_cache[* (u_int32_t *) s1]; | |||
| 367 | struct sc_ent *e2 = state_cache[* (u_int32_t *) s2]; | |||
| 368 | ||||
| 369 | if (e1 == NULL((void *)0)) | |||
| 370 | return sortdir; | |||
| 371 | if (e2 == NULL((void *)0)) | |||
| 372 | return -sortdir; | |||
| 373 | ||||
| 374 | if (e2->rate > e1 -> rate) | |||
| 375 | return sortdir; | |||
| 376 | if (e2->rate < e1 -> rate) | |||
| 377 | return -sortdir; | |||
| 378 | return 0; | |||
| 379 | } | |||
| 380 | ||||
| 381 | int | |||
| 382 | sort_peak_callback(const void *s1, const void *s2) | |||
| 383 | { | |||
| 384 | struct sc_ent *e1 = state_cache[* (u_int32_t *) s1]; | |||
| 385 | struct sc_ent *e2 = state_cache[* (u_int32_t *) s2]; | |||
| 386 | ||||
| 387 | if (e2 == NULL((void *)0)) | |||
| 388 | return -sortdir; | |||
| 389 | if (e1 == NULL((void *)0) || e2 == NULL((void *)0)) | |||
| 390 | return 0; | |||
| 391 | ||||
| 392 | if (e2->peak > e1 -> peak) | |||
| 393 | return sortdir; | |||
| 394 | if (e2->peak < e1 -> peak) | |||
| 395 | return -sortdir; | |||
| 396 | return 0; | |||
| 397 | } | |||
| 398 | ||||
| 399 | int | |||
| 400 | compare_addr(int af, const struct pf_addr *a, const struct pf_addr *b) | |||
| 401 | { | |||
| 402 | switch (af) { | |||
| 403 | case AF_INET2: | |||
| 404 | if (ntohl(a->addr32[0])(__uint32_t)(__builtin_constant_p(a->pfa.addr32[0]) ? (__uint32_t )(((__uint32_t)(a->pfa.addr32[0]) & 0xff) << 24 | ((__uint32_t)(a->pfa.addr32[0]) & 0xff00) << 8 | ((__uint32_t)(a->pfa.addr32[0]) & 0xff0000) >> 8 | ((__uint32_t)(a->pfa.addr32[0]) & 0xff000000) >> 24) : __swap32md(a->pfa.addr32[0])) > ntohl(b->addr32[0])(__uint32_t)(__builtin_constant_p(b->pfa.addr32[0]) ? (__uint32_t )(((__uint32_t)(b->pfa.addr32[0]) & 0xff) << 24 | ((__uint32_t)(b->pfa.addr32[0]) & 0xff00) << 8 | ((__uint32_t)(b->pfa.addr32[0]) & 0xff0000) >> 8 | ((__uint32_t)(b->pfa.addr32[0]) & 0xff000000) >> 24) : __swap32md(b->pfa.addr32[0]))) | |||
| 405 | return 1; | |||
| 406 | if (a->addr32pfa.addr32[0] != b->addr32pfa.addr32[0]) | |||
| 407 | return -1; | |||
| 408 | break; | |||
| 409 | case AF_INET624: | |||
| 410 | if (ntohl(a->addr32[0])(__uint32_t)(__builtin_constant_p(a->pfa.addr32[0]) ? (__uint32_t )(((__uint32_t)(a->pfa.addr32[0]) & 0xff) << 24 | ((__uint32_t)(a->pfa.addr32[0]) & 0xff00) << 8 | ((__uint32_t)(a->pfa.addr32[0]) & 0xff0000) >> 8 | ((__uint32_t)(a->pfa.addr32[0]) & 0xff000000) >> 24) : __swap32md(a->pfa.addr32[0])) > ntohl(b->addr32[0])(__uint32_t)(__builtin_constant_p(b->pfa.addr32[0]) ? (__uint32_t )(((__uint32_t)(b->pfa.addr32[0]) & 0xff) << 24 | ((__uint32_t)(b->pfa.addr32[0]) & 0xff00) << 8 | ((__uint32_t)(b->pfa.addr32[0]) & 0xff0000) >> 8 | ((__uint32_t)(b->pfa.addr32[0]) & 0xff000000) >> 24) : __swap32md(b->pfa.addr32[0]))) | |||
| 411 | return 1; | |||
| 412 | if (a->addr32pfa.addr32[0] != b->addr32pfa.addr32[0]) | |||
| 413 | return -1; | |||
| 414 | if (ntohl(a->addr32[1])(__uint32_t)(__builtin_constant_p(a->pfa.addr32[1]) ? (__uint32_t )(((__uint32_t)(a->pfa.addr32[1]) & 0xff) << 24 | ((__uint32_t)(a->pfa.addr32[1]) & 0xff00) << 8 | ((__uint32_t)(a->pfa.addr32[1]) & 0xff0000) >> 8 | ((__uint32_t)(a->pfa.addr32[1]) & 0xff000000) >> 24) : __swap32md(a->pfa.addr32[1])) > ntohl(b->addr32[1])(__uint32_t)(__builtin_constant_p(b->pfa.addr32[1]) ? (__uint32_t )(((__uint32_t)(b->pfa.addr32[1]) & 0xff) << 24 | ((__uint32_t)(b->pfa.addr32[1]) & 0xff00) << 8 | ((__uint32_t)(b->pfa.addr32[1]) & 0xff0000) >> 8 | ((__uint32_t)(b->pfa.addr32[1]) & 0xff000000) >> 24) : __swap32md(b->pfa.addr32[1]))) | |||
| 415 | return 1; | |||
| 416 | if (a->addr32pfa.addr32[1] != b->addr32pfa.addr32[1]) | |||
| 417 | return -1; | |||
| 418 | if (ntohl(a->addr32[2])(__uint32_t)(__builtin_constant_p(a->pfa.addr32[2]) ? (__uint32_t )(((__uint32_t)(a->pfa.addr32[2]) & 0xff) << 24 | ((__uint32_t)(a->pfa.addr32[2]) & 0xff00) << 8 | ((__uint32_t)(a->pfa.addr32[2]) & 0xff0000) >> 8 | ((__uint32_t)(a->pfa.addr32[2]) & 0xff000000) >> 24) : __swap32md(a->pfa.addr32[2])) > ntohl(b->addr32[2])(__uint32_t)(__builtin_constant_p(b->pfa.addr32[2]) ? (__uint32_t )(((__uint32_t)(b->pfa.addr32[2]) & 0xff) << 24 | ((__uint32_t)(b->pfa.addr32[2]) & 0xff00) << 8 | ((__uint32_t)(b->pfa.addr32[2]) & 0xff0000) >> 8 | ((__uint32_t)(b->pfa.addr32[2]) & 0xff000000) >> 24) : __swap32md(b->pfa.addr32[2]))) | |||
| 419 | return 1; | |||
| 420 | if (a->addr32pfa.addr32[2] != b->addr32pfa.addr32[2]) | |||
| 421 | return -1; | |||
| 422 | if (ntohl(a->addr32[3])(__uint32_t)(__builtin_constant_p(a->pfa.addr32[3]) ? (__uint32_t )(((__uint32_t)(a->pfa.addr32[3]) & 0xff) << 24 | ((__uint32_t)(a->pfa.addr32[3]) & 0xff00) << 8 | ((__uint32_t)(a->pfa.addr32[3]) & 0xff0000) >> 8 | ((__uint32_t)(a->pfa.addr32[3]) & 0xff000000) >> 24) : __swap32md(a->pfa.addr32[3])) > ntohl(b->addr32[3])(__uint32_t)(__builtin_constant_p(b->pfa.addr32[3]) ? (__uint32_t )(((__uint32_t)(b->pfa.addr32[3]) & 0xff) << 24 | ((__uint32_t)(b->pfa.addr32[3]) & 0xff00) << 8 | ((__uint32_t)(b->pfa.addr32[3]) & 0xff0000) >> 8 | ((__uint32_t)(b->pfa.addr32[3]) & 0xff000000) >> 24) : __swap32md(b->pfa.addr32[3]))) | |||
| 423 | return 1; | |||
| 424 | if (a->addr32pfa.addr32[3] != b->addr32pfa.addr32[3]) | |||
| 425 | return -1; | |||
| 426 | break; | |||
| 427 | } | |||
| 428 | ||||
| 429 | return 0; | |||
| 430 | } | |||
| 431 | ||||
| 432 | static __inline int | |||
| 433 | sort_addr_callback(const struct pfsync_state *s1, | |||
| 434 | const struct pfsync_state *s2, int dir) | |||
| 435 | { | |||
| 436 | const struct pf_addr *aa, *ab; | |||
| 437 | u_int16_t pa, pb; | |||
| 438 | int af, side, ret, ii, io; | |||
| 439 | ||||
| 440 | side = s1->direction == PF_IN ? PF_SK_STACK : PF_SK_WIRE; | |||
| 441 | ||||
| 442 | if (s1->key[side].af > s2->key[side].af) | |||
| 443 | return sortdir; | |||
| 444 | if (s1->key[side].af < s2->key[side].af) | |||
| 445 | return -sortdir; | |||
| 446 | ||||
| 447 | ii = io = 0; | |||
| 448 | ||||
| 449 | if (dir == PF_OUT) /* looking for source addr */ | |||
| 450 | io = 1; | |||
| 451 | else /* looking for dest addr */ | |||
| 452 | ii = 1; | |||
| 453 | ||||
| 454 | if (s1->key[PF_SK_STACK].af != s1->key[PF_SK_WIRE].af) { | |||
| 455 | dir = PF_OUT; | |||
| 456 | side = PF_SK_STACK; | |||
| 457 | } else { | |||
| 458 | dir = s1->direction; | |||
| 459 | side = PF_SK_WIRE; | |||
| 460 | } | |||
| 461 | ||||
| 462 | if (dir == PF_IN) { | |||
| 463 | aa = &s1->key[PF_SK_STACK].addr[ii]; | |||
| 464 | pa = s1->key[PF_SK_STACK].port[ii]; | |||
| 465 | af = s1->key[PF_SK_STACK].af; | |||
| 466 | } else { | |||
| 467 | aa = &s1->key[side].addr[io]; | |||
| 468 | pa = s1->key[side].port[io]; | |||
| 469 | af = s1->key[side].af; | |||
| 470 | } | |||
| 471 | ||||
| 472 | if (s2->key[PF_SK_STACK].af != s2->key[PF_SK_WIRE].af) { | |||
| 473 | dir = PF_OUT; | |||
| 474 | side = PF_SK_STACK; | |||
| 475 | } else { | |||
| 476 | dir = s2->direction; | |||
| 477 | side = PF_SK_WIRE; | |||
| 478 | } | |||
| 479 | ||||
| 480 | if (dir == PF_IN) { | |||
| 481 | ab = &s2->key[PF_SK_STACK].addr[ii]; | |||
| 482 | pb = s2->key[PF_SK_STACK].port[ii]; | |||
| 483 | af = s1->key[PF_SK_STACK].af; | |||
| 484 | } else { | |||
| 485 | ab = &s2->key[side].addr[io]; | |||
| 486 | pb = s2->key[side].port[io]; | |||
| 487 | af = s1->key[side].af; | |||
| 488 | } | |||
| 489 | ||||
| 490 | ret = compare_addr(af, aa, ab); | |||
| 491 | if (ret) | |||
| 492 | return ret * sortdir; | |||
| 493 | ||||
| 494 | if (ntohs(pa)(__uint16_t)(__builtin_constant_p(pa) ? (__uint16_t)(((__uint16_t )(pa) & 0xffU) << 8 | ((__uint16_t)(pa) & 0xff00U ) >> 8) : __swap16md(pa)) > ntohs(pb)(__uint16_t)(__builtin_constant_p(pb) ? (__uint16_t)(((__uint16_t )(pb) & 0xffU) << 8 | ((__uint16_t)(pb) & 0xff00U ) >> 8) : __swap16md(pb))) | |||
| 495 | return sortdir; | |||
| 496 | return -sortdir; | |||
| 497 | } | |||
| 498 | ||||
| 499 | static __inline int | |||
| 500 | sort_port_callback(const struct pfsync_state *s1, | |||
| 501 | const struct pfsync_state *s2, int dir) | |||
| 502 | { | |||
| 503 | const struct pf_addr *aa, *ab; | |||
| 504 | u_int16_t pa, pb; | |||
| 505 | int af, side, ret, ii, io; | |||
| 506 | ||||
| 507 | side = s1->direction == PF_IN ? PF_SK_STACK : PF_SK_WIRE; | |||
| 508 | ||||
| 509 | if (s1->key[side].af > s2->key[side].af) | |||
| 510 | return sortdir; | |||
| 511 | if (s1->key[side].af < s2->key[side].af) | |||
| 512 | return -sortdir; | |||
| 513 | ||||
| 514 | ii = io = 0; | |||
| 515 | ||||
| 516 | if (dir == PF_OUT) /* looking for source addr */ | |||
| 517 | io = 1; | |||
| 518 | else /* looking for dest addr */ | |||
| 519 | ii = 1; | |||
| 520 | ||||
| 521 | if (s1->key[PF_SK_STACK].af != s1->key[PF_SK_WIRE].af) { | |||
| 522 | dir = PF_OUT; | |||
| 523 | side = PF_SK_STACK; | |||
| 524 | } else { | |||
| 525 | dir = s1->direction; | |||
| 526 | side = PF_SK_WIRE; | |||
| 527 | } | |||
| 528 | ||||
| 529 | if (dir == PF_IN) { | |||
| 530 | aa = &s1->key[PF_SK_STACK].addr[ii]; | |||
| 531 | pa = s1->key[PF_SK_STACK].port[ii]; | |||
| 532 | af = s1->key[PF_SK_STACK].af; | |||
| 533 | } else { | |||
| 534 | aa = &s1->key[side].addr[io]; | |||
| 535 | pa = s1->key[side].port[io]; | |||
| 536 | af = s1->key[side].af; | |||
| 537 | } | |||
| 538 | ||||
| 539 | if (s2->key[PF_SK_STACK].af != s2->key[PF_SK_WIRE].af) { | |||
| 540 | dir = PF_OUT; | |||
| 541 | side = PF_SK_STACK; | |||
| 542 | } else { | |||
| 543 | dir = s2->direction; | |||
| 544 | side = PF_SK_WIRE; | |||
| 545 | } | |||
| 546 | ||||
| 547 | if (dir == PF_IN) { | |||
| 548 | ab = &s2->key[PF_SK_STACK].addr[ii]; | |||
| 549 | pb = s2->key[PF_SK_STACK].port[ii]; | |||
| 550 | af = s1->key[PF_SK_STACK].af; | |||
| 551 | } else { | |||
| 552 | ab = &s2->key[side].addr[io]; | |||
| 553 | pb = s2->key[side].port[io]; | |||
| 554 | af = s1->key[side].af; | |||
| 555 | } | |||
| 556 | ||||
| 557 | ||||
| 558 | if (ntohs(pa)(__uint16_t)(__builtin_constant_p(pa) ? (__uint16_t)(((__uint16_t )(pa) & 0xffU) << 8 | ((__uint16_t)(pa) & 0xff00U ) >> 8) : __swap16md(pa)) > ntohs(pb)(__uint16_t)(__builtin_constant_p(pb) ? (__uint16_t)(((__uint16_t )(pb) & 0xffU) << 8 | ((__uint16_t)(pb) & 0xff00U ) >> 8) : __swap16md(pb))) | |||
| 559 | return sortdir; | |||
| 560 | if (ntohs(pa)(__uint16_t)(__builtin_constant_p(pa) ? (__uint16_t)(((__uint16_t )(pa) & 0xffU) << 8 | ((__uint16_t)(pa) & 0xff00U ) >> 8) : __swap16md(pa)) < ntohs(pb)(__uint16_t)(__builtin_constant_p(pb) ? (__uint16_t)(((__uint16_t )(pb) & 0xffU) << 8 | ((__uint16_t)(pb) & 0xff00U ) >> 8) : __swap16md(pb))) | |||
| 561 | return - sortdir; | |||
| 562 | ||||
| 563 | ret = compare_addr(af, aa, ab); | |||
| 564 | if (ret) | |||
| 565 | return ret * sortdir; | |||
| 566 | return -sortdir; | |||
| 567 | } | |||
| 568 | ||||
| 569 | int | |||
| 570 | sort_sa_callback(const void *p1, const void *p2) | |||
| 571 | { | |||
| 572 | struct pfsync_state *s1 = state_buf + (* (size_t *) p1); | |||
| 573 | struct pfsync_state *s2 = state_buf + (* (size_t *) p2); | |||
| 574 | return sort_addr_callback(s1, s2, PF_OUT); | |||
| 575 | } | |||
| 576 | ||||
| 577 | int | |||
| 578 | sort_da_callback(const void *p1, const void *p2) | |||
| 579 | { | |||
| 580 | struct pfsync_state *s1 = state_buf + (* (size_t *) p1); | |||
| 581 | struct pfsync_state *s2 = state_buf + (* (size_t *) p2); | |||
| 582 | return sort_addr_callback(s1, s2, PF_IN); | |||
| 583 | } | |||
| 584 | ||||
| 585 | int | |||
| 586 | sort_sp_callback(const void *p1, const void *p2) | |||
| 587 | { | |||
| 588 | struct pfsync_state *s1 = state_buf + (* (size_t *) p1); | |||
| 589 | struct pfsync_state *s2 = state_buf + (* (size_t *) p2); | |||
| 590 | return sort_port_callback(s1, s2, PF_OUT); | |||
| 591 | } | |||
| 592 | ||||
| 593 | int | |||
| 594 | sort_dp_callback(const void *p1, const void *p2) | |||
| 595 | { | |||
| 596 | struct pfsync_state *s1 = state_buf + (* (size_t *) p1); | |||
| 597 | struct pfsync_state *s2 = state_buf + (* (size_t *) p2); | |||
| 598 | return sort_port_callback(s1, s2, PF_IN); | |||
| 599 | } | |||
| 600 | ||||
| 601 | void | |||
| 602 | sort_states(void) | |||
| 603 | { | |||
| 604 | order_type *ordering; | |||
| 605 | ||||
| 606 | if (curr_mgr == NULL((void *)0)) | |||
| 607 | return; | |||
| 608 | ||||
| 609 | ordering = curr_mgr->order_curr; | |||
| 610 | ||||
| 611 | if (ordering == NULL((void *)0)) | |||
| 612 | return; | |||
| 613 | if (ordering->func == NULL((void *)0)) | |||
| 614 | return; | |||
| 615 | if (state_buf == NULL((void *)0)) | |||
| 616 | return; | |||
| 617 | if (num_states <= 0) | |||
| 618 | return; | |||
| 619 | ||||
| 620 | mergesort(state_ord, num_states, sizeof(size_t), ordering->func); | |||
| 621 | } | |||
| 622 | ||||
| 623 | /* state management functions */ | |||
| 624 | ||||
| 625 | void | |||
| 626 | alloc_buf(size_t ns) | |||
| 627 | { | |||
| 628 | size_t len; | |||
| 629 | ||||
| 630 | if (ns < MIN_NUM_STATES1024) | |||
| 631 | ns = MIN_NUM_STATES1024; | |||
| 632 | ||||
| 633 | len = ns; | |||
| 634 | ||||
| 635 | if (len >= state_buf_len) { | |||
| 636 | len += NUM_STATE_INC1024; | |||
| 637 | state_buf = reallocarray(state_buf, len, | |||
| 638 | sizeof(struct pfsync_state)); | |||
| 639 | state_ord = reallocarray(state_ord, len, sizeof(size_t)); | |||
| 640 | state_cache = reallocarray(state_cache, len, | |||
| 641 | sizeof(struct sc_ent *)); | |||
| 642 | if (state_buf == NULL((void *)0) || state_ord == NULL((void *)0) || | |||
| 643 | state_cache == NULL((void *)0)) | |||
| 644 | err(1, "realloc"); | |||
| 645 | state_buf_len = len; | |||
| 646 | } | |||
| 647 | } | |||
| 648 | ||||
| 649 | int | |||
| 650 | select_states(void) | |||
| 651 | { | |||
| 652 | num_disp = num_states; | |||
| 653 | return (0); | |||
| 654 | } | |||
| 655 | ||||
| 656 | int | |||
| 657 | read_states(void) | |||
| 658 | { | |||
| 659 | struct pfioc_states ps; | |||
| 660 | size_t n; | |||
| 661 | ||||
| 662 | if (pf_dev == -1) | |||
| 663 | return -1; | |||
| 664 | ||||
| 665 | for (;;) { | |||
| 666 | size_t sbytes = state_buf_len * sizeof(struct pfsync_state); | |||
| 667 | ||||
| 668 | ps.ps_len = sbytes; | |||
| 669 | ps.ps_statesps_u.psu_states = state_buf; | |||
| 670 | ||||
| 671 | if (ioctl(pf_dev, DIOCGETSTATES(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_states) & 0x1fff) << 16) | ((('D')) << 8) | ((25))), &ps) == -1) { | |||
| 672 | error("DIOCGETSTATES"); | |||
| 673 | } | |||
| 674 | num_states_all = ps.ps_len / sizeof(struct pfsync_state); | |||
| 675 | ||||
| 676 | if (ps.ps_len < sbytes) | |||
| 677 | break; | |||
| 678 | ||||
| 679 | alloc_buf(num_states_all); | |||
| 680 | } | |||
| 681 | ||||
| 682 | num_states = num_states_all; | |||
| 683 | for (n = 0; n < num_states_all; n++) | |||
| 684 | state_ord[n] = n; | |||
| 685 | ||||
| 686 | if (cachestates) { | |||
| 687 | for (n = 0; n < num_states; n++) | |||
| 688 | state_cache[n] = cache_state(state_buf + n); | |||
| 689 | cache_endupdate(); | |||
| 690 | } | |||
| 691 | ||||
| 692 | num_disp = num_states; | |||
| 693 | return 0; | |||
| 694 | } | |||
| 695 | ||||
| 696 | int | |||
| 697 | unmask(struct pf_addr * m) | |||
| 698 | { | |||
| 699 | int i = 31, j = 0, b = 0; | |||
| 700 | u_int32_t tmp; | |||
| 701 | ||||
| 702 | while (j < 4 && m->addr32pfa.addr32[j] == 0xffffffff) { | |||
| 703 | b += 32; | |||
| 704 | j++; | |||
| 705 | } | |||
| 706 | if (j < 4) { | |||
| 707 | tmp = ntohl(m->addr32[j])(__uint32_t)(__builtin_constant_p(m->pfa.addr32[j]) ? (__uint32_t )(((__uint32_t)(m->pfa.addr32[j]) & 0xff) << 24 | ((__uint32_t)(m->pfa.addr32[j]) & 0xff00) << 8 | ((__uint32_t)(m->pfa.addr32[j]) & 0xff0000) >> 8 | ((__uint32_t)(m->pfa.addr32[j]) & 0xff000000) >> 24) : __swap32md(m->pfa.addr32[j])); | |||
| 708 | for (i = 31; tmp & (1 << i); --i) | |||
| 709 | b++; | |||
| 710 | } | |||
| 711 | return (b); | |||
| 712 | } | |||
| 713 | ||||
| 714 | /* display functions */ | |||
| 715 | ||||
| 716 | void | |||
| 717 | tb_print_addr(struct pf_addr * addr, struct pf_addr * mask, int af) | |||
| 718 | { | |||
| 719 | switch (af) { | |||
| 720 | case AF_INET2: { | |||
| 721 | tbprintf("%s", inetname(addr->v4pfa.v4)); | |||
| 722 | break; | |||
| 723 | } | |||
| 724 | case AF_INET624: { | |||
| 725 | tbprintf("%s", inet6name(&addr->v6pfa.v6)); | |||
| 726 | break; | |||
| 727 | } | |||
| 728 | } | |||
| 729 | ||||
| 730 | if (mask != NULL((void *)0)) { | |||
| 731 | if (!PF_AZERO(mask, af)((af == 2 && !(mask)->pfa.addr32[0]) || (af == 24 && !(mask)->pfa.addr32[0] && !(mask)->pfa.addr32[ 1] && !(mask)->pfa.addr32[2] && !(mask)-> pfa.addr32[3] ))) | |||
| 732 | tbprintf("/%u", unmask(mask)); | |||
| 733 | } | |||
| 734 | } | |||
| 735 | ||||
| 736 | void | |||
| 737 | print_fld_host2(field_def *fld, struct pfsync_state_key *ks, | |||
| 738 | struct pfsync_state_key *kn, int idx) | |||
| 739 | { | |||
| 740 | struct pf_addr *as = &ks->addr[idx]; | |||
| 741 | struct pf_addr *an = &kn->addr[idx]; | |||
| 742 | ||||
| 743 | u_int16_t ps = ntohs(ks->port[idx])(__uint16_t)(__builtin_constant_p(ks->port[idx]) ? (__uint16_t )(((__uint16_t)(ks->port[idx]) & 0xffU) << 8 | ( (__uint16_t)(ks->port[idx]) & 0xff00U) >> 8) : __swap16md (ks->port[idx])); | |||
| 744 | u_int16_t pn = ntohs(kn->port[idx])(__uint16_t)(__builtin_constant_p(kn->port[idx]) ? (__uint16_t )(((__uint16_t)(kn->port[idx]) & 0xffU) << 8 | ( (__uint16_t)(kn->port[idx]) & 0xff00U) >> 8) : __swap16md (kn->port[idx])); | |||
| 745 | ||||
| 746 | int asf = ks->af; | |||
| 747 | int anf = kn->af; | |||
| 748 | ||||
| 749 | if (fld == NULL((void *)0)) | |||
| 750 | return; | |||
| 751 | ||||
| 752 | if (fld->width < 3) { | |||
| 753 | print_fld_str(fld, "*"); | |||
| 754 | return; | |||
| 755 | } | |||
| 756 | ||||
| 757 | tb_start(); | |||
| 758 | tb_print_addr(as, NULL((void *)0), asf); | |||
| 759 | ||||
| 760 | if (asf == AF_INET2) | |||
| 761 | tbprintf(":%u", ps); | |||
| 762 | else | |||
| 763 | tbprintf("[%u]", ps); | |||
| 764 | ||||
| 765 | print_fld_tb(fld); | |||
| 766 | ||||
| 767 | if (asf != anf || PF_ANEQ(as, an, asf)((asf == 2 && (as)->pfa.addr32[0] != (an)->pfa. addr32[0]) || (asf == 24 && ((as)->pfa.addr32[3] != (an)->pfa.addr32[3] || (as)->pfa.addr32[2] != (an)-> pfa.addr32[2] || (as)->pfa.addr32[1] != (an)->pfa.addr32 [1] || (as)->pfa.addr32[0] != (an)->pfa.addr32[0]))) || ps != pn) { | |||
| 768 | tb_start(); | |||
| 769 | tb_print_addr(an, NULL((void *)0), anf); | |||
| 770 | ||||
| 771 | if (anf == AF_INET2) | |||
| 772 | tbprintf(":%u", pn); | |||
| 773 | else | |||
| 774 | tbprintf("[%u]", pn); | |||
| 775 | print_fld_tb(FLD_GW(&fields[2])); | |||
| 776 | } | |||
| 777 | ||||
| 778 | } | |||
| 779 | ||||
| 780 | void | |||
| 781 | print_fld_state(field_def *fld, unsigned int proto, | |||
| 782 | unsigned int s1, unsigned int s2) | |||
| 783 | { | |||
| 784 | int len; | |||
| 785 | ||||
| 786 | if (fld == NULL((void *)0)) | |||
| 787 | return; | |||
| 788 | ||||
| 789 | len = fld->width; | |||
| 790 | if (len < 1) | |||
| 791 | return; | |||
| 792 | ||||
| 793 | tb_start(); | |||
| 794 | ||||
| 795 | if (proto == IPPROTO_TCP6) { | |||
| 796 | if (s1 <= TCPS_TIME_WAIT10 && s2 <= TCPS_TIME_WAIT10) | |||
| 797 | tbprintf("%s:%s", tcpstates[s1], tcpstates[s2]); | |||
| 798 | #ifdef PF_TCPS_PROXY_SRC((11)+0) | |||
| 799 | else if (s1 == PF_TCPS_PROXY_SRC((11)+0) || | |||
| 800 | s2 == PF_TCPS_PROXY_SRC((11)+0)) | |||
| 801 | tbprintf("PROXY:SRC\n"); | |||
| 802 | else if (s1 == PF_TCPS_PROXY_DST((11)+1) || | |||
| 803 | s2 == PF_TCPS_PROXY_DST((11)+1)) | |||
| 804 | tbprintf("PROXY:DST\n"); | |||
| 805 | #endif | |||
| 806 | else | |||
| 807 | tbprintf("<BAD STATE LEVELS>"); | |||
| 808 | } else if (proto == IPPROTO_UDP17 && s1 < PFUDPS_NSTATES3 && | |||
| 809 | s2 < PFUDPS_NSTATES3) { | |||
| 810 | const char *states[] = PFUDPS_NAMES{ "NO_TRAFFIC", "SINGLE", "MULTIPLE", ((void *)0) }; | |||
| 811 | tbprintf("%s:%s", states[s1], states[s2]); | |||
| 812 | } else if (proto != IPPROTO_ICMP1 && s1 < PFOTHERS_NSTATES3 && | |||
| 813 | s2 < PFOTHERS_NSTATES3) { | |||
| 814 | /* XXX ICMP doesn't really have state levels */ | |||
| 815 | const char *states[] = PFOTHERS_NAMES{ "NO_TRAFFIC", "SINGLE", "MULTIPLE", ((void *)0) }; | |||
| 816 | tbprintf("%s:%s", states[s1], states[s2]); | |||
| 817 | } else { | |||
| 818 | tbprintf("%u:%u", s1, s2); | |||
| 819 | } | |||
| 820 | ||||
| 821 | if (strlen(tmp_buf) > len) { | |||
| 822 | tb_start(); | |||
| 823 | tbprintf("%u:%u", s1, s2); | |||
| 824 | } | |||
| 825 | ||||
| 826 | print_fld_tb(fld); | |||
| 827 | } | |||
| 828 | ||||
| 829 | int | |||
| 830 | print_state(struct pfsync_state * s, struct sc_ent * ent) | |||
| 831 | { | |||
| 832 | struct pfsync_state_peer *src, *dst; | |||
| 833 | struct protoent *p; | |||
| 834 | u_int64_t sz; | |||
| 835 | int afto, dir; | |||
| 836 | ||||
| 837 | afto = s->key[PF_SK_STACK].af == s->key[PF_SK_WIRE].af ? 0 : 1; | |||
| 838 | dir = afto ? PF_OUT : s->direction; | |||
| 839 | ||||
| 840 | if (dir == PF_OUT) { | |||
| 841 | src = &s->src; | |||
| 842 | dst = &s->dst; | |||
| 843 | } else { | |||
| 844 | src = &s->dst; | |||
| 845 | dst = &s->src; | |||
| 846 | } | |||
| 847 | ||||
| 848 | p = getprotobynumber(s->proto); | |||
| 849 | ||||
| 850 | if (p != NULL((void *)0)) | |||
| 851 | print_fld_str(FLD_PROTO(&fields[6]), p->p_name); | |||
| 852 | else | |||
| 853 | print_fld_uint(FLD_PROTO(&fields[6]), s->proto); | |||
| 854 | ||||
| 855 | if (dir == PF_OUT) { | |||
| 856 | print_fld_host2(FLD_SRC(&fields[0]), | |||
| 857 | &s->key[afto ? PF_SK_STACK : PF_SK_WIRE], | |||
| 858 | &s->key[PF_SK_STACK], 1); | |||
| 859 | print_fld_host2(FLD_DEST(&fields[1]), | |||
| 860 | &s->key[afto ? PF_SK_STACK : PF_SK_WIRE], | |||
| 861 | &s->key[afto ? PF_SK_WIRE : PF_SK_STACK], 0); | |||
| 862 | } else { | |||
| 863 | print_fld_host2(FLD_SRC(&fields[0]), &s->key[PF_SK_STACK], | |||
| 864 | &s->key[PF_SK_WIRE], 0); | |||
| 865 | print_fld_host2(FLD_DEST(&fields[1]), &s->key[PF_SK_STACK], | |||
| 866 | &s->key[PF_SK_WIRE], 1); | |||
| 867 | } | |||
| 868 | ||||
| 869 | if (dir == PF_OUT) | |||
| 870 | print_fld_str(FLD_DIR(&fields[7]), "Out"); | |||
| 871 | else | |||
| 872 | print_fld_str(FLD_DIR(&fields[7]), "In"); | |||
| 873 | ||||
| 874 | print_fld_state(FLD_STATE(&fields[3]), s->proto, src->state, dst->state); | |||
| 875 | print_fld_age(FLD_AGE(&fields[4]), ntohl(s->creation)(__uint32_t)(__builtin_constant_p(s->creation) ? (__uint32_t )(((__uint32_t)(s->creation) & 0xff) << 24 | ((__uint32_t )(s->creation) & 0xff00) << 8 | ((__uint32_t)(s-> creation) & 0xff0000) >> 8 | ((__uint32_t)(s->creation ) & 0xff000000) >> 24) : __swap32md(s->creation) )); | |||
| 876 | print_fld_age(FLD_EXP(&fields[5]), ntohl(s->expire)(__uint32_t)(__builtin_constant_p(s->expire) ? (__uint32_t )(((__uint32_t)(s->expire) & 0xff) << 24 | ((__uint32_t )(s->expire) & 0xff00) << 8 | ((__uint32_t)(s-> expire) & 0xff0000) >> 8 | ((__uint32_t)(s->expire ) & 0xff000000) >> 24) : __swap32md(s->expire))); | |||
| 877 | ||||
| 878 | sz = COUNTER(s->bytes[0])((((u_int64_t) (__uint32_t)(__builtin_constant_p(s->bytes[ 0][0]) ? (__uint32_t)(((__uint32_t)(s->bytes[0][0]) & 0xff ) << 24 | ((__uint32_t)(s->bytes[0][0]) & 0xff00 ) << 8 | ((__uint32_t)(s->bytes[0][0]) & 0xff0000 ) >> 8 | ((__uint32_t)(s->bytes[0][0]) & 0xff000000 ) >> 24) : __swap32md(s->bytes[0][0])))<<32) + (__uint32_t)(__builtin_constant_p(s->bytes[0][1]) ? (__uint32_t )(((__uint32_t)(s->bytes[0][1]) & 0xff) << 24 | ( (__uint32_t)(s->bytes[0][1]) & 0xff00) << 8 | (( __uint32_t)(s->bytes[0][1]) & 0xff0000) >> 8 | ( (__uint32_t)(s->bytes[0][1]) & 0xff000000) >> 24 ) : __swap32md(s->bytes[0][1]))) + COUNTER(s->bytes[1])((((u_int64_t) (__uint32_t)(__builtin_constant_p(s->bytes[ 1][0]) ? (__uint32_t)(((__uint32_t)(s->bytes[1][0]) & 0xff ) << 24 | ((__uint32_t)(s->bytes[1][0]) & 0xff00 ) << 8 | ((__uint32_t)(s->bytes[1][0]) & 0xff0000 ) >> 8 | ((__uint32_t)(s->bytes[1][0]) & 0xff000000 ) >> 24) : __swap32md(s->bytes[1][0])))<<32) + (__uint32_t)(__builtin_constant_p(s->bytes[1][1]) ? (__uint32_t )(((__uint32_t)(s->bytes[1][1]) & 0xff) << 24 | ( (__uint32_t)(s->bytes[1][1]) & 0xff00) << 8 | (( __uint32_t)(s->bytes[1][1]) & 0xff0000) >> 8 | ( (__uint32_t)(s->bytes[1][1]) & 0xff000000) >> 24 ) : __swap32md(s->bytes[1][1]))); | |||
| 879 | ||||
| 880 | print_fld_size(FLD_PKTS(&fields[8]), COUNTER(s->packets[0])((((u_int64_t) (__uint32_t)(__builtin_constant_p(s->packets [0][0]) ? (__uint32_t)(((__uint32_t)(s->packets[0][0]) & 0xff) << 24 | ((__uint32_t)(s->packets[0][0]) & 0xff00) << 8 | ((__uint32_t)(s->packets[0][0]) & 0xff0000) >> 8 | ((__uint32_t)(s->packets[0][0]) & 0xff000000) >> 24) : __swap32md(s->packets[0][0]))) <<32) + (__uint32_t)(__builtin_constant_p(s->packets [0][1]) ? (__uint32_t)(((__uint32_t)(s->packets[0][1]) & 0xff) << 24 | ((__uint32_t)(s->packets[0][1]) & 0xff00) << 8 | ((__uint32_t)(s->packets[0][1]) & 0xff0000) >> 8 | ((__uint32_t)(s->packets[0][1]) & 0xff000000) >> 24) : __swap32md(s->packets[0][1]))) + | |||
| 881 | COUNTER(s->packets[1])((((u_int64_t) (__uint32_t)(__builtin_constant_p(s->packets [1][0]) ? (__uint32_t)(((__uint32_t)(s->packets[1][0]) & 0xff) << 24 | ((__uint32_t)(s->packets[1][0]) & 0xff00) << 8 | ((__uint32_t)(s->packets[1][0]) & 0xff0000) >> 8 | ((__uint32_t)(s->packets[1][0]) & 0xff000000) >> 24) : __swap32md(s->packets[1][0]))) <<32) + (__uint32_t)(__builtin_constant_p(s->packets [1][1]) ? (__uint32_t)(((__uint32_t)(s->packets[1][1]) & 0xff) << 24 | ((__uint32_t)(s->packets[1][1]) & 0xff00) << 8 | ((__uint32_t)(s->packets[1][1]) & 0xff0000) >> 8 | ((__uint32_t)(s->packets[1][1]) & 0xff000000) >> 24) : __swap32md(s->packets[1][1])))); | |||
| 882 | print_fld_size(FLD_BYTES(&fields[9]), sz); | |||
| 883 | print_fld_rate(FLD_SA(&fields[22]), (s->creation) ? | |||
| 884 | ((double)sz/(double)ntohl(s->creation)(__uint32_t)(__builtin_constant_p(s->creation) ? (__uint32_t )(((__uint32_t)(s->creation) & 0xff) << 24 | ((__uint32_t )(s->creation) & 0xff00) << 8 | ((__uint32_t)(s-> creation) & 0xff0000) >> 8 | ((__uint32_t)(s->creation ) & 0xff000000) >> 24) : __swap32md(s->creation) )) : -1); | |||
| 885 | ||||
| 886 | print_fld_uint(FLD_RULE(&fields[10]), ntohl(s->rule)(__uint32_t)(__builtin_constant_p(s->rule) ? (__uint32_t)( ((__uint32_t)(s->rule) & 0xff) << 24 | ((__uint32_t )(s->rule) & 0xff00) << 8 | ((__uint32_t)(s-> rule) & 0xff0000) >> 8 | ((__uint32_t)(s->rule) & 0xff000000) >> 24) : __swap32md(s->rule))); | |||
| 887 | if (cachestates && ent != NULL((void *)0)) { | |||
| 888 | print_fld_rate(FLD_SI(&fields[21]), ent->rate); | |||
| 889 | print_fld_rate(FLD_SP(&fields[23]), ent->peak); | |||
| 890 | } | |||
| 891 | ||||
| 892 | end_line(); | |||
| 893 | return 1; | |||
| 894 | } | |||
| 895 | ||||
| 896 | void | |||
| 897 | print_states(void) | |||
| 898 | { | |||
| 899 | int n, count = 0; | |||
| 900 | ||||
| 901 | for (n = dispstart; n < num_disp; n++) { | |||
| 902 | count += print_state(state_buf + state_ord[n], | |||
| 903 | state_cache[state_ord[n]]); | |||
| 904 | if (maxprint > 0 && count >= maxprint) | |||
| 905 | break; | |||
| 906 | } | |||
| 907 | } | |||
| 908 | ||||
| 909 | /* rule display */ | |||
| 910 | ||||
| 911 | struct pf_rule *rules = NULL((void *)0); | |||
| 912 | u_int32_t alloc_rules = 0; | |||
| 913 | ||||
| 914 | int | |||
| 915 | select_rules(void) | |||
| 916 | { | |||
| 917 | num_disp = num_rules; | |||
| 918 | return (0); | |||
| 919 | } | |||
| 920 | ||||
| 921 | ||||
| 922 | void | |||
| 923 | add_rule_alloc(u_int32_t nr) | |||
| 924 | { | |||
| 925 | if (nr == 0) | |||
| 926 | return; | |||
| 927 | ||||
| 928 | num_rules += nr; | |||
| 929 | ||||
| 930 | if (rules == NULL((void *)0)) { | |||
| 931 | rules = reallocarray(NULL((void *)0), num_rules, sizeof(struct pf_rule)); | |||
| 932 | if (rules == NULL((void *)0)) | |||
| 933 | err(1, "malloc"); | |||
| 934 | alloc_rules = num_rules; | |||
| 935 | } else if (num_rules > alloc_rules) { | |||
| 936 | rules = reallocarray(rules, num_rules, sizeof(struct pf_rule)); | |||
| 937 | if (rules == NULL((void *)0)) | |||
| 938 | err(1, "realloc"); | |||
| 939 | alloc_rules = num_rules; | |||
| 940 | } | |||
| 941 | } | |||
| 942 | ||||
| 943 | int label_length; | |||
| 944 | ||||
| 945 | int | |||
| 946 | read_anchor_rules(char *anchor) | |||
| 947 | { | |||
| 948 | struct pfioc_rule pr; | |||
| 949 | u_int32_t nr, num, off; | |||
| 950 | int len; | |||
| 951 | ||||
| 952 | if (pf_dev < 0) | |||
| 953 | return (-1); | |||
| 954 | ||||
| 955 | memset(&pr, 0, sizeof(pr)); | |||
| 956 | strlcpy(pr.anchor, anchor, sizeof(pr.anchor)); | |||
| 957 | ||||
| 958 | if (ioctl(pf_dev, DIOCGETRULES(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_rule) & 0x1fff) << 16) | ((('D')) << 8) | ((6))), &pr) == -1) { | |||
| 959 | error("anchor %s: %s", anchor, strerror(errno(*__errno()))); | |||
| 960 | return (-1); | |||
| 961 | } | |||
| 962 | ||||
| 963 | off = num_rules; | |||
| 964 | num = pr.nr; | |||
| 965 | add_rule_alloc(num); | |||
| 966 | ||||
| 967 | for (nr = 0; nr < num; ++nr) { | |||
| 968 | pr.nr = nr; | |||
| 969 | if (ioctl(pf_dev, DIOCGETRULE(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_rule) & 0x1fff) << 16) | ((('D')) << 8) | ((7))), &pr) == -1) { | |||
| 970 | error("DIOCGETRULE: %s", strerror(errno(*__errno()))); | |||
| 971 | return (-1); | |||
| 972 | } | |||
| 973 | /* XXX overload pr.anchor, to store a pointer to | |||
| 974 | * anchor name */ | |||
| 975 | pr.rule.anchor = (struct pf_anchor *) anchor; | |||
| 976 | len = strlen(pr.rule.label); | |||
| 977 | if (len > label_length) | |||
| 978 | label_length = len; | |||
| 979 | rules[off + nr] = pr.rule; | |||
| 980 | } | |||
| 981 | ||||
| 982 | return (num); | |||
| 983 | } | |||
| 984 | ||||
| 985 | struct anchor_name { | |||
| 986 | char name[PATH_MAX1024]; | |||
| 987 | struct anchor_name *next; | |||
| 988 | u_int32_t ref; | |||
| 989 | }; | |||
| 990 | ||||
| 991 | struct anchor_name *anchor_root = NULL((void *)0); | |||
| 992 | struct anchor_name *anchor_end = NULL((void *)0); | |||
| 993 | struct anchor_name *anchor_free = NULL((void *)0); | |||
| 994 | ||||
| 995 | struct anchor_name* | |||
| 996 | alloc_anchor_name(const char *path) | |||
| 997 | { | |||
| 998 | struct anchor_name *a; | |||
| 999 | ||||
| 1000 | a = anchor_free; | |||
| 1001 | if (a == NULL((void *)0)) { | |||
| 1002 | a = malloc(sizeof(struct anchor_name)); | |||
| 1003 | if (a == NULL((void *)0)) | |||
| 1004 | return (NULL((void *)0)); | |||
| 1005 | } else | |||
| 1006 | anchor_free = a->next; | |||
| 1007 | ||||
| 1008 | if (anchor_root == NULL((void *)0)) | |||
| 1009 | anchor_end = a; | |||
| 1010 | ||||
| 1011 | a->next = anchor_root; | |||
| 1012 | anchor_root = a; | |||
| 1013 | ||||
| 1014 | a->ref = 0; | |||
| 1015 | strlcpy(a->name, path, sizeof(a->name)); | |||
| 1016 | return (a); | |||
| 1017 | } | |||
| 1018 | ||||
| 1019 | void | |||
| 1020 | reset_anchor_names(void) | |||
| 1021 | { | |||
| 1022 | if (anchor_end == NULL((void *)0)) | |||
| 1023 | return; | |||
| 1024 | ||||
| 1025 | anchor_end->next = anchor_free; | |||
| 1026 | anchor_free = anchor_root; | |||
| 1027 | anchor_root = anchor_end = NULL((void *)0); | |||
| 1028 | } | |||
| 1029 | ||||
| 1030 | struct pfioc_ruleset ruleset; | |||
| 1031 | char *rs_end = NULL((void *)0); | |||
| 1032 | ||||
| 1033 | int | |||
| 1034 | read_rulesets(const char *path) | |||
| 1035 | { | |||
| 1036 | char *pre; | |||
| 1037 | struct anchor_name *a; | |||
| 1038 | u_int32_t nr, ns; | |||
| 1039 | int len; | |||
| 1040 | ||||
| 1041 | if (path == NULL((void *)0)) | |||
| 1042 | ruleset.path[0] = '\0'; | |||
| 1043 | else if (strlcpy(ruleset.path, path, sizeof(ruleset.path)) >= | |||
| 1044 | sizeof(ruleset.path)) | |||
| 1045 | return (-1); | |||
| 1046 | ||||
| 1047 | /* a persistent storage for anchor names */ | |||
| 1048 | a = alloc_anchor_name(ruleset.path); | |||
| 1049 | if (a == NULL((void *)0)) | |||
| 1050 | return (-1); | |||
| 1051 | ||||
| 1052 | len = read_anchor_rules(a->name); | |||
| 1053 | if (len < 0) | |||
| 1054 | return (-1); | |||
| 1055 | ||||
| 1056 | a->ref += len; | |||
| 1057 | ||||
| 1058 | if (ioctl(pf_dev, DIOCGETRULESETS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_ruleset) & 0x1fff) << 16) | ((('D')) << 8) | ((58))), &ruleset) == -1) { | |||
| 1059 | error("DIOCGETRULESETS: %s", strerror(errno(*__errno()))); | |||
| 1060 | return (-1); | |||
| 1061 | } | |||
| 1062 | ||||
| 1063 | ns = ruleset.nr; | |||
| 1064 | ||||
| 1065 | if (rs_end == NULL((void *)0)) | |||
| 1066 | rs_end = ruleset.path + sizeof(ruleset.path); | |||
| 1067 | ||||
| 1068 | /* 'pre' tracks the previous level on the anchor */ | |||
| 1069 | pre = strchr(ruleset.path, 0); | |||
| 1070 | len = rs_end - pre; | |||
| 1071 | if (len < 1) | |||
| 1072 | return (-1); | |||
| 1073 | --len; | |||
| 1074 | ||||
| 1075 | for (nr = 0; nr < ns; ++nr) { | |||
| 1076 | ruleset.nr = nr; | |||
| 1077 | if (ioctl(pf_dev, DIOCGETRULESET(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_ruleset) & 0x1fff) << 16) | ((('D')) << 8) | ((59))), &ruleset) == -1) { | |||
| 1078 | error("DIOCGETRULESET: %s", strerror(errno(*__errno()))); | |||
| 1079 | return (-1); | |||
| 1080 | } | |||
| 1081 | *pre = '/'; | |||
| 1082 | if (strlcpy(pre + 1, ruleset.name, len) < len) | |||
| 1083 | read_rulesets(ruleset.path); | |||
| 1084 | *pre = '\0'; | |||
| 1085 | } | |||
| 1086 | ||||
| 1087 | return (0); | |||
| 1088 | } | |||
| 1089 | ||||
| 1090 | void | |||
| 1091 | compute_anchor_field(void) | |||
| 1092 | { | |||
| 1093 | struct anchor_name *a; | |||
| 1094 | int sum, cnt, mx, nx; | |||
| 1095 | sum = cnt = mx = 0; | |||
| 1096 | ||||
| 1097 | for (a = anchor_root; a != NULL((void *)0); a = a->next, cnt++) { | |||
| 1098 | int len; | |||
| 1099 | if (a->ref == 0) | |||
| 1100 | continue; | |||
| 1101 | len = strlen(a->name); | |||
| 1102 | sum += len; | |||
| 1103 | if (len > mx) | |||
| 1104 | mx = len; | |||
| 1105 | } | |||
| 1106 | ||||
| 1107 | nx = sum/cnt; | |||
| ||||
| 1108 | if (nx < ANCHOR_FLD_SIZE12) | |||
| 1109 | nx = (mx < ANCHOR_FLD_SIZE12) ? mx : ANCHOR_FLD_SIZE12; | |||
| 1110 | ||||
| 1111 | if (FLD_ANCHOR(&fields[24])->max_width != mx || | |||
| 1112 | FLD_ANCHOR(&fields[24])->norm_width != nx) { | |||
| 1113 | FLD_ANCHOR(&fields[24])->max_width = mx; | |||
| 1114 | FLD_ANCHOR(&fields[24])->norm_width = nx; | |||
| 1115 | field_setup(); | |||
| 1116 | need_update = 1; | |||
| 1117 | } | |||
| 1118 | } | |||
| 1119 | ||||
| 1120 | int | |||
| 1121 | read_rules(void) | |||
| 1122 | { | |||
| 1123 | int ret, nw, mw; | |||
| 1124 | num_rules = 0; | |||
| 1125 | ||||
| 1126 | if (pf_dev == -1) | |||
| ||||
| 1127 | return (-1); | |||
| 1128 | ||||
| 1129 | label_length = MIN_LABEL_SIZE5; | |||
| 1130 | ||||
| 1131 | reset_anchor_names(); | |||
| 1132 | ret = read_rulesets(NULL((void *)0)); | |||
| 1133 | compute_anchor_field(); | |||
| 1134 | ||||
| 1135 | nw = mw = label_length; | |||
| 1136 | if (nw > 16) | |||
| 1137 | nw = 16; | |||
| 1138 | ||||
| 1139 | if (FLD_LABEL(&fields[11])->norm_width != nw || | |||
| 1140 | FLD_LABEL(&fields[11])->max_width != mw) { | |||
| 1141 | FLD_LABEL(&fields[11])->norm_width = nw; | |||
| 1142 | FLD_LABEL(&fields[11])->max_width = mw; | |||
| 1143 | field_setup(); | |||
| 1144 | need_update = 1; | |||
| 1145 | } | |||
| 1146 | ||||
| 1147 | num_disp = num_rules; | |||
| 1148 | return (ret); | |||
| 1149 | } | |||
| 1150 | ||||
| 1151 | void | |||
| 1152 | tb_print_addrw(struct pf_addr_wrap *addr, struct pf_addr *mask, u_int8_t af) | |||
| 1153 | { | |||
| 1154 | switch (addr->type) { | |||
| 1155 | case PF_ADDR_ADDRMASK: | |||
| 1156 | tb_print_addr(&addr->v.a.addr, mask, af); | |||
| 1157 | break; | |||
| 1158 | case PF_ADDR_NOROUTE: | |||
| 1159 | tbprintf("noroute"); | |||
| 1160 | break; | |||
| 1161 | case PF_ADDR_DYNIFTL: | |||
| 1162 | tbprintf("(%s)", addr->v.ifname); | |||
| 1163 | break; | |||
| 1164 | case PF_ADDR_TABLE: | |||
| 1165 | tbprintf("<%s>", addr->v.tblname); | |||
| 1166 | break; | |||
| 1167 | default: | |||
| 1168 | tbprintf("UNKNOWN"); | |||
| 1169 | break; | |||
| 1170 | } | |||
| 1171 | } | |||
| 1172 | ||||
| 1173 | void | |||
| 1174 | tb_print_op(u_int8_t op, const char *a1, const char *a2) | |||
| 1175 | { | |||
| 1176 | if (op == PF_OP_IRG) | |||
| 1177 | tbprintf("%s >< %s ", a1, a2); | |||
| 1178 | else if (op == PF_OP_XRG) | |||
| 1179 | tbprintf("%s <> %s ", a1, a2); | |||
| 1180 | else if (op == PF_OP_RRG) | |||
| 1181 | tbprintf("%s:%s ", a1, a2); | |||
| 1182 | else if (op == PF_OP_EQ) | |||
| 1183 | tbprintf("= %s ", a1); | |||
| 1184 | else if (op == PF_OP_NE) | |||
| 1185 | tbprintf("!= %s ", a1); | |||
| 1186 | else if (op == PF_OP_LT) | |||
| 1187 | tbprintf("< %s ", a1); | |||
| 1188 | else if (op == PF_OP_LE) | |||
| 1189 | tbprintf("<= %s ", a1); | |||
| 1190 | else if (op == PF_OP_GT) | |||
| 1191 | tbprintf("> %s ", a1); | |||
| 1192 | else if (op == PF_OP_GE) | |||
| 1193 | tbprintf(">= %s ", a1); | |||
| 1194 | } | |||
| 1195 | ||||
| 1196 | void | |||
| 1197 | tb_print_port(u_int8_t op, u_int16_t p1, u_int16_t p2, char *proto) | |||
| 1198 | { | |||
| 1199 | char a1[6], a2[6]; | |||
| 1200 | struct servent *s = getservbyport(p1, proto); | |||
| 1201 | ||||
| 1202 | p1 = ntohs(p1)(__uint16_t)(__builtin_constant_p(p1) ? (__uint16_t)(((__uint16_t )(p1) & 0xffU) << 8 | ((__uint16_t)(p1) & 0xff00U ) >> 8) : __swap16md(p1)); | |||
| 1203 | p2 = ntohs(p2)(__uint16_t)(__builtin_constant_p(p2) ? (__uint16_t)(((__uint16_t )(p2) & 0xffU) << 8 | ((__uint16_t)(p2) & 0xff00U ) >> 8) : __swap16md(p2)); | |||
| 1204 | snprintf(a1, sizeof(a1), "%u", p1); | |||
| 1205 | snprintf(a2, sizeof(a2), "%u", p2); | |||
| 1206 | tbprintf("port "); | |||
| 1207 | if (s != NULL((void *)0) && (op == PF_OP_EQ || op == PF_OP_NE)) | |||
| 1208 | tb_print_op(op, s->s_name, a2); | |||
| 1209 | else | |||
| 1210 | tb_print_op(op, a1, a2); | |||
| 1211 | } | |||
| 1212 | ||||
| 1213 | void | |||
| 1214 | tb_print_fromto(struct pf_rule_addr *src, struct pf_rule_addr *dst, | |||
| 1215 | u_int8_t af, u_int8_t proto) | |||
| 1216 | { | |||
| 1217 | if ( | |||
| 1218 | PF_AZERO(PT_ADDR(src), AF_INET6)((24 == 2 && !((&(src)->addr.v.a.addr))->pfa .addr32[0]) || (24 == 24 && !((&(src)->addr.v. a.addr))->pfa.addr32[0] && !((&(src)->addr. v.a.addr))->pfa.addr32[1] && !((&(src)->addr .v.a.addr))->pfa.addr32[2] && !((&(src)->addr .v.a.addr))->pfa.addr32[3] )) && | |||
| 1219 | PF_AZERO(PT_ADDR(dst), AF_INET6)((24 == 2 && !((&(dst)->addr.v.a.addr))->pfa .addr32[0]) || (24 == 24 && !((&(dst)->addr.v. a.addr))->pfa.addr32[0] && !((&(dst)->addr. v.a.addr))->pfa.addr32[1] && !((&(dst)->addr .v.a.addr))->pfa.addr32[2] && !((&(dst)->addr .v.a.addr))->pfa.addr32[3] )) && | |||
| 1220 | ! PT_NOROUTE(src)((src)->addr.type == PF_ADDR_NOROUTE) && ! PT_NOROUTE(dst)((dst)->addr.type == PF_ADDR_NOROUTE) && | |||
| 1221 | PF_AZERO(PT_MASK(src), AF_INET6)((24 == 2 && !((&(src)->addr.v.a.mask))->pfa .addr32[0]) || (24 == 24 && !((&(src)->addr.v. a.mask))->pfa.addr32[0] && !((&(src)->addr. v.a.mask))->pfa.addr32[1] && !((&(src)->addr .v.a.mask))->pfa.addr32[2] && !((&(src)->addr .v.a.mask))->pfa.addr32[3] )) && | |||
| 1222 | PF_AZERO(PT_MASK(dst), AF_INET6)((24 == 2 && !((&(dst)->addr.v.a.mask))->pfa .addr32[0]) || (24 == 24 && !((&(dst)->addr.v. a.mask))->pfa.addr32[0] && !((&(dst)->addr. v.a.mask))->pfa.addr32[1] && !((&(dst)->addr .v.a.mask))->pfa.addr32[2] && !((&(dst)->addr .v.a.mask))->pfa.addr32[3] )) && | |||
| 1223 | !src->port_op && !dst->port_op) | |||
| 1224 | tbprintf("all "); | |||
| 1225 | else { | |||
| 1226 | tbprintf("from "); | |||
| 1227 | if (PT_NOROUTE(src)((src)->addr.type == PF_ADDR_NOROUTE)) | |||
| 1228 | tbprintf("no-route "); | |||
| 1229 | else if (PF_AZERO(PT_ADDR(src), AF_INET6)((24 == 2 && !((&(src)->addr.v.a.addr))->pfa .addr32[0]) || (24 == 24 && !((&(src)->addr.v. a.addr))->pfa.addr32[0] && !((&(src)->addr. v.a.addr))->pfa.addr32[1] && !((&(src)->addr .v.a.addr))->pfa.addr32[2] && !((&(src)->addr .v.a.addr))->pfa.addr32[3] )) && | |||
| 1230 | PF_AZERO(PT_MASK(src), AF_INET6)((24 == 2 && !((&(src)->addr.v.a.mask))->pfa .addr32[0]) || (24 == 24 && !((&(src)->addr.v. a.mask))->pfa.addr32[0] && !((&(src)->addr. v.a.mask))->pfa.addr32[1] && !((&(src)->addr .v.a.mask))->pfa.addr32[2] && !((&(src)->addr .v.a.mask))->pfa.addr32[3] ))) | |||
| 1231 | tbprintf("any "); | |||
| 1232 | else { | |||
| 1233 | if (src->neg) | |||
| 1234 | tbprintf("! "); | |||
| 1235 | tb_print_addrw(&src->addr, PT_MASK(src)(&(src)->addr.v.a.mask), af); | |||
| 1236 | tbprintf(" "); | |||
| 1237 | } | |||
| 1238 | if (src->port_op) | |||
| 1239 | tb_print_port(src->port_op, src->port[0], | |||
| 1240 | src->port[1], | |||
| 1241 | proto == IPPROTO_TCP6 ? "tcp" : "udp"); | |||
| 1242 | ||||
| 1243 | tbprintf("to "); | |||
| 1244 | if (PT_NOROUTE(dst)((dst)->addr.type == PF_ADDR_NOROUTE)) | |||
| 1245 | tbprintf("no-route "); | |||
| 1246 | else if (PF_AZERO(PT_ADDR(dst), AF_INET6)((24 == 2 && !((&(dst)->addr.v.a.addr))->pfa .addr32[0]) || (24 == 24 && !((&(dst)->addr.v. a.addr))->pfa.addr32[0] && !((&(dst)->addr. v.a.addr))->pfa.addr32[1] && !((&(dst)->addr .v.a.addr))->pfa.addr32[2] && !((&(dst)->addr .v.a.addr))->pfa.addr32[3] )) && | |||
| 1247 | PF_AZERO(PT_MASK(dst), AF_INET6)((24 == 2 && !((&(dst)->addr.v.a.mask))->pfa .addr32[0]) || (24 == 24 && !((&(dst)->addr.v. a.mask))->pfa.addr32[0] && !((&(dst)->addr. v.a.mask))->pfa.addr32[1] && !((&(dst)->addr .v.a.mask))->pfa.addr32[2] && !((&(dst)->addr .v.a.mask))->pfa.addr32[3] ))) | |||
| 1248 | tbprintf("any "); | |||
| 1249 | else { | |||
| 1250 | if (dst->neg) | |||
| 1251 | tbprintf("! "); | |||
| 1252 | tb_print_addrw(&dst->addr, PT_MASK(dst)(&(dst)->addr.v.a.mask), af); | |||
| 1253 | tbprintf(" "); | |||
| 1254 | } | |||
| 1255 | if (dst->port_op) | |||
| 1256 | tb_print_port(dst->port_op, dst->port[0], | |||
| 1257 | dst->port[1], | |||
| 1258 | proto == IPPROTO_TCP6 ? "tcp" : "udp"); | |||
| 1259 | } | |||
| 1260 | } | |||
| 1261 | ||||
| 1262 | void | |||
| 1263 | tb_print_ugid(u_int8_t op, id_t i1, id_t i2, const char *t) | |||
| 1264 | { | |||
| 1265 | char a1[11], a2[11]; | |||
| 1266 | ||||
| 1267 | snprintf(a1, sizeof(a1), "%u", i1); | |||
| 1268 | snprintf(a2, sizeof(a2), "%u", i2); | |||
| 1269 | ||||
| 1270 | tbprintf("%s ", t); | |||
| 1271 | if (i1 == -1 && (op == PF_OP_EQ || op == PF_OP_NE)) | |||
| 1272 | tb_print_op(op, "unknown", a2); | |||
| 1273 | else | |||
| 1274 | tb_print_op(op, a1, a2); | |||
| 1275 | } | |||
| 1276 | ||||
| 1277 | void | |||
| 1278 | tb_print_flags(u_int8_t f) | |||
| 1279 | { | |||
| 1280 | const char *tcpflags = "FSRPAUEW"; | |||
| 1281 | int i; | |||
| 1282 | ||||
| 1283 | for (i = 0; tcpflags[i]; ++i) | |||
| 1284 | if (f & (1 << i)) | |||
| 1285 | tbprintf("%c", tcpflags[i]); | |||
| 1286 | } | |||
| 1287 | ||||
| 1288 | void | |||
| 1289 | print_rule(struct pf_rule *pr) | |||
| 1290 | { | |||
| 1291 | static const char *actiontypes[] = { "Pass", "Block", "Scrub", | |||
| 1292 | "no Scrub", "Nat", "no Nat", "Binat", "no Binat", "Rdr", | |||
| 1293 | "no Rdr", "SynProxy Block", "Defer", "Match" }; | |||
| 1294 | int numact = sizeof(actiontypes) / sizeof(char *); | |||
| 1295 | ||||
| 1296 | static const char *routetypes[] = { "", "fastroute", "route-to", | |||
| 1297 | "dup-to", "reply-to" }; | |||
| 1298 | ||||
| 1299 | int numroute = sizeof(routetypes) / sizeof(char *); | |||
| 1300 | ||||
| 1301 | if (pr == NULL((void *)0)) return; | |||
| 1302 | ||||
| 1303 | print_fld_str(FLD_LABEL(&fields[11]), pr->label); | |||
| 1304 | print_fld_size(FLD_STATS(&fields[12]), pr->states_tot); | |||
| 1305 | ||||
| 1306 | print_fld_size(FLD_PKTS(&fields[8]), pr->packets[0] + pr->packets[1]); | |||
| 1307 | print_fld_size(FLD_BYTES(&fields[9]), pr->bytes[0] + pr->bytes[1]); | |||
| 1308 | ||||
| 1309 | print_fld_uint(FLD_RULE(&fields[10]), pr->nr); | |||
| 1310 | if (pr->direction == PF_OUT) | |||
| 1311 | print_fld_str(FLD_DIR(&fields[7]), "Out"); | |||
| 1312 | else if (pr->direction == PF_IN) | |||
| 1313 | print_fld_str(FLD_DIR(&fields[7]), "In"); | |||
| 1314 | else | |||
| 1315 | print_fld_str(FLD_DIR(&fields[7]), "Any"); | |||
| 1316 | ||||
| 1317 | if (pr->quick) | |||
| 1318 | print_fld_str(FLD_QUICK(&fields[16]), "Quick"); | |||
| 1319 | ||||
| 1320 | if (pr->keep_state == PF_STATE_NORMAL0x1) | |||
| 1321 | print_fld_str(FLD_KST(&fields[17]), "Keep"); | |||
| 1322 | else if (pr->keep_state == PF_STATE_MODULATE0x2) | |||
| 1323 | print_fld_str(FLD_KST(&fields[17]), "Mod"); | |||
| 1324 | else if (pr->keep_state == PF_STATE_SYNPROXY0x3) | |||
| 1325 | print_fld_str(FLD_KST(&fields[17]), "Syn"); | |||
| 1326 | if (pr->log == 1) | |||
| 1327 | print_fld_str(FLD_LOG(&fields[15]), "Log"); | |||
| 1328 | else if (pr->log == 2) | |||
| 1329 | print_fld_str(FLD_LOG(&fields[15]), "All"); | |||
| 1330 | ||||
| 1331 | if (pr->action >= numact) | |||
| 1332 | print_fld_uint(FLD_ACTION(&fields[14]), pr->action); | |||
| 1333 | else print_fld_str(FLD_ACTION(&fields[14]), actiontypes[pr->action]); | |||
| 1334 | ||||
| 1335 | if (pr->proto) { | |||
| 1336 | struct protoent *p = getprotobynumber(pr->proto); | |||
| 1337 | ||||
| 1338 | if (p != NULL((void *)0)) | |||
| 1339 | print_fld_str(FLD_PROTO(&fields[6]), p->p_name); | |||
| 1340 | else | |||
| 1341 | print_fld_uint(FLD_PROTO(&fields[6]), pr->proto); | |||
| 1342 | } | |||
| 1343 | ||||
| 1344 | if (pr->ifname[0]) { | |||
| 1345 | tb_start(); | |||
| 1346 | if (pr->ifnot) | |||
| 1347 | tbprintf("!"); | |||
| 1348 | tbprintf("%s", pr->ifname); | |||
| 1349 | print_fld_tb(FLD_IF(&fields[18])); | |||
| 1350 | } | |||
| 1351 | if (pr->max_states) | |||
| 1352 | print_fld_uint(FLD_STMAX(&fields[20]), pr->max_states); | |||
| 1353 | ||||
| 1354 | /* print info field */ | |||
| 1355 | ||||
| 1356 | tb_start(); | |||
| 1357 | ||||
| 1358 | if (pr->action == PF_DROP) { | |||
| 1359 | if (pr->rule_flag & PFRULE_RETURNRST0x0001) | |||
| 1360 | tbprintf("return-rst "); | |||
| 1361 | #ifdef PFRULE_RETURN0x0008 | |||
| 1362 | else if (pr->rule_flag & PFRULE_RETURN0x0008) | |||
| 1363 | tbprintf("return "); | |||
| 1364 | #endif | |||
| 1365 | #ifdef PFRULE_RETURNICMP0x0004 | |||
| 1366 | else if (pr->rule_flag & PFRULE_RETURNICMP0x0004) | |||
| 1367 | tbprintf("return-icmp "); | |||
| 1368 | #endif | |||
| 1369 | else | |||
| 1370 | tbprintf("drop "); | |||
| 1371 | } | |||
| 1372 | ||||
| 1373 | if (pr->rt > 0 && pr->rt < numroute) { | |||
| 1374 | tbprintf("%s ", routetypes[pr->rt]); | |||
| 1375 | } | |||
| 1376 | ||||
| 1377 | if (pr->af) { | |||
| 1378 | if (pr->af == AF_INET2) | |||
| 1379 | tbprintf("inet "); | |||
| 1380 | else | |||
| 1381 | tbprintf("inet6 "); | |||
| 1382 | } | |||
| 1383 | ||||
| 1384 | tb_print_fromto(&pr->src, &pr->dst, pr->af, pr->proto); | |||
| 1385 | ||||
| 1386 | if (pr->uid.op) | |||
| 1387 | tb_print_ugid(pr->uid.op, pr->uid.uid[0], pr->uid.uid[1], | |||
| 1388 | "user"); | |||
| 1389 | if (pr->gid.op) | |||
| 1390 | tb_print_ugid(pr->gid.op, pr->gid.gid[0], pr->gid.gid[1], | |||
| 1391 | "group"); | |||
| 1392 | ||||
| 1393 | if (pr->action == PF_PASS && | |||
| 1394 | (pr->proto == 0 || pr->proto == IPPROTO_TCP6) && | |||
| 1395 | (pr->flags != TH_SYN0x02 || pr->flagset != (TH_SYN0x02 | TH_ACK0x10) )) { | |||
| 1396 | tbprintf("flags "); | |||
| 1397 | if (pr->flags || pr->flagset) { | |||
| 1398 | tb_print_flags(pr->flags); | |||
| 1399 | tbprintf("/"); | |||
| 1400 | tb_print_flags(pr->flagset); | |||
| 1401 | } else | |||
| 1402 | tbprintf("any "); | |||
| 1403 | } | |||
| 1404 | ||||
| 1405 | tbprintf(" "); | |||
| 1406 | ||||
| 1407 | if (pr->tos) | |||
| 1408 | tbprintf("tos 0x%2.2x ", pr->tos); | |||
| 1409 | #ifdef PFRULE_FRAGMENT0x0002 | |||
| 1410 | if (pr->rule_flag & PFRULE_FRAGMENT0x0002) | |||
| 1411 | tbprintf("fragment "); | |||
| 1412 | #endif | |||
| 1413 | #ifdef PFRULE_NODF | |||
| 1414 | if (pr->rule_flag & PFRULE_NODF) | |||
| 1415 | tbprintf("no-df "); | |||
| 1416 | #endif | |||
| 1417 | #ifdef PFRULE_RANDOMID | |||
| 1418 | if (pr->rule_flag & PFRULE_RANDOMID) | |||
| 1419 | tbprintf("random-id "); | |||
| 1420 | #endif | |||
| 1421 | if (pr->min_ttl) | |||
| 1422 | tbprintf("min-ttl %d ", pr->min_ttl); | |||
| 1423 | if (pr->max_mss) | |||
| 1424 | tbprintf("max-mss %d ", pr->max_mss); | |||
| 1425 | if (pr->allow_opts) | |||
| 1426 | tbprintf("allow-opts "); | |||
| 1427 | ||||
| 1428 | /* XXX more missing */ | |||
| 1429 | ||||
| 1430 | if (pr->qname[0] && pr->pqname[0]) | |||
| 1431 | tbprintf("queue(%s, %s) ", pr->qname, pr->pqname); | |||
| 1432 | else if (pr->qname[0]) | |||
| 1433 | tbprintf("queue %s ", pr->qname); | |||
| 1434 | ||||
| 1435 | if (pr->tagname[0]) | |||
| 1436 | tbprintf("tag %s ", pr->tagname); | |||
| 1437 | if (pr->match_tagname[0]) { | |||
| 1438 | if (pr->match_tag_not) | |||
| 1439 | tbprintf("! "); | |||
| 1440 | tbprintf("tagged %s ", pr->match_tagname); | |||
| 1441 | } | |||
| 1442 | ||||
| 1443 | print_fld_tb(FLD_RINFO(&fields[19])); | |||
| 1444 | ||||
| 1445 | /* XXX anchor field overloaded with anchor name */ | |||
| 1446 | print_fld_str(FLD_ANCHOR(&fields[24]), (char *)pr->anchor); | |||
| 1447 | tb_end(); | |||
| 1448 | ||||
| 1449 | end_line(); | |||
| 1450 | } | |||
| 1451 | ||||
| 1452 | void | |||
| 1453 | print_rules(void) | |||
| 1454 | { | |||
| 1455 | u_int32_t n, count = 0; | |||
| 1456 | ||||
| 1457 | for (n = dispstart; n < num_rules; n++) { | |||
| 1458 | print_rule(rules + n); | |||
| 1459 | count ++; | |||
| 1460 | if (maxprint > 0 && count >= maxprint) | |||
| 1461 | break; | |||
| 1462 | } | |||
| 1463 | } | |||
| 1464 | ||||
| 1465 | /* queue display */ | |||
| 1466 | struct pfctl_queue_node * | |||
| 1467 | pfctl_find_queue_node(const char *qname, const char *ifname) | |||
| 1468 | { | |||
| 1469 | struct pfctl_queue_node *node; | |||
| 1470 | ||||
| 1471 | TAILQ_FOREACH(node, &qnodes, entries)for((node) = ((&qnodes)->tqh_first); (node) != ((void * )0); (node) = ((node)->entries.tqe_next)) | |||
| 1472 | if (!strcmp(node->qs.qname, qname) | |||
| 1473 | && !(strcmp(node->qs.ifname, ifname))) | |||
| 1474 | return (node); | |||
| 1475 | return (NULL((void *)0)); | |||
| 1476 | } | |||
| 1477 | ||||
| 1478 | void | |||
| 1479 | pfctl_insert_queue_node(const struct pf_queuespec qs, | |||
| 1480 | const struct queue_stats qstats) | |||
| 1481 | { | |||
| 1482 | struct pfctl_queue_node *node, *parent; | |||
| 1483 | ||||
| 1484 | node = calloc(1, sizeof(struct pfctl_queue_node)); | |||
| 1485 | if (node == NULL((void *)0)) | |||
| 1486 | err(1, "pfctl_insert_queue_node: calloc"); | |||
| 1487 | memcpy(&node->qs, &qs, sizeof(qs)); | |||
| 1488 | memcpy(&node->qstats, &qstats, sizeof(qstats)); | |||
| 1489 | ||||
| 1490 | if (node->qs.parent[0]) { | |||
| 1491 | parent = pfctl_find_queue_node(node->qs.parent, | |||
| 1492 | node->qs.ifname); | |||
| 1493 | if (parent) | |||
| 1494 | node->depth = parent->depth + 1; | |||
| 1495 | } | |||
| 1496 | ||||
| 1497 | TAILQ_INSERT_TAIL(&qnodes, node, entries)do { (node)->entries.tqe_next = ((void *)0); (node)->entries .tqe_prev = (&qnodes)->tqh_last; *(&qnodes)->tqh_last = (node); (&qnodes)->tqh_last = &(node)->entries .tqe_next; } while (0); | |||
| 1498 | } | |||
| 1499 | ||||
| 1500 | int | |||
| 1501 | pfctl_update_qstats(void) | |||
| 1502 | { | |||
| 1503 | struct pfctl_queue_node *node; | |||
| 1504 | struct pfioc_queue pq; | |||
| 1505 | struct pfioc_qstats pqs; | |||
| 1506 | u_int32_t mnr, nr; | |||
| 1507 | struct queue_stats qstats; | |||
| 1508 | static u_int32_t last_ticket; | |||
| 1509 | ||||
| 1510 | memset(&pq, 0, sizeof(pq)); | |||
| 1511 | memset(&pqs, 0, sizeof(pqs)); | |||
| 1512 | memset(&qstats, 0, sizeof(qstats)); | |||
| 1513 | ||||
| 1514 | if (pf_dev < 0) | |||
| 1515 | return (-1); | |||
| 1516 | ||||
| 1517 | if (ioctl(pf_dev, DIOCGETQUEUES(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_queue) & 0x1fff) << 16) | ((('D')) << 8) | ((94))), &pq) == -1) { | |||
| 1518 | error("DIOCGETQUEUES: %s", strerror(errno(*__errno()))); | |||
| 1519 | return (-1); | |||
| 1520 | } | |||
| 1521 | ||||
| 1522 | /* if a new set is found, start over */ | |||
| 1523 | if (pq.ticket != last_ticket) | |||
| 1524 | while ((node = TAILQ_FIRST(&qnodes)((&qnodes)->tqh_first)) != NULL((void *)0)) { | |||
| 1525 | TAILQ_REMOVE(&qnodes, node, entries)do { if (((node)->entries.tqe_next) != ((void *)0)) (node) ->entries.tqe_next->entries.tqe_prev = (node)->entries .tqe_prev; else (&qnodes)->tqh_last = (node)->entries .tqe_prev; *(node)->entries.tqe_prev = (node)->entries. tqe_next; ; ; } while (0); | |||
| 1526 | free(node); | |||
| 1527 | } | |||
| 1528 | last_ticket = pq.ticket; | |||
| 1529 | ||||
| 1530 | num_queues = mnr = pq.nr; | |||
| 1531 | for (nr = 0; nr < mnr; ++nr) { | |||
| 1532 | pqs.nr = nr; | |||
| 1533 | pqs.ticket = pq.ticket; | |||
| 1534 | pqs.buf = &qstats.data; | |||
| 1535 | pqs.nbytes = sizeof(qstats.data); | |||
| 1536 | if (ioctl(pf_dev, DIOCGETQSTATS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_qstats) & 0x1fff) << 16) | ((('D')) << 8) | ((96))), &pqs) == -1) { | |||
| 1537 | error("DIOCGETQSTATS: %s", strerror(errno(*__errno()))); | |||
| 1538 | return (-1); | |||
| 1539 | } | |||
| 1540 | qstats.valid = 1; | |||
| 1541 | gettimeofday(&qstats.timestamp, NULL((void *)0)); | |||
| 1542 | if ((node = pfctl_find_queue_node(pqs.queue.qname, | |||
| 1543 | pqs.queue.ifname)) != NULL((void *)0)) { | |||
| 1544 | memcpy(&node->qstats_last, &node->qstats, | |||
| 1545 | sizeof(struct queue_stats)); | |||
| 1546 | memcpy(&node->qstats, &qstats, | |||
| 1547 | sizeof(struct queue_stats)); | |||
| 1548 | } else { | |||
| 1549 | pfctl_insert_queue_node(pqs.queue, qstats); | |||
| 1550 | } | |||
| 1551 | } | |||
| 1552 | return (0); | |||
| 1553 | } | |||
| 1554 | ||||
| 1555 | int | |||
| 1556 | select_queues(void) | |||
| 1557 | { | |||
| 1558 | num_disp = num_queues; | |||
| 1559 | return (0); | |||
| 1560 | } | |||
| 1561 | ||||
| 1562 | int | |||
| 1563 | read_queues(void) | |||
| 1564 | { | |||
| 1565 | num_disp = num_queues = 0; | |||
| 1566 | ||||
| 1567 | if (pfctl_update_qstats() < 0) | |||
| 1568 | return (-1); | |||
| 1569 | num_disp = num_queues; | |||
| 1570 | ||||
| 1571 | return(0); | |||
| 1572 | } | |||
| 1573 | ||||
| 1574 | double | |||
| 1575 | calc_interval(struct timeval *cur_time, struct timeval *last_time) | |||
| 1576 | { | |||
| 1577 | double sec; | |||
| 1578 | ||||
| 1579 | sec = (double)(cur_time->tv_sec - last_time->tv_sec) + | |||
| 1580 | (double)(cur_time->tv_usec - last_time->tv_usec) / 1000000; | |||
| 1581 | ||||
| 1582 | return (sec); | |||
| 1583 | } | |||
| 1584 | ||||
| 1585 | double | |||
| 1586 | calc_rate(u_int64_t new_bytes, u_int64_t last_bytes, double interval) | |||
| 1587 | { | |||
| 1588 | double rate; | |||
| 1589 | ||||
| 1590 | rate = (double)(new_bytes - last_bytes) / interval; | |||
| 1591 | return (rate); | |||
| 1592 | } | |||
| 1593 | ||||
| 1594 | double | |||
| 1595 | calc_pps(u_int64_t new_pkts, u_int64_t last_pkts, double interval) | |||
| 1596 | { | |||
| 1597 | double pps; | |||
| 1598 | ||||
| 1599 | pps = (double)(new_pkts - last_pkts) / interval; | |||
| 1600 | return (pps); | |||
| 1601 | } | |||
| 1602 | ||||
| 1603 | void | |||
| 1604 | print_queue_node(struct pfctl_queue_node *node) | |||
| 1605 | { | |||
| 1606 | u_int rate, rtmp; | |||
| 1607 | int i; | |||
| 1608 | double interval, pps, bps; | |||
| 1609 | static const char unit[] = " KMG"; | |||
| 1610 | ||||
| 1611 | tb_start(); | |||
| 1612 | for (i = 0; i < node->depth; i++) | |||
| 1613 | tbprintf(" "); | |||
| 1614 | tbprintf("%s", node->qs.qname); | |||
| 1615 | if (i == 0 && node->qs.ifname[0]) | |||
| 1616 | tbprintf(" on %s ", node->qs.ifname); | |||
| 1617 | print_fld_tb(FLD_QUEUE(&fields[25])); | |||
| 1618 | ||||
| 1619 | // XXX: missing min, max, burst | |||
| 1620 | tb_start(); | |||
| 1621 | rate = node->qs.linkshare.m2.absolute; | |||
| 1622 | for (i = 0; rate > 9999 && i <= 3; i++) { | |||
| 1623 | rtmp = rate / 1000; | |||
| 1624 | if (rtmp <= 9999) | |||
| 1625 | rtmp += (rate % 1000) / 500; | |||
| 1626 | rate = rtmp; | |||
| 1627 | } | |||
| 1628 | if (rate == 0 && (node->qs.flags & PFQS_FLOWQUEUE0x0001)) { | |||
| 1629 | /* | |||
| 1630 | * XXX We're abusing the fact that 'flows' in | |||
| 1631 | * the fqcodel_stats structure is at the same | |||
| 1632 | * spot as the 'period' in hfsc_class_stats. | |||
| 1633 | */ | |||
| 1634 | tbprintf("%u", node->qstats.data.period); | |||
| 1635 | } else | |||
| 1636 | tbprintf("%u%c", rate, unit[i]); | |||
| 1637 | print_fld_tb(FLD_BANDW(&fields[26])); | |||
| 1638 | ||||
| 1639 | print_fld_str(FLD_SCHED(&fields[27]), node->qs.flags & PFQS_FLOWQUEUE0x0001 ? | |||
| 1640 | "flow" : "fifo"); | |||
| 1641 | ||||
| 1642 | if (node->qstats.valid && node->qstats_last.valid) | |||
| 1643 | interval = calc_interval(&node->qstats.timestamp, | |||
| 1644 | &node->qstats_last.timestamp); | |||
| 1645 | else | |||
| 1646 | interval = 0; | |||
| 1647 | ||||
| 1648 | print_fld_size(FLD_PKTS(&fields[8]), node->qstats.data.xmit_cnt.packets); | |||
| 1649 | print_fld_size(FLD_BYTES(&fields[9]), node->qstats.data.xmit_cnt.bytes); | |||
| 1650 | print_fld_size(FLD_DROPP(&fields[28]), node->qstats.data.drop_cnt.packets); | |||
| 1651 | print_fld_size(FLD_DROPB(&fields[29]), node->qstats.data.drop_cnt.bytes); | |||
| 1652 | print_fld_size(FLD_QLEN(&fields[30]), node->qstats.data.qlength); | |||
| 1653 | ||||
| 1654 | if (interval > 0) { | |||
| 1655 | pps = calc_pps(node->qstats.data.xmit_cnt.packets, | |||
| 1656 | node->qstats_last.data.xmit_cnt.packets, interval); | |||
| 1657 | bps = calc_rate(node->qstats.data.xmit_cnt.bytes, | |||
| 1658 | node->qstats_last.data.xmit_cnt.bytes, interval); | |||
| 1659 | ||||
| 1660 | tb_start(); | |||
| 1661 | if (pps > 0 && pps < 1) | |||
| 1662 | tbprintf("%-3.1lf", pps); | |||
| 1663 | else | |||
| 1664 | tbprintf("%u", (unsigned int)pps); | |||
| 1665 | ||||
| 1666 | print_fld_tb(FLD_PKTSPS(&fields[33])); | |||
| 1667 | print_fld_bw(FLD_BYTESPS(&fields[34]), bps); | |||
| 1668 | } | |||
| 1669 | } | |||
| 1670 | ||||
| 1671 | void | |||
| 1672 | print_queues(void) | |||
| 1673 | { | |||
| 1674 | uint32_t n, count, start; | |||
| 1675 | struct pfctl_queue_node *node; | |||
| 1676 | ||||
| 1677 | n = count = 0; | |||
| 1678 | start = dispstart; | |||
| 1679 | ||||
| 1680 | TAILQ_FOREACH(node, &qnodes, entries)for((node) = ((&qnodes)->tqh_first); (node) != ((void * )0); (node) = ((node)->entries.tqe_next)) { | |||
| 1681 | if (n < start) { | |||
| 1682 | n++; | |||
| 1683 | continue; | |||
| 1684 | } | |||
| 1685 | print_queue_node(node); | |||
| 1686 | end_line(); | |||
| 1687 | count++; | |||
| 1688 | if (maxprint > 0 && count >= maxprint) | |||
| 1689 | return; | |||
| 1690 | } | |||
| 1691 | } | |||
| 1692 | ||||
| 1693 | /* main program functions */ | |||
| 1694 | ||||
| 1695 | void | |||
| 1696 | update_cache(void) | |||
| 1697 | { | |||
| 1698 | static int pstate = -1; | |||
| 1699 | if (pstate == cachestates) | |||
| 1700 | return; | |||
| 1701 | ||||
| 1702 | pstate = cachestates; | |||
| 1703 | if (cachestates) { | |||
| 1704 | show_field(FLD_SI(&fields[21])); | |||
| 1705 | show_field(FLD_SP(&fields[23])); | |||
| 1706 | gotsig_alarm = 1; | |||
| 1707 | } else { | |||
| 1708 | hide_field(FLD_SI(&fields[21])); | |||
| 1709 | hide_field(FLD_SP(&fields[23])); | |||
| 1710 | need_update = 1; | |||
| 1711 | } | |||
| 1712 | field_setup(); | |||
| 1713 | } | |||
| 1714 | ||||
| 1715 | int | |||
| 1716 | initpftop(void) | |||
| 1717 | { | |||
| 1718 | struct pf_status status; | |||
| 1719 | field_view *v; | |||
| 1720 | int cachesize = DEFAULT_CACHE_SIZE10000; | |||
| 1721 | ||||
| 1722 | v = views; | |||
| 1723 | while(v->name != NULL((void *)0)) | |||
| 1724 | add_view(v++); | |||
| 1725 | ||||
| 1726 | pf_dev = open("/dev/pf", O_RDONLY0x0000); | |||
| 1727 | if (pf_dev == -1) { | |||
| 1728 | alloc_buf(0); | |||
| 1729 | } else if (ioctl(pf_dev, DIOCGETSTATUS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pf_status) & 0x1fff) << 16) | ((('D')) << 8) | ((21))), &status) == -1) { | |||
| 1730 | warn("DIOCGETSTATUS"); | |||
| 1731 | alloc_buf(0); | |||
| 1732 | } else | |||
| 1733 | alloc_buf(status.states); | |||
| 1734 | ||||
| 1735 | /* initialize cache with given size */ | |||
| 1736 | if (cache_init(cachesize)) | |||
| 1737 | warnx("Failed to initialize cache."); | |||
| 1738 | else if (interactive && cachesize > 0) | |||
| 1739 | cachestates = 1; | |||
| 1740 | ||||
| 1741 | update_cache(); | |||
| 1742 | ||||
| 1743 | show_field(FLD_STMAX(&fields[20])); | |||
| 1744 | show_field(FLD_ANCHOR(&fields[24])); | |||
| 1745 | ||||
| 1746 | return (1); | |||
| 1747 | } |