if_pppoe.c revision 1.42
1/* $NetBSD: if_pppoe.c,v 1.42 2003/03/01 15:50:15 martin Exp $ */
2
3/*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Martin Husemann <martin@netbsd.org>.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *        This product includes software developed by the NetBSD
21 *        Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 *    contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#include <sys/cdefs.h>
40__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.42 2003/03/01 15:50:15 martin Exp $");
41
42#include "pppoe.h"
43#include "bpfilter.h"
44
45#include <sys/param.h>
46#include <sys/systm.h>
47#include <sys/kernel.h>
48#include <sys/callout.h>
49#include <sys/malloc.h>
50#include <sys/mbuf.h>
51#include <sys/socket.h>
52#include <sys/proc.h>
53#include <sys/ioctl.h>
54#include <net/if.h>
55#include <net/if_types.h>
56#include <net/if_ether.h>
57#include <net/if_sppp.h>
58#include <net/if_spppvar.h>
59#include <net/if_pppoe.h>
60
61#if NBPFILTER > 0
62#include <net/bpf.h>
63#endif
64
65#include <machine/intr.h>
66
67#undef PPPOE_DEBUG		/* XXX - remove this or make it an option */
68/* #define PPPOE_DEBUG 1 */
69
70struct pppoehdr {
71	u_int8_t vertype;
72	u_int8_t code;
73	u_int16_t session;
74	u_int16_t plen;
75} __attribute__((__packed__));
76
77struct pppoetag {
78	u_int16_t tag;
79	u_int16_t len;
80} __attribute__((__packed__));
81
82#define PPPOE_HEADERLEN	sizeof(struct pppoehdr)
83#define	PPPOE_VERTYPE	0x11	/* VER=1, TYPE = 1 */
84
85#define	PPPOE_TAG_EOL		0x0000		/* end of list */
86#define	PPPOE_TAG_SNAME		0x0101		/* service name */
87#define	PPPOE_TAG_ACNAME	0x0102		/* access concentrator name */
88#define	PPPOE_TAG_HUNIQUE	0x0103		/* host unique */
89#define	PPPOE_TAG_ACCOOKIE	0x0104		/* AC cookie */
90#define	PPPOE_TAG_VENDOR	0x0105		/* vendor specific */
91#define	PPPOE_TAG_RELAYSID	0x0110		/* relay session id */
92#define	PPPOE_TAG_SNAME_ERR	0x0201		/* service name error */
93#define	PPPOE_TAG_ACSYS_ERR	0x0202		/* AC system error */
94#define	PPPOE_TAG_GENERIC_ERR	0x0203		/* gerneric error */
95
96#define PPPOE_CODE_PADI		0x09		/* Active Discovery Initiation */
97#define	PPPOE_CODE_PADO		0x07		/* Active Discovery Offer */
98#define	PPPOE_CODE_PADR		0x19		/* Active Discovery Request */
99#define	PPPOE_CODE_PADS		0x65		/* Active Discovery Session confirmation */
100#define	PPPOE_CODE_PADT		0xA7		/* Active Discovery Terminate */
101
102/* two byte PPP protocol discriminator, then IP data */
103#define	PPPOE_MAXMTU	(ETHERMTU-PPPOE_HEADERLEN-2)
104
105/* Add a 16 bit unsigned value to a buffer pointed to by PTR */
106#define	PPPOE_ADD_16(PTR, VAL)			\
107		*(PTR)++ = (VAL) / 256;		\
108		*(PTR)++ = (VAL) % 256
109
110/* Add a complete PPPoE header to the buffer pointed to by PTR */
111#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN)	\
112		*(PTR)++ = PPPOE_VERTYPE;	\
113		*(PTR)++ = (CODE);		\
114		PPPOE_ADD_16(PTR, SESS);	\
115		PPPOE_ADD_16(PTR, LEN)
116
117#define	PPPOE_DISC_TIMEOUT	(hz*5)	/* base for quick timeout calculation */
118#define	PPPOE_SLOW_RETRY	(hz*60)	/* persistent retry interval */
119#define PPPOE_DISC_MAXPADI	4	/* retry PADI four times (quickly) */
120#define	PPPOE_DISC_MAXPADR	2	/* retry PADR twice */
121
122struct pppoe_softc {
123	struct sppp sc_sppp;		/* contains a struct ifnet as first element */
124	LIST_ENTRY(pppoe_softc) sc_list;
125	struct ifnet *sc_eth_if;	/* ethernet interface we are using */
126
127	int sc_state;			/* discovery phase or session connected */
128	struct ether_addr sc_dest;	/* hardware address of concentrator */
129	u_int16_t sc_session;		/* PPPoE session id */
130
131	char *sc_service_name;		/* if != NULL: requested name of service */
132	char *sc_concentrator_name;	/* if != NULL: requested concentrator id */
133	u_int8_t *sc_ac_cookie;		/* content of AC cookie we must echo back */
134	size_t sc_ac_cookie_len;	/* length of cookie data */
135	struct callout sc_timeout;	/* timeout while not in session state */
136	int sc_padi_retried;		/* number of PADI retries already done */
137	int sc_padr_retried;		/* number of PADR retries already done */
138};
139
140/* incoming traffic will be queued here */
141struct ifqueue ppoediscinq = { NULL };
142struct ifqueue ppoeinq = { NULL };
143
144#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
145void * pppoe_softintr = NULL;
146static void pppoe_softintr_handler(void *);
147#else
148struct callout pppoe_softintr = CALLOUT_INITIALIZER;
149void pppoe_softintr_handler(void *);
150#endif
151
152extern int sppp_ioctl(struct ifnet *, unsigned long, void *);
153
154/* input routines */
155static void pppoe_input(void);
156static void pppoe_disc_input(struct mbuf *);
157static void pppoe_dispatch_disc_pkt(struct mbuf *, int);
158static void pppoe_data_input(struct mbuf *);
159
160/* management routines */
161void pppoeattach(int);
162static int pppoe_connect(struct pppoe_softc *);
163static int pppoe_disconnect(struct pppoe_softc *);
164static void pppoe_abort_connect(struct pppoe_softc *);
165static int pppoe_ioctl(struct ifnet *, unsigned long, caddr_t);
166static void pppoe_tls(struct sppp *);
167static void pppoe_tlf(struct sppp *);
168static void pppoe_start(struct ifnet *);
169
170/* internal timeout handling */
171static void pppoe_timeout(void *);
172
173/* sending actual protocol controll packets */
174static int pppoe_send_padi(struct pppoe_softc *);
175static int pppoe_send_padr(struct pppoe_softc *);
176static int pppoe_send_padt(struct ifnet *, u_int, const u_int8_t *);
177
178/* raw output */
179static int pppoe_output(struct pppoe_softc *, struct mbuf *);
180
181/* internal helper functions */
182static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *);
183static struct pppoe_softc * pppoe_find_softc_by_hunique(u_int8_t *, size_t, struct ifnet *);
184static struct mbuf *pppoe_get_mbuf(size_t len);
185
186LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list;
187
188int	pppoe_clone_create __P((struct if_clone *, int));
189void	pppoe_clone_destroy __P((struct ifnet *));
190
191struct if_clone pppoe_cloner =
192    IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy);
193
194/* ARGSUSED */
195void
196pppoeattach(count)
197	int count;
198{
199	LIST_INIT(&pppoe_softc_list);
200	if_clone_attach(&pppoe_cloner);
201
202	ppoediscinq.ifq_maxlen = IFQ_MAXLEN;
203	ppoeinq.ifq_maxlen = IFQ_MAXLEN;
204
205#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
206	pppoe_softintr = softintr_establish(IPL_SOFTNET, pppoe_softintr_handler, NULL);
207#endif
208}
209
210int
211pppoe_clone_create(ifc, unit)
212	struct if_clone *ifc;
213	int unit;
214{
215	struct pppoe_softc *sc;
216
217	sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK);
218	memset(sc, 0, sizeof(struct pppoe_softc));
219
220	sprintf(sc->sc_sppp.pp_if.if_xname, "pppoe%d", unit);
221	sc->sc_sppp.pp_if.if_softc = sc;
222	sc->sc_sppp.pp_if.if_mtu = PPPOE_MAXMTU;
223	sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX|IFF_POINTOPOINT|IFF_MULTICAST;
224	sc->sc_sppp.pp_if.if_type = IFT_PPP;
225	sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN;
226	sc->sc_sppp.pp_if.if_dlt = DLT_PPP_ETHER;
227	sc->sc_sppp.pp_flags |= PP_KEEPALIVE |	/* use LCP keepalive */
228				PP_NOFRAMING;	/* no serial encapsulation */
229	sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl;
230	IFQ_SET_MAXLEN(&sc->sc_sppp.pp_if.if_snd, IFQ_MAXLEN);
231	IFQ_SET_READY(&sc->sc_sppp.pp_if.if_snd);
232
233	/* changed to real address later */
234	memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
235
236	callout_init(&sc->sc_timeout);
237
238	sc->sc_sppp.pp_if.if_start = pppoe_start;
239	sc->sc_sppp.pp_tls = pppoe_tls;
240	sc->sc_sppp.pp_tlf = pppoe_tlf;
241	sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN;	/* framing added to ppp packets */
242
243	if_attach(&sc->sc_sppp.pp_if);
244	sppp_attach(&sc->sc_sppp.pp_if);
245
246#if NBPFILTER > 0
247	bpfattach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0);
248#endif
249	LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list);
250	return 0;
251}
252
253void
254pppoe_clone_destroy(ifp)
255	struct ifnet *ifp;
256{
257	struct pppoe_softc * sc = ifp->if_softc;
258
259	LIST_REMOVE(sc, sc_list);
260#if NBPFILTER > 0
261	bpfdetach(ifp);
262#endif
263	sppp_detach(&sc->sc_sppp.pp_if);
264	if_detach(ifp);
265	if (sc->sc_concentrator_name)
266		free(sc->sc_concentrator_name, M_DEVBUF);
267	if (sc->sc_service_name)
268		free(sc->sc_service_name, M_DEVBUF);
269	if (sc->sc_ac_cookie)
270		free(sc->sc_ac_cookie, M_DEVBUF);
271	free(sc, M_DEVBUF);
272}
273
274/*
275 * Find the interface handling the specified session.
276 * Note: O(number of sessions open), this is a client-side only, mean
277 * and lean implementation, so number of open sessions typically should
278 * be 1.
279 */
280static struct pppoe_softc *
281pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif)
282{
283	struct pppoe_softc *sc;
284
285	if (session == 0)
286		return NULL;
287
288	LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
289		if (sc->sc_state == PPPOE_STATE_SESSION
290		    && sc->sc_session == session) {
291			if (sc->sc_eth_if == rcvif)
292				return sc;
293			else
294				return NULL;
295		}
296	}
297	return NULL;
298}
299
300/* Check host unique token passed and return appropriate softc pointer,
301 * or NULL if token is bogus. */
302static struct pppoe_softc *
303pppoe_find_softc_by_hunique(u_int8_t *token, size_t len, struct ifnet *rcvif)
304{
305	struct pppoe_softc *sc, *t;
306
307	if (LIST_EMPTY(&pppoe_softc_list))
308		return NULL;
309
310	if (len != sizeof sc)
311		return NULL;
312	memcpy(&t, token, len);
313
314	LIST_FOREACH(sc, &pppoe_softc_list, sc_list)
315		if (sc == t) break;
316
317	if (sc == NULL) {
318#ifdef PPPOE_DEBUG
319		printf("pppoe: alien host unique tag, no session found\n");
320#endif
321		return NULL;
322	}
323
324	/* should be safe to access *sc now */
325	if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) {
326		printf("%s: host unique tag found, but it belongs to a connection in state %d\n",
327			sc->sc_sppp.pp_if.if_xname, sc->sc_state);
328		return NULL;
329	}
330	if (sc->sc_eth_if != rcvif) {
331		printf("%s: wrong interface, not accepting host unique\n",
332			sc->sc_sppp.pp_if.if_xname);
333		return NULL;
334	}
335	return sc;
336}
337
338#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
339static void pppoe_softintr_handler(void *dummy)
340{
341	/* called at splsoftnet() */
342	pppoe_input();
343}
344#else
345void pppoe_softintr_handler(void *dummy)
346{
347	int s = splnet();
348	pppoe_input();
349	splx(s);
350}
351#endif
352
353/* called at appropriate protection level */
354static void
355pppoe_input()
356{
357	struct mbuf *m;
358	int s, disc_done, data_done;
359
360	do {
361		disc_done = 0;
362		data_done = 0;
363		for (;;) {
364			s = splnet();
365			IF_DEQUEUE(&ppoediscinq, m);
366			splx(s);
367			if (m == NULL) break;
368			disc_done = 1;
369			pppoe_disc_input(m);
370		}
371
372		for (;;) {
373			s = splnet();
374			IF_DEQUEUE(&ppoeinq, m);
375			splx(s);
376			if (m == NULL) break;
377			data_done = 1;
378			pppoe_data_input(m);
379		}
380	} while (disc_done || data_done);
381}
382
383/* analyze and handle a single received packet while not in session state */
384static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
385{
386	u_int16_t tag, len;
387	u_int16_t session, plen;
388	struct pppoe_softc *sc;
389	const char *err_msg = NULL;
390	u_int8_t *ac_cookie;
391	size_t ac_cookie_len;
392	struct pppoehdr *ph;
393	struct pppoetag *pt;
394	struct mbuf *n;
395	int noff;
396	struct ether_header *eh;
397
398	if (m->m_len < sizeof(*eh)) {
399		m = m_pullup(m, sizeof(*eh));
400		if (!m)
401			goto done;
402	}
403	eh = mtod(m, struct ether_header *);
404	off += sizeof(*eh);
405
406	ac_cookie = NULL;
407	ac_cookie_len = 0;
408	session = 0;
409	if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) {
410		printf("pppoe: packet too short: %d\n", m->m_pkthdr.len);
411		goto done;
412	}
413
414	n = m_pulldown(m, off, sizeof(*ph), &noff);
415	if (!n) {
416		printf("pppoe: could not get PPPoE header\n");
417		m = NULL;
418		goto done;
419	}
420	ph = (struct pppoehdr *)(mtod(n, caddr_t) + noff);
421	if (ph->vertype != PPPOE_VERTYPE) {
422		printf("pppoe: unknown version/type packet: 0x%x\n",
423		    ph->vertype);
424		goto done;
425	}
426	session = ntohs(ph->session);
427	plen = ntohs(ph->plen);
428	off += sizeof(*ph);
429
430	if (plen + off > m->m_pkthdr.len) {
431		printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n",
432		    m->m_pkthdr.len - off, plen);
433		goto done;
434	}
435	m_adj(m, off + plen - m->m_pkthdr.len);	/* ignore trailing garbage */
436	tag = 0;
437	len = 0;
438	sc = NULL;
439	while (off + sizeof(*pt) <= m->m_pkthdr.len) {
440		n = m_pulldown(m, off, sizeof(*pt), &noff);
441		if (!n) {
442			printf("%s: parse error\n",
443			    sc ? sc->sc_sppp.pp_if.if_xname : "pppoe");
444			m = NULL;
445			goto done;
446		}
447		pt = (struct pppoetag *)(mtod(n, caddr_t) + noff);
448		tag = ntohs(pt->tag);
449		len = ntohs(pt->len);
450		if (off + len > m->m_pkthdr.len) {
451			printf("pppoe: tag 0x%x len 0x%x is too long\n",
452			    tag, len);
453			goto done;
454		}
455		switch (tag) {
456		case PPPOE_TAG_EOL:
457			goto breakbreak;
458		case PPPOE_TAG_SNAME:
459			break;	/* ignored */
460		case PPPOE_TAG_ACNAME:
461			break;	/* ignored */
462		case PPPOE_TAG_HUNIQUE:
463			if (sc != NULL)
464				break;
465			n = m_pulldown(m, off + sizeof(*pt), len, &noff);
466			if (!n) {
467				err_msg = "TAG HUNIQUE ERROR";
468				m = NULL;
469				goto done;
470			}
471			sc = pppoe_find_softc_by_hunique(mtod(n, caddr_t) + noff,
472			    len, m->m_pkthdr.rcvif);
473			break;
474		case PPPOE_TAG_ACCOOKIE:
475			if (ac_cookie == NULL) {
476				n = m_pulldown(m, off + sizeof(*pt), len,
477				    &noff);
478				if (!n) {
479					err_msg = "TAG ACCOOKIE ERROR";
480					m = NULL;
481					break;
482				}
483				ac_cookie = mtod(n, caddr_t) + noff;
484				ac_cookie_len = len;
485			}
486			break;
487		case PPPOE_TAG_SNAME_ERR:
488			err_msg = "SERVICE NAME ERROR";
489			break;
490		case PPPOE_TAG_ACSYS_ERR:
491			err_msg = "AC SYSTEM ERROR";
492			break;
493		case PPPOE_TAG_GENERIC_ERR:
494			err_msg = "GENERIC ERROR";
495			break;
496		}
497		if (err_msg) {
498			printf("%s: %s\n",
499			    sc ? sc->sc_sppp.pp_if.if_xname : "pppoe",
500			    err_msg);
501			goto done;
502		}
503		off += sizeof(*pt) + len;
504	}
505breakbreak:;
506	switch (ph->code) {
507	case PPPOE_CODE_PADI:
508	case PPPOE_CODE_PADR:
509		/* ignore, we are no access concentrator */
510		goto done;
511	case PPPOE_CODE_PADO:
512		if (sc == NULL) {
513			/* be quiet if there is not a single pppoe instance */
514			if (!LIST_EMPTY(&pppoe_softc_list))
515				printf("pppoe: received PADO but could not find request for it\n");
516			goto done;
517		}
518		if (sc->sc_state != PPPOE_STATE_PADI_SENT) {
519			printf("%s: received unexpected PADO\n",
520			    sc->sc_sppp.pp_if.if_xname);
521			goto done;
522		}
523		if (ac_cookie) {
524			if (sc->sc_ac_cookie)
525				free(sc->sc_ac_cookie, M_DEVBUF);
526			sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF,
527			    M_DONTWAIT);
528			if (sc->sc_ac_cookie == NULL)
529				goto done;
530			sc->sc_ac_cookie_len = ac_cookie_len;
531			memcpy(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
532		}
533		memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
534		callout_stop(&sc->sc_timeout);
535		sc->sc_padr_retried = 0;
536		sc->sc_state = PPPOE_STATE_PADR_SENT;
537		if (pppoe_send_padr(sc) == 0)
538			callout_reset(&sc->sc_timeout,
539			    PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried),
540			    pppoe_timeout, sc);
541		else
542			pppoe_abort_connect(sc);
543		break;
544	case PPPOE_CODE_PADS:
545		if (sc == NULL)
546			goto done;
547		sc->sc_session = session;
548		callout_stop(&sc->sc_timeout);
549		if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
550			printf("%s: session 0x%x connected\n",
551			    sc->sc_sppp.pp_if.if_xname, session);
552		sc->sc_state = PPPOE_STATE_SESSION;
553		sc->sc_sppp.pp_up(&sc->sc_sppp);	/* notify upper layers */
554		break;
555	case PPPOE_CODE_PADT:
556		if (sc == NULL)
557			goto done;
558		/* stop timer (we might be about to transmit a PADT ourself) */
559		callout_stop(&sc->sc_timeout);
560		if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
561			printf("%s: session 0x%x terminated, received PADT\n",
562			    sc->sc_sppp.pp_if.if_xname, session);
563		/* clean up softc */
564		sc->sc_state = PPPOE_STATE_INITIAL;
565		memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
566		if (sc->sc_ac_cookie) {
567			free(sc->sc_ac_cookie, M_DEVBUF);
568			sc->sc_ac_cookie = NULL;
569		}
570		sc->sc_ac_cookie_len = 0;
571		sc->sc_session = 0;
572		/* signal upper layer */
573		sc->sc_sppp.pp_down(&sc->sc_sppp);
574		break;
575	default:
576		printf("%s: unknown code (0x%04x) session = 0x%04x\n",
577		    sc? sc->sc_sppp.pp_if.if_xname : "pppoe",
578		    ph->code, session);
579		break;
580	}
581
582done:
583	m_freem(m);
584	return;
585}
586
587static void
588pppoe_disc_input(struct mbuf *m)
589{
590
591	/* avoid error messages if there is not a single pppoe instance */
592	if (!LIST_EMPTY(&pppoe_softc_list)) {
593		KASSERT(m->m_flags & M_PKTHDR);
594		pppoe_dispatch_disc_pkt(m, 0);
595	} else
596		m_freem(m);
597}
598
599static void
600pppoe_data_input(struct mbuf *m)
601{
602	u_int16_t session, plen;
603	struct pppoe_softc *sc;
604	struct pppoehdr *ph;
605#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
606	u_int8_t shost[ETHER_ADDR_LEN];
607#endif
608
609	KASSERT(m->m_flags & M_PKTHDR);
610
611#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
612	memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN);
613#endif
614	m_adj(m, sizeof(struct ether_header));
615	if (m->m_pkthdr.len <= PPPOE_HEADERLEN) {
616		printf("pppoe (data): dropping too short packet: %d bytes\n",
617		    m->m_pkthdr.len);
618		goto drop;
619	}
620
621	if (m->m_len < sizeof(*ph)) {
622		m = m_pullup(m, sizeof(*ph));
623		if (!m) {
624			printf("pppoe: could not get PPPoE header\n");
625			return;
626		}
627	}
628	ph = mtod(m, struct pppoehdr *);
629
630	if (ph->vertype != PPPOE_VERTYPE) {
631		printf("pppoe (data): unknown version/type packet: 0x%x\n",
632		    ph->vertype);
633		goto drop;
634	}
635	if (ph->code != 0)
636		goto drop;
637
638	session = ntohs(ph->session);
639	sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif);
640	if (sc == NULL) {
641#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
642		printf("pppoe: input for unknown session 0x%x, sending PADT\n",
643		    session);
644		pppoe_send_padt(m->m_pkthdr.rcvif, session, shost);
645#endif
646		goto drop;
647	}
648
649	plen = ntohs(ph->plen);
650
651#if NBPFILTER > 0
652	if(sc->sc_sppp.pp_if.if_bpf)
653		bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m);
654#endif
655
656	m_adj(m, PPPOE_HEADERLEN);
657
658#ifdef PPPOE_DEBUG
659	{
660		struct mbuf *p;
661
662		printf("%s: pkthdr.len=%d, pppoe.len=%d",
663			sc->sc_sppp.pp_if.if_xname,
664			m->m_pkthdr.len, plen);
665		p = m;
666		while (p) {
667			printf(" l=%d", p->m_len);
668			p = p->m_next;
669		}
670		printf("\n");
671	}
672#endif
673
674	if (m->m_pkthdr.len < plen)
675		goto drop;
676
677	/* fix incoming interface pointer (not the raw ethernet interface anymore) */
678	m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if;
679
680	/* pass packet up and account for it */
681	sc->sc_sppp.pp_if.if_ipackets++;
682	sppp_input(&sc->sc_sppp.pp_if, m);
683	return;
684
685drop:
686	m_freem(m);
687}
688
689static int
690pppoe_output(struct pppoe_softc *sc, struct mbuf *m)
691{
692	struct sockaddr dst;
693	struct ether_header *eh;
694	u_int16_t etype;
695
696	if (sc->sc_eth_if == NULL)
697		return EIO;
698
699	memset(&dst, 0, sizeof dst);
700	dst.sa_family = AF_UNSPEC;
701	eh = (struct ether_header*)&dst.sa_data;
702	etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC;
703	eh->ether_type = htons(etype);
704	memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest);
705
706#ifdef PPPOE_DEBUG
707	printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n",
708	    sc->sc_sppp.pp_if.if_xname, etype,
709	    sc->sc_state, sc->sc_session,
710	    ether_sprintf((const unsigned char *)&sc->sc_dest), m->m_pkthdr.len);
711#endif
712
713	m->m_flags &= ~(M_BCAST|M_MCAST);
714	sc->sc_sppp.pp_if.if_opackets++;
715	return sc->sc_eth_if->if_output(sc->sc_eth_if, m, &dst, NULL);
716}
717
718static int
719pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data)
720{
721	struct proc *p = curproc;	/* XXX */
722	struct pppoe_softc *sc = (struct pppoe_softc*)ifp;
723	int error = 0;
724
725	switch (cmd) {
726	case PPPOESETPARMS:
727	{
728		struct pppoediscparms *parms = (struct pppoediscparms*)data;
729		if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
730			return error;
731		if (parms->eth_ifname[0] != 0) {
732			sc->sc_eth_if = ifunit(parms->eth_ifname);
733			if (sc->sc_eth_if == NULL)
734				return ENXIO;
735		}
736		if (parms->ac_name) {
737			size_t s;
738			char * p = malloc(parms->ac_name_len + 1, M_DEVBUF, M_WAITOK);
739			copyinstr(parms->ac_name, p, parms->ac_name_len, &s);
740			if (sc->sc_concentrator_name)
741				free(sc->sc_concentrator_name, M_DEVBUF);
742			sc->sc_concentrator_name = p;
743		}
744		if (parms->service_name) {
745			size_t s;
746			char * p = malloc(parms->service_name_len + 1, M_DEVBUF, M_WAITOK);
747			copyinstr(parms->service_name, p, parms->service_name_len, &s);
748			if (sc->sc_service_name)
749				free(sc->sc_service_name, M_DEVBUF);
750			sc->sc_service_name = p;
751		}
752		return 0;
753	}
754	break;
755	case PPPOEGETPARMS:
756	{
757		struct pppoediscparms *parms = (struct pppoediscparms*)data;
758		memset(parms, 0, sizeof *parms);
759		if (sc->sc_eth_if)
760			strncpy(parms->ifname, sc->sc_eth_if->if_xname, IFNAMSIZ);
761		return 0;
762	}
763	break;
764	case PPPOEGETSESSION:
765	{
766		struct pppoeconnectionstate *state = (struct pppoeconnectionstate*)data;
767		state->state = sc->sc_state;
768		state->session_id = sc->sc_session;
769		state->padi_retry_no = sc->sc_padi_retried;
770		state->padr_retry_no = sc->sc_padr_retried;
771		return 0;
772	}
773	break;
774	case SIOCSIFFLAGS:
775	{
776		struct ifreq *ifr = (struct ifreq*) data;
777		/*
778		 * Prevent running re-establishment timers overriding
779		 * administrators choice.
780		 */
781		if ((ifr->ifr_flags & IFF_UP) == 0
782		     && sc->sc_state >= PPPOE_STATE_PADI_SENT
783		     && sc->sc_state < PPPOE_STATE_SESSION) {
784			callout_stop(&sc->sc_timeout);
785			sc->sc_state = PPPOE_STATE_INITIAL;
786			sc->sc_padi_retried = 0;
787			sc->sc_padr_retried = 0;
788			memcpy(&sc->sc_dest, etherbroadcastaddr,
789			    sizeof(sc->sc_dest));
790		}
791		return sppp_ioctl(ifp, cmd, data);
792	}
793	case SIOCSIFMTU:
794	{
795		struct ifreq *ifr = (struct ifreq*) data;
796
797		if (ifr->ifr_mtu > PPPOE_MAXMTU)
798			return EINVAL;
799		return sppp_ioctl(ifp, cmd, data);
800	}
801	default:
802		return sppp_ioctl(ifp, cmd, data);
803	}
804	return 0;
805}
806
807/*
808 * Allocate a mbuf/cluster with space to store the given data length
809 * of payload, leaving space for prepending an ethernet header
810 * in front.
811 */
812static struct mbuf *
813pppoe_get_mbuf(size_t len)
814{
815	struct mbuf *m;
816
817	MGETHDR(m, M_DONTWAIT, MT_DATA);
818	if (m == NULL)
819		return NULL;
820	if (len + sizeof(struct ether_header) > MHLEN) {
821		MCLGET(m, M_DONTWAIT);
822		if ((m->m_flags & M_EXT) == 0) {
823			struct mbuf *n;
824			MFREE(m, n);
825			return 0;
826		}
827	}
828	m->m_data += sizeof(struct ether_header);
829	m->m_len = len;
830	m->m_pkthdr.len = len;
831	m->m_pkthdr.rcvif = NULL;
832
833	return m;
834}
835
836static int
837pppoe_send_padi(struct pppoe_softc *sc)
838{
839	struct mbuf *m0;
840	int len, l1, l2;
841	u_int8_t *p;
842
843	if (sc->sc_state >PPPOE_STATE_PADI_SENT)
844		panic("pppoe_send_padi in state %d", sc->sc_state);
845
846	/* calculate length of frame (excluding ethernet header + pppoe header) */
847	len = 2 + 2 + 2 + 2 + sizeof sc;	/* service name tag is required, host unique is send too */
848	if (sc->sc_service_name != NULL) {
849		l1 = strlen(sc->sc_service_name);
850		len += l1;
851	}
852	if (sc->sc_concentrator_name != NULL) {
853		l2 = strlen(sc->sc_concentrator_name);
854		len += 2 + 2 + l2;
855	}
856
857	/* allocate a buffer */
858	m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);	/* header len + payload len */
859	if (!m0)
860		return ENOBUFS;
861
862	/* fill in pkt */
863	p = mtod(m0, u_int8_t *);
864	PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len);
865	PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
866	if (sc->sc_service_name != NULL) {
867		PPPOE_ADD_16(p, l1);
868		memcpy(p, sc->sc_service_name, l1);
869		p += l1;
870	} else {
871		PPPOE_ADD_16(p, 0);
872	}
873	if (sc->sc_concentrator_name != NULL) {
874		PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
875		PPPOE_ADD_16(p, l2);
876		memcpy(p, sc->sc_concentrator_name, l2);
877		p += l2;
878	}
879	PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
880	PPPOE_ADD_16(p, sizeof(sc));
881	memcpy(p, &sc, sizeof sc);
882
883#ifdef PPPOE_DEBUG
884	p += sizeof sc;
885	if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN)
886		panic("pppoe_send_padi: garbled output len, should be %ld, is %ld",
887		    (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *)));
888#endif
889
890	/* send pkt */
891	return pppoe_output(sc, m0);
892}
893
894static void
895pppoe_timeout(void *arg)
896{
897	int x, retry_wait;
898	struct pppoe_softc *sc = (struct pppoe_softc*)arg;
899
900#ifdef PPPOE_DEBUG
901	printf("%s: timeout\n", sc->sc_sppp.pp_if.if_xname);
902#endif
903
904	switch (sc->sc_state) {
905	case PPPOE_STATE_PADI_SENT:
906		/*
907		 * We have two basic ways of retrying:
908		 *  - Quick retry mode: try a few times in short sequence
909		 *  - Slow retry mode: we already had a connection successfully
910		 *    established and will try infinitely (without user
911		 *    intervention)
912		 * We only enter slow retry mode if IFF_LINK1 (aka autodial)
913		 * is not set.
914		 */
915
916		/* initialize for quick retry mode */
917		retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried);
918
919		x = splnet();
920		sc->sc_padi_retried++;
921		if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) {
922			if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) {
923				/* slow retry mode */
924				retry_wait = PPPOE_SLOW_RETRY;
925			} else {
926				pppoe_abort_connect(sc);
927				splx(x);
928				return;
929			}
930		}
931		if (pppoe_send_padi(sc) == 0)
932			callout_reset(&sc->sc_timeout, retry_wait,
933			    pppoe_timeout, sc);
934		else
935			pppoe_abort_connect(sc);
936		splx(x);
937		break;
938
939	case PPPOE_STATE_PADR_SENT:
940		x = splnet();
941		sc->sc_padr_retried++;
942		if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) {
943			memcpy(&sc->sc_dest, etherbroadcastaddr,
944			    sizeof(sc->sc_dest));
945			sc->sc_state = PPPOE_STATE_PADI_SENT;
946			sc->sc_padr_retried = 0;
947			if (pppoe_send_padi(sc) == 0)
948				callout_reset(&sc->sc_timeout,
949				    PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried),
950				    pppoe_timeout, sc);
951			else
952				pppoe_abort_connect(sc);
953			splx(x);
954			return;
955		}
956		if (pppoe_send_padr(sc) == 0)
957			callout_reset(&sc->sc_timeout,
958			    PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried),
959			    pppoe_timeout, sc);
960		else
961			pppoe_abort_connect(sc);
962		splx(x);
963		break;
964	case PPPOE_STATE_CLOSING:
965		pppoe_disconnect(sc);
966		break;
967	default:
968		return;	/* all done, work in peace */
969	}
970}
971
972/* Start a connection (i.e. initiate discovery phase) */
973static int
974pppoe_connect(struct pppoe_softc *sc)
975{
976	int x, err, retry;
977
978	if (sc->sc_state != PPPOE_STATE_INITIAL)
979		return EBUSY;
980
981	x = splnet();
982	/* save state, in case we fail to send PADI */
983	retry =	sc->sc_padr_retried;
984	sc->sc_state = PPPOE_STATE_PADI_SENT;
985	sc->sc_padr_retried = 0;
986	err = pppoe_send_padi(sc);
987	if (err != 0) {
988		/*
989		 * We failed to send a single PADI packet.
990		 * This is unfortunate, because we have no good way to recover
991		 * from here.
992		 */
993
994		/* recover state and return the error */
995		sc->sc_state = PPPOE_STATE_INITIAL;
996		sc->sc_padr_retried = retry;
997	} else {
998		callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT,
999		    pppoe_timeout, sc);
1000	}
1001	splx(x);
1002	return err;
1003}
1004
1005/* disconnect */
1006static int
1007pppoe_disconnect(struct pppoe_softc *sc)
1008{
1009	int err, x;
1010
1011	x = splnet();
1012
1013	if (sc->sc_state < PPPOE_STATE_SESSION)
1014		err = EBUSY;
1015	else {
1016		if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1017			printf("%s: disconnecting\n",
1018			    sc->sc_sppp.pp_if.if_xname);
1019		err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const u_int8_t *)&sc->sc_dest);
1020	}
1021
1022	/* cleanup softc */
1023	sc->sc_state = PPPOE_STATE_INITIAL;
1024	memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
1025	if (sc->sc_ac_cookie) {
1026		free(sc->sc_ac_cookie, M_DEVBUF);
1027		sc->sc_ac_cookie = NULL;
1028	}
1029	sc->sc_ac_cookie_len = 0;
1030	sc->sc_session = 0;
1031
1032	/* notify upper layer */
1033	sc->sc_sppp.pp_down(&sc->sc_sppp);
1034
1035	splx(x);
1036
1037	return err;
1038}
1039
1040/* Connection attempt aborted */
1041static void
1042pppoe_abort_connect(struct pppoe_softc *sc)
1043{
1044	printf("%s: could not establish connection\n",
1045		sc->sc_sppp.pp_if.if_xname);
1046	sc->sc_state = PPPOE_STATE_CLOSING;
1047
1048	/* notify upper layer */
1049	sc->sc_sppp.pp_down(&sc->sc_sppp);
1050
1051	/* clear connection state */
1052	memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
1053	sc->sc_state = PPPOE_STATE_INITIAL;
1054}
1055
1056/* Send a PADR packet */
1057static int
1058pppoe_send_padr(struct pppoe_softc *sc)
1059{
1060	struct mbuf *m0;
1061	u_int8_t *p;
1062	size_t len, l1;
1063
1064	if (sc->sc_state != PPPOE_STATE_PADR_SENT)
1065		return EIO;
1066
1067	len = 2 + 2 + 2 + 2 + sizeof(sc);		/* service name, host unique */
1068	if (sc->sc_service_name != NULL) {		/* service name tag maybe empty */
1069		l1 = strlen(sc->sc_service_name);
1070		len += l1;
1071	}
1072	if (sc->sc_ac_cookie_len > 0)
1073		len += 2 + 2 + sc->sc_ac_cookie_len;	/* AC cookie */
1074	m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
1075	if (!m0)
1076		return ENOBUFS;
1077	p = mtod(m0, u_int8_t *);
1078	PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
1079	PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
1080	if (sc->sc_service_name != NULL) {
1081		PPPOE_ADD_16(p, l1);
1082		memcpy(p, sc->sc_service_name, l1);
1083		p += l1;
1084	} else {
1085		PPPOE_ADD_16(p, 0);
1086	}
1087	if (sc->sc_ac_cookie_len > 0) {
1088		PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
1089		PPPOE_ADD_16(p, sc->sc_ac_cookie_len);
1090		memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len);
1091		p += sc->sc_ac_cookie_len;
1092	}
1093	PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
1094	PPPOE_ADD_16(p, sizeof(sc));
1095	memcpy(p, &sc, sizeof sc);
1096
1097#ifdef PPPOE_DEBUG
1098	p += sizeof sc;
1099	if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN)
1100		panic("pppoe_send_padr: garbled output len, should be %ld, is %ld",
1101			(long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *)));
1102#endif
1103
1104	return pppoe_output(sc, m0);
1105}
1106
1107/* send a PADT packet */
1108static int
1109pppoe_send_padt(struct ifnet *outgoing_if, u_int session, const u_int8_t *dest)
1110{
1111	struct ether_header *eh;
1112	struct sockaddr dst;
1113	struct mbuf *m0;
1114	u_int8_t *p;
1115
1116	m0 = pppoe_get_mbuf(PPPOE_HEADERLEN);
1117	if (!m0)
1118		return EIO;
1119	p = mtod(m0, u_int8_t *);
1120	PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0);
1121
1122	memset(&dst, 0, sizeof dst);
1123	dst.sa_family = AF_UNSPEC;
1124	eh = (struct ether_header*)&dst.sa_data;
1125	eh->ether_type = htons(ETHERTYPE_PPPOEDISC);
1126	memcpy(&eh->ether_dhost, dest, ETHER_ADDR_LEN);
1127
1128	m0->m_flags &= ~(M_BCAST|M_MCAST);
1129	return outgoing_if->if_output(outgoing_if, m0, &dst, NULL);
1130}
1131
1132static void
1133pppoe_tls(struct sppp *sp)
1134{
1135	struct pppoe_softc *sc = (void *)sp;
1136	if (sc->sc_state != PPPOE_STATE_INITIAL)
1137		return;
1138	pppoe_connect(sc);
1139}
1140
1141static void
1142pppoe_tlf(struct sppp *sp)
1143{
1144	struct pppoe_softc *sc = (void *)sp;
1145	if (sc->sc_state < PPPOE_STATE_SESSION)
1146		return;
1147	/*
1148	 * Do not call pppoe_disconnect here, the upper layer state
1149	 * machine gets confused by this. We must return from this
1150	 * function and defer disconnecting to the timeout handler.
1151	 */
1152	sc->sc_state = PPPOE_STATE_CLOSING;
1153	callout_reset(&sc->sc_timeout, hz/50, pppoe_timeout, sc);
1154}
1155
1156static void
1157pppoe_start(struct ifnet *ifp)
1158{
1159	struct pppoe_softc *sc = (void *)ifp;
1160	struct mbuf *m;
1161	u_int8_t *p;
1162	size_t len;
1163
1164	if (sppp_isempty(ifp))
1165		return;
1166
1167	/* are we ready to proccess data yet? */
1168	if (sc->sc_state < PPPOE_STATE_SESSION) {
1169		sppp_flush(&sc->sc_sppp.pp_if);
1170		return;
1171	}
1172
1173	while ((m = sppp_dequeue(ifp)) != NULL) {
1174		len = m->m_pkthdr.len;
1175		M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT);
1176		if (m == NULL) {
1177			ifp->if_oerrors++;
1178			continue;
1179		}
1180		p = mtod(m, u_int8_t *);
1181		PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
1182
1183#if NBPFILTER > 0
1184		if(sc->sc_sppp.pp_if.if_bpf)
1185			bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m);
1186#endif
1187
1188		pppoe_output(sc, m);
1189	}
1190}
1191