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