No empty .Rs/.Re
[netbsd-mini2440.git] / sys / net / if_pppoe.c
blobabac17349d33bd37e13ebde5999a18b85fac1629
1 /* $NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $ */
3 /*-
4 * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Martin Husemann <martin@NetBSD.org>.
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.
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.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $");
35 #include "pppoe.h"
36 #include "bpfilter.h"
37 #include "opt_pfil_hooks.h"
38 #include "opt_pppoe.h"
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>
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>
60 #if NBPFILTER > 0
61 #include <net/bpf.h>
62 #endif
65 #undef PPPOE_DEBUG /* XXX - remove this or make it an option */
66 /* #define PPPOE_DEBUG 1 */
68 struct pppoehdr {
69 uint8_t vertype;
70 uint8_t code;
71 uint16_t session;
72 uint16_t plen;
73 } __packed;
75 struct pppoetag {
76 uint16_t tag;
77 uint16_t len;
78 } __packed;
80 #define PPPOE_HEADERLEN sizeof(struct pppoehdr)
81 #define PPPOE_OVERHEAD (PPPOE_HEADERLEN + 2)
82 #define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */
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 */
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 */
101 /* two byte PPP protocol discriminator, then IP data */
102 #define PPPOE_MAXMTU (ETHERMTU - PPPOE_OVERHEAD)
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
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)
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_RECON_FAST (hz*15) /* first retry after auth failure */
119 #define PPPOE_RECON_IMMEDIATE (hz/10) /* "no delay" reconnect */
120 #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */
121 #define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */
123 #ifdef PPPOE_SERVER
124 /* from if_spppsubr.c */
125 #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */
126 #endif
128 struct pppoe_softc {
129 struct sppp sc_sppp; /* contains a struct ifnet as first element */
130 LIST_ENTRY(pppoe_softc) sc_list;
131 struct ifnet *sc_eth_if; /* ethernet interface we are using */
133 int sc_state; /* discovery phase or session connected */
134 struct ether_addr sc_dest; /* hardware address of concentrator */
135 uint16_t sc_session; /* PPPoE session id */
137 char *sc_service_name; /* if != NULL: requested name of service */
138 char *sc_concentrator_name; /* if != NULL: requested concentrator id */
139 uint8_t *sc_ac_cookie; /* content of AC cookie we must echo back */
140 size_t sc_ac_cookie_len; /* length of cookie data */
141 uint8_t *sc_relay_sid; /* content of relay SID we must echo back */
142 size_t sc_relay_sid_len; /* length of relay SID data */
143 #ifdef PPPOE_SERVER
144 uint8_t *sc_hunique; /* content of host unique we must echo back */
145 size_t sc_hunique_len; /* length of host unique */
146 #endif
147 callout_t sc_timeout; /* timeout while not in session state */
148 int sc_padi_retried; /* number of PADI retries already done */
149 int sc_padr_retried; /* number of PADR retries already done */
152 /* incoming traffic will be queued here */
153 struct ifqueue ppoediscinq = { .ifq_maxlen = IFQ_MAXLEN };
154 struct ifqueue ppoeinq = { .ifq_maxlen = IFQ_MAXLEN };
156 void *pppoe_softintr = NULL;
157 static void pppoe_softintr_handler(void *);
159 extern int sppp_ioctl(struct ifnet *, unsigned long, void *);
161 /* input routines */
162 static void pppoe_input(void);
163 static void pppoe_disc_input(struct mbuf *);
164 static void pppoe_dispatch_disc_pkt(struct mbuf *, int);
165 static void pppoe_data_input(struct mbuf *);
167 /* management routines */
168 void pppoeattach(int);
169 static int pppoe_connect(struct pppoe_softc *);
170 static int pppoe_disconnect(struct pppoe_softc *);
171 static void pppoe_abort_connect(struct pppoe_softc *);
172 static int pppoe_ioctl(struct ifnet *, unsigned long, void *);
173 static void pppoe_tls(struct sppp *);
174 static void pppoe_tlf(struct sppp *);
175 static void pppoe_start(struct ifnet *);
176 static void pppoe_clear_softc(struct pppoe_softc *, const char *);
178 /* internal timeout handling */
179 static void pppoe_timeout(void *);
181 /* sending actual protocol controll packets */
182 static int pppoe_send_padi(struct pppoe_softc *);
183 static int pppoe_send_padr(struct pppoe_softc *);
184 #ifdef PPPOE_SERVER
185 static int pppoe_send_pado(struct pppoe_softc *);
186 static int pppoe_send_pads(struct pppoe_softc *);
187 #endif
188 static int pppoe_send_padt(struct ifnet *, u_int, const uint8_t *);
190 /* raw output */
191 static int pppoe_output(struct pppoe_softc *, struct mbuf *);
193 /* internal helper functions */
194 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *);
195 static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *, size_t, struct ifnet *);
196 static struct mbuf *pppoe_get_mbuf(size_t len);
198 #ifdef PFIL_HOOKS
199 static int pppoe_ifattach_hook(void *, struct mbuf **, struct ifnet *, int);
200 #endif
202 static LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list;
204 static int pppoe_clone_create(struct if_clone *, int);
205 static int pppoe_clone_destroy(struct ifnet *);
207 static struct if_clone pppoe_cloner =
208 IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy);
210 /* ARGSUSED */
211 void
212 pppoeattach(int count)
214 LIST_INIT(&pppoe_softc_list);
215 if_clone_attach(&pppoe_cloner);
217 pppoe_softintr = softint_establish(SOFTINT_NET, pppoe_softintr_handler, NULL);
220 static int
221 pppoe_clone_create(struct if_clone *ifc, int unit)
223 struct pppoe_softc *sc;
225 sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK|M_ZERO);
227 if_initname(&sc->sc_sppp.pp_if, "pppoe", unit);
228 sc->sc_sppp.pp_if.if_softc = sc;
229 sc->sc_sppp.pp_if.if_mtu = PPPOE_MAXMTU;
230 sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX|IFF_POINTOPOINT|IFF_MULTICAST;
231 sc->sc_sppp.pp_if.if_type = IFT_PPP;
232 sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN;
233 sc->sc_sppp.pp_if.if_dlt = DLT_PPP_ETHER;
234 sc->sc_sppp.pp_flags |= PP_KEEPALIVE | /* use LCP keepalive */
235 PP_NOFRAMING; /* no serial encapsulation */
236 sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl;
237 IFQ_SET_MAXLEN(&sc->sc_sppp.pp_if.if_snd, IFQ_MAXLEN);
238 IFQ_SET_READY(&sc->sc_sppp.pp_if.if_snd);
240 /* changed to real address later */
241 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
243 callout_init(&sc->sc_timeout, 0);
245 sc->sc_sppp.pp_if.if_start = pppoe_start;
246 sc->sc_sppp.pp_tls = pppoe_tls;
247 sc->sc_sppp.pp_tlf = pppoe_tlf;
248 sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN; /* framing added to ppp packets */
250 if_attach(&sc->sc_sppp.pp_if);
251 sppp_attach(&sc->sc_sppp.pp_if);
253 #if NBPFILTER > 0
254 bpfattach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0);
255 #endif
256 #ifdef PFIL_HOOKS
257 if (LIST_EMPTY(&pppoe_softc_list))
258 pfil_add_hook(pppoe_ifattach_hook, NULL,
259 PFIL_IFNET|PFIL_WAITOK, &if_pfil);
260 #endif
261 LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list);
262 return 0;
265 static int
266 pppoe_clone_destroy(struct ifnet *ifp)
268 struct pppoe_softc * sc = ifp->if_softc;
270 callout_stop(&sc->sc_timeout);
271 LIST_REMOVE(sc, sc_list);
272 #ifdef PFIL_HOOKS
273 if (LIST_EMPTY(&pppoe_softc_list))
274 pfil_remove_hook(pppoe_ifattach_hook, NULL,
275 PFIL_IFNET|PFIL_WAITOK, &if_pfil);
276 #endif
277 #if NBPFILTER > 0
278 bpfdetach(ifp);
279 #endif
280 sppp_detach(&sc->sc_sppp.pp_if);
281 if_detach(ifp);
282 if (sc->sc_concentrator_name)
283 free(sc->sc_concentrator_name, M_DEVBUF);
284 if (sc->sc_service_name)
285 free(sc->sc_service_name, M_DEVBUF);
286 if (sc->sc_ac_cookie)
287 free(sc->sc_ac_cookie, M_DEVBUF);
288 if (sc->sc_relay_sid)
289 free(sc->sc_relay_sid, M_DEVBUF);
290 callout_destroy(&sc->sc_timeout);
291 free(sc, M_DEVBUF);
293 return (0);
297 * Find the interface handling the specified session.
298 * Note: O(number of sessions open), this is a client-side only, mean
299 * and lean implementation, so number of open sessions typically should
300 * be 1.
302 static struct pppoe_softc *
303 pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif)
305 struct pppoe_softc *sc;
307 if (session == 0)
308 return NULL;
310 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
311 if (sc->sc_state == PPPOE_STATE_SESSION
312 && sc->sc_session == session
313 && sc->sc_eth_if == rcvif)
314 return sc;
316 return NULL;
319 /* Check host unique token passed and return appropriate softc pointer,
320 * or NULL if token is bogus. */
321 static struct pppoe_softc *
322 pppoe_find_softc_by_hunique(uint8_t *token, size_t len, struct ifnet *rcvif)
324 struct pppoe_softc *sc, *t;
326 if (LIST_EMPTY(&pppoe_softc_list))
327 return NULL;
329 if (len != sizeof sc)
330 return NULL;
331 memcpy(&t, token, len);
333 LIST_FOREACH(sc, &pppoe_softc_list, sc_list)
334 if (sc == t) break;
336 if (sc == NULL) {
337 #ifdef PPPOE_DEBUG
338 printf("pppoe: alien host unique tag, no session found\n");
339 #endif
340 return NULL;
343 /* should be safe to access *sc now */
344 if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) {
345 printf("%s: host unique tag found, but it belongs to a connection in state %d\n",
346 sc->sc_sppp.pp_if.if_xname, sc->sc_state);
347 return NULL;
349 if (sc->sc_eth_if != rcvif) {
350 printf("%s: wrong interface, not accepting host unique\n",
351 sc->sc_sppp.pp_if.if_xname);
352 return NULL;
354 return sc;
357 static void
358 pppoe_softintr_handler(void *dummy)
360 /* called at splsoftnet() */
361 mutex_enter(softnet_lock);
362 pppoe_input();
363 mutex_exit(softnet_lock);
366 /* called at appropriate protection level */
367 static void
368 pppoe_input(void)
370 struct mbuf *m;
371 int s, disc_done, data_done;
373 do {
374 disc_done = 0;
375 data_done = 0;
376 for (;;) {
377 s = splnet();
378 IF_DEQUEUE(&ppoediscinq, m);
379 splx(s);
380 if (m == NULL) break;
381 disc_done = 1;
382 pppoe_disc_input(m);
385 for (;;) {
386 s = splnet();
387 IF_DEQUEUE(&ppoeinq, m);
388 splx(s);
389 if (m == NULL) break;
390 data_done = 1;
391 pppoe_data_input(m);
393 } while (disc_done || data_done);
396 /* analyze and handle a single received packet while not in session state */
397 static void
398 pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
400 uint16_t tag, len;
401 uint16_t session, plen;
402 struct pppoe_softc *sc;
403 const char *err_msg, *devname;
404 char *error;
405 uint8_t *ac_cookie;
406 size_t ac_cookie_len;
407 uint8_t *relay_sid;
408 size_t relay_sid_len;
409 #ifdef PPPOE_SERVER
410 uint8_t *hunique;
411 size_t hunique_len;
412 #endif
413 struct pppoehdr *ph;
414 struct pppoetag *pt;
415 struct mbuf *n;
416 int noff, err, errortag;
417 struct ether_header *eh;
419 devname = "pppoe"; /* as long as we don't know which instance */
420 err_msg = NULL;
421 errortag = 0;
422 if (m->m_len < sizeof(*eh)) {
423 m = m_pullup(m, sizeof(*eh));
424 if (!m)
425 goto done;
427 eh = mtod(m, struct ether_header *);
428 off += sizeof(*eh);
430 ac_cookie = NULL;
431 ac_cookie_len = 0;
432 relay_sid = NULL;
433 relay_sid_len = 0;
434 #ifdef PPPOE_SERVER
435 hunique = NULL;
436 hunique_len = 0;
437 #endif
438 session = 0;
439 if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) {
440 printf("pppoe: packet too short: %d\n", m->m_pkthdr.len);
441 goto done;
444 n = m_pulldown(m, off, sizeof(*ph), &noff);
445 if (!n) {
446 printf("pppoe: could not get PPPoE header\n");
447 m = NULL;
448 goto done;
450 ph = (struct pppoehdr *)(mtod(n, char *) + noff);
451 if (ph->vertype != PPPOE_VERTYPE) {
452 printf("pppoe: unknown version/type packet: 0x%x\n",
453 ph->vertype);
454 goto done;
456 session = ntohs(ph->session);
457 plen = ntohs(ph->plen);
458 off += sizeof(*ph);
460 if (plen + off > m->m_pkthdr.len) {
461 printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n",
462 m->m_pkthdr.len - off, plen);
463 goto done;
465 m_adj(m, off + plen - m->m_pkthdr.len); /* ignore trailing garbage */
466 tag = 0;
467 len = 0;
468 sc = NULL;
469 while (off + sizeof(*pt) <= m->m_pkthdr.len) {
470 n = m_pulldown(m, off, sizeof(*pt), &noff);
471 if (!n) {
472 printf("%s: parse error\n", devname);
473 m = NULL;
474 goto done;
476 pt = (struct pppoetag *)(mtod(n, char *) + noff);
477 tag = ntohs(pt->tag);
478 len = ntohs(pt->len);
479 if (off + len + sizeof(*pt) > m->m_pkthdr.len) {
480 printf("pppoe: tag 0x%x len 0x%x is too long\n",
481 tag, len);
482 goto done;
484 switch (tag) {
485 case PPPOE_TAG_EOL:
486 goto breakbreak;
487 case PPPOE_TAG_SNAME:
488 break; /* ignored */
489 case PPPOE_TAG_ACNAME:
490 error = NULL;
491 if (sc != NULL && len > 0) {
492 error = malloc(len+1, M_TEMP, M_NOWAIT);
493 if (error) {
494 n = m_pulldown(m, off + sizeof(*pt),
495 len, &noff);
496 if (n) {
497 strncpy(error,
498 mtod(n, char*) + noff,
499 len);
500 error[len] = '\0';
502 printf("%s: connected to %s\n",
503 devname, error);
504 free(error, M_TEMP);
507 break; /* ignored */
508 case PPPOE_TAG_HUNIQUE:
509 if (sc != NULL)
510 break;
511 n = m_pulldown(m, off + sizeof(*pt), len, &noff);
512 if (!n) {
513 m = NULL;
514 err_msg = "TAG HUNIQUE ERROR";
515 break;
517 #ifdef PPPOE_SERVER
518 hunique = mtod(n, uint8_t *) + noff;
519 hunique_len = len;
520 #endif
521 sc = pppoe_find_softc_by_hunique(mtod(n, char *) + noff,
522 len, m->m_pkthdr.rcvif);
523 if (sc != NULL)
524 devname = sc->sc_sppp.pp_if.if_xname;
525 break;
526 case PPPOE_TAG_ACCOOKIE:
527 if (ac_cookie == NULL) {
528 n = m_pulldown(m, off + sizeof(*pt), len,
529 &noff);
530 if (!n) {
531 err_msg = "TAG ACCOOKIE ERROR";
532 m = NULL;
533 break;
535 ac_cookie = mtod(n, char *) + noff;
536 ac_cookie_len = len;
538 break;
539 case PPPOE_TAG_RELAYSID:
540 if (relay_sid == NULL) {
541 n = m_pulldown(m, off + sizeof(*pt), len,
542 &noff);
543 if (!n) {
544 err_msg = "TAG RELAYSID ERROR";
545 m = NULL;
546 break;
548 relay_sid = mtod(n, char *) + noff;
549 relay_sid_len = len;
551 break;
552 case PPPOE_TAG_SNAME_ERR:
553 err_msg = "SERVICE NAME ERROR";
554 errortag = 1;
555 break;
556 case PPPOE_TAG_ACSYS_ERR:
557 err_msg = "AC SYSTEM ERROR";
558 errortag = 1;
559 break;
560 case PPPOE_TAG_GENERIC_ERR:
561 err_msg = "GENERIC ERROR";
562 errortag = 1;
563 break;
565 if (err_msg) {
566 error = NULL;
567 if (errortag && len) {
568 error = malloc(len+1, M_TEMP, M_NOWAIT);
569 n = m_pulldown(m, off + sizeof(*pt), len,
570 &noff);
571 if (n && error) {
572 strncpy(error,
573 mtod(n, char *) + noff, len);
574 error[len] = '\0';
577 if (error) {
578 printf("%s: %s: %s\n", devname,
579 err_msg, error);
580 free(error, M_TEMP);
581 } else
582 printf("%s: %s\n", devname, err_msg);
583 if (errortag || m == NULL)
584 goto done;
586 off += sizeof(*pt) + len;
588 breakbreak:;
589 switch (ph->code) {
590 case PPPOE_CODE_PADI:
591 #ifdef PPPOE_SERVER
593 * got service name, concentrator name, and/or host unique.
594 * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP.
596 if (LIST_EMPTY(&pppoe_softc_list))
597 goto done;
598 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
599 if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP))
600 continue;
601 if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE))
602 continue;
603 if (sc->sc_state == PPPOE_STATE_INITIAL)
604 break;
606 if (sc == NULL) {
607 /* printf("pppoe: free passive interface is not found\n");*/
608 goto done;
610 if (hunique) {
611 if (sc->sc_hunique)
612 free(sc->sc_hunique, M_DEVBUF);
613 sc->sc_hunique = malloc(hunique_len, M_DEVBUF,
614 M_DONTWAIT);
615 if (sc->sc_hunique == NULL)
616 goto done;
617 sc->sc_hunique_len = hunique_len;
618 memcpy(sc->sc_hunique, hunique, hunique_len);
620 memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
621 sc->sc_state = PPPOE_STATE_PADO_SENT;
622 pppoe_send_pado(sc);
623 break;
624 #endif /* PPPOE_SERVER */
625 case PPPOE_CODE_PADR:
626 #ifdef PPPOE_SERVER
628 * get sc from ac_cookie if IFF_PASSIVE
630 if (ac_cookie == NULL) {
631 /* be quiet if there is not a single pppoe instance */
632 printf("pppoe: received PADR but not includes ac_cookie\n");
633 goto done;
635 sc = pppoe_find_softc_by_hunique(ac_cookie,
636 ac_cookie_len,
637 m->m_pkthdr.rcvif);
638 if (sc == NULL) {
639 /* be quiet if there is not a single pppoe instance */
640 if (!LIST_EMPTY(&pppoe_softc_list))
641 printf("pppoe: received PADR but could not find request for it\n");
642 goto done;
644 if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
645 printf("%s: received unexpected PADR\n",
646 sc->sc_sppp.pp_if.if_xname);
647 goto done;
649 if (hunique) {
650 if (sc->sc_hunique)
651 free(sc->sc_hunique, M_DEVBUF);
652 sc->sc_hunique = malloc(hunique_len, M_DEVBUF,
653 M_DONTWAIT);
654 if (sc->sc_hunique == NULL)
655 goto done;
656 sc->sc_hunique_len = hunique_len;
657 memcpy(sc->sc_hunique, hunique, hunique_len);
659 pppoe_send_pads(sc);
660 sc->sc_state = PPPOE_STATE_SESSION;
661 sc->sc_sppp.pp_up(&sc->sc_sppp);
662 break;
663 #else
664 /* ignore, we are no access concentrator */
665 goto done;
666 #endif /* PPPOE_SERVER */
667 case PPPOE_CODE_PADO:
668 if (sc == NULL) {
669 /* be quiet if there is not a single pppoe instance */
670 if (!LIST_EMPTY(&pppoe_softc_list))
671 printf("pppoe: received PADO but could not find request for it\n");
672 goto done;
674 if (sc->sc_state != PPPOE_STATE_PADI_SENT) {
675 printf("%s: received unexpected PADO\n",
676 sc->sc_sppp.pp_if.if_xname);
677 goto done;
679 if (ac_cookie) {
680 if (sc->sc_ac_cookie)
681 free(sc->sc_ac_cookie, M_DEVBUF);
682 sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF,
683 M_DONTWAIT);
684 if (sc->sc_ac_cookie == NULL) {
685 printf("%s: FATAL: could not allocate memory "
686 "for AC cookie\n",
687 sc->sc_sppp.pp_if.if_xname);
688 goto done;
690 sc->sc_ac_cookie_len = ac_cookie_len;
691 memcpy(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
693 if (relay_sid) {
694 if (sc->sc_relay_sid)
695 free(sc->sc_relay_sid, M_DEVBUF);
696 sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF,
697 M_DONTWAIT);
698 if (sc->sc_relay_sid == NULL) {
699 printf("%s: FATAL: could not allocate memory "
700 "for relay SID\n",
701 sc->sc_sppp.pp_if.if_xname);
702 goto done;
704 sc->sc_relay_sid_len = relay_sid_len;
705 memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len);
707 memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
708 callout_stop(&sc->sc_timeout);
709 sc->sc_padr_retried = 0;
710 sc->sc_state = PPPOE_STATE_PADR_SENT;
711 if ((err = pppoe_send_padr(sc)) != 0) {
712 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
713 printf("%s: failed to send PADR, "
714 "error=%d\n", sc->sc_sppp.pp_if.if_xname,
715 err);
717 callout_reset(&sc->sc_timeout,
718 PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried),
719 pppoe_timeout, sc);
720 break;
721 case PPPOE_CODE_PADS:
722 if (sc == NULL)
723 goto done;
724 sc->sc_session = session;
725 callout_stop(&sc->sc_timeout);
726 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
727 printf("%s: session 0x%x connected\n",
728 sc->sc_sppp.pp_if.if_xname, session);
729 sc->sc_state = PPPOE_STATE_SESSION;
730 sc->sc_sppp.pp_up(&sc->sc_sppp); /* notify upper layers */
731 break;
732 case PPPOE_CODE_PADT:
733 if (sc == NULL)
734 goto done;
735 pppoe_clear_softc(sc, "received PADT");
736 break;
737 default:
738 printf("%s: unknown code (0x%04x) session = 0x%04x\n",
739 sc? sc->sc_sppp.pp_if.if_xname : "pppoe",
740 ph->code, session);
741 break;
744 done:
745 if (m)
746 m_freem(m);
747 return;
750 static void
751 pppoe_disc_input(struct mbuf *m)
754 /* avoid error messages if there is not a single pppoe instance */
755 if (!LIST_EMPTY(&pppoe_softc_list)) {
756 KASSERT(m->m_flags & M_PKTHDR);
757 pppoe_dispatch_disc_pkt(m, 0);
758 } else
759 m_freem(m);
762 static void
763 pppoe_data_input(struct mbuf *m)
765 uint16_t session, plen;
766 struct pppoe_softc *sc;
767 struct pppoehdr *ph;
768 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
769 uint8_t shost[ETHER_ADDR_LEN];
770 #endif
772 KASSERT(m->m_flags & M_PKTHDR);
774 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
775 memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN);
776 #endif
777 m_adj(m, sizeof(struct ether_header));
778 if (m->m_pkthdr.len <= PPPOE_HEADERLEN) {
779 printf("pppoe (data): dropping too short packet: %d bytes\n",
780 m->m_pkthdr.len);
781 goto drop;
784 if (m->m_len < sizeof(*ph)) {
785 m = m_pullup(m, sizeof(*ph));
786 if (!m) {
787 printf("pppoe: could not get PPPoE header\n");
788 return;
791 ph = mtod(m, struct pppoehdr *);
793 if (ph->vertype != PPPOE_VERTYPE) {
794 printf("pppoe (data): unknown version/type packet: 0x%x\n",
795 ph->vertype);
796 goto drop;
798 if (ph->code != 0)
799 goto drop;
801 session = ntohs(ph->session);
802 sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif);
803 if (sc == NULL) {
804 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
805 printf("pppoe: input for unknown session 0x%x, sending PADT\n",
806 session);
807 pppoe_send_padt(m->m_pkthdr.rcvif, session, shost);
808 #endif
809 goto drop;
812 plen = ntohs(ph->plen);
814 #if NBPFILTER > 0
815 if(sc->sc_sppp.pp_if.if_bpf)
816 bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m);
817 #endif
819 m_adj(m, PPPOE_HEADERLEN);
821 #ifdef PPPOE_DEBUG
823 struct mbuf *p;
825 printf("%s: pkthdr.len=%d, pppoe.len=%d",
826 sc->sc_sppp.pp_if.if_xname,
827 m->m_pkthdr.len, plen);
828 p = m;
829 while (p) {
830 printf(" l=%d", p->m_len);
831 p = p->m_next;
833 printf("\n");
835 #endif
837 if (m->m_pkthdr.len < plen)
838 goto drop;
840 /* fix incoming interface pointer (not the raw ethernet interface anymore) */
841 m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if;
843 /* pass packet up and account for it */
844 sc->sc_sppp.pp_if.if_ipackets++;
845 sppp_input(&sc->sc_sppp.pp_if, m);
846 return;
848 drop:
849 m_freem(m);
852 static int
853 pppoe_output(struct pppoe_softc *sc, struct mbuf *m)
855 struct sockaddr dst;
856 struct ether_header *eh;
857 uint16_t etype;
859 if (sc->sc_eth_if == NULL) {
860 m_freem(m);
861 return EIO;
864 memset(&dst, 0, sizeof dst);
865 dst.sa_family = AF_UNSPEC;
866 eh = (struct ether_header*)&dst.sa_data;
867 etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC;
868 eh->ether_type = htons(etype);
869 memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest);
871 #ifdef PPPOE_DEBUG
872 printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n",
873 sc->sc_sppp.pp_if.if_xname, etype,
874 sc->sc_state, sc->sc_session,
875 ether_sprintf((const unsigned char *)&sc->sc_dest), m->m_pkthdr.len);
876 #endif
878 m->m_flags &= ~(M_BCAST|M_MCAST);
879 sc->sc_sppp.pp_if.if_opackets++;
880 return sc->sc_eth_if->if_output(sc->sc_eth_if, m, &dst, NULL);
883 static int
884 pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, void *data)
886 struct lwp *l = curlwp; /* XXX */
887 struct pppoe_softc *sc = (struct pppoe_softc*)ifp;
888 struct ifreq *ifr = data;
889 int error = 0;
891 switch (cmd) {
892 case PPPOESETPARMS:
894 struct pppoediscparms *parms = (struct pppoediscparms*)data;
895 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE,
896 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
897 NULL) != 0)
898 return (EPERM);
899 if (parms->eth_ifname[0] != 0) {
900 struct ifnet *eth_if;
902 eth_if = ifunit(parms->eth_ifname);
903 if (eth_if == NULL || eth_if->if_dlt != DLT_EN10MB) {
904 sc->sc_eth_if = NULL;
905 return ENXIO;
908 if (sc->sc_sppp.pp_if.if_mtu >
909 eth_if->if_mtu - PPPOE_OVERHEAD) {
910 sc->sc_sppp.pp_if.if_mtu = eth_if->if_mtu -
911 PPPOE_OVERHEAD;
913 sc->sc_eth_if = eth_if;
915 if (parms->ac_name != NULL) {
916 size_t s;
917 char *b = malloc(parms->ac_name_len + 1, M_DEVBUF,
918 M_WAITOK);
919 if (b == NULL)
920 return ENOMEM;
921 error = copyinstr(parms->ac_name, b,
922 parms->ac_name_len+1, &s);
923 if (error != 0) {
924 free(b, M_DEVBUF);
925 return error;
927 if (s != parms->ac_name_len+1) {
928 free(b, M_DEVBUF);
929 return EINVAL;
931 if (sc->sc_concentrator_name)
932 free(sc->sc_concentrator_name, M_DEVBUF);
933 sc->sc_concentrator_name = b;
935 if (parms->service_name != NULL) {
936 size_t s;
937 char *b = malloc(parms->service_name_len + 1, M_DEVBUF,
938 M_WAITOK);
939 if (b == NULL)
940 return ENOMEM;
941 error = copyinstr(parms->service_name, b,
942 parms->service_name_len+1, &s);
943 if (error != 0) {
944 free(b, M_DEVBUF);
945 return error;
947 if (s != parms->service_name_len+1) {
948 free(b, M_DEVBUF);
949 return EINVAL;
951 if (sc->sc_service_name)
952 free(sc->sc_service_name, M_DEVBUF);
953 sc->sc_service_name = b;
955 return 0;
957 break;
958 case PPPOEGETPARMS:
960 struct pppoediscparms *parms = (struct pppoediscparms*)data;
961 memset(parms, 0, sizeof *parms);
962 if (sc->sc_eth_if)
963 strncpy(parms->ifname, sc->sc_eth_if->if_xname, IFNAMSIZ);
964 return 0;
966 break;
967 case PPPOEGETSESSION:
969 struct pppoeconnectionstate *state = (struct pppoeconnectionstate*)data;
970 state->state = sc->sc_state;
971 state->session_id = sc->sc_session;
972 state->padi_retry_no = sc->sc_padi_retried;
973 state->padr_retry_no = sc->sc_padr_retried;
974 return 0;
976 break;
977 case SIOCSIFFLAGS:
979 * Prevent running re-establishment timers overriding
980 * administrators choice.
982 if ((ifr->ifr_flags & IFF_UP) == 0
983 && sc->sc_state >= PPPOE_STATE_PADI_SENT
984 && sc->sc_state < PPPOE_STATE_SESSION) {
985 callout_stop(&sc->sc_timeout);
986 sc->sc_state = PPPOE_STATE_INITIAL;
987 sc->sc_padi_retried = 0;
988 sc->sc_padr_retried = 0;
989 memcpy(&sc->sc_dest, etherbroadcastaddr,
990 sizeof(sc->sc_dest));
992 return sppp_ioctl(ifp, cmd, data);
993 case SIOCSIFMTU:
994 if (ifr->ifr_mtu > (sc->sc_eth_if == NULL ?
995 PPPOE_MAXMTU : (sc->sc_eth_if->if_mtu - PPPOE_OVERHEAD))) {
996 return EINVAL;
998 /*FALLTHROUGH*/
999 default:
1000 return sppp_ioctl(ifp, cmd, data);
1002 return 0;
1006 * Allocate a mbuf/cluster with space to store the given data length
1007 * of payload, leaving space for prepending an ethernet header
1008 * in front.
1010 static struct mbuf *
1011 pppoe_get_mbuf(size_t len)
1013 struct mbuf *m;
1015 MGETHDR(m, M_DONTWAIT, MT_DATA);
1016 if (m == NULL)
1017 return NULL;
1018 if (len + sizeof(struct ether_header) > MHLEN) {
1019 MCLGET(m, M_DONTWAIT);
1020 if ((m->m_flags & M_EXT) == 0) {
1021 struct mbuf *n;
1022 MFREE(m, n);
1023 return 0;
1026 m->m_data += sizeof(struct ether_header);
1027 m->m_len = len;
1028 m->m_pkthdr.len = len;
1029 m->m_pkthdr.rcvif = NULL;
1031 return m;
1034 static int
1035 pppoe_send_padi(struct pppoe_softc *sc)
1037 struct mbuf *m0;
1038 int len, l1 = 0, l2 = 0; /* XXX: gcc */
1039 uint8_t *p;
1041 if (sc->sc_state >PPPOE_STATE_PADI_SENT)
1042 panic("pppoe_send_padi in state %d", sc->sc_state);
1044 /* calculate length of frame (excluding ethernet header + pppoe header) */
1045 len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */
1046 if (sc->sc_service_name != NULL) {
1047 l1 = strlen(sc->sc_service_name);
1048 len += l1;
1050 if (sc->sc_concentrator_name != NULL) {
1051 l2 = strlen(sc->sc_concentrator_name);
1052 len += 2 + 2 + l2;
1055 /* allocate a buffer */
1056 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); /* header len + payload len */
1057 if (!m0)
1058 return ENOBUFS;
1060 /* fill in pkt */
1061 p = mtod(m0, uint8_t *);
1062 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len);
1063 PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
1064 if (sc->sc_service_name != NULL) {
1065 PPPOE_ADD_16(p, l1);
1066 memcpy(p, sc->sc_service_name, l1);
1067 p += l1;
1068 } else {
1069 PPPOE_ADD_16(p, 0);
1071 if (sc->sc_concentrator_name != NULL) {
1072 PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
1073 PPPOE_ADD_16(p, l2);
1074 memcpy(p, sc->sc_concentrator_name, l2);
1075 p += l2;
1077 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
1078 PPPOE_ADD_16(p, sizeof(sc));
1079 memcpy(p, &sc, sizeof sc);
1081 #ifdef PPPOE_DEBUG
1082 p += sizeof sc;
1083 if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN)
1084 panic("pppoe_send_padi: garbled output len, should be %ld, is %ld",
1085 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *)));
1086 #endif
1088 /* send pkt */
1089 return pppoe_output(sc, m0);
1092 static void
1093 pppoe_timeout(void *arg)
1095 int x, retry_wait, err;
1096 struct pppoe_softc *sc = (struct pppoe_softc*)arg;
1098 #ifdef PPPOE_DEBUG
1099 printf("%s: timeout\n", sc->sc_sppp.pp_if.if_xname);
1100 #endif
1102 switch (sc->sc_state) {
1103 case PPPOE_STATE_INITIAL:
1104 /* delayed connect from pppoe_tls() */
1105 pppoe_connect(sc);
1106 break;
1107 case PPPOE_STATE_PADI_SENT:
1109 * We have two basic ways of retrying:
1110 * - Quick retry mode: try a few times in short sequence
1111 * - Slow retry mode: we already had a connection successfully
1112 * established and will try infinitely (without user
1113 * intervention)
1114 * We only enter slow retry mode if IFF_LINK1 (aka autodial)
1115 * is not set.
1118 /* initialize for quick retry mode */
1119 retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried);
1121 x = splnet();
1122 sc->sc_padi_retried++;
1123 if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) {
1124 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) {
1125 /* slow retry mode */
1126 retry_wait = PPPOE_SLOW_RETRY;
1127 } else {
1128 pppoe_abort_connect(sc);
1129 splx(x);
1130 return;
1133 if ((err = pppoe_send_padi(sc)) != 0) {
1134 sc->sc_padi_retried--;
1135 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1136 printf("%s: failed to transmit PADI, "
1137 "error=%d\n",
1138 sc->sc_sppp.pp_if.if_xname, err);
1140 callout_reset(&sc->sc_timeout, retry_wait,
1141 pppoe_timeout, sc);
1142 splx(x);
1143 break;
1145 case PPPOE_STATE_PADR_SENT:
1146 x = splnet();
1147 sc->sc_padr_retried++;
1148 if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) {
1149 memcpy(&sc->sc_dest, etherbroadcastaddr,
1150 sizeof(sc->sc_dest));
1151 sc->sc_state = PPPOE_STATE_PADI_SENT;
1152 sc->sc_padr_retried = 0;
1153 if ((err = pppoe_send_padi(sc)) != 0) {
1154 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1155 printf("%s: failed to send PADI"
1156 ", error=%d\n",
1157 sc->sc_sppp.pp_if.if_xname,
1158 err);
1160 callout_reset(&sc->sc_timeout,
1161 PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried),
1162 pppoe_timeout, sc);
1163 splx(x);
1164 return;
1166 if ((err = pppoe_send_padr(sc)) != 0) {
1167 sc->sc_padr_retried--;
1168 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1169 printf("%s: failed to send PADR, "
1170 "error=%d\n", sc->sc_sppp.pp_if.if_xname,
1171 err);
1173 callout_reset(&sc->sc_timeout,
1174 PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried),
1175 pppoe_timeout, sc);
1176 splx(x);
1177 break;
1178 case PPPOE_STATE_CLOSING:
1179 pppoe_disconnect(sc);
1180 break;
1181 default:
1182 return; /* all done, work in peace */
1186 /* Start a connection (i.e. initiate discovery phase) */
1187 static int
1188 pppoe_connect(struct pppoe_softc *sc)
1190 int x, err;
1192 if (sc->sc_state != PPPOE_STATE_INITIAL)
1193 return EBUSY;
1195 #ifdef PPPOE_SERVER
1196 /* wait PADI if IFF_PASSIVE */
1197 if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE))
1198 return 0;
1199 #endif
1200 x = splnet();
1201 /* save state, in case we fail to send PADI */
1202 sc->sc_state = PPPOE_STATE_PADI_SENT;
1203 sc->sc_padr_retried = 0;
1204 err = pppoe_send_padi(sc);
1205 if (err != 0 && sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1206 printf("%s: failed to send PADI, error=%d\n",
1207 sc->sc_sppp.pp_if.if_xname, err);
1208 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc);
1209 splx(x);
1210 return err;
1213 /* disconnect */
1214 static int
1215 pppoe_disconnect(struct pppoe_softc *sc)
1217 int err, x;
1219 x = splnet();
1221 if (sc->sc_state < PPPOE_STATE_SESSION)
1222 err = EBUSY;
1223 else {
1224 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1225 printf("%s: disconnecting\n",
1226 sc->sc_sppp.pp_if.if_xname);
1227 err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const uint8_t *)&sc->sc_dest);
1230 /* cleanup softc */
1231 sc->sc_state = PPPOE_STATE_INITIAL;
1232 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
1233 if (sc->sc_ac_cookie) {
1234 free(sc->sc_ac_cookie, M_DEVBUF);
1235 sc->sc_ac_cookie = NULL;
1237 sc->sc_ac_cookie_len = 0;
1238 if (sc->sc_relay_sid) {
1239 free(sc->sc_relay_sid, M_DEVBUF);
1240 sc->sc_relay_sid = NULL;
1242 sc->sc_relay_sid_len = 0;
1243 #ifdef PPPOE_SERVER
1244 if (sc->sc_hunique) {
1245 free(sc->sc_hunique, M_DEVBUF);
1246 sc->sc_hunique = NULL;
1248 sc->sc_hunique_len = 0;
1249 #endif
1250 sc->sc_session = 0;
1252 /* notify upper layer */
1253 sc->sc_sppp.pp_down(&sc->sc_sppp);
1255 splx(x);
1257 return err;
1260 /* Connection attempt aborted */
1261 static void
1262 pppoe_abort_connect(struct pppoe_softc *sc)
1264 printf("%s: could not establish connection\n",
1265 sc->sc_sppp.pp_if.if_xname);
1266 sc->sc_state = PPPOE_STATE_CLOSING;
1268 /* notify upper layer */
1269 sc->sc_sppp.pp_down(&sc->sc_sppp);
1271 /* clear connection state */
1272 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
1273 sc->sc_state = PPPOE_STATE_INITIAL;
1276 /* Send a PADR packet */
1277 static int
1278 pppoe_send_padr(struct pppoe_softc *sc)
1280 struct mbuf *m0;
1281 uint8_t *p;
1282 size_t len, l1 = 0; /* XXX: gcc */
1284 if (sc->sc_state != PPPOE_STATE_PADR_SENT)
1285 return EIO;
1287 len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */
1288 if (sc->sc_service_name != NULL) { /* service name tag maybe empty */
1289 l1 = strlen(sc->sc_service_name);
1290 len += l1;
1292 if (sc->sc_ac_cookie_len > 0)
1293 len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */
1294 if (sc->sc_relay_sid_len > 0)
1295 len += 2 + 2 + sc->sc_relay_sid_len; /* Relay SID */
1296 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
1297 if (!m0)
1298 return ENOBUFS;
1299 p = mtod(m0, uint8_t *);
1300 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
1301 PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
1302 if (sc->sc_service_name != NULL) {
1303 PPPOE_ADD_16(p, l1);
1304 memcpy(p, sc->sc_service_name, l1);
1305 p += l1;
1306 } else {
1307 PPPOE_ADD_16(p, 0);
1309 if (sc->sc_ac_cookie_len > 0) {
1310 PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
1311 PPPOE_ADD_16(p, sc->sc_ac_cookie_len);
1312 memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len);
1313 p += sc->sc_ac_cookie_len;
1315 if (sc->sc_relay_sid_len > 0) {
1316 PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID);
1317 PPPOE_ADD_16(p, sc->sc_relay_sid_len);
1318 memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len);
1319 p += sc->sc_relay_sid_len;
1321 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
1322 PPPOE_ADD_16(p, sizeof(sc));
1323 memcpy(p, &sc, sizeof sc);
1325 #ifdef PPPOE_DEBUG
1326 p += sizeof sc;
1327 if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN)
1328 panic("pppoe_send_padr: garbled output len, should be %ld, is %ld",
1329 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *)));
1330 #endif
1332 return pppoe_output(sc, m0);
1335 /* send a PADT packet */
1336 static int
1337 pppoe_send_padt(struct ifnet *outgoing_if, u_int session, const uint8_t *dest)
1339 struct ether_header *eh;
1340 struct sockaddr dst;
1341 struct mbuf *m0;
1342 uint8_t *p;
1344 m0 = pppoe_get_mbuf(PPPOE_HEADERLEN);
1345 if (!m0)
1346 return EIO;
1347 p = mtod(m0, uint8_t *);
1348 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0);
1350 memset(&dst, 0, sizeof dst);
1351 dst.sa_family = AF_UNSPEC;
1352 eh = (struct ether_header*)&dst.sa_data;
1353 eh->ether_type = htons(ETHERTYPE_PPPOEDISC);
1354 memcpy(&eh->ether_dhost, dest, ETHER_ADDR_LEN);
1356 m0->m_flags &= ~(M_BCAST|M_MCAST);
1357 return outgoing_if->if_output(outgoing_if, m0, &dst, NULL);
1360 #ifdef PPPOE_SERVER
1361 static int
1362 pppoe_send_pado(struct pppoe_softc *sc)
1364 struct mbuf *m0;
1365 uint8_t *p;
1366 size_t len;
1368 if (sc->sc_state != PPPOE_STATE_PADO_SENT)
1369 return EIO;
1371 /* calc length */
1372 len = 0;
1373 /* include ac_cookie */
1374 len += 2 + 2 + sizeof(sc);
1375 /* include hunique */
1376 len += 2 + 2 + sc->sc_hunique_len;
1377 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
1378 if (!m0)
1379 return EIO;
1380 p = mtod(m0, uint8_t *);
1381 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len);
1382 PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
1383 PPPOE_ADD_16(p, sizeof(sc));
1384 memcpy(p, &sc, sizeof(sc));
1385 p += sizeof(sc);
1386 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
1387 PPPOE_ADD_16(p, sc->sc_hunique_len);
1388 memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
1389 return pppoe_output(sc, m0);
1392 static int
1393 pppoe_send_pads(struct pppoe_softc *sc)
1395 struct bintime bt;
1396 struct mbuf *m0;
1397 uint8_t *p;
1398 size_t len, l1 = 0; /* XXX: gcc */
1400 if (sc->sc_state != PPPOE_STATE_PADO_SENT)
1401 return EIO;
1403 getbinuptime(&bt);
1404 sc->sc_session = bt.sec % 0xff + 1;
1405 /* calc length */
1406 len = 0;
1407 /* include hunique */
1408 len += 2 + 2 + 2 + 2 + sc->sc_hunique_len; /* service name, host unique*/
1409 if (sc->sc_service_name != NULL) { /* service name tag maybe empty */
1410 l1 = strlen(sc->sc_service_name);
1411 len += l1;
1413 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
1414 if (!m0)
1415 return ENOBUFS;
1416 p = mtod(m0, uint8_t *);
1417 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len);
1418 PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
1419 if (sc->sc_service_name != NULL) {
1420 PPPOE_ADD_16(p, l1);
1421 memcpy(p, sc->sc_service_name, l1);
1422 p += l1;
1423 } else {
1424 PPPOE_ADD_16(p, 0);
1426 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
1427 PPPOE_ADD_16(p, sc->sc_hunique_len);
1428 memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
1429 return pppoe_output(sc, m0);
1431 #endif
1433 static void
1434 pppoe_tls(struct sppp *sp)
1436 struct pppoe_softc *sc = (void *)sp;
1437 int wtime;
1439 if (sc->sc_state != PPPOE_STATE_INITIAL)
1440 return;
1442 if (sc->sc_sppp.pp_phase == SPPP_PHASE_ESTABLISH &&
1443 sc->sc_sppp.pp_auth_failures > 0) {
1445 * Delay trying to reconnect a bit more - the peer
1446 * might have failed to contact it's radius server.
1448 wtime = PPPOE_RECON_FAST * sc->sc_sppp.pp_auth_failures;
1449 if (wtime > PPPOE_SLOW_RETRY)
1450 wtime = PPPOE_SLOW_RETRY;
1451 } else {
1452 wtime = PPPOE_RECON_IMMEDIATE;
1454 callout_reset(&sc->sc_timeout, wtime, pppoe_timeout, sc);
1457 static void
1458 pppoe_tlf(struct sppp *sp)
1460 struct pppoe_softc *sc = (void *)sp;
1461 if (sc->sc_state < PPPOE_STATE_SESSION)
1462 return;
1464 * Do not call pppoe_disconnect here, the upper layer state
1465 * machine gets confused by this. We must return from this
1466 * function and defer disconnecting to the timeout handler.
1468 sc->sc_state = PPPOE_STATE_CLOSING;
1469 callout_reset(&sc->sc_timeout, hz/50, pppoe_timeout, sc);
1472 static void
1473 pppoe_start(struct ifnet *ifp)
1475 struct pppoe_softc *sc = (void *)ifp;
1476 struct mbuf *m;
1477 uint8_t *p;
1478 size_t len;
1480 if (sppp_isempty(ifp))
1481 return;
1483 /* are we ready to process data yet? */
1484 if (sc->sc_state < PPPOE_STATE_SESSION) {
1485 sppp_flush(&sc->sc_sppp.pp_if);
1486 return;
1489 while ((m = sppp_dequeue(ifp)) != NULL) {
1490 len = m->m_pkthdr.len;
1491 M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT);
1492 if (m == NULL) {
1493 ifp->if_oerrors++;
1494 continue;
1496 p = mtod(m, uint8_t *);
1497 PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
1499 #if NBPFILTER > 0
1500 if(sc->sc_sppp.pp_if.if_bpf)
1501 bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m);
1502 #endif
1504 pppoe_output(sc, m);
1509 #ifdef PFIL_HOOKS
1510 static int
1511 pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp,
1512 int dir)
1514 struct pppoe_softc *sc;
1515 int s;
1517 if (mp != (struct mbuf **)PFIL_IFNET_DETACH)
1518 return 0;
1520 s = splnet();
1521 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
1522 if (sc->sc_eth_if != ifp)
1523 continue;
1524 if (sc->sc_sppp.pp_if.if_flags & IFF_UP) {
1525 sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
1526 printf("%s: ethernet interface detached, going down\n",
1527 sc->sc_sppp.pp_if.if_xname);
1529 sc->sc_eth_if = NULL;
1530 pppoe_clear_softc(sc, "ethernet interface detached");
1532 splx(s);
1534 return 0;
1536 #endif
1538 static void
1539 pppoe_clear_softc(struct pppoe_softc *sc, const char *message)
1541 /* stop timer */
1542 callout_stop(&sc->sc_timeout);
1543 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
1544 printf("%s: session 0x%x terminated, %s\n",
1545 sc->sc_sppp.pp_if.if_xname, sc->sc_session, message);
1547 /* fix our state */
1548 sc->sc_state = PPPOE_STATE_INITIAL;
1550 /* signal upper layer */
1551 sc->sc_sppp.pp_down(&sc->sc_sppp);
1553 /* clean up softc */
1554 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
1555 if (sc->sc_ac_cookie) {
1556 free(sc->sc_ac_cookie, M_DEVBUF);
1557 sc->sc_ac_cookie = NULL;
1559 if (sc->sc_relay_sid) {
1560 free(sc->sc_relay_sid, M_DEVBUF);
1561 sc->sc_relay_sid = NULL;
1563 sc->sc_ac_cookie_len = 0;
1564 sc->sc_session = 0;