[BACK]Return to if_pflog.c CVS log [TXT][DIR] Up to [local] / sys / net

Annotation of sys/net/if_pflog.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb