168349Sobrien/*-
2133359Sobrien * SPDX-License-Identifier: BSD-2-Clause
3133359Sobrien *
4133359Sobrien * Copyright (c) 2020 Yandex LLC
5191736Sobrien * Copyright (c) 2020 Andrey V. Elsukov <ae@FreeBSD.org>
6133359Sobrien *
7133359Sobrien * Redistribution and use in source and binary forms, with or without
8133359Sobrien * modification, are permitted provided that the following conditions
9133359Sobrien * are met:
10133359Sobrien * 1. Redistributions of source code must retain the above copyright
11133359Sobrien *    notice, this list of conditions and the following disclaimer.
12133359Sobrien * 2. Redistributions in binary form must reproduce the above copyright
13133359Sobrien *    notice, this list of conditions and the following disclaimer in the
14133359Sobrien *    documentation and/or other materials provided with the distribution.
15191736Sobrien *
16133359Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17133359Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18133359Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19133359Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
20133359Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21133359Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22133359Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23133359Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24133359Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25133359Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26133359Sobrien * SUCH DAMAGE.
27133359Sobrien */
28133359Sobrien
2968349Sobrien#pragma D depends_on provider ipfw
30328875Seadler
3168349Sobrien/* ipfw_chk() return values */
3268349Sobrien#pragma D binding "1.0" IP_FW_PASS
3368349Sobrieninline int IP_FW_PASS = 	0;
3468349Sobrien#pragma D binding "1.0" IP_FW_DENY
3568349Sobrieninline int IP_FW_DENY = 	1;
3668349Sobrien#pragma D binding "1.0" IP_FW_DIVERT
3768349Sobrieninline int IP_FW_DIVERT =	2;
3868349Sobrien#pragma D binding "1.0" IP_FW_TEE
39328875Seadlerinline int IP_FW_TEE =		3;
40328875Seadler#pragma D binding "1.0" IP_FW_DUMMYNET
41328875Seadlerinline int IP_FW_DUMMYNET =	4;
42328875Seadler#pragma D binding "1.0" IP_FW_NETGRAPH
4368349Sobrieninline int IP_FW_NETGRAPH =	5;
44226048Sobrien#pragma D binding "1.0" IP_FW_NGTEE
45226048Sobrieninline int IP_FW_NGTEE =	6;
46226048Sobrien#pragma D binding "1.0" IP_FW_NAT
47226048Sobrieninline int IP_FW_NAT =		7;
48226048Sobrien#pragma D binding "1.0" IP_FW_REASS
49226048Sobrieninline int IP_FW_REASS =	8;
50226048Sobrien#pragma D binding "1.0" IP_FW_NAT64
51290152Sdelphijinline int IP_FW_NAT64 =	9;
52226048Sobrien
53226048Sobrien#pragma D binding "1.0" ipfw_retcodes
54226048Sobrieninline string ipfw_retcodes[int ret] =
55290152Sdelphij	ret == IP_FW_PASS ? "PASS" :
56226048Sobrien	ret == IP_FW_DENY ? "DENY" :
57328875Seadler	ret == IP_FW_DIVERT ? "DIVERT" :
58328875Seadler	ret == IP_FW_TEE ? "TEE" :
59226048Sobrien	ret == IP_FW_DUMMYNET ? "DUMMYNET" :
60133359Sobrien	ret == IP_FW_NETGRAPH ? "NETGRAPH" :
61103373Sobrien	ret == IP_FW_NGTEE ? "NGTEE" :
62159764Sobrien	ret == IP_FW_NAT ? "NAT" :
63133359Sobrien	ret == IP_FW_REASS ? "REASS" :
64110949Sobrien	ret == IP_FW_NAT64 ? "NAT64" :
65103373Sobrien	"<unknown>";
66169962Sobrien
67267843Sdelphij/* ip_fw_args flags */
68169942Sobrien#pragma D binding "1.0" IPFW_ARGS_ETHER
69276415Sdelphijinline int IPFW_ARGS_ETHER =	0x00010000; /* valid ethernet header */
70191736Sobrien#pragma D binding "1.0" IPFW_ARGS_NH4
71276415Sdelphijinline int IPFW_ARGS_NH4 =	0x00020000; /* IPv4 next hop in hopstore */
72103373Sobrien#pragma D binding "1.0" IPFW_ARGS_NH6
73103373Sobrieninline int IPFW_ARGS_NH6 =	0x00040000; /* IPv6 next hop in hopstore */
74186690Sobrien#pragma D binding "1.0" IPFW_ARGS_NH4PTR
7568349Sobrieninline int IPFW_ARGS_NH4PTR =	0x00080000; /* IPv4 next hop in next_hop */
76169962Sobrien#pragma D binding "1.0" IPFW_ARGS_NH6PTR
77169962Sobrieninline int IPFW_ARGS_NH6PTR =	0x00100000; /* IPv6 next hop in next_hop6 */
78133359Sobrien#pragma D binding "1.0" IPFW_ARGS_REF
79133359Sobrieninline int IPFW_ARGS_REF =	0x00200000; /* valid ipfw_rule_ref	*/
80133359Sobrien#pragma D binding "1.0" IPFW_ARGS_IN
81133359Sobrieninline int IPFW_ARGS_IN =	0x00400000; /* called on input */
82226048Sobrien#pragma D binding "1.0" IPFW_ARGS_OUT
83133359Sobrieninline int IPFW_ARGS_OUT =	0x00800000; /* called on output */
84133359Sobrien#pragma D binding "1.0" IPFW_ARGS_IP4
85133359Sobrieninline int IPFW_ARGS_IP4 =	0x01000000; /* belongs to v4 ISR */
86133359Sobrien#pragma D binding "1.0" IPFW_ARGS_IP6
87133359Sobrieninline int IPFW_ARGS_IP6 =	0x02000000; /* belongs to v6 ISR */
88133359Sobrien#pragma D binding "1.0" IPFW_ARGS_DROP
89267843Sdelphijinline int IPFW_ARGS_DROP =	0x04000000; /* drop it (dummynet) */
90267843Sdelphij#pragma D binding "1.0" IPFW_ARGS_LENMASK
91267843Sdelphijinline int IPFW_ARGS_LENMASK =	0x0000ffff; /* length of data in *mem */
92133359Sobrien
93267843Sdelphij/* ipfw_rule_ref.info */
94267843Sdelphij#pragma D binding "1.0" IPFW_INFO_MASK
95267843Sdelphijinline int IPFW_INFO_MASK =	0x0000ffff;
96267843Sdelphij#pragma D binding "1.0" IPFW_INFO_OUT
97267843Sdelphijinline int IPFW_INFO_OUT =	0x00000000;
98133359Sobrien#pragma D binding "1.0" IPFW_INFO_IN
99133359Sobrieninline int IPFW_INFO_IN =	0x80000000;
100267843Sdelphij#pragma D binding "1.0" IPFW_ONEPASS
101133359Sobrieninline int IPFW_ONEPASS =	0x40000000;
102226048Sobrien#pragma D binding "1.0" IPFW_IS_MASK
103226048Sobrieninline int IPFW_IS_MASK =	0x30000000;
104226048Sobrien#pragma D binding "1.0" IPFW_IS_DIVERT
105226048Sobrieninline int IPFW_IS_DIVERT =	0x20000000;
106169962Sobrien#pragma D binding "1.0" IPFW_IS_DUMMYNET
107169962Sobrieninline int IPFW_IS_DUMMYNET =	0x10000000;
108169962Sobrien#pragma D binding "1.0" IPFW_IS_PIPE
109169962Sobrieninline int IPFW_IS_PIPE =	0x08000000;
110169962Sobrien
111169962Sobrientypedef struct ipfw_match_info {
112169962Sobrien	uint32_t	flags;
113169962Sobrien
114169962Sobrien	struct mbuf	*m;
115169962Sobrien	void		*mem;
116186690Sobrien	struct inpcb	*inp;
117186690Sobrien	struct ifnet	*ifp;
118186690Sobrien	struct ip	*ipp;
119186690Sobrien	struct ip6_hdr	*ip6p;
120186690Sobrien
121186690Sobrien	/* flow id */
122169962Sobrien	uint8_t		addr_type;
123169962Sobrien	uint8_t		proto;
124169962Sobrien	uint8_t		proto_flags;
125169962Sobrien	uint16_t	fib;	/* XXX */
126186690Sobrien	in_addr_t	dst_ip;	/* in network byte order */
127186690Sobrien	in_addr_t	src_ip;	/* in network byte order */
128186690Sobrien	struct in6_addr	dst_ip6;
129186690Sobrien	struct in6_addr	src_ip6;
130300899Sdelphij
131300899Sdelphij	uint16_t	dst_port; /* in host byte order */
13268349Sobrien	uint16_t	src_port; /* in host byte order */
133186690Sobrien
134186690Sobrien	uint32_t	flowid;	/* IPv6 flowid */
135267843Sdelphij	uint32_t	extra;
136267843Sdelphij
137309848Sdelphij	/* ipfw_rule_ref */
13868349Sobrien	uint32_t	slot;
13974784Sobrien	uint32_t	rulenum;
140309848Sdelphij	uint32_t	rule_id;
141309848Sdelphij	uint32_t	chain_id;
14274784Sobrien	uint32_t	match_info;
143133359Sobrien} ipfw_match_info_t;
144133359Sobrien
145133359Sobrien#pragma D binding "1.0" translator
146226048Sobrientranslator ipfw_match_info_t < struct ip_fw_args *p > {
14774784Sobrien	flags =		p->flags;
148186690Sobrien	m =		(p->flags & IPFW_ARGS_LENMASK) ? NULL : p->m;
149186690Sobrien	mem =		(p->flags & IPFW_ARGS_LENMASK) ? p->mem : NULL;
150186690Sobrien	inp =		p->inp;
151186690Sobrien	ifp =		p->ifp;
152186690Sobrien	/* Initialize IP pointer corresponding to addr_type */
153186690Sobrien	ipp =		(p->flags & IPFW_ARGS_IP4) ?
154186690Sobrien	    (p->flags & IPFW_ARGS_LENMASK) ? (struct ip *)p->mem :
155186690Sobrien	    (p->m != NULL) ? (struct ip *)p->m->m_data : NULL : NULL;
156186690Sobrien	ip6p =		(p->flags & IPFW_ARGS_IP6) ?
157186690Sobrien	    (p->flags & IPFW_ARGS_LENMASK) ? (struct ip6_hdr *)p->mem :
158186690Sobrien	    (p->m != NULL) ? (struct ip6_hdr *)p->m->m_data : NULL : NULL;
159186690Sobrien
160191736Sobrien	/* fill f_id fields */
161186690Sobrien	addr_type =	p->f_id.addr_type;
16268349Sobrien	proto =		p->f_id.proto;
163133359Sobrien	proto_flags =	p->f_id._flags;
164103373Sobrien
165103373Sobrien	/* f_id.fib keeps truncated fibnum, use mbuf's fibnum if possible */
166186690Sobrien	fib =		p->m != NULL ? p->m->m_pkthdr.fibnum : p->f_id.fib;
167186690Sobrien
168186690Sobrien	/*
169186690Sobrien	 * ipfw_chk() keeps IPv4 addresses in host byte order. But for
170186690Sobrien	 * dtrace script it is useful to have them in network byte order,
171186690Sobrien	 * because inet_ntoa() uses address in network byte order.
172191736Sobrien	 */
173226048Sobrien	dst_ip =	htonl(p->f_id.dst_ip);
174169962Sobrien	src_ip =	htonl(p->f_id.src_ip);
175186690Sobrien
176186690Sobrien	dst_ip6 =	p->f_id.dst_ip6;
177133359Sobrien	src_ip6 =	p->f_id.src_ip6;
178103373Sobrien
179103373Sobrien	dst_port =	p->f_id.dst_port;
180186690Sobrien	src_port =	p->f_id.src_port;
181186690Sobrien
182169962Sobrien	flowid =	p->f_id.flow_id6;
183133359Sobrien	extra = 	p->f_id.extra;
184133359Sobrien
185169962Sobrien	/* ipfw_rule_ref */
186133359Sobrien	slot =		(p->flags & IPFW_ARGS_REF) ? p->rule.slot : 0;
187133359Sobrien	rulenum =	(p->flags & IPFW_ARGS_REF) ? p->rule.rulenum : 0;
188133359Sobrien	rule_id =	(p->flags & IPFW_ARGS_REF) ? p->rule.rule_id : 0;
189133359Sobrien	chain_id =	(p->flags & IPFW_ARGS_REF) ? p->rule.chain_id : 0;
190133359Sobrien	match_info =	(p->flags & IPFW_ARGS_REF) ? p->rule.info : 0;
191133359Sobrien};
192133359Sobrien
193133359Sobrientypedef struct ipfw_rule_info {
194133359Sobrien	uint16_t	act_ofs;
195133359Sobrien	uint16_t	cmd_len;
196133359Sobrien	uint32_t	rulenum;
197133359Sobrien	uint8_t		flags;
198133359Sobrien	uint8_t		set;
199133359Sobrien	uint32_t	rule_id;
200139368Sobrien	uint32_t	cached_id;
201139368Sobrien	uint32_t	cached_pos;
202159764Sobrien	uint32_t	refcnt;
203159764Sobrien} ipfw_rule_info_t;
204159764Sobrien
205159764Sobrien#pragma D binding "1.0" translator
206169942Sobrientranslator ipfw_rule_info_t < struct ip_fw *r > {
207169942Sobrien	act_ofs =	r->act_ofs;
208169942Sobrien	cmd_len =	r->cmd_len;
209169942Sobrien	rulenum =	r->rulenum;
210169942Sobrien	flags =		r->flags;
211169942Sobrien	set =		r->set;
212169942Sobrien	rule_id =	r->id;
213169942Sobrien	cached_id =	r->cache.id;
214169942Sobrien	cached_pos =	r->cache.pos;
215175296Sobrien	refcnt =	r->refcnt;
216175296Sobrien};
217175296Sobrien
218175296Sobrien