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