1/*	$NetBSD: if_pfsync.h,v 1.4 2018/09/14 05:09:51 maxv Exp $	*/
2/*	$OpenBSD: if_pfsync.h,v 1.31 2007/05/31 04:11:42 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#define  INADDR_PFSYNC_GROUP     __IPADDR(0xe00000f0)    /* 224.0.0.240 */
34
35#define PFSYNC_ID_LEN	sizeof(u_int64_t)
36
37struct pfsync_tdb {
38	u_int32_t	spi;
39	union sockaddr_union dst;
40	u_int32_t	rpl;
41	u_int64_t	cur_bytes;
42	u_int8_t	sproto;
43	u_int8_t	updates;
44	u_int8_t	pad[2];
45} __packed;
46
47struct pfsync_state_upd {
48	u_int32_t		id[2];
49	struct pfsync_state_peer	src;
50	struct pfsync_state_peer	dst;
51	u_int32_t		creatorid;
52	u_int32_t		expire;
53	u_int8_t		timeout;
54	u_int8_t		updates;
55	u_int8_t		pad[6];
56} __packed;
57
58struct pfsync_state_del {
59	u_int32_t		id[2];
60	u_int32_t		creatorid;
61	struct {
62		u_int8_t	state;
63	} src;
64	struct {
65		u_int8_t	state;
66	} dst;
67	u_int8_t		pad[2];
68} __packed;
69
70struct pfsync_state_upd_req {
71	u_int32_t		id[2];
72	u_int32_t		creatorid;
73	u_int32_t		pad;
74} __packed;
75
76struct pfsync_state_clr {
77	char			ifname[IFNAMSIZ];
78	u_int32_t		creatorid;
79	u_int32_t		pad;
80} __packed;
81
82struct pfsync_state_bus {
83	u_int32_t		creatorid;
84	u_int32_t		endtime;
85	u_int8_t		status;
86#define PFSYNC_BUS_START	1
87#define PFSYNC_BUS_END		2
88	u_int8_t		pad[7];
89} __packed;
90
91#ifdef _KERNEL
92
93union sc_statep {
94	struct pfsync_state	*s;
95	struct pfsync_state_upd	*u;
96	struct pfsync_state_del	*d;
97	struct pfsync_state_clr	*c;
98	struct pfsync_state_bus	*b;
99	struct pfsync_state_upd_req	*r;
100};
101
102union sc_tdb_statep {
103	struct pfsync_tdb	*t;
104};
105
106extern int	pfsync_sync_ok;
107
108struct pfsync_softc {
109	struct ifnet		 sc_if;
110	struct ifnet		*sc_sync_ifp;
111
112	struct ip_moptions	 sc_imo;
113	struct callout		 sc_tmo;
114	struct callout		 sc_tdb_tmo;
115	struct callout		 sc_bulk_tmo;
116	struct callout		 sc_bulkfail_tmo;
117	struct in_addr		 sc_sync_peer;
118	struct in_addr		 sc_sendaddr;
119	struct mbuf		*sc_mbuf;	/* current cumulative mbuf */
120	struct mbuf		*sc_mbuf_net;	/* current cumulative mbuf */
121    	struct mbuf		*sc_mbuf_tdb;	/* dito for TDB updates */
122	union sc_statep		 sc_statep;
123	union sc_statep		 sc_statep_net;
124	union sc_tdb_statep	 sc_statep_tdb;
125	u_int32_t		 sc_ureq_received;
126	u_int32_t		 sc_ureq_sent;
127	struct pf_state		*sc_bulk_send_next;
128	struct pf_state		*sc_bulk_terminator;
129	int			 sc_bulk_tries;
130	int			 sc_maxcount;	/* number of states in mtu */
131	int			 sc_maxupdates;	/* number of updates/state */
132};
133
134extern struct pfsync_softc	*pfsyncif;
135#endif
136
137
138struct pfsync_header {
139	u_int8_t version;
140#define	PFSYNC_VERSION	3
141	u_int8_t af;
142	u_int8_t action;
143#define	PFSYNC_ACT_CLR		0	/* clear all states */
144#define	PFSYNC_ACT_INS		1	/* insert state */
145#define	PFSYNC_ACT_UPD		2	/* update state */
146#define	PFSYNC_ACT_DEL		3	/* delete state */
147#define	PFSYNC_ACT_UPD_C	4	/* "compressed" state update */
148#define	PFSYNC_ACT_DEL_C	5	/* "compressed" state delete */
149#define	PFSYNC_ACT_INS_F	6	/* insert fragment */
150#define	PFSYNC_ACT_DEL_F	7	/* delete fragments */
151#define	PFSYNC_ACT_UREQ		8	/* request "uncompressed" state */
152#define PFSYNC_ACT_BUS		9	/* Bulk Update Status */
153#define PFSYNC_ACT_TDB_UPD	10	/* TDB replay counter update */
154#define	PFSYNC_ACT_MAX		11
155	u_int8_t count;
156	u_int8_t pf_chksum[PF_MD5_DIGEST_LENGTH];
157} __packed;
158
159#define PFSYNC_BULKPACKETS	1	/* # of packets per timeout */
160#define PFSYNC_MAX_BULKTRIES	12
161#define PFSYNC_HDRLEN	sizeof(struct pfsync_header)
162#define	PFSYNC_ACTIONS \
163	"CLR ST", "INS ST", "UPD ST", "DEL ST", \
164	"UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \
165	"UPD REQ", "BLK UPD STAT", "TDB UPD"
166
167#define PFSYNC_DFLTTL		255
168
169#define PFSYNC_STAT_IPACKETS	0	/* total input packets, IPv4 */
170#define PFSYNC_STAT_IPACKETS6	1	/* total input packets, IPv6 */
171#define PFSYNC_STAT_BADIF		2	/* not the right interface */
172#define PFSYNC_STAT_BADTTL		3	/* TTL is not PFSYNC_DFLTTL */
173#define PFSYNC_STAT_HDROPS		4	/* packets shorter than hdr */
174#define PFSYNC_STAT_BADVER		5	/* bad (incl unsupp) version */
175#define PFSYNC_STAT_BADACT		6	/* bad action */
176#define PFSYNC_STAT_BADLEN		7	/* data length does not match */
177#define PFSYNC_STAT_BADAUTH		8	/* bad authentication */
178#define PFSYNC_STAT_STALE		9	/* stale state */
179#define PFSYNC_STAT_BADVAL		10	/* bad values */
180#define PFSYNC_STAT_BADSTATE	11	/* insert/lookup failed */
181#define PFSYNC_STAT_OPACKETS	12	/* total output packets, IPv4 */
182#define PFSYNC_STAT_OPACKETS6	13	/* total output packets, IPv6 */
183#define PFSYNC_STAT_ONOMEM		14	/* no memory for an mbuf */
184#define PFSYNC_STAT_OERRORS		15	/* ip output error */
185
186#define PFSYNC_NSTATS			16
187
188/*
189 * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
190 */
191struct pfsyncreq {
192	char		 pfsyncr_syncdev[IFNAMSIZ];
193	struct in_addr	 pfsyncr_syncpeer;
194	int		 pfsyncr_maxupdates;
195	int		 pfsyncr_authlevel;
196};
197
198
199/* for copies to/from network */
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	if ((s)->scrub) {						\
209		(d)->scrub.pfss_flags = 				\
210		    htons((s)->scrub->pfss_flags & PFSS_TIMESTAMP);	\
211		(d)->scrub.pfss_ttl = (s)->scrub->pfss_ttl;		\
212		(d)->scrub.pfss_ts_mod = htonl((s)->scrub->pfss_ts_mod);\
213		(d)->scrub.scrub_flag = PFSYNC_SCRUB_FLAG_VALID;	\
214	}								\
215} while (0)
216
217#define pf_state_peer_ntoh(s,d) do {		\
218	(d)->seqlo = ntohl((s)->seqlo);		\
219	(d)->seqhi = ntohl((s)->seqhi);		\
220	(d)->seqdiff = ntohl((s)->seqdiff);	\
221	(d)->max_win = ntohs((s)->max_win);	\
222	(d)->mss = ntohs((s)->mss);		\
223	(d)->state = (s)->state;		\
224	(d)->wscale = (s)->wscale;		\
225	if ((s)->scrub.scrub_flag == PFSYNC_SCRUB_FLAG_VALID && 	\
226	    (d)->scrub != NULL) {					\
227		(d)->scrub->pfss_flags =				\
228		    ntohs((s)->scrub.pfss_flags) & PFSS_TIMESTAMP;	\
229		(d)->scrub->pfss_ttl = (s)->scrub.pfss_ttl;		\
230		(d)->scrub->pfss_ts_mod = ntohl((s)->scrub.pfss_ts_mod);\
231	}								\
232} while (0)
233
234#define pf_state_host_hton(s,d) do {				\
235	memcpy(&(d)->addr, &(s)->addr, sizeof((d)->addr));	\
236	(d)->port = (s)->port;					\
237} while (0)
238
239#define pf_state_host_ntoh(s,d) do {				\
240	memcpy(&(d)->addr, &(s)->addr, sizeof((d)->addr));	\
241	(d)->port = (s)->port;					\
242} while (0)
243
244#define pf_state_counter_hton(s,d) do {				\
245	d[0] = htonl((s>>32)&0xffffffff);			\
246	d[1] = htonl(s&0xffffffff);				\
247} while (0)
248
249#define pf_state_counter_ntoh(s,d) do {				\
250	d = ntohl(s[0]);					\
251	d = d<<32;						\
252	d += ntohl(s[1]);					\
253} while (0)
254
255#ifdef _KERNEL
256void pfsync_input(struct mbuf *, int, int);
257int pfsync_clear_states(u_int32_t, char *);
258int pfsync_pack_state(u_int8_t, struct pf_state *, int);
259#define pfsync_insert_state(st)	do {				\
260	if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) ||	\
261	    (st->state_key->proto == IPPROTO_PFSYNC))			\
262		st->sync_flags |= PFSTATE_NOSYNC;		\
263	else if (!st->sync_flags)				\
264		pfsync_pack_state(PFSYNC_ACT_INS, (st), 	\
265		    PFSYNC_FLAG_COMPRESS);			\
266	st->sync_flags &= ~PFSTATE_FROMSYNC;			\
267} while (0)
268#define pfsync_update_state(st) do {				\
269	if (!st->sync_flags)					\
270		pfsync_pack_state(PFSYNC_ACT_UPD, (st), 	\
271		    PFSYNC_FLAG_COMPRESS);			\
272	st->sync_flags &= ~PFSTATE_FROMSYNC;			\
273} while (0)
274#define pfsync_delete_state(st) do {				\
275	if (!st->sync_flags)					\
276		pfsync_pack_state(PFSYNC_ACT_DEL, (st),		\
277		    PFSYNC_FLAG_COMPRESS);			\
278} while (0)
279#ifdef NOTYET
280int pfsync_update_tdb(struct tdb *, int);
281#endif /* NOTYET */
282#endif
283
284#endif /* _NET_IF_PFSYNC_H_ */
285