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