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