xref: /openbsd-src/sys/net/pipex.c (revision c90a81c56dcebd6a1b73fe4aff9b03385b8e63b3)
1 /*	$OpenBSD: pipex.c,v 1.106 2017/11/20 10:35:24 mpi 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/param.h>
30 #include <sys/systm.h>
31 #include <sys/mbuf.h>
32 #include <sys/socket.h>
33 #include <sys/ioctl.h>
34 #include <sys/select.h>
35 #include <sys/sysctl.h>
36 #include <sys/syslog.h>
37 #include <sys/conf.h>
38 #include <sys/time.h>
39 #include <sys/timeout.h>
40 #include <sys/kernel.h>
41 #include <sys/pool.h>
42 
43 #include <net/if.h>
44 #include <net/if_types.h>
45 #include <netinet/in.h>
46 #include <netinet/if_ether.h>
47 #include <net/if_dl.h>
48 
49 #include <net/radix.h>
50 #include <net/route.h>
51 #include <net/netisr.h>
52 #include <net/ppp_defs.h>
53 #include <net/ppp-comp.h>
54 
55 #include "pf.h"
56 #if NPF > 0
57 #include <net/pfvar.h>
58 #endif
59 
60 #include "bpfilter.h"
61 #if NBPFILTER > 0
62 #include <net/bpf.h>
63 #endif
64 
65 #include <netinet/ip.h>
66 #include <netinet/ip_var.h>
67 #ifdef INET6
68 #include <netinet/ip6.h>
69 #include <netinet6/ip6_var.h>
70 #endif
71 #include <netinet/tcp.h>
72 #include <netinet/udp.h>
73 #include <netinet/udp_var.h>
74 #include <crypto/arc4.h>
75 
76 /* drop static for ddb debuggability */
77 #define	Static
78 
79 #include <net/pipex.h>
80 #include "pipex_local.h"
81 
82 struct pool pipex_session_pool;
83 struct pool mppe_key_pool;
84 
85 /*
86  * static/global variables
87  */
88 int	pipex_enable = 0;
89 struct pipex_hash_head
90     pipex_session_list,				/* master session list */
91     pipex_close_wait_list,			/* expired session list */
92     pipex_peer_addr_hashtable[PIPEX_HASH_SIZE],	/* peer's address hash */
93     pipex_id_hashtable[PIPEX_HASH_SIZE];	/* peer id hash */
94 
95 struct radix_node_head	*pipex_rd_head4 = NULL;
96 struct radix_node_head	*pipex_rd_head6 = NULL;
97 struct timeout pipex_timer_ch;		/* callout timer context */
98 int pipex_prune = 1;			/* walk list every seconds */
99 
100 /* pipex traffic queue */
101 struct mbuf_queue pipexinq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET);
102 struct mbuf_queue pipexoutq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET);
103 
104 /* borrow an mbuf pkthdr field */
105 #define ph_ppp_proto ether_vtag
106 
107 /* from udp_usrreq.c */
108 extern int udpcksum;
109 
110 #ifdef PIPEX_DEBUG
111 int pipex_debug = 0;		/* systcl net.inet.ip.pipex_debug */
112 #endif
113 
114 /* PPP compression == MPPE is assumed, so don't answer CCP Reset-Request. */
115 #define PIPEX_NO_CCP_RESETACK	1
116 
117 /************************************************************************
118  * Core functions
119  ************************************************************************/
120 void
121 pipex_init(void)
122 {
123 	int		 i;
124 	static int	 pipex_init_done = 0;
125 
126 	if (pipex_init_done++)
127 		return;
128 
129 	rn_init(sizeof(struct sockaddr_in6));
130 
131 	pool_init(&pipex_session_pool, sizeof(struct pipex_session), 0,
132 	    IPL_SOFTNET, PR_WAITOK, "ppxss", NULL);
133 	pool_init(&mppe_key_pool, PIPEX_MPPE_KEYLEN * PIPEX_MPPE_NOLDKEY, 0,
134 	    IPL_SOFTNET, PR_WAITOK, "mppekey", NULL);
135 
136 	LIST_INIT(&pipex_session_list);
137 	LIST_INIT(&pipex_close_wait_list);
138 
139 	for (i = 0; i < nitems(pipex_id_hashtable); i++)
140 		LIST_INIT(&pipex_id_hashtable[i]);
141 	for (i = 0; i < nitems(pipex_peer_addr_hashtable); i++)
142 		LIST_INIT(&pipex_peer_addr_hashtable[i]);
143 }
144 
145 void
146 pipex_iface_init(struct pipex_iface_context *pipex_iface, struct ifnet *ifp)
147 {
148 	struct pipex_session *session;
149 
150 	pipex_iface->pipexmode = 0;
151 	pipex_iface->ifnet_this = ifp;
152 
153 	if (pipex_rd_head4 == NULL) {
154 		if (!rn_inithead((void **)&pipex_rd_head4,
155 		    offsetof(struct sockaddr_in, sin_addr)))
156 			panic("rn_inithead() failed on pipex_init()");
157 	}
158 	if (pipex_rd_head6 == NULL) {
159 		if (!rn_inithead((void **)&pipex_rd_head6,
160 		    offsetof(struct sockaddr_in6, sin6_addr)))
161 			panic("rn_inithead() failed on pipex_init()");
162 	}
163 
164 	/* virtual pipex_session entry for multicast */
165 	session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO);
166 	session->is_multicast = 1;
167 	session->pipex_iface = pipex_iface;
168 	pipex_iface->multicast_session = session;
169 }
170 
171 Static void
172 pipex_iface_start(struct pipex_iface_context *pipex_iface)
173 {
174 	pipex_iface->pipexmode = 1;
175 }
176 
177 Static void
178 pipex_iface_stop(struct pipex_iface_context *pipex_iface)
179 {
180 	struct pipex_session *session;
181 	struct pipex_session *session_next;
182 
183 	pipex_iface->pipexmode = 0;
184 	/*
185 	 * traversal all pipex sessions.
186 	 * it will become heavy if the number of pppac devices bocomes large.
187 	 */
188 	for (session = LIST_FIRST(&pipex_session_list);
189 	    session; session = session_next) {
190 		session_next = LIST_NEXT(session, session_list);
191 		if (session->pipex_iface == pipex_iface)
192 			pipex_destroy_session(session);
193 	}
194 }
195 
196 void
197 pipex_iface_fini(struct pipex_iface_context *pipex_iface)
198 {
199 	pool_put(&pipex_session_pool, pipex_iface->multicast_session);
200 	pipex_iface_stop(pipex_iface);
201 }
202 
203 int
204 pipex_ioctl(struct pipex_iface_context *pipex_iface, u_long cmd, caddr_t data)
205 {
206 	int pipexmode, ret = 0;
207 
208 	NET_LOCK();
209 	switch (cmd) {
210 	case PIPEXSMODE:
211 		pipexmode = *(int *)data;
212 		if (pipex_iface->pipexmode != pipexmode) {
213 			if (pipexmode)
214 				pipex_iface_start(pipex_iface);
215 			else
216 				pipex_iface_stop(pipex_iface);
217 		}
218 		break;
219 
220 	case PIPEXGMODE:
221 		*(int *)data = pipex_iface->pipexmode;
222 		break;
223 
224 	case PIPEXASESSION:
225 		ret = pipex_add_session((struct pipex_session_req *)data,
226 		    pipex_iface);
227 		break;
228 
229 	case PIPEXDSESSION:
230 		ret = pipex_close_session(
231 		    (struct pipex_session_close_req *)data);
232 		break;
233 
234 	case PIPEXCSESSION:
235 		ret = pipex_config_session(
236 		    (struct pipex_session_config_req *)data);
237 		break;
238 
239 	case PIPEXGSTAT:
240 		ret = pipex_get_stat((struct pipex_session_stat_req *)data);
241 		break;
242 
243 	case PIPEXGCLOSED:
244 		ret = pipex_get_closed((struct pipex_session_list_req *)data);
245 		break;
246 
247 	default:
248 		ret = ENOTTY;
249 		break;
250 	}
251 	NET_UNLOCK();
252 
253 	return (ret);
254 }
255 
256 /************************************************************************
257  * Session management functions
258  ************************************************************************/
259 Static int
260 pipex_add_session(struct pipex_session_req *req,
261     struct pipex_iface_context *iface)
262 {
263 	struct pipex_session *session;
264 	struct pipex_hash_head *chain;
265 	struct radix_node *rn;
266 #ifdef PIPEX_PPPOE
267 	struct ifnet *over_ifp = NULL;
268 #endif
269 
270 	/* Checks requeted parameters.  */
271 	if (!iface->pipexmode)
272 		return (ENXIO);
273 	switch (req->pr_protocol) {
274 #ifdef PIPEX_PPPOE
275 	case PIPEX_PROTO_PPPOE:
276 		over_ifp = ifunit(req->pr_proto.pppoe.over_ifname);
277 		if (over_ifp == NULL)
278 			return (EINVAL);
279 		if (req->pr_peer_address.ss_family != AF_UNSPEC)
280 			return (EINVAL);
281 		break;
282 #endif
283 #if defined(PIPEX_L2TP) || defined(PIPEX_PPTP)
284 #ifdef PIPEX_PPTP
285 	case PIPEX_PROTO_PPTP:
286 #endif
287 #ifdef PIPEX_L2TP
288 	case PIPEX_PROTO_L2TP:
289 #endif
290 		switch (req->pr_peer_address.ss_family) {
291 		case AF_INET:
292 			if (req->pr_peer_address.ss_len !=
293 			    sizeof(struct sockaddr_in))
294 				return (EINVAL);
295 			break;
296 #ifdef INET6
297 		case AF_INET6:
298 			if (req->pr_peer_address.ss_len !=
299 			    sizeof(struct sockaddr_in6))
300 				return (EINVAL);
301 			break;
302 #endif
303 		default:
304 			return (EPROTONOSUPPORT);
305 		}
306 		if (req->pr_peer_address.ss_family !=
307 		    req->pr_local_address.ss_family ||
308 		    req->pr_peer_address.ss_len !=
309 		    req->pr_local_address.ss_len)
310 			return (EINVAL);
311 		break;
312 #endif
313 	default:
314 		return (EPROTONOSUPPORT);
315 	}
316 
317 	/* prepare a new session */
318 	session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO);
319 	session->state = PIPEX_STATE_OPENED;
320 	session->protocol = req->pr_protocol;
321 	session->session_id = req->pr_session_id;
322 	session->peer_session_id = req->pr_peer_session_id;
323 	session->peer_mru = req->pr_peer_mru;
324 	session->timeout_sec = req->pr_timeout_sec;
325 	session->pipex_iface = iface;
326 	session->ppp_flags = req->pr_ppp_flags;
327 	session->ppp_id = req->pr_ppp_id;
328 
329 	session->ip_forward = 1;
330 
331 	session->ip_address.sin_family = AF_INET;
332 	session->ip_address.sin_len = sizeof(struct sockaddr_in);
333 	session->ip_address.sin_addr = req->pr_ip_address;
334 
335 	session->ip_netmask.sin_family = AF_INET;
336 	session->ip_netmask.sin_len = sizeof(struct sockaddr_in);
337 	session->ip_netmask.sin_addr = req->pr_ip_netmask;
338 
339 	if (session->ip_netmask.sin_addr.s_addr == 0L)
340 		session->ip_netmask.sin_addr.s_addr = 0xffffffffL;
341 	session->ip_address.sin_addr.s_addr &=
342 	    session->ip_netmask.sin_addr.s_addr;
343 
344 	if (req->pr_peer_address.ss_len > 0)
345 		memcpy(&session->peer, &req->pr_peer_address,
346 		    MIN(req->pr_peer_address.ss_len, sizeof(session->peer)));
347 	if (req->pr_local_address.ss_len > 0)
348 		memcpy(&session->local, &req->pr_local_address,
349 		    MIN(req->pr_local_address.ss_len, sizeof(session->local)));
350 #ifdef PIPEX_PPPOE
351 	if (req->pr_protocol == PIPEX_PROTO_PPPOE)
352 		session->proto.pppoe.over_ifidx = over_ifp->if_index;
353 #endif
354 #ifdef PIPEX_PPTP
355 	if (req->pr_protocol == PIPEX_PROTO_PPTP) {
356 		struct pipex_pptp_session *sess_pptp = &session->proto.pptp;
357 
358 		sess_pptp->snd_gap = 0;
359 		sess_pptp->rcv_gap = 0;
360 		sess_pptp->snd_una = req->pr_proto.pptp.snd_una;
361 		sess_pptp->snd_nxt = req->pr_proto.pptp.snd_nxt;
362 		sess_pptp->rcv_nxt = req->pr_proto.pptp.rcv_nxt;
363 		sess_pptp->rcv_acked = req->pr_proto.pptp.rcv_acked;
364 
365 		sess_pptp->winsz = req->pr_proto.pptp.winsz;
366 		sess_pptp->maxwinsz = req->pr_proto.pptp.maxwinsz;
367 		sess_pptp->peer_maxwinsz = req->pr_proto.pptp.peer_maxwinsz;
368 		/* last ack number */
369 		sess_pptp->ul_snd_una = sess_pptp->snd_una - 1;
370 	}
371 #endif
372 #ifdef PIPEX_L2TP
373 	if (req->pr_protocol == PIPEX_PROTO_L2TP) {
374 		struct pipex_l2tp_session *sess_l2tp = &session->proto.l2tp;
375 
376 		/* session keys */
377 		sess_l2tp->tunnel_id = req->pr_proto.l2tp.tunnel_id;
378 		sess_l2tp->peer_tunnel_id = req->pr_proto.l2tp.peer_tunnel_id;
379 
380 		/* protocol options */
381 		sess_l2tp->option_flags = req->pr_proto.l2tp.option_flags;
382 
383 		/* initial state of dynamic context */
384 		sess_l2tp->ns_gap = sess_l2tp->nr_gap = 0;
385 		sess_l2tp->ns_nxt = req->pr_proto.l2tp.ns_nxt;
386 		sess_l2tp->nr_nxt = req->pr_proto.l2tp.nr_nxt;
387 		sess_l2tp->ns_una = req->pr_proto.l2tp.ns_una;
388 		sess_l2tp->nr_acked = req->pr_proto.l2tp.nr_acked;
389 		/* last ack number */
390 		sess_l2tp->ul_ns_una = sess_l2tp->ns_una - 1;
391 		sess_l2tp->ipsecflowinfo = req->pr_proto.l2tp.ipsecflowinfo;
392 	}
393 #endif
394 #ifdef PIPEX_MPPE
395 	if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ACCEPTED) != 0) {
396 		if (req->pr_mppe_recv.keylenbits <= 0) {
397 			pool_put(&pipex_session_pool, session);
398 			return (EINVAL);
399 		}
400 		pipex_session_init_mppe_recv(session,
401 		    req->pr_mppe_recv.stateless, req->pr_mppe_recv.keylenbits,
402 		    req->pr_mppe_recv.master_key);
403 	}
404 	if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ENABLED) != 0) {
405 		if (req->pr_mppe_send.keylenbits <= 0) {
406 			pool_put(&pipex_session_pool, session);
407 			return (EINVAL);
408 		}
409 		pipex_session_init_mppe_send(session,
410 		    req->pr_mppe_send.stateless, req->pr_mppe_send.keylenbits,
411 		    req->pr_mppe_send.master_key);
412 	}
413 
414 	if (pipex_session_is_mppe_required(session)) {
415 		if (!pipex_session_is_mppe_enabled(session) ||
416 		    !pipex_session_is_mppe_accepted(session)) {
417 			pool_put(&pipex_session_pool, session);
418 			return (EINVAL);
419 		}
420 	}
421 #endif
422 
423 	NET_ASSERT_LOCKED();
424 	/* commit the session */
425 	if (!in_nullhost(session->ip_address.sin_addr)) {
426 		if (pipex_lookup_by_ip_address(session->ip_address.sin_addr)
427 		    != NULL) {
428 			pool_put(&pipex_session_pool, session);
429 			return (EADDRINUSE);
430 		}
431 
432 		rn = rn_addroute(&session->ip_address, &session->ip_netmask,
433 		    pipex_rd_head4, session->ps4_rn, RTP_STATIC);
434 		if (rn == NULL) {
435 			pool_put(&pipex_session_pool, session);
436 			return (ENOMEM);
437 		}
438 	}
439 	if (0) { /* NOT YET */
440 		rn = rn_addroute(&session->ip6_address, &session->ip6_prefixlen,
441 		    pipex_rd_head6, session->ps6_rn, RTP_STATIC);
442 		if (rn == NULL) {
443 			pool_put(&pipex_session_pool, session);
444 			return (ENOMEM);
445 		}
446 	}
447 
448 	chain = PIPEX_ID_HASHTABLE(session->session_id);
449 	LIST_INSERT_HEAD(chain, session, id_chain);
450 	LIST_INSERT_HEAD(&pipex_session_list, session, session_list);
451 	switch (req->pr_protocol) {
452 	case PIPEX_PROTO_PPTP:
453 	case PIPEX_PROTO_L2TP:
454 		chain = PIPEX_PEER_ADDR_HASHTABLE(
455 		    pipex_sockaddr_hash_key(&session->peer.sa));
456 		LIST_INSERT_HEAD(chain, session, peer_addr_chain);
457 	}
458 
459 	/* if first session is added, start timer */
460 	if (LIST_NEXT(session, session_list) == NULL)
461 		pipex_timer_start();
462 
463 	pipex_session_log(session, LOG_INFO, "PIPEX is ready.");
464 
465 	return (0);
466 }
467 
468 int
469 pipex_notify_close_session(struct pipex_session *session)
470 {
471 	NET_ASSERT_LOCKED();
472 	session->state = PIPEX_STATE_CLOSE_WAIT;
473 	session->stat.idle_time = 0;
474 	LIST_INSERT_HEAD(&pipex_close_wait_list, session, state_list);
475 
476 	return (0);
477 }
478 
479 int
480 pipex_notify_close_session_all(void)
481 {
482 	struct pipex_session *session;
483 
484 	NET_ASSERT_LOCKED();
485 	LIST_FOREACH(session, &pipex_session_list, session_list)
486 		if (session->state == PIPEX_STATE_OPENED)
487 			pipex_notify_close_session(session);
488 	return (0);
489 }
490 
491 Static int
492 pipex_close_session(struct pipex_session_close_req *req)
493 {
494 	struct pipex_session *session;
495 
496 	NET_ASSERT_LOCKED();
497 	session = pipex_lookup_by_session_id(req->pcr_protocol,
498 	    req->pcr_session_id);
499 	if (session == NULL)
500 		return (EINVAL);
501 
502 	/* remove from close_wait list */
503 	if (session->state == PIPEX_STATE_CLOSE_WAIT)
504 		LIST_REMOVE(session, state_list);
505 
506 	/* get statistics before destroy the session */
507 	req->pcr_stat = session->stat;
508 	session->state = PIPEX_STATE_CLOSED;
509 
510 	return (0);
511 }
512 
513 Static int
514 pipex_config_session(struct pipex_session_config_req *req)
515 {
516 	struct pipex_session *session;
517 
518 	NET_ASSERT_LOCKED();
519 	session = pipex_lookup_by_session_id(req->pcr_protocol,
520 	    req->pcr_session_id);
521 	if (session == NULL)
522 		return (EINVAL);
523 	session->ip_forward = req->pcr_ip_forward;
524 
525 	return (0);
526 }
527 
528 Static int
529 pipex_get_stat(struct pipex_session_stat_req *req)
530 {
531 	struct pipex_session *session;
532 
533 	NET_ASSERT_LOCKED();
534 	session = pipex_lookup_by_session_id(req->psr_protocol,
535 	    req->psr_session_id);
536 	if (session == NULL) {
537 		return (EINVAL);
538 	}
539 	req->psr_stat = session->stat;
540 
541 	return (0);
542 }
543 
544 Static int
545 pipex_get_closed(struct pipex_session_list_req *req)
546 {
547 	struct pipex_session *session;
548 
549 	NET_ASSERT_LOCKED();
550 	bzero(req, sizeof(*req));
551 	while (!LIST_EMPTY(&pipex_close_wait_list)) {
552 		session = LIST_FIRST(&pipex_close_wait_list);
553 		req->plr_ppp_id[req->plr_ppp_id_count++] = session->ppp_id;
554 		LIST_REMOVE(session, state_list);
555 		session->state = PIPEX_STATE_CLOSE_WAIT2;
556 		if (req->plr_ppp_id_count >= PIPEX_MAX_LISTREQ) {
557 			if (!LIST_EMPTY(&pipex_close_wait_list))
558 				req->plr_flags |= PIPEX_LISTREQ_MORE;
559 			break;
560 		}
561 	}
562 
563 	return (0);
564 }
565 
566 Static int
567 pipex_destroy_session(struct pipex_session *session)
568 {
569 	struct radix_node *rn;
570 
571 	/* remove from radix tree and hash chain */
572 	NET_ASSERT_LOCKED();
573 
574 	if (!in_nullhost(session->ip_address.sin_addr)) {
575 		rn = rn_delete(&session->ip_address, &session->ip_netmask,
576 		    pipex_rd_head4, (struct radix_node *)session);
577 		KASSERT(rn != NULL);
578 	}
579 
580 	LIST_REMOVE(session, id_chain);
581 	LIST_REMOVE(session, session_list);
582 #ifdef PIPEX_PPTP
583 	if (session->protocol == PIPEX_PROTO_PPTP) {
584 		LIST_REMOVE(session, peer_addr_chain);
585 	}
586 #endif
587 #ifdef PIPEX_L2TP
588 	if (session->protocol == PIPEX_PROTO_L2TP) {
589 		LIST_REMOVE(session, peer_addr_chain);
590 	}
591 #endif
592 	/* if final session is destroyed, stop timer */
593 	if (LIST_EMPTY(&pipex_session_list))
594 		pipex_timer_stop();
595 
596 	if (session->mppe_recv.old_session_keys)
597 		pool_put(&mppe_key_pool, session->mppe_recv.old_session_keys);
598 	pool_put(&pipex_session_pool, session);
599 
600 	return (0);
601 }
602 
603 Static struct pipex_session *
604 pipex_lookup_by_ip_address(struct in_addr addr)
605 {
606 	struct pipex_session *session;
607 	struct sockaddr_in pipex_in4, pipex_in4mask;
608 
609 	bzero(&pipex_in4, sizeof(pipex_in4));
610 	pipex_in4.sin_addr = addr;
611 	pipex_in4.sin_family = AF_INET;
612 	pipex_in4.sin_len = sizeof(pipex_in4);
613 
614 	bzero(&pipex_in4mask, sizeof(pipex_in4mask));
615 	pipex_in4mask.sin_addr.s_addr = htonl(0xFFFFFFFFL);
616 	pipex_in4mask.sin_family = AF_INET;
617 	pipex_in4mask.sin_len = sizeof(pipex_in4mask);
618 
619 	session = (struct pipex_session *)rn_lookup(&pipex_in4, &pipex_in4mask,
620 	    pipex_rd_head4);
621 
622 #ifdef PIPEX_DEBUG
623 	if (session == NULL) {
624 		char buf[INET_ADDRSTRLEN];
625 
626 		PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found (addr=%s)",
627 		    __func__, inet_ntop(AF_INET, &addr, buf, sizeof(buf))));
628 	}
629 #endif
630 
631 	return (session);
632 }
633 
634 Static struct pipex_session *
635 pipex_lookup_by_session_id(int protocol, int session_id)
636 {
637 	struct pipex_hash_head *list;
638 	struct pipex_session *session;
639 
640 	NET_ASSERT_LOCKED();
641 	list = PIPEX_ID_HASHTABLE(session_id);
642 	LIST_FOREACH(session, list, id_chain) {
643 		if (session->protocol == protocol &&
644 		    session->session_id == session_id)
645 			break;
646 	}
647 
648 #ifdef PIPEX_DEBUG
649 	if (session == NULL)
650 		PIPEX_DBG((NULL, LOG_DEBUG,
651 		    "<%s> session not found (session_id=%d)", __func__,
652 		    session_id));
653 #endif
654 
655 	return (session);
656 }
657 
658 /***********************************************************************
659  * Queue and Software Interrupt Handler
660  ***********************************************************************/
661 void
662 pipexintr(void)
663 {
664 	struct pipex_session *pkt_session;
665 	u_int16_t proto;
666 	struct mbuf *m;
667 	struct mbuf_list ml;
668 
669 	/* ppp output */
670 	mq_delist(&pipexoutq, &ml);
671 	while ((m = ml_dequeue(&ml)) != NULL) {
672 		pkt_session = m->m_pkthdr.ph_cookie;
673 		if (pkt_session == NULL) {
674 			m_freem(m);
675 			continue;
676 		}
677 		proto = m->m_pkthdr.ph_ppp_proto;
678 
679 		m->m_pkthdr.ph_cookie = NULL;
680 		m->m_pkthdr.ph_ppp_proto = 0;
681 
682 		if (pkt_session->is_multicast != 0) {
683 			struct pipex_session *session;
684 			struct mbuf *m0;
685 
686 			LIST_FOREACH(session, &pipex_session_list,
687 			    session_list) {
688 				if (session->pipex_iface !=
689 				    pkt_session->pipex_iface)
690 					continue;
691 				if (session->ip_forward == 0 &&
692 				    session->ip6_forward == 0)
693 					continue;
694 				m0 = m_copym(m, 0, M_COPYALL, M_NOWAIT);
695 				if (m0 == NULL) {
696 					session->stat.oerrors++;
697 					continue;
698 				}
699 				pipex_ppp_output(m0, session, proto);
700 			}
701 			m_freem(m);
702 		} else
703 			pipex_ppp_output(m, pkt_session, proto);
704 	}
705 
706 	/* ppp input */
707 	mq_delist(&pipexinq, &ml);
708 	while ((m = ml_dequeue(&ml)) != NULL) {
709 		pkt_session = m->m_pkthdr.ph_cookie;
710 		if (pkt_session == NULL) {
711 			m_freem(m);
712 			continue;
713 		}
714 		pipex_ppp_input(m, pkt_session, 0);
715 	}
716 }
717 
718 Static int
719 pipex_ppp_enqueue(struct mbuf *m0, struct pipex_session *session,
720     struct mbuf_queue *mq)
721 {
722 	m0->m_pkthdr.ph_cookie = session;
723 	/* XXX need to support other protocols */
724 	m0->m_pkthdr.ph_ppp_proto = PPP_IP;
725 
726 	if (mq_enqueue(mq, m0) != 0)
727 		return (1);
728 
729 	schednetisr(NETISR_PIPEX);
730 
731 	return (0);
732 }
733 
734 /***********************************************************************
735  * Timer functions
736  ***********************************************************************/
737 Static void
738 pipex_timer_start(void)
739 {
740 	timeout_set_proc(&pipex_timer_ch, pipex_timer, NULL);
741 	timeout_add_sec(&pipex_timer_ch, pipex_prune);
742 }
743 
744 Static void
745 pipex_timer_stop(void)
746 {
747 	timeout_del(&pipex_timer_ch);
748 }
749 
750 Static void
751 pipex_timer(void *ignored_arg)
752 {
753 	struct pipex_session *session;
754 	struct pipex_session *session_next;
755 
756 	timeout_add_sec(&pipex_timer_ch, pipex_prune);
757 
758 	NET_LOCK();
759 	/* walk through */
760 	for (session = LIST_FIRST(&pipex_session_list); session;
761 	    session = session_next) {
762 		session_next = LIST_NEXT(session, session_list);
763 		switch (session->state) {
764 		case PIPEX_STATE_OPENED:
765 			if (session->timeout_sec == 0)
766 				continue;
767 
768 			session->stat.idle_time++;
769 			if (session->stat.idle_time < session->timeout_sec)
770 				continue;
771 
772 			pipex_notify_close_session(session);
773 			break;
774 
775 		case PIPEX_STATE_CLOSE_WAIT:
776 		case PIPEX_STATE_CLOSE_WAIT2:
777 			/* Wait PIPEXDSESSION from userland */
778 			session->stat.idle_time++;
779 			if (session->stat.idle_time < PIPEX_CLOSE_TIMEOUT)
780 				continue;
781 
782 			if (session->state == PIPEX_STATE_CLOSE_WAIT)
783 				LIST_REMOVE(session, state_list);
784 			session->state = PIPEX_STATE_CLOSED;
785 			/* FALLTHROUGH */
786 
787 		case PIPEX_STATE_CLOSED:
788 			/*
789 			 * mbuf queued in pipexinq or pipexoutq may have a
790 			 * refererce to this session.
791 			 */
792 			if (!mq_empty(&pipexinq) || !mq_empty(&pipexoutq))
793 				continue;
794 
795 			pipex_destroy_session(session);
796 			break;
797 
798 		default:
799 			break;
800 		}
801 	}
802 
803 	NET_UNLOCK();
804 }
805 
806 /***********************************************************************
807  * Common network I/O functions.  (tunnel protocol independent)
808  ***********************************************************************/
809 struct mbuf *
810 pipex_output(struct mbuf *m0, int af, int off,
811     struct pipex_iface_context *pipex_iface)
812 {
813 	struct pipex_session *session;
814 	struct ip ip;
815 	struct mbuf *mret;
816 
817 	session = NULL;
818 	mret = NULL;
819 	switch (af) {
820 	case AF_INET:
821 		if (m0->m_pkthdr.len >= sizeof(struct ip) + off) {
822 			m_copydata(m0, off, sizeof(struct ip), (caddr_t)&ip);
823 			if (IN_MULTICAST(ip.ip_dst.s_addr))
824 				session = pipex_iface->multicast_session;
825 			else
826 				session = pipex_lookup_by_ip_address(ip.ip_dst);
827 		}
828 		if (session != NULL) {
829 			if (session == pipex_iface->multicast_session) {
830 				mret = m0;
831 				m0 = m_copym(m0, 0, M_COPYALL, M_NOWAIT);
832 				if (m0 == NULL) {
833 					m0 = mret;
834 					mret = NULL;
835 					goto drop;
836 				}
837 			}
838 
839 			if (off > 0)
840 				m_adj(m0, off);
841 
842 			pipex_ip_output(m0, session);
843 			return (mret);
844 		}
845 		break;
846 	}
847 
848 	return (m0);
849 
850 drop:
851 	m_freem(m0);
852 	if (session != NULL)
853 		session->stat.oerrors++;
854 	return(NULL);
855 }
856 
857 Static void
858 pipex_ip_output(struct mbuf *m0, struct pipex_session *session)
859 {
860 	int is_idle;
861 	struct ifnet *ifp;
862 
863 	/* output succeed here as a interface */
864 	ifp = session->pipex_iface->ifnet_this;
865 	ifp->if_opackets++;
866 	ifp->if_obytes+=m0->m_pkthdr.len;
867 
868 	if (session->is_multicast == 0) {
869 		/*
870 		 * Multicast packet is a idle packet and it's not TCP.
871 		 */
872 		if (session->ip_forward == 0 && session->ip6_forward == 0)
873 			goto drop;
874 		/* reset idle timer */
875 		if (session->timeout_sec != 0) {
876 			is_idle = 0;
877 			m0 = ip_is_idle_packet(m0, &is_idle);
878 			if (m0 == NULL)
879 				goto dropped;
880 			if (is_idle == 0)
881 				/* update expire time */
882 				session->stat.idle_time = 0;
883 		}
884 
885 		/* adjust tcpmss */
886 		if ((session->ppp_flags & PIPEX_PPP_ADJUST_TCPMSS) != 0) {
887 			m0 = adjust_tcp_mss(m0, session->peer_mru);
888 			if (m0 == NULL)
889 				goto dropped;
890 		}
891 	} else
892 		m0->m_flags &= ~(M_BCAST|M_MCAST);
893 
894 	/* output ip packets to the session tunnel */
895 	if (pipex_ppp_enqueue(m0, session, &pipexoutq))
896 		goto dropped;
897 
898 	return;
899 drop:
900 	m_freem(m0);
901 dropped:
902 	session->stat.oerrors++;
903 }
904 
905 Static void
906 pipex_ppp_output(struct mbuf *m0, struct pipex_session *session, int proto)
907 {
908 	u_char *cp, hdr[16];
909 
910 #ifdef PIPEX_MPPE
911 	if (pipex_session_is_mppe_enabled(session)) {
912 		if (proto == PPP_IP) {
913 			pipex_mppe_output(m0, session, PPP_IP);
914 			return;
915 		}
916 	}
917 #endif /* PIPEX_MPPE */
918 	cp = hdr;
919 	if (session->protocol != PIPEX_PROTO_PPPOE) {
920 		/* PPPoE has not address and control field */
921 		PUTCHAR(PPP_ALLSTATIONS, cp);
922 		PUTCHAR(PPP_UI, cp);
923 	}
924 	PUTSHORT(proto, cp);
925 
926 	M_PREPEND(m0, cp - hdr, M_NOWAIT);
927 	if (m0 == NULL)
928 		goto drop;
929 	memcpy(mtod(m0, u_char *), hdr, cp - hdr);
930 
931 	switch (session->protocol) {
932 #ifdef	PIPEX_PPPOE
933 	case PIPEX_PROTO_PPPOE:
934 		pipex_pppoe_output(m0, session);
935 		break;
936 #endif
937 #ifdef PIPEX_PPTP
938 	case PIPEX_PROTO_PPTP:
939 		pipex_pptp_output(m0, session, 1, 1);
940 		break;
941 #endif
942 #ifdef	PIPEX_L2TP
943 	case PIPEX_PROTO_L2TP:
944 		pipex_l2tp_output(m0, session);
945 		break;
946 #endif
947 	default:
948 		goto drop;
949 	}
950 
951 	return;
952 drop:
953 	m_freem(m0);
954 	session->stat.oerrors++;
955 }
956 
957 Static void
958 pipex_ppp_input(struct mbuf *m0, struct pipex_session *session, int decrypted)
959 {
960 	int proto, hlen = 0;
961 	struct mbuf *n;
962 
963 	KASSERT(m0->m_pkthdr.len >= PIPEX_PPPMINLEN);
964 	proto = pipex_ppp_proto(m0, session, 0, &hlen);
965 #ifdef PIPEX_MPPE
966 	if (proto == PPP_COMP) {
967 		if (decrypted)
968 			goto drop;
969 
970 		/* checked this on ppp_common_input() already. */
971 		KASSERT(pipex_session_is_mppe_accepted(session));
972 
973 		m_adj(m0, hlen);
974 		pipex_mppe_input(m0, session);
975 		return;
976 	}
977 	if (proto == PPP_CCP) {
978 		if (decrypted)
979 			goto drop;
980 
981 #if NBPFILTER > 0
982 	    {
983 		struct ifnet *ifp = session->pipex_iface->ifnet_this;
984 		if (ifp->if_bpf && ifp->if_type == IFT_PPP)
985 			bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_IN);
986 	    }
987 #endif
988 		m_adj(m0, hlen);
989 		pipex_ccp_input(m0, session);
990 		return;
991 	}
992 #endif
993 	m_adj(m0, hlen);
994 	if (!ALIGNED_POINTER(mtod(m0, caddr_t), uint32_t)) {
995 		n = m_dup_pkt(m0, 0, M_NOWAIT);
996 		if (n == NULL)
997 			goto drop;
998 		m_freem(m0);
999 		m0 = n;
1000 	}
1001 
1002 	switch (proto) {
1003 	case PPP_IP:
1004 		if (session->ip_forward == 0)
1005 			goto drop;
1006 		if (!decrypted && pipex_session_is_mppe_required(session))
1007 			/*
1008 			 * if ip packet received when mppe
1009 			 * is required, discard it.
1010 			 */
1011 			goto drop;
1012 		pipex_ip_input(m0, session);
1013 		return;
1014 #ifdef INET6
1015 	case PPP_IPV6:
1016 		if (session->ip6_forward == 0)
1017 			goto drop;
1018 		if (!decrypted && pipex_session_is_mppe_required(session))
1019 			/*
1020 			 * if ip packet received when mppe
1021 			 * is required, discard it.
1022 			 */
1023 			goto drop;
1024 		pipex_ip6_input(m0, session);
1025 		return;
1026 #endif
1027 	default:
1028 		if (decrypted)
1029 			goto drop;
1030 		/* protocol must be checked on pipex_common_input() already */
1031 		KASSERT(0);
1032 		goto drop;
1033 	}
1034 
1035 	return;
1036 drop:
1037 	m_freem(m0);
1038 	session->stat.ierrors++;
1039 }
1040 
1041 Static void
1042 pipex_ip_input(struct mbuf *m0, struct pipex_session *session)
1043 {
1044 	struct ifnet *ifp;
1045 	struct ip *ip;
1046 	int len;
1047 	int is_idle;
1048 
1049 	/* change recvif */
1050 	ifp = session->pipex_iface->ifnet_this;
1051 	m0->m_pkthdr.ph_ifidx = ifp->if_index;
1052 
1053 	if (ISSET(session->ppp_flags, PIPEX_PPP_INGRESS_FILTER)) {
1054 		PIPEX_PULLUP(m0, sizeof(struct ip));
1055 		if (m0 == NULL)
1056 			goto drop;
1057 		/* ingress filter */
1058 		ip = mtod(m0, struct ip *);
1059 		if ((ip->ip_src.s_addr & session->ip_netmask.sin_addr.s_addr) !=
1060 		    session->ip_address.sin_addr.s_addr) {
1061 			char src[INET_ADDRSTRLEN];
1062 
1063 			pipex_session_log(session, LOG_DEBUG,
1064 			    "ip packet discarded by ingress filter (src %s)",
1065 			    inet_ntop(AF_INET, &ip->ip_src, src, sizeof(src)));
1066 			goto drop;
1067 		}
1068 	}
1069 
1070 	/* idle timer */
1071 	if (session->timeout_sec != 0) {
1072 		is_idle = 0;
1073 		m0 = ip_is_idle_packet(m0, &is_idle);
1074 		if (m0 == NULL)
1075 			goto drop;
1076 		if (is_idle == 0)
1077 			/* update expire time */
1078 			session->stat.idle_time = 0;
1079 	}
1080 
1081 	/* adjust tcpmss */
1082 	if (session->ppp_flags & PIPEX_PPP_ADJUST_TCPMSS) {
1083 		m0 = adjust_tcp_mss(m0, session->peer_mru);
1084 		if (m0 == NULL)
1085 			goto drop;
1086 	}
1087 
1088 #if NPF > 0
1089 	pf_pkt_addr_changed(m0);
1090 #endif
1091 
1092 	len = m0->m_pkthdr.len;
1093 
1094 #if NBPFILTER > 0
1095 	if (ifp->if_bpf)
1096 		bpf_mtap_af(ifp->if_bpf, AF_INET, m0, BPF_DIRECTION_IN);
1097 #endif
1098 
1099 	ifp->if_ipackets++;
1100 	ifp->if_ibytes += len;
1101 	session->stat.ipackets++;
1102 	session->stat.ibytes += len;
1103 	ipv4_input(ifp, m0);
1104 
1105 	return;
1106 drop:
1107 	m_freem(m0);
1108 	session->stat.ierrors++;
1109 }
1110 
1111 #ifdef INET6
1112 Static void
1113 pipex_ip6_input(struct mbuf *m0, struct pipex_session *session)
1114 {
1115 	struct ifnet *ifp;
1116 	int len;
1117 
1118 	/* change recvif */
1119 	ifp = session->pipex_iface->ifnet_this;
1120 	m0->m_pkthdr.ph_ifidx = ifp->if_index;
1121 
1122 	/*
1123 	 * XXX: what is reasonable ingress filter ???
1124 	 *      only one address is enough ??
1125 	 */
1126 
1127 	/* XXX: we must define idle packet for IPv6(ICMPv6). */
1128 
1129 	/*
1130 	 * XXX: tcpmss adjustment for IPv6 is required???
1131 	 *      We may use PMTUD in IPv6....
1132 	 */
1133 
1134 #if NPF > 0
1135 	pf_pkt_addr_changed(m0);
1136 #endif
1137 
1138 	len = m0->m_pkthdr.len;
1139 
1140 #if NBPFILTER > 0
1141 	if (ifp->if_bpf)
1142 		bpf_mtap_af(ifp->if_bpf, AF_INET6, m0, BPF_DIRECTION_IN);
1143 #endif
1144 
1145 	ifp->if_ipackets++;
1146 	ifp->if_ibytes += len;
1147 	session->stat.ipackets++;
1148 	session->stat.ibytes += len;
1149 	ipv6_input(ifp, m0);
1150 }
1151 #endif
1152 
1153 Static struct mbuf *
1154 pipex_common_input(struct pipex_session *session, struct mbuf *m0, int hlen,
1155     int plen, int useq)
1156 {
1157 	int proto, ppphlen;
1158 	u_char code;
1159 
1160 	if ((m0->m_pkthdr.len < hlen + PIPEX_PPPMINLEN) ||
1161 	    (plen < PIPEX_PPPMINLEN))
1162 		goto drop;
1163 
1164 	proto = pipex_ppp_proto(m0, session, hlen, &ppphlen);
1165 	switch (proto) {
1166 #ifdef PIPEX_MPPE
1167 	case PPP_CCP:
1168 		code = 0;
1169 		KASSERT(m0->m_pkthdr.len >= hlen + ppphlen + 1);
1170 		m_copydata(m0, hlen + ppphlen, 1, (caddr_t)&code);
1171 		if (code != CCP_RESETREQ && code != CCP_RESETACK)
1172 			goto not_ours;
1173 		break;
1174 
1175 	case PPP_COMP:
1176 		if (pipex_session_is_mppe_accepted(session))
1177 			break;
1178 		goto not_ours;
1179 #endif
1180 	case PPP_IP:
1181 #ifdef INET6
1182 	case PPP_IPV6:
1183 #endif
1184 		break;
1185 	default:
1186 		goto not_ours;
1187 	}
1188 
1189 	/* ok,  The packet is for PIPEX */
1190 	m_adj(m0, hlen);/* cut off the tunnle protocol header */
1191 
1192 	/* ensure the mbuf length equals the PPP frame length */
1193 	if (m0->m_pkthdr.len < plen)
1194 		goto drop;
1195 	if (m0->m_pkthdr.len > plen) {
1196 		if (m0->m_len == m0->m_pkthdr.len) {
1197 			m0->m_len = plen;
1198 			m0->m_pkthdr.len = plen;
1199 		} else
1200 			m_adj(m0, plen - m0->m_pkthdr.len);
1201 	}
1202 
1203 	if (!useq) {
1204 		pipex_ppp_input(m0, session, 0);
1205 		return (NULL);
1206 	}
1207 
1208 	/* input ppp packets to kernel session */
1209 	if (pipex_ppp_enqueue(m0, session, &pipexinq) != 0)
1210 		goto dropped;
1211 	else
1212 		return (NULL);
1213 drop:
1214 	m_freem(m0);
1215 dropped:
1216 	session->stat.ierrors++;
1217 	return (NULL);
1218 
1219 not_ours:
1220 	return (m0);	/* Not to be handled by PIPEX */
1221 }
1222 
1223 /*
1224  * pipex_ppp_proto
1225  */
1226 Static int
1227 pipex_ppp_proto(struct mbuf *m0, struct pipex_session *session, int off,
1228     int *hlenp)
1229 {
1230 	int proto;
1231 	u_char *cp, pktbuf[4];
1232 
1233 	KASSERT(m0->m_pkthdr.len > sizeof(pktbuf));
1234 	m_copydata(m0, off, sizeof(pktbuf), pktbuf);
1235 	cp = pktbuf;
1236 
1237 	if (pipex_session_has_acf(session)) {
1238 		if (cp[0] == PPP_ALLSTATIONS && cp[1] == PPP_UI)
1239 			cp += 2;
1240 #ifdef PIPEX_DEBUG
1241 		else if (!pipex_session_is_acfc_accepted(session))
1242 			PIPEX_DBG((session, LOG_DEBUG,
1243 			    "no acf but acfc is not accepted by the peer."));
1244 #endif
1245 	}
1246 	if ((*cp & 0x01) != 0) {
1247 		if (!pipex_session_is_pfc_accepted(session)) {
1248 			PIPEX_DBG((session, LOG_DEBUG, "Received a broken ppp "
1249 			    "frame.  No protocol field. %02x-%02x",
1250 			    cp[0], cp[1]));
1251 			return (-1);
1252 		}
1253 		GETCHAR(proto, cp);
1254 	} else
1255 		GETSHORT(proto, cp);
1256 
1257 	if (hlenp != NULL)
1258 		*hlenp = cp - pktbuf;
1259 
1260 	return (proto);
1261 }
1262 
1263 #ifdef PIPEX_PPPOE
1264 /***********************************************************************
1265  * PPPoE
1266  ***********************************************************************/
1267 Static u_char	pipex_pppoe_padding[ETHERMIN];
1268 /*
1269  * pipex_pppoe_lookup_session
1270  */
1271 struct pipex_session *
1272 pipex_pppoe_lookup_session(struct mbuf *m0)
1273 {
1274 	struct pipex_session *session;
1275 	struct pipex_pppoe_header pppoe;
1276 
1277 	/* short packet */
1278 	if (m0->m_pkthdr.len < (sizeof(struct ether_header) + sizeof(pppoe)))
1279 		return (NULL);
1280 
1281 	m_copydata(m0, sizeof(struct ether_header),
1282 	    sizeof(struct pipex_pppoe_header), (caddr_t)&pppoe);
1283 	pppoe.session_id = ntohs(pppoe.session_id);
1284 	session = pipex_lookup_by_session_id(PIPEX_PROTO_PPPOE,
1285 	    pppoe.session_id);
1286 #ifdef PIPEX_DEBUG
1287 	if (session == NULL)
1288 		PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found (id=%d)",
1289 		    __func__, pppoe.session_id));
1290 #endif
1291 	if (session && session->proto.pppoe.over_ifidx != m0->m_pkthdr.ph_ifidx)
1292 		session = NULL;
1293 
1294 	return (session);
1295 }
1296 
1297 struct mbuf *
1298 pipex_pppoe_input(struct mbuf *m0, struct pipex_session *session)
1299 {
1300 	int hlen;
1301 	struct pipex_pppoe_header pppoe;
1302 
1303 	/* already checked at pipex_pppoe_lookup_session */
1304 	KASSERT(m0->m_pkthdr.len >= (sizeof(struct ether_header) +
1305 	    sizeof(pppoe)));
1306 
1307 	m_copydata(m0, sizeof(struct ether_header),
1308 	    sizeof(struct pipex_pppoe_header), (caddr_t)&pppoe);
1309 
1310 	hlen = sizeof(struct ether_header) + sizeof(struct pipex_pppoe_header);
1311 	if ((m0 = pipex_common_input(session, m0, hlen, ntohs(pppoe.length), 0))
1312 	    == NULL)
1313 		return (NULL);
1314 	m_freem(m0);
1315 	session->stat.ierrors++;
1316 	return (NULL);
1317 }
1318 
1319 /*
1320  * pipex_ppope_output
1321  */
1322 Static void
1323 pipex_pppoe_output(struct mbuf *m0, struct pipex_session *session)
1324 {
1325 	struct pipex_pppoe_header *pppoe;
1326 	struct ifnet *ifp;
1327 	int len, padlen;
1328 
1329 	/* save length for pppoe header */
1330 	len = m0->m_pkthdr.len;
1331 
1332 	/* prepend protocol header */
1333 	M_PREPEND(m0, sizeof(struct pipex_pppoe_header), M_NOWAIT);
1334 	if (m0 == NULL) {
1335 		PIPEX_DBG((NULL, LOG_ERR,
1336 		    "<%s> cannot prepend header.", __func__));
1337 		session->stat.oerrors++;
1338 		return;
1339 	}
1340 	padlen = ETHERMIN - m0->m_pkthdr.len;
1341 	if (padlen > 0)
1342 		m_copyback(m0, m0->m_pkthdr.len, padlen, pipex_pppoe_padding,
1343 		    M_NOWAIT);
1344 
1345 	/* setup pppoe header information */
1346 	pppoe = mtod(m0, struct pipex_pppoe_header *);
1347 	pppoe->vertype = PIPEX_PPPOE_VERTYPE;
1348 	pppoe->code = PIPEX_PPPOE_CODE_SESSION;
1349 	pppoe->session_id = htons(session->session_id);
1350 	pppoe->length = htons(len);
1351 
1352 	m0->m_pkthdr.ph_ifidx = session->proto.pppoe.over_ifidx;
1353 	m0->m_flags &= ~(M_BCAST|M_MCAST);
1354 
1355 	ifp = if_get(session->proto.pppoe.over_ifidx);
1356 	if (ifp != NULL) {
1357 		ifp->if_output(ifp, m0, &session->peer.sa, NULL);
1358 		session->stat.opackets++;
1359 		session->stat.obytes += len;
1360 	} else {
1361 		m_freem(m0);
1362 		session->stat.oerrors++;
1363 	}
1364 	if_put(ifp);
1365 }
1366 #endif /* PIPEX_PPPOE */
1367 
1368 #ifdef PIPEX_PPTP
1369 /***********************************************************************
1370  * PPTP
1371  ***********************************************************************/
1372 Static void
1373 pipex_pptp_output(struct mbuf *m0, struct pipex_session *session,
1374     int has_seq, int has_ack)
1375 {
1376 	int len, reqlen;
1377 	struct pipex_gre_header *gre = NULL;
1378 	struct ip *ip;
1379 	u_char *cp;
1380 
1381 	reqlen = PIPEX_IPGRE_HDRLEN + (has_seq + has_ack) * 4;
1382 
1383 	len = 0;
1384 	if (m0 != NULL) {
1385 		/* save length for gre header */
1386 		len = m0->m_pkthdr.len;
1387 		/* prepend protocol header */
1388 		M_PREPEND(m0, reqlen, M_NOWAIT);
1389 		if (m0 == NULL)
1390 			goto drop;
1391 	} else {
1392 		MGETHDR(m0, M_DONTWAIT, MT_DATA);
1393 		if (m0 && reqlen > MHLEN) {
1394 			MCLGET(m0, M_DONTWAIT);
1395 			if ((m0->m_flags & M_EXT) == 0) {
1396 				m_freem(m0);
1397 				m0 = NULL;
1398 			}
1399 		}
1400 		if (m0 == NULL)
1401 			goto drop;
1402 		m0->m_pkthdr.len = m0->m_len = reqlen;
1403 	}
1404 
1405 	/* setup ip header information */
1406 	ip = mtod(m0, struct ip *);
1407 
1408 	ip->ip_len = htons(m0->m_pkthdr.len);
1409 	ip->ip_off = 0;
1410 	ip->ip_ttl = MAXTTL;
1411 	ip->ip_p = IPPROTO_GRE;
1412 	ip->ip_tos = 0;
1413 
1414 	ip->ip_src = session->local.sin4.sin_addr;
1415 	ip->ip_dst = session->peer.sin4.sin_addr;
1416 #if NPF > 0
1417 	pf_pkt_addr_changed(m0);
1418 #endif
1419 
1420 	/* setup gre(ver1) header information */
1421 	gre = PIPEX_SEEK_NEXTHDR(ip, sizeof(struct ip),
1422 	    struct pipex_gre_header *);
1423 	gre->type = htons(PIPEX_GRE_PROTO_PPP);
1424 	gre->call_id = htons(session->peer_session_id);
1425 	gre->flags = PIPEX_GRE_KFLAG | PIPEX_GRE_VER;	/* do htons later */
1426 	gre->len = htons(len);
1427 
1428 	cp = PIPEX_SEEK_NEXTHDR(gre, sizeof(struct pipex_gre_header),u_char *);
1429 	if (has_seq) {
1430 		gre->flags |= PIPEX_GRE_SFLAG;
1431 		PUTLONG(session->proto.pptp.snd_nxt, cp);
1432 		session->proto.pptp.snd_nxt++;
1433 		session->proto.pptp.snd_gap++;
1434 	}
1435 	if (has_ack) {
1436 		gre->flags |= PIPEX_GRE_AFLAG;
1437 		session->proto.pptp.rcv_acked = session->proto.pptp.rcv_nxt - 1;
1438 		PUTLONG(session->proto.pptp.rcv_acked, cp);
1439 	}
1440 	gre->flags = htons(gre->flags);
1441 
1442 	m0->m_pkthdr.ph_ifidx = session->pipex_iface->ifnet_this->if_index;
1443 	if (ip_output(m0, NULL, NULL, 0, NULL, NULL, 0) != 0) {
1444 		PIPEX_DBG((session, LOG_DEBUG, "ip_output failed."));
1445 		goto drop;
1446 	}
1447 	if (len > 0) {	/* network layer only */
1448 		/* countup statistics */
1449 		session->stat.opackets++;
1450 		session->stat.obytes += len;
1451 	}
1452 
1453 	return;
1454 drop:
1455 	session->stat.oerrors++;
1456 }
1457 
1458 struct pipex_session *
1459 pipex_pptp_lookup_session(struct mbuf *m0)
1460 {
1461 	struct pipex_session *session;
1462 	struct pipex_gre_header gre;
1463 	struct ip ip;
1464 	uint16_t flags;
1465 	uint16_t id;
1466 	int hlen;
1467 
1468 	if (m0->m_pkthdr.len < PIPEX_IPGRE_HDRLEN) {
1469 		PIPEX_DBG((NULL, LOG_DEBUG,
1470 		    "<%s> packet length is too short", __func__));
1471 		goto not_ours;
1472 	}
1473 
1474 	/* get ip header info */
1475 	m_copydata(m0, 0, sizeof(struct ip), (caddr_t)&ip);
1476 	hlen = ip.ip_hl << 2;
1477 
1478 	/*
1479 	 * m0 has already passed ip_input(), so there is
1480 	 * no necessity for ip packet inspection.
1481 	 */
1482 
1483 	/* get gre flags */
1484 	m_copydata(m0, hlen, sizeof(gre), (caddr_t)&gre);
1485 	flags = ntohs(gre.flags);
1486 
1487 	/* gre version must be '1' */
1488 	if ((flags & PIPEX_GRE_VERMASK) != PIPEX_GRE_VER) {
1489 		PIPEX_DBG((NULL, LOG_DEBUG,
1490 		    "<%s> gre header wrong version.", __func__));
1491 		goto not_ours;
1492 	}
1493 
1494 	/* gre keys must be present */
1495 	if ((flags & PIPEX_GRE_KFLAG) == 0) {
1496 		PIPEX_DBG((NULL, LOG_DEBUG,
1497 		    "<%s> gre header has no keys.", __func__));
1498 		goto not_ours;
1499 	}
1500 
1501 	/* flag check */
1502 	if ((flags & PIPEX_GRE_UNUSEDFLAGS) != 0) {
1503 		PIPEX_DBG((NULL, LOG_DEBUG,
1504 		    "<%s> gre header has unused flags at pptp.", __func__));
1505 		goto not_ours;
1506 	}
1507 
1508 	/* lookup pipex session table */
1509 	id = ntohs(gre.call_id);
1510 	session = pipex_lookup_by_session_id(PIPEX_PROTO_PPTP, id);
1511 #ifdef PIPEX_DEBUG
1512 	if (session == NULL) {
1513 		PIPEX_DBG((NULL, LOG_DEBUG,
1514 		    "<%s> session not found (id=%d)", __func__, id));
1515 		goto not_ours;
1516 	}
1517 #endif
1518 
1519 	return (session);
1520 
1521 not_ours:
1522 	return (NULL);
1523 }
1524 
1525 struct mbuf *
1526 pipex_pptp_input(struct mbuf *m0, struct pipex_session *session)
1527 {
1528 	int hlen, has_seq, has_ack, nseq;
1529 	const char *reason = "";
1530 	u_char *cp, *seqp = NULL, *ackp = NULL;
1531 	uint32_t flags, seq = 0, ack = 0;
1532 	struct ip *ip;
1533 	struct pipex_gre_header *gre;
1534 	struct pipex_pptp_session *pptp_session;
1535 	int rewind = 0;
1536 
1537 	KASSERT(m0->m_pkthdr.len >= PIPEX_IPGRE_HDRLEN);
1538 	pptp_session = &session->proto.pptp;
1539 
1540 	/* get ip header */
1541 	ip = mtod(m0, struct ip *);
1542 	hlen = ip->ip_hl << 2;
1543 
1544 	/* seek gre header */
1545 	gre = PIPEX_SEEK_NEXTHDR(ip, hlen, struct pipex_gre_header *);
1546 	flags = ntohs(gre->flags);
1547 
1548 	/* pullup for seek sequences in header */
1549 	has_seq = (flags & PIPEX_GRE_SFLAG) ? 1 : 0;
1550 	has_ack = (flags & PIPEX_GRE_AFLAG) ? 1 : 0;
1551 	hlen = PIPEX_IPGRE_HDRLEN + 4 * (has_seq + has_ack);
1552 	if (m0->m_len < hlen) {
1553 		m0 = m_pullup(m0, hlen);
1554 		if (m0 == NULL) {
1555 			PIPEX_DBG((session, LOG_DEBUG, "pullup failed."));
1556 			goto drop;
1557 		}
1558 	}
1559 
1560 	/* check sequence */
1561 	cp = PIPEX_SEEK_NEXTHDR(gre, sizeof(struct pipex_gre_header),u_char *);
1562 	if (has_seq) {
1563 		seqp = cp;
1564 		GETLONG(seq, cp);
1565 	}
1566 	if (has_ack) {
1567 		ackp = cp;
1568 		GETLONG(ack, cp);
1569 		if (ack + 1 == pptp_session->snd_una) {
1570 			/* ack has not changed before */
1571 		} else if (SEQ32_LT(ack, pptp_session->snd_una)) {
1572 			/* OoO ack packets should not be dropped. */
1573 			rewind = 1;
1574 		} else if (SEQ32_GT(ack, pptp_session->snd_nxt)) {
1575 			reason = "ack for unknown sequence";
1576 			goto out_seq;
1577 		} else
1578 			pptp_session->snd_una = ack + 1;
1579 	}
1580 	if (!has_seq) {
1581 		/* ack only packet */
1582 		goto not_ours;
1583 	}
1584 	if (SEQ32_LT(seq, pptp_session->rcv_nxt)) {
1585 		rewind = 1;
1586 		if (SEQ32_LT(seq,
1587 		    pptp_session->rcv_nxt - PIPEX_REWIND_LIMIT)) {
1588 			reason = "out of sequence";
1589 			goto out_seq;
1590 		}
1591 	} else if (SEQ32_GE(seq, pptp_session->rcv_nxt +
1592 	    pptp_session->maxwinsz)) {
1593 		pipex_session_log(session, LOG_DEBUG,
1594 		    "received packet caused window overflow. seq=%u(%u-%u)"
1595 		    "may lost %d packets.", seq, pptp_session->rcv_nxt,
1596 		    pptp_session->rcv_nxt + pptp_session->maxwinsz,
1597 		    (int)SEQ32_SUB(seq, pptp_session->rcv_nxt));
1598 	}
1599 
1600 	seq++;
1601 	nseq = SEQ32_SUB(seq, pptp_session->rcv_nxt);
1602 	if (!rewind) {
1603 		pptp_session->rcv_nxt = seq;
1604 		if (SEQ32_SUB(seq, pptp_session->rcv_acked) >
1605 		    roundup(pptp_session->winsz, 2) / 2) /* Send ack only packet. */
1606 			pipex_pptp_output(NULL, session, 0, 1);
1607 	}
1608 
1609 	if ((m0 = pipex_common_input(session, m0, hlen, ntohs(gre->len), 1))
1610 	    == NULL) {
1611 		/* ok,  The packet is for PIPEX */
1612 		if (!rewind)
1613 			session->proto.pptp.rcv_gap += nseq;
1614 		return (NULL);
1615 	}
1616 
1617 	if (rewind)
1618 		goto out_seq;
1619 
1620 not_ours:
1621 	seq--;	/* revert original seq value */
1622 
1623 	/*
1624 	 * overwrite sequence numbers to adjust a gap between pipex and
1625 	 * userland.
1626 	 */
1627 	if (seqp != NULL) {
1628 		seq -= pptp_session->rcv_gap;
1629 		PUTLONG(seq, seqp);
1630 	}
1631 	if (ackp != NULL) {
1632 		if (pptp_session->snd_nxt == pptp_session->snd_una) {
1633 			ack -= session->proto.pptp.snd_gap;
1634 			pptp_session->ul_snd_una = ack;
1635 		} else {
1636 			/*
1637 			 * There are sending packets they are not acked.
1638 			 * In this situation, (ack - snd_gap) may points
1639 			 * before sending window of userland.  So we don't
1640 			 * update the ack number.
1641 			 */
1642 			ack = pptp_session->ul_snd_una;
1643 		}
1644 		PUTLONG(ack, ackp);
1645 	}
1646 
1647 	return (m0);
1648 out_seq:
1649 	pipex_session_log(session, LOG_DEBUG,
1650 	    "Received bad data packet: %s: seq=%u(%u-%u) ack=%u(%u-%u)",
1651 	    reason, seq, pptp_session->rcv_nxt,
1652 	    pptp_session->rcv_nxt + pptp_session->maxwinsz,
1653 	    ack, pptp_session->snd_una,
1654 	    pptp_session->snd_nxt);
1655 
1656 	/* FALLTHROUGH */
1657 drop:
1658 	m_freem(m0);
1659 	session->stat.ierrors++;
1660 
1661 	return (NULL);
1662 }
1663 
1664 struct pipex_session *
1665 pipex_pptp_userland_lookup_session_ipv4(struct mbuf *m0, struct in_addr dst)
1666 {
1667 	struct sockaddr_in sin;
1668 
1669 	memset(&sin, 0, sizeof(sin));
1670 	sin.sin_len = sizeof(sin);
1671 	sin.sin_family = AF_INET;
1672 	sin.sin_addr = dst;
1673 
1674 	return pipex_pptp_userland_lookup_session(m0, sintosa(&sin));
1675 }
1676 
1677 #ifdef INET6
1678 struct pipex_session *
1679 pipex_pptp_userland_lookup_session_ipv6(struct mbuf *m0, struct in6_addr dst)
1680 {
1681 	struct sockaddr_in6 sin6;
1682 
1683 	memset(&sin6, 0, sizeof(sin6));
1684 	sin6.sin6_len = sizeof(sin6);
1685 	sin6.sin6_family = AF_INET6;
1686 	in6_recoverscope(&sin6, &dst);
1687 
1688 	return pipex_pptp_userland_lookup_session(m0, sin6tosa(&sin6));
1689 }
1690 #endif
1691 
1692 Static struct pipex_session *
1693 pipex_pptp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
1694 {
1695 	struct pipex_gre_header gre;
1696 	struct pipex_hash_head *list;
1697 	struct pipex_session *session;
1698 	uint16_t id, flags;
1699 
1700 	/* pullup */
1701 	if (m0->m_pkthdr.len < sizeof(gre)) {
1702 		PIPEX_DBG((NULL, LOG_DEBUG,
1703 		    "<%s> packet length is too short", __func__));
1704 		return (NULL);
1705 	}
1706 
1707 	/* get flags */
1708 	m_copydata(m0, 0, sizeof(struct pipex_gre_header), (caddr_t)&gre);
1709 	flags = ntohs(gre.flags);
1710 
1711 	/* gre version must be '1' */
1712 	if ((flags & PIPEX_GRE_VERMASK) != PIPEX_GRE_VER) {
1713 		PIPEX_DBG((NULL, LOG_DEBUG,
1714 		    "<%s> gre header wrong version.", __func__));
1715 		return (NULL);
1716 	}
1717 
1718 	/* gre keys must be present */
1719 	if ((flags & PIPEX_GRE_KFLAG) == 0) {
1720 		PIPEX_DBG((NULL, LOG_DEBUG,
1721 		    "<%s> gre header has no keys.", __func__));
1722 		return (NULL);
1723 	}
1724 
1725 	/* lookup pipex session table */
1726 	id = ntohs(gre.call_id);
1727 
1728 	list = PIPEX_PEER_ADDR_HASHTABLE(pipex_sockaddr_hash_key(sa));
1729 	LIST_FOREACH(session, list, peer_addr_chain) {
1730 		if (pipex_sockaddr_compar_addr(&session->peer.sa, sa) != 0)
1731 			continue;
1732 		if (session->peer_session_id == id)
1733 			break;
1734 	}
1735 #ifdef PIPEX_DEBUG
1736 	if (session == NULL) {
1737 		PIPEX_DBG((NULL, LOG_DEBUG,
1738 		    "<%s> session not found (,call_id=%d)",
1739 		    __func__, (int)gre.call_id));
1740 	}
1741 #endif
1742 	return (session);
1743 }
1744 
1745 /*
1746  * pipex_pptp_userland_output
1747  */
1748 struct mbuf *
1749 pipex_pptp_userland_output(struct mbuf *m0, struct pipex_session *session)
1750 {
1751 	int len;
1752 	struct pipex_gre_header *gre, gre0;
1753 	uint16_t flags;
1754 	u_char *cp, *cp0;
1755 	uint32_t val32;
1756 
1757 	len = sizeof(struct pipex_gre_header);
1758 	m_copydata(m0, 0, len, (caddr_t)&gre0);
1759 	gre = &gre0;
1760 	flags = ntohs(gre->flags);
1761 	if ((flags & PIPEX_GRE_SFLAG) != 0)
1762 		len += 4;
1763 	if ((flags & PIPEX_GRE_AFLAG) != 0)
1764 		len += 4;
1765 
1766 	/* check length */
1767 	PIPEX_PULLUP(m0, len);
1768 	if (m0 == NULL) {
1769 		PIPEX_DBG((session, LOG_DEBUG, "gre header is too short."));
1770 		return (NULL);
1771 	}
1772 
1773 	gre = mtod(m0, struct pipex_gre_header *);
1774 	cp = PIPEX_SEEK_NEXTHDR(gre, sizeof(struct pipex_gre_header), u_char *);
1775 
1776 	/*
1777 	 * overwrite sequence numbers to adjust a gap between pipex and
1778 	 * userland.
1779 	 */
1780 	if ((flags & PIPEX_GRE_SFLAG) != 0) {
1781 		cp0 = cp;
1782 		GETLONG(val32, cp);
1783 		val32 += session->proto.pptp.snd_gap;
1784 		PUTLONG(val32, cp0);
1785 		session->proto.pptp.snd_nxt++;
1786 	}
1787 	if ((flags & PIPEX_GRE_AFLAG) != 0) {
1788 		cp0 = cp;
1789 		GETLONG(val32, cp);
1790 		val32 += session->proto.pptp.rcv_gap;
1791 		PUTLONG(val32, cp0);
1792 		if (SEQ32_GT(val32, session->proto.pptp.rcv_acked))
1793 			session->proto.pptp.rcv_acked = val32;
1794 	}
1795 
1796 	return (m0);
1797 }
1798 #endif /* PIPEX_PPTP */
1799 
1800 #ifdef PIPEX_L2TP
1801 /***********************************************************************
1802  * L2TP support
1803  ***********************************************************************/
1804 Static void
1805 pipex_l2tp_output(struct mbuf *m0, struct pipex_session *session)
1806 {
1807 	int hlen, plen, datalen;
1808 	struct pipex_l2tp_header *l2tp = NULL;
1809 	struct pipex_l2tp_seq_header *seq = NULL;
1810 	struct udphdr *udp;
1811 	struct ip *ip;
1812 #ifdef INET6
1813 	struct ip6_hdr *ip6;
1814 #endif
1815 
1816 	hlen = sizeof(struct pipex_l2tp_header) +
1817 	    ((pipex_session_is_l2tp_data_sequencing_on(session))
1818 		    ? sizeof(struct pipex_l2tp_seq_header) : 0) +
1819 	    sizeof(struct udphdr) +
1820 #ifdef INET6
1821 	    ((session->peer.sin6.sin6_family == AF_INET6)
1822 		    ? sizeof(struct ip6_hdr) : sizeof(struct ip));
1823 #else
1824 	    sizeof(struct ip);
1825 #endif
1826 
1827 	datalen = 0;
1828 	if (m0 != NULL) {
1829 		datalen = m0->m_pkthdr.len;
1830 		M_PREPEND(m0, hlen, M_NOWAIT);
1831 		if (m0 == NULL)
1832 			goto drop;
1833 	} else {
1834 		MGETHDR(m0, M_DONTWAIT, MT_DATA);
1835 		if (m0 == NULL)
1836 			goto drop;
1837 		KASSERT(hlen <= MHLEN);
1838 		m0->m_pkthdr.len = m0->m_len = hlen;
1839 	}
1840 
1841 #ifdef INET6
1842 	hlen = (session->peer.sin6.sin6_family == AF_INET6)
1843 	    ? sizeof(struct ip6_hdr) : sizeof(struct ip);
1844 #else
1845 	hlen = sizeof(struct ip);
1846 #endif
1847 	plen = datalen + sizeof(struct pipex_l2tp_header) +
1848 	    ((pipex_session_is_l2tp_data_sequencing_on(session))
1849 		    ? sizeof(struct pipex_l2tp_seq_header) : 0);
1850 
1851 	l2tp = (struct pipex_l2tp_header *)
1852 	    (mtod(m0, caddr_t) + hlen + sizeof(struct udphdr));
1853 	l2tp->flagsver = PIPEX_L2TP_VER | PIPEX_L2TP_FLAG_LENGTH;
1854 	l2tp->length = htons(plen);
1855 	l2tp->tunnel_id = htons(session->proto.l2tp.peer_tunnel_id);
1856 	l2tp->session_id = htons(session->peer_session_id);
1857 	if (pipex_session_is_l2tp_data_sequencing_on(session)) {
1858 		seq = (struct pipex_l2tp_seq_header *)(l2tp + 1);
1859 		l2tp->flagsver |= PIPEX_L2TP_FLAG_SEQUENCE;
1860 		seq->ns = htons(session->proto.l2tp.ns_nxt);
1861 		session->proto.l2tp.ns_nxt++;
1862 		session->proto.l2tp.ns_gap++;
1863 		session->proto.l2tp.nr_acked = session->proto.l2tp.nr_nxt - 1;
1864 		seq->nr = htons(session->proto.l2tp.nr_acked);
1865 	}
1866 	l2tp->flagsver = htons(l2tp->flagsver);
1867 
1868 	plen += sizeof(struct udphdr);
1869 	udp = (struct udphdr *)(mtod(m0, caddr_t) + hlen);
1870 	udp->uh_sport = session->local.sin6.sin6_port;
1871 	udp->uh_dport = session->peer.sin6.sin6_port;
1872 	udp->uh_ulen = htons(plen);
1873 	udp->uh_sum = 0;
1874 
1875 	m0->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
1876 	m0->m_pkthdr.ph_ifidx = session->pipex_iface->ifnet_this->if_index;
1877 #if NPF > 0
1878 	pf_pkt_addr_changed(m0);
1879 #endif
1880 	switch (session->peer.sin6.sin6_family) {
1881 	case AF_INET:
1882 		ip = mtod(m0, struct ip *);
1883 		ip->ip_p = IPPROTO_UDP;
1884 		ip->ip_src = session->local.sin4.sin_addr;
1885 		ip->ip_dst = session->peer.sin4.sin_addr;
1886 		ip->ip_len = htons(hlen + plen);
1887 		ip->ip_ttl = MAXTTL;
1888 		ip->ip_tos = 0;
1889 		ip->ip_off = 0;
1890 
1891 		if (ip_output(m0, NULL, NULL, 0, NULL, NULL,
1892 		    session->proto.l2tp.ipsecflowinfo) != 0) {
1893 			PIPEX_DBG((session, LOG_DEBUG, "ip_output failed."));
1894 			goto drop;
1895 		}
1896 		break;
1897 #ifdef INET6
1898 	case AF_INET6:
1899 		ip6 = mtod(m0, struct ip6_hdr *);
1900 
1901 		ip6->ip6_flow = 0;
1902 		ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
1903 		ip6->ip6_vfc |= IPV6_VERSION;
1904 		ip6->ip6_nxt = IPPROTO_UDP;
1905 		ip6->ip6_src = session->local.sin6.sin6_addr;
1906 		(void)in6_embedscope(&ip6->ip6_dst,
1907 		    &session->peer.sin6, NULL);
1908 		/* ip6->ip6_plen will be filled in ip6_output. */
1909 
1910 		if (ip6_output(m0, NULL, NULL, 0, NULL, NULL) != 0) {
1911 			PIPEX_DBG((session, LOG_DEBUG, "ip6_output failed."));
1912 			goto drop;
1913 		}
1914 		break;
1915 #endif
1916 	}
1917 	udpstat_inc(udps_opackets);
1918 
1919 	if (datalen > 0) {	/* network layer only */
1920 		/* countup statistics */
1921 		session->stat.opackets++;
1922 		session->stat.obytes += datalen;
1923 	}
1924 
1925 	return;
1926 drop:
1927 	session->stat.oerrors++;
1928 }
1929 
1930 struct pipex_session *
1931 pipex_l2tp_lookup_session(struct mbuf *m0, int off)
1932 {
1933 	struct pipex_session *session;
1934 	uint16_t flags, session_id, ver;
1935 	u_char *cp, buf[PIPEX_L2TP_MINLEN];
1936 
1937 	if (m0->m_pkthdr.len < off + PIPEX_L2TP_MINLEN) {
1938 		PIPEX_DBG((NULL, LOG_DEBUG,
1939 		    "<%s> packet length is too short", __func__));
1940 		goto not_ours;
1941 	}
1942 
1943 	/* get first 16bits of L2TP */
1944 	m_copydata(m0, off, sizeof(buf), buf);
1945 	cp = buf;
1946 	GETSHORT(flags, cp);
1947 	ver = flags & PIPEX_L2TP_VER_MASK;
1948 
1949 	/* l2tp version must be '2' */
1950 	if (ver != PIPEX_L2TP_VER) {
1951 		PIPEX_DBG((NULL, LOG_DEBUG,
1952 		    "<%s> l2tp header wrong version %u.", __func__, ver));
1953 		goto not_ours;
1954 	}
1955 	if ((flags & PIPEX_L2TP_FLAG_TYPE) != 0)
1956 		goto not_ours;
1957 
1958 	if (flags & PIPEX_L2TP_FLAG_LENGTH)
1959 		cp += 2;			/* skip length field */
1960 	cp += 2;				/* skip tunnel-id field */
1961 	GETSHORT(session_id, cp);		/* get session-id field */
1962 
1963 	/* lookup pipex session table */
1964 	session = pipex_lookup_by_session_id(PIPEX_PROTO_L2TP, session_id);
1965 #ifdef PIPEX_DEBUG
1966 	if (session == NULL) {
1967 		PIPEX_DBG((NULL, LOG_DEBUG,
1968 		    "<%s> session not found (id=%d)", __func__, session_id));
1969 		goto not_ours;
1970 	}
1971 #endif
1972 
1973 	return (session);
1974 
1975 not_ours:
1976 	return (NULL);
1977 }
1978 
1979 struct mbuf *
1980 pipex_l2tp_input(struct mbuf *m0, int off0, struct pipex_session *session,
1981     uint32_t ipsecflowinfo)
1982 {
1983 	struct pipex_l2tp_session *l2tp_session;
1984 	int length, offset, hlen, nseq;
1985 	u_char *cp, *nsp, *nrp;
1986 	uint16_t flags, ns = 0, nr = 0;
1987 	int rewind = 0;
1988 
1989 	length = offset = ns = nr = 0;
1990 	l2tp_session = &session->proto.l2tp;
1991 	l2tp_session->ipsecflowinfo = ipsecflowinfo;
1992 	nsp = nrp = NULL;
1993 
1994 	m_copydata(m0, off0, sizeof(flags), (caddr_t)&flags);
1995 
1996 	flags = ntohs(flags) & PIPEX_L2TP_FLAG_MASK;
1997 	KASSERT((flags & PIPEX_L2TP_FLAG_TYPE) == 0);
1998 
1999 	hlen = 2;				/* flags and version fields */
2000 	if (flags & PIPEX_L2TP_FLAG_LENGTH)	/* length */
2001 		hlen += 2;
2002 	hlen += 4;				/* tunnel-id and session-id */
2003 	if (flags & PIPEX_L2TP_FLAG_SEQUENCE)	/* ns and nr */
2004 		hlen += 4;
2005 	if (flags & PIPEX_L2TP_FLAG_OFFSET)	/* offset */
2006 		hlen += 2;
2007 
2008 	PIPEX_PULLUP(m0, off0 + hlen);
2009 	if (m0  == NULL)
2010 		goto drop;
2011 
2012 	cp = mtod(m0, u_char *) + off0;
2013 	cp += 2;	/* flags and version */
2014 	if (flags & PIPEX_L2TP_FLAG_LENGTH)
2015 		GETSHORT(length, cp);
2016 	else
2017 		length = m0->m_pkthdr.len - off0;
2018 	cp += 4;	/* skip tunnel-id and session-id field */
2019 
2020 	/* pullup for seek sequences in header */
2021 	nseq = 0;
2022 	if (flags & PIPEX_L2TP_FLAG_SEQUENCE) {
2023 		nsp = cp;
2024 		GETSHORT(ns, cp);
2025 		nrp = cp;
2026 		GETSHORT(nr, cp);
2027 
2028 		nr++;
2029 		if (SEQ16_GT(nr, l2tp_session->ns_una) &&
2030 		    SEQ16_LE(nr, l2tp_session->ns_nxt))
2031 			/* update 'ns_una' only if the ns is in valid range */
2032 			l2tp_session->ns_una = nr;
2033 		if (SEQ16_LT(ns, l2tp_session->nr_nxt)) {
2034 			rewind = 1;
2035 			if (SEQ16_LT(ns,
2036 			    l2tp_session->nr_nxt - PIPEX_REWIND_LIMIT))
2037 				goto out_seq;
2038 		}
2039 
2040 		ns++;
2041 		nseq = SEQ16_SUB(ns, l2tp_session->nr_nxt);
2042 		if (!rewind)
2043 			l2tp_session->nr_nxt = ns;
2044 	}
2045 	if (flags & PIPEX_L2TP_FLAG_OFFSET)
2046 		GETSHORT(offset, cp);
2047 
2048 	length -= hlen + offset;
2049 	hlen += off0 + offset;
2050 	if ((m0 = pipex_common_input(session, m0, hlen, length, 1)) == NULL) {
2051 		/* ok,  The packet is for PIPEX */
2052 		if (!rewind)
2053 			session->proto.l2tp.nr_gap += nseq;
2054 		return (NULL);
2055 	}
2056 
2057 	if (rewind)
2058 		goto out_seq;
2059 
2060 	/*
2061 	 * overwrite sequence numbers to adjust a gap between pipex and
2062 	 * userland.
2063 	 */
2064 	if (flags & PIPEX_L2TP_FLAG_SEQUENCE) {
2065 		--ns; --nr;	/* revert original values */
2066 		ns -= l2tp_session->nr_gap;
2067 		PUTSHORT(ns, nsp);
2068 
2069 		if (l2tp_session->ns_nxt == l2tp_session->ns_una) {
2070 			nr -= l2tp_session->ns_gap;
2071 			l2tp_session->ul_ns_una = nr;
2072 		} else {
2073 			/*
2074 			 * There are sending packets they are not acked.
2075 			 * In this situation, (ack - snd_gap) may points
2076 			 * before sending window of userland.  So we don't
2077 			 * update the ack number.
2078 			 */
2079 			nr = l2tp_session->ul_ns_una;
2080 		}
2081 		PUTSHORT(nr, nrp);
2082 	}
2083 
2084 	return (m0);
2085 out_seq:
2086 	pipex_session_log(session, LOG_DEBUG,
2087 	    "Received bad data packet: out of sequence: seq=%u(%u-) "
2088 	    "ack=%u(%u-%u)", ns, l2tp_session->nr_nxt, nr, l2tp_session->ns_una,
2089 	    l2tp_session->ns_nxt);
2090 
2091 	/* FALLTHROUGH */
2092 drop:
2093 	m_freem(m0);
2094 	session->stat.ierrors++;
2095 
2096 	return (NULL);
2097 }
2098 
2099 struct pipex_session *
2100 pipex_l2tp_userland_lookup_session_ipv4(struct mbuf *m0, struct in_addr dst)
2101 {
2102 	struct sockaddr_in sin;
2103 
2104 	memset(&sin, 0, sizeof(sin));
2105 	sin.sin_len = sizeof(sin);
2106 	sin.sin_family = AF_INET;
2107 	sin.sin_addr = dst;
2108 
2109 	return pipex_l2tp_userland_lookup_session(m0, sintosa(&sin));
2110 }
2111 
2112 #ifdef INET6
2113 struct pipex_session *
2114 pipex_l2tp_userland_lookup_session_ipv6(struct mbuf *m0, struct in6_addr dst)
2115 {
2116 	struct sockaddr_in6 sin6;
2117 
2118 	memset(&sin6, 0, sizeof(sin6));
2119 	sin6.sin6_len = sizeof(sin6);
2120 	sin6.sin6_family = AF_INET6;
2121 	in6_recoverscope(&sin6, &dst);
2122 
2123 	return pipex_l2tp_userland_lookup_session(m0, sin6tosa(&sin6));
2124 }
2125 #endif
2126 
2127 struct pipex_session *
2128 pipex_l2tp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
2129 {
2130 	struct pipex_l2tp_header l2tp;
2131 	struct pipex_hash_head *list;
2132 	struct pipex_session *session;
2133 	uint16_t session_id, tunnel_id, flags;
2134 
2135 	if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
2136 		return (NULL);
2137 
2138 	/* pullup */
2139 	if (m0->m_pkthdr.len < sizeof(l2tp)) {
2140 		PIPEX_DBG((NULL, LOG_DEBUG,
2141 		    "<%s> packet length is too short", __func__));
2142 		return (NULL);
2143 	}
2144 
2145 	/* get flags */
2146 	m_copydata(m0, 0, sizeof(l2tp), (caddr_t)&l2tp);
2147 	flags = ntohs(l2tp.flagsver);
2148 
2149 	/* l2tp version must be '2' */
2150 	if ((flags & PIPEX_L2TP_VER_MASK) != PIPEX_L2TP_VER) {
2151 		PIPEX_DBG((NULL, LOG_DEBUG,
2152 		    "<%s> l2tp header wrong version.", __func__));
2153 		return (NULL);
2154 	}
2155 	/* We need L2TP data messages only */
2156 	if ((flags & PIPEX_L2TP_FLAG_TYPE) != 0)
2157 		return (NULL);
2158 	/* No need to hook packets that don't have the sequence field */
2159 	if ((flags & PIPEX_L2TP_FLAG_SEQUENCE) == 0)
2160 		return (NULL);
2161 
2162 	session_id = ntohs(l2tp.session_id);
2163 	tunnel_id = ntohs(l2tp.tunnel_id);
2164 
2165 	list = PIPEX_PEER_ADDR_HASHTABLE(pipex_sockaddr_hash_key(sa));
2166 	LIST_FOREACH(session, list, peer_addr_chain) {
2167 		if (pipex_sockaddr_compar_addr(&session->peer.sa, sa) != 0)
2168 			continue;
2169 		if (session->proto.l2tp.peer_tunnel_id != tunnel_id)
2170 			continue;
2171 		if (session->peer_session_id == session_id)
2172 			break;
2173 	}
2174 #ifdef PIPEX_DEBUG
2175 	if (session == NULL) {
2176 		PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found "
2177 		    "(tunnel_id=%d, session_id=%d)", __func__,
2178 		    tunnel_id, session_id));
2179 	}
2180 #endif
2181 
2182 	return (session);
2183 }
2184 
2185 struct mbuf *
2186 pipex_l2tp_userland_output(struct mbuf *m0, struct pipex_session *session)
2187 {
2188 	struct pipex_l2tp_header *l2tp;
2189 	struct pipex_l2tp_seq_header *seq;
2190 	uint16_t ns, nr;
2191 
2192 	/* check length */
2193 	PIPEX_PULLUP(m0, sizeof(struct pipex_l2tp_header) +
2194 	    sizeof(struct pipex_l2tp_seq_header));
2195 	if (m0 == NULL)
2196 		return (NULL);
2197 
2198 	l2tp = mtod(m0, struct pipex_l2tp_header *);
2199 	KASSERT(ntohs(l2tp->flagsver) & PIPEX_L2TP_FLAG_SEQUENCE);
2200 
2201 	/*
2202 	 * overwrite sequence numbers to adjust a gap between pipex and
2203 	 * userland.
2204 	 */
2205 		seq = (struct pipex_l2tp_seq_header *)(l2tp + 1);
2206 		ns = ntohs(seq->ns);
2207 		nr = ntohs(seq->nr);
2208 
2209 		ns += session->proto.l2tp.ns_gap;
2210 		seq->ns = htons(ns);
2211 		session->proto.l2tp.ns_nxt++;
2212 
2213 		nr += session->proto.l2tp.nr_gap;
2214 		seq->nr = htons(nr);
2215 		if (SEQ16_GT(nr, session->proto.l2tp.nr_acked))
2216 			session->proto.l2tp.nr_acked = nr;
2217 
2218 	return (m0);
2219 }
2220 #endif /* PIPEX_L2TP */
2221 
2222 #ifdef PIPEX_MPPE
2223 /**********************************************************************
2224  * MPPE
2225  ***********************************************************************/
2226 #define	PIPEX_COHERENCY_CNT_MASK		0x0fff
2227 Static void
2228 pipex_mppe_init(struct pipex_mppe *mppe, int stateless, int keylenbits,
2229     u_char *master_key, int has_oldkey)
2230 {
2231 	memset(mppe, 0, sizeof(struct pipex_mppe));
2232 	if (stateless)
2233 		mppe->stateless = 1;
2234 	if (has_oldkey)
2235 		mppe->old_session_keys =
2236 		    pool_get(&mppe_key_pool, PR_WAITOK);
2237 	else
2238 		mppe->old_session_keys = NULL;
2239 	memcpy(mppe->master_key, master_key, sizeof(mppe->master_key));
2240 
2241 	mppe->keylenbits = keylenbits;
2242 	switch (keylenbits) {
2243 	case 40:
2244 	case 56:
2245 		mppe->keylen = 8;
2246 		break;
2247 	case 128:
2248 		mppe->keylen = 16;
2249 		break;
2250 	}
2251 
2252 	GetNewKeyFromSHA(mppe->master_key, mppe->master_key, mppe->keylen,
2253 	    mppe->session_key);
2254 	pipex_mppe_reduce_key(mppe);
2255 	pipex_mppe_setkey(mppe);
2256 }
2257 
2258 void
2259 pipex_session_init_mppe_recv(struct pipex_session *session, int stateless,
2260     int keylenbits, u_char *master_key)
2261 {
2262 	pipex_mppe_init(&session->mppe_recv, stateless, keylenbits,
2263 	    master_key, stateless);
2264 	session->ppp_flags |= PIPEX_PPP_MPPE_ACCEPTED;
2265 }
2266 
2267 void
2268 pipex_session_init_mppe_send(struct pipex_session *session, int stateless,
2269     int keylenbits, u_char *master_key)
2270 {
2271 	pipex_mppe_init(&session->mppe_send, stateless, keylenbits,
2272 	    master_key, 0);
2273 	session->ppp_flags |= PIPEX_PPP_MPPE_ENABLED;
2274 }
2275 
2276 #include <crypto/sha1.h>
2277 
2278 static u_char SHAPad1[] = {
2279 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2280 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2281 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2282 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2283 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2284 }, SHAPad2[] = {
2285 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2286 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2287 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2288 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2289 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2290 };
2291 
2292 Static void
2293 GetNewKeyFromSHA(u_char *StartKey, u_char *SessionKey, int SessionKeyLength,
2294     u_char *InterimKey)
2295 {
2296 	u_char Digest[20];
2297 	SHA1_CTX Context;
2298 
2299 	SHA1Init(&Context);
2300 	SHA1Update(&Context, StartKey, SessionKeyLength);
2301 	SHA1Update(&Context, SHAPad1, 40);
2302 	SHA1Update(&Context, SessionKey, SessionKeyLength);
2303 	SHA1Update(&Context, SHAPad2, 40);
2304 	SHA1Final(Digest, &Context);
2305 
2306 	memcpy(InterimKey, Digest, SessionKeyLength);
2307 }
2308 
2309 Static void
2310 pipex_mppe_reduce_key(struct pipex_mppe *mppe)
2311 {
2312 	switch (mppe->keylenbits) {
2313 	case 40:
2314 		mppe->session_key[0] = 0xd1;
2315 		mppe->session_key[1] = 0x26;
2316 		mppe->session_key[2] = 0x9e;
2317 		break;
2318 	case 56:
2319 		mppe->session_key[0] = 0xd1;
2320 		break;
2321 	}
2322 }
2323 
2324 Static void
2325 mppe_key_change(struct pipex_mppe *mppe)
2326 {
2327 	u_char interim[16];
2328 	struct rc4_ctx keychg;
2329 
2330 	memset(&keychg, 0, sizeof(keychg));
2331 
2332 	GetNewKeyFromSHA(mppe->master_key, mppe->session_key, mppe->keylen,
2333 	    interim);
2334 
2335 	rc4_keysetup(&keychg, interim, mppe->keylen);
2336 	rc4_crypt(&keychg, interim, mppe->session_key, mppe->keylen);
2337 
2338 	pipex_mppe_reduce_key(mppe);
2339 
2340 	if (mppe->old_session_keys) {
2341 		int idx = mppe->coher_cnt & PIPEX_MPPE_OLDKEYMASK;
2342 		memcpy(mppe->old_session_keys[idx],
2343 		    mppe->session_key, PIPEX_MPPE_KEYLEN);
2344 	}
2345 }
2346 
2347 Static void
2348 pipex_mppe_input(struct mbuf *m0, struct pipex_session *session)
2349 {
2350 	int pktloss, encrypt, flushed, m, n, len;
2351 	struct pipex_mppe *mppe;
2352 	uint16_t coher_cnt;
2353 	struct mbuf *m1;
2354 	u_char *cp;
2355 	int rewind = 0;
2356 
2357 	/* pullup */
2358 	PIPEX_PULLUP(m0, sizeof(coher_cnt));
2359 	if (m0 == NULL)
2360 		goto drop;
2361 
2362 	mppe = &session->mppe_recv;
2363 	/* get header information */
2364 	cp = mtod(m0, u_char *);
2365 	GETSHORT(coher_cnt, cp);
2366 	flushed = ((coher_cnt & 0x8000) != 0) ? 1 : 0;
2367 	encrypt = ((coher_cnt & 0x1000) != 0) ? 1 : 0;
2368 	coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2369 	pktloss = 0;
2370 
2371 	PIPEX_MPPE_DBG((session, LOG_DEBUG, "in coher_cnt=%03x %s%s",
2372 	    mppe->coher_cnt, (flushed) ? "[flushed]" : "",
2373 	    (encrypt) ? "[encrypt]" : ""));
2374 
2375 	if (encrypt == 0) {
2376 		pipex_session_log(session, LOG_DEBUG,
2377 		    "Received unexpected MPPE packet.(no ecrypt)");
2378 		goto drop;
2379 	}
2380 
2381 	/* adjust mbuf */
2382 	m_adj(m0, sizeof(coher_cnt));
2383 
2384 	/*
2385 	 * L2TP data session may be used without sequencing, PPP frames may
2386 	 * arrive in disorder.  The 'coherency counter' of MPPE detects such
2387 	 * situations, but we cannot distinguish between 'disorder' and
2388 	 * 'packet loss' exactly.
2389 	 *
2390 	 * When 'coherency counter' detects lost packets greater than
2391 	 * (4096 - 256), we treat as 'disorder' otherwise treat as
2392 	 * 'packet loss'.
2393 	 */
2394     {
2395 	int coher_cnt0;
2396 
2397 	coher_cnt0 = coher_cnt;
2398 	if (coher_cnt < mppe->coher_cnt)
2399 		coher_cnt0 += 0x1000;
2400 	if (coher_cnt0 - mppe->coher_cnt > 0x0f00) {
2401 		if (!mppe->stateless ||
2402 		    coher_cnt0 - mppe->coher_cnt
2403 		    <= 0x1000 - PIPEX_MPPE_NOLDKEY) {
2404 			pipex_session_log(session, LOG_DEBUG,
2405 			    "Workaround the out-of-sequence PPP framing problem: "
2406 			    "%d => %d", mppe->coher_cnt, coher_cnt);
2407 			goto drop;
2408 		}
2409 		rewind = 1;
2410 	}
2411     }
2412 
2413 	if (mppe->stateless != 0) {
2414 		if (!rewind) {
2415 			mppe_key_change(mppe);
2416 			while (mppe->coher_cnt != coher_cnt) {
2417 				mppe->coher_cnt++;
2418 				mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2419 				mppe_key_change(mppe);
2420 				pktloss++;
2421 			}
2422 		}
2423 		pipex_mppe_setoldkey(mppe, coher_cnt);
2424 	} else {
2425 		if (flushed) {
2426 			if (coher_cnt < mppe->coher_cnt) {
2427 				coher_cnt += 0x1000;
2428 			}
2429 			pktloss += coher_cnt - mppe->coher_cnt;
2430 			m = mppe->coher_cnt / 256;
2431 			n = coher_cnt / 256;
2432 			while (m++ < n)
2433 				mppe_key_change(mppe);
2434 
2435 			coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2436 			mppe->coher_cnt = coher_cnt;
2437 		} else if (mppe->coher_cnt != coher_cnt) {
2438 			/* Send CCP ResetReq */
2439 			PIPEX_DBG((session, LOG_DEBUG, "CCP SendResetReq"));
2440 			pipex_ccp_output(session, CCP_RESETREQ,
2441 			    session->ccp_id++);
2442 			goto drop;
2443 		}
2444 		if ((coher_cnt & 0xff) == 0xff) {
2445 			mppe_key_change(mppe);
2446 			flushed = 1;
2447 		}
2448 		if (flushed)
2449 			pipex_mppe_setkey(mppe);
2450 	}
2451 
2452 	if (pktloss > 1000) {
2453 		pipex_session_log(session, LOG_DEBUG,
2454 		    "%d packets loss.", pktloss);
2455 	}
2456 
2457 	/* decrypt ppp payload */
2458 	for (m1 = m0; m1; m1 = m1->m_next) {
2459 		cp = mtod(m1, u_char *);
2460 		len = m1->m_len;
2461 		pipex_mppe_crypt(mppe, len, cp, cp);
2462 	}
2463 
2464 	if (!rewind) {
2465 		/* update coher_cnt */
2466 		mppe->coher_cnt++;
2467 		mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2468 	}
2469 	if (m0->m_pkthdr.len < PIPEX_PPPMINLEN)
2470 		goto drop;
2471 
2472 	pipex_ppp_input(m0, session, 1);
2473 
2474 	return;
2475 drop:
2476 	m_freem(m0);
2477 	session->stat.ierrors++;
2478 }
2479 
2480 Static void
2481 pipex_mppe_output(struct mbuf *m0, struct pipex_session *session,
2482     uint16_t protocol)
2483 {
2484 	int encrypt, flushed, len;
2485 	struct mppe_header {
2486 		uint16_t coher_cnt;
2487 		uint16_t protocol;
2488 	} __packed *hdr;
2489 	u_char *cp;
2490 	struct pipex_mppe *mppe;
2491 	struct mbuf *m;
2492 
2493 	mppe = &session->mppe_send;
2494 
2495 	/*
2496 	 * create a deep-copy if the mbuf has a shared mbuf cluster.
2497 	 * this is required to handle cases of tcp retransmition.
2498 	 */
2499 	for (m = m0; m != NULL; m = m->m_next) {
2500 		if (M_READONLY(m)) {
2501 			m = m_dup_pkt(m0, max_linkhdr, M_NOWAIT);
2502 			m_freem(m0);
2503 			if (m == NULL)
2504 				goto drop;
2505 			m0 = m;
2506 			break;
2507 		}
2508 	}
2509 	/* prepend mppe header */
2510 	M_PREPEND(m0, sizeof(struct mppe_header), M_NOWAIT);
2511 	if (m0 == NULL)
2512 		goto drop;
2513 	hdr = mtod(m0, struct mppe_header *);
2514 	hdr->protocol = protocol;
2515 
2516 	/* check coherency counter */
2517 	flushed = 0;
2518 	encrypt = 1;
2519 
2520 	if (mppe->stateless != 0) {
2521 		flushed = 1;
2522 		mppe_key_change(mppe);
2523 	} else {
2524 		if ((mppe->coher_cnt % 0x100) == 0xff) {
2525 			flushed = 1;
2526 			mppe_key_change(mppe);
2527 		} else if (mppe->resetreq != 0) {
2528 			flushed = 1;
2529 			mppe->resetreq = 0;
2530 		}
2531 	}
2532 
2533 	if (flushed)
2534 		pipex_mppe_setkey(mppe);
2535 
2536 	PIPEX_MPPE_DBG((session, LOG_DEBUG, "out coher_cnt=%03x %s%s",
2537 	    mppe->coher_cnt, (flushed) ? "[flushed]" : "",
2538 	    (encrypt) ? "[encrypt]" : ""));
2539 
2540 	/* setup header information */
2541 	hdr->coher_cnt = (mppe->coher_cnt++) & PIPEX_COHERENCY_CNT_MASK;
2542 	hdr->coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2543 	if (flushed)
2544 		hdr->coher_cnt |= 0x8000;
2545 	if (encrypt)
2546 		hdr->coher_cnt |= 0x1000;
2547 
2548 	hdr->protocol = htons(hdr->protocol);
2549 	hdr->coher_cnt = htons(hdr->coher_cnt);
2550 
2551 	/* encrypt chain */
2552 	for (m = m0; m; m = m->m_next) {
2553 		cp = mtod(m, u_char *);
2554 		len = m->m_len;
2555 		if (m == m0 && len > offsetof(struct mppe_header, protocol)) {
2556 			len -= offsetof(struct mppe_header, protocol);
2557 			cp += offsetof(struct mppe_header, protocol);
2558 		}
2559 		pipex_mppe_crypt(mppe, len, cp, cp);
2560 	}
2561 
2562 	pipex_ppp_output(m0, session, PPP_COMP);
2563 
2564 	return;
2565 drop:
2566 	session->stat.oerrors++;
2567 }
2568 
2569 Static void
2570 pipex_ccp_input(struct mbuf *m0, struct pipex_session *session)
2571 {
2572 	u_char *cp;
2573 	int code, id, len;
2574 
2575 	if (m0->m_pkthdr.len < PPP_HDRLEN)
2576 		goto drop;
2577 	if ((m0 = m_pullup(m0, PPP_HDRLEN)) == NULL)
2578 		goto drop;
2579 
2580 	cp = mtod(m0, u_char *);
2581 	GETCHAR(code, cp);
2582 	GETCHAR(id, cp);
2583 	GETSHORT(len, cp);
2584 
2585 	switch (code) {
2586 	case CCP_RESETREQ:
2587 		PIPEX_DBG((session, LOG_DEBUG, "CCP RecvResetReq"));
2588 		session->mppe_send.resetreq = 1;
2589 #ifndef PIPEX_NO_CCP_RESETACK
2590 		PIPEX_DBG((session, LOG_DEBUG, "CCP SendResetAck"));
2591 		pipex_ccp_output(session, CCP_RESETACK, id);
2592 #endif
2593 		/* ignore error */
2594 		break;
2595 	case CCP_RESETACK:
2596 		PIPEX_DBG((session, LOG_DEBUG, "CCP RecvResetAck"));
2597 		break;
2598 	default:
2599 		PIPEX_DBG((session, LOG_DEBUG, "CCP Recv code=%d", code));
2600 		goto drop;
2601 	}
2602 	m_freem(m0);
2603 
2604 	return;
2605 drop:
2606 	m_freem(m0);
2607 	session->stat.ierrors++;
2608 }
2609 
2610 Static int
2611 pipex_ccp_output(struct pipex_session *session, int code, int id)
2612 {
2613 	u_char *cp;
2614 	struct mbuf *m;
2615 
2616 	MGETHDR(m, M_DONTWAIT, MT_DATA);
2617 	if (m == NULL) {
2618 		session->stat.oerrors++;
2619 		return (1);
2620 	}
2621 	m->m_pkthdr.len = m->m_len = 4;
2622 	cp = mtod(m, u_char *);
2623 	PUTCHAR(code, cp);
2624 	PUTCHAR(id, cp);
2625 	PUTSHORT(4, cp);
2626 
2627 	pipex_ppp_output(m, session, PPP_CCP);
2628 
2629 	return (0);
2630 }
2631 #endif
2632 /***********************************************************************
2633  * Miscellaneous fuctions
2634  ***********************************************************************/
2635 /* adapted from FreeBSD:src/usr.sbin/ppp/tcpmss.c */
2636 /*
2637  * Copyright (c) 2000 Ruslan Ermilov and Brian Somers <brian@Awfulhak.org>
2638  * All rights reserved.
2639  *
2640  * Redistribution and use in source and binary forms, with or without
2641  * modification, are permitted provided that the following conditions
2642  * are met:
2643  * 1. Redistributions of source code must retain the above copyright
2644  *    notice, this list of conditions and the following disclaimer.
2645  * 2. Redistributions in binary form must reproduce the above copyright
2646  *    notice, this list of conditions and the following disclaimer in the
2647  *    documentation and/or other materials provided with the distribution.
2648  *
2649  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2650  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2651  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2652  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2653  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2654  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2655  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2656  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2657  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2658  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2659  * SUCH DAMAGE.
2660  *
2661  * $FreeBSD: src/usr.sbin/ppp/tcpmss.c,v 1.1.4.3 2001/07/19 11:39:54 brian Exp $
2662  */
2663 #define TCP_OPTLEN_IN_SEGMENT	12	/* timestamp option and padding */
2664 #define MAXMSS(mtu) (mtu - sizeof(struct ip) - sizeof(struct tcphdr) - \
2665     TCP_OPTLEN_IN_SEGMENT)
2666 /*
2667  * The following macro is used to update an internet checksum.  "acc" is a
2668  * 32-bit accumulation of all the changes to the checksum (adding in old
2669  * 16-bit words and subtracting out new words), and "cksum" is the checksum
2670  * value to be updated.
2671  */
2672 #define ADJUST_CHECKSUM(acc, cksum) {			\
2673 	acc += cksum;					\
2674 	if (acc < 0) {					\
2675 		acc = -acc;				\
2676 		acc = (acc >> 16) + (acc & 0xffff);	\
2677 		acc += acc >> 16;			\
2678 		cksum = (u_short) ~acc;			\
2679 	} else {					\
2680 		acc = (acc >> 16) + (acc & 0xffff);	\
2681 		acc += acc >> 16;			\
2682 		cksum = (u_short) acc;			\
2683 	}						\
2684 }
2685 
2686 /*
2687  * Rewrite max-segment-size TCP option to avoid PMTU blackhole issues.
2688  * The mtu parameter should be the MTU bottleneck (as far as we know)
2689  * on the link between the source and the destination.
2690  */
2691 Static struct mbuf *
2692 adjust_tcp_mss(struct mbuf *m0, int mtu)
2693 {
2694 	int opt, optlen, acc, mss, maxmss, lpktp;
2695 	struct ip *pip;
2696 	struct tcphdr *th;
2697 	u_char *pktp, *mssp;
2698 	u_int16_t ip_off;
2699 
2700 	lpktp = sizeof(struct ip) + sizeof(struct tcphdr) + PIPEX_TCP_OPTLEN;
2701 	lpktp = MIN(lpktp, m0->m_pkthdr.len);
2702 
2703 	PIPEX_PULLUP(m0, lpktp);
2704 	if (m0 == NULL)
2705 		goto drop;
2706 
2707 	pktp = mtod(m0, char *);
2708 	pip = (struct ip *)pktp;
2709 	ip_off = ntohs(pip->ip_off);
2710 
2711 	/* Non TCP or fragmented packet must not have a MSS option */
2712 	if (pip->ip_p != IPPROTO_TCP ||
2713 	    (ip_off & IP_MF) != 0 || (ip_off & IP_OFFMASK) != 0)
2714 		goto handled;
2715 
2716 	pktp += pip->ip_hl << 2;
2717 	lpktp -= pip->ip_hl << 2;
2718 
2719 	/* packet is broken */
2720 	if (sizeof(struct tcphdr) > lpktp)
2721 		goto drop;
2722 	th = (struct tcphdr *)pktp;
2723 
2724 	/*
2725 	 * As RFC 973, a MSS field must only be sent in the initial
2726 	 * connection request(it must be with SYN).
2727 	 */
2728 	if ((th->th_flags & TH_SYN) == 0)
2729 		goto handled;
2730 
2731 	lpktp = MIN(th->th_off << 4, lpktp);
2732 
2733 	pktp += sizeof(struct tcphdr);
2734 	lpktp -= sizeof(struct tcphdr);
2735 	while (lpktp >= TCPOLEN_MAXSEG) {
2736 		GETCHAR(opt, pktp);
2737 		switch (opt) {
2738 		case TCPOPT_MAXSEG:
2739 			GETCHAR(optlen, pktp);
2740 			mssp = pktp;		/* mss place holder */
2741 			GETSHORT(mss, pktp);
2742 			maxmss = MAXMSS(mtu);
2743 			if (mss > maxmss) {
2744 				PIPEX_DBG((NULL, LOG_DEBUG,
2745 				    "change tcp-mss %d => %d", mss, maxmss));
2746 				PUTSHORT(maxmss, mssp);
2747 				acc = htons(mss);
2748 				acc -= htons(maxmss);
2749 				ADJUST_CHECKSUM(acc, th->th_sum);
2750 			}
2751 			goto handled;
2752 			/* NOTREACHED */
2753 		case TCPOPT_EOL:
2754 			goto handled;
2755 			/* NOTREACHED */
2756 		case TCPOPT_NOP:
2757 			lpktp--;
2758 			break;
2759 		default:
2760 			GETCHAR(optlen, pktp);
2761 			if (optlen < 2)	/* packet is broken */
2762 				goto drop;
2763 			pktp += optlen - 2;
2764 			lpktp -= optlen;
2765 			break;
2766 		}
2767 	}
2768 
2769 handled:
2770 	return (m0);
2771 
2772 drop:
2773 	m_freem(m0);
2774 	return (NULL);
2775 }
2776 
2777 /*
2778  *  Check whether a packet should reset idle timer
2779  *  Returns 1 to don't reset timer (i.e. the packet is "idle" packet)
2780  */
2781 Static struct mbuf *
2782 ip_is_idle_packet(struct mbuf *m0, int *ris_idle)
2783 {
2784 	u_int16_t ip_off;
2785 	const struct udphdr *uh;
2786 	struct ip *pip;
2787 	int len;
2788 
2789 	/* pullup ip header */
2790 	len = sizeof(struct ip);
2791 	PIPEX_PULLUP(m0, len);
2792 	if (m0 == NULL)
2793 		goto error;
2794 	pip = mtod(m0, struct ip *);
2795 
2796 	/*
2797 	 * the packet which fragmentations was not the idle packet.
2798 	 */
2799 	ip_off = ntohs(pip->ip_off);
2800 	if ((ip_off & IP_MF) || ((ip_off & IP_OFFMASK) != 0))
2801 		goto is_active;
2802 
2803 	switch (pip->ip_p) {
2804 	case IPPROTO_IGMP:
2805 		goto is_active;
2806 	case IPPROTO_ICMP:
2807 		len = pip->ip_hl * 4 + 8;
2808 		PIPEX_PULLUP(m0, len);
2809 		if (m0 == NULL)
2810 			goto error;
2811 		pip = mtod(m0, struct ip *);
2812 
2813 		switch (((unsigned char *) pip)[pip->ip_hl * 4]) {
2814 		case 0:	/* Echo Reply */
2815 		case 8:	/* Echo Request */
2816 			goto is_active;
2817 		default:
2818 			goto is_idle;
2819 		}
2820 
2821 	case IPPROTO_UDP:
2822 	case IPPROTO_TCP:
2823 		len = pip->ip_hl * 4 + sizeof(struct udphdr);
2824 		PIPEX_PULLUP(m0, len);
2825 		if (m0 == NULL)
2826 			goto error;
2827 		pip = mtod(m0, struct ip *);
2828 		uh = (struct udphdr *)(mtod(m0, caddr_t) + pip->ip_hl * 4);
2829 
2830 		switch (ntohs(uh->uh_sport)) {
2831 		case 53:	/* DOMAIN */
2832 		case 67:	/* BOOTPS */
2833 		case 68:	/* BOOTPC */
2834 		case 123:	/* NTP */
2835 		case 137:	/* NETBIOS-NS */
2836 		case 520:	/* RIP */
2837 			goto is_idle;
2838 		}
2839 		switch (ntohs(uh->uh_dport)) {
2840 		case 53:	/* DOMAIN */
2841 		case 67:	/* BOOTPS */
2842 		case 68:	/* BOOTPC */
2843 		case 123:	/* NTP */
2844 		case 137:	/* NETBIOS-NS */
2845 		case 520:	/* RIP */
2846 			goto is_idle;
2847 		}
2848 		goto is_active;
2849 	default:
2850 		goto is_active;
2851 	}
2852 
2853 is_active:
2854 	*ris_idle = 0;
2855 	return (m0);
2856 
2857 is_idle:
2858 	*ris_idle = 1;
2859 	return (m0);
2860 
2861 error:
2862 	return (NULL);
2863 }
2864 
2865 Static void
2866 pipex_session_log(struct pipex_session *session, int prio, const char *fmt, ...)
2867 {
2868 	char logbuf[1024];
2869 	va_list ap;
2870 
2871 	logpri(prio);
2872 	if (session != NULL) {
2873 		addlog("pipex: ppp=%d iface=%s protocol=%s id=%d ",
2874 		    session->ppp_id, session->pipex_iface->ifnet_this->if_xname,
2875 		    (session->protocol == PIPEX_PROTO_PPPOE)? "PPPoE" :
2876 		    (session->protocol == PIPEX_PROTO_PPTP)? "PPTP" :
2877 		    (session->protocol == PIPEX_PROTO_L2TP) ? "L2TP" :
2878 		    "Unknown", session->session_id);
2879 	} else
2880 		addlog("pipex: ");
2881 
2882 	va_start(ap, fmt);
2883 	vsnprintf(logbuf, sizeof(logbuf), fmt, ap);
2884 	va_end(ap);
2885 	addlog("%s\n", logbuf);
2886 }
2887 
2888 Static uint32_t
2889 pipex_sockaddr_hash_key(struct sockaddr *sa)
2890 {
2891 	switch (sa->sa_family) {
2892 	case AF_INET:
2893 		return ntohl(satosin(sa)->sin_addr.s_addr);
2894 	case AF_INET6:
2895 		return ntohl(satosin6(sa)->sin6_addr.s6_addr32[3]);
2896 	}
2897 	panic("pipex_sockaddr_hash_key: unknown address family");
2898 	return (0);
2899 }
2900 
2901 /*
2902  * Compare struct sockaddr_in{,6} with the address only.
2903  * The port number is not covered.
2904  */
2905 Static int
2906 pipex_sockaddr_compar_addr(struct sockaddr *a, struct sockaddr *b)
2907 {
2908 	int cmp;
2909 
2910 	cmp = b->sa_family - a->sa_family;
2911 	if (cmp != 0)
2912 		return cmp;
2913 	switch (a->sa_family) {
2914 	case AF_INET:
2915 		return (satosin(b)->sin_addr.s_addr -
2916 		    satosin(a)->sin_addr.s_addr);
2917 	case AF_INET6:
2918 		cmp = (satosin6(b)->sin6_scope_id - satosin6(a)->sin6_scope_id);
2919 		if (cmp != 0)
2920 			return cmp;
2921 		return (memcmp(&satosin6(a)->sin6_addr,
2922 		    &satosin6(b)->sin6_addr,
2923 		    sizeof(struct in6_addr)));
2924 	}
2925 	panic("pipex_sockaddr_compar_addr: unknown address family");
2926 
2927 	return (-1);
2928 }
2929 
2930 Static inline int
2931 pipex_mppe_setkey(struct pipex_mppe *mppe)
2932 {
2933 	rc4_keysetup(&mppe->rc4ctx, mppe->session_key, mppe->keylen);
2934 
2935 	return (0);
2936 }
2937 
2938 Static inline int
2939 pipex_mppe_setoldkey(struct pipex_mppe *mppe, uint16_t coher_cnt)
2940 {
2941 	KASSERT(mppe->old_session_keys != NULL);
2942 
2943 	rc4_keysetup(&mppe->rc4ctx,
2944 	    mppe->old_session_keys[coher_cnt & PIPEX_MPPE_OLDKEYMASK],
2945 	    mppe->keylen);
2946 
2947 	return (0);
2948 }
2949 
2950 Static inline void
2951 pipex_mppe_crypt(struct pipex_mppe *mppe, int len, u_char *indata,
2952     u_char *outdata)
2953 {
2954 	rc4_crypt(&mppe->rc4ctx, indata, outdata, len);
2955 }
2956 
2957 int
2958 pipex_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
2959     size_t newlen)
2960 {
2961 	switch (name[0]) {
2962 	case PIPEXCTL_ENABLE:
2963 		if (namelen != 1)
2964 			return (ENOTDIR);
2965 		return (sysctl_int(oldp, oldlenp, newp, newlen,
2966 		    &pipex_enable));
2967 	case PIPEXCTL_INQ:
2968 	        return (sysctl_mq(name + 1, namelen - 1,
2969 		    oldp, oldlenp, newp, newlen, &pipexinq));
2970 	case PIPEXCTL_OUTQ:
2971 	        return (sysctl_mq(name + 1, namelen - 1,
2972 		    oldp, oldlenp, newp, newlen, &pipexoutq));
2973 	default:
2974 		return (ENOPROTOOPT);
2975 	}
2976 	/* NOTREACHED */
2977 }
2978