xref: /openbsd/sys/net/if_pfsync.h (revision 94cb5eb8)
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