Annotation of sys/net/if_pflog.c, Revision 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