if_pppoe.c revision 1.74
1/* $NetBSD: if_pppoe.c,v 1.74 2006/10/25 20:28:45 elad 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.74 2006/10/25 20:28:45 elad Exp $");
41
42#include "pppoe.h"
43#include "bpfilter.h"
44#include "opt_pfil_hooks.h"
45#include "opt_pppoe.h"
46
47#include <sys/param.h>
48#include <sys/systm.h>
49#include <sys/kernel.h>
50#include <sys/callout.h>
51#include <sys/malloc.h>
52#include <sys/mbuf.h>
53#include <sys/socket.h>
54#include <sys/proc.h>
55#include <sys/ioctl.h>
56#include <sys/kauth.h>
57#include <net/if.h>
58#include <net/if_types.h>
59#include <net/if_ether.h>
60#include <net/if_sppp.h>
61#include <net/if_spppvar.h>
62#include <net/if_pppoe.h>
63
64#if NBPFILTER > 0
65#include <net/bpf.h>
66#endif
67
68#include <machine/intr.h>
69
70#undef PPPOE_DEBUG		/* XXX - remove this or make it an option */
71/* #define PPPOE_DEBUG 1 */
72
73struct pppoehdr {
74	u_int8_t vertype;
75	u_int8_t code;
76	u_int16_t session;
77	u_int16_t plen;
78} __attribute__((__packed__));
79
80struct pppoetag {
81	u_int16_t tag;
82	u_int16_t len;
83} __attribute__((__packed__));
84
85#define PPPOE_HEADERLEN	sizeof(struct pppoehdr)
86#define	PPPOE_OVERHEAD	(PPPOE_HEADERLEN + 2)
87#define	PPPOE_VERTYPE	0x11	/* VER=1, TYPE = 1 */
88
89#define	PPPOE_TAG_EOL		0x0000		/* end of list */
90#define	PPPOE_TAG_SNAME		0x0101		/* service name */
91#define	PPPOE_TAG_ACNAME	0x0102		/* access concentrator name */
92#define	PPPOE_TAG_HUNIQUE	0x0103		/* host unique */
93#define	PPPOE_TAG_ACCOOKIE	0x0104		/* AC cookie */
94#define	PPPOE_TAG_VENDOR	0x0105		/* vendor specific */
95#define	PPPOE_TAG_RELAYSID	0x0110		/* relay session id */
96#define	PPPOE_TAG_SNAME_ERR	0x0201		/* service name error */
97#define	PPPOE_TAG_ACSYS_ERR	0x0202		/* AC system error */
98#define	PPPOE_TAG_GENERIC_ERR	0x0203		/* gerneric error */
99
100#define PPPOE_CODE_PADI		0x09		/* Active Discovery Initiation */
101#define	PPPOE_CODE_PADO		0x07		/* Active Discovery Offer */
102#define	PPPOE_CODE_PADR		0x19		/* Active Discovery Request */
103#define	PPPOE_CODE_PADS		0x65		/* Active Discovery Session confirmation */
104#define	PPPOE_CODE_PADT		0xA7		/* Active Discovery Terminate */
105
106/* two byte PPP protocol discriminator, then IP data */
107#define	PPPOE_MAXMTU	(ETHERMTU - PPPOE_OVERHEAD)
108
109/* Add a 16 bit unsigned value to a buffer pointed to by PTR */
110#define	PPPOE_ADD_16(PTR, VAL)			\
111		*(PTR)++ = (VAL) / 256;		\
112		*(PTR)++ = (VAL) % 256
113
114/* Add a complete PPPoE header to the buffer pointed to by PTR */
115#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN)	\
116		*(PTR)++ = PPPOE_VERTYPE;	\
117		*(PTR)++ = (CODE);		\
118		PPPOE_ADD_16(PTR, SESS);	\
119		PPPOE_ADD_16(PTR, LEN)
120
121#define	PPPOE_DISC_TIMEOUT	(hz*5)	/* base for quick timeout calculation */
122#define	PPPOE_SLOW_RETRY	(hz*60)	/* persistent retry interval */
123#define PPPOE_DISC_MAXPADI	4	/* retry PADI four times (quickly) */
124#define	PPPOE_DISC_MAXPADR	2	/* retry PADR twice */
125
126#ifdef PPPOE_SERVER
127/* from if_spppsubr.c */
128#define IFF_PASSIVE	IFF_LINK0	/* wait passively for connection */
129#endif
130
131struct pppoe_softc {
132	struct sppp sc_sppp;		/* contains a struct ifnet as first element */
133	LIST_ENTRY(pppoe_softc) sc_list;
134	struct ifnet *sc_eth_if;	/* ethernet interface we are using */
135
136	int sc_state;			/* discovery phase or session connected */
137	struct ether_addr sc_dest;	/* hardware address of concentrator */
138	u_int16_t sc_session;		/* PPPoE session id */
139
140	char *sc_service_name;		/* if != NULL: requested name of service */
141	char *sc_concentrator_name;	/* if != NULL: requested concentrator id */
142	u_int8_t *sc_ac_cookie;		/* content of AC cookie we must echo back */
143	size_t sc_ac_cookie_len;	/* length of cookie data */
144#ifdef PPPOE_SERVER
145	u_int8_t *sc_hunique;		/* content of host unique we must echo back */
146	size_t sc_hunique_len;		/* length of host unique */
147#endif
148	struct callout sc_timeout;	/* timeout while not in session state */
149	int sc_padi_retried;		/* number of PADI retries already done */
150	int sc_padr_retried;		/* number of PADR retries already done */
151};
152
153/* incoming traffic will be queued here */
154struct ifqueue ppoediscinq = { .ifq_maxlen = IFQ_MAXLEN };
155struct ifqueue ppoeinq = { .ifq_maxlen = IFQ_MAXLEN };
156
157#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
158void * pppoe_softintr = NULL;
159static void pppoe_softintr_handler(void *);
160#else
161struct callout pppoe_softintr = CALLOUT_INITIALIZER;
162void pppoe_softintr_handler(void *);
163#endif
164
165extern int sppp_ioctl(struct ifnet *, unsigned long, void *);
166
167/* input routines */
168static void pppoe_input(void);
169static void pppoe_disc_input(struct mbuf *);
170static void pppoe_dispatch_disc_pkt(struct mbuf *, int);
171static void pppoe_data_input(struct mbuf *);
172
173/* management routines */
174void pppoeattach(int);
175static int pppoe_connect(struct pppoe_softc *);
176static int pppoe_disconnect(struct pppoe_softc *);
177static void pppoe_abort_connect(struct pppoe_softc *);
178static int pppoe_ioctl(struct ifnet *, unsigned long, caddr_t);
179static void pppoe_tls(struct sppp *);
180static void pppoe_tlf(struct sppp *);
181static void pppoe_start(struct ifnet *);
182static void pppoe_clear_softc(struct pppoe_softc *, const char *);
183
184/* internal timeout handling */
185static void pppoe_timeout(void *);
186
187/* sending actual protocol controll packets */
188static int pppoe_send_padi(struct pppoe_softc *);
189static int pppoe_send_padr(struct pppoe_softc *);
190#ifdef PPPOE_SERVER
191static int pppoe_send_pado(struct pppoe_softc *);
192static int pppoe_send_pads(struct pppoe_softc *);
193#endif
194static int pppoe_send_padt(struct ifnet *, u_int, const u_int8_t *);
195
196/* raw output */
197static int pppoe_output(struct pppoe_softc *, struct mbuf *);
198
199/* internal helper functions */
200static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *);
201static struct pppoe_softc * pppoe_find_softc_by_hunique(u_int8_t *, size_t, struct ifnet *);
202static struct mbuf *pppoe_get_mbuf(size_t len);
203
204#ifdef PFIL_HOOKS
205static int pppoe_ifattach_hook(void *, struct mbuf **, struct ifnet *, int);
206#endif
207
208static LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list;
209
210static int	pppoe_clone_create(struct if_clone *, int);
211static int	pppoe_clone_destroy(struct ifnet *);
212
213static struct if_clone pppoe_cloner =
214    IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy);
215
216/* ARGSUSED */
217void
218pppoeattach(int count __unused)
219{
220	LIST_INIT(&pppoe_softc_list);
221	if_clone_attach(&pppoe_cloner);
222
223#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
224	pppoe_softintr = softintr_establish(IPL_SOFTNET, pppoe_softintr_handler, NULL);
225#endif
226}
227
228static int
229pppoe_clone_create(struct if_clone *ifc __unused, int unit)
230{
231	struct pppoe_softc *sc;
232
233	sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK);
234	memset(sc, 0, sizeof(struct pppoe_softc));
235
236	snprintf(sc->sc_sppp.pp_if.if_xname, sizeof(sc->sc_sppp.pp_if.if_xname),
237	    "pppoe%d", unit);
238	sc->sc_sppp.pp_if.if_softc = sc;
239	sc->sc_sppp.pp_if.if_mtu = PPPOE_MAXMTU;
240	sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX|IFF_POINTOPOINT|IFF_MULTICAST;
241	sc->sc_sppp.pp_if.if_type = IFT_PPP;
242	sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN;
243	sc->sc_sppp.pp_if.if_dlt = DLT_PPP_ETHER;
244	sc->sc_sppp.pp_flags |= PP_KEEPALIVE |	/* use LCP keepalive */
245				PP_NOFRAMING;	/* no serial encapsulation */
246	sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl;
247	IFQ_SET_MAXLEN(&sc->sc_sppp.pp_if.if_snd, IFQ_MAXLEN);
248	IFQ_SET_READY(&sc->sc_sppp.pp_if.if_snd);
249
250	/* changed to real address later */
251	memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
252
253	callout_init(&sc->sc_timeout);
254
255	sc->sc_sppp.pp_if.if_start = pppoe_start;
256	sc->sc_sppp.pp_tls = pppoe_tls;
257	sc->sc_sppp.pp_tlf = pppoe_tlf;
258	sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN;	/* framing added to ppp packets */
259
260	if_attach(&sc->sc_sppp.pp_if);
261	sppp_attach(&sc->sc_sppp.pp_if);
262
263#if NBPFILTER > 0
264	bpfattach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0);
265#endif
266#ifdef PFIL_HOOKS
267	if (LIST_EMPTY(&pppoe_softc_list))
268		pfil_add_hook(pppoe_ifattach_hook, NULL,
269		    PFIL_IFNET|PFIL_WAITOK, &if_pfil);
270#endif
271	LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list);
272	return 0;
273}
274
275static int
276pppoe_clone_destroy(struct ifnet *ifp)
277{
278	struct pppoe_softc * sc = ifp->if_softc;
279
280	callout_stop(&sc->sc_timeout);
281	LIST_REMOVE(sc, sc_list);
282#ifdef PFIL_HOOKS
283	if (LIST_EMPTY(&pppoe_softc_list))
284		pfil_remove_hook(pppoe_ifattach_hook, NULL,
285		    PFIL_IFNET|PFIL_WAITOK, &if_pfil);
286#endif
287#if NBPFILTER > 0
288	bpfdetach(ifp);
289#endif
290	sppp_detach(&sc->sc_sppp.pp_if);
291	if_detach(ifp);
292	if (sc->sc_concentrator_name)
293		free(sc->sc_concentrator_name, M_DEVBUF);
294	if (sc->sc_service_name)
295		free(sc->sc_service_name, M_DEVBUF);
296	if (sc->sc_ac_cookie)
297		free(sc->sc_ac_cookie, M_DEVBUF);
298	free(sc, M_DEVBUF);
299
300	return (0);
301}
302
303/*
304 * Find the interface handling the specified session.
305 * Note: O(number of sessions open), this is a client-side only, mean
306 * and lean implementation, so number of open sessions typically should
307 * be 1.
308 */
309static struct pppoe_softc *
310pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif)
311{
312	struct pppoe_softc *sc;
313
314	if (session == 0)
315		return NULL;
316
317	LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
318		if (sc->sc_state == PPPOE_STATE_SESSION
319		    && sc->sc_session == session) {
320			if (sc->sc_eth_if == rcvif)
321				return sc;
322			else
323				return NULL;
324		}
325	}
326	return NULL;
327}
328
329/* Check host unique token passed and return appropriate softc pointer,
330 * or NULL if token is bogus. */
331static struct pppoe_softc *
332pppoe_find_softc_by_hunique(u_int8_t *token, size_t len, struct ifnet *rcvif)
333{
334	struct pppoe_softc *sc, *t;
335
336	if (LIST_EMPTY(&pppoe_softc_list))
337		return NULL;
338
339	if (len != sizeof sc)
340		return NULL;
341	memcpy(&t, token, len);
342
343	LIST_FOREACH(sc, &pppoe_softc_list, sc_list)
344		if (sc == t) break;
345
346	if (sc == NULL) {
347#ifdef PPPOE_DEBUG
348		printf("pppoe: alien host unique tag, no session found\n");
349#endif
350		return NULL;
351	}
352
353	/* should be safe to access *sc now */
354	if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) {
355		printf("%s: host unique tag found, but it belongs to a connection in state %d\n",
356			sc->sc_sppp.pp_if.if_xname, sc->sc_state);
357		return NULL;
358	}
359	if (sc->sc_eth_if != rcvif) {
360		printf("%s: wrong interface, not accepting host unique\n",
361			sc->sc_sppp.pp_if.if_xname);
362		return NULL;
363	}
364	return sc;
365}
366
367#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
368static void
369pppoe_softintr_handler(void *dummy __unused)
370{
371	/* called at splsoftnet() */
372	pppoe_input();
373}
374#else
375void
376pppoe_softintr_handler(void *dummy)
377{
378	int s = splnet();
379	pppoe_input();
380	splx(s);
381}
382#endif
383
384/* called at appropriate protection level */
385static void
386pppoe_input(void)
387{
388	struct mbuf *m;
389	int s, disc_done, data_done;
390
391	do {
392		disc_done = 0;
393		data_done = 0;
394		for (;;) {
395			s = splnet();
396			IF_DEQUEUE(&ppoediscinq, m);
397			splx(s);
398			if (m == NULL) break;
399			disc_done = 1;
400			pppoe_disc_input(m);
401		}
402
403		for (;;) {
404			s = splnet();
405			IF_DEQUEUE(&ppoeinq, m);
406			splx(s);
407			if (m == NULL) break;
408			data_done = 1;
409			pppoe_data_input(m);
410		}
411	} while (disc_done || data_done);
412}
413
414/* analyze and handle a single received packet while not in session state */
415static void
416pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
417{
418	u_int16_t tag, len;
419	u_int16_t session, plen;
420	struct pppoe_softc *sc;
421	const char *err_msg, *devname;
422	char *error;
423	u_int8_t *ac_cookie;
424	size_t ac_cookie_len;
425#ifdef PPPOE_SERVER
426	u_int8_t *hunique;
427	size_t hunique_len;
428#endif
429	struct pppoehdr *ph;
430	struct pppoetag *pt;
431	struct mbuf *n;
432	int noff, err, errortag;
433	struct ether_header *eh;
434
435	devname = "pppoe";	/* as long as we don't know which instance */
436	err_msg = NULL;
437	errortag = 0;
438	if (m->m_len < sizeof(*eh)) {
439		m = m_pullup(m, sizeof(*eh));
440		if (!m)
441			goto done;
442	}
443	eh = mtod(m, struct ether_header *);
444	off += sizeof(*eh);
445
446	ac_cookie = NULL;
447	ac_cookie_len = 0;
448#ifdef PPPOE_SERVER
449	hunique = NULL;
450	hunique_len = 0;
451#endif
452	session = 0;
453	if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) {
454		printf("pppoe: packet too short: %d\n", m->m_pkthdr.len);
455		goto done;
456	}
457
458	n = m_pulldown(m, off, sizeof(*ph), &noff);
459	if (!n) {
460		printf("pppoe: could not get PPPoE header\n");
461		m = NULL;
462		goto done;
463	}
464	ph = (struct pppoehdr *)(mtod(n, caddr_t) + noff);
465	if (ph->vertype != PPPOE_VERTYPE) {
466		printf("pppoe: unknown version/type packet: 0x%x\n",
467		    ph->vertype);
468		goto done;
469	}
470	session = ntohs(ph->session);
471	plen = ntohs(ph->plen);
472	off += sizeof(*ph);
473
474	if (plen + off > m->m_pkthdr.len) {
475		printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n",
476		    m->m_pkthdr.len - off, plen);
477		goto done;
478	}
479	m_adj(m, off + plen - m->m_pkthdr.len);	/* ignore trailing garbage */
480	tag = 0;
481	len = 0;
482	sc = NULL;
483	while (off + sizeof(*pt) <= m->m_pkthdr.len) {
484		n = m_pulldown(m, off, sizeof(*pt), &noff);
485		if (!n) {
486			printf("%s: parse error\n", devname);
487			m = NULL;
488			goto done;
489		}
490		pt = (struct pppoetag *)(mtod(n, caddr_t) + noff);
491		tag = ntohs(pt->tag);
492		len = ntohs(pt->len);
493		if (off + len > m->m_pkthdr.len) {
494			printf("pppoe: tag 0x%x len 0x%x is too long\n",
495			    tag, len);
496			goto done;
497		}
498		switch (tag) {
499		case PPPOE_TAG_EOL:
500			goto breakbreak;
501		case PPPOE_TAG_SNAME:
502			break;	/* ignored */
503		case PPPOE_TAG_ACNAME:
504			break;	/* ignored */
505		case PPPOE_TAG_HUNIQUE:
506			if (sc != NULL)
507				break;
508			n = m_pulldown(m, off + sizeof(*pt), len, &noff);
509			if (!n) {
510				m = NULL;
511				err_msg = "TAG HUNIQUE ERROR";
512				break;
513			}
514#ifdef PPPOE_SERVER
515			hunique = mtod(n, caddr_t) + noff;
516			hunique_len = len;
517#endif
518			sc = pppoe_find_softc_by_hunique(mtod(n, caddr_t) + noff,
519			    len, m->m_pkthdr.rcvif);
520			if (sc != NULL)
521				devname = sc->sc_sppp.pp_if.if_xname;
522			break;
523		case PPPOE_TAG_ACCOOKIE:
524			if (ac_cookie == NULL) {
525				n = m_pulldown(m, off + sizeof(*pt), len,
526				    &noff);
527				if (!n) {
528					err_msg = "TAG ACCOOKIE ERROR";
529					m = NULL;
530					break;
531				}
532				ac_cookie = mtod(n, caddr_t) + noff;
533				ac_cookie_len = len;
534			}
535			break;
536		case PPPOE_TAG_SNAME_ERR:
537			err_msg = "SERVICE NAME ERROR";
538			errortag = 1;
539			break;
540		case PPPOE_TAG_ACSYS_ERR:
541			err_msg = "AC SYSTEM ERROR";
542			errortag = 1;
543			break;
544		case PPPOE_TAG_GENERIC_ERR:
545			err_msg = "GENERIC ERROR";
546			errortag = 1;
547			break;
548		}
549		if (err_msg) {
550			error = NULL;
551			if (errortag && len) {
552				error = malloc(len+1, M_TEMP, M_NOWAIT);
553				n = m_pulldown(m, off + sizeof(*pt), len,
554				    &noff);
555				if (n && error) {
556					strncpy(error,
557					    mtod(n, caddr_t) + noff, len);
558					error[len-1] = '\0';
559				}
560			}
561			if (error) {
562				printf("%s: %s: %s\n", devname,
563				    err_msg, error);
564				free(error, M_TEMP);
565			} else
566				printf("%s: %s\n", devname, err_msg);
567			if (errortag)
568				goto done;
569		}
570		off += sizeof(*pt) + len;
571	}
572breakbreak:;
573	switch (ph->code) {
574	case PPPOE_CODE_PADI:
575#ifdef PPPOE_SERVER
576		/*
577		 * got service name, concentrator name, and/or host unique.
578		 * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP.
579		 */
580		if (LIST_EMPTY(&pppoe_softc_list))
581			goto done;
582		LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
583			if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP))
584				continue;
585			if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE))
586				continue;
587			if (sc->sc_state == PPPOE_STATE_INITIAL)
588				break;
589		}
590		if (sc == NULL) {
591/*			printf("pppoe: free passive interface is not found\n");*/
592			goto done;
593		}
594		if (hunique) {
595			if (sc->sc_hunique)
596				free(sc->sc_hunique, M_DEVBUF);
597			sc->sc_hunique = malloc(hunique_len, M_DEVBUF,
598			    M_DONTWAIT);
599			if (sc->sc_hunique == NULL)
600				goto done;
601			sc->sc_hunique_len = hunique_len;
602			memcpy(sc->sc_hunique, hunique, hunique_len);
603		}
604		memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
605		sc->sc_state = PPPOE_STATE_PADO_SENT;
606		pppoe_send_pado(sc);
607		break;
608#endif /* PPPOE_SERVER */
609	case PPPOE_CODE_PADR:
610#ifdef PPPOE_SERVER
611		/*
612		 * get sc from ac_cookie if IFF_PASSIVE
613		 */
614		if (ac_cookie == NULL) {
615			/* be quiet if there is not a single pppoe instance */
616			printf("pppoe: received PADR but not includes ac_cookie\n");
617			goto done;
618		}
619		sc = pppoe_find_softc_by_hunique(ac_cookie,
620						 ac_cookie_len,
621						 m->m_pkthdr.rcvif);
622		if (sc == NULL) {
623			/* be quiet if there is not a single pppoe instance */
624			if (!LIST_EMPTY(&pppoe_softc_list))
625				printf("pppoe: received PADR but could not find request for it\n");
626			goto done;
627		}
628		if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
629			printf("%s: received unexpected PADR\n",
630			    sc->sc_sppp.pp_if.if_xname);
631			goto done;
632		}
633		if (hunique) {
634			if (sc->sc_hunique)
635				free(sc->sc_hunique, M_DEVBUF);
636			sc->sc_hunique = malloc(hunique_len, M_DEVBUF,
637			    M_DONTWAIT);
638			if (sc->sc_hunique == NULL)
639				goto done;
640			sc->sc_hunique_len = hunique_len;
641			memcpy(sc->sc_hunique, hunique, hunique_len);
642		}
643		pppoe_send_pads(sc);
644		sc->sc_state = PPPOE_STATE_SESSION;
645		sc->sc_sppp.pp_up(&sc->sc_sppp);
646		break;
647#else
648		/* ignore, we are no access concentrator */
649		goto done;
650#endif /* PPPOE_SERVER */
651	case PPPOE_CODE_PADO:
652		if (sc == NULL) {
653			/* be quiet if there is not a single pppoe instance */
654			if (!LIST_EMPTY(&pppoe_softc_list))
655				printf("pppoe: received PADO but could not find request for it\n");
656			goto done;
657		}
658		if (sc->sc_state != PPPOE_STATE_PADI_SENT) {
659			printf("%s: received unexpected PADO\n",
660			    sc->sc_sppp.pp_if.if_xname);
661			goto done;
662		}
663		if (ac_cookie) {
664			if (sc->sc_ac_cookie)
665				free(sc->sc_ac_cookie, M_DEVBUF);
666			sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF,
667			    M_DONTWAIT);
668			if (sc->sc_ac_cookie == NULL)
669				goto done;
670			sc->sc_ac_cookie_len = ac_cookie_len;
671			memcpy(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
672		}
673		memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
674		callout_stop(&sc->sc_timeout);
675		sc->sc_padr_retried = 0;
676		sc->sc_state = PPPOE_STATE_PADR_SENT;
677		if ((err = pppoe_send_padr(sc)) != 0) {
678			if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
679				printf("%s: failed to send PADR, "
680				    "error=%d\n", sc->sc_sppp.pp_if.if_xname,
681				    err);
682		}
683		callout_reset(&sc->sc_timeout,
684		    PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried),
685		    pppoe_timeout, sc);
686		break;
687	case PPPOE_CODE_PADS:
688		if (sc == NULL)
689			goto done;
690		sc->sc_session = session;
691		callout_stop(&sc->sc_timeout);
692		if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
693			printf("%s: session 0x%x connected\n",
694			    sc->sc_sppp.pp_if.if_xname, session);
695		sc->sc_state = PPPOE_STATE_SESSION;
696		sc->sc_sppp.pp_up(&sc->sc_sppp);	/* notify upper layers */
697		break;
698	case PPPOE_CODE_PADT:
699		if (sc == NULL)
700			goto done;
701		pppoe_clear_softc(sc, "received PADT");
702		break;
703	default:
704		printf("%s: unknown code (0x%04x) session = 0x%04x\n",
705		    sc? sc->sc_sppp.pp_if.if_xname : "pppoe",
706		    ph->code, session);
707		break;
708	}
709
710done:
711	if (m)
712		m_freem(m);
713	return;
714}
715
716static void
717pppoe_disc_input(struct mbuf *m)
718{
719
720	/* avoid error messages if there is not a single pppoe instance */
721	if (!LIST_EMPTY(&pppoe_softc_list)) {
722		KASSERT(m->m_flags & M_PKTHDR);
723		pppoe_dispatch_disc_pkt(m, 0);
724	} else
725		m_freem(m);
726}
727
728static void
729pppoe_data_input(struct mbuf *m)
730{
731	u_int16_t session, plen;
732	struct pppoe_softc *sc;
733	struct pppoehdr *ph;
734#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
735	u_int8_t shost[ETHER_ADDR_LEN];
736#endif
737
738	KASSERT(m->m_flags & M_PKTHDR);
739
740#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
741	memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN);
742#endif
743	m_adj(m, sizeof(struct ether_header));
744	if (m->m_pkthdr.len <= PPPOE_HEADERLEN) {
745		printf("pppoe (data): dropping too short packet: %d bytes\n",
746		    m->m_pkthdr.len);
747		goto drop;
748	}
749
750	if (m->m_len < sizeof(*ph)) {
751		m = m_pullup(m, sizeof(*ph));
752		if (!m) {
753			printf("pppoe: could not get PPPoE header\n");
754			return;
755		}
756	}
757	ph = mtod(m, struct pppoehdr *);
758
759	if (ph->vertype != PPPOE_VERTYPE) {
760		printf("pppoe (data): unknown version/type packet: 0x%x\n",
761		    ph->vertype);
762		goto drop;
763	}
764	if (ph->code != 0)
765		goto drop;
766
767	session = ntohs(ph->session);
768	sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif);
769	if (sc == NULL) {
770#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
771		printf("pppoe: input for unknown session 0x%x, sending PADT\n",
772		    session);
773		pppoe_send_padt(m->m_pkthdr.rcvif, session, shost);
774#endif
775		goto drop;
776	}
777
778	plen = ntohs(ph->plen);
779
780#if NBPFILTER > 0
781	if(sc->sc_sppp.pp_if.if_bpf)
782		bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m);
783#endif
784
785	m_adj(m, PPPOE_HEADERLEN);
786
787#ifdef PPPOE_DEBUG
788	{
789		struct mbuf *p;
790
791		printf("%s: pkthdr.len=%d, pppoe.len=%d",
792			sc->sc_sppp.pp_if.if_xname,
793			m->m_pkthdr.len, plen);
794		p = m;
795		while (p) {
796			printf(" l=%d", p->m_len);
797			p = p->m_next;
798		}
799		printf("\n");
800	}
801#endif
802
803	if (m->m_pkthdr.len < plen)
804		goto drop;
805
806	/* fix incoming interface pointer (not the raw ethernet interface anymore) */
807	m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if;
808
809	/* pass packet up and account for it */
810	sc->sc_sppp.pp_if.if_ipackets++;
811	sppp_input(&sc->sc_sppp.pp_if, m);
812	return;
813
814drop:
815	m_freem(m);
816}
817
818static int
819pppoe_output(struct pppoe_softc *sc, struct mbuf *m)
820{
821	struct sockaddr dst;
822	struct ether_header *eh;
823	u_int16_t etype;
824
825	if (sc->sc_eth_if == NULL) {
826		m_freem(m);
827		return EIO;
828	}
829
830	memset(&dst, 0, sizeof dst);
831	dst.sa_family = AF_UNSPEC;
832	eh = (struct ether_header*)&dst.sa_data;
833	etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC;
834	eh->ether_type = htons(etype);
835	memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest);
836
837#ifdef PPPOE_DEBUG
838	printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n",
839	    sc->sc_sppp.pp_if.if_xname, etype,
840	    sc->sc_state, sc->sc_session,
841	    ether_sprintf((const unsigned char *)&sc->sc_dest), m->m_pkthdr.len);
842#endif
843
844	m->m_flags &= ~(M_BCAST|M_MCAST);
845	sc->sc_sppp.pp_if.if_opackets++;
846	return sc->sc_eth_if->if_output(sc->sc_eth_if, m, &dst, NULL);
847}
848
849static int
850pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data)
851{
852	struct lwp *l = curlwp;	/* XXX */
853	struct pppoe_softc *sc = (struct pppoe_softc*)ifp;
854	int error = 0;
855
856	switch (cmd) {
857	case PPPOESETPARMS:
858	{
859		struct pppoediscparms *parms = (struct pppoediscparms*)data;
860		if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE,
861		    KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
862		    NULL) != 0)
863			return (EPERM);
864		if (parms->eth_ifname[0] != 0) {
865			struct ifnet	*eth_if;
866
867			eth_if = ifunit(parms->eth_ifname);
868			if (eth_if == NULL || eth_if->if_dlt != DLT_EN10MB) {
869				sc->sc_eth_if = NULL;
870				return ENXIO;
871			}
872
873			if (sc->sc_sppp.pp_if.if_mtu >
874			    eth_if->if_mtu - PPPOE_OVERHEAD) {
875				sc->sc_sppp.pp_if.if_mtu = eth_if->if_mtu -
876				    PPPOE_OVERHEAD;
877			}
878			sc->sc_eth_if = eth_if;
879		}
880		if (parms->ac_name != NULL) {
881			size_t s;
882			char *b = malloc(parms->ac_name_len + 1, M_DEVBUF,
883			    M_WAITOK);
884			if (b == NULL)
885				return ENOMEM;
886			error = copyinstr(parms->ac_name, b,
887			    parms->ac_name_len+1, &s);
888			if (error != 0) {
889				free(b, M_DEVBUF);
890				return error;
891			}
892			if (s != parms->ac_name_len+1) {
893				free(b, M_DEVBUF);
894				return EINVAL;
895			}
896			if (sc->sc_concentrator_name)
897				free(sc->sc_concentrator_name, M_DEVBUF);
898			sc->sc_concentrator_name = b;
899		}
900		if (parms->service_name != NULL) {
901			size_t s;
902			char *b = malloc(parms->service_name_len + 1, M_DEVBUF,
903			    M_WAITOK);
904			if (b == NULL)
905				return ENOMEM;
906			error = copyinstr(parms->service_name, b,
907			    parms->service_name_len+1, &s);
908			if (error != 0) {
909				free(b, M_DEVBUF);
910				return error;
911			}
912			if (s != parms->service_name_len+1) {
913				free(b, M_DEVBUF);
914				return EINVAL;
915			}
916			if (sc->sc_service_name)
917				free(sc->sc_service_name, M_DEVBUF);
918			sc->sc_service_name = b;
919		}
920		return 0;
921	}
922	break;
923	case PPPOEGETPARMS:
924	{
925		struct pppoediscparms *parms = (struct pppoediscparms*)data;
926		memset(parms, 0, sizeof *parms);
927		if (sc->sc_eth_if)
928			strncpy(parms->ifname, sc->sc_eth_if->if_xname, IFNAMSIZ);
929		return 0;
930	}
931	break;
932	case PPPOEGETSESSION:
933	{
934		struct pppoeconnectionstate *state = (struct pppoeconnectionstate*)data;
935		state->state = sc->sc_state;
936		state->session_id = sc->sc_session;
937		state->padi_retry_no = sc->sc_padi_retried;
938		state->padr_retry_no = sc->sc_padr_retried;
939		return 0;
940	}
941	break;
942	case SIOCSIFFLAGS:
943	{
944		struct ifreq *ifr = (struct ifreq*) data;
945		/*
946		 * Prevent running re-establishment timers overriding
947		 * administrators choice.
948		 */
949		if ((ifr->ifr_flags & IFF_UP) == 0
950		     && sc->sc_state >= PPPOE_STATE_PADI_SENT
951		     && sc->sc_state < PPPOE_STATE_SESSION) {
952			callout_stop(&sc->sc_timeout);
953			sc->sc_state = PPPOE_STATE_INITIAL;
954			sc->sc_padi_retried = 0;
955			sc->sc_padr_retried = 0;
956			memcpy(&sc->sc_dest, etherbroadcastaddr,
957			    sizeof(sc->sc_dest));
958		}
959		return sppp_ioctl(ifp, cmd, data);
960	}
961	case SIOCSIFMTU:
962	{
963		struct ifreq *ifr = (struct ifreq *)data;
964
965		if (ifr->ifr_mtu > (sc->sc_eth_if == NULL ?
966		    PPPOE_MAXMTU : (sc->sc_eth_if->if_mtu - PPPOE_OVERHEAD))) {
967			return EINVAL;
968		}
969		return sppp_ioctl(ifp, cmd, data);
970	}
971	default:
972		return sppp_ioctl(ifp, cmd, data);
973	}
974	return 0;
975}
976
977/*
978 * Allocate a mbuf/cluster with space to store the given data length
979 * of payload, leaving space for prepending an ethernet header
980 * in front.
981 */
982static struct mbuf *
983pppoe_get_mbuf(size_t len)
984{
985	struct mbuf *m;
986
987	MGETHDR(m, M_DONTWAIT, MT_DATA);
988	if (m == NULL)
989		return NULL;
990	if (len + sizeof(struct ether_header) > MHLEN) {
991		MCLGET(m, M_DONTWAIT);
992		if ((m->m_flags & M_EXT) == 0) {
993			struct mbuf *n;
994			MFREE(m, n);
995			return 0;
996		}
997	}
998	m->m_data += sizeof(struct ether_header);
999	m->m_len = len;
1000	m->m_pkthdr.len = len;
1001	m->m_pkthdr.rcvif = NULL;
1002
1003	return m;
1004}
1005
1006static int
1007pppoe_send_padi(struct pppoe_softc *sc)
1008{
1009	struct mbuf *m0;
1010	int len, l1 = 0, l2 = 0; /* XXX: gcc */
1011	u_int8_t *p;
1012
1013	if (sc->sc_state >PPPOE_STATE_PADI_SENT)
1014		panic("pppoe_send_padi in state %d", sc->sc_state);
1015
1016	/* calculate length of frame (excluding ethernet header + pppoe header) */
1017	len = 2 + 2 + 2 + 2 + sizeof sc;	/* service name tag is required, host unique is send too */
1018	if (sc->sc_service_name != NULL) {
1019		l1 = strlen(sc->sc_service_name);
1020		len += l1;
1021	}
1022	if (sc->sc_concentrator_name != NULL) {
1023		l2 = strlen(sc->sc_concentrator_name);
1024		len += 2 + 2 + l2;
1025	}
1026
1027	/* allocate a buffer */
1028	m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);	/* header len + payload len */
1029	if (!m0)
1030		return ENOBUFS;
1031
1032	/* fill in pkt */
1033	p = mtod(m0, u_int8_t *);
1034	PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len);
1035	PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
1036	if (sc->sc_service_name != NULL) {
1037		PPPOE_ADD_16(p, l1);
1038		memcpy(p, sc->sc_service_name, l1);
1039		p += l1;
1040	} else {
1041		PPPOE_ADD_16(p, 0);
1042	}
1043	if (sc->sc_concentrator_name != NULL) {
1044		PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
1045		PPPOE_ADD_16(p, l2);
1046		memcpy(p, sc->sc_concentrator_name, l2);
1047		p += l2;
1048	}
1049	PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
1050	PPPOE_ADD_16(p, sizeof(sc));
1051	memcpy(p, &sc, sizeof sc);
1052
1053#ifdef PPPOE_DEBUG
1054	p += sizeof sc;
1055	if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN)
1056		panic("pppoe_send_padi: garbled output len, should be %ld, is %ld",
1057		    (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *)));
1058#endif
1059
1060	/* send pkt */
1061	return pppoe_output(sc, m0);
1062}
1063
1064static void
1065pppoe_timeout(void *arg)
1066{
1067	int x, retry_wait, err;
1068	struct pppoe_softc *sc = (struct pppoe_softc*)arg;
1069
1070#ifdef PPPOE_DEBUG
1071	printf("%s: timeout\n", sc->sc_sppp.pp_if.if_xname);
1072#endif
1073
1074	switch (sc->sc_state) {
1075	case PPPOE_STATE_PADI_SENT:
1076		/*
1077		 * We have two basic ways of retrying:
1078		 *  - Quick retry mode: try a few times in short sequence
1079		 *  - Slow retry mode: we already had a connection successfully
1080		 *    established and will try infinitely (without user
1081		 *    intervention)
1082		 * We only enter slow retry mode if IFF_LINK1 (aka autodial)
1083		 * is not set.
1084		 */
1085
1086		/* initialize for quick retry mode */
1087		retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried);
1088
1089		x = splnet();
1090		sc->sc_padi_retried++;
1091		if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) {
1092			if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) {
1093				/* slow retry mode */
1094				retry_wait = PPPOE_SLOW_RETRY;
1095			} else {
1096				pppoe_abort_connect(sc);
1097				splx(x);
1098				return;
1099			}
1100		}
1101		if ((err = pppoe_send_padi(sc)) != 0) {
1102			sc->sc_padi_retried--;
1103			if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1104				printf("%s: failed to transmit PADI, "
1105				    "error=%d\n",
1106				    sc->sc_sppp.pp_if.if_xname, err);
1107		}
1108		callout_reset(&sc->sc_timeout, retry_wait,
1109		    pppoe_timeout, sc);
1110		splx(x);
1111		break;
1112
1113	case PPPOE_STATE_PADR_SENT:
1114		x = splnet();
1115		sc->sc_padr_retried++;
1116		if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) {
1117			memcpy(&sc->sc_dest, etherbroadcastaddr,
1118			    sizeof(sc->sc_dest));
1119			sc->sc_state = PPPOE_STATE_PADI_SENT;
1120			sc->sc_padr_retried = 0;
1121			if ((err = pppoe_send_padi(sc)) != 0) {
1122				if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1123					printf("%s: failed to send PADI"
1124					    ", error=%d\n",
1125					    sc->sc_sppp.pp_if.if_xname,
1126					    err);
1127			}
1128			callout_reset(&sc->sc_timeout,
1129			    PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried),
1130			    pppoe_timeout, sc);
1131			splx(x);
1132			return;
1133		}
1134		if ((err = pppoe_send_padr(sc)) != 0) {
1135			sc->sc_padr_retried--;
1136			if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1137				printf("%s: failed to send PADR, "
1138				    "error=%d\n", sc->sc_sppp.pp_if.if_xname,
1139				    err);
1140		}
1141		callout_reset(&sc->sc_timeout,
1142		    PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried),
1143		    pppoe_timeout, sc);
1144		splx(x);
1145		break;
1146	case PPPOE_STATE_CLOSING:
1147		pppoe_disconnect(sc);
1148		break;
1149	default:
1150		return;	/* all done, work in peace */
1151	}
1152}
1153
1154/* Start a connection (i.e. initiate discovery phase) */
1155static int
1156pppoe_connect(struct pppoe_softc *sc)
1157{
1158	int x, err;
1159
1160	if (sc->sc_state != PPPOE_STATE_INITIAL)
1161		return EBUSY;
1162
1163#ifdef PPPOE_SERVER
1164	/* wait PADI if IFF_PASSIVE */
1165	if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE))
1166		return 0;
1167#endif
1168	x = splnet();
1169	/* save state, in case we fail to send PADI */
1170	sc->sc_state = PPPOE_STATE_PADI_SENT;
1171	sc->sc_padr_retried = 0;
1172	err = pppoe_send_padi(sc);
1173	if (err != 0 && sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1174		printf("%s: failed to send PADI, error=%d\n",
1175		    sc->sc_sppp.pp_if.if_xname, err);
1176	callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc);
1177	splx(x);
1178	return err;
1179}
1180
1181/* disconnect */
1182static int
1183pppoe_disconnect(struct pppoe_softc *sc)
1184{
1185	int err, x;
1186
1187	x = splnet();
1188
1189	if (sc->sc_state < PPPOE_STATE_SESSION)
1190		err = EBUSY;
1191	else {
1192		if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1193			printf("%s: disconnecting\n",
1194			    sc->sc_sppp.pp_if.if_xname);
1195		err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const u_int8_t *)&sc->sc_dest);
1196	}
1197
1198	/* cleanup softc */
1199	sc->sc_state = PPPOE_STATE_INITIAL;
1200	memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
1201	if (sc->sc_ac_cookie) {
1202		free(sc->sc_ac_cookie, M_DEVBUF);
1203		sc->sc_ac_cookie = NULL;
1204	}
1205	sc->sc_ac_cookie_len = 0;
1206#ifdef PPPOE_SERVER
1207	if (sc->sc_hunique) {
1208		free(sc->sc_hunique, M_DEVBUF);
1209		sc->sc_hunique = NULL;
1210	}
1211	sc->sc_hunique_len = 0;
1212#endif
1213	sc->sc_session = 0;
1214
1215	/* notify upper layer */
1216	sc->sc_sppp.pp_down(&sc->sc_sppp);
1217
1218	splx(x);
1219
1220	return err;
1221}
1222
1223/* Connection attempt aborted */
1224static void
1225pppoe_abort_connect(struct pppoe_softc *sc)
1226{
1227	printf("%s: could not establish connection\n",
1228		sc->sc_sppp.pp_if.if_xname);
1229	sc->sc_state = PPPOE_STATE_CLOSING;
1230
1231	/* notify upper layer */
1232	sc->sc_sppp.pp_down(&sc->sc_sppp);
1233
1234	/* clear connection state */
1235	memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
1236	sc->sc_state = PPPOE_STATE_INITIAL;
1237}
1238
1239/* Send a PADR packet */
1240static int
1241pppoe_send_padr(struct pppoe_softc *sc)
1242{
1243	struct mbuf *m0;
1244	u_int8_t *p;
1245	size_t len, l1 = 0; /* XXX: gcc */
1246
1247	if (sc->sc_state != PPPOE_STATE_PADR_SENT)
1248		return EIO;
1249
1250	len = 2 + 2 + 2 + 2 + sizeof(sc);		/* service name, host unique */
1251	if (sc->sc_service_name != NULL) {		/* service name tag maybe empty */
1252		l1 = strlen(sc->sc_service_name);
1253		len += l1;
1254	}
1255	if (sc->sc_ac_cookie_len > 0)
1256		len += 2 + 2 + sc->sc_ac_cookie_len;	/* AC cookie */
1257	m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
1258	if (!m0)
1259		return ENOBUFS;
1260	p = mtod(m0, u_int8_t *);
1261	PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
1262	PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
1263	if (sc->sc_service_name != NULL) {
1264		PPPOE_ADD_16(p, l1);
1265		memcpy(p, sc->sc_service_name, l1);
1266		p += l1;
1267	} else {
1268		PPPOE_ADD_16(p, 0);
1269	}
1270	if (sc->sc_ac_cookie_len > 0) {
1271		PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
1272		PPPOE_ADD_16(p, sc->sc_ac_cookie_len);
1273		memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len);
1274		p += sc->sc_ac_cookie_len;
1275	}
1276	PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
1277	PPPOE_ADD_16(p, sizeof(sc));
1278	memcpy(p, &sc, sizeof sc);
1279
1280#ifdef PPPOE_DEBUG
1281	p += sizeof sc;
1282	if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN)
1283		panic("pppoe_send_padr: garbled output len, should be %ld, is %ld",
1284			(long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *)));
1285#endif
1286
1287	return pppoe_output(sc, m0);
1288}
1289
1290/* send a PADT packet */
1291static int
1292pppoe_send_padt(struct ifnet *outgoing_if, u_int session, const u_int8_t *dest)
1293{
1294	struct ether_header *eh;
1295	struct sockaddr dst;
1296	struct mbuf *m0;
1297	u_int8_t *p;
1298
1299	m0 = pppoe_get_mbuf(PPPOE_HEADERLEN);
1300	if (!m0)
1301		return EIO;
1302	p = mtod(m0, u_int8_t *);
1303	PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0);
1304
1305	memset(&dst, 0, sizeof dst);
1306	dst.sa_family = AF_UNSPEC;
1307	eh = (struct ether_header*)&dst.sa_data;
1308	eh->ether_type = htons(ETHERTYPE_PPPOEDISC);
1309	memcpy(&eh->ether_dhost, dest, ETHER_ADDR_LEN);
1310
1311	m0->m_flags &= ~(M_BCAST|M_MCAST);
1312	return outgoing_if->if_output(outgoing_if, m0, &dst, NULL);
1313}
1314
1315#ifdef PPPOE_SERVER
1316static int
1317pppoe_send_pado(struct pppoe_softc *sc)
1318{
1319	struct mbuf *m0;
1320	u_int8_t *p;
1321	size_t len;
1322
1323	if (sc->sc_state != PPPOE_STATE_PADO_SENT)
1324		return EIO;
1325
1326	/* calc length */
1327	len = 0;
1328	/* include ac_cookie */
1329	len += 2 + 2 + sizeof(sc);
1330	/* include hunique */
1331	len += 2 + 2 + sc->sc_hunique_len;
1332	m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
1333	if (!m0)
1334		return EIO;
1335	p = mtod(m0, u_int8_t *);
1336	PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len);
1337	PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
1338	PPPOE_ADD_16(p, sizeof(sc));
1339	memcpy(p, &sc, sizeof(sc));
1340	p += sizeof(sc);
1341	PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
1342	PPPOE_ADD_16(p, sc->sc_hunique_len);
1343	memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
1344	return pppoe_output(sc, m0);
1345}
1346
1347static int
1348pppoe_send_pads(struct pppoe_softc *sc)
1349{
1350	struct bintime bt;
1351	struct mbuf *m0;
1352	u_int8_t *p;
1353	size_t len, l1 = 0;	/* XXX: gcc */
1354
1355	if (sc->sc_state != PPPOE_STATE_PADO_SENT)
1356		return EIO;
1357
1358	getbinuptime(&bt);
1359	sc->sc_session = bt.sec % 0xff + 1;
1360	/* calc length */
1361	len = 0;
1362	/* include hunique */
1363	len += 2 + 2 + 2 + 2 + sc->sc_hunique_len;	/* service name, host unique*/
1364	if (sc->sc_service_name != NULL) {		/* service name tag maybe empty */
1365		l1 = strlen(sc->sc_service_name);
1366		len += l1;
1367	}
1368	m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
1369	if (!m0)
1370		return ENOBUFS;
1371	p = mtod(m0, u_int8_t *);
1372	PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len);
1373	PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
1374	if (sc->sc_service_name != NULL) {
1375		PPPOE_ADD_16(p, l1);
1376		memcpy(p, sc->sc_service_name, l1);
1377		p += l1;
1378	} else {
1379		PPPOE_ADD_16(p, 0);
1380	}
1381	PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
1382	PPPOE_ADD_16(p, sc->sc_hunique_len);
1383	memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
1384	return pppoe_output(sc, m0);
1385}
1386#endif
1387
1388static void
1389pppoe_tls(struct sppp *sp)
1390{
1391	struct pppoe_softc *sc = (void *)sp;
1392	if (sc->sc_state != PPPOE_STATE_INITIAL)
1393		return;
1394	pppoe_connect(sc);
1395}
1396
1397static void
1398pppoe_tlf(struct sppp *sp)
1399{
1400	struct pppoe_softc *sc = (void *)sp;
1401	if (sc->sc_state < PPPOE_STATE_SESSION)
1402		return;
1403	/*
1404	 * Do not call pppoe_disconnect here, the upper layer state
1405	 * machine gets confused by this. We must return from this
1406	 * function and defer disconnecting to the timeout handler.
1407	 */
1408	sc->sc_state = PPPOE_STATE_CLOSING;
1409	callout_reset(&sc->sc_timeout, hz/50, pppoe_timeout, sc);
1410}
1411
1412static void
1413pppoe_start(struct ifnet *ifp)
1414{
1415	struct pppoe_softc *sc = (void *)ifp;
1416	struct mbuf *m;
1417	u_int8_t *p;
1418	size_t len;
1419
1420	if (sppp_isempty(ifp))
1421		return;
1422
1423	/* are we ready to process data yet? */
1424	if (sc->sc_state < PPPOE_STATE_SESSION) {
1425		sppp_flush(&sc->sc_sppp.pp_if);
1426		return;
1427	}
1428
1429	while ((m = sppp_dequeue(ifp)) != NULL) {
1430		len = m->m_pkthdr.len;
1431		M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT);
1432		if (m == NULL) {
1433			ifp->if_oerrors++;
1434			continue;
1435		}
1436		p = mtod(m, u_int8_t *);
1437		PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
1438
1439#if NBPFILTER > 0
1440		if(sc->sc_sppp.pp_if.if_bpf)
1441			bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m);
1442#endif
1443
1444		pppoe_output(sc, m);
1445	}
1446}
1447
1448
1449#ifdef PFIL_HOOKS
1450static int
1451pppoe_ifattach_hook(void *arg __unused, struct mbuf **mp, struct ifnet *ifp,
1452    int dir __unused)
1453{
1454	struct pppoe_softc *sc;
1455	int s;
1456
1457	if (mp != (struct mbuf **)PFIL_IFNET_DETACH)
1458		return 0;
1459
1460	s = splnet();
1461	LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
1462		if (sc->sc_eth_if != ifp)
1463			continue;
1464		if (sc->sc_sppp.pp_if.if_flags & IFF_UP) {
1465			sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
1466			printf("%s: ethernet interface detached, going down\n",
1467			    sc->sc_sppp.pp_if.if_xname);
1468		}
1469		sc->sc_eth_if = NULL;
1470		pppoe_clear_softc(sc, "ethernet interface detached");
1471	}
1472	splx(s);
1473
1474	return 0;
1475}
1476#endif
1477
1478static void
1479pppoe_clear_softc(struct pppoe_softc *sc, const char *message)
1480{
1481	/* stop timer */
1482	callout_stop(&sc->sc_timeout);
1483	if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1484		printf("%s: session 0x%x terminated, %s\n",
1485		    sc->sc_sppp.pp_if.if_xname, sc->sc_session, message);
1486
1487	/* fix our state */
1488	sc->sc_state = PPPOE_STATE_INITIAL;
1489
1490	/* signal upper layer */
1491	sc->sc_sppp.pp_down(&sc->sc_sppp);
1492
1493	/* clean up softc */
1494	memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
1495	if (sc->sc_ac_cookie) {
1496		free(sc->sc_ac_cookie, M_DEVBUF);
1497		sc->sc_ac_cookie = NULL;
1498	}
1499	sc->sc_ac_cookie_len = 0;
1500	sc->sc_session = 0;
1501}
1502