pf: Update packet filter to the version that comes with OpenBSD 4.1
[dragonfly.git] / sys / net / pf / if_pfsync.h
1 /*      $OpenBSD: if_pfsync.h,v 1.30 2006/10/31 14:49:01 henning 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
33 #define PFSYNC_ID_LEN   sizeof(u_int64_t)
34
35 struct pfsync_state_scrub {
36         u_int16_t       pfss_flags;
37         u_int8_t        pfss_ttl;       /* stashed TTL          */
38 #define PFSYNC_SCRUB_FLAG_VALID         0x01
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        pad[6];
59 } __packed;
60
61 struct pfsync_state {
62         u_int32_t        id[2];
63         char             ifname[IFNAMSIZ];
64         struct pfsync_state_host lan;
65         struct pfsync_state_host gwy;
66         struct pfsync_state_host ext;
67         struct pfsync_state_peer src;
68         struct pfsync_state_peer dst;
69         struct pf_addr   rt_addr;
70         u_int32_t        rule;
71         u_int32_t        anchor;
72         u_int32_t        nat_rule;
73         u_int32_t        creation;
74         u_int32_t        expire;
75         u_int32_t        packets[2][2];
76         u_int32_t        bytes[2][2];
77         u_int32_t        creatorid;
78         sa_family_t      af;
79         u_int8_t         proto;
80         u_int8_t         direction;
81         u_int8_t         log;
82         u_int8_t         allow_opts;
83         u_int8_t         timeout;
84         u_int8_t         sync_flags;
85         u_int8_t         updates;
86 } __packed;
87
88 #define PFSYNC_FLAG_COMPRESS    0x01
89 #define PFSYNC_FLAG_STALE       0x02
90
91 struct pfsync_tdb {
92         u_int32_t       spi;
93         union sockaddr_union dst;
94         u_int32_t       rpl;
95         u_int64_t       cur_bytes;
96         u_int8_t        sproto;
97         u_int8_t        updates;
98         u_int8_t        pad[2];
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 union sc_tdb_statep {
157         struct pfsync_tdb       *t;
158 };
159
160 extern int      pfsync_sync_ok;
161
162 struct pfsync_softc {
163         struct ifnet             sc_if;
164         struct ifnet            *sc_sync_ifp;
165
166         struct ip_moptions       sc_imo;
167         struct timeout           sc_tmo;
168         struct timeout           sc_tdb_tmo;
169         struct timeout           sc_bulk_tmo;
170         struct timeout           sc_bulkfail_tmo;
171         struct in_addr           sc_sync_peer;
172         struct in_addr           sc_sendaddr;
173         struct mbuf             *sc_mbuf;       /* current cumulative mbuf */
174         struct mbuf             *sc_mbuf_net;   /* current cumulative mbuf */
175         struct mbuf             *sc_mbuf_tdb;   /* dito for TDB updates */
176         union sc_statep          sc_statep;
177         union sc_statep          sc_statep_net;
178         union sc_tdb_statep      sc_statep_tdb;
179         u_int32_t                sc_ureq_received;
180         u_int32_t                sc_ureq_sent;
181         struct pf_state         *sc_bulk_send_next;
182         struct pf_state         *sc_bulk_terminator;
183         int                      sc_bulk_tries;
184         int                      sc_maxcount;   /* number of states in mtu */
185         int                      sc_maxupdates; /* number of updates/state */
186 };
187
188 extern struct pfsync_softc      *pfsyncif;
189 #endif
190
191
192 struct pfsync_header {
193         u_int8_t version;
194 #define PFSYNC_VERSION  3
195         u_int8_t af;
196         u_int8_t action;
197 #define PFSYNC_ACT_CLR          0       /* clear all states */
198 #define PFSYNC_ACT_INS          1       /* insert state */
199 #define PFSYNC_ACT_UPD          2       /* update state */
200 #define PFSYNC_ACT_DEL          3       /* delete state */
201 #define PFSYNC_ACT_UPD_C        4       /* "compressed" state update */
202 #define PFSYNC_ACT_DEL_C        5       /* "compressed" state delete */
203 #define PFSYNC_ACT_INS_F        6       /* insert fragment */
204 #define PFSYNC_ACT_DEL_F        7       /* delete fragments */
205 #define PFSYNC_ACT_UREQ         8       /* request "uncompressed" state */
206 #define PFSYNC_ACT_BUS          9       /* Bulk Update Status */
207 #define PFSYNC_ACT_TDB_UPD      10      /* TDB replay counter update */
208 #define PFSYNC_ACT_MAX          11
209         u_int8_t count;
210         u_int8_t pf_chksum[PF_MD5_DIGEST_LENGTH];
211 } __packed;
212
213 #define PFSYNC_BULKPACKETS      1       /* # of packets per timeout */
214 #define PFSYNC_MAX_BULKTRIES    12
215 #define PFSYNC_HDRLEN   sizeof(struct pfsync_header)
216 #define PFSYNC_ACTIONS \
217         "CLR ST", "INS ST", "UPD ST", "DEL ST", \
218         "UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \
219         "UPD REQ", "BLK UPD STAT", "TDB UPD"
220
221 #define PFSYNC_DFLTTL           255
222
223 struct pfsyncstats {
224         u_int64_t       pfsyncs_ipackets;       /* total input packets, IPv4 */
225         u_int64_t       pfsyncs_ipackets6;      /* total input packets, IPv6 */
226         u_int64_t       pfsyncs_badif;          /* not the right interface */
227         u_int64_t       pfsyncs_badttl;         /* TTL is not PFSYNC_DFLTTL */
228         u_int64_t       pfsyncs_hdrops;         /* packets shorter than hdr */
229         u_int64_t       pfsyncs_badver;         /* bad (incl unsupp) version */
230         u_int64_t       pfsyncs_badact;         /* bad action */
231         u_int64_t       pfsyncs_badlen;         /* data length does not match */
232         u_int64_t       pfsyncs_badauth;        /* bad authentication */
233         u_int64_t       pfsyncs_stale;          /* stale state */
234         u_int64_t       pfsyncs_badval;         /* bad values */
235         u_int64_t       pfsyncs_badstate;       /* insert/lookup failed */
236
237         u_int64_t       pfsyncs_opackets;       /* total output packets, IPv4 */
238         u_int64_t       pfsyncs_opackets6;      /* total output packets, IPv6 */
239         u_int64_t       pfsyncs_onomem;         /* no memory for an mbuf */
240         u_int64_t       pfsyncs_oerrors;        /* ip output error */
241 };
242
243 /*
244  * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
245  */
246 struct pfsyncreq {
247         char             pfsyncr_syncdev[IFNAMSIZ];
248         struct in_addr   pfsyncr_syncpeer;
249         int              pfsyncr_maxupdates;
250         int              pfsyncr_authlevel;
251 };
252
253
254 #define pf_state_peer_hton(s,d) do {            \
255         (d)->seqlo = htonl((s)->seqlo);         \
256         (d)->seqhi = htonl((s)->seqhi);         \
257         (d)->seqdiff = htonl((s)->seqdiff);     \
258         (d)->max_win = htons((s)->max_win);     \
259         (d)->mss = htons((s)->mss);             \
260         (d)->state = (s)->state;                \
261         (d)->wscale = (s)->wscale;              \
262         if ((s)->scrub) {                                               \
263                 (d)->scrub.pfss_flags =                                 \
264                     htons((s)->scrub->pfss_flags & PFSS_TIMESTAMP);     \
265                 (d)->scrub.pfss_ttl = (s)->scrub->pfss_ttl;             \
266                 (d)->scrub.pfss_ts_mod = htonl((s)->scrub->pfss_ts_mod);\
267                 (d)->scrub.scrub_flag = PFSYNC_SCRUB_FLAG_VALID;        \
268         }                                                               \
269 } while (0)
270
271 #define pf_state_peer_ntoh(s,d) do {            \
272         (d)->seqlo = ntohl((s)->seqlo);         \
273         (d)->seqhi = ntohl((s)->seqhi);         \
274         (d)->seqdiff = ntohl((s)->seqdiff);     \
275         (d)->max_win = ntohs((s)->max_win);     \
276         (d)->mss = ntohs((s)->mss);             \
277         (d)->state = (s)->state;                \
278         (d)->wscale = (s)->wscale;              \
279         if ((s)->scrub.scrub_flag == PFSYNC_SCRUB_FLAG_VALID &&         \
280             (d)->scrub != NULL) {                                       \
281                 (d)->scrub->pfss_flags =                                \
282                     ntohs((s)->scrub.pfss_flags) & PFSS_TIMESTAMP;      \
283                 (d)->scrub->pfss_ttl = (s)->scrub.pfss_ttl;             \
284                 (d)->scrub->pfss_ts_mod = ntohl((s)->scrub.pfss_ts_mod);\
285         }                                                               \
286 } while (0)
287
288 #define pf_state_host_hton(s,d) do {                            \
289         bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));       \
290         (d)->port = (s)->port;                                  \
291 } while (0)
292
293 #define pf_state_host_ntoh(s,d) do {                            \
294         bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));       \
295         (d)->port = (s)->port;                                  \
296 } while (0)
297
298 #define pf_state_counter_hton(s,d) do {                         \
299         d[0] = htonl((s>>32)&0xffffffff);                       \
300         d[1] = htonl(s&0xffffffff);                             \
301 } while (0)
302
303 #define pf_state_counter_ntoh(s,d) do {                         \
304         d = ntohl(s[0]);                                        \
305         d = d<<32;                                              \
306         d += ntohl(s[1]);                                       \
307 } while (0)
308
309 #ifdef _KERNEL
310 void pfsync_input(struct mbuf *, ...);
311 int pfsync_clear_states(u_int32_t, char *);
312 int pfsync_pack_state(u_int8_t, struct pf_state *, int);
313 #define pfsync_insert_state(st) do {                            \
314         if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) ||        \
315             (st->proto == IPPROTO_PFSYNC))                      \
316                 st->sync_flags |= PFSTATE_NOSYNC;               \
317         else if (!st->sync_flags)                               \
318                 pfsync_pack_state(PFSYNC_ACT_INS, (st),         \
319                     PFSYNC_FLAG_COMPRESS);                      \
320         st->sync_flags &= ~PFSTATE_FROMSYNC;                    \
321 } while (0)
322 #define pfsync_update_state(st) do {                            \
323         if (!st->sync_flags)                                    \
324                 pfsync_pack_state(PFSYNC_ACT_UPD, (st),         \
325                     PFSYNC_FLAG_COMPRESS);                      \
326         st->sync_flags &= ~PFSTATE_FROMSYNC;                    \
327 } while (0)
328 #define pfsync_delete_state(st) do {                            \
329         if (!st->sync_flags)                                    \
330                 pfsync_pack_state(PFSYNC_ACT_DEL, (st),         \
331                     PFSYNC_FLAG_COMPRESS);                      \
332 } while (0)
333 int pfsync_update_tdb(struct tdb *, int);
334 #endif
335
336 #endif /* _NET_IF_PFSYNC_H_ */