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