1 /*
2  * Copyright (c) 2002 Daniel Hartmeier
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  *    - Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *    - Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials provided
14  *      with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  */
30 
31 /*
32  * Get current pf statistics and return them in symon_buf as
33  *
34  *   bytes_v4_in : bytes_v4_out : bytes_v6_in : bytes_v6_out :
35  *   packets_v4_in_pass : * packets_v4_in_drop : packets_v4_out_pass :
36  *   packets_v4_out_drop : * packets_v6_in_pass : packets_v6_in_drop :
37  *   packets_v6_out_pass : * packets_v6_out_drop : states_entries :
38  *   states_searches : states_inserts : * states_removals : counters_match :
39  *   counters_badoffset : counters_fragment : * counters_short :
40  *   counters_normalize : counters_memory
41  *
42  */
43 
44 #include "conf.h"
45 
46 #include <sys/types.h>
47 #include <sys/ioctl.h>
48 #include <sys/socket.h>
49 
50 #include <netinet/in.h>
51 #include <net/if.h>
52 #ifdef HAS_PFVAR_H
53 #include <net/pfvar.h>
54 #endif
55 #include <errno.h>
56 #include <fcntl.h>
57 #include <string.h>
58 
59 #include "error.h"
60 #include "symon.h"
61 
62 #ifndef HAS_PFVAR_H
63 void
privinit_pf()64 privinit_pf()
65 {
66 }
67 void
init_pf(struct stream * st)68 init_pf(struct stream *st)
69 {
70     fatal("pf support not available");
71 }
72 int
get_pf(char * symon_buf,int maxlen,struct stream * st)73 get_pf(char *symon_buf, int maxlen, struct stream *st)
74 {
75     fatal("pf support not available");
76     return 0;
77 }
78 void
gets_pf()79 gets_pf()
80 {
81     fatal("pf support not available");
82 }
83 
84 #else
85 
86 /* Globals for this module start with pf_ */
87 int pf_dev = -1;
88 struct pf_status pf_stat;
89 
90 void
privinit_pf()91 privinit_pf()
92 {
93     if ((pf_dev = open("/dev/pf", O_RDONLY)) == -1) {
94         warning("could not open \"/dev/pf\", %.200s", strerror(errno));
95     }
96 }
97 
98 void
init_pf(struct stream * st)99 init_pf(struct stream *st)
100 {
101     if (pf_dev == -1) {
102         privinit_pf();
103     }
104 
105     info("started module pf()");
106 }
107 
108 void
gets_pf()109 gets_pf()
110 {
111     if (pf_dev == -1) {
112         warning("could not get pf stats (dev == -1)");
113         pf_stat.running = 0;
114         return;
115     }
116 
117     if (ioctl(pf_dev, DIOCGETSTATUS, &pf_stat)) {
118         warning("could not get pf stats (ioctl error)");
119         pf_stat.running = 0;
120         return;
121     }
122 }
123 
124 int
get_pf(char * symon_buf,int maxlen,struct stream * st)125 get_pf(char *symon_buf, int maxlen, struct stream *st)
126 {
127     u_int64_t n;
128 
129     if (!pf_stat.running) {
130         return 0;
131     }
132 
133     n = pf_stat.states;
134     return snpack(symon_buf, maxlen, st->arg, MT_PF,
135                   pf_stat.bcounters[0][0],
136                   pf_stat.bcounters[0][1],
137                   pf_stat.bcounters[1][0],
138                   pf_stat.bcounters[1][1],
139                   pf_stat.pcounters[0][0][PF_PASS],
140                   pf_stat.pcounters[0][0][PF_DROP],
141                   pf_stat.pcounters[0][1][PF_PASS],
142                   pf_stat.pcounters[0][1][PF_DROP],
143                   pf_stat.pcounters[1][0][PF_PASS],
144                   pf_stat.pcounters[1][0][PF_DROP],
145                   pf_stat.pcounters[1][1][PF_PASS],
146                   pf_stat.pcounters[1][1][PF_DROP],
147                   n,
148                   pf_stat.fcounters[0],
149                   pf_stat.fcounters[1],
150                   pf_stat.fcounters[2],
151                   pf_stat.counters[0],
152                   pf_stat.counters[1],
153                   pf_stat.counters[2],
154                   pf_stat.counters[3],
155                   pf_stat.counters[4],
156                   pf_stat.counters[5]
157         );
158 }
159 #endif /* HAS_PFVAR_H */
160