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