1 /* $OpenBSD: if_pfsync.h,v 1.9 2004/01/18 19:55:52 mcbride Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Michael Shalayeff 5 * All rights reserved. 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef _NET_IF_PFSYNC_H_ 30 #define _NET_IF_PFSYNC_H_ 31 32 struct pfsync_state_scrub { 33 u_int16_t pfss_flags; 34 u_int8_t pfss_ttl; /* stashed TTL */ 35 u_int8_t scrub_flag; 36 u_int32_t pfss_ts_mod; /* timestamp modulation */ 37 } __packed; 38 39 struct pfsync_state_host { 40 struct pf_addr addr; 41 u_int16_t port; 42 u_int16_t pad[3]; 43 } __packed; 44 45 struct pfsync_state_peer { 46 struct pfsync_state_scrub scrub; /* state is scrubbed */ 47 u_int32_t seqlo; /* Max sequence number sent */ 48 u_int32_t seqhi; /* Max the other end ACKd + win */ 49 u_int32_t seqdiff; /* Sequence number modulator */ 50 u_int16_t max_win; /* largest window (pre scaling) */ 51 u_int16_t mss; /* Maximum segment size option */ 52 u_int8_t state; /* active state level */ 53 u_int8_t wscale; /* window scaling factor */ 54 u_int8_t scrub_flag; 55 u_int8_t pad[5]; 56 } __packed; 57 58 struct pfsync_state { 59 u_int64_t id; 60 char ifname[IFNAMSIZ]; 61 struct pfsync_state_host lan; 62 struct pfsync_state_host gwy; 63 struct pfsync_state_host ext; 64 struct pfsync_state_peer src; 65 struct pfsync_state_peer dst; 66 struct pf_addr rt_addr; 67 u_int32_t rule; 68 u_int32_t anchor; 69 u_int32_t nat_rule; 70 u_int32_t creation; 71 u_int32_t expire; 72 u_int32_t packets[2]; 73 u_int32_t bytes[2]; 74 u_int32_t creatorid; 75 sa_family_t af; 76 u_int8_t proto; 77 u_int8_t direction; 78 u_int8_t log; 79 u_int8_t allow_opts; 80 u_int8_t timeout; 81 u_int8_t sync_flags; 82 u_int8_t updates; 83 } __packed; 84 85 struct pfsync_state_upd { 86 u_int64_t id; 87 struct pfsync_state_peer src; 88 struct pfsync_state_peer dst; 89 u_int32_t creatorid; 90 u_int32_t expire; 91 u_int8_t updates; 92 u_int8_t pad[7]; 93 } __packed; 94 95 struct pfsync_state_del { 96 u_int64_t id; 97 u_int32_t creatorid; 98 struct { 99 u_int8_t state; 100 } src; 101 struct { 102 u_int8_t state; 103 } dst; 104 u_int8_t pad[2]; 105 } __packed; 106 107 struct pfsync_state_upd_req { 108 u_int64_t id; 109 u_int32_t creatorid; 110 u_int32_t pad; 111 } __packed; 112 113 struct pfsync_state_clr { 114 u_int32_t creatorid; 115 u_int32_t pad; 116 } __packed; 117 118 #ifdef _KERNEL 119 120 union sc_statep { 121 struct pfsync_state *s; 122 struct pfsync_state_upd *u; 123 struct pfsync_state_del *d; 124 struct pfsync_state_clr *c; 125 struct pfsync_state_upd_req *r; 126 }; 127 128 struct pfsync_softc { 129 struct ifnet sc_if; 130 struct ifnet *sc_sync_ifp; 131 132 struct ip_moptions sc_imo; 133 struct timeout sc_tmo; 134 struct in_addr sc_sendaddr; 135 struct mbuf *sc_mbuf; /* current cummulative mbuf */ 136 struct mbuf *sc_mbuf_net; /* current cummulative mbuf */ 137 union sc_statep sc_statep; 138 union sc_statep sc_statep_net; 139 int sc_maxcount; /* number of states in mtu */ 140 int sc_maxupdates; /* number of updates/state */ 141 }; 142 #endif 143 144 145 struct pfsync_header { 146 u_int8_t version; 147 #define PFSYNC_VERSION 2 148 u_int8_t af; 149 u_int8_t action; 150 #define PFSYNC_ACT_CLR 0 /* clear all states */ 151 #define PFSYNC_ACT_INS 1 /* insert state */ 152 #define PFSYNC_ACT_UPD 2 /* update state */ 153 #define PFSYNC_ACT_DEL 3 /* delete state */ 154 #define PFSYNC_ACT_UPD_C 4 /* "compressed" state update */ 155 #define PFSYNC_ACT_DEL_C 5 /* "compressed" state delete */ 156 #define PFSYNC_ACT_INS_F 6 /* insert fragment */ 157 #define PFSYNC_ACT_DEL_F 7 /* delete fragments */ 158 #define PFSYNC_ACT_UREQ 8 /* request "uncompressed" state */ 159 #define PFSYNC_ACT_MAX 9 160 u_int8_t count; 161 } __packed; 162 163 #define PFSYNC_HDRLEN sizeof(struct pfsync_header) 164 #define PFSYNC_ACTIONS \ 165 "CLR ST", "INS ST", "UPD ST", "DEL ST", \ 166 "UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", "UPD REQ" 167 168 #define PFSYNC_DFLTTL 255 169 170 struct pfsyncstats { 171 u_long pfsyncs_ipackets; /* total input packets, IPv4 */ 172 u_long pfsyncs_ipackets6; /* total input packets, IPv6 */ 173 u_long pfsyncs_badif; /* not the right interface */ 174 u_long pfsyncs_badttl; /* TTL is not PFSYNC_DFLTTL */ 175 u_long pfsyncs_hdrops; /* packets shorter than header */ 176 u_long pfsyncs_badver; /* bad (incl unsupp) version */ 177 u_long pfsyncs_badact; /* bad action */ 178 u_long pfsyncs_badlen; /* data length does not match */ 179 u_long pfsyncs_badauth; /* bad authentication */ 180 u_long pfsyncs_badstate; /* insert/lookup failed */ 181 182 u_long pfsyncs_opackets; /* total output packets, IPv4 */ 183 u_long pfsyncs_opackets6; /* total output packets, IPv6 */ 184 u_long pfsyncs_onomem; /* no memory for an mbuf for a send */ 185 u_long pfsyncs_oerrors; /* ip output error */ 186 }; 187 188 /* 189 * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC 190 */ 191 struct pfsyncreq { 192 char pfsyncr_syncif[IFNAMSIZ]; 193 int pfsyncr_maxupdates; 194 int pfsyncr_authlevel; 195 }; 196 #define SIOCSETPFSYNC _IOW('i', 247, struct ifreq) 197 #define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq) 198 199 200 #define pf_state_peer_hton(s,d) do { \ 201 (d)->seqlo = htonl((s)->seqlo); \ 202 (d)->seqhi = htonl((s)->seqhi); \ 203 (d)->seqdiff = htonl((s)->seqdiff); \ 204 (d)->max_win = htons((s)->max_win); \ 205 (d)->mss = htons((s)->mss); \ 206 (d)->state = (s)->state; \ 207 (d)->wscale = (s)->wscale; \ 208 } while (0) 209 210 #define pf_state_peer_ntoh(s,d) do { \ 211 (d)->seqlo = ntohl((s)->seqlo); \ 212 (d)->seqhi = ntohl((s)->seqhi); \ 213 (d)->seqdiff = ntohl((s)->seqdiff); \ 214 (d)->max_win = ntohs((s)->max_win); \ 215 (d)->mss = ntohs((s)->mss); \ 216 (d)->state = (s)->state; \ 217 (d)->wscale = (s)->wscale; \ 218 } while (0) 219 220 #define pf_state_host_hton(s,d) do { \ 221 bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ 222 (d)->port = (s)->port; \ 223 } while (0) 224 225 #define pf_state_host_ntoh(s,d) do { \ 226 bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ 227 (d)->port = (s)->port; \ 228 } while (0) 229 230 #ifdef _KERNEL 231 void pfsync_input(struct mbuf *, ...); 232 int pfsync_clear_states(u_int32_t); 233 int pfsync_pack_state(u_int8_t, struct pf_state *, int); 234 #define pfsync_insert_state(st) do { \ 235 if (st->rule.ptr->rule_flag & PFRULE_NOSYNC) \ 236 st->sync_flags |= PFSTATE_NOSYNC; \ 237 else if (!st->sync_flags) \ 238 pfsync_pack_state(PFSYNC_ACT_INS, (st), 1); \ 239 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 240 } while (0) 241 #define pfsync_update_state(st) do { \ 242 if (!st->sync_flags) \ 243 pfsync_pack_state(PFSYNC_ACT_UPD, (st), 1); \ 244 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 245 } while (0) 246 #define pfsync_delete_state(st) do { \ 247 if (!st->sync_flags) \ 248 pfsync_pack_state(PFSYNC_ACT_DEL, (st), 1); \ 249 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 250 } while (0) 251 #endif 252 253 #endif /* _NET_IF_PFSYNC_H_ */ 254