File: | src/usr.bin/systat/pftop.c |
Warning: | line 469, column 3 Value stored to 'af' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: pftop.c,v 1.46 2023/07/04 11:34:19 sashan 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; |
Value stored to 'af' is never read | |
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 | void |
946 | close_pf_trans(u_int32_t ticket) |
947 | { |
948 | if (ioctl(pf_dev, DIOCXEND(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (u_int32_t) & 0x1fff) << 16) | ((('D')) << 8) | ((100))), &ticket) == -1) |
949 | error("DIOCXEND: %s", strerror(errno(*__errno()))); |
950 | } |
951 | |
952 | int |
953 | read_anchor_rules(char *anchor) |
954 | { |
955 | struct pfioc_rule pr; |
956 | u_int32_t nr, num, off; |
957 | int len; |
958 | |
959 | if (pf_dev < 0) |
960 | return (-1); |
961 | |
962 | memset(&pr, 0, sizeof(pr)); |
963 | strlcpy(pr.anchor, anchor, sizeof(pr.anchor)); |
964 | |
965 | if (ioctl(pf_dev, DIOCGETRULES(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_rule) & 0x1fff) << 16) | ((('D')) << 8) | ((6))), &pr) == -1) { |
966 | error("anchor %s: %s", anchor, strerror(errno(*__errno()))); |
967 | return (-1); |
968 | } |
969 | |
970 | off = num_rules; |
971 | num = pr.nr; |
972 | add_rule_alloc(num); |
973 | |
974 | for (nr = 0; nr < num; ++nr) { |
975 | pr.nr = nr; |
976 | if (ioctl(pf_dev, DIOCGETRULE(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_rule) & 0x1fff) << 16) | ((('D')) << 8) | ((7))), &pr) == -1) { |
977 | error("DIOCGETRULE: %s", strerror(errno(*__errno()))); |
978 | close_pf_trans(pr.ticket); |
979 | return (-1); |
980 | } |
981 | /* XXX overload pr.anchor, to store a pointer to |
982 | * anchor name */ |
983 | pr.rule.anchor = (struct pf_anchor *) anchor; |
984 | len = strlen(pr.rule.label); |
985 | if (len > label_length) |
986 | label_length = len; |
987 | rules[off + nr] = pr.rule; |
988 | } |
989 | |
990 | close_pf_trans(pr.ticket); |
991 | |
992 | return (num); |
993 | } |
994 | |
995 | struct anchor_name { |
996 | char name[PATH_MAX1024]; |
997 | struct anchor_name *next; |
998 | u_int32_t ref; |
999 | }; |
1000 | |
1001 | struct anchor_name *anchor_root = NULL((void *)0); |
1002 | struct anchor_name *anchor_end = NULL((void *)0); |
1003 | struct anchor_name *anchor_free = NULL((void *)0); |
1004 | |
1005 | struct anchor_name* |
1006 | alloc_anchor_name(const char *path) |
1007 | { |
1008 | struct anchor_name *a; |
1009 | |
1010 | a = anchor_free; |
1011 | if (a == NULL((void *)0)) { |
1012 | a = malloc(sizeof(struct anchor_name)); |
1013 | if (a == NULL((void *)0)) |
1014 | return (NULL((void *)0)); |
1015 | } else |
1016 | anchor_free = a->next; |
1017 | |
1018 | if (anchor_root == NULL((void *)0)) |
1019 | anchor_end = a; |
1020 | |
1021 | a->next = anchor_root; |
1022 | anchor_root = a; |
1023 | |
1024 | a->ref = 0; |
1025 | strlcpy(a->name, path, sizeof(a->name)); |
1026 | return (a); |
1027 | } |
1028 | |
1029 | void |
1030 | reset_anchor_names(void) |
1031 | { |
1032 | if (anchor_end == NULL((void *)0)) |
1033 | return; |
1034 | |
1035 | anchor_end->next = anchor_free; |
1036 | anchor_free = anchor_root; |
1037 | anchor_root = anchor_end = NULL((void *)0); |
1038 | } |
1039 | |
1040 | struct pfioc_ruleset ruleset; |
1041 | char *rs_end = NULL((void *)0); |
1042 | |
1043 | int |
1044 | read_rulesets(const char *path) |
1045 | { |
1046 | char *pre; |
1047 | struct anchor_name *a; |
1048 | u_int32_t nr, ns; |
1049 | int len; |
1050 | |
1051 | if (path == NULL((void *)0)) |
1052 | ruleset.path[0] = '\0'; |
1053 | else if (strlcpy(ruleset.path, path, sizeof(ruleset.path)) >= |
1054 | sizeof(ruleset.path)) |
1055 | return (-1); |
1056 | |
1057 | /* a persistent storage for anchor names */ |
1058 | a = alloc_anchor_name(ruleset.path); |
1059 | if (a == NULL((void *)0)) |
1060 | return (-1); |
1061 | |
1062 | len = read_anchor_rules(a->name); |
1063 | if (len < 0) |
1064 | return (-1); |
1065 | |
1066 | a->ref += len; |
1067 | |
1068 | if (ioctl(pf_dev, DIOCGETRULESETS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_ruleset) & 0x1fff) << 16) | ((('D')) << 8) | ((58))), &ruleset) == -1) { |
1069 | error("DIOCGETRULESETS: %s", strerror(errno(*__errno()))); |
1070 | return (-1); |
1071 | } |
1072 | |
1073 | ns = ruleset.nr; |
1074 | |
1075 | if (rs_end == NULL((void *)0)) |
1076 | rs_end = ruleset.path + sizeof(ruleset.path); |
1077 | |
1078 | /* 'pre' tracks the previous level on the anchor */ |
1079 | pre = strchr(ruleset.path, 0); |
1080 | len = rs_end - pre; |
1081 | if (len < 1) |
1082 | return (-1); |
1083 | --len; |
1084 | |
1085 | for (nr = 0; nr < ns; ++nr) { |
1086 | ruleset.nr = nr; |
1087 | if (ioctl(pf_dev, DIOCGETRULESET(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_ruleset) & 0x1fff) << 16) | ((('D')) << 8) | ((59))), &ruleset) == -1) { |
1088 | error("DIOCGETRULESET: %s", strerror(errno(*__errno()))); |
1089 | return (-1); |
1090 | } |
1091 | *pre = '/'; |
1092 | if (strlcpy(pre + 1, ruleset.name, len) < len) |
1093 | read_rulesets(ruleset.path); |
1094 | *pre = '\0'; |
1095 | } |
1096 | |
1097 | return (0); |
1098 | } |
1099 | |
1100 | void |
1101 | compute_anchor_field(void) |
1102 | { |
1103 | struct anchor_name *a; |
1104 | int sum, cnt, mx, nx; |
1105 | sum = cnt = mx = 0; |
1106 | |
1107 | for (a = anchor_root; a != NULL((void *)0); a = a->next, cnt++) { |
1108 | int len; |
1109 | if (a->ref == 0) |
1110 | continue; |
1111 | len = strlen(a->name); |
1112 | sum += len; |
1113 | if (len > mx) |
1114 | mx = len; |
1115 | } |
1116 | |
1117 | nx = sum/cnt; |
1118 | if (nx < ANCHOR_FLD_SIZE12) |
1119 | nx = (mx < ANCHOR_FLD_SIZE12) ? mx : ANCHOR_FLD_SIZE12; |
1120 | |
1121 | if (FLD_ANCHOR(&fields[24])->max_width != mx || |
1122 | FLD_ANCHOR(&fields[24])->norm_width != nx) { |
1123 | FLD_ANCHOR(&fields[24])->max_width = mx; |
1124 | FLD_ANCHOR(&fields[24])->norm_width = nx; |
1125 | field_setup(); |
1126 | need_update = 1; |
1127 | } |
1128 | } |
1129 | |
1130 | int |
1131 | read_rules(void) |
1132 | { |
1133 | int ret, nw, mw; |
1134 | num_rules = 0; |
1135 | |
1136 | if (pf_dev == -1) |
1137 | return (-1); |
1138 | |
1139 | label_length = MIN_LABEL_SIZE5; |
1140 | |
1141 | reset_anchor_names(); |
1142 | ret = read_rulesets(NULL((void *)0)); |
1143 | compute_anchor_field(); |
1144 | |
1145 | nw = mw = label_length; |
1146 | if (nw > 16) |
1147 | nw = 16; |
1148 | |
1149 | if (FLD_LABEL(&fields[11])->norm_width != nw || |
1150 | FLD_LABEL(&fields[11])->max_width != mw) { |
1151 | FLD_LABEL(&fields[11])->norm_width = nw; |
1152 | FLD_LABEL(&fields[11])->max_width = mw; |
1153 | field_setup(); |
1154 | need_update = 1; |
1155 | } |
1156 | |
1157 | num_disp = num_rules; |
1158 | return (ret); |
1159 | } |
1160 | |
1161 | void |
1162 | tb_print_addrw(struct pf_addr_wrap *addr, struct pf_addr *mask, u_int8_t af) |
1163 | { |
1164 | switch (addr->type) { |
1165 | case PF_ADDR_ADDRMASK: |
1166 | tb_print_addr(&addr->v.a.addr, mask, af); |
1167 | break; |
1168 | case PF_ADDR_NOROUTE: |
1169 | tbprintf("noroute"); |
1170 | break; |
1171 | case PF_ADDR_DYNIFTL: |
1172 | tbprintf("(%s)", addr->v.ifname); |
1173 | break; |
1174 | case PF_ADDR_TABLE: |
1175 | tbprintf("<%s>", addr->v.tblname); |
1176 | break; |
1177 | default: |
1178 | tbprintf("UNKNOWN"); |
1179 | break; |
1180 | } |
1181 | } |
1182 | |
1183 | void |
1184 | tb_print_op(u_int8_t op, const char *a1, const char *a2) |
1185 | { |
1186 | if (op == PF_OP_IRG) |
1187 | tbprintf("%s >< %s ", a1, a2); |
1188 | else if (op == PF_OP_XRG) |
1189 | tbprintf("%s <> %s ", a1, a2); |
1190 | else if (op == PF_OP_RRG) |
1191 | tbprintf("%s:%s ", a1, a2); |
1192 | else if (op == PF_OP_EQ) |
1193 | tbprintf("= %s ", a1); |
1194 | else if (op == PF_OP_NE) |
1195 | tbprintf("!= %s ", a1); |
1196 | else if (op == PF_OP_LT) |
1197 | tbprintf("< %s ", a1); |
1198 | else if (op == PF_OP_LE) |
1199 | tbprintf("<= %s ", a1); |
1200 | else if (op == PF_OP_GT) |
1201 | tbprintf("> %s ", a1); |
1202 | else if (op == PF_OP_GE) |
1203 | tbprintf(">= %s ", a1); |
1204 | } |
1205 | |
1206 | void |
1207 | tb_print_port(u_int8_t op, u_int16_t p1, u_int16_t p2, char *proto) |
1208 | { |
1209 | char a1[6], a2[6]; |
1210 | struct servent *s = getservbyport(p1, proto); |
1211 | |
1212 | p1 = ntohs(p1)(__uint16_t)(__builtin_constant_p(p1) ? (__uint16_t)(((__uint16_t )(p1) & 0xffU) << 8 | ((__uint16_t)(p1) & 0xff00U ) >> 8) : __swap16md(p1)); |
1213 | p2 = ntohs(p2)(__uint16_t)(__builtin_constant_p(p2) ? (__uint16_t)(((__uint16_t )(p2) & 0xffU) << 8 | ((__uint16_t)(p2) & 0xff00U ) >> 8) : __swap16md(p2)); |
1214 | snprintf(a1, sizeof(a1), "%u", p1); |
1215 | snprintf(a2, sizeof(a2), "%u", p2); |
1216 | tbprintf("port "); |
1217 | if (s != NULL((void *)0) && (op == PF_OP_EQ || op == PF_OP_NE)) |
1218 | tb_print_op(op, s->s_name, a2); |
1219 | else |
1220 | tb_print_op(op, a1, a2); |
1221 | } |
1222 | |
1223 | void |
1224 | tb_print_fromto(struct pf_rule_addr *src, struct pf_rule_addr *dst, |
1225 | u_int8_t af, u_int8_t proto) |
1226 | { |
1227 | if ( |
1228 | 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] )) && |
1229 | 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] )) && |
1230 | ! PT_NOROUTE(src)((src)->addr.type == PF_ADDR_NOROUTE) && ! PT_NOROUTE(dst)((dst)->addr.type == PF_ADDR_NOROUTE) && |
1231 | 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] )) && |
1232 | 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] )) && |
1233 | !src->port_op && !dst->port_op) |
1234 | tbprintf("all "); |
1235 | else { |
1236 | tbprintf("from "); |
1237 | if (PT_NOROUTE(src)((src)->addr.type == PF_ADDR_NOROUTE)) |
1238 | tbprintf("no-route "); |
1239 | 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] )) && |
1240 | 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] ))) |
1241 | tbprintf("any "); |
1242 | else { |
1243 | if (src->neg) |
1244 | tbprintf("! "); |
1245 | tb_print_addrw(&src->addr, PT_MASK(src)(&(src)->addr.v.a.mask), af); |
1246 | tbprintf(" "); |
1247 | } |
1248 | if (src->port_op) |
1249 | tb_print_port(src->port_op, src->port[0], |
1250 | src->port[1], |
1251 | proto == IPPROTO_TCP6 ? "tcp" : "udp"); |
1252 | |
1253 | tbprintf("to "); |
1254 | if (PT_NOROUTE(dst)((dst)->addr.type == PF_ADDR_NOROUTE)) |
1255 | tbprintf("no-route "); |
1256 | 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] )) && |
1257 | 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] ))) |
1258 | tbprintf("any "); |
1259 | else { |
1260 | if (dst->neg) |
1261 | tbprintf("! "); |
1262 | tb_print_addrw(&dst->addr, PT_MASK(dst)(&(dst)->addr.v.a.mask), af); |
1263 | tbprintf(" "); |
1264 | } |
1265 | if (dst->port_op) |
1266 | tb_print_port(dst->port_op, dst->port[0], |
1267 | dst->port[1], |
1268 | proto == IPPROTO_TCP6 ? "tcp" : "udp"); |
1269 | } |
1270 | } |
1271 | |
1272 | void |
1273 | tb_print_ugid(u_int8_t op, id_t i1, id_t i2, const char *t) |
1274 | { |
1275 | char a1[11], a2[11]; |
1276 | |
1277 | snprintf(a1, sizeof(a1), "%u", i1); |
1278 | snprintf(a2, sizeof(a2), "%u", i2); |
1279 | |
1280 | tbprintf("%s ", t); |
1281 | if (i1 == -1 && (op == PF_OP_EQ || op == PF_OP_NE)) |
1282 | tb_print_op(op, "unknown", a2); |
1283 | else |
1284 | tb_print_op(op, a1, a2); |
1285 | } |
1286 | |
1287 | void |
1288 | tb_print_flags(u_int8_t f) |
1289 | { |
1290 | const char *tcpflags = "FSRPAUEW"; |
1291 | int i; |
1292 | |
1293 | for (i = 0; tcpflags[i]; ++i) |
1294 | if (f & (1 << i)) |
1295 | tbprintf("%c", tcpflags[i]); |
1296 | } |
1297 | |
1298 | void |
1299 | print_rule(struct pf_rule *pr) |
1300 | { |
1301 | static const char *actiontypes[] = { "Pass", "Block", "Scrub", |
1302 | "no Scrub", "Nat", "no Nat", "Binat", "no Binat", "Rdr", |
1303 | "no Rdr", "SynProxy Block", "Defer", "Match" }; |
1304 | int numact = sizeof(actiontypes) / sizeof(char *); |
1305 | |
1306 | static const char *routetypes[] = { "", "fastroute", "route-to", |
1307 | "dup-to", "reply-to" }; |
1308 | |
1309 | int numroute = sizeof(routetypes) / sizeof(char *); |
1310 | |
1311 | if (pr == NULL((void *)0)) return; |
1312 | |
1313 | print_fld_str(FLD_LABEL(&fields[11]), pr->label); |
1314 | print_fld_size(FLD_STATS(&fields[12]), pr->states_tot); |
1315 | |
1316 | print_fld_size(FLD_PKTS(&fields[8]), pr->packets[0] + pr->packets[1]); |
1317 | print_fld_size(FLD_BYTES(&fields[9]), pr->bytes[0] + pr->bytes[1]); |
1318 | |
1319 | print_fld_uint(FLD_RULE(&fields[10]), pr->nr); |
1320 | if (pr->direction == PF_OUT) |
1321 | print_fld_str(FLD_DIR(&fields[7]), "Out"); |
1322 | else if (pr->direction == PF_IN) |
1323 | print_fld_str(FLD_DIR(&fields[7]), "In"); |
1324 | else |
1325 | print_fld_str(FLD_DIR(&fields[7]), "Any"); |
1326 | |
1327 | if (pr->quick) |
1328 | print_fld_str(FLD_QUICK(&fields[16]), "Quick"); |
1329 | |
1330 | if (pr->keep_state == PF_STATE_NORMAL0x1) |
1331 | print_fld_str(FLD_KST(&fields[17]), "Keep"); |
1332 | else if (pr->keep_state == PF_STATE_MODULATE0x2) |
1333 | print_fld_str(FLD_KST(&fields[17]), "Mod"); |
1334 | else if (pr->keep_state == PF_STATE_SYNPROXY0x3) |
1335 | print_fld_str(FLD_KST(&fields[17]), "Syn"); |
1336 | if (pr->log == 1) |
1337 | print_fld_str(FLD_LOG(&fields[15]), "Log"); |
1338 | else if (pr->log == 2) |
1339 | print_fld_str(FLD_LOG(&fields[15]), "All"); |
1340 | |
1341 | if (pr->action >= numact) |
1342 | print_fld_uint(FLD_ACTION(&fields[14]), pr->action); |
1343 | else print_fld_str(FLD_ACTION(&fields[14]), actiontypes[pr->action]); |
1344 | |
1345 | if (pr->proto) { |
1346 | struct protoent *p = getprotobynumber(pr->proto); |
1347 | |
1348 | if (p != NULL((void *)0)) |
1349 | print_fld_str(FLD_PROTO(&fields[6]), p->p_name); |
1350 | else |
1351 | print_fld_uint(FLD_PROTO(&fields[6]), pr->proto); |
1352 | } |
1353 | |
1354 | if (pr->ifname[0]) { |
1355 | tb_start(); |
1356 | if (pr->ifnot) |
1357 | tbprintf("!"); |
1358 | tbprintf("%s", pr->ifname); |
1359 | print_fld_tb(FLD_IF(&fields[18])); |
1360 | } |
1361 | if (pr->max_states) |
1362 | print_fld_uint(FLD_STMAX(&fields[20]), pr->max_states); |
1363 | |
1364 | /* print info field */ |
1365 | |
1366 | tb_start(); |
1367 | |
1368 | if (pr->action == PF_DROP) { |
1369 | if (pr->rule_flag & PFRULE_RETURNRST0x0001) |
1370 | tbprintf("return-rst "); |
1371 | #ifdef PFRULE_RETURN0x0008 |
1372 | else if (pr->rule_flag & PFRULE_RETURN0x0008) |
1373 | tbprintf("return "); |
1374 | #endif |
1375 | #ifdef PFRULE_RETURNICMP0x0004 |
1376 | else if (pr->rule_flag & PFRULE_RETURNICMP0x0004) |
1377 | tbprintf("return-icmp "); |
1378 | #endif |
1379 | else |
1380 | tbprintf("drop "); |
1381 | } |
1382 | |
1383 | if (pr->rt > 0 && pr->rt < numroute) { |
1384 | tbprintf("%s ", routetypes[pr->rt]); |
1385 | } |
1386 | |
1387 | if (pr->af) { |
1388 | if (pr->af == AF_INET2) |
1389 | tbprintf("inet "); |
1390 | else |
1391 | tbprintf("inet6 "); |
1392 | } |
1393 | |
1394 | tb_print_fromto(&pr->src, &pr->dst, pr->af, pr->proto); |
1395 | |
1396 | if (pr->uid.op) |
1397 | tb_print_ugid(pr->uid.op, pr->uid.uid[0], pr->uid.uid[1], |
1398 | "user"); |
1399 | if (pr->gid.op) |
1400 | tb_print_ugid(pr->gid.op, pr->gid.gid[0], pr->gid.gid[1], |
1401 | "group"); |
1402 | |
1403 | if (pr->action == PF_PASS && |
1404 | (pr->proto == 0 || pr->proto == IPPROTO_TCP6) && |
1405 | (pr->flags != TH_SYN0x02 || pr->flagset != (TH_SYN0x02 | TH_ACK0x10) )) { |
1406 | tbprintf("flags "); |
1407 | if (pr->flags || pr->flagset) { |
1408 | tb_print_flags(pr->flags); |
1409 | tbprintf("/"); |
1410 | tb_print_flags(pr->flagset); |
1411 | } else |
1412 | tbprintf("any "); |
1413 | } |
1414 | |
1415 | tbprintf(" "); |
1416 | |
1417 | if (pr->tos) |
1418 | tbprintf("tos 0x%2.2x ", pr->tos); |
1419 | #ifdef PFRULE_FRAGMENT0x0002 |
1420 | if (pr->rule_flag & PFRULE_FRAGMENT0x0002) |
1421 | tbprintf("fragment "); |
1422 | #endif |
1423 | #ifdef PFRULE_NODF |
1424 | if (pr->rule_flag & PFRULE_NODF) |
1425 | tbprintf("no-df "); |
1426 | #endif |
1427 | #ifdef PFRULE_RANDOMID |
1428 | if (pr->rule_flag & PFRULE_RANDOMID) |
1429 | tbprintf("random-id "); |
1430 | #endif |
1431 | if (pr->min_ttl) |
1432 | tbprintf("min-ttl %d ", pr->min_ttl); |
1433 | if (pr->max_mss) |
1434 | tbprintf("max-mss %d ", pr->max_mss); |
1435 | if (pr->allow_opts) |
1436 | tbprintf("allow-opts "); |
1437 | |
1438 | /* XXX more missing */ |
1439 | |
1440 | if (pr->qname[0] && pr->pqname[0]) |
1441 | tbprintf("queue(%s, %s) ", pr->qname, pr->pqname); |
1442 | else if (pr->qname[0]) |
1443 | tbprintf("queue %s ", pr->qname); |
1444 | |
1445 | if (pr->tagname[0]) |
1446 | tbprintf("tag %s ", pr->tagname); |
1447 | if (pr->match_tagname[0]) { |
1448 | if (pr->match_tag_not) |
1449 | tbprintf("! "); |
1450 | tbprintf("tagged %s ", pr->match_tagname); |
1451 | } |
1452 | |
1453 | print_fld_tb(FLD_RINFO(&fields[19])); |
1454 | |
1455 | /* XXX anchor field overloaded with anchor name */ |
1456 | print_fld_str(FLD_ANCHOR(&fields[24]), (char *)pr->anchor); |
1457 | tb_end(); |
1458 | |
1459 | end_line(); |
1460 | } |
1461 | |
1462 | void |
1463 | print_rules(void) |
1464 | { |
1465 | u_int32_t n, count = 0; |
1466 | |
1467 | for (n = dispstart; n < num_rules; n++) { |
1468 | print_rule(rules + n); |
1469 | count ++; |
1470 | if (maxprint > 0 && count >= maxprint) |
1471 | break; |
1472 | } |
1473 | } |
1474 | |
1475 | /* queue display */ |
1476 | struct pfctl_queue_node * |
1477 | pfctl_find_queue_node(const char *qname, const char *ifname) |
1478 | { |
1479 | struct pfctl_queue_node *node; |
1480 | |
1481 | TAILQ_FOREACH(node, &qnodes, entries)for((node) = ((&qnodes)->tqh_first); (node) != ((void * )0); (node) = ((node)->entries.tqe_next)) |
1482 | if (!strcmp(node->qs.qname, qname) |
1483 | && !(strcmp(node->qs.ifname, ifname))) |
1484 | return (node); |
1485 | return (NULL((void *)0)); |
1486 | } |
1487 | |
1488 | void |
1489 | pfctl_insert_queue_node(const struct pf_queuespec qs, |
1490 | const struct queue_stats qstats) |
1491 | { |
1492 | struct pfctl_queue_node *node, *parent; |
1493 | |
1494 | node = calloc(1, sizeof(struct pfctl_queue_node)); |
1495 | if (node == NULL((void *)0)) |
1496 | err(1, "pfctl_insert_queue_node: calloc"); |
1497 | memcpy(&node->qs, &qs, sizeof(qs)); |
1498 | memcpy(&node->qstats, &qstats, sizeof(qstats)); |
1499 | |
1500 | if (node->qs.parent[0]) { |
1501 | parent = pfctl_find_queue_node(node->qs.parent, |
1502 | node->qs.ifname); |
1503 | if (parent) |
1504 | node->depth = parent->depth + 1; |
1505 | } |
1506 | |
1507 | 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); |
1508 | } |
1509 | |
1510 | int |
1511 | pfctl_update_qstats(void) |
1512 | { |
1513 | struct pfctl_queue_node *node; |
1514 | struct pfioc_queue pq; |
1515 | struct pfioc_qstats pqs; |
1516 | u_int32_t mnr, nr; |
1517 | struct queue_stats qstats; |
1518 | static u_int32_t last_ticket; |
1519 | |
1520 | memset(&pq, 0, sizeof(pq)); |
1521 | memset(&pqs, 0, sizeof(pqs)); |
1522 | memset(&qstats, 0, sizeof(qstats)); |
1523 | |
1524 | if (pf_dev < 0) |
1525 | return (-1); |
1526 | |
1527 | if (ioctl(pf_dev, DIOCGETQUEUES(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_queue) & 0x1fff) << 16) | ((('D')) << 8) | ((94))), &pq) == -1) { |
1528 | error("DIOCGETQUEUES: %s", strerror(errno(*__errno()))); |
1529 | return (-1); |
1530 | } |
1531 | |
1532 | /* if a new set is found, start over */ |
1533 | if (pq.ticket != last_ticket) |
1534 | while ((node = TAILQ_FIRST(&qnodes)((&qnodes)->tqh_first)) != NULL((void *)0)) { |
1535 | 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); |
1536 | free(node); |
1537 | } |
1538 | last_ticket = pq.ticket; |
1539 | |
1540 | num_queues = mnr = pq.nr; |
1541 | for (nr = 0; nr < mnr; ++nr) { |
1542 | pqs.nr = nr; |
1543 | pqs.ticket = pq.ticket; |
1544 | pqs.buf = &qstats.data; |
1545 | pqs.nbytes = sizeof(qstats.data); |
1546 | if (ioctl(pf_dev, DIOCGETQSTATS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pfioc_qstats) & 0x1fff) << 16) | ((('D')) << 8) | ((96))), &pqs) == -1) { |
1547 | error("DIOCGETQSTATS: %s", strerror(errno(*__errno()))); |
1548 | return (-1); |
1549 | } |
1550 | qstats.valid = 1; |
1551 | gettimeofday(&qstats.timestamp, NULL((void *)0)); |
1552 | if ((node = pfctl_find_queue_node(pqs.queue.qname, |
1553 | pqs.queue.ifname)) != NULL((void *)0)) { |
1554 | memcpy(&node->qstats_last, &node->qstats, |
1555 | sizeof(struct queue_stats)); |
1556 | memcpy(&node->qstats, &qstats, |
1557 | sizeof(struct queue_stats)); |
1558 | } else { |
1559 | pfctl_insert_queue_node(pqs.queue, qstats); |
1560 | } |
1561 | } |
1562 | return (0); |
1563 | } |
1564 | |
1565 | int |
1566 | select_queues(void) |
1567 | { |
1568 | num_disp = num_queues; |
1569 | return (0); |
1570 | } |
1571 | |
1572 | int |
1573 | read_queues(void) |
1574 | { |
1575 | num_disp = num_queues = 0; |
1576 | |
1577 | if (pfctl_update_qstats() < 0) |
1578 | return (-1); |
1579 | num_disp = num_queues; |
1580 | |
1581 | return(0); |
1582 | } |
1583 | |
1584 | double |
1585 | calc_interval(struct timeval *cur_time, struct timeval *last_time) |
1586 | { |
1587 | double sec; |
1588 | |
1589 | sec = (double)(cur_time->tv_sec - last_time->tv_sec) + |
1590 | (double)(cur_time->tv_usec - last_time->tv_usec) / 1000000; |
1591 | |
1592 | return (sec); |
1593 | } |
1594 | |
1595 | double |
1596 | calc_rate(u_int64_t new_bytes, u_int64_t last_bytes, double interval) |
1597 | { |
1598 | double rate; |
1599 | |
1600 | rate = (double)(new_bytes - last_bytes) / interval; |
1601 | return (rate); |
1602 | } |
1603 | |
1604 | double |
1605 | calc_pps(u_int64_t new_pkts, u_int64_t last_pkts, double interval) |
1606 | { |
1607 | double pps; |
1608 | |
1609 | pps = (double)(new_pkts - last_pkts) / interval; |
1610 | return (pps); |
1611 | } |
1612 | |
1613 | void |
1614 | print_queue_node(struct pfctl_queue_node *node) |
1615 | { |
1616 | u_int rate, rtmp; |
1617 | int i; |
1618 | double interval, pps, bps; |
1619 | static const char unit[] = " KMG"; |
1620 | |
1621 | tb_start(); |
1622 | for (i = 0; i < node->depth; i++) |
1623 | tbprintf(" "); |
1624 | tbprintf("%s", node->qs.qname); |
1625 | if (i == 0 && node->qs.ifname[0]) |
1626 | tbprintf(" on %s ", node->qs.ifname); |
1627 | print_fld_tb(FLD_QUEUE(&fields[25])); |
1628 | |
1629 | // XXX: missing min, max, burst |
1630 | tb_start(); |
1631 | rate = node->qs.linkshare.m2.absolute; |
1632 | for (i = 0; rate > 9999 && i <= 3; i++) { |
1633 | rtmp = rate / 1000; |
1634 | if (rtmp <= 9999) |
1635 | rtmp += (rate % 1000) / 500; |
1636 | rate = rtmp; |
1637 | } |
1638 | if (rate == 0 && (node->qs.flags & PFQS_FLOWQUEUE0x0001)) { |
1639 | /* |
1640 | * XXX We're abusing the fact that 'flows' in |
1641 | * the fqcodel_stats structure is at the same |
1642 | * spot as the 'period' in hfsc_class_stats. |
1643 | */ |
1644 | tbprintf("%u", node->qstats.data.period); |
1645 | } else |
1646 | tbprintf("%u%c", rate, unit[i]); |
1647 | print_fld_tb(FLD_BANDW(&fields[26])); |
1648 | |
1649 | print_fld_str(FLD_SCHED(&fields[27]), node->qs.flags & PFQS_FLOWQUEUE0x0001 ? |
1650 | "flow" : "fifo"); |
1651 | |
1652 | if (node->qstats.valid && node->qstats_last.valid) |
1653 | interval = calc_interval(&node->qstats.timestamp, |
1654 | &node->qstats_last.timestamp); |
1655 | else |
1656 | interval = 0; |
1657 | |
1658 | print_fld_size(FLD_PKTS(&fields[8]), node->qstats.data.xmit_cnt.packets); |
1659 | print_fld_size(FLD_BYTES(&fields[9]), node->qstats.data.xmit_cnt.bytes); |
1660 | print_fld_size(FLD_DROPP(&fields[28]), node->qstats.data.drop_cnt.packets); |
1661 | print_fld_size(FLD_DROPB(&fields[29]), node->qstats.data.drop_cnt.bytes); |
1662 | print_fld_size(FLD_QLEN(&fields[30]), node->qstats.data.qlength); |
1663 | |
1664 | if (interval > 0) { |
1665 | pps = calc_pps(node->qstats.data.xmit_cnt.packets, |
1666 | node->qstats_last.data.xmit_cnt.packets, interval); |
1667 | bps = calc_rate(node->qstats.data.xmit_cnt.bytes, |
1668 | node->qstats_last.data.xmit_cnt.bytes, interval); |
1669 | |
1670 | tb_start(); |
1671 | if (pps > 0 && pps < 1) |
1672 | tbprintf("%-3.1lf", pps); |
1673 | else |
1674 | tbprintf("%u", (unsigned int)pps); |
1675 | |
1676 | print_fld_tb(FLD_PKTSPS(&fields[33])); |
1677 | print_fld_bw(FLD_BYTESPS(&fields[34]), bps); |
1678 | } |
1679 | } |
1680 | |
1681 | void |
1682 | print_queues(void) |
1683 | { |
1684 | uint32_t n, count, start; |
1685 | struct pfctl_queue_node *node; |
1686 | |
1687 | n = count = 0; |
1688 | start = dispstart; |
1689 | |
1690 | TAILQ_FOREACH(node, &qnodes, entries)for((node) = ((&qnodes)->tqh_first); (node) != ((void * )0); (node) = ((node)->entries.tqe_next)) { |
1691 | if (n < start) { |
1692 | n++; |
1693 | continue; |
1694 | } |
1695 | print_queue_node(node); |
1696 | end_line(); |
1697 | count++; |
1698 | if (maxprint > 0 && count >= maxprint) |
1699 | return; |
1700 | } |
1701 | } |
1702 | |
1703 | /* main program functions */ |
1704 | |
1705 | void |
1706 | update_cache(void) |
1707 | { |
1708 | static int pstate = -1; |
1709 | if (pstate == cachestates) |
1710 | return; |
1711 | |
1712 | pstate = cachestates; |
1713 | if (cachestates) { |
1714 | show_field(FLD_SI(&fields[21])); |
1715 | show_field(FLD_SP(&fields[23])); |
1716 | gotsig_alarm = 1; |
1717 | } else { |
1718 | hide_field(FLD_SI(&fields[21])); |
1719 | hide_field(FLD_SP(&fields[23])); |
1720 | need_update = 1; |
1721 | } |
1722 | field_setup(); |
1723 | } |
1724 | |
1725 | int |
1726 | initpftop(void) |
1727 | { |
1728 | struct pf_status status; |
1729 | field_view *v; |
1730 | int cachesize = DEFAULT_CACHE_SIZE10000; |
1731 | |
1732 | v = views; |
1733 | while(v->name != NULL((void *)0)) |
1734 | add_view(v++); |
1735 | |
1736 | pf_dev = open("/dev/pf", O_RDONLY0x0000); |
1737 | if (pf_dev == -1) { |
1738 | alloc_buf(0); |
1739 | } else if (ioctl(pf_dev, DIOCGETSTATUS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct pf_status) & 0x1fff) << 16) | ((('D')) << 8) | ((21))), &status) == -1) { |
1740 | warn("DIOCGETSTATUS"); |
1741 | alloc_buf(0); |
1742 | } else |
1743 | alloc_buf(status.states); |
1744 | |
1745 | /* initialize cache with given size */ |
1746 | if (cache_init(cachesize)) |
1747 | warnx("Failed to initialize cache."); |
1748 | else if (interactive && cachesize > 0) |
1749 | cachestates = 1; |
1750 | |
1751 | update_cache(); |
1752 | |
1753 | show_field(FLD_STMAX(&fields[20])); |
1754 | show_field(FLD_ANCHOR(&fields[24])); |
1755 | |
1756 | return (1); |
1757 | } |