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