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