2 * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
4 * Copyright (c) 2015 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
39 #error IPFIREWALL3 requires INET.
42 #include <sys/cdefs.h>
43 #include <sys/param.h>
44 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/socket.h>
48 #include <sys/sysctl.h>
49 #include <sys/syslog.h>
50 #include <sys/ucred.h>
53 #include <net/ethernet.h> /* for ETHERTYPE_IP */
55 #include <net/if_var.h>
56 #include <net/ifq_var.h>
57 #include <net/if_clone.h>
58 #include <net/if_types.h> /* for IFT_PFLOG */
59 #include <net/bpf.h> /* for BPF */
61 #include <netinet/in.h>
62 #include <netinet/ip.h>
63 #include <netinet/ip_icmp.h>
64 #include <netinet/ip_var.h>
65 #include <netinet/tcp_var.h>
66 #include <netinet/udp.h>
69 #include <netinet/ip6.h>
70 #include <netinet/icmp6.h>
71 #include <netinet6/in6_var.h> /* ip6_sprintf() */
74 #include <net/ipfw3/ip_fw.h>
75 #include <net/ipfw3/ip_fw3_log.h>
77 extern int fw_verbose
;
78 extern struct if_clone
*if_clone_lookup(const char *, int *);
80 static const char ipfw_log_ifname
[] = "ipfw";
81 static int log_if_count
;
82 struct ifnet
*log_if_table
[LOG_IF_MAX
];
83 struct lock log_if_lock
;
86 u_char fake_eh
[14] = {0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
87 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x08, 0x00};
89 static const u_char ipfwbroadcastaddr
[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
91 #define LOGIF_LOCK_INIT(x) lockinit(&log_if_lock, "fw3log_lk", 0, LK_CANRECURSE)
92 #define LOGIF_LOCK_DESTROY(x) lockuninit(&log_if_lock)
93 #define LOGIF_RLOCK(x) lockmgr(&log_if_lock, LK_SHARED)
94 #define LOGIF_RUNLOCK(x) lockmgr(&log_if_lock, LK_RELEASE)
95 #define LOGIF_WLOCK(x) lockmgr(&log_if_lock, LK_EXCLUSIVE)
96 #define LOGIF_WUNLOCK(x) lockmgr(&log_if_lock, LK_RELEASE)
99 /* we use this dummy function for all ifnet callbacks */
101 log_dummy(struct ifnet
*ifp
, u_long cmd
, caddr_t addr
, struct ucred
*uc
)
107 ipfw_log_output(struct ifnet
*ifp
, struct mbuf
*m
,
108 struct sockaddr
*dst
, struct rtentry
*rtent
)
117 ipfw_log_start(struct ifnet
* ifp
, struct ifaltq_subque
*subque
)
122 * bpf_mtap into the ipfw interface.
123 * eh == NULL when mbuf is a packet, then use the fake_eh
124 * the ip_len need to be twisted before and after bpf copy.
127 ipfw_log(struct mbuf
*m
, struct ether_header
*eh
, uint16_t id
)
129 struct ifnet
*the_if
= NULL
;
134 the_if
= log_if_table
[id
];
135 if (the_if
== NULL
|| the_if
->if_bpf
== NULL
) {
141 bpf_mtap_hdr(the_if
->if_bpf
, (caddr_t
)eh
,
142 ETHER_HDR_LEN
, m
, 0);
147 ip
= mtod(m
, struct ip
*);
148 /* twist the ip_len for the bpf copy */
149 ip
->ip_len
=htons(ip
->ip_len
);
152 bpf_mtap_hdr(the_if
->if_bpf
, (caddr_t
)fake_eh
,
153 ETHER_HDR_LEN
, m
, 0);
155 ip
->ip_len
=ntohs(ip
->ip_len
);
159 #endif /* !WITHOUT_BPF */
164 ipfw_log_clone_create(struct if_clone
*ifc
, int unit
, caddr_t param __unused
)
168 if (unit
< 0 || unit
>= LOG_IF_MAX
) {
171 if (log_if_table
[unit
] != NULL
) {
175 ifp
= if_alloc(IFT_PFLOG
);
176 if_initname(ifp
, ipfw_log_ifname
, unit
);
177 ifq_set_maxlen(&ifp
->if_snd
, ifqmaxlen
);
178 ifq_set_ready(&ifp
->if_snd
);
181 ifp
->if_flags
= IFF_UP
| IFF_SIMPLEX
| IFF_MULTICAST
;
182 ifp
->if_init
= (void *)log_dummy
;
183 ifp
->if_ioctl
= log_dummy
;
184 ifp
->if_start
= ipfw_log_start
;
185 ifp
->if_output
= ipfw_log_output
;
188 ifp
->if_broadcastaddr
= ipfwbroadcastaddr
;
189 ifp
->if_baudrate
= IF_Mbps(10);
192 log_if_table
[unit
] = ifp
;
194 if_attach(ifp
, NULL
);
195 bpfattach(ifp
, DLT_EN10MB
, ETHER_HDR_LEN
);
202 ipfw_log_clone_destroy(struct ifnet
*ifp
)
209 unit
= ifp
->if_dunit
;
210 if (unit
< 0 || unit
>= LOG_IF_MAX
) {
213 if (log_if_table
[unit
] == NULL
) {
217 log_if_table
[unit
] = NULL
;
227 static eventhandler_tag ipfw_log_ifdetach_cookie
;
228 static struct if_clone ipfw_log_cloner
= IF_CLONE_INITIALIZER(ipfw_log_ifname
,
229 ipfw_log_clone_create
, ipfw_log_clone_destroy
, 0, 9);
232 void ipfw3_log_modevent(int type
){
240 if_clone_attach(&ipfw_log_cloner
);
241 ipfw_log_ifdetach_cookie
=
242 EVENTHANDLER_REGISTER(ifnet_detach_event
,
243 ipfw_log_clone_destroy
, &ipfw_log_cloner
,
244 EVENTHANDLER_PRI_ANY
);
247 EVENTHANDLER_DEREGISTER(ifnet_detach_event
,
248 ipfw_log_ifdetach_cookie
);
249 if_clone_detach(&ipfw_log_cloner
);
250 for(i
= 0; log_if_count
> 0 && i
< LOG_IF_MAX
; i
++){
251 tmpif
= log_if_table
[i
];
253 ipfw_log_clone_destroy(tmpif
);
256 LOGIF_LOCK_DESTROY();