xref: /freebsd/share/dtrace/ipfw.d (revision c66ec88fed842fbaad62c30d510644ceb7bd2d71)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2020 Yandex LLC
5  * Copyright (c) 2020 Andrey V. Elsukov <ae@FreeBSD.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30 
31 #pragma D depends_on provider ipfw
32 
33 /* ipfw_chk() return values */
34 #pragma D binding "1.0" IP_FW_PASS
35 inline int IP_FW_PASS = 	0;
36 #pragma D binding "1.0" IP_FW_DENY
37 inline int IP_FW_DENY = 	1;
38 #pragma D binding "1.0" IP_FW_DIVERT
39 inline int IP_FW_DIVERT =	2;
40 #pragma D binding "1.0" IP_FW_TEE
41 inline int IP_FW_TEE =		3;
42 #pragma D binding "1.0" IP_FW_DUMMYNET
43 inline int IP_FW_DUMMYNET =	4;
44 #pragma D binding "1.0" IP_FW_NETGRAPH
45 inline int IP_FW_NETGRAPH =	5;
46 #pragma D binding "1.0" IP_FW_NGTEE
47 inline int IP_FW_NGTEE =	6;
48 #pragma D binding "1.0" IP_FW_NAT
49 inline int IP_FW_NAT =		7;
50 #pragma D binding "1.0" IP_FW_REASS
51 inline int IP_FW_REASS =	8;
52 #pragma D binding "1.0" IP_FW_NAT64
53 inline int IP_FW_NAT64 =	9;
54 
55 #pragma D binding "1.0" ipfw_retcodes
56 inline string ipfw_retcodes[int ret] =
57 	ret == IP_FW_PASS ? "PASS" :
58 	ret == IP_FW_DENY ? "DENY" :
59 	ret == IP_FW_DIVERT ? "DIVERT" :
60 	ret == IP_FW_TEE ? "TEE" :
61 	ret == IP_FW_DUMMYNET ? "DUMMYNET" :
62 	ret == IP_FW_NETGRAPH ? "NETGRAPH" :
63 	ret == IP_FW_NGTEE ? "NGTEE" :
64 	ret == IP_FW_NAT ? "NAT" :
65 	ret == IP_FW_REASS ? "REASS" :
66 	ret == IP_FW_NAT64 ? "NAT64" :
67 	"<unknown>";
68 
69 /* ip_fw_args flags */
70 #pragma D binding "1.0" IPFW_ARGS_ETHER
71 inline int IPFW_ARGS_ETHER =	0x00010000; /* valid ethernet header */
72 #pragma D binding "1.0" IPFW_ARGS_NH4
73 inline int IPFW_ARGS_NH4 =	0x00020000; /* IPv4 next hop in hopstore */
74 #pragma D binding "1.0" IPFW_ARGS_NH6
75 inline int IPFW_ARGS_NH6 =	0x00040000; /* IPv6 next hop in hopstore */
76 #pragma D binding "1.0" IPFW_ARGS_NH4PTR
77 inline int IPFW_ARGS_NH4PTR =	0x00080000; /* IPv4 next hop in next_hop */
78 #pragma D binding "1.0" IPFW_ARGS_NH6PTR
79 inline int IPFW_ARGS_NH6PTR =	0x00100000; /* IPv6 next hop in next_hop6 */
80 #pragma D binding "1.0" IPFW_ARGS_REF
81 inline int IPFW_ARGS_REF =	0x00200000; /* valid ipfw_rule_ref	*/
82 #pragma D binding "1.0" IPFW_ARGS_IN
83 inline int IPFW_ARGS_IN =	0x00400000; /* called on input */
84 #pragma D binding "1.0" IPFW_ARGS_OUT
85 inline int IPFW_ARGS_OUT =	0x00800000; /* called on output */
86 #pragma D binding "1.0" IPFW_ARGS_IP4
87 inline int IPFW_ARGS_IP4 =	0x01000000; /* belongs to v4 ISR */
88 #pragma D binding "1.0" IPFW_ARGS_IP6
89 inline int IPFW_ARGS_IP6 =	0x02000000; /* belongs to v6 ISR */
90 #pragma D binding "1.0" IPFW_ARGS_DROP
91 inline int IPFW_ARGS_DROP =	0x04000000; /* drop it (dummynet) */
92 #pragma D binding "1.0" IPFW_ARGS_LENMASK
93 inline int IPFW_ARGS_LENMASK =	0x0000ffff; /* length of data in *mem */
94 
95 /* ipfw_rule_ref.info */
96 #pragma D binding "1.0" IPFW_INFO_MASK
97 inline int IPFW_INFO_MASK =	0x0000ffff;
98 #pragma D binding "1.0" IPFW_INFO_OUT
99 inline int IPFW_INFO_OUT =	0x00000000;
100 #pragma D binding "1.0" IPFW_INFO_IN
101 inline int IPFW_INFO_IN =	0x80000000;
102 #pragma D binding "1.0" IPFW_ONEPASS
103 inline int IPFW_ONEPASS =	0x40000000;
104 #pragma D binding "1.0" IPFW_IS_MASK
105 inline int IPFW_IS_MASK =	0x30000000;
106 #pragma D binding "1.0" IPFW_IS_DIVERT
107 inline int IPFW_IS_DIVERT =	0x20000000;
108 #pragma D binding "1.0" IPFW_IS_DUMMYNET
109 inline int IPFW_IS_DUMMYNET =	0x10000000;
110 #pragma D binding "1.0" IPFW_IS_PIPE
111 inline int IPFW_IS_PIPE =	0x08000000;
112 
113 typedef struct ipfw_match_info {
114 	uint32_t	flags;
115 
116 	struct mbuf	*m;
117 	void		*mem;
118 	struct inpcb	*inp;
119 	struct ifnet	*ifp;
120 	struct ip	*ipp;
121 	struct ip6_hdr	*ip6p;
122 
123 	/* flow id */
124 	uint8_t		addr_type;
125 	uint8_t		proto;
126 	uint8_t		proto_flags;
127 	uint16_t	fib;	/* XXX */
128 	in_addr_t	dst_ip;	/* in network byte order */
129 	in_addr_t	src_ip;	/* in network byte order */
130 	struct in6_addr	dst_ip6;
131 	struct in6_addr	src_ip6;
132 
133 	uint16_t	dst_port; /* in host byte order */
134 	uint16_t	src_port; /* in host byte order */
135 
136 	uint32_t	flowid;	/* IPv6 flowid */
137 	uint32_t	extra;
138 
139 	/* ipfw_rule_ref */
140 	uint32_t	slot;
141 	uint32_t	rulenum;
142 	uint32_t	rule_id;
143 	uint32_t	chain_id;
144 	uint32_t	match_info;
145 } ipfw_match_info_t;
146 
147 #pragma D binding "1.0" translator
148 translator ipfw_match_info_t < struct ip_fw_args *p > {
149 	flags =		p->flags;
150 	m =		(p->flags & IPFW_ARGS_LENMASK) ? NULL : p->m;
151 	mem =		(p->flags & IPFW_ARGS_LENMASK) ? p->mem : NULL;
152 	inp =		p->inp;
153 	ifp =		p->ifp;
154 	/* Initialize IP pointer corresponding to addr_type */
155 	ipp =		(p->flags & IPFW_ARGS_IP4) ?
156 	    (p->flags & IPFW_ARGS_LENMASK) ? (struct ip *)p->mem :
157 	    (p->m != NULL) ? (struct ip *)p->m->m_data : NULL : NULL;
158 	ip6p =		(p->flags & IPFW_ARGS_IP6) ?
159 	    (p->flags & IPFW_ARGS_LENMASK) ? (struct ip6_hdr *)p->mem :
160 	    (p->m != NULL) ? (struct ip6_hdr *)p->m->m_data : NULL : NULL;
161 
162 	/* fill f_id fields */
163 	addr_type =	p->f_id.addr_type;
164 	proto =		p->f_id.proto;
165 	proto_flags =	p->f_id._flags;
166 
167 	/* f_id.fib keeps truncated fibnum, use mbuf's fibnum if possible */
168 	fib =		p->m != NULL ? p->m->m_pkthdr.fibnum : p->f_id.fib;
169 
170 	/*
171 	 * ipfw_chk() keeps IPv4 addresses in host byte order. But for
172 	 * dtrace script it is useful to have them in network byte order,
173 	 * because inet_ntoa() uses address in network byte order.
174 	 */
175 	dst_ip =	htonl(p->f_id.dst_ip);
176 	src_ip =	htonl(p->f_id.src_ip);
177 
178 	dst_ip6 =	p->f_id.dst_ip6;
179 	src_ip6 =	p->f_id.src_ip6;
180 
181 	dst_port =	p->f_id.dst_port;
182 	src_port =	p->f_id.src_port;
183 
184 	flowid =	p->f_id.flow_id6;
185 	extra = 	p->f_id.extra;
186 
187 	/* ipfw_rule_ref */
188 	slot =		(p->flags & IPFW_ARGS_REF) ? p->rule.slot : 0;
189 	rulenum =	(p->flags & IPFW_ARGS_REF) ? p->rule.rulenum : 0;
190 	rule_id =	(p->flags & IPFW_ARGS_REF) ? p->rule.rule_id : 0;
191 	chain_id =	(p->flags & IPFW_ARGS_REF) ? p->rule.chain_id : 0;
192 	match_info =	(p->flags & IPFW_ARGS_REF) ? p->rule.info : 0;
193 };
194 
195 typedef struct ipfw_rule_info {
196 	uint16_t	act_ofs;
197 	uint16_t	cmd_len;
198 	uint32_t	rulenum;
199 	uint8_t		flags;
200 	uint8_t		set;
201 	uint32_t	rule_id;
202 	uint32_t	cached_id;
203 	uint32_t	cached_pos;
204 	uint32_t	refcnt;
205 } ipfw_rule_info_t;
206 
207 #pragma D binding "1.0" translator
208 translator ipfw_rule_info_t < struct ip_fw *r > {
209 	act_ofs =	r->act_ofs;
210 	cmd_len =	r->cmd_len;
211 	rulenum =	r->rulenum;
212 	flags =		r->flags;
213 	set =		r->set;
214 	rule_id =	r->id;
215 	cached_id =	r->cached_id;
216 	cached_pos =	r->cached_pos;
217 	refcnt =	r->refcnt;
218 };
219 
220