1 /* $NetBSD: npf.h,v 1.10 2011/11/06 02:49:03 rmind Exp $ */ 2 3 /*- 4 * Copyright (c) 2009-2011 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This material is based upon work partially supported by The 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 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 the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Public NPF interfaces. 34 */ 35 36 #ifndef _NPF_NET_H_ 37 #define _NPF_NET_H_ 38 39 #include <sys/param.h> 40 #include <sys/types.h> 41 42 #include <sys/ioctl.h> 43 #include <prop/proplib.h> 44 45 #include <netinet/in_systm.h> 46 #include <netinet/in.h> 47 48 #ifdef _NPF_TESTING 49 #include "testing.h" 50 #endif 51 52 #define NPF_VERSION 3 53 54 /* 55 * Public declarations and definitions. 56 */ 57 58 /* Storage of address (both for IPv4 and IPv6) and netmask */ 59 typedef struct in6_addr npf_addr_t; 60 typedef uint8_t npf_netmask_t; 61 62 #define NPF_NO_NETMASK ((npf_netmask_t)~0) 63 64 #if defined(_KERNEL) || defined(_NPF_TESTING) 65 66 /* Network buffer. */ 67 typedef void nbuf_t; 68 69 struct npf_rproc; 70 struct npf_hook; 71 72 typedef struct npf_rproc npf_rproc_t; 73 typedef struct npf_hook npf_hook_t; 74 75 /* 76 * Packet information cache. 77 */ 78 #include <netinet/ip.h> 79 #include <netinet/ip6.h> 80 #include <netinet/tcp.h> 81 #include <netinet/udp.h> 82 #include <netinet/ip_icmp.h> 83 84 #define NPC_IP4 0x01 /* Indicates fetched IPv4 header. */ 85 #define NPC_IP6 0x02 /* Indicates IPv6 header. */ 86 #define NPC_IPFRAG 0x04 /* IPv4/IPv6 fragment. */ 87 #define NPC_LAYER4 0x08 /* Layer 4 has been fetched. */ 88 89 #define NPC_TCP 0x10 /* TCP header. */ 90 #define NPC_UDP 0x20 /* UDP header. */ 91 #define NPC_ICMP 0x40 /* ICMP header. */ 92 #define NPC_ICMP_ID 0x80 /* ICMP with query ID. */ 93 94 #define NPC_IP46 (NPC_IP4|NPC_IP6) 95 96 typedef struct { 97 /* Information flags. */ 98 uint32_t npc_info; 99 /* Pointers to the IP v4/v6 addresses. */ 100 npf_addr_t * npc_srcip; 101 npf_addr_t * npc_dstip; 102 /* Size (v4 or v6) of IP addresses. */ 103 int npc_ipsz; 104 size_t npc_hlen; 105 int npc_next_proto; 106 /* IPv4, IPv6. */ 107 union { 108 struct ip v4; 109 struct ip6_hdr v6; 110 } npc_ip; 111 /* TCP, UDP, ICMP. */ 112 union { 113 struct tcphdr tcp; 114 struct udphdr udp; 115 struct icmp icmp; 116 } npc_l4; 117 } npf_cache_t; 118 119 static inline void 120 npf_generate_mask(npf_addr_t *dst, const npf_netmask_t omask) 121 { 122 uint_fast8_t length = omask; 123 124 /* Note: maximum length is 32 for IPv4 and 128 for IPv6. */ 125 KASSERT(length <= 128); 126 127 for (int i = 0; i < 4; i++) { 128 if (length >= 32) { 129 dst->s6_addr32[i] = htonl(0xffffffff); 130 length -= 32; 131 } else { 132 dst->s6_addr32[i] = htonl(0xffffffff << (32 - length)); 133 length = 0; 134 } 135 } 136 } 137 138 static inline void 139 npf_calculate_masked_addr(npf_addr_t *dst, const npf_addr_t *src, 140 const npf_netmask_t omask) 141 { 142 npf_addr_t mask; 143 144 npf_generate_mask(&mask, omask); 145 for (int i = 0; i < 4; i++) { 146 dst->s6_addr32[i] = src->s6_addr32[i] & mask.s6_addr32[i]; 147 } 148 } 149 150 /* 151 * npf_compare_cidr: compare two addresses, either IPv4 or IPv6. 152 * 153 * => If the mask is NULL, ignore it. 154 */ 155 static inline int 156 npf_compare_cidr(const npf_addr_t *addr1, const npf_netmask_t mask1, 157 const npf_addr_t *addr2, const npf_netmask_t mask2) 158 { 159 npf_addr_t realmask1, realmask2; 160 161 if (mask1 != NPF_NO_NETMASK) { 162 npf_generate_mask(&realmask1, mask1); 163 } 164 if (mask2 != NPF_NO_NETMASK) { 165 npf_generate_mask(&realmask2, mask2); 166 } 167 for (int i = 0; i < 4; i++) { 168 const uint32_t x = mask1 != NPF_NO_NETMASK ? 169 addr1->s6_addr32[i] & realmask1.s6_addr32[i] : 170 addr1->s6_addr32[i]; 171 const uint32_t y = mask2 != NPF_NO_NETMASK ? 172 addr2->s6_addr32[i] & realmask2.s6_addr32[i] : 173 addr2->s6_addr32[i]; 174 if (x < y) { 175 return -1; 176 } 177 if (x > y) { 178 return 1; 179 } 180 } 181 182 return 0; 183 } 184 185 static inline bool 186 npf_iscached(const npf_cache_t *npc, const int inf) 187 { 188 189 return __predict_true((npc->npc_info & inf) != 0); 190 } 191 192 static inline int 193 npf_cache_ipproto(const npf_cache_t *npc) 194 { 195 KASSERT(npf_iscached(npc, NPC_IP46)); 196 return npc->npc_next_proto; 197 } 198 199 static inline int 200 npf_cache_hlen(const npf_cache_t *npc, nbuf_t *nbuf) 201 { 202 KASSERT(npf_iscached(npc, NPC_IP46)); 203 return npc->npc_hlen; 204 } 205 206 /* Network buffer interface. */ 207 void * nbuf_dataptr(void *); 208 void * nbuf_advance(nbuf_t **, void *, u_int); 209 int nbuf_advfetch(nbuf_t **, void **, u_int, size_t, void *); 210 int nbuf_advstore(nbuf_t **, void **, u_int, size_t, void *); 211 int nbuf_fetch_datum(nbuf_t *, void *, size_t, void *); 212 int nbuf_store_datum(nbuf_t *, void *, size_t, void *); 213 214 int nbuf_add_tag(nbuf_t *, uint32_t, uint32_t); 215 int nbuf_find_tag(nbuf_t *, uint32_t, void **); 216 217 #if 0 218 npf_hook_t * npf_hook_register(npf_rule_t *, 219 void (*)(npf_cache_t *, nbuf_t *, void *), void *); 220 void npf_hook_unregister(npf_rule_t *, npf_hook_t *); 221 #endif 222 223 #endif /* _KERNEL */ 224 225 /* Rule attributes. */ 226 #define NPF_RULE_PASS 0x0001 227 #define NPF_RULE_DEFAULT 0x0002 228 #define NPF_RULE_FINAL 0x0004 229 #define NPF_RULE_KEEPSTATE 0x0008 230 #define NPF_RULE_RETRST 0x0010 231 #define NPF_RULE_RETICMP 0x0020 232 233 #define NPF_RULE_IN 0x10000000 234 #define NPF_RULE_OUT 0x20000000 235 #define NPF_RULE_DIMASK (NPF_RULE_IN | NPF_RULE_OUT) 236 237 /* Rule procedure flags. */ 238 #define NPF_RPROC_LOG 0x0001 239 #define NPF_RPROC_NORMALIZE 0x0002 240 241 /* Address translation types and flags. */ 242 #define NPF_NATIN 1 243 #define NPF_NATOUT 2 244 245 #define NPF_NAT_PORTS 0x01 246 #define NPF_NAT_PORTMAP 0x02 247 248 /* Table types. */ 249 #define NPF_TABLE_HASH 1 250 #define NPF_TABLE_RBTREE 2 251 252 /* Layers. */ 253 #define NPF_LAYER_2 2 254 #define NPF_LAYER_3 3 255 256 /* XXX mbuf.h: just for now. */ 257 #define PACKET_TAG_NPF 10 258 259 /* 260 * IOCTL structures. 261 */ 262 263 #define NPF_IOCTL_TBLENT_ADD 1 264 #define NPF_IOCTL_TBLENT_REM 2 265 266 typedef struct npf_ioctl_table { 267 int nct_action; 268 u_int nct_tid; 269 npf_addr_t nct_addr; 270 npf_netmask_t nct_mask; 271 } npf_ioctl_table_t; 272 273 typedef enum { 274 /* Packets passed. */ 275 NPF_STAT_PASS_DEFAULT, 276 NPF_STAT_PASS_RULESET, 277 NPF_STAT_PASS_SESSION, 278 /* Packets blocked. */ 279 NPF_STAT_BLOCK_DEFAULT, 280 NPF_STAT_BLOCK_RULESET, 281 /* Session and NAT entries. */ 282 NPF_STAT_SESSION_CREATE, 283 NPF_STAT_SESSION_DESTROY, 284 NPF_STAT_NAT_CREATE, 285 NPF_STAT_NAT_DESTROY, 286 /* Invalid state cases. */ 287 NPF_STAT_INVALID_STATE, 288 NPF_STAT_INVALID_STATE_TCP1, 289 NPF_STAT_INVALID_STATE_TCP2, 290 NPF_STAT_INVALID_STATE_TCP3, 291 /* Raced packets. */ 292 NPF_STAT_RACE_SESSION, 293 NPF_STAT_RACE_NAT, 294 /* Rule procedure cases. */ 295 NPF_STAT_RPROC_LOG, 296 NPF_STAT_RPROC_NORM, 297 /* Other errors. */ 298 NPF_STAT_ERROR, 299 /* Count (last). */ 300 NPF_STATS_COUNT 301 } npf_stats_t; 302 303 #define NPF_STATS_SIZE (sizeof(uint64_t) * NPF_STATS_COUNT) 304 305 /* 306 * IOCTL operations. 307 */ 308 309 #define IOC_NPF_VERSION _IOR('N', 100, int) 310 #define IOC_NPF_SWITCH _IOW('N', 101, int) 311 #define IOC_NPF_RELOAD _IOW('N', 102, struct plistref) 312 #define IOC_NPF_TABLE _IOW('N', 103, struct npf_ioctl_table) 313 #define IOC_NPF_STATS _IOW('N', 104, void *) 314 #define IOC_NPF_SESSIONS_SAVE _IOR('N', 105, struct plistref) 315 #define IOC_NPF_SESSIONS_LOAD _IOW('N', 106, struct plistref) 316 #define IOC_NPF_UPDATE_RULE _IOW('N', 107, struct plistref) 317 318 #endif /* _NPF_NET_H_ */ 319