1 /* $FreeBSD: src/sys/contrib/pf/net/if_pfsync.h,v 1.4 2004/06/16 23:24:00 mlaier Exp $ */ 2 /* $OpenBSD: if_pfsync.h,v 1.13 2004/03/22 04:54:17 mcbride Exp $ */ 3 /* $DragonFly: src/sys/net/pf/if_pfsync.h,v 1.2 2004/09/20 01:43:13 dillon Exp $ */ 4 5 /* 6 * Copyright (c) 2004 The DragonFly Project. All rights reserved. 7 * 8 * Copyright (c) 2001 Michael Shalayeff 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef _NET_IF_PFSYNC_H_ 34 #define _NET_IF_PFSYNC_H_ 35 36 #include <sys/ioccom.h> 37 38 /* 39 * pfvar.h is required to get struct pf_addr. Also kdump and other utilities 40 * blindly include header files to try to get all the ioctl constants and 41 * buildworld will fail without this. We need a better way XXX 42 */ 43 #ifndef _NET_PFVAR_H_ 44 #include "pfvar.h" 45 #endif 46 47 48 #define PFSYNC_ID_LEN sizeof(u_int64_t) 49 50 struct pfsync_state_scrub { 51 u_int16_t pfss_flags; 52 u_int8_t pfss_ttl; /* stashed TTL */ 53 u_int8_t scrub_flag; 54 u_int32_t pfss_ts_mod; /* timestamp modulation */ 55 } __packed; 56 57 struct pfsync_state_host { 58 struct pf_addr addr; 59 u_int16_t port; 60 u_int16_t pad[3]; 61 } __packed; 62 63 struct pfsync_state_peer { 64 struct pfsync_state_scrub scrub; /* state is scrubbed */ 65 u_int32_t seqlo; /* Max sequence number sent */ 66 u_int32_t seqhi; /* Max the other end ACKd + win */ 67 u_int32_t seqdiff; /* Sequence number modulator */ 68 u_int16_t max_win; /* largest window (pre scaling) */ 69 u_int16_t mss; /* Maximum segment size option */ 70 u_int8_t state; /* active state level */ 71 u_int8_t wscale; /* window scaling factor */ 72 u_int8_t scrub_flag; 73 u_int8_t pad[5]; 74 } __packed; 75 76 struct pfsync_state { 77 u_int32_t id[2]; 78 char ifname[IFNAMSIZ]; 79 struct pfsync_state_host lan; 80 struct pfsync_state_host gwy; 81 struct pfsync_state_host ext; 82 struct pfsync_state_peer src; 83 struct pfsync_state_peer dst; 84 struct pf_addr rt_addr; 85 u_int32_t rule; 86 u_int32_t anchor; 87 u_int32_t nat_rule; 88 u_int32_t creation; 89 u_int32_t expire; 90 u_int32_t packets[2]; 91 u_int32_t bytes[2]; 92 u_int32_t creatorid; 93 sa_family_t af; 94 u_int8_t proto; 95 u_int8_t direction; 96 u_int8_t log; 97 u_int8_t allow_opts; 98 u_int8_t timeout; 99 u_int8_t sync_flags; 100 u_int8_t updates; 101 } __packed; 102 103 struct pfsync_state_upd { 104 u_int32_t id[2]; 105 struct pfsync_state_peer src; 106 struct pfsync_state_peer dst; 107 u_int32_t creatorid; 108 u_int32_t expire; 109 u_int8_t timeout; 110 u_int8_t updates; 111 u_int8_t pad[6]; 112 } __packed; 113 114 struct pfsync_state_del { 115 u_int32_t id[2]; 116 u_int32_t creatorid; 117 struct { 118 u_int8_t state; 119 } src; 120 struct { 121 u_int8_t state; 122 } dst; 123 u_int8_t pad[2]; 124 } __packed; 125 126 struct pfsync_state_upd_req { 127 u_int32_t id[2]; 128 u_int32_t creatorid; 129 u_int32_t pad; 130 } __packed; 131 132 struct pfsync_state_clr { 133 char ifname[IFNAMSIZ]; 134 u_int32_t creatorid; 135 u_int32_t pad; 136 } __packed; 137 138 struct pfsync_state_bus { 139 u_int32_t creatorid; 140 u_int32_t endtime; 141 u_int8_t status; 142 #define PFSYNC_BUS_START 1 143 #define PFSYNC_BUS_END 2 144 u_int8_t pad[7]; 145 } __packed; 146 147 #ifdef _KERNEL 148 149 union sc_statep { 150 struct pfsync_state *s; 151 struct pfsync_state_upd *u; 152 struct pfsync_state_del *d; 153 struct pfsync_state_clr *c; 154 struct pfsync_state_bus *b; 155 struct pfsync_state_upd_req *r; 156 }; 157 158 extern int pfsync_sync_ok; 159 160 struct pfsync_softc { 161 struct ifnet sc_if; 162 struct ifnet *sc_sync_ifp; 163 164 struct ip_moptions sc_imo; 165 struct callout sc_tmo; 166 struct callout sc_bulk_tmo; 167 struct callout sc_bulkfail_tmo; 168 struct in_addr sc_sendaddr; 169 struct mbuf *sc_mbuf; /* current cummulative mbuf */ 170 struct mbuf *sc_mbuf_net; /* current cummulative mbuf */ 171 union sc_statep sc_statep; 172 union sc_statep sc_statep_net; 173 u_int32_t sc_ureq_received; 174 u_int32_t sc_ureq_sent; 175 int sc_bulk_tries; 176 int sc_maxcount; /* number of states in mtu */ 177 int sc_maxupdates; /* number of updates/state */ 178 LIST_ENTRY(pfsync_softc) sc_next; 179 }; 180 #endif 181 182 183 struct pfsync_header { 184 u_int8_t version; 185 #define PFSYNC_VERSION 2 186 u_int8_t af; 187 u_int8_t action; 188 #define PFSYNC_ACT_CLR 0 /* clear all states */ 189 #define PFSYNC_ACT_INS 1 /* insert state */ 190 #define PFSYNC_ACT_UPD 2 /* update state */ 191 #define PFSYNC_ACT_DEL 3 /* delete state */ 192 #define PFSYNC_ACT_UPD_C 4 /* "compressed" state update */ 193 #define PFSYNC_ACT_DEL_C 5 /* "compressed" state delete */ 194 #define PFSYNC_ACT_INS_F 6 /* insert fragment */ 195 #define PFSYNC_ACT_DEL_F 7 /* delete fragments */ 196 #define PFSYNC_ACT_UREQ 8 /* request "uncompressed" state */ 197 #define PFSYNC_ACT_BUS 9 /* Bulk Update Status */ 198 #define PFSYNC_ACT_MAX 10 199 u_int8_t count; 200 } __packed; 201 202 #define PFSYNC_BULKPACKETS 1 /* # of packets per timeout */ 203 #define PFSYNC_MAX_BULKTRIES 12 204 #define PFSYNC_HDRLEN sizeof(struct pfsync_header) 205 #define PFSYNC_ACTIONS \ 206 "CLR ST", "INS ST", "UPD ST", "DEL ST", \ 207 "UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \ 208 "UPD REQ", "BLK UPD STAT" 209 210 #define PFSYNC_DFLTTL 255 211 212 struct pfsyncstats { 213 u_long pfsyncs_ipackets; /* total input packets, IPv4 */ 214 u_long pfsyncs_ipackets6; /* total input packets, IPv6 */ 215 u_long pfsyncs_badif; /* not the right interface */ 216 u_long pfsyncs_badttl; /* TTL is not PFSYNC_DFLTTL */ 217 u_long pfsyncs_hdrops; /* packets shorter than header */ 218 u_long pfsyncs_badver; /* bad (incl unsupp) version */ 219 u_long pfsyncs_badact; /* bad action */ 220 u_long pfsyncs_badlen; /* data length does not match */ 221 u_long pfsyncs_badauth; /* bad authentication */ 222 u_long pfsyncs_badstate; /* insert/lookup failed */ 223 224 u_long pfsyncs_opackets; /* total output packets, IPv4 */ 225 u_long pfsyncs_opackets6; /* total output packets, IPv6 */ 226 u_long pfsyncs_onomem; /* no memory for an mbuf for a send */ 227 u_long pfsyncs_oerrors; /* ip output error */ 228 }; 229 230 /* 231 * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC 232 */ 233 struct pfsyncreq { 234 char pfsyncr_syncif[IFNAMSIZ]; 235 int pfsyncr_maxupdates; 236 int pfsyncr_authlevel; 237 }; 238 #define SIOCSETPFSYNC _IOW('i', 247, struct ifreq) 239 #define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq) 240 241 242 #define pf_state_peer_hton(s,d) do { \ 243 (d)->seqlo = htonl((s)->seqlo); \ 244 (d)->seqhi = htonl((s)->seqhi); \ 245 (d)->seqdiff = htonl((s)->seqdiff); \ 246 (d)->max_win = htons((s)->max_win); \ 247 (d)->mss = htons((s)->mss); \ 248 (d)->state = (s)->state; \ 249 (d)->wscale = (s)->wscale; \ 250 } while (0) 251 252 #define pf_state_peer_ntoh(s,d) do { \ 253 (d)->seqlo = ntohl((s)->seqlo); \ 254 (d)->seqhi = ntohl((s)->seqhi); \ 255 (d)->seqdiff = ntohl((s)->seqdiff); \ 256 (d)->max_win = ntohs((s)->max_win); \ 257 (d)->mss = ntohs((s)->mss); \ 258 (d)->state = (s)->state; \ 259 (d)->wscale = (s)->wscale; \ 260 } while (0) 261 262 #define pf_state_host_hton(s,d) do { \ 263 bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ 264 (d)->port = (s)->port; \ 265 } while (0) 266 267 #define pf_state_host_ntoh(s,d) do { \ 268 bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ 269 (d)->port = (s)->port; \ 270 } while (0) 271 272 #ifdef _KERNEL 273 void pfsync_input(struct mbuf *, ...); 274 int pfsync_clear_states(u_int32_t, char *); 275 int pfsync_pack_state(u_int8_t, struct pf_state *, int); 276 #define pfsync_insert_state(st) do { \ 277 if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) || \ 278 (st->proto == IPPROTO_PFSYNC)) \ 279 st->sync_flags |= PFSTATE_NOSYNC; \ 280 else if (!st->sync_flags) \ 281 pfsync_pack_state(PFSYNC_ACT_INS, (st), 1); \ 282 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 283 } while (0) 284 #define pfsync_update_state(st) do { \ 285 if (!st->sync_flags) \ 286 pfsync_pack_state(PFSYNC_ACT_UPD, (st), 1); \ 287 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 288 } while (0) 289 #define pfsync_delete_state(st) do { \ 290 if (!st->sync_flags) \ 291 pfsync_pack_state(PFSYNC_ACT_DEL, (st), 1); \ 292 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 293 } while (0) 294 #endif 295 296 #endif /* _NET_IF_PFSYNC_H_ */ 297