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