Deleted Added
sdiff udiff text old ( 126259 ) new ( 126261 )
full compact
1/* $FreeBSD: head/sys/contrib/pf/net/if_pflog.c 126261 2004-02-26 02:34:12Z mlaier $ */
2/* $OpenBSD: if_pflog.c,v 1.9 2003/05/14 08:42:00 canacar Exp $ */
3/*
4 * The authors of this code are John Ioannidis (ji@tla.org),
5 * Angelos D. Keromytis (kermit@csd.uch.gr) and
6 * Niels Provos (provos@physnet.uni-hamburg.de).
7 *
8 * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
9 * in November 1995.

--- 19 unchanged lines hidden (view full) ---

29 *
30 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
31 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
32 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
33 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
34 * PURPOSE.
35 */
36
37#if defined(__FreeBSD__)
38#include "opt_inet.h"
39#include "opt_inet6.h"
40#endif
41
42#if !defined(__FreeBSD__)
43#include "bpfilter.h"
44#include "pflog.h"
45#elif __FreeBSD__ >= 5
46#include "opt_bpf.h"
47#define NBPFILTER DEV_BPF
48#include "opt_pf.h"
49#define NPFLOG DEV_PFLOG
50#endif
51
52#include <sys/param.h>
53#include <sys/systm.h>
54#include <sys/mbuf.h>
55#include <sys/socket.h>
56#if defined(__FreeBSD__)
57#include <sys/kernel.h>
58#include <sys/malloc.h>
59#include <sys/sockio.h>
60#else
61#include <sys/ioctl.h>
62#endif
63
64#include <net/if.h>
65#include <net/if_types.h>
66#include <net/route.h>
67#include <net/bpf.h>
68
69#ifdef INET
70#include <netinet/in.h>
71#include <netinet/in_var.h>
72#include <netinet/in_systm.h>
73#include <netinet/ip.h>
74#endif
75
76#if defined(__FreeBSD__)
77#include <machine/in_cksum.h>
78#endif
79
80#ifdef INET6
81#ifndef INET
82#include <netinet/in.h>
83#endif
84#include <netinet6/nd6.h>
85#endif /* INET6 */
86
87#include <net/pfvar.h>
88#include <net/if_pflog.h>
89
90#if defined(__FreeBSD__)
91#define PFLOGNAME "pflog"
92#endif
93
94#define PFLOGMTU (32768 + MHLEN + MLEN)
95
96#ifdef PFLOGDEBUG
97#define DPRINTF(x) do { if (pflogdebug) printf x ; } while (0)
98#else
99#define DPRINTF(x)
100#endif
101
102#if !defined(__FreeBSD__)
103struct pflog_softc pflogif[NPFLOG];
104#endif
105
106#if defined(__FreeBSD__)
107void pflog_clone_destroy(struct ifnet *);
108int pflog_clone_create(struct if_clone *, int);
109#else
110void pflogattach(int);
111#endif
112int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
113 struct rtentry *);
114int pflogioctl(struct ifnet *, u_long, caddr_t);
115void pflogrtrequest(int, struct rtentry *, struct sockaddr *);
116void pflogstart(struct ifnet *);
117
118#if !defined(__FreeBSD__)
119extern int ifqmaxlen;
120#endif
121
122#if defined(__FreeBSD__)
123static MALLOC_DEFINE(M_PFLOG, PFLOGNAME, "Packet Filter Logging Interface");
124static LIST_HEAD(pflog_list, pflog_softc) pflog_list;
125struct if_clone pflog_cloner = IF_CLONE_INITIALIZER(PFLOGNAME,
126 pflog_clone_create, pflog_clone_destroy, 1, IF_MAXUNIT);
127
128void
129pflog_clone_destroy(struct ifnet *ifp)
130{
131 struct pflog_softc *sc;
132
133 sc = ifp->if_softc;
134
135 /*
136 * Does we really need this?
137 */
138 IF_DRAIN(&ifp->if_snd);
139
140 bpfdetach(ifp);
141 if_detach(ifp);
142 LIST_REMOVE(sc, sc_next);
143 free(sc, M_PFLOG);
144}
145#endif /* __FreeBSD__ */
146
147#if defined(__FreeBSD__)
148int
149pflog_clone_create(struct if_clone *ifc, int unit)
150{
151 struct pflog_softc *sc;
152
153 MALLOC(sc, struct pflog_softc *, sizeof(*sc), M_PFLOG, M_WAITOK|M_ZERO);
154
155#if (__FreeBSD_version < 501113)
156 sc->sc_if.if_name = PFLOGNAME;
157 sc->sc_if.if_unit = unit;
158#else
159 if_initname(&sc->sc_if, ifc->ifc_name, unit);
160#endif
161 sc->sc_if.if_mtu = PFLOGMTU;
162 sc->sc_if.if_ioctl = pflogioctl;
163 sc->sc_if.if_output = pflogoutput;
164 sc->sc_if.if_start = pflogstart;
165 sc->sc_if.if_type = IFT_PFLOG;
166 sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen;
167 sc->sc_if.if_hdrlen = PFLOG_HDRLEN;
168 sc->sc_if.if_softc = sc;
169 /*
170 * We would get a message like
171 * "in6_ifattach: pflog0 is not multicast capable, IPv6 not enabled".
172 * We need a patch to in6_ifattach() to exclude interface type
173 * IFT_PFLOG.
174 */
175 if_attach(&sc->sc_if);
176
177 LIST_INSERT_HEAD(&pflog_list, sc, sc_next);
178#if NBPFILTER > 0
179 bpfattach(&sc->sc_if, DLT_PFLOG, PFLOG_HDRLEN);
180#endif
181
182 return (0);
183}
184#else /* !__FreeBSD__ */
185void
186pflogattach(int npflog)
187{
188 struct ifnet *ifp;
189 int i;
190
191 bzero(pflogif, sizeof(pflogif));
192
193 for (i = 0; i < NPFLOG; i++) {

--- 11 unchanged lines hidden (view full) ---

205 if_alloc_sadl(ifp);
206
207#if NBPFILTER > 0
208 bpfattach(&pflogif[i].sc_if.if_bpf, ifp, DLT_PFLOG,
209 PFLOG_HDRLEN);
210#endif
211 }
212}
213#endif /* __FreeBSD__ */
214
215/*
216 * Start output on the pflog interface.
217 */
218void
219pflogstart(struct ifnet *ifp)
220{
221 struct mbuf *m;
222#if defined(__FreeBSD__) && defined(ALTQ)
223 struct ifaltq *ifq;
224#else
225 struct ifqueue *ifq;
226#endif
227 int s;
228
229#if defined(__FreeBSD__)
230 ifq = &ifp->if_snd;
231#endif
232 for (;;) {
233 s = splimp();
234#if defined(__FreeBSD__)
235 IF_LOCK(ifq);
236 _IF_DROP(ifq);
237 _IF_DEQUEUE(ifq, m);
238 IF_UNLOCK(ifq);
239#else
240 IF_DROP(&ifp->if_snd);
241 IF_DEQUEUE(&ifp->if_snd, m);
242#endif
243 splx(s);
244 if (m == NULL)
245 return;
246 else
247 m_freem(m);
248 }
249}
250
251int

--- 45 unchanged lines hidden (view full) ---

297
298 if (ifp == NULL || m == NULL || rm == NULL)
299 return (-1);
300
301 hdr.length = PFLOG_REAL_HDRLEN;
302 hdr.af = af;
303 hdr.action = rm->action;
304 hdr.reason = reason;
305#if defined(__FreeBSD__) && (__FreeBSD_version < 501113)
306 snprintf(hdr.ifname, IFNAMSIZ, "%s%d", ifp->if_name, ifp->if_unit);
307#else
308 memcpy(hdr.ifname, ifp->if_xname, sizeof(hdr.ifname));
309#endif
310
311 if (am == NULL) {
312 hdr.rulenr = htonl(rm->nr);
313 hdr.subrulenr = -1;
314 bzero(hdr.ruleset, sizeof(hdr.ruleset));
315 } else {
316 hdr.rulenr = htonl(am->nr);
317 hdr.subrulenr = htonl(rm->nr);

--- 16 unchanged lines hidden (view full) ---

334 ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
335 }
336#endif /* INET */
337
338 m1.m_next = m;
339 m1.m_len = PFLOG_HDRLEN;
340 m1.m_data = (char *) &hdr;
341
342#if defined(__FreeBSD__)
343 KASSERT((!LIST_EMPTY(&pflog_list)), ("pflog: no interface"));
344 ifn = &LIST_FIRST(&pflog_list)->sc_if;
345#else
346 ifn = &(pflogif[0].sc_if);
347#endif
348
349 if (ifn->if_bpf)
350 bpf_mtap(ifn->if_bpf, &m1);
351#endif
352
353 return (0);
354}
355
356#if defined(__FreeBSD__)
357static int
358pflog_modevent(module_t mod, int type, void *data)
359{
360 int error = 0;
361
362 switch (type) {
363 case MOD_LOAD:
364 LIST_INIT(&pflog_list);
365 if_clone_attach(&pflog_cloner);
366 printf("pflog: $Name: $\n");
367 break;
368
369 case MOD_UNLOAD:
370 if_clone_detach(&pflog_cloner);
371 while (!LIST_EMPTY(&pflog_list))
372 pflog_clone_destroy(
373 &LIST_FIRST(&pflog_list)->sc_if);
374 break;
375
376 default:
377 error = EINVAL;
378 break;
379 }
380
381 return error;
382}
383
384static moduledata_t pflog_mod = {
385 "pflog",
386 pflog_modevent,
387 0
388};
389
390#define PFLOG_MODVER 1
391
392DECLARE_MODULE(pflog, pflog_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
393MODULE_VERSION(pflog, PFLOG_MODVER);
394#endif /* __FreeBSD__ */