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