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