Annotation of src/usr.bin/systat/pf.c, Revision 1.5
1.5 ! deraadt 1: /* $OpenBSD: pf.c,v 1.4 2011/03/02 06:48:17 jasper 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>
19: #include <sys/ioctl.h>
20: #include <sys/socket.h>
21: #include <net/if.h>
22: #include <netinet/in.h>
23: #include <netinet/in_systm.h>
24: #include <netinet/ip.h>
25: #include <net/pfvar.h>
26:
27: #include <stdio.h>
28: #include <stdlib.h>
29: #include <string.h>
30: #include <ctype.h>
31: #include <errno.h>
32: #include <err.h>
33: #include <unistd.h>
1.2 mcbride 34: #include <syslog.h>
1.1 canacar 35: #include "pfctl_parser.h"
36: #include "systat.h"
37:
38: void print_pf(void);
39: int read_pf(void);
40: int select_pf(void);
1.3 lum 41: void print_fld_double(field_def *, double);
1.1 canacar 42:
43: const char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES;
44: const char *pf_lcounters[LCNT_MAX+1] = LCNT_NAMES;
45: const char *pf_fcounters[FCNT_MAX+1] = FCNT_NAMES;
46: const char *pf_scounters[FCNT_MAX+1] = FCNT_NAMES;
47:
48: static struct pf_status status;
49: extern int pf_dev;
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: {"NOTES", 10, 20, 1, FLD_ALIGN_LEFT, -1, 0, 0, 60},
58: };
59:
1.4 jasper 60: #define FLD_PF_TYPE FIELD_ADDR(fields_pf,0)
61: #define FLD_PF_NAME FIELD_ADDR(fields_pf,1)
62: #define FLD_PF_VALUE FIELD_ADDR(fields_pf,2)
63: #define FLD_PF_RATE FIELD_ADDR(fields_pf,3)
64: #define FLD_PF_DESC FIELD_ADDR(fields_pf,4)
1.1 canacar 65:
66: /* Define views */
67: field_def *view_pf_0[] = {
68: FLD_PF_TYPE, FLD_PF_NAME, FLD_PF_VALUE, FLD_PF_RATE, FLD_PF_DESC, NULL
69: };
70:
71:
72: /* Define view managers */
73: struct view_manager pf_mgr = {
74: "PF", select_pf, read_pf, NULL, print_header,
75: print_pf, keyboard_callback, NULL, NULL
76: };
77:
78: field_view views_pf[] = {
79: {view_pf_0, "pf", 'P', &pf_mgr},
80: {NULL, NULL, 0, NULL}
81: };
82:
83:
84:
85: int
86: select_pf(void)
87: {
88: return (0);
89: }
90:
91: int
92: read_pf(void)
93: {
94: if (pf_dev < 0) {
95: num_disp = 0;
96: return 0;
97: }
98:
99: if (ioctl(pf_dev, DIOCGETSTATUS, &status)) {
100: error("DIOCGETSTATUS: %s", strerror(errno));
101: return (-1);
102: }
103:
104: num_disp = 4;
105:
106: if (status.ifname[0] != 0)
107: num_disp += 13;
108:
109: num_disp += FCNT_MAX + 2;
110: num_disp += SCNT_MAX + 2;
111: num_disp += PFRES_MAX + 1;
112: num_disp += LCNT_MAX + 1;
113:
114: return (0);
115: }
116:
117: int
118: initpf(void)
119: {
120: field_view *v;
121:
122: for (v = views_pf; v->name != NULL; v++)
123: add_view(v);
124:
125: return(1);
126: }
127:
128: void
129: print_fld_double(field_def *fld, double val)
130: {
131: int len;
132:
133: if (fld == NULL)
134: return;
135:
136: len = fld->width;
137: if (len < 1)
138: return;
139:
140: tb_start();
141: if (tbprintf("%.2f", val) > len)
142: print_fld_str(fld, "*");
143: else
144: print_fld_tb(fld);
145: tb_end();
146: }
147:
148: #define ADD_LINE_A(t, n, v) \
149: do { \
150: if (cur >= dispstart && cur < end) { \
151: print_fld_str(FLD_PF_TYPE, (t)); \
152: print_fld_str(FLD_PF_NAME, (n)); \
153: print_fld_age(FLD_PF_VALUE, (v)); \
154: end_line(); \
155: } \
156: if (++cur >= end) \
157: return; \
158: } while (0)
159:
160: #define ADD_EMPTY_LINE \
161: do { \
162: if (cur >= dispstart && cur < end) \
163: end_line(); \
164: if (++cur >= end) \
165: return; \
166: } while (0)
167:
168: #define ADD_LINE_S(t, n, v) \
169: do { \
170: if (cur >= dispstart && cur < end) { \
171: print_fld_str(FLD_PF_TYPE, (t)); \
172: print_fld_str(FLD_PF_NAME, (n)); \
173: print_fld_str(FLD_PF_VALUE, (v)); \
174: end_line(); \
175: } \
176: if (++cur >= end) \
177: return; \
178: } while (0)
179:
180: #define ADD_LINE_V(t, n, v) \
181: do { \
182: if (cur >= dispstart && cur < end) { \
183: print_fld_str(FLD_PF_TYPE, (t)); \
184: print_fld_str(FLD_PF_NAME, (n)); \
185: print_fld_size(FLD_PF_VALUE, (v)); \
186: end_line(); \
187: } \
188: if (++cur >= end) \
189: return; \
190: } while (0)
191:
192: #define ADD_LINE_VD(t, n, v, d) \
193: do { \
194: if (cur >= dispstart && cur < end) { \
195: print_fld_str(FLD_PF_TYPE, (t)); \
196: print_fld_str(FLD_PF_NAME, (n)); \
197: print_fld_size(FLD_PF_VALUE, (v)); \
198: print_fld_str(FLD_PF_DESC, (d)); \
199: end_line(); \
200: } \
201: if (++cur >= end) \
202: return; \
203: } while (0)
204:
205: #define ADD_LINE_VR(t, n, v, r) \
206: do { \
207: if (cur >= dispstart && cur < end) { \
208: print_fld_str(FLD_PF_TYPE, (t)); \
209: print_fld_str(FLD_PF_NAME, (n)); \
210: print_fld_size(FLD_PF_VALUE, (v)); \
211: print_fld_double(FLD_PF_RATE, (r)); \
212: end_line(); \
213: } \
214: if (++cur >= end) \
215: return; \
216: } while (0)
217:
218:
219: void
220: print_pf(void)
221: {
222: char *debug;
223: time_t tm;
224: int i;
225: struct pf_status *s = &status;
226:
227: int cur = 0;
228: int end = dispstart + maxprint;
229: if (end > num_disp)
230: end = num_disp;
231:
232: tm = time(NULL) - s->since;
233:
234: ADD_LINE_S("pf", "Status", s->running ? "Enabled" : "Disabled");
235: ADD_LINE_A("pf", "Since", tm);
236:
237: switch (s->debug) {
1.2 mcbride 238: case LOG_EMERG:
239: debug = "emerg";
1.1 canacar 240: break;
1.2 mcbride 241: case LOG_ALERT:
242: debug = "alert";
1.1 canacar 243: break;
1.2 mcbride 244: case LOG_CRIT:
245: debug = "crit";
1.1 canacar 246: break;
1.2 mcbride 247: case LOG_ERR:
248: debug = "err";
249: break;
250: case LOG_WARNING:
251: debug = "warning";
252: break;
253: case LOG_NOTICE:
254: debug = "notice";
255: break;
256: case LOG_INFO:
257: debug = "info";
258: break;
259: case LOG_DEBUG:
260: debug = "debug";
1.1 canacar 261: break;
262: }
263: ADD_LINE_S("pf", "Debug", debug);
264:
265: tb_start();
266: tbprintf("0x%08x\n", ntohl(s->hostid));
267: tb_end();
268:
269: ADD_LINE_S("pf", "Hostid", tmp_buf);
270:
271: if (s->ifname[0] != 0) {
272: ADD_EMPTY_LINE;
273: ADD_LINE_VD(s->ifname, "Bytes In", s->bcounters[0][0], "IPv4");
274: ADD_LINE_VD(s->ifname, "Bytes In", s->bcounters[1][0], "IPv6");
275: ADD_LINE_VD(s->ifname, "Bytes Out", s->bcounters[0][1], "IPv4");
276: ADD_LINE_VD(s->ifname, "Bytes Out", s->bcounters[1][1], "IPv6");
277: ADD_LINE_VD(s->ifname, "Packets In", s->pcounters[0][0][PF_PASS], "IPv4, Passed");
278: ADD_LINE_VD(s->ifname, "Packets In", s->pcounters[1][0][PF_PASS], "IPv6, Passed");
279: ADD_LINE_VD(s->ifname, "Packets In", s->pcounters[0][0][PF_DROP], "IPv4, Blocked");
280: ADD_LINE_VD(s->ifname, "Packets In", s->pcounters[1][0][PF_DROP], "IPv6, Blocked");
281: ADD_LINE_VD(s->ifname, "Packets Out", s->pcounters[0][1][PF_PASS], "IPv4, Passed");
282: ADD_LINE_VD(s->ifname, "Packets Out", s->pcounters[1][1][PF_PASS], "IPv6, Passed");
283: ADD_LINE_VD(s->ifname, "Packets Out", s->pcounters[0][1][PF_DROP], "IPv4, Blocked");
284: ADD_LINE_VD(s->ifname, "Packets Out", s->pcounters[1][1][PF_DROP], "IPv6, Blocked");
285: }
286:
287:
288: ADD_EMPTY_LINE;
289: ADD_LINE_V("state", "Count", s->states);
290:
291: for (i = 0; i < FCNT_MAX; i++) {
292: if (tm > 0)
293: ADD_LINE_VR("state", pf_fcounters[i], s->fcounters[i],
294: (double)s->fcounters[i] / (double)tm);
295: else
296: ADD_LINE_V("state", pf_fcounters[i], s->fcounters[i]);
297: }
298:
299:
300: ADD_EMPTY_LINE;
301: ADD_LINE_V("src track", "Count", s->src_nodes);
302:
303: for (i = 0; i < SCNT_MAX; i++) {
304: if (tm > 0)
305: ADD_LINE_VR("src track", pf_scounters[i], s->scounters[i],
306: (double)s->scounters[i] / (double)tm);
307: else
308: ADD_LINE_V("src track", pf_scounters[i], s->scounters[i]);
309: }
310:
311: ADD_EMPTY_LINE;
312: for (i = 0; i < PFRES_MAX; i++) {
313: if (tm > 0)
314: ADD_LINE_VR("counter", pf_reasons[i], s->counters[i],
315: (double)s->counters[i] / (double)tm);
316: else
317: ADD_LINE_V("counter", pf_reasons[i], s->counters[i]);
318: }
319:
320: ADD_EMPTY_LINE;
321: for (i = 0; i < LCNT_MAX; i++) {
322: if (tm > 0)
323: ADD_LINE_VR("limit counter", pf_lcounters[i], s->lcounters[i],
324: (double)s->lcounters[i] / (double)tm);
325: else
326: ADD_LINE_V("limit counter", pf_lcounters[i], s->lcounters[i]);
327: }
328: }