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