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