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 /* 37 * pfvar.h is required to get struct pf_addr. Also kdump and other utilities 38 * blindly include header files to try to get all the ioctl constants and 39 * buildworld will fail without this. We need a better way XXX 40 */ 41 #ifndef _NET_PFVAR_H_ 42 #include "pfvar.h" 43 #endif 44 45 46 #define PFSYNC_ID_LEN sizeof(u_int64_t) 47 48 struct pfsync_state_scrub { 49 u_int16_t pfss_flags; 50 u_int8_t pfss_ttl; /* stashed TTL */ 51 u_int8_t scrub_flag; 52 u_int32_t pfss_ts_mod; /* timestamp modulation */ 53 } __packed; 54 55 struct pfsync_state_host { 56 struct pf_addr addr; 57 u_int16_t port; 58 u_int16_t pad[3]; 59 } __packed; 60 61 struct pfsync_state_peer { 62 struct pfsync_state_scrub scrub; /* state is scrubbed */ 63 u_int32_t seqlo; /* Max sequence number sent */ 64 u_int32_t seqhi; /* Max the other end ACKd + win */ 65 u_int32_t seqdiff; /* Sequence number modulator */ 66 u_int16_t max_win; /* largest window (pre scaling) */ 67 u_int16_t mss; /* Maximum segment size option */ 68 u_int8_t state; /* active state level */ 69 u_int8_t wscale; /* window scaling factor */ 70 u_int8_t scrub_flag; 71 u_int8_t pad[5]; 72 } __packed; 73 74 struct pfsync_state { 75 u_int32_t id[2]; 76 char ifname[IFNAMSIZ]; 77 struct pfsync_state_host lan; 78 struct pfsync_state_host gwy; 79 struct pfsync_state_host ext; 80 struct pfsync_state_peer src; 81 struct pfsync_state_peer dst; 82 struct pf_addr rt_addr; 83 u_int32_t rule; 84 u_int32_t anchor; 85 u_int32_t nat_rule; 86 u_int32_t creation; 87 u_int32_t expire; 88 u_int32_t packets[2]; 89 u_int32_t bytes[2]; 90 u_int32_t creatorid; 91 sa_family_t af; 92 u_int8_t proto; 93 u_int8_t direction; 94 u_int8_t log; 95 u_int8_t allow_opts; 96 u_int8_t timeout; 97 u_int8_t sync_flags; 98 u_int8_t updates; 99 } __packed; 100 101 struct pfsync_state_upd { 102 u_int32_t id[2]; 103 struct pfsync_state_peer src; 104 struct pfsync_state_peer dst; 105 u_int32_t creatorid; 106 u_int32_t expire; 107 u_int8_t timeout; 108 u_int8_t updates; 109 u_int8_t pad[6]; 110 } __packed; 111 112 struct pfsync_state_del { 113 u_int32_t id[2]; 114 u_int32_t creatorid; 115 struct { 116 u_int8_t state; 117 } src; 118 struct { 119 u_int8_t state; 120 } dst; 121 u_int8_t pad[2]; 122 } __packed; 123 124 struct pfsync_state_upd_req { 125 u_int32_t id[2]; 126 u_int32_t creatorid; 127 u_int32_t pad; 128 } __packed; 129 130 struct pfsync_state_clr { 131 char ifname[IFNAMSIZ]; 132 u_int32_t creatorid; 133 u_int32_t pad; 134 } __packed; 135 136 struct pfsync_state_bus { 137 u_int32_t creatorid; 138 u_int32_t endtime; 139 u_int8_t status; 140 #define PFSYNC_BUS_START 1 141 #define PFSYNC_BUS_END 2 142 u_int8_t pad[7]; 143 } __packed; 144 145 #ifdef _KERNEL 146 147 union sc_statep { 148 struct pfsync_state *s; 149 struct pfsync_state_upd *u; 150 struct pfsync_state_del *d; 151 struct pfsync_state_clr *c; 152 struct pfsync_state_bus *b; 153 struct pfsync_state_upd_req *r; 154 }; 155 156 extern int pfsync_sync_ok; 157 158 struct pfsync_softc { 159 struct ifnet sc_if; 160 struct ifnet *sc_sync_ifp; 161 162 struct ip_moptions sc_imo; 163 struct callout sc_tmo; 164 struct callout sc_bulk_tmo; 165 struct callout sc_bulkfail_tmo; 166 struct in_addr sc_sendaddr; 167 struct mbuf *sc_mbuf; /* current cummulative mbuf */ 168 struct mbuf *sc_mbuf_net; /* current cummulative mbuf */ 169 union sc_statep sc_statep; 170 union sc_statep sc_statep_net; 171 u_int32_t sc_ureq_received; 172 u_int32_t sc_ureq_sent; 173 int sc_bulk_tries; 174 int sc_maxcount; /* number of states in mtu */ 175 int sc_maxupdates; /* number of updates/state */ 176 LIST_ENTRY(pfsync_softc) sc_next; 177 }; 178 #endif 179 180 181 struct pfsync_header { 182 u_int8_t version; 183 #define PFSYNC_VERSION 2 184 u_int8_t af; 185 u_int8_t action; 186 #define PFSYNC_ACT_CLR 0 /* clear all states */ 187 #define PFSYNC_ACT_INS 1 /* insert state */ 188 #define PFSYNC_ACT_UPD 2 /* update state */ 189 #define PFSYNC_ACT_DEL 3 /* delete state */ 190 #define PFSYNC_ACT_UPD_C 4 /* "compressed" state update */ 191 #define PFSYNC_ACT_DEL_C 5 /* "compressed" state delete */ 192 #define PFSYNC_ACT_INS_F 6 /* insert fragment */ 193 #define PFSYNC_ACT_DEL_F 7 /* delete fragments */ 194 #define PFSYNC_ACT_UREQ 8 /* request "uncompressed" state */ 195 #define PFSYNC_ACT_BUS 9 /* Bulk Update Status */ 196 #define PFSYNC_ACT_MAX 10 197 u_int8_t count; 198 } __packed; 199 200 #define PFSYNC_BULKPACKETS 1 /* # of packets per timeout */ 201 #define PFSYNC_MAX_BULKTRIES 12 202 #define PFSYNC_HDRLEN sizeof(struct pfsync_header) 203 #define PFSYNC_ACTIONS \ 204 "CLR ST", "INS ST", "UPD ST", "DEL ST", \ 205 "UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \ 206 "UPD REQ", "BLK UPD STAT" 207 208 #define PFSYNC_DFLTTL 255 209 210 struct pfsyncstats { 211 u_long pfsyncs_ipackets; /* total input packets, IPv4 */ 212 u_long pfsyncs_ipackets6; /* total input packets, IPv6 */ 213 u_long pfsyncs_badif; /* not the right interface */ 214 u_long pfsyncs_badttl; /* TTL is not PFSYNC_DFLTTL */ 215 u_long pfsyncs_hdrops; /* packets shorter than header */ 216 u_long pfsyncs_badver; /* bad (incl unsupp) version */ 217 u_long pfsyncs_badact; /* bad action */ 218 u_long pfsyncs_badlen; /* data length does not match */ 219 u_long pfsyncs_badauth; /* bad authentication */ 220 u_long pfsyncs_badstate; /* insert/lookup failed */ 221 222 u_long pfsyncs_opackets; /* total output packets, IPv4 */ 223 u_long pfsyncs_opackets6; /* total output packets, IPv6 */ 224 u_long pfsyncs_onomem; /* no memory for an mbuf for a send */ 225 u_long pfsyncs_oerrors; /* ip output error */ 226 }; 227 228 /* 229 * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC 230 */ 231 struct pfsyncreq { 232 char pfsyncr_syncif[IFNAMSIZ]; 233 int pfsyncr_maxupdates; 234 int pfsyncr_authlevel; 235 }; 236 #define SIOCSETPFSYNC _IOW('i', 247, struct ifreq) 237 #define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq) 238 239 240 #define pf_state_peer_hton(s,d) do { \ 241 (d)->seqlo = htonl((s)->seqlo); \ 242 (d)->seqhi = htonl((s)->seqhi); \ 243 (d)->seqdiff = htonl((s)->seqdiff); \ 244 (d)->max_win = htons((s)->max_win); \ 245 (d)->mss = htons((s)->mss); \ 246 (d)->state = (s)->state; \ 247 (d)->wscale = (s)->wscale; \ 248 } while (0) 249 250 #define pf_state_peer_ntoh(s,d) do { \ 251 (d)->seqlo = ntohl((s)->seqlo); \ 252 (d)->seqhi = ntohl((s)->seqhi); \ 253 (d)->seqdiff = ntohl((s)->seqdiff); \ 254 (d)->max_win = ntohs((s)->max_win); \ 255 (d)->mss = ntohs((s)->mss); \ 256 (d)->state = (s)->state; \ 257 (d)->wscale = (s)->wscale; \ 258 } while (0) 259 260 #define pf_state_host_hton(s,d) do { \ 261 bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ 262 (d)->port = (s)->port; \ 263 } while (0) 264 265 #define pf_state_host_ntoh(s,d) do { \ 266 bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ 267 (d)->port = (s)->port; \ 268 } while (0) 269 270 #ifdef _KERNEL 271 void pfsync_input(struct mbuf *, ...); 272 int pfsync_clear_states(u_int32_t, char *); 273 int pfsync_pack_state(u_int8_t, struct pf_state *, int); 274 #define pfsync_insert_state(st) do { \ 275 if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) || \ 276 (st->proto == IPPROTO_PFSYNC)) \ 277 st->sync_flags |= PFSTATE_NOSYNC; \ 278 else if (!st->sync_flags) \ 279 pfsync_pack_state(PFSYNC_ACT_INS, (st), 1); \ 280 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 281 } while (0) 282 #define pfsync_update_state(st) do { \ 283 if (!st->sync_flags) \ 284 pfsync_pack_state(PFSYNC_ACT_UPD, (st), 1); \ 285 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 286 } while (0) 287 #define pfsync_delete_state(st) do { \ 288 if (!st->sync_flags) \ 289 pfsync_pack_state(PFSYNC_ACT_DEL, (st), 1); \ 290 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 291 } while (0) 292 #endif 293 294 #endif /* _NET_IF_PFSYNC_H_ */ 295