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->cache.id; 216 cached_pos = r->cache.pos; 217 refcnt = r->refcnt; 218 }; 219 220