1 /* $OpenBSD: if_pfsync.h,v 1.4 2003/12/15 07:11:30 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 struct pfsync_state_host lan; 61 struct pfsync_state_host gwy; 62 struct pfsync_state_host ext; 63 struct pfsync_state_peer src; 64 struct pfsync_state_peer dst; 65 struct pf_addr rt_addr; 66 u_int32_t rule; 67 u_int32_t anchor; 68 u_int32_t nat_rule; 69 u_int32_t creation; 70 u_int32_t expire; 71 u_int32_t packets[2]; 72 u_int32_t bytes[2]; 73 u_int32_t creatorid; 74 sa_family_t af; 75 u_int8_t proto; 76 u_int8_t direction; 77 u_int8_t log; 78 u_int8_t allow_opts; 79 u_int8_t timeout; 80 u_int8_t sync_flags; 81 u_int8_t updates; 82 } __packed; 83 84 struct pfsync_state_upd { 85 u_int64_t id; 86 struct pfsync_state_peer src; 87 struct pfsync_state_peer dst; 88 u_int32_t creatorid; 89 u_int32_t expire; 90 u_int8_t updates; 91 u_int8_t pad[7]; 92 } __packed; 93 94 struct pfsync_state_del { 95 u_int64_t id; 96 u_int32_t creatorid; 97 struct { 98 u_int8_t state; 99 } src; 100 struct { 101 u_int8_t state; 102 } dst; 103 u_int8_t pad[2]; 104 } __packed; 105 106 struct pfsync_state_clr { 107 u_int32_t creatorid; 108 u_int32_t pad; 109 } __packed; 110 111 #ifdef _KERNEL 112 113 union sc_sp { 114 struct pfsync_state *s; 115 struct pfsync_state_upd *u; 116 struct pfsync_state_del *d; 117 struct pfsync_state_clr *c; 118 }; 119 120 struct pfsync_softc { 121 struct ifnet sc_if; 122 struct ifnet *sc_sync_ifp; 123 124 struct ip_moptions sc_imo; 125 struct timeout sc_tmo; 126 struct mbuf *sc_mbuf; /* current cummulative mbuf */ 127 struct mbuf *sc_mbuf_net; /* current cummulative mbuf */ 128 union sc_sp sc_sp; 129 union sc_sp sc_sp_net; 130 int sc_maxcount; /* number of states in mtu */ 131 int sc_maxupdates; /* number of updates/state */ 132 }; 133 #endif 134 135 136 struct pfsync_header { 137 u_int8_t version; 138 #define PFSYNC_VERSION 1 139 u_int8_t af; 140 u_int8_t action; 141 #define PFSYNC_ACT_CLR 0 /* clear all states */ 142 #define PFSYNC_ACT_INS 1 /* insert state */ 143 #define PFSYNC_ACT_UPD 2 /* update state */ 144 #define PFSYNC_ACT_DEL 3 /* delete state */ 145 #define PFSYNC_ACT_UPD_C 4 /* "compressed" state update */ 146 #define PFSYNC_ACT_DEL_C 5 /* "compressed" state delete */ 147 #define PFSYNC_ACT_INS_F 6 /* insert fragment */ 148 #define PFSYNC_ACT_DEL_F 7 /* delete fragments */ 149 #define PFSYNC_ACT_MAX 8 150 u_int8_t count; 151 } __packed; 152 153 #define PFSYNC_HDRLEN sizeof(struct pfsync_header) 154 #define PFSYNC_ACTIONS \ 155 "CLR ST", "INS ST", "UPD ST", "DEL ST", \ 156 "UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR" 157 158 #define PFSYNC_DFLTTL 255 159 160 struct pfsyncstats { 161 u_long pfsyncs_ipackets; /* total input packets, IPv4 */ 162 u_long pfsyncs_ipackets6; /* total input packets, IPv6 */ 163 u_long pfsyncs_badif; /* not the right interface */ 164 u_long pfsyncs_badttl; /* TTL is not PFSYNC_DFLTTL */ 165 u_long pfsyncs_hdrops; /* packets shorter than header */ 166 u_long pfsyncs_badver; /* bad (incl unsupp) version */ 167 u_long pfsyncs_badact; /* bad action */ 168 u_long pfsyncs_badlen; /* data length does not match */ 169 u_long pfsyncs_badauth; /* bad authentication */ 170 u_long pfsyncs_badstate; /* insert/lookup failed */ 171 172 u_long pfsyncs_opackets; /* total output packets, IPv4 */ 173 u_long pfsyncs_opackets6; /* total output packets, IPv6 */ 174 u_long pfsyncs_onomem; /* no memory for an mbuf for a send */ 175 u_long pfsyncs_oerrors; /* ip output error */ 176 }; 177 178 /* 179 * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC 180 */ 181 struct pfsyncreq { 182 char pfsyncr_syncif[IFNAMSIZ]; 183 int pfsyncr_maxupdates; 184 int pfsyncr_authlevel; 185 }; 186 #define SIOCSETPFSYNC _IOW('i', 247, struct ifreq) 187 #define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq) 188 189 190 #define pf_state_peer_hton(s,d) do { \ 191 (d)->seqlo = htonl((s)->seqlo); \ 192 (d)->seqhi = htonl((s)->seqhi); \ 193 (d)->seqdiff = htonl((s)->seqdiff); \ 194 (d)->max_win = htons((s)->max_win); \ 195 (d)->mss = htons((s)->mss); \ 196 (d)->state = (s)->state; \ 197 (d)->wscale = (s)->wscale; \ 198 } while (0) 199 200 #define pf_state_peer_ntoh(s,d) do { \ 201 (d)->seqlo = ntohl((s)->seqlo); \ 202 (d)->seqhi = ntohl((s)->seqhi); \ 203 (d)->seqdiff = ntohl((s)->seqdiff); \ 204 (d)->max_win = ntohs((s)->max_win); \ 205 (d)->mss = ntohs((s)->mss); \ 206 (d)->state = (s)->state; \ 207 (d)->wscale = (s)->wscale; \ 208 } while (0) 209 210 #define pf_state_host_hton(s,d) do { \ 211 bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ 212 (d)->port = htons((s)->port); \ 213 } while (0) 214 215 #define pf_state_host_ntoh(s,d) do { \ 216 bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ 217 (d)->port = ntohs((s)->port); \ 218 } while (0) 219 220 #ifdef _KERNEL 221 void pfsync_input(struct mbuf *, ...); 222 int pfsync_clear_states(u_int32_t); 223 int pfsync_pack_state(u_int8_t, struct pf_state *); 224 #define pfsync_insert_state(st) do { \ 225 if (st->rule.ptr->rule_flag & PFRULE_NOSYNC) \ 226 st->sync_flags |= PFSTATE_NOSYNC; \ 227 else if (!st->sync_flags) \ 228 pfsync_pack_state(PFSYNC_ACT_INS, (st));\ 229 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 230 } while (0) 231 #define pfsync_update_state(st) do { \ 232 if (!st->sync_flags) \ 233 pfsync_pack_state(PFSYNC_ACT_UPD, (st));\ 234 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 235 } while (0) 236 #define pfsync_delete_state(st) do { \ 237 if (!st->sync_flags) \ 238 pfsync_pack_state(PFSYNC_ACT_DEL, (st));\ 239 st->sync_flags &= ~PFSTATE_FROMSYNC; \ 240 } while (0) 241 #endif 242 243 #endif /* _NET_IF_PFSYNC_H_ */ 244