This source file includes following definitions.
- pflogattach
- pflog_clone_create
- pflog_clone_destroy
- pflogstart
- pflogoutput
- pflogioctl
- pflog_packet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include "bpfilter.h"
37 #include "pflog.h"
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/mbuf.h>
42 #include <sys/proc.h>
43 #include <sys/socket.h>
44 #include <sys/ioctl.h>
45
46 #include <net/if.h>
47 #include <net/if_types.h>
48 #include <net/route.h>
49 #include <net/bpf.h>
50
51 #ifdef INET
52 #include <netinet/in.h>
53 #include <netinet/in_var.h>
54 #include <netinet/in_systm.h>
55 #include <netinet/ip.h>
56 #endif
57
58 #ifdef INET6
59 #ifndef INET
60 #include <netinet/in.h>
61 #endif
62 #include <netinet6/nd6.h>
63 #endif
64
65 #include <net/pfvar.h>
66 #include <net/if_pflog.h>
67
68 #define PFLOGMTU (32768 + MHLEN + MLEN)
69
70 #ifdef PFLOGDEBUG
71 #define DPRINTF(x) do { if (pflogdebug) printf x ; } while (0)
72 #else
73 #define DPRINTF(x)
74 #endif
75
76 void pflogattach(int);
77 int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
78 struct rtentry *);
79 int pflogioctl(struct ifnet *, u_long, caddr_t);
80 void pflogstart(struct ifnet *);
81 int pflog_clone_create(struct if_clone *, int);
82 int pflog_clone_destroy(struct ifnet *);
83
84 LIST_HEAD(, pflog_softc) pflogif_list;
85 struct if_clone pflog_cloner =
86 IF_CLONE_INITIALIZER("pflog", pflog_clone_create, pflog_clone_destroy);
87
88 struct ifnet *pflogifs[PFLOGIFS_MAX];
89
90 void
91 pflogattach(int npflog)
92 {
93 int i;
94 LIST_INIT(&pflogif_list);
95 for (i = 0; i < PFLOGIFS_MAX; i++)
96 pflogifs[i] = NULL;
97 if_clone_attach(&pflog_cloner);
98 }
99
100 int
101 pflog_clone_create(struct if_clone *ifc, int unit)
102 {
103 struct ifnet *ifp;
104 struct pflog_softc *pflogif;
105 int s;
106
107 if (unit >= PFLOGIFS_MAX)
108 return (EINVAL);
109
110 if ((pflogif = malloc(sizeof(*pflogif), M_DEVBUF, M_NOWAIT)) == NULL)
111 return (ENOMEM);
112 bzero(pflogif, sizeof(*pflogif));
113
114 pflogif->sc_unit = unit;
115 ifp = &pflogif->sc_if;
116 snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflog%d", unit);
117 ifp->if_softc = pflogif;
118 ifp->if_mtu = PFLOGMTU;
119 ifp->if_ioctl = pflogioctl;
120 ifp->if_output = pflogoutput;
121 ifp->if_start = pflogstart;
122 ifp->if_type = IFT_PFLOG;
123 ifp->if_snd.ifq_maxlen = ifqmaxlen;
124 ifp->if_hdrlen = PFLOG_HDRLEN;
125 if_attach(ifp);
126 if_alloc_sadl(ifp);
127
128 #if NBPFILTER > 0
129 bpfattach(&pflogif->sc_if.if_bpf, ifp, DLT_PFLOG, PFLOG_HDRLEN);
130 #endif
131
132 s = splnet();
133 LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list);
134 pflogifs[unit] = ifp;
135 splx(s);
136
137 return (0);
138 }
139
140 int
141 pflog_clone_destroy(struct ifnet *ifp)
142 {
143 struct pflog_softc *pflogif = ifp->if_softc;
144 int s;
145
146 s = splnet();
147 pflogifs[pflogif->sc_unit] = NULL;
148 LIST_REMOVE(pflogif, sc_list);
149 splx(s);
150
151 #if NBPFILTER > 0
152 bpfdetach(ifp);
153 #endif
154 if_detach(ifp);
155 free(pflogif, M_DEVBUF);
156 return (0);
157 }
158
159
160
161
162 void
163 pflogstart(struct ifnet *ifp)
164 {
165 struct mbuf *m;
166 int s;
167
168 for (;;) {
169 s = splnet();
170 IF_DROP(&ifp->if_snd);
171 IF_DEQUEUE(&ifp->if_snd, m);
172 splx(s);
173
174 if (m == NULL)
175 return;
176 else
177 m_freem(m);
178 }
179 }
180
181 int
182 pflogoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
183 struct rtentry *rt)
184 {
185 m_freem(m);
186 return (0);
187 }
188
189
190 int
191 pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
192 {
193 switch (cmd) {
194 case SIOCSIFADDR:
195 case SIOCAIFADDR:
196 case SIOCSIFDSTADDR:
197 case SIOCSIFFLAGS:
198 if (ifp->if_flags & IFF_UP)
199 ifp->if_flags |= IFF_RUNNING;
200 else
201 ifp->if_flags &= ~IFF_RUNNING;
202 break;
203 default:
204 return (EINVAL);
205 }
206
207 return (0);
208 }
209
210 int
211 pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
212 u_int8_t reason, struct pf_rule *rm, struct pf_rule *am,
213 struct pf_ruleset *ruleset, struct pf_pdesc *pd)
214 {
215 #if NBPFILTER > 0
216 struct ifnet *ifn;
217 struct pfloghdr hdr;
218
219 if (kif == NULL || m == NULL || rm == NULL || pd == NULL)
220 return (-1);
221
222 if ((ifn = pflogifs[rm->logif]) == NULL || !ifn->if_bpf)
223 return (0);
224
225 bzero(&hdr, sizeof(hdr));
226 hdr.length = PFLOG_REAL_HDRLEN;
227 hdr.af = af;
228 hdr.action = rm->action;
229 hdr.reason = reason;
230 memcpy(hdr.ifname, kif->pfik_name, sizeof(hdr.ifname));
231
232 if (am == NULL) {
233 hdr.rulenr = htonl(rm->nr);
234 hdr.subrulenr = -1;
235 } else {
236 hdr.rulenr = htonl(am->nr);
237 hdr.subrulenr = htonl(rm->nr);
238 if (ruleset != NULL && ruleset->anchor != NULL)
239 strlcpy(hdr.ruleset, ruleset->anchor->name,
240 sizeof(hdr.ruleset));
241 }
242 if (rm->log & PF_LOG_SOCKET_LOOKUP && !pd->lookup.done)
243 pd->lookup.done = pf_socket_lookup(dir, pd);
244 if (pd->lookup.done > 0) {
245 hdr.uid = pd->lookup.uid;
246 hdr.pid = pd->lookup.pid;
247 } else {
248 hdr.uid = UID_MAX;
249 hdr.pid = NO_PID;
250 }
251 hdr.rule_uid = rm->cuid;
252 hdr.rule_pid = rm->cpid;
253 hdr.dir = dir;
254
255 #ifdef INET
256 if (af == AF_INET && dir == PF_OUT) {
257 struct ip *ip;
258
259 ip = mtod(m, struct ip *);
260 ip->ip_sum = 0;
261 ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
262 }
263 #endif
264
265 ifn->if_opackets++;
266 ifn->if_obytes += m->m_pkthdr.len;
267 bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, PFLOG_HDRLEN, m,
268 BPF_DIRECTION_OUT);
269 #endif
270
271 return (0);
272 }