Home | History | Annotate | Line # | Download | only in net
if_pfsync.h revision 1.1
      1 /*	$OpenBSD: if_pfsync.h,v 1.13 2004/03/22 04:54:17 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 
     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 	u_int8_t	scrub_flag;
     39 	u_int32_t	pfss_ts_mod;	/* timestamp modulation	*/
     40 } __packed;
     41 
     42 struct pfsync_state_host {
     43 	struct pf_addr	addr;
     44 	u_int16_t	port;
     45 	u_int16_t	pad[3];
     46 } __packed;
     47 
     48 struct pfsync_state_peer {
     49 	struct pfsync_state_scrub scrub;	/* state is scrubbed	*/
     50 	u_int32_t	seqlo;		/* Max sequence number sent	*/
     51 	u_int32_t	seqhi;		/* Max the other end ACKd + win	*/
     52 	u_int32_t	seqdiff;	/* Sequence number modulator	*/
     53 	u_int16_t	max_win;	/* largest window (pre scaling)	*/
     54 	u_int16_t	mss;		/* Maximum segment size option	*/
     55 	u_int8_t	state;		/* active state level		*/
     56 	u_int8_t	wscale;		/* window scaling factor	*/
     57 	u_int8_t	scrub_flag;
     58 	u_int8_t	pad[5];
     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];
     76 	u_int32_t	 bytes[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 struct pfsync_state_upd {
     89 	u_int32_t		id[2];
     90 	struct pfsync_state_peer	src;
     91 	struct pfsync_state_peer	dst;
     92 	u_int32_t		creatorid;
     93 	u_int32_t		expire;
     94 	u_int8_t		timeout;
     95 	u_int8_t		updates;
     96 	u_int8_t		pad[6];
     97 } __packed;
     98 
     99 struct pfsync_state_del {
    100 	u_int32_t		id[2];
    101 	u_int32_t		creatorid;
    102 	struct {
    103 		u_int8_t	state;
    104 	} src;
    105 	struct {
    106 		u_int8_t	state;
    107 	} dst;
    108 	u_int8_t		pad[2];
    109 } __packed;
    110 
    111 struct pfsync_state_upd_req {
    112 	u_int32_t		id[2];
    113 	u_int32_t		creatorid;
    114 	u_int32_t		pad;
    115 } __packed;
    116 
    117 struct pfsync_state_clr {
    118 	char			ifname[IFNAMSIZ];
    119 	u_int32_t		creatorid;
    120 	u_int32_t		pad;
    121 } __packed;
    122 
    123 struct pfsync_state_bus {
    124 	u_int32_t		creatorid;
    125 	u_int32_t		endtime;
    126 	u_int8_t		status;
    127 #define PFSYNC_BUS_START	1
    128 #define PFSYNC_BUS_END		2
    129 	u_int8_t		pad[7];
    130 } __packed;
    131 
    132 #ifdef _KERNEL
    133 
    134 union sc_statep {
    135 	struct pfsync_state	*s;
    136 	struct pfsync_state_upd	*u;
    137 	struct pfsync_state_del	*d;
    138 	struct pfsync_state_clr	*c;
    139 	struct pfsync_state_bus	*b;
    140 	struct pfsync_state_upd_req	*r;
    141 };
    142 
    143 extern int	pfsync_sync_ok;
    144 
    145 struct pfsync_softc {
    146 	struct ifnet		 sc_if;
    147 	struct ifnet		*sc_sync_ifp;
    148 
    149 	struct ip_moptions	 sc_imo;
    150 	struct timeout		 sc_tmo;
    151 	struct timeout		 sc_bulk_tmo;
    152 	struct timeout		 sc_bulkfail_tmo;
    153 	struct in_addr		 sc_sendaddr;
    154 	struct mbuf		*sc_mbuf;	/* current cummulative mbuf */
    155 	struct mbuf		*sc_mbuf_net;	/* current cummulative mbuf */
    156 	union sc_statep		 sc_statep;
    157 	union sc_statep		 sc_statep_net;
    158 	u_int32_t		 sc_ureq_received;
    159 	u_int32_t		 sc_ureq_sent;
    160 	int			 sc_bulk_tries;
    161 	int			 sc_maxcount;	/* number of states in mtu */
    162 	int			 sc_maxupdates;	/* number of updates/state */
    163 };
    164 #endif
    165 
    166 
    167 struct pfsync_header {
    168 	u_int8_t version;
    169 #define	PFSYNC_VERSION	2
    170 	u_int8_t af;
    171 	u_int8_t action;
    172 #define	PFSYNC_ACT_CLR		0	/* clear all states */
    173 #define	PFSYNC_ACT_INS		1	/* insert state */
    174 #define	PFSYNC_ACT_UPD		2	/* update state */
    175 #define	PFSYNC_ACT_DEL		3	/* delete state */
    176 #define	PFSYNC_ACT_UPD_C	4	/* "compressed" state update */
    177 #define	PFSYNC_ACT_DEL_C	5	/* "compressed" state delete */
    178 #define	PFSYNC_ACT_INS_F	6	/* insert fragment */
    179 #define	PFSYNC_ACT_DEL_F	7	/* delete fragments */
    180 #define	PFSYNC_ACT_UREQ		8	/* request "uncompressed" state */
    181 #define PFSYNC_ACT_BUS		9	/* Bulk Update Status */
    182 #define	PFSYNC_ACT_MAX		10
    183 	u_int8_t count;
    184 } __packed;
    185 
    186 #define PFSYNC_BULKPACKETS	1	/* # of packets per timeout */
    187 #define PFSYNC_MAX_BULKTRIES	12
    188 #define PFSYNC_HDRLEN	sizeof(struct pfsync_header)
    189 #define	PFSYNC_ACTIONS \
    190 	"CLR ST", "INS ST", "UPD ST", "DEL ST", \
    191 	"UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \
    192 	"UPD REQ", "BLK UPD STAT"
    193 
    194 #define PFSYNC_DFLTTL		255
    195 
    196 struct pfsyncstats {
    197 	u_long	pfsyncs_ipackets;	/* total input packets, IPv4 */
    198 	u_long	pfsyncs_ipackets6;	/* total input packets, IPv6 */
    199 	u_long	pfsyncs_badif;		/* not the right interface */
    200 	u_long	pfsyncs_badttl;		/* TTL is not PFSYNC_DFLTTL */
    201 	u_long	pfsyncs_hdrops;		/* packets shorter than header */
    202 	u_long	pfsyncs_badver;		/* bad (incl unsupp) version */
    203 	u_long	pfsyncs_badact;		/* bad action */
    204 	u_long	pfsyncs_badlen;		/* data length does not match */
    205 	u_long	pfsyncs_badauth;	/* bad authentication */
    206 	u_long	pfsyncs_badstate;	/* insert/lookup failed */
    207 
    208 	u_long	pfsyncs_opackets;	/* total output packets, IPv4 */
    209 	u_long	pfsyncs_opackets6;	/* total output packets, IPv6 */
    210 	u_long	pfsyncs_onomem;		/* no memory for an mbuf for a send */
    211 	u_long	pfsyncs_oerrors;	/* ip output error */
    212 };
    213 
    214 /*
    215  * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
    216  */
    217 struct pfsyncreq {
    218 	char	pfsyncr_syncif[IFNAMSIZ];
    219 	int	pfsyncr_maxupdates;
    220 	int	pfsyncr_authlevel;
    221 };
    222 #define SIOCSETPFSYNC	_IOW('i', 247, struct ifreq)
    223 #define SIOCGETPFSYNC	_IOWR('i', 248, struct ifreq)
    224 
    225 
    226 #define pf_state_peer_hton(s,d) do {		\
    227 	(d)->seqlo = htonl((s)->seqlo);		\
    228 	(d)->seqhi = htonl((s)->seqhi);		\
    229 	(d)->seqdiff = htonl((s)->seqdiff);	\
    230 	(d)->max_win = htons((s)->max_win);	\
    231 	(d)->mss = htons((s)->mss);		\
    232 	(d)->state = (s)->state;		\
    233 	(d)->wscale = (s)->wscale;		\
    234 } while (0)
    235 
    236 #define pf_state_peer_ntoh(s,d) do {		\
    237 	(d)->seqlo = ntohl((s)->seqlo);		\
    238 	(d)->seqhi = ntohl((s)->seqhi);		\
    239 	(d)->seqdiff = ntohl((s)->seqdiff);	\
    240 	(d)->max_win = ntohs((s)->max_win);	\
    241 	(d)->mss = ntohs((s)->mss);		\
    242 	(d)->state = (s)->state;		\
    243 	(d)->wscale = (s)->wscale;		\
    244 } while (0)
    245 
    246 #define pf_state_host_hton(s,d) do {				\
    247 	bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));	\
    248 	(d)->port = (s)->port;					\
    249 } while (0)
    250 
    251 #define pf_state_host_ntoh(s,d) do {				\
    252 	bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));	\
    253 	(d)->port = (s)->port;					\
    254 } while (0)
    255 
    256 #ifdef _KERNEL
    257 void pfsync_input(struct mbuf *, ...);
    258 int pfsync_clear_states(u_int32_t, char *);
    259 int pfsync_pack_state(u_int8_t, struct pf_state *, int);
    260 #define pfsync_insert_state(st)	do {				\
    261 	if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) ||	\
    262 	    (st->proto == IPPROTO_PFSYNC))			\
    263 		st->sync_flags |= PFSTATE_NOSYNC;		\
    264 	else if (!st->sync_flags)				\
    265 		pfsync_pack_state(PFSYNC_ACT_INS, (st), 1);	\
    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), 1);	\
    271 	st->sync_flags &= ~PFSTATE_FROMSYNC;			\
    272 } while (0)
    273 #define pfsync_delete_state(st) do {				\
    274 	if (!st->sync_flags)					\
    275 		pfsync_pack_state(PFSYNC_ACT_DEL, (st), 1);	\
    276 	st->sync_flags &= ~PFSTATE_FROMSYNC;			\
    277 } while (0)
    278 #endif
    279 
    280 #endif /* _NET_IF_PFSYNC_H_ */
    281