source: rtems-libbsd/freebsd/sys/contrib/pf/net/if_pflog.c @ 66659ff

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 66659ff was 66659ff, checked in by Sebastian Huber <sebastian.huber@…>, on 11/06/13 at 15:20:21

Update to FreeBSD 9.2

  • Property mode set to 100644
File size: 9.1 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
3/*      $OpenBSD: if_pflog.c,v 1.26 2007/10/18 21:58:18 mpf Exp $       */
4/*
5 * The authors of this code are John Ioannidis (ji@tla.org),
6 * Angelos D. Keromytis (kermit@csd.uch.gr) and
7 * Niels Provos (provos@physnet.uni-hamburg.de).
8 *
9 * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
10 * in November 1995.
11 *
12 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
13 * by Angelos D. Keromytis.
14 *
15 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
16 * and Niels Provos.
17 *
18 * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis
19 * and Niels Provos.
20 * Copyright (c) 2001, Angelos D. Keromytis, Niels Provos.
21 *
22 * Permission to use, copy, and modify this software with or without fee
23 * is hereby granted, provided that this entire notice is included in
24 * all copies of any software which is or includes a copy or
25 * modification of this software.
26 * You may use this code under the GNU public license if you so wish. Please
27 * contribute changes back to the authors under this freer than GPL license
28 * so that we may further the use of strong encryption without limitations to
29 * all.
30 *
31 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
32 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
33 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
34 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
35 * PURPOSE.
36 */
37
38#ifdef __FreeBSD__
39#include <rtems/bsd/local/opt_inet.h>
40#include <rtems/bsd/local/opt_inet6.h>
41#include <rtems/bsd/local/opt_bpf.h>
42#include <rtems/bsd/local/opt_pf.h>
43
44#include <sys/cdefs.h>
45__FBSDID("$FreeBSD$");
46
47#ifdef DEV_BPF
48#define NBPFILTER       DEV_BPF
49#else
50#define NBPFILTER       0
51#endif
52
53#ifdef DEV_PFLOG
54#define NPFLOG          DEV_PFLOG
55#else
56#define NPFLOG          0
57#endif
58
59#else /* ! __FreeBSD__ */
60#include "bpfilter.h"
61#include "pflog.h"
62#endif /* __FreeBSD__ */
63
64#include <rtems/bsd/sys/param.h>
65#include <sys/systm.h>
66#include <sys/mbuf.h>
67#include <sys/proc.h>
68#include <sys/socket.h>
69#ifdef __FreeBSD__
70#include <sys/kernel.h>
71#include <sys/limits.h>
72#include <sys/malloc.h>
73#include <sys/module.h>
74#include <sys/sockio.h>
75#else
76#include <sys/ioctl.h>
77#endif
78
79#include <net/if.h>
80#ifdef __FreeBSD__
81#include <net/if_clone.h>
82#endif
83#include <net/if_types.h>
84#include <net/route.h>
85#include <net/bpf.h>
86
87#if defined(INET) || defined(INET6)
88#include <netinet/in.h>
89#endif
90#ifdef  INET
91#include <netinet/in_var.h>
92#include <netinet/in_systm.h>
93#include <netinet/ip.h>
94#endif
95
96#ifdef INET6
97#include <netinet6/in6_var.h>
98#include <netinet6/nd6.h>
99#endif /* INET6 */
100
101#include <net/pfvar.h>
102#include <net/if_pflog.h>
103
104#ifdef __FreeBSD__
105#ifdef INET
106#include <machine/in_cksum.h>
107#endif /* INET */
108#endif /* __FreeBSD__ */
109
110#define PFLOGMTU        (32768 + MHLEN + MLEN)
111
112#ifdef PFLOGDEBUG
113#define DPRINTF(x)    do { if (pflogdebug) printf x ; } while (0)
114#else
115#define DPRINTF(x)
116#endif
117
118void    pflogattach(int);
119int     pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
120#ifdef __FreeBSD__
121            struct route *);
122#else
123            struct rtentry *);
124#endif
125int     pflogioctl(struct ifnet *, u_long, caddr_t);
126void    pflogstart(struct ifnet *);
127#ifdef __FreeBSD__
128static int pflog_clone_create(struct if_clone *, int, caddr_t);
129static void pflog_clone_destroy(struct ifnet *);
130#else
131int     pflog_clone_create(struct if_clone *, int);
132int     pflog_clone_destroy(struct ifnet *);
133#endif
134
135LIST_HEAD(, pflog_softc)        pflogif_list;
136#ifdef __FreeBSD__
137IFC_SIMPLE_DECLARE(pflog, 1);
138#else
139struct if_clone pflog_cloner =
140    IF_CLONE_INITIALIZER("pflog", pflog_clone_create, pflog_clone_destroy);
141#endif
142
143struct ifnet    *pflogifs[PFLOGIFS_MAX];        /* for fast access */
144
145void
146pflogattach(int npflog)
147{
148        int     i;
149        LIST_INIT(&pflogif_list);
150        for (i = 0; i < PFLOGIFS_MAX; i++)
151                pflogifs[i] = NULL;
152        if_clone_attach(&pflog_cloner);
153}
154
155#ifdef __FreeBSD__
156static int
157pflog_clone_create(struct if_clone *ifc, int unit, caddr_t param)
158#else
159int
160pflog_clone_create(struct if_clone *ifc, int unit)
161#endif
162{
163        struct ifnet *ifp;
164        struct pflog_softc *pflogif;
165        int s;
166
167        if (unit >= PFLOGIFS_MAX)
168                return (EINVAL);
169
170        if ((pflogif = malloc(sizeof(*pflogif),
171            M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
172                return (ENOMEM);
173
174        pflogif->sc_unit = unit;
175#ifdef __FreeBSD__
176        ifp = pflogif->sc_ifp = if_alloc(IFT_PFLOG);
177        if (ifp == NULL) {
178                free(pflogif, M_DEVBUF);
179                return (ENOSPC);
180        }
181        if_initname(ifp, ifc->ifc_name, unit);
182#else
183        ifp = &pflogif->sc_if;
184        snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflog%d", unit);
185#endif
186        ifp->if_softc = pflogif;
187        ifp->if_mtu = PFLOGMTU;
188        ifp->if_ioctl = pflogioctl;
189        ifp->if_output = pflogoutput;
190        ifp->if_start = pflogstart;
191#ifndef __FreeBSD__
192        ifp->if_type = IFT_PFLOG;
193#endif
194        ifp->if_snd.ifq_maxlen = ifqmaxlen;
195        ifp->if_hdrlen = PFLOG_HDRLEN;
196        if_attach(ifp);
197#ifndef __FreeBSD__
198        if_alloc_sadl(ifp);
199#endif
200
201#if NBPFILTER > 0
202#ifdef __FreeBSD__
203        bpfattach(ifp, DLT_PFLOG, PFLOG_HDRLEN);
204#else
205        bpfattach(&pflogif->sc_if.if_bpf, ifp, DLT_PFLOG, PFLOG_HDRLEN);
206#endif
207#endif
208
209        s = splnet();
210#ifdef __FreeBSD__
211        /* XXX: Why pf(4) lock?! Better add a pflog lock?! */
212        PF_LOCK();
213#endif
214        LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list);
215        pflogifs[unit] = ifp;
216#ifdef __FreeBSD__
217        PF_UNLOCK();
218#endif
219        splx(s);
220
221        return (0);
222}
223
224#ifdef __FreeBSD__
225static void
226pflog_clone_destroy(struct ifnet *ifp)
227#else
228int
229pflog_clone_destroy(struct ifnet *ifp)
230#endif
231{
232        struct pflog_softc      *pflogif = ifp->if_softc;
233        int                      s;
234
235        s = splnet();
236#ifdef __FreeBSD__
237        PF_LOCK();
238#endif
239        pflogifs[pflogif->sc_unit] = NULL;
240        LIST_REMOVE(pflogif, sc_list);
241#ifdef __FreeBSD__
242        PF_UNLOCK();
243#endif
244        splx(s);
245
246#if NBPFILTER > 0
247        bpfdetach(ifp);
248#endif
249        if_detach(ifp);
250#ifdef __FreeBSD__
251        if_free(ifp);
252#endif
253        free(pflogif, M_DEVBUF);
254#ifndef __FreeBSD__
255        return (0);
256#endif
257}
258
259/*
260 * Start output on the pflog interface.
261 */
262void
263pflogstart(struct ifnet *ifp)
264{
265        struct mbuf *m;
266#ifndef __FreeBSD__
267        int s;
268#endif
269
270        for (;;) {
271#ifdef __FreeBSD__
272                IF_LOCK(&ifp->if_snd);
273                _IF_DROP(&ifp->if_snd);
274                _IF_DEQUEUE(&ifp->if_snd, m);
275                IF_UNLOCK(&ifp->if_snd);
276#else
277                s = splnet();
278                IF_DROP(&ifp->if_snd);
279                IF_DEQUEUE(&ifp->if_snd, m);
280                splx(s);
281#endif
282
283                if (m == NULL)
284                        return;
285                else
286                        m_freem(m);
287        }
288}
289
290int
291pflogoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
292#ifdef __FreeBSD__
293        struct route *rt)
294#else
295        struct rtentry *rt)
296#endif
297{
298        m_freem(m);
299        return (0);
300}
301
302/* ARGSUSED */
303int
304pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
305{
306        switch (cmd) {
307        case SIOCSIFFLAGS:
308#ifdef __FreeBSD__
309                if (ifp->if_flags & IFF_UP)
310                        ifp->if_drv_flags |= IFF_DRV_RUNNING;
311                else
312                        ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
313#else
314                if (ifp->if_flags & IFF_UP)
315                        ifp->if_flags |= IFF_RUNNING;
316                else
317                        ifp->if_flags &= ~IFF_RUNNING;
318#endif
319                break;
320        default:
321                return (ENOTTY);
322        }
323
324        return (0);
325}
326
327int
328pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
329    u_int8_t reason, struct pf_rule *rm, struct pf_rule *am,
330    struct pf_ruleset *ruleset, struct pf_pdesc *pd)
331{
332#if NBPFILTER > 0
333        struct ifnet *ifn;
334        struct pfloghdr hdr;
335
336        if (kif == NULL || m == NULL || rm == NULL || pd == NULL)
337                return ( 1);
338
339        if ((ifn = pflogifs[rm->logif]) == NULL || !ifn->if_bpf)
340                return (0);
341
342        bzero(&hdr, sizeof(hdr));
343        hdr.length = PFLOG_REAL_HDRLEN;
344        hdr.af = af;
345        hdr.action = rm->action;
346        hdr.reason = reason;
347        memcpy(hdr.ifname, kif->pfik_name, sizeof(hdr.ifname));
348
349        if (am == NULL) {
350                hdr.rulenr = htonl(rm->nr);
351                hdr.subrulenr =  1;
352        } else {
353                hdr.rulenr = htonl(am->nr);
354                hdr.subrulenr = htonl(rm->nr);
355                if (ruleset != NULL && ruleset->anchor != NULL)
356                        strlcpy(hdr.ruleset, ruleset->anchor->name,
357                            sizeof(hdr.ruleset));
358        }
359        if (rm->log & PF_LOG_SOCKET_LOOKUP && !pd->lookup.done)
360#ifdef __FreeBSD__
361                /*
362                 * XXX: This should not happen as we force an early lookup
363                 * via debug.pfugidhack
364                 */
365                ; /* empty */
366#else
367                pd->lookup.done = pf_socket_lookup(dir, pd);
368#endif
369        if (pd->lookup.done > 0) {
370                hdr.uid = pd->lookup.uid;
371                hdr.pid = pd->lookup.pid;
372        } else {
373                hdr.uid = UID_MAX;
374                hdr.pid = NO_PID;
375        }
376        hdr.rule_uid = rm->cuid;
377        hdr.rule_pid = rm->cpid;
378        hdr.dir = dir;
379
380#ifdef INET
381        if (af == AF_INET && dir == PF_OUT) {
382                struct ip *ip;
383
384                ip = mtod(m, struct ip *);
385                ip->ip_sum = 0;
386                ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
387        }
388#endif /* INET */
389
390        ifn->if_opackets++;
391        ifn->if_obytes += m->m_pkthdr.len;
392#ifdef __FreeBSD__
393        BPF_MTAP2(ifn, &hdr, PFLOG_HDRLEN, m);
394#else
395        bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, PFLOG_HDRLEN, m,
396            BPF_DIRECTION_OUT);
397#endif
398#endif
399
400        return (0);
401}
402
403#ifdef __FreeBSD__
404static int
405pflog_modevent(module_t mod, int type, void *data)
406{
407        int error = 0;
408
409        switch (type) {
410        case MOD_LOAD:
411                pflogattach(1);
412                PF_LOCK();
413                pflog_packet_ptr = pflog_packet;
414                PF_UNLOCK();
415                break;
416        case MOD_UNLOAD:
417                PF_LOCK();
418                pflog_packet_ptr = NULL;
419                PF_UNLOCK();
420                if_clone_detach(&pflog_cloner);
421                break;
422        default:
423                error = EINVAL;
424                break;
425        }
426
427        return error;
428}
429
430static moduledata_t pflog_mod = { "pflog", pflog_modevent, 0 };
431
432#define PFLOG_MODVER 1
433
434DECLARE_MODULE(pflog, pflog_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
435MODULE_VERSION(pflog, PFLOG_MODVER);
436MODULE_DEPEND(pflog, pf, PF_MODVER, PF_MODVER, PF_MODVER);
437#endif /* __FreeBSD__ */
Note: See TracBrowser for help on using the repository browser.