2 * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
4 * Copyright (c) 2015 - 2018 The DragonFly Project. All rights reserved.
6 * This code is derived from software contributed to The DragonFly Project
7 * by Bill Yuan <bycn82@dragonflybsd.org>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
19 * 3. Neither the name of The DragonFly Project nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific, prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include <sys/cdefs.h>
38 #include <sys/param.h>
39 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/socket.h>
43 #include <sys/sysctl.h>
44 #include <sys/syslog.h>
45 #include <sys/ucred.h>
48 #include <net/ethernet.h> /* for ETHERTYPE_IP */
50 #include <net/if_var.h>
51 #include <net/ifq_var.h>
52 #include <net/if_clone.h>
53 #include <net/if_types.h> /* for IFT_PFLOG */
54 #include <net/bpf.h> /* for BPF */
56 #include <netinet/in.h>
57 #include <netinet/ip.h>
58 #include <netinet/ip_icmp.h>
59 #include <netinet/ip_var.h>
60 #include <netinet/tcp_var.h>
61 #include <netinet/udp.h>
63 #include <net/ipfw3/ip_fw.h>
64 #include <net/ipfw3_basic/ip_fw3_log.h>
66 extern int sysctl_var_fw3_verbose;
67 extern struct if_clone *if_clone_lookup(const char *, int *);
69 static const char ipfw3_log_ifname[] = "ipfw";
70 static int log_if_count;
71 struct ifnet *log_if_table[LOG_IF_MAX];
72 struct lock log_if_lock;
75 u_char fake_eh[14] = {0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
76 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x08, 0x00};
78 static const u_char ipfwbroadcastaddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
80 #define LOGIF_LOCK_INIT(x) lockinit(&log_if_lock, "fw3log_lk", 0, LK_CANRECURSE)
81 #define LOGIF_LOCK_DESTROY(x) lockuninit(&log_if_lock)
82 #define LOGIF_RLOCK(x) lockmgr(&log_if_lock, LK_SHARED)
83 #define LOGIF_RUNLOCK(x) lockmgr(&log_if_lock, LK_RELEASE)
84 #define LOGIF_WLOCK(x) lockmgr(&log_if_lock, LK_EXCLUSIVE)
85 #define LOGIF_WUNLOCK(x) lockmgr(&log_if_lock, LK_RELEASE)
88 /* we use this dummy function for all ifnet callbacks */
90 ip_fw3_log_dummy(struct ifnet *ifp, u_long cmd, caddr_t addr, struct ucred *uc)
96 ip_fw3_log_output(struct ifnet *ifp, struct mbuf *m,
97 struct sockaddr *dst, struct rtentry *rtent)
106 ip_fw3_log_start(struct ifnet* ifp, struct ifaltq_subque *subque)
111 * bpf_mtap into the ipfw interface.
112 * eh == NULL when mbuf is a packet, then use the fake_eh
113 * the ip_len need to be twisted before and after bpf copy.
116 ip_fw3_log(struct mbuf *m, struct ether_header *eh, uint16_t id)
118 struct ifnet *the_if = NULL;
120 if (sysctl_var_fw3_verbose) {
123 the_if = log_if_table[id];
124 if (the_if == NULL || the_if->if_bpf == NULL) {
130 bpf_mtap_hdr(the_if->if_bpf, (caddr_t)eh,
131 ETHER_HDR_LEN, m, 0);
136 ip = mtod(m, struct ip *);
137 /* twist the ip_len for the bpf copy */
138 ip->ip_len =htons(ip->ip_len);
141 bpf_mtap_hdr(the_if->if_bpf, (caddr_t)fake_eh,
142 ETHER_HDR_LEN, m, 0);
144 ip->ip_len =ntohs(ip->ip_len);
148 #endif /* !WITHOUT_BPF */
153 ip_fw3_log_clone_create(struct if_clone *ifc, int unit, caddr_t param __unused)
157 if (unit < 0 || unit >= LOG_IF_MAX) {
160 if (log_if_table[unit] != NULL) {
164 ifp = if_alloc(IFT_PFLOG);
165 if_initname(ifp, ipfw3_log_ifname, unit);
166 ifq_set_maxlen(&ifp->if_snd, ifqmaxlen);
167 ifq_set_ready(&ifp->if_snd);
170 ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
171 ifp->if_init = (void *)ip_fw3_log_dummy;
172 ifp->if_ioctl = ip_fw3_log_dummy;
173 ifp->if_start = ip_fw3_log_start;
174 ifp->if_output = ip_fw3_log_output;
177 ifp->if_broadcastaddr = ipfwbroadcastaddr;
178 ifp->if_baudrate = IF_Mbps(10);
181 log_if_table[unit] = ifp;
183 if_attach(ifp, NULL);
184 bpfattach(ifp, DLT_EN10MB, ETHER_HDR_LEN);
191 ip_fw3_log_clone_destroy(struct ifnet *ifp)
198 unit = ifp->if_dunit;
199 if (unit < 0 || unit >= LOG_IF_MAX) {
202 if (log_if_table[unit] == NULL) {
206 log_if_table[unit] = NULL;
216 static eventhandler_tag ip_fw3_log_ifdetach_cookie;
217 static struct if_clone ipfw3_log_cloner = IF_CLONE_INITIALIZER(ipfw3_log_ifname,
218 ip_fw3_log_clone_create, ip_fw3_log_clone_destroy, 0, 9);
221 void ip_fw3_log_modevent(int type){
229 if_clone_attach(&ipfw3_log_cloner);
230 ip_fw3_log_ifdetach_cookie =
231 EVENTHANDLER_REGISTER(ifnet_detach_event,
232 ip_fw3_log_clone_destroy, &ipfw3_log_cloner,
233 EVENTHANDLER_PRI_ANY);
236 EVENTHANDLER_DEREGISTER(ifnet_detach_event,
237 ip_fw3_log_ifdetach_cookie);
238 if_clone_detach(&ipfw3_log_cloner);
239 for(i = 0; log_if_count > 0 && i < LOG_IF_MAX; i++){
240 tmpif = log_if_table[i];
242 ip_fw3_log_clone_destroy(tmpif);
245 LOGIF_LOCK_DESTROY();