root/net/if_pflog.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pflogattach
  2. pflog_clone_create
  3. pflog_clone_destroy
  4. pflogstart
  5. pflogoutput
  6. pflogioctl
  7. pflog_packet

    1 /*      $OpenBSD: if_pflog.c,v 1.24 2007/05/26 17:13:30 jason Exp $     */
    2 /*
    3  * The authors of this code are John Ioannidis (ji@tla.org),
    4  * Angelos D. Keromytis (kermit@csd.uch.gr) and 
    5  * Niels Provos (provos@physnet.uni-hamburg.de).
    6  *
    7  * This code was written by John Ioannidis for BSD/OS in Athens, Greece, 
    8  * in November 1995.
    9  *
   10  * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
   11  * by Angelos D. Keromytis.
   12  *
   13  * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
   14  * and Niels Provos.
   15  *
   16  * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis
   17  * and Niels Provos.
   18  * Copyright (c) 2001, Angelos D. Keromytis, Niels Provos.
   19  *
   20  * Permission to use, copy, and modify this software with or without fee
   21  * is hereby granted, provided that this entire notice is included in
   22  * all copies of any software which is or includes a copy or
   23  * modification of this software. 
   24  * You may use this code under the GNU public license if you so wish. Please
   25  * contribute changes back to the authors under this freer than GPL license
   26  * so that we may further the use of strong encryption without limitations to
   27  * all.
   28  *
   29  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
   30  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
   31  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
   32  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
   33  * PURPOSE.
   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 /* INET6 */
   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];        /* for fast access */
   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  * Start output on the pflog interface.
  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 /* ARGSUSED */
  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 /* INET */
  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 }

/* [<][>][^][v][top][bottom][index][help] */