xref: /freebsd/share/dtrace/ipfw.d (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
17ec2f6bcSAndrey V. Elsukov /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
37ec2f6bcSAndrey V. Elsukov  *
47ec2f6bcSAndrey V. Elsukov  * Copyright (c) 2020 Yandex LLC
57ec2f6bcSAndrey V. Elsukov  * Copyright (c) 2020 Andrey V. Elsukov <ae@FreeBSD.org>
67ec2f6bcSAndrey V. Elsukov  *
77ec2f6bcSAndrey V. Elsukov  * Redistribution and use in source and binary forms, with or without
87ec2f6bcSAndrey V. Elsukov  * modification, are permitted provided that the following conditions
97ec2f6bcSAndrey V. Elsukov  * are met:
107ec2f6bcSAndrey V. Elsukov  * 1. Redistributions of source code must retain the above copyright
117ec2f6bcSAndrey V. Elsukov  *    notice, this list of conditions and the following disclaimer.
127ec2f6bcSAndrey V. Elsukov  * 2. Redistributions in binary form must reproduce the above copyright
137ec2f6bcSAndrey V. Elsukov  *    notice, this list of conditions and the following disclaimer in the
147ec2f6bcSAndrey V. Elsukov  *    documentation and/or other materials provided with the distribution.
157ec2f6bcSAndrey V. Elsukov  *
167ec2f6bcSAndrey V. Elsukov  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
177ec2f6bcSAndrey V. Elsukov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
187ec2f6bcSAndrey V. Elsukov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
197ec2f6bcSAndrey V. Elsukov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
207ec2f6bcSAndrey V. Elsukov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
217ec2f6bcSAndrey V. Elsukov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
227ec2f6bcSAndrey V. Elsukov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
237ec2f6bcSAndrey V. Elsukov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
247ec2f6bcSAndrey V. Elsukov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
257ec2f6bcSAndrey V. Elsukov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
267ec2f6bcSAndrey V. Elsukov  * SUCH DAMAGE.
277ec2f6bcSAndrey V. Elsukov  */
287ec2f6bcSAndrey V. Elsukov 
297ec2f6bcSAndrey V. Elsukov #pragma D depends_on provider ipfw
307ec2f6bcSAndrey V. Elsukov 
317ec2f6bcSAndrey V. Elsukov /* ipfw_chk() return values */
327ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IP_FW_PASS
337ec2f6bcSAndrey V. Elsukov inline int IP_FW_PASS = 	0;
347ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IP_FW_DENY
357ec2f6bcSAndrey V. Elsukov inline int IP_FW_DENY = 	1;
367ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IP_FW_DIVERT
377ec2f6bcSAndrey V. Elsukov inline int IP_FW_DIVERT =	2;
387ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IP_FW_TEE
397ec2f6bcSAndrey V. Elsukov inline int IP_FW_TEE =		3;
407ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IP_FW_DUMMYNET
417ec2f6bcSAndrey V. Elsukov inline int IP_FW_DUMMYNET =	4;
427ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IP_FW_NETGRAPH
437ec2f6bcSAndrey V. Elsukov inline int IP_FW_NETGRAPH =	5;
447ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IP_FW_NGTEE
457ec2f6bcSAndrey V. Elsukov inline int IP_FW_NGTEE =	6;
467ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IP_FW_NAT
477ec2f6bcSAndrey V. Elsukov inline int IP_FW_NAT =		7;
487ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IP_FW_REASS
497ec2f6bcSAndrey V. Elsukov inline int IP_FW_REASS =	8;
507ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IP_FW_NAT64
517ec2f6bcSAndrey V. Elsukov inline int IP_FW_NAT64 =	9;
527ec2f6bcSAndrey V. Elsukov 
537ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" ipfw_retcodes
547ec2f6bcSAndrey V. Elsukov inline string ipfw_retcodes[int ret] =
557ec2f6bcSAndrey V. Elsukov 	ret == IP_FW_PASS ? "PASS" :
567ec2f6bcSAndrey V. Elsukov 	ret == IP_FW_DENY ? "DENY" :
577ec2f6bcSAndrey V. Elsukov 	ret == IP_FW_DIVERT ? "DIVERT" :
587ec2f6bcSAndrey V. Elsukov 	ret == IP_FW_TEE ? "TEE" :
597ec2f6bcSAndrey V. Elsukov 	ret == IP_FW_DUMMYNET ? "DUMMYNET" :
607ec2f6bcSAndrey V. Elsukov 	ret == IP_FW_NETGRAPH ? "NETGRAPH" :
617ec2f6bcSAndrey V. Elsukov 	ret == IP_FW_NGTEE ? "NGTEE" :
627ec2f6bcSAndrey V. Elsukov 	ret == IP_FW_NAT ? "NAT" :
637ec2f6bcSAndrey V. Elsukov 	ret == IP_FW_REASS ? "REASS" :
647ec2f6bcSAndrey V. Elsukov 	ret == IP_FW_NAT64 ? "NAT64" :
657ec2f6bcSAndrey V. Elsukov 	"<unknown>";
667ec2f6bcSAndrey V. Elsukov 
677ec2f6bcSAndrey V. Elsukov /* ip_fw_args flags */
687ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_ETHER
697ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_ETHER =	0x00010000; /* valid ethernet header */
707ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_NH4
717ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_NH4 =	0x00020000; /* IPv4 next hop in hopstore */
727ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_NH6
737ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_NH6 =	0x00040000; /* IPv6 next hop in hopstore */
747ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_NH4PTR
757ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_NH4PTR =	0x00080000; /* IPv4 next hop in next_hop */
767ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_NH6PTR
777ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_NH6PTR =	0x00100000; /* IPv6 next hop in next_hop6 */
787ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_REF
797ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_REF =	0x00200000; /* valid ipfw_rule_ref	*/
807ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_IN
817ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_IN =	0x00400000; /* called on input */
827ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_OUT
837ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_OUT =	0x00800000; /* called on output */
847ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_IP4
857ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_IP4 =	0x01000000; /* belongs to v4 ISR */
867ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_IP6
877ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_IP6 =	0x02000000; /* belongs to v6 ISR */
887ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_DROP
897ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_DROP =	0x04000000; /* drop it (dummynet) */
907ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ARGS_LENMASK
917ec2f6bcSAndrey V. Elsukov inline int IPFW_ARGS_LENMASK =	0x0000ffff; /* length of data in *mem */
927ec2f6bcSAndrey V. Elsukov 
937ec2f6bcSAndrey V. Elsukov /* ipfw_rule_ref.info */
947ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_INFO_MASK
957ec2f6bcSAndrey V. Elsukov inline int IPFW_INFO_MASK =	0x0000ffff;
967ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_INFO_OUT
977ec2f6bcSAndrey V. Elsukov inline int IPFW_INFO_OUT =	0x00000000;
987ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_INFO_IN
997ec2f6bcSAndrey V. Elsukov inline int IPFW_INFO_IN =	0x80000000;
1007ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_ONEPASS
1017ec2f6bcSAndrey V. Elsukov inline int IPFW_ONEPASS =	0x40000000;
1027ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_IS_MASK
1037ec2f6bcSAndrey V. Elsukov inline int IPFW_IS_MASK =	0x30000000;
1047ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_IS_DIVERT
1057ec2f6bcSAndrey V. Elsukov inline int IPFW_IS_DIVERT =	0x20000000;
1067ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_IS_DUMMYNET
1077ec2f6bcSAndrey V. Elsukov inline int IPFW_IS_DUMMYNET =	0x10000000;
1087ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" IPFW_IS_PIPE
1097ec2f6bcSAndrey V. Elsukov inline int IPFW_IS_PIPE =	0x08000000;
1107ec2f6bcSAndrey V. Elsukov 
1117ec2f6bcSAndrey V. Elsukov typedef struct ipfw_match_info {
1127ec2f6bcSAndrey V. Elsukov 	uint32_t	flags;
1137ec2f6bcSAndrey V. Elsukov 
1147ec2f6bcSAndrey V. Elsukov 	struct mbuf	*m;
1157ec2f6bcSAndrey V. Elsukov 	void		*mem;
1167ec2f6bcSAndrey V. Elsukov 	struct inpcb	*inp;
1177ec2f6bcSAndrey V. Elsukov 	struct ifnet	*ifp;
1187ec2f6bcSAndrey V. Elsukov 	struct ip	*ipp;
1197ec2f6bcSAndrey V. Elsukov 	struct ip6_hdr	*ip6p;
1207ec2f6bcSAndrey V. Elsukov 
1217ec2f6bcSAndrey V. Elsukov 	/* flow id */
1227ec2f6bcSAndrey V. Elsukov 	uint8_t		addr_type;
1237ec2f6bcSAndrey V. Elsukov 	uint8_t		proto;
1247ec2f6bcSAndrey V. Elsukov 	uint8_t		proto_flags;
1257ec2f6bcSAndrey V. Elsukov 	uint16_t	fib;	/* XXX */
1267ec2f6bcSAndrey V. Elsukov 	in_addr_t	dst_ip;	/* in network byte order */
1277ec2f6bcSAndrey V. Elsukov 	in_addr_t	src_ip;	/* in network byte order */
1287ec2f6bcSAndrey V. Elsukov 	struct in6_addr	dst_ip6;
1297ec2f6bcSAndrey V. Elsukov 	struct in6_addr	src_ip6;
1307ec2f6bcSAndrey V. Elsukov 
1317ec2f6bcSAndrey V. Elsukov 	uint16_t	dst_port; /* in host byte order */
1327ec2f6bcSAndrey V. Elsukov 	uint16_t	src_port; /* in host byte order */
1337ec2f6bcSAndrey V. Elsukov 
1347ec2f6bcSAndrey V. Elsukov 	uint32_t	flowid;	/* IPv6 flowid */
1357ec2f6bcSAndrey V. Elsukov 	uint32_t	extra;
1367ec2f6bcSAndrey V. Elsukov 
1377ec2f6bcSAndrey V. Elsukov 	/* ipfw_rule_ref */
1387ec2f6bcSAndrey V. Elsukov 	uint32_t	slot;
1397ec2f6bcSAndrey V. Elsukov 	uint32_t	rulenum;
1407ec2f6bcSAndrey V. Elsukov 	uint32_t	rule_id;
1417ec2f6bcSAndrey V. Elsukov 	uint32_t	chain_id;
1427ec2f6bcSAndrey V. Elsukov 	uint32_t	match_info;
1437ec2f6bcSAndrey V. Elsukov } ipfw_match_info_t;
1447ec2f6bcSAndrey V. Elsukov 
1457ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" translator
1467ec2f6bcSAndrey V. Elsukov translator ipfw_match_info_t < struct ip_fw_args *p > {
1477ec2f6bcSAndrey V. Elsukov 	flags =		p->flags;
1487ec2f6bcSAndrey V. Elsukov 	m =		(p->flags & IPFW_ARGS_LENMASK) ? NULL : p->m;
1497ec2f6bcSAndrey V. Elsukov 	mem =		(p->flags & IPFW_ARGS_LENMASK) ? p->mem : NULL;
1507ec2f6bcSAndrey V. Elsukov 	inp =		p->inp;
1517ec2f6bcSAndrey V. Elsukov 	ifp =		p->ifp;
1527ec2f6bcSAndrey V. Elsukov 	/* Initialize IP pointer corresponding to addr_type */
1537ec2f6bcSAndrey V. Elsukov 	ipp =		(p->flags & IPFW_ARGS_IP4) ?
1547ec2f6bcSAndrey V. Elsukov 	    (p->flags & IPFW_ARGS_LENMASK) ? (struct ip *)p->mem :
1557ec2f6bcSAndrey V. Elsukov 	    (p->m != NULL) ? (struct ip *)p->m->m_data : NULL : NULL;
1567ec2f6bcSAndrey V. Elsukov 	ip6p =		(p->flags & IPFW_ARGS_IP6) ?
1577ec2f6bcSAndrey V. Elsukov 	    (p->flags & IPFW_ARGS_LENMASK) ? (struct ip6_hdr *)p->mem :
1587ec2f6bcSAndrey V. Elsukov 	    (p->m != NULL) ? (struct ip6_hdr *)p->m->m_data : NULL : NULL;
1597ec2f6bcSAndrey V. Elsukov 
1607ec2f6bcSAndrey V. Elsukov 	/* fill f_id fields */
1617ec2f6bcSAndrey V. Elsukov 	addr_type =	p->f_id.addr_type;
1627ec2f6bcSAndrey V. Elsukov 	proto =		p->f_id.proto;
1637ec2f6bcSAndrey V. Elsukov 	proto_flags =	p->f_id._flags;
1647ec2f6bcSAndrey V. Elsukov 
1657ec2f6bcSAndrey V. Elsukov 	/* f_id.fib keeps truncated fibnum, use mbuf's fibnum if possible */
1667ec2f6bcSAndrey V. Elsukov 	fib =		p->m != NULL ? p->m->m_pkthdr.fibnum : p->f_id.fib;
1677ec2f6bcSAndrey V. Elsukov 
1687ec2f6bcSAndrey V. Elsukov 	/*
1697ec2f6bcSAndrey V. Elsukov 	 * ipfw_chk() keeps IPv4 addresses in host byte order. But for
1707ec2f6bcSAndrey V. Elsukov 	 * dtrace script it is useful to have them in network byte order,
1717ec2f6bcSAndrey V. Elsukov 	 * because inet_ntoa() uses address in network byte order.
1727ec2f6bcSAndrey V. Elsukov 	 */
1737ec2f6bcSAndrey V. Elsukov 	dst_ip =	htonl(p->f_id.dst_ip);
1747ec2f6bcSAndrey V. Elsukov 	src_ip =	htonl(p->f_id.src_ip);
1757ec2f6bcSAndrey V. Elsukov 
1767ec2f6bcSAndrey V. Elsukov 	dst_ip6 =	p->f_id.dst_ip6;
1777ec2f6bcSAndrey V. Elsukov 	src_ip6 =	p->f_id.src_ip6;
1787ec2f6bcSAndrey V. Elsukov 
1797ec2f6bcSAndrey V. Elsukov 	dst_port =	p->f_id.dst_port;
1807ec2f6bcSAndrey V. Elsukov 	src_port =	p->f_id.src_port;
1817ec2f6bcSAndrey V. Elsukov 
1827ec2f6bcSAndrey V. Elsukov 	flowid =	p->f_id.flow_id6;
1837ec2f6bcSAndrey V. Elsukov 	extra = 	p->f_id.extra;
1847ec2f6bcSAndrey V. Elsukov 
1857ec2f6bcSAndrey V. Elsukov 	/* ipfw_rule_ref */
1867ec2f6bcSAndrey V. Elsukov 	slot =		(p->flags & IPFW_ARGS_REF) ? p->rule.slot : 0;
1877ec2f6bcSAndrey V. Elsukov 	rulenum =	(p->flags & IPFW_ARGS_REF) ? p->rule.rulenum : 0;
1887ec2f6bcSAndrey V. Elsukov 	rule_id =	(p->flags & IPFW_ARGS_REF) ? p->rule.rule_id : 0;
1897ec2f6bcSAndrey V. Elsukov 	chain_id =	(p->flags & IPFW_ARGS_REF) ? p->rule.chain_id : 0;
1907ec2f6bcSAndrey V. Elsukov 	match_info =	(p->flags & IPFW_ARGS_REF) ? p->rule.info : 0;
1917ec2f6bcSAndrey V. Elsukov };
1927ec2f6bcSAndrey V. Elsukov 
1937ec2f6bcSAndrey V. Elsukov typedef struct ipfw_rule_info {
1947ec2f6bcSAndrey V. Elsukov 	uint16_t	act_ofs;
1957ec2f6bcSAndrey V. Elsukov 	uint16_t	cmd_len;
1967ec2f6bcSAndrey V. Elsukov 	uint32_t	rulenum;
1977ec2f6bcSAndrey V. Elsukov 	uint8_t		flags;
1987ec2f6bcSAndrey V. Elsukov 	uint8_t		set;
1997ec2f6bcSAndrey V. Elsukov 	uint32_t	rule_id;
2007ec2f6bcSAndrey V. Elsukov 	uint32_t	cached_id;
2017ec2f6bcSAndrey V. Elsukov 	uint32_t	cached_pos;
2027ec2f6bcSAndrey V. Elsukov 	uint32_t	refcnt;
2037ec2f6bcSAndrey V. Elsukov } ipfw_rule_info_t;
2047ec2f6bcSAndrey V. Elsukov 
2057ec2f6bcSAndrey V. Elsukov #pragma D binding "1.0" translator
2067ec2f6bcSAndrey V. Elsukov translator ipfw_rule_info_t < struct ip_fw *r > {
2077ec2f6bcSAndrey V. Elsukov 	act_ofs =	r->act_ofs;
2087ec2f6bcSAndrey V. Elsukov 	cmd_len =	r->cmd_len;
2097ec2f6bcSAndrey V. Elsukov 	rulenum =	r->rulenum;
2107ec2f6bcSAndrey V. Elsukov 	flags =		r->flags;
2117ec2f6bcSAndrey V. Elsukov 	set =		r->set;
2127ec2f6bcSAndrey V. Elsukov 	rule_id =	r->id;
2135c8e8e82SAndrey V. Elsukov 	cached_id =	r->cache.id;
2145c8e8e82SAndrey V. Elsukov 	cached_pos =	r->cache.pos;
2157ec2f6bcSAndrey V. Elsukov 	refcnt =	r->refcnt;
2167ec2f6bcSAndrey V. Elsukov };
2177ec2f6bcSAndrey V. Elsukov 
218