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