Annotation of src/usr.bin/systat/pf.c, Revision 1.13
1.13 ! kn 1: /* $OpenBSD: pf.c,v 1.12 2020/05/15 00:56:03 cheloha Exp $ */
1.1 canacar 2: /*
3: * Copyright (c) 2001, 2007 Can Erkin Acar <canacar@openbsd.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: #include <sys/types.h>
1.10 claudio 19: #include <sys/sysctl.h>
1.1 canacar 20: #include <sys/ioctl.h>
21: #include <sys/socket.h>
1.7 deraadt 22: #include <sys/signal.h>
1.1 canacar 23: #include <net/if.h>
24: #include <netinet/in.h>
25: #include <netinet/ip.h>
26: #include <net/pfvar.h>
27:
28: #include <stdio.h>
29: #include <stdlib.h>
30: #include <string.h>
31: #include <ctype.h>
32: #include <errno.h>
33: #include <err.h>
34: #include <unistd.h>
1.2 mcbride 35: #include <syslog.h>
1.1 canacar 36: #include "pfctl_parser.h"
37: #include "systat.h"
38:
39: void print_pf(void);
40: int read_pf(void);
41: int select_pf(void);
1.3 lum 42: void print_fld_double(field_def *, double);
1.1 canacar 43:
44: const char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES;
45: const char *pf_lcounters[LCNT_MAX+1] = LCNT_NAMES;
46: const char *pf_fcounters[FCNT_MAX+1] = FCNT_NAMES;
47: const char *pf_scounters[FCNT_MAX+1] = FCNT_NAMES;
48:
49: static struct pf_status status;
50: int num_pf = 0;
51:
52: field_def fields_pf[] = {
53: {"TYPE", 13, 16, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
54: {"NAME", 12, 24, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
55: {"VALUE", 8, 10, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
56: {"RATE", 8, 10, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 60},
57: };
58:
1.4 jasper 59: #define FLD_PF_TYPE FIELD_ADDR(fields_pf,0)
60: #define FLD_PF_NAME FIELD_ADDR(fields_pf,1)
61: #define FLD_PF_VALUE FIELD_ADDR(fields_pf,2)
62: #define FLD_PF_RATE FIELD_ADDR(fields_pf,3)
1.1 canacar 63:
64: /* Define views */
65: field_def *view_pf_0[] = {
1.13 ! kn 66: FLD_PF_TYPE, FLD_PF_NAME, FLD_PF_VALUE, FLD_PF_RATE, NULL
1.1 canacar 67: };
68:
69:
70: /* Define view managers */
71: struct view_manager pf_mgr = {
72: "PF", select_pf, read_pf, NULL, print_header,
73: print_pf, keyboard_callback, NULL, NULL
74: };
75:
76: field_view views_pf[] = {
77: {view_pf_0, "pf", 'P', &pf_mgr},
78: {NULL, NULL, 0, NULL}
79: };
80:
81:
82:
83: int
84: select_pf(void)
85: {
86: return (0);
87: }
88:
89: int
90: read_pf(void)
91: {
1.10 claudio 92: size_t size = sizeof(status);
93: int mib[3] = { CTL_KERN, KERN_PFSTATUS };
1.1 canacar 94:
1.11 deraadt 95: if (sysctl(mib, 2, &status, &size, NULL, 0) == -1) {
1.10 claudio 96: error("sysctl(PFCTL_STATUS): %s", strerror(errno));
1.1 canacar 97: return (-1);
98: }
99:
100: num_disp = 4;
101:
102: if (status.ifname[0] != 0)
103: num_disp += 13;
104:
105: num_disp += FCNT_MAX + 2;
106: num_disp += SCNT_MAX + 2;
107: num_disp += PFRES_MAX + 1;
108: num_disp += LCNT_MAX + 1;
109:
110: return (0);
111: }
112:
113: int
114: initpf(void)
115: {
116: field_view *v;
117:
118: for (v = views_pf; v->name != NULL; v++)
119: add_view(v);
120:
121: return(1);
122: }
123:
124: void
125: print_fld_double(field_def *fld, double val)
126: {
127: int len;
128:
129: if (fld == NULL)
130: return;
131:
132: len = fld->width;
133: if (len < 1)
134: return;
135:
136: tb_start();
137: if (tbprintf("%.2f", val) > len)
138: print_fld_str(fld, "*");
139: else
140: print_fld_tb(fld);
141: tb_end();
142: }
143:
144: #define ADD_LINE_A(t, n, v) \
145: do { \
146: if (cur >= dispstart && cur < end) { \
147: print_fld_str(FLD_PF_TYPE, (t)); \
148: print_fld_str(FLD_PF_NAME, (n)); \
149: print_fld_age(FLD_PF_VALUE, (v)); \
150: end_line(); \
151: } \
152: if (++cur >= end) \
153: return; \
154: } while (0)
155:
156: #define ADD_EMPTY_LINE \
157: do { \
158: if (cur >= dispstart && cur < end) \
159: end_line(); \
160: if (++cur >= end) \
161: return; \
162: } while (0)
163:
164: #define ADD_LINE_S(t, n, v) \
165: do { \
166: if (cur >= dispstart && cur < end) { \
167: print_fld_str(FLD_PF_TYPE, (t)); \
168: print_fld_str(FLD_PF_NAME, (n)); \
169: print_fld_str(FLD_PF_VALUE, (v)); \
170: end_line(); \
171: } \
172: if (++cur >= end) \
173: return; \
174: } while (0)
175:
176: #define ADD_LINE_V(t, n, v) \
177: do { \
178: if (cur >= dispstart && cur < end) { \
179: print_fld_str(FLD_PF_TYPE, (t)); \
180: print_fld_str(FLD_PF_NAME, (n)); \
181: print_fld_size(FLD_PF_VALUE, (v)); \
182: end_line(); \
183: } \
184: if (++cur >= end) \
185: return; \
186: } while (0)
187:
188: #define ADD_LINE_VR(t, n, v, r) \
189: do { \
190: if (cur >= dispstart && cur < end) { \
191: print_fld_str(FLD_PF_TYPE, (t)); \
192: print_fld_str(FLD_PF_NAME, (n)); \
193: print_fld_size(FLD_PF_VALUE, (v)); \
194: print_fld_double(FLD_PF_RATE, (r)); \
195: end_line(); \
196: } \
197: if (++cur >= end) \
198: return; \
199: } while (0)
200:
201:
202: void
203: print_pf(void)
204: {
205: char *debug;
1.9 patrick 206: time_t tm = 0;
207: struct timespec uptime;
1.1 canacar 208: int i;
209: struct pf_status *s = &status;
210:
211: int cur = 0;
212: int end = dispstart + maxprint;
213: if (end > num_disp)
214: end = num_disp;
215:
1.12 cheloha 216: if (!clock_gettime(CLOCK_BOOTTIME, &uptime))
1.9 patrick 217: tm = uptime.tv_sec - s->since;
1.1 canacar 218:
219: ADD_LINE_S("pf", "Status", s->running ? "Enabled" : "Disabled");
220: ADD_LINE_A("pf", "Since", tm);
221:
222: switch (s->debug) {
1.2 mcbride 223: case LOG_EMERG:
224: debug = "emerg";
1.1 canacar 225: break;
1.2 mcbride 226: case LOG_ALERT:
227: debug = "alert";
1.1 canacar 228: break;
1.2 mcbride 229: case LOG_CRIT:
230: debug = "crit";
1.1 canacar 231: break;
1.2 mcbride 232: case LOG_ERR:
233: debug = "err";
234: break;
235: case LOG_WARNING:
236: debug = "warning";
237: break;
238: case LOG_NOTICE:
239: debug = "notice";
240: break;
241: case LOG_INFO:
242: debug = "info";
243: break;
244: case LOG_DEBUG:
245: debug = "debug";
1.1 canacar 246: break;
1.8 benno 247: default:
248: debug = "unknown";
249: break;
1.1 canacar 250: }
251: ADD_LINE_S("pf", "Debug", debug);
252:
253: tb_start();
254: tbprintf("0x%08x\n", ntohl(s->hostid));
255: tb_end();
256:
257: ADD_LINE_S("pf", "Hostid", tmp_buf);
258:
259: if (s->ifname[0] != 0) {
260: ADD_EMPTY_LINE;
1.13 ! kn 261: ADD_LINE_V(s->ifname, "Bytes In IPv4", s->bcounters[0][0]);
! 262: ADD_LINE_V(s->ifname, "Bytes In IPv6", s->bcounters[1][0]);
! 263: ADD_LINE_V(s->ifname, "Bytes Out IPv4", s->bcounters[0][1]);
! 264: ADD_LINE_V(s->ifname, "Bytes Out IPv6", s->bcounters[1][1]);
! 265: ADD_LINE_V(s->ifname, "Packets In Passed IPv4", s->pcounters[0][0][PF_PASS]);
! 266: ADD_LINE_V(s->ifname, "Packets In Passed IPv6", s->pcounters[1][0][PF_PASS]);
! 267: ADD_LINE_V(s->ifname, "Packets In Blocked IPv4", s->pcounters[0][0][PF_DROP]);
! 268: ADD_LINE_V(s->ifname, "Packets In Blocked IPv6", s->pcounters[1][0][PF_DROP]);
! 269: ADD_LINE_V(s->ifname, "Packets Out Passed IPv4", s->pcounters[0][1][PF_PASS]);
! 270: ADD_LINE_V(s->ifname, "Packets Out Passed IPv6", s->pcounters[1][1][PF_PASS]);
! 271: ADD_LINE_V(s->ifname, "Packets Out Blocked IPv4", s->pcounters[0][1][PF_DROP]);
! 272: ADD_LINE_V(s->ifname, "Packets Out Blocked IPv6", s->pcounters[1][1][PF_DROP]);
1.1 canacar 273: }
274:
275:
276: ADD_EMPTY_LINE;
277: ADD_LINE_V("state", "Count", s->states);
278:
279: for (i = 0; i < FCNT_MAX; i++) {
280: if (tm > 0)
281: ADD_LINE_VR("state", pf_fcounters[i], s->fcounters[i],
282: (double)s->fcounters[i] / (double)tm);
283: else
284: ADD_LINE_V("state", pf_fcounters[i], s->fcounters[i]);
285: }
286:
287:
288: ADD_EMPTY_LINE;
289: ADD_LINE_V("src track", "Count", s->src_nodes);
290:
291: for (i = 0; i < SCNT_MAX; i++) {
292: if (tm > 0)
293: ADD_LINE_VR("src track", pf_scounters[i], s->scounters[i],
294: (double)s->scounters[i] / (double)tm);
295: else
296: ADD_LINE_V("src track", pf_scounters[i], s->scounters[i]);
297: }
298:
299: ADD_EMPTY_LINE;
300: for (i = 0; i < PFRES_MAX; i++) {
301: if (tm > 0)
302: ADD_LINE_VR("counter", pf_reasons[i], s->counters[i],
303: (double)s->counters[i] / (double)tm);
304: else
305: ADD_LINE_V("counter", pf_reasons[i], s->counters[i]);
306: }
307:
308: ADD_EMPTY_LINE;
309: for (i = 0; i < LCNT_MAX; i++) {
310: if (tm > 0)
311: ADD_LINE_VR("limit counter", pf_lcounters[i], s->lcounters[i],
312: (double)s->lcounters[i] / (double)tm);
313: else
314: ADD_LINE_V("limit counter", pf_lcounters[i], s->lcounters[i]);
315: }
316: }