xref: /openbsd/sys/net/pipex_local.h (revision 528abb89)
1 /*	$OpenBSD: pipex_local.h,v 1.52 2024/05/29 00:48:15 jsg Exp $	*/
2 
3 /*
4  * Copyright (c) 2009 Internet Initiative Japan Inc.
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 AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/mutex.h>
30 #include <sys/refcnt.h>
31 
32 extern struct mutex pipex_list_mtx;
33 
34 #define	PIPEX_PPTP	1
35 #define	PIPEX_L2TP	1
36 #define	PIPEX_PPPOE	1
37 #define	PIPEX_MPPE	1
38 
39 #define PIPEX_REWIND_LIMIT		64
40 
41 #define PIPEX_ENABLED			0x0001
42 
43 /* compile time option constants */
44 #ifndef	PIPEX_MAX_SESSION
45 #define PIPEX_MAX_SESSION		512
46 #endif
47 #define PIPEX_HASH_DIV			8
48 #define PIPEX_HASH_SIZE			(PIPEX_MAX_SESSION/PIPEX_HASH_DIV)
49 #define PIPEX_HASH_MASK			(PIPEX_HASH_SIZE-1)
50 #define PIPEX_CLOSE_TIMEOUT		30
51 #define	PIPEX_PPPMINLEN			5
52 	/* minimum PPP header length is 1 and minimum ppp payload length is 4 */
53 
54 #define PIPEX_MPPE_NOLDKEY		64 /* should be power of two */
55 #define PIPEX_MPPE_OLDKEYMASK		(PIPEX_MPPE_NOLDKEY - 1)
56 
57 /*
58  * Locks used to protect struct members:
59  *      A       atomic operation
60  *      I       immutable after creation
61  *      L       pipex_list_mtx
62  *      s       this pipex_session' `pxs_mtx'
63  *      m       this pipex_mppe' `pxm_mtx'
64  */
65 
66 #ifdef PIPEX_MPPE
67 /* mppe rc4 key */
68 struct pipex_mppe {
69 	struct mutex pxm_mtx;
70 	u_int flags;				/* [m] flags, see below */
71 #define PIPEX_MPPE_STATELESS	0x01		/* [I] key change mode */
72 #define PIPEX_MPPE_RESETREQ	0x02		/* [m] */
73 
74 	int16_t	keylenbits;			/* [I] key length */
75 	int16_t keylen;				/* [I] */
76 	uint16_t coher_cnt;			/* [m] coherency counter */
77 	struct  rc4_ctx rc4ctx;			/* [m] */
78 	u_char master_key[PIPEX_MPPE_KEYLEN];	/* [m] master key of MPPE */
79 	u_char session_key[PIPEX_MPPE_KEYLEN];	/* [m] session key of MPPE */
80 	u_char (*old_session_keys)[PIPEX_MPPE_KEYLEN];
81 						/* [m] old session keys */
82 };
83 #endif /* PIPEX_MPPE */
84 
85 #ifdef PIPEX_PPPOE
86 struct pipex_pppoe_session {
87 	u_int	 over_ifidx;                    /* [I] ether interface */
88 };
89 #endif /* PIPEX_PPPOE */
90 
91 #ifdef PIPEX_PPTP
92 struct pipex_pptp_session {
93 	/* sequence number gap between pipex and userland */
94 	int32_t	snd_gap;		/* [s] gap of our sequence */
95 	int32_t rcv_gap;		/* [s] gap of peer's sequence */
96 	int32_t ul_snd_una;		/* [s] userland send acked seq */
97 
98 	uint32_t snd_nxt;		/* [s] send next */
99 	uint32_t rcv_nxt;		/* [s] receive next */
100 	uint32_t snd_una;		/* [s] send acked sequence */
101 	uint32_t rcv_acked;		/* [s] recv acked sequence */
102 
103 	int winsz;			/* [I] windows size */
104 	int maxwinsz;			/* [I] max windows size */
105 	int peer_maxwinsz;		/* [I] peer's max windows size */
106 };
107 #endif /* PIPEX_PPTP */
108 
109 #ifdef PIPEX_L2TP
110 /*
111  * L2TP Packet headers
112  *
113  *   +----+---+----+---+----+--------+
114  *   |IPv4|UDP|L2TP|PPP|IPv4|Data....|
115  *   +----+---+----+---+----+--------+
116  *
117  * Session Data
118  *
119  *   IPv4    IP_SRC         <-- required for encap.
120  *           IP_DST         <-- required for encap.
121  *
122  *   UDP     SPort          <-- required for encap.
123  *           DPort          <-- required for encap.
124  *
125  *   L2TP    FLAGS          <-- only handle TYPE=0 (data)
126  *           Tunnel ID      <-- ID per tunnel(NOT a key: differed from RFC)
127  *           Session ID     <-- ID per PPP session(KEY to look up session)
128  *           Ns(SEND SEQ)   <-- sequence number of packet to send(opt.)
129  *           Nr(RECV SEQ)   <-- sequence number of packet to recv(opt.)
130  *
131  * - Recv Session lookup key is (Tunnnel ID, Session ID) in RFC.
132  *   - BUT (Session ID) in PIPEX. SESSION ID MUST BE UNIQ.
133  *
134  * - We must update (Ns, Nr) of data channel. and we must adjust (Ns, Nr)
135  *   in packets from/to userland.
136  */
137 struct pipex_l2tp_session {
138 	/* KEYS for session lookup (host byte order) */
139 	uint16_t tunnel_id;		/* [I] our tunnel-id */
140 	uint16_t peer_tunnel_id;	/* [I] peer's tunnel-id */
141 
142 	uint32_t option_flags;		/* [I] protocol options */
143 
144 	int16_t ns_gap;		/* [s] gap between userland and pipex */
145 	int16_t nr_gap;		/* [s] gap between userland and pipex */
146 	uint16_t ul_ns_una;	/* [s] unacked sequence number (userland) */
147 
148 	uint16_t ns_nxt;	/* [s] next sequence number to send */
149 	uint16_t ns_una;	/* [s] unacked sequence number to send */
150 
151 	uint16_t nr_nxt;	/* [s] next sequence number to recv */
152 	uint16_t nr_acked;	/* [s] acked sequence number to recv */
153 	uint32_t ipsecflowinfo;	/* [s] IPsec SA flow id for NAT-T */
154 };
155 #endif /* PIPEX_L2TP */
156 
157 struct cpumem;
158 
159 /* special iterator session */
160 struct pipex_session_iterator {
161 	/* Fields below should be in sync with pipex_session structure */
162 	struct radix_node	ps4_rn[2];
163 	u_int		flags;			/* [I] flags, see below */
164 	LIST_ENTRY(pipex_session) session_list;	/* [L] all session chain */
165 };
166 
167 /* pppac ip-extension session table */
168 struct pipex_session {
169 	struct radix_node	ps4_rn[2];
170 					/* [L] tree glue, and other values */
171 	u_int		flags;		/* [I] flags, see below */
172 #define PIPEX_SFLAGS_MULTICAST		0x01 /* virtual entry for multicast */
173 #define PIPEX_SFLAGS_PPPX		0x02 /* interface is
174 						point2point(pppx) */
175 #define PIPEX_SFLAGS_ITERATOR		0x04 /* iterator session */
176 
177 	LIST_ENTRY(pipex_session) session_list;	/* [L] all session chain */
178 	LIST_ENTRY(pipex_session) state_list;	/* [L] state list chain */
179 	LIST_ENTRY(pipex_session) id_chain;	/* [L] id hash chain */
180 	LIST_ENTRY(pipex_session) peer_addr_chain;
181 					/* [L] peer's address hash chain */
182 	struct refcnt pxs_refcnt;
183 	struct mutex pxs_mtx;
184 
185 	u_int		state;		/* [L] pipex session state */
186 #define PIPEX_STATE_INITIAL		0x0000
187 #define PIPEX_STATE_OPENED		0x0001
188 #define PIPEX_STATE_CLOSE_WAIT		0x0002
189 #define PIPEX_STATE_CLOSE_WAIT2		0x0003
190 #define PIPEX_STATE_CLOSED		0x0004
191 
192 	uint32_t	idle_time;	/* [L] idle time in seconds */
193 
194 	uint16_t	protocol;		/* [I] tunnel protocol (PK) */
195 	uint16_t	session_id;		/* [I] session-id (PK) */
196 	uint16_t	peer_session_id;	/* [I] peer's session-id */
197 	uint16_t	peer_mru;		/* [I] peer's MRU */
198 	uint32_t	timeout_sec;		/* [I] idle timeout */
199 	int		ppp_id;			/* [I] PPP id */
200 
201 	struct sockaddr_in ip_address;   /* [I] remote address (AK) */
202 	struct sockaddr_in ip_netmask;   /* [I] remote address mask (AK) */
203 	struct sockaddr_in6 ip6_address; /* [I] remote IPv6 address */
204 	int		ip6_prefixlen;   /* [I] remote IPv6 prefixlen */
205 
206 	u_int		ifindex;		/* [A] interface index */
207 	void		*ownersc;		/* [I] owner context */
208 
209 	uint32_t	ppp_flags;		/* [I] configure flags */
210 #ifdef PIPEX_MPPE
211 	int ccp_id;				/* [s] CCP packet id */
212 	struct pipex_mppe
213 	    mppe_recv,				/* MPPE context for incoming */
214 	    mppe_send;				/* MPPE context for outgoing */
215 #endif /*PIPEXMPPE */
216 
217 	struct cpumem	*stat_counters;
218 
219 	union {
220 #ifdef PIPEX_PPPOE
221 		struct pipex_pppoe_session pppoe;	/* context for PPPoE */
222 #endif /* PIPEX_PPPOE */
223 #ifdef PIPEX_PPTP
224 		struct pipex_pptp_session pptp;		/* context for PPTP */
225 #endif /* PIPEX_PPTP */
226 #ifdef PIPEX_L2TP
227 		struct pipex_l2tp_session l2tp;
228 #endif
229 		char _proto_unknown[0];
230 	} proto;
231 	union {
232 		struct sockaddr		sa;
233 		struct sockaddr_in	sin4;
234 		struct sockaddr_in6	sin6;
235 		struct sockaddr_dl	sdl;
236 	} peer, local;					/* [I] */
237 };
238 
239 enum pipex_counters {
240 	pxc_ipackets,	/* packets received from tunnel */
241 	pxc_ierrors,	/* error packets received from tunnel */
242 	pxc_ibytes,	/* number of received bytes from tunnel */
243 	pxc_opackets,	/* packets sent to tunnel */
244 	pxc_oerrors,	/* error packets on sending to tunnel */
245 	pxc_obytes,	/* number of sent bytes to tunnel */
246 	pxc_ncounters
247 };
248 
249 /* gre header */
250 struct pipex_gre_header {
251 	uint16_t flags;				/* flags and version*/
252 #define PIPEX_GRE_KFLAG			0x2000	/* keys present */
253 #define PIPEX_GRE_SFLAG			0x1000	/* seq present */
254 #define PIPEX_GRE_AFLAG			0x0080	/* ack present */
255 #define PIPEX_GRE_VER			0x0001	/* gre version code */
256 #define PIPEX_GRE_VERMASK		0x0007	/* gre version mask */
257 #define PIPEX_GRE_UNUSEDFLAGS		0xcf78	/* unused at pptp. set 0 in rfc2637 */
258 
259 	uint16_t type;
260 #define PIPEX_GRE_PROTO_PPP		0x880b	/* gre/ppp */
261 
262 	uint16_t len;			/* length not include gre header */
263 	uint16_t call_id;			/* call_id */
264 } __packed;
265 
266 /* pppoe header */
267 struct pipex_pppoe_header {
268 	uint8_t vertype;			/* version and type */
269 #define PIPEX_PPPOE_VERTYPE		0x11	/* version and type code */
270 
271 	uint8_t code;				/* code */
272 #define PIPEX_PPPOE_CODE_SESSION	0x00	/* code session */
273 
274 	uint16_t session_id;			/* session id */
275 	uint16_t length;			/* length */
276 } __packed;
277 
278 /* l2tp header */
279 struct pipex_l2tp_header {
280 	uint16_t flagsver;
281 #define PIPEX_L2TP_FLAG_MASK		0xfff0
282 #define PIPEX_L2TP_FLAG_TYPE		0x8000
283 #define PIPEX_L2TP_FLAG_LENGTH		0x4000
284 #define PIPEX_L2TP_FLAG_SEQUENCE	0x0800
285 #define PIPEX_L2TP_FLAG_OFFSET		0x0200
286 #define PIPEX_L2TP_FLAG_PRIORITY	0x0100
287 #define PIPEX_L2TP_VER_MASK		0x000f
288 #define PIPEX_L2TP_VER			2
289 	uint16_t length; /* optional */
290 	uint16_t tunnel_id;
291 	uint16_t session_id;
292 	/* can be followed by option header */
293 } __packed;
294 
295 /* l2tp option header */
296 struct pipex_l2tp_seq_header {
297 	uint16_t ns;
298 	uint16_t nr;
299 } __packed;
300 
301 struct pipex_l2tp_offset_header {
302 	uint16_t offset_size;
303 	/* uint8_t offset_pad[] */
304 } __packed;
305 
306 #ifdef PIPEX_DEBUG
307 #define PIPEX_DBG(a) if (pipex_debug & 1) pipex_session_log a
308 /* #define PIPEX_MPPE_DBG(a) if (pipex_debug & 1) pipex_session_log a */
309 #define PIPEX_MPPE_DBG(a)
310 #else
311 #define PIPEX_DBG(a)
312 #define PIPEX_MPPE_DBG(a)
313 #endif /* PIPEX_DEBUG */
314 
315 LIST_HEAD(pipex_hash_head, pipex_session);
316 
317 extern struct pipex_hash_head	pipex_session_list;
318 extern struct pipex_hash_head	pipex_close_wait_list;
319 extern struct pipex_hash_head	pipex_peer_addr_hashtable[];
320 extern struct pipex_hash_head	pipex_id_hashtable[];
321 extern struct pool		pipex_session_pool;
322 
323 
324 #define PIPEX_ID_HASHTABLE(key)						\
325 	(&pipex_id_hashtable[(key) & PIPEX_HASH_MASK])
326 #define PIPEX_PEER_ADDR_HASHTABLE(key)					\
327 	(&pipex_peer_addr_hashtable[(key) & PIPEX_HASH_MASK])
328 
329 #define GETCHAR(c, cp) do {						\
330 	(c) = *(cp)++;							\
331 } while (0)
332 
333 #define PUTCHAR(s, cp) do {						\
334 	*(cp)++ = (u_char)(s);						\
335 } while (0)
336 
337 #define GETSHORT(s, cp) do {						\
338 	(s) = *(cp)++ << 8;						\
339 	(s) |= *(cp)++;							\
340 } while (0)
341 
342 #define PUTSHORT(s, cp) do {						\
343 	*(cp)++ = (u_char) ((s) >> 8);					\
344 	*(cp)++ = (u_char) (s);						\
345 } while (0)
346 
347 #define GETLONG(l, cp) do {						\
348 	(l) = *(cp)++ << 8;						\
349 	(l) |= *(cp)++; (l) <<= 8;					\
350 	(l) |= *(cp)++; (l) <<= 8;					\
351 	(l) |= *(cp)++;							\
352 } while (0)
353 
354 #define PUTLONG(l, cp) do {						\
355 	*(cp)++ = (u_char) ((l) >> 24);					\
356 	*(cp)++ = (u_char) ((l) >> 16);					\
357 	*(cp)++ = (u_char) ((l) >> 8);					\
358 	*(cp)++ = (u_char) (l);						\
359 } while (0)
360 
361 #define PIPEX_PULLUP(m0, l)						\
362 	if ((m0)->m_len < (l)) {					\
363 		if ((m0)->m_pkthdr.len < (l)) {				\
364 			PIPEX_DBG((NULL, LOG_DEBUG,			\
365 			    "<%s> received packet is too short.",	\
366 			    __func__));					\
367 			m_freem(m0);					\
368 			(m0) = NULL;					\
369 		} else  {						\
370 			(m0) = m_pullup((m0), (l));			\
371 			KASSERT((m0) != NULL);				\
372 		}							\
373 	}
374 #define PIPEX_SEEK_NEXTHDR(ptr, len, t)					\
375     ((t) (((char *)ptr) + len))
376 #define SEQ32_LT(a,b)	((int32_t)((a) - (b)) <  0)
377 #define SEQ32_LE(a,b)	((int32_t)((a) - (b)) <= 0)
378 #define SEQ32_GT(a,b)	((int32_t)((a) - (b)) >  0)
379 #define SEQ32_GE(a,b)	((int32_t)((a) - (b)) >= 0)
380 #define SEQ32_SUB(a,b)	((int32_t)((a) - (b)))
381 
382 #define SEQ16_LT(a,b)	((int16_t)((a) - (b)) <  0)
383 #define SEQ16_LE(a,b)	((int16_t)((a) - (b)) <= 0)
384 #define SEQ16_GT(a,b)	((int16_t)((a) - (b)) >  0)
385 #define SEQ16_GE(a,b)	((int16_t)((a) - (b)) >= 0)
386 #define SEQ16_SUB(a,b)	((int16_t)((a) - (b)))
387 
388 #define	pipex_session_is_acfc_accepted(s)				\
389     (((s)->ppp_flags & PIPEX_PPP_ACFC_ACCEPTED)? 1 : 0)
390 #define	pipex_session_is_pfc_accepted(s)				\
391     (((s)->ppp_flags & PIPEX_PPP_PFC_ACCEPTED)? 1 : 0)
392 #define	pipex_session_is_acfc_enabled(s)				\
393     (((s)->ppp_flags & PIPEX_PPP_ACFC_ENABLED)? 1 : 0)
394 #define	pipex_session_is_pfc_enabled(s)					\
395     (((s)->ppp_flags & PIPEX_PPP_PFC_ENABLED)? 1 : 0)
396 #define	pipex_session_has_acf(s)					\
397     (((s)->ppp_flags & PIPEX_PPP_HAS_ACF)? 1 : 0)
398 #define	pipex_session_is_mppe_accepted(s)				\
399     (((s)->ppp_flags & PIPEX_PPP_MPPE_ACCEPTED)? 1 : 0)
400 #define	pipex_session_is_mppe_enabled(s)				\
401     (((s)->ppp_flags & PIPEX_PPP_MPPE_ENABLED)? 1 : 0)
402 #define	pipex_session_is_mppe_required(s)				\
403     (((s)->ppp_flags & PIPEX_PPP_MPPE_REQUIRED)? 1 : 0)
404 #define pipex_mppe_rc4_keybits(r) ((r)->keylen << 3)
405 #define pipex_session_is_l2tp_data_sequencing_on(s)			\
406     (((s)->proto.l2tp.option_flags & PIPEX_L2TP_USE_SEQUENCING) ? 1 : 0)
407 
408 #define PIPEX_IPGRE_HDRLEN (sizeof(struct ip) + sizeof(struct pipex_gre_header))
409 #define PIPEX_TCP_OPTLEN 40
410 #define	PIPEX_L2TP_MINLEN	8
411 
412 void                  pipex_destroy_all_sessions (void *);
413 int                   pipex_init_session(struct pipex_session **,
414                                              struct pipex_session_req *);
415 int                   pipex_link_session(struct pipex_session *,
416                           struct ifnet *, void *);
417 void                  pipex_unlink_session(struct pipex_session *);
418 void                  pipex_unlink_session_locked(struct pipex_session *);
419 void                  pipex_export_session_stats(struct pipex_session *,
420                           struct pipex_statistics *);
421 int                   pipex_get_stat (struct pipex_session_stat_req *,
422                           void *);
423 int                   pipex_get_closed (struct pipex_session_list_req *,
424                           void *);
425 struct pipex_session  *pipex_lookup_by_ip_address_locked (struct in_addr);
426 struct pipex_session  *pipex_lookup_by_ip_address (struct in_addr);
427 struct pipex_session  *pipex_lookup_by_session_id_locked (int, int);
428 struct pipex_session  *pipex_lookup_by_session_id (int, int);
429 void                  pipex_ip_output (struct mbuf *, struct pipex_session *);
430 void                  pipex_ppp_output (struct mbuf *, struct pipex_session *, int);
431 int                   pipex_ppp_proto (struct mbuf *, struct pipex_session *, int, int *);
432 void                  pipex_ppp_input (struct mbuf *, struct pipex_session *, int);
433 void                  pipex_ip_input (struct mbuf *, struct pipex_session *);
434 #ifdef INET6
435 void                  pipex_ip6_input (struct mbuf *, struct pipex_session *);
436 #endif
437 struct mbuf           *pipex_common_input(struct pipex_session *,
438                           struct mbuf *, int, int, int);
439 
440 #ifdef PIPEX_PPPOE
441 void                  pipex_pppoe_output (struct mbuf *, struct pipex_session *);
442 #endif
443 
444 #ifdef PIPEX_PPTP
445 void                  pipex_pptp_output (struct mbuf *, struct pipex_session *, int, int);
446 struct pipex_session  *pipex_pptp_userland_lookup_session(struct mbuf *, struct sockaddr *);
447 #endif
448 
449 #ifdef PIPEX_L2TP
450 void                  pipex_l2tp_output (struct mbuf *, struct pipex_session *);
451 #endif
452 
453 #ifdef PIPEX_MPPE
454 void                  pipex_mppe_init (struct pipex_mppe *, int, int, u_char *, int);
455 void                  GetNewKeyFromSHA (u_char *, u_char *, int, u_char *);
456 void                  pipex_mppe_reduce_key (struct pipex_mppe *);
457 void                  mppe_key_change (struct pipex_mppe *);
458 struct mbuf           *pipex_mppe_input (struct mbuf *,
459                           struct pipex_session *);
460 struct mbuf           *pipex_mppe_output (struct mbuf *,
461                           struct pipex_session *, uint16_t);
462 void                  pipex_ccp_input (struct mbuf *, struct pipex_session *);
463 int                   pipex_ccp_output (struct pipex_session *, int, int);
464 #endif
465 
466 struct mbuf           *adjust_tcp_mss (struct mbuf *, int);
467 struct mbuf           *ip_is_idle_packet (struct mbuf *, int *);
468 void                  pipex_session_log (struct pipex_session *, int, const char *, ...)  __attribute__((__format__(__printf__,3,4)));
469 uint32_t              pipex_sockaddr_hash_key(struct sockaddr *);
470 int                   pipex_sockaddr_compar_addr(struct sockaddr *, struct sockaddr *);
471 void                  pipex_timer_start (void);
472 void                  pipex_timer_stop (void);
473 void                  pipex_timer (void *);
474 struct pipex_session  *pipex_iterator(struct pipex_session *,
475                           struct pipex_session_iterator *, void *);
476