1/* $OpenBSD: pipex_local.h,v 1.54 2025/03/02 21:28:32 bluhm 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
32extern 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 */
68struct 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
86struct pipex_pppoe_session {
87 u_int over_ifidx; /* [I] ether interface */
88};
89#endif /* PIPEX_PPPOE */
90
91#ifdef PIPEX_PPTP
92struct 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 */
137struct 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 uint32_t ipsecflowinfo; /* [I] IPsec SA flow id for NAT-T */
144
145 int16_t ns_gap; /* [s] gap between userland and pipex */
146 int16_t nr_gap; /* [s] gap between userland and pipex */
147 uint16_t ul_ns_una; /* [s] unacked sequence number (userland) */
148
149 uint16_t ns_nxt; /* [s] next sequence number to send */
150 uint16_t ns_una; /* [s] unacked sequence number to send */
151
152 uint16_t nr_nxt; /* [s] next sequence number to recv */
153 uint16_t nr_acked; /* [s] acked sequence number to recv */
154};
155#endif /* PIPEX_L2TP */
156
157struct cpumem;
158
159/* special iterator session */
160struct 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 */
168struct 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
239enum 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 */
250struct 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 */
267struct 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 */
279struct 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 */
296struct pipex_l2tp_seq_header {
297 uint16_t ns;
298 uint16_t nr;
299} __packed;
300
301struct 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
315LIST_HEAD(pipex_hash_head, pipex_session);
316
317extern struct pipex_hash_head pipex_session_list;
318extern struct pipex_hash_head pipex_close_wait_list;
319extern struct pipex_hash_head pipex_peer_addr_hashtable[];
320extern struct pipex_hash_head pipex_id_hashtable[];
321extern 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
412void pipex_destroy_all_sessions (void *);
413int pipex_init_session(struct pipex_session **,
414 struct pipex_session_req *);
415int pipex_link_session(struct pipex_session *,
416 struct ifnet *, void *);
417void pipex_unlink_session(struct pipex_session *);
418void pipex_unlink_session_locked(struct pipex_session *);
419void pipex_export_session_stats(struct pipex_session *,
420 struct pipex_statistics *);
421int pipex_get_stat (struct pipex_session_stat_req *,
422 void *);
423int pipex_get_closed (struct pipex_session_list_req *,
424 void *);
425struct pipex_session *pipex_lookup_by_ip_address_locked (struct in_addr);
426struct pipex_session *pipex_lookup_by_ip_address (struct in_addr);
427struct pipex_session *pipex_lookup_by_session_id_locked (int, int);
428struct pipex_session *pipex_lookup_by_session_id (int, int);
429void pipex_ip_output(struct mbuf *, struct pipex_session *);
430void pipex_ppp_output(struct mbuf *, struct pipex_session *,
431 int);
432int pipex_ppp_proto(struct mbuf *, struct pipex_session *,
433 int, int *);
434void pipex_ppp_input(struct mbuf *, struct pipex_session *,
435 int, struct netstack *);
436void pipex_ip_input(struct mbuf *, struct pipex_session *,
437 struct netstack *);
438void pipex_ip6_input(struct mbuf *, struct pipex_session *,
439 struct netstack *);
440struct mbuf *pipex_common_input(struct pipex_session *,
441 struct mbuf *, int, int, int, struct netstack *);
442
443#ifdef PIPEX_PPPOE
444void pipex_pppoe_output (struct mbuf *, struct pipex_session *);
445#endif
446
447#ifdef PIPEX_PPTP
448void pipex_pptp_output (struct mbuf *, struct pipex_session *, int, int);
449struct pipex_session *pipex_pptp_userland_lookup_session(struct mbuf *, struct sockaddr *);
450#endif
451
452#ifdef PIPEX_L2TP
453void pipex_l2tp_output (struct mbuf *, struct pipex_session *);
454#endif
455
456#ifdef PIPEX_MPPE
457void pipex_mppe_init (struct pipex_mppe *, int, int, u_char *, int);
458void GetNewKeyFromSHA (u_char *, u_char *, int, u_char *);
459void pipex_mppe_reduce_key (struct pipex_mppe *);
460void mppe_key_change (struct pipex_mppe *);
461struct mbuf *pipex_mppe_input (struct mbuf *,
462 struct pipex_session *);
463struct mbuf *pipex_mppe_output (struct mbuf *,
464 struct pipex_session *, uint16_t);
465void pipex_ccp_input (struct mbuf *, struct pipex_session *);
466int pipex_ccp_output (struct pipex_session *, int, int);
467#endif
468
469struct mbuf *adjust_tcp_mss (struct mbuf *, int);
470struct mbuf *ip_is_idle_packet (struct mbuf *, int *);
471void pipex_session_log (struct pipex_session *, int, const char *, ...) __attribute__((__format__(__printf__,3,4)));
472uint32_t pipex_sockaddr_hash_key(struct sockaddr *);
473int pipex_sockaddr_compar_addr(struct sockaddr *, struct sockaddr *);
474void pipex_timer_start (void);
475void pipex_timer_stop (void);
476void pipex_timer (void *);
477struct pipex_session *pipex_iterator(struct pipex_session *,
478 struct pipex_session_iterator *, void *);