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