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