Merge commit 'origin/vendor/PAM_PASSWDQC'
[dragonfly.git] / sys / net / pf / if_pfsync.h
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_ */