if_pppoe.c revision 1.30
1/* $NetBSD: if_pppoe.c,v 1.30 2002/06/22 11:46:16 itojun 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.30 2002/06/22 11:46:16 itojun 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 pppoe_softc *); 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 *); 184 185LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list; 186 187int pppoe_clone_create __P((struct if_clone *, int)); 188void pppoe_clone_destroy __P((struct ifnet *)); 189 190struct if_clone pppoe_cloner = 191 IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy); 192 193/* ARGSUSED */ 194void 195pppoeattach(count) 196 int count; 197{ 198 LIST_INIT(&pppoe_softc_list); 199 if_clone_attach(&pppoe_cloner); 200 201 ppoediscinq.ifq_maxlen = IFQ_MAXLEN; 202 ppoeinq.ifq_maxlen = IFQ_MAXLEN; 203 204#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 205 pppoe_softintr = softintr_establish(IPL_SOFTNET, pppoe_softintr_handler, NULL); 206#endif 207} 208 209int 210pppoe_clone_create(ifc, unit) 211 struct if_clone *ifc; 212 int unit; 213{ 214 struct pppoe_softc *sc; 215 216 sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK); 217 memset(sc, 0, sizeof(struct pppoe_softc)); 218 219 sprintf(sc->sc_sppp.pp_if.if_xname, "pppoe%d", unit); 220 sc->sc_sppp.pp_if.if_softc = sc; 221 sc->sc_sppp.pp_if.if_mtu = PPPOE_MAXMTU; 222 sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX|IFF_POINTOPOINT|IFF_MULTICAST; 223 sc->sc_sppp.pp_if.if_type = IFT_PPP; 224 sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN; 225 sc->sc_sppp.pp_if.if_dlt = DLT_PPP_ETHER; 226 sc->sc_sppp.pp_flags |= PP_KEEPALIVE | /* use LCP keepalive */ 227 PP_NOFRAMING; /* no serial encapsulation */ 228 sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl; 229 IFQ_SET_MAXLEN(&sc->sc_sppp.pp_if.if_snd, IFQ_MAXLEN); 230 IFQ_SET_READY(&sc->sc_sppp.pp_if.if_snd); 231 232 /* changed to real address later */ 233 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); 234 235 callout_init(&sc->sc_timeout); 236 237 sc->sc_sppp.pp_if.if_start = pppoe_start; 238 sc->sc_sppp.pp_tls = pppoe_tls; 239 sc->sc_sppp.pp_tlf = pppoe_tlf; 240 sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN; /* framing added to ppp packets */ 241 242 if_attach(&sc->sc_sppp.pp_if); 243 sppp_attach(&sc->sc_sppp.pp_if); 244 245#if NBPFILTER > 0 246 bpfattach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0); 247#endif 248 LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list); 249 return 0; 250} 251 252void 253pppoe_clone_destroy(ifp) 254 struct ifnet *ifp; 255{ 256 struct pppoe_softc * sc = ifp->if_softc; 257 258 LIST_REMOVE(sc, sc_list); 259#if NBPFILTER > 0 260 bpfdetach(ifp); 261#endif 262 sppp_detach(&sc->sc_sppp.pp_if); 263 if_detach(ifp); 264 free(sc, M_DEVBUF); 265} 266 267/* 268 * Find the interface handling the specified session. 269 * Note: O(number of sessions open), this is a client-side only, mean 270 * and lean implementation, so number of open sessions typically should 271 * be 1. 272 */ 273static struct pppoe_softc * 274pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif) 275{ 276 struct pppoe_softc *sc; 277 278 if (session == 0) 279 return NULL; 280 281 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { 282 if (sc->sc_state == PPPOE_STATE_SESSION 283 && sc->sc_session == session) { 284 if (sc->sc_eth_if == rcvif) 285 return sc; 286 else 287 return NULL; 288 } 289 } 290 return NULL; 291} 292 293/* Check host unique token passed and return appropriate softc pointer, 294 * or NULL if token is bogus. */ 295static struct pppoe_softc * 296pppoe_find_softc_by_hunique(u_int8_t *token, size_t len, struct ifnet *rcvif) 297{ 298 struct pppoe_softc *sc, *t; 299 300 if (LIST_EMPTY(&pppoe_softc_list)) 301 return NULL; 302 303 if (len != sizeof sc) 304 return NULL; 305 memcpy(&t, token, len); 306 307 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) 308 if (sc == t) break; 309 310 if (sc != t) { 311#ifdef PPPOE_DEBUG 312 printf("pppoe: alien host unique tag, no session found\n"); 313#endif 314 return NULL; 315 } 316 317 /* should be safe to access *sc now */ 318 if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) { 319 printf("%s: host unique tag found, but it belongs to a connection in state %d\n", 320 sc->sc_sppp.pp_if.if_xname, sc->sc_state); 321 return NULL; 322 } 323 if (sc->sc_eth_if != rcvif) { 324 printf("%s: wrong interface, not accepting host unique\n", 325 sc->sc_sppp.pp_if.if_xname); 326 return NULL; 327 } 328 return sc; 329} 330 331#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 332static void pppoe_softintr_handler(void *dummy) 333{ 334 /* called at splsoftnet() */ 335 pppoe_input(); 336} 337#else 338void pppoe_softintr_handler(void *dummy) 339{ 340 int s = splnet(); 341 pppoe_input(); 342 callout_deactivate(&pppoe_softintr); 343 splx(s); 344} 345#endif 346 347/* called at appropriate protection level */ 348static void 349pppoe_input() 350{ 351 struct mbuf *m; 352 int s, disc_done, data_done; 353 354 do { 355 disc_done = 0; 356 data_done = 0; 357 for (;;) { 358 s = splnet(); 359 IF_DEQUEUE(&ppoediscinq, m); 360 splx(s); 361 if (m == NULL) break; 362 disc_done = 1; 363 pppoe_disc_input(m); 364 } 365 366 for (;;) { 367 s = splnet(); 368 IF_DEQUEUE(&ppoeinq, m); 369 splx(s); 370 if (m == NULL) break; 371 data_done = 1; 372 pppoe_data_input(m); 373 } 374 } while (disc_done || data_done); 375} 376 377/* analyze and handle a single received packet while not in session state */ 378static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off) 379{ 380 u_int16_t tag, len; 381 u_int16_t session, plen; 382 struct pppoe_softc *sc; 383 const char *err_msg = NULL; 384 u_int8_t *ac_cookie; 385 size_t ac_cookie_len; 386 struct pppoehdr *ph; 387 struct pppoetag *pt; 388 struct mbuf *n; 389 int noff; 390 struct ether_header *eh; 391 392 if (m->m_len < sizeof(*eh)) { 393 m = m_pullup(m, sizeof(*eh)); 394 if (!m) 395 goto done; 396 } 397 eh = mtod(m, struct ether_header *); 398 off += sizeof(*eh); 399 400 ac_cookie = NULL; 401 ac_cookie_len = 0; 402 session = 0; 403 if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) { 404 printf("pppoe: packet too short: %d\n", m->m_pkthdr.len); 405 goto done; 406 } 407 408 n = m_pulldown(m, off, sizeof(*ph), &noff); 409 if (!n) { 410 printf("pppoe: could not get PPPoE header\n"); 411 m = NULL; 412 goto done; 413 } 414 ph = (struct pppoehdr *)(mtod(n, caddr_t) + noff); 415 if (ph->vertype != PPPOE_VERTYPE) { 416 printf("pppoe: unknown version/type packet: 0x%x\n", 417 ph->vertype); 418 goto done; 419 } 420 session = ntohs(ph->session); 421 plen = ntohs(ph->plen); 422 off += sizeof(*ph); 423 424 if (plen + off > m->m_pkthdr.len) { 425 printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n", 426 m->m_pkthdr.len - off, plen); 427 goto done; 428 } 429 m_adj(m, off + plen - m->m_pkthdr.len); /* ignore trailing garbage */ 430 tag = 0; 431 len = 0; 432 sc = NULL; 433 while (off + sizeof(*pt) < m->m_pkthdr.len) { 434 n = m_pulldown(m, off, sizeof(*pt), &noff); 435 if (!n) { 436 printf("%s: parse error\n", 437 sc ? sc->sc_sppp.pp_if.if_xname : "pppoe"); 438 m = NULL; 439 goto done; 440 } 441 pt = (struct pppoetag *)(mtod(n, caddr_t) + noff); 442 tag = ntohs(pt->tag); 443 len = ntohs(pt->len); 444 if (off + len > m->m_pkthdr.len) { 445 printf("pppoe: tag 0x%x len 0x%x is too long\n", 446 tag, len); 447 goto done; 448 } 449 switch (tag) { 450 case PPPOE_TAG_EOL: 451 goto breakbreak; 452 case PPPOE_TAG_SNAME: 453 break; /* ignored */ 454 case PPPOE_TAG_ACNAME: 455 break; /* ignored */ 456 case PPPOE_TAG_HUNIQUE: 457 if (sc != NULL) 458 break; 459 n = m_pulldown(m, off + sizeof(*pt), len, &noff); 460 if (!n) { 461 err_msg = "TAG HUNIQUE ERROR"; 462 m = NULL; 463 goto done; 464 } 465 sc = pppoe_find_softc_by_hunique(mtod(n, caddr_t) + noff, 466 len, m->m_pkthdr.rcvif); 467 break; 468 case PPPOE_TAG_ACCOOKIE: 469 if (ac_cookie == NULL) { 470 n = m_pulldown(m, off + sizeof(*pt), len, 471 &noff); 472 if (!n) { 473 err_msg = "TAG ACCOOKIE ERROR"; 474 m = NULL; 475 break; 476 } 477 ac_cookie = mtod(n, caddr_t) + noff; 478 ac_cookie_len = len; 479 } 480 break; 481 case PPPOE_TAG_SNAME_ERR: 482 err_msg = "SERVICE NAME ERROR"; 483 break; 484 case PPPOE_TAG_ACSYS_ERR: 485 err_msg = "AC SYSTEM ERROR"; 486 break; 487 case PPPOE_TAG_GENERIC_ERR: 488 err_msg = "GENERIC ERROR"; 489 break; 490 } 491 if (err_msg) { 492 printf("%s: %s\n", 493 sc ? sc->sc_sppp.pp_if.if_xname : "pppoe", 494 err_msg); 495 goto done; 496 } 497 off += sizeof(*pt) + len; 498 } 499breakbreak:; 500 switch (ph->code) { 501 case PPPOE_CODE_PADI: 502 case PPPOE_CODE_PADR: 503 /* ignore, we are no access concentrator */ 504 goto done; 505 case PPPOE_CODE_PADO: 506 if (sc == NULL) { 507 /* be quiete if there is not a single pppoe instance */ 508 if (!LIST_EMPTY(&pppoe_softc_list)) 509 printf("pppoe: received PADO but could not find request for it\n"); 510 goto done; 511 } 512 if (sc->sc_state != PPPOE_STATE_PADI_SENT) { 513 printf("%s: received unexpected PADO\n", 514 sc->sc_sppp.pp_if.if_xname); 515 goto done; 516 } 517 if (ac_cookie) { 518 sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF, 519 M_DONTWAIT); 520 if (sc->sc_ac_cookie == NULL) 521 goto done; 522 sc->sc_ac_cookie_len = ac_cookie_len; 523 memcpy(sc->sc_ac_cookie, ac_cookie, ac_cookie_len); 524 } 525 memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest); 526 callout_stop(&sc->sc_timeout); 527 sc->sc_padr_retried = 0; 528 sc->sc_state = PPPOE_STATE_PADR_SENT; 529 if (pppoe_send_padr(sc) == 0) 530 callout_reset(&sc->sc_timeout, 531 PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), 532 pppoe_timeout, sc); 533 else 534 pppoe_abort_connect(sc); 535 break; 536 case PPPOE_CODE_PADS: 537 if (sc == NULL) 538 goto done; 539 sc->sc_session = session; 540 callout_stop(&sc->sc_timeout); 541 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) 542 printf("%s: session 0x%x connected\n", 543 sc->sc_sppp.pp_if.if_xname, session); 544 sc->sc_state = PPPOE_STATE_SESSION; 545 sc->sc_sppp.pp_up(&sc->sc_sppp); /* notify upper layers */ 546 break; 547 case PPPOE_CODE_PADT: 548 if (sc == NULL) 549 goto done; 550 /* stop timer (we might be about to transmit a PADT ourself) */ 551 callout_stop(&sc->sc_timeout); 552 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) 553 printf("%s: session 0x%x terminated, received PADT\n", 554 sc->sc_sppp.pp_if.if_xname, session); 555 /* clean up softc */ 556 sc->sc_state = PPPOE_STATE_INITIAL; 557 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); 558 if (sc->sc_ac_cookie) { 559 free(sc->sc_ac_cookie, M_MBUF); 560 sc->sc_ac_cookie = NULL; 561 } 562 sc->sc_ac_cookie_len = 0; 563 sc->sc_session = 0; 564 /* signal upper layer */ 565 sc->sc_sppp.pp_down(&sc->sc_sppp); 566 break; 567 default: 568 printf("%s: unknown code (0x%04x) session = 0x%04x\n", 569 sc? sc->sc_sppp.pp_if.if_xname : "pppoe", 570 ph->code, session); 571 break; 572 } 573 574done: 575 m_freem(m); 576 return; 577} 578 579static void 580pppoe_disc_input(struct mbuf *m) 581{ 582 583 /* avoid error messages if there is not a single pppoe instance */ 584 if (!LIST_EMPTY(&pppoe_softc_list)) { 585 KASSERT(m->m_flags & M_PKTHDR); 586 pppoe_dispatch_disc_pkt(m, 0); 587 } else 588 m_freem(m); 589} 590 591static void 592pppoe_data_input(struct mbuf *m) 593{ 594 u_int16_t session, plen; 595 struct pppoe_softc *sc; 596 struct pppoehdr *ph; 597 598 KASSERT(m->m_flags & M_PKTHDR); 599 600 m_adj(m, sizeof(struct ether_header)); 601 if (m->m_pkthdr.len <= PPPOE_HEADERLEN) { 602 printf("pppoe (data): dropping too short packet: %d bytes\n", 603 m->m_pkthdr.len); 604 goto drop; 605 } 606 607 if (m->m_len < sizeof(*ph)) { 608 m = m_pullup(m, sizeof(*ph)); 609 if (!m) { 610 printf("pppoe: could not get PPPoE header\n"); 611 return; 612 } 613 } 614 ph = mtod(m, struct pppoehdr *); 615 616 if (ph->vertype != PPPOE_VERTYPE) { 617 printf("pppoe (data): unknown version/type packet: 0x%x\n", 618 ph->vertype); 619 goto drop; 620 } 621 if (ph->code != 0) 622 goto drop; 623 624 session = ntohs(ph->session); 625 sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); 626 if (sc == NULL) 627 goto drop; 628 629 plen = ntohs(ph->plen); 630 631#if NBPFILTER > 0 632 if(sc->sc_sppp.pp_if.if_bpf) 633 bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); 634#endif 635 636 m_adj(m, PPPOE_HEADERLEN); 637 638#ifdef PPPOE_DEBUG 639 { 640 struct mbuf *p; 641 642 printf("%s: pkthdr.len=%d, pppoe.len=%d", 643 sc->sc_sppp.pp_if.if_xname, 644 m->m_pkthdr.len, plen); 645 p = m; 646 while (p) { 647 printf(" l=%d", p->m_len); 648 p = p->m_next; 649 } 650 printf("\n"); 651 } 652#endif 653 654 if (m->m_pkthdr.len < plen) 655 goto drop; 656 657 /* fix incoming interface pointer (not the raw ethernet interface anymore) */ 658 m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if; 659 660 /* pass packet up and account for it */ 661 sc->sc_sppp.pp_if.if_ipackets++; 662 sppp_input(&sc->sc_sppp.pp_if, m); 663 return; 664 665drop: 666 m_freem(m); 667} 668 669static int 670pppoe_output(struct pppoe_softc *sc, struct mbuf *m) 671{ 672 struct sockaddr dst; 673 struct ether_header *eh; 674 u_int16_t etype; 675 676 if (sc->sc_eth_if == NULL) 677 return EIO; 678 679 memset(&dst, 0, sizeof dst); 680 dst.sa_family = AF_UNSPEC; 681 eh = (struct ether_header*)&dst.sa_data; 682 etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; 683 eh->ether_type = htons(etype); 684 memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest); 685 686#ifdef PPPOE_DEBUG 687 printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n", 688 sc->sc_sppp.pp_if.if_xname, etype, 689 sc->sc_state, sc->sc_session, 690 ether_sprintf((const unsigned char *)&sc->sc_dest), m->m_pkthdr.len); 691#endif 692 693 m->m_flags &= ~(M_BCAST|M_MCAST); 694 sc->sc_sppp.pp_if.if_opackets++; 695 return sc->sc_eth_if->if_output(sc->sc_eth_if, m, &dst, NULL); 696} 697 698static int 699pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data) 700{ 701 struct proc *p = curproc; /* XXX */ 702 struct pppoe_softc *sc = (struct pppoe_softc*)ifp; 703 int error = 0; 704 705 switch (cmd) { 706 case PPPOESETPARMS: 707 { 708 struct pppoediscparms *parms = (struct pppoediscparms*)data; 709 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 710 return error; 711 if (parms->eth_ifname[0] != 0) { 712 sc->sc_eth_if = ifunit(parms->eth_ifname); 713 if (sc->sc_eth_if == NULL) 714 return ENXIO; 715 } 716 if (parms->ac_name) { 717 size_t s; 718 char * p = malloc(parms->ac_name_len + 1, M_DEVBUF, M_WAITOK); 719 copyinstr(parms->ac_name, p, parms->ac_name_len, &s); 720 if (sc->sc_concentrator_name) 721 free(sc->sc_concentrator_name, M_DEVBUF); 722 sc->sc_concentrator_name = p; 723 } 724 if (parms->service_name) { 725 size_t s; 726 char * p = malloc(parms->service_name_len + 1, M_DEVBUF, M_WAITOK); 727 copyinstr(parms->service_name, p, parms->service_name_len, &s); 728 if (sc->sc_service_name) 729 free(sc->sc_service_name, M_DEVBUF); 730 sc->sc_service_name = p; 731 } 732 return 0; 733 } 734 break; 735 case PPPOEGETPARMS: 736 { 737 struct pppoediscparms *parms = (struct pppoediscparms*)data; 738 memset(parms, 0, sizeof *parms); 739 if (sc->sc_eth_if) 740 strncpy(parms->ifname, sc->sc_eth_if->if_xname, IFNAMSIZ); 741 return 0; 742 } 743 break; 744 case PPPOEGETSESSION: 745 { 746 struct pppoeconnectionstate *state = (struct pppoeconnectionstate*)data; 747 state->state = sc->sc_state; 748 state->session_id = sc->sc_session; 749 state->padi_retry_no = sc->sc_padi_retried; 750 state->padr_retry_no = sc->sc_padr_retried; 751 return 0; 752 } 753 break; 754 case SIOCSIFFLAGS: 755 { 756 struct ifreq *ifr = (struct ifreq*) data; 757 /* 758 * Prevent running re-establishment timers overriding 759 * administrators choice. 760 */ 761 if ((ifr->ifr_flags & IFF_UP) == 0 762 && sc->sc_state >= PPPOE_STATE_PADI_SENT 763 && sc->sc_state < PPPOE_STATE_SESSION) { 764 callout_stop(&sc->sc_timeout); 765 sc->sc_state = PPPOE_STATE_INITIAL; 766 sc->sc_padi_retried = 0; 767 sc->sc_padr_retried = 0; 768 memcpy(&sc->sc_dest, etherbroadcastaddr, 769 sizeof(sc->sc_dest)); 770 } 771 return sppp_ioctl(ifp, cmd, data); 772 } 773 case SIOCSIFMTU: 774 { 775 struct ifreq *ifr = (struct ifreq*) data; 776 777 if (ifr->ifr_mtu > PPPOE_MAXMTU) 778 return EINVAL; 779 return sppp_ioctl(ifp, cmd, data); 780 } 781 default: 782 return sppp_ioctl(ifp, cmd, data); 783 } 784 return 0; 785} 786 787/* 788 * Allocate a mbuf/cluster with space to store the given data length 789 * of payload, leaving space for prepending an ethernet header 790 * in front. 791 */ 792static struct mbuf * 793pppoe_get_mbuf(size_t len) 794{ 795 struct mbuf *m; 796 797 MGETHDR(m, M_DONTWAIT, MT_DATA); 798 if (m == NULL) 799 return NULL; 800 if (len + sizeof(struct ether_header) > MHLEN) { 801 MCLGET(m, M_DONTWAIT); 802 if ((m->m_flags & M_EXT) == 0) { 803 struct mbuf *n; 804 MFREE(m, n); 805 return 0; 806 } 807 } 808 m->m_data += sizeof(struct ether_header); 809 m->m_len = len; 810 m->m_pkthdr.len = len; 811 m->m_pkthdr.rcvif = NULL; 812 813 return m; 814} 815 816static int 817pppoe_send_padi(struct pppoe_softc *sc) 818{ 819 struct mbuf *m0; 820 int len, l1, l2; 821 u_int8_t *p; 822 823 if (sc->sc_state >PPPOE_STATE_PADI_SENT) 824 panic("pppoe_send_padi in state %d", sc->sc_state); 825 826 /* calculate length of frame (excluding ethernet header + pppoe header) */ 827 len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ 828 if (sc->sc_service_name != NULL) { 829 l1 = strlen(sc->sc_service_name); 830 len += l1; 831 } 832 if (sc->sc_concentrator_name != NULL) { 833 l2 = strlen(sc->sc_concentrator_name); 834 len += 2 + 2 + l2; 835 } 836 837 /* allocate a buffer */ 838 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); /* header len + payload len */ 839 if (!m0) 840 return ENOBUFS; 841 842 /* fill in pkt */ 843 p = mtod(m0, u_int8_t *); 844 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len); 845 PPPOE_ADD_16(p, PPPOE_TAG_SNAME); 846 if (sc->sc_service_name != NULL) { 847 PPPOE_ADD_16(p, l1); 848 memcpy(p, sc->sc_service_name, l1); 849 p += l1; 850 } else { 851 PPPOE_ADD_16(p, 0); 852 } 853 if (sc->sc_concentrator_name != NULL) { 854 PPPOE_ADD_16(p, PPPOE_TAG_ACNAME); 855 PPPOE_ADD_16(p, l2); 856 memcpy(p, sc->sc_concentrator_name, l2); 857 p += l2; 858 } 859 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); 860 PPPOE_ADD_16(p, sizeof(sc)); 861 memcpy(p, &sc, sizeof sc); 862 863#ifdef PPPOE_DEBUG 864 p += sizeof sc; 865 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) 866 panic("pppoe_send_padi: garbled output len, should be %ld, is %ld", 867 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); 868#endif 869 870 /* send pkt */ 871 return pppoe_output(sc, m0); 872} 873 874static void 875pppoe_timeout(void *arg) 876{ 877 int x, retry_wait; 878 struct pppoe_softc *sc = (struct pppoe_softc*)arg; 879 880#ifdef PPPOE_DEBUG 881 printf("%s: timeout\n", sc->sc_sppp.pp_if.if_xname); 882#endif 883 884 switch (sc->sc_state) { 885 case PPPOE_STATE_PADI_SENT: 886 /* 887 * We have two basic ways of retrying: 888 * - Quick retry mode: try a few times in short sequence 889 * - Slow retry mode: we already had a connection successfully 890 * established and will try infinitely (without user 891 * intervention) 892 * We only enter slow retry mode if IFF_LINK1 (aka autodial) 893 * is not set and we already had a successfull connection. 894 */ 895 896 /* initialize for quick retry mode */ 897 retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried); 898 899 x = splnet(); 900 sc->sc_padi_retried++; 901 if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { 902 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0 && 903 sc->sc_sppp.pp_if.if_ibytes) { 904 /* slow retry mode */ 905 retry_wait = PPPOE_SLOW_RETRY; 906 } else { 907 pppoe_abort_connect(sc); 908 splx(x); 909 return; 910 } 911 } 912 if (pppoe_send_padi(sc) == 0) 913 callout_reset(&sc->sc_timeout, retry_wait, 914 pppoe_timeout, sc); 915 else 916 pppoe_abort_connect(sc); 917 splx(x); 918 break; 919 920 case PPPOE_STATE_PADR_SENT: 921 x = splnet(); 922 sc->sc_padr_retried++; 923 if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) { 924 memcpy(&sc->sc_dest, etherbroadcastaddr, 925 sizeof(sc->sc_dest)); 926 sc->sc_state = PPPOE_STATE_PADI_SENT; 927 sc->sc_padr_retried = 0; 928 if (pppoe_send_padi(sc) == 0) 929 callout_reset(&sc->sc_timeout, 930 PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), 931 pppoe_timeout, sc); 932 else 933 pppoe_abort_connect(sc); 934 splx(x); 935 return; 936 } 937 if (pppoe_send_padr(sc) == 0) 938 callout_reset(&sc->sc_timeout, 939 PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), 940 pppoe_timeout, sc); 941 else 942 pppoe_abort_connect(sc); 943 splx(x); 944 break; 945 case PPPOE_STATE_CLOSING: 946 pppoe_disconnect(sc); 947 break; 948 default: 949 return; /* all done, work in peace */ 950 } 951} 952 953/* Start a connection (i.e. initiate discovery phase) */ 954static int 955pppoe_connect(struct pppoe_softc *sc) 956{ 957 int x, err; 958 959 if (sc->sc_state != PPPOE_STATE_INITIAL) 960 return EBUSY; 961 962 x = splnet(); 963 sc->sc_state = PPPOE_STATE_PADI_SENT; 964 sc->sc_padr_retried = 0; 965 err = pppoe_send_padi(sc); 966 if (err == 0) 967 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, 968 pppoe_timeout, sc); 969 else 970 pppoe_abort_connect(sc); 971 splx(x); 972 return err; 973} 974 975/* disconnect */ 976static int 977pppoe_disconnect(struct pppoe_softc *sc) 978{ 979 int err, x; 980 981 x = splnet(); 982 983 if (sc->sc_state < PPPOE_STATE_SESSION) 984 err = EBUSY; 985 else { 986 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) 987 printf("%s: disconnecting\n", 988 sc->sc_sppp.pp_if.if_xname); 989 err = pppoe_send_padt(sc); 990 } 991 992 /* cleanup softc */ 993 sc->sc_state = PPPOE_STATE_INITIAL; 994 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); 995 if (sc->sc_ac_cookie) { 996 free(sc->sc_ac_cookie, M_MBUF); 997 sc->sc_ac_cookie = NULL; 998 } 999 sc->sc_ac_cookie_len = 0; 1000 sc->sc_session = 0; 1001 1002 /* notify upper layer */ 1003 sc->sc_sppp.pp_down(&sc->sc_sppp); 1004 1005 splx(x); 1006 1007 return err; 1008} 1009 1010/* Connection attempt aborted */ 1011static void 1012pppoe_abort_connect(struct pppoe_softc *sc) 1013{ 1014 printf("%s: could not establish connection\n", 1015 sc->sc_sppp.pp_if.if_xname); 1016 sc->sc_state = PPPOE_STATE_INITIAL; 1017 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); 1018 1019 /* notify upper layer */ 1020 sc->sc_sppp.pp_down(&sc->sc_sppp); 1021} 1022 1023/* Send a PADR packet */ 1024static int 1025pppoe_send_padr(struct pppoe_softc *sc) 1026{ 1027 struct mbuf *m0; 1028 u_int8_t *p; 1029 size_t len, l1; 1030 1031 if (sc->sc_state != PPPOE_STATE_PADR_SENT) 1032 return EIO; 1033 1034 len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ 1035 if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ 1036 l1 = strlen(sc->sc_service_name); 1037 len += l1; 1038 } 1039 if (sc->sc_ac_cookie_len > 0) 1040 len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ 1041 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); 1042 if (!m0) 1043 return ENOBUFS; 1044 p = mtod(m0, u_int8_t *); 1045 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); 1046 PPPOE_ADD_16(p, PPPOE_TAG_SNAME); 1047 if (sc->sc_service_name != NULL) { 1048 PPPOE_ADD_16(p, l1); 1049 memcpy(p, sc->sc_service_name, l1); 1050 p += l1; 1051 } else { 1052 PPPOE_ADD_16(p, 0); 1053 } 1054 if (sc->sc_ac_cookie_len > 0) { 1055 PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); 1056 PPPOE_ADD_16(p, sc->sc_ac_cookie_len); 1057 memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len); 1058 p += sc->sc_ac_cookie_len; 1059 } 1060 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); 1061 PPPOE_ADD_16(p, sizeof(sc)); 1062 memcpy(p, &sc, sizeof sc); 1063 1064#ifdef PPPOE_DEBUG 1065 p += sizeof sc; 1066 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) 1067 panic("pppoe_send_padr: garbled output len, should be %ld, is %ld", 1068 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); 1069#endif 1070 1071 return pppoe_output(sc, m0); 1072} 1073 1074/* send a PADT packet */ 1075static int 1076pppoe_send_padt(struct pppoe_softc *sc) 1077{ 1078 struct mbuf *m0; 1079 u_int8_t *p; 1080 1081 if (sc->sc_state < PPPOE_STATE_SESSION) 1082 return EIO; 1083 1084#ifdef PPPOE_DEBUG 1085 printf("%s: sending PADT\n", sc->sc_sppp.pp_if.if_xname); 1086#endif 1087 m0 = pppoe_get_mbuf(PPPOE_HEADERLEN); 1088 if (!m0) 1089 return ENOBUFS; 1090 p = mtod(m0, u_int8_t *); 1091 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, sc->sc_session, 0); 1092 return pppoe_output(sc, m0); 1093} 1094 1095static void 1096pppoe_tls(struct sppp *sp) 1097{ 1098 struct pppoe_softc *sc = (void *)sp; 1099 if (sc->sc_state != PPPOE_STATE_INITIAL) 1100 return; 1101 pppoe_connect(sc); 1102} 1103 1104static void 1105pppoe_tlf(struct sppp *sp) 1106{ 1107 struct pppoe_softc *sc = (void *)sp; 1108 if (sc->sc_state < PPPOE_STATE_SESSION) 1109 return; 1110 /* 1111 * Do not call pppoe_disconnect here, the upper layer state 1112 * machine gets confused by this. We must return from this 1113 * function and defer disconnecting to the timeout handler. 1114 */ 1115 sc->sc_state = PPPOE_STATE_CLOSING; 1116 callout_reset(&sc->sc_timeout, hz/50, pppoe_timeout, sc); 1117} 1118 1119static void 1120pppoe_start(struct ifnet *ifp) 1121{ 1122 struct pppoe_softc *sc = (void *)ifp; 1123 struct mbuf *m; 1124 u_int8_t *p; 1125 size_t len; 1126 1127 if (sppp_isempty(ifp)) 1128 return; 1129 1130 /* are we ready to proccess data yet? */ 1131 if (sc->sc_state < PPPOE_STATE_SESSION) { 1132 sppp_flush(&sc->sc_sppp.pp_if); 1133 return; 1134 } 1135 1136 while ((m = sppp_dequeue(ifp)) != NULL) { 1137 len = m->m_pkthdr.len; 1138 M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT); 1139 if (m == NULL) { 1140 m_free(m); 1141 break; 1142 } 1143 p = mtod(m, u_int8_t *); 1144 PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); 1145 1146#if NBPFILTER > 0 1147 if(sc->sc_sppp.pp_if.if_bpf) 1148 bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); 1149#endif 1150 1151 pppoe_output(sc, m); 1152 } 1153} 1154