1 /***************************************************************************** 2 * pppoe.c - PPP Over Ethernet implementation for lwIP. 3 * 4 * Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. 5 * 6 * The authors hereby grant permission to use, copy, modify, distribute, 7 * and license this software and its documentation for any purpose, provided 8 * that existing copyright notices are retained in all copies and that this 9 * notice and the following disclaimer are included verbatim in any 10 * distributions. No written agreement, license, or royalty fee is required 11 * for any of the authorized uses. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 ****************************************************************************** 25 * REVISION HISTORY 26 * 27 * 06-01-01 Marc Boucher <marc@mbsi.ca> 28 * Ported to lwIP. 29 *****************************************************************************/ 30 31 32 33 /* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ 34 35 /*- 36 * Copyright (c) 2002 The NetBSD Foundation, Inc. 37 * All rights reserved. 38 * 39 * This code is derived from software contributed to The NetBSD Foundation 40 * by Martin Husemann <martin@NetBSD.org>. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by the NetBSD 53 * Foundation, Inc. and its contributors. 54 * 4. Neither the name of The NetBSD Foundation nor the names of its 55 * contributors may be used to endorse or promote products derived 56 * from this software without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 59 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 60 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 61 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 62 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 63 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 64 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 65 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 66 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 67 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 68 * POSSIBILITY OF SUCH DAMAGE. 69 */ 70 71 #include "netif/ppp/ppp_opts.h" 72 #if PPP_SUPPORT && PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ 73 74 #if 0 /* UNUSED */ 75 #include <string.h> 76 #include <stdio.h> 77 #endif /* UNUSED */ 78 79 #include "lwip/timeouts.h" 80 #include "lwip/memp.h" 81 #include "lwip/stats.h" 82 #include "lwip/snmp.h" 83 84 #include "netif/ethernet.h" 85 #include "netif/ppp/ppp_impl.h" 86 #include "netif/ppp/lcp.h" 87 #include "netif/ppp/ipcp.h" 88 #include "netif/ppp/pppoe.h" 89 90 /* Memory pool */ 91 LWIP_MEMPOOL_DECLARE(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") 92 93 /* Add a 16 bit unsigned value to a buffer pointed to by PTR */ 94 #define PPPOE_ADD_16(PTR, VAL) \ 95 *(PTR)++ = (u8_t)((VAL) / 256); \ 96 *(PTR)++ = (u8_t)((VAL) % 256) 97 98 /* Add a complete PPPoE header to the buffer pointed to by PTR */ 99 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ 100 *(PTR)++ = PPPOE_VERTYPE; \ 101 *(PTR)++ = (CODE); \ 102 PPPOE_ADD_16(PTR, SESS); \ 103 PPPOE_ADD_16(PTR, LEN) 104 105 #define PPPOE_DISC_TIMEOUT (5*1000) /* base for quick timeout calculation */ 106 #define PPPOE_SLOW_RETRY (60*1000) /* persistent retry interval */ 107 #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ 108 #define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ 109 110 #ifdef PPPOE_SERVER 111 #error "PPPOE_SERVER is not yet supported under lwIP!" 112 /* from if_spppsubr.c */ 113 #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ 114 #endif 115 116 #define PPPOE_ERRORSTRING_LEN 64 117 118 119 /* callbacks called from PPP core */ 120 static err_t pppoe_write(ppp_pcb *ppp, void *ctx, struct pbuf *p); 121 static err_t pppoe_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol); 122 static void pppoe_connect(ppp_pcb *ppp, void *ctx); 123 static void pppoe_disconnect(ppp_pcb *ppp, void *ctx); 124 static err_t pppoe_destroy(ppp_pcb *ppp, void *ctx); 125 126 /* management routines */ 127 static void pppoe_abort_connect(struct pppoe_softc *); 128 #if 0 /* UNUSED */ 129 static void pppoe_clear_softc(struct pppoe_softc *, const char *); 130 #endif /* UNUSED */ 131 132 /* internal timeout handling */ 133 static void pppoe_timeout(void *); 134 135 /* sending actual protocol control packets */ 136 static err_t pppoe_send_padi(struct pppoe_softc *); 137 static err_t pppoe_send_padr(struct pppoe_softc *); 138 #ifdef PPPOE_SERVER 139 static err_t pppoe_send_pado(struct pppoe_softc *); 140 static err_t pppoe_send_pads(struct pppoe_softc *); 141 #endif 142 static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *); 143 144 /* internal helper functions */ 145 static err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); 146 static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif); 147 static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif); 148 149 /** linked list of created pppoe interfaces */ 150 static struct pppoe_softc *pppoe_softc_list; 151 152 /* Callbacks structure for PPP core */ 153 static const struct link_callbacks pppoe_callbacks = { 154 pppoe_connect, 155 #if PPP_SERVER 156 NULL, 157 #endif /* PPP_SERVER */ 158 pppoe_disconnect, 159 pppoe_destroy, 160 pppoe_write, 161 pppoe_netif_output, 162 NULL, 163 NULL 164 }; 165 166 /* 167 * Create a new PPP Over Ethernet (PPPoE) connection. 168 * 169 * Return 0 on success, an error code on failure. 170 */ 171 ppp_pcb *pppoe_create(struct netif *pppif, 172 struct netif *ethif, 173 const char *service_name, const char *concentrator_name, 174 ppp_link_status_cb_fn link_status_cb, void *ctx_cb) 175 { 176 ppp_pcb *ppp; 177 struct pppoe_softc *sc; 178 #if PPPOE_SCNAME_SUPPORT 179 size_t l; 180 #else /* PPPOE_SCNAME_SUPPORT */ 181 LWIP_UNUSED_ARG(service_name); 182 LWIP_UNUSED_ARG(concentrator_name); 183 #endif /* PPPOE_SCNAME_SUPPORT */ 184 LWIP_ASSERT_CORE_LOCKED(); 185 186 #if PPPOE_SCNAME_SUPPORT 187 /* 188 * Check that service_name and concentrator_name strings length will 189 * not trigger integer overflows when computing packets length. 190 */ 191 l = strlen(service_name); 192 if (l > 1024) { 193 return NULL; 194 } 195 l = strlen(concentrator_name); 196 if (l > 1024) { 197 return NULL; 198 } 199 #endif /* PPPOE_SCNAME_SUPPORT */ 200 201 sc = (struct pppoe_softc *)LWIP_MEMPOOL_ALLOC(PPPOE_IF); 202 if (sc == NULL) { 203 return NULL; 204 } 205 206 ppp = ppp_new(pppif, &pppoe_callbacks, sc, link_status_cb, ctx_cb); 207 if (ppp == NULL) { 208 LWIP_MEMPOOL_FREE(PPPOE_IF, sc); 209 return NULL; 210 } 211 212 memset(sc, 0, sizeof(struct pppoe_softc)); 213 sc->pcb = ppp; 214 sc->sc_ethif = ethif; 215 #if PPPOE_SCNAME_SUPPORT 216 sc->sc_service_name = service_name; 217 sc->sc_concentrator_name = concentrator_name; 218 #endif /* PPPOE_SCNAME_SUPPORT */ 219 /* put the new interface at the head of the list */ 220 sc->next = pppoe_softc_list; 221 pppoe_softc_list = sc; 222 return ppp; 223 } 224 225 /* Called by PPP core */ 226 static err_t pppoe_write(ppp_pcb *ppp, void *ctx, struct pbuf *p) { 227 struct pppoe_softc *sc = (struct pppoe_softc *)ctx; 228 struct pbuf *ph; /* Ethernet + PPPoE header */ 229 err_t ret; 230 #if MIB2_STATS 231 u16_t tot_len; 232 #else /* MIB2_STATS */ 233 LWIP_UNUSED_ARG(ppp); 234 #endif /* MIB2_STATS */ 235 236 /* skip address & flags */ 237 pbuf_remove_header(p, 2); 238 239 ph = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM); 240 if(!ph) { 241 LINK_STATS_INC(link.memerr); 242 LINK_STATS_INC(link.proterr); 243 MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); 244 pbuf_free(p); 245 return ERR_MEM; 246 } 247 248 pbuf_remove_header(ph, PPPOE_HEADERLEN); /* hide PPPoE header */ 249 pbuf_cat(ph, p); 250 #if MIB2_STATS 251 tot_len = ph->tot_len; 252 #endif /* MIB2_STATS */ 253 254 ret = pppoe_xmit(sc, ph); 255 if (ret != ERR_OK) { 256 LINK_STATS_INC(link.err); 257 MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); 258 return ret; 259 } 260 261 MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, (u16_t)tot_len); 262 MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); 263 LINK_STATS_INC(link.xmit); 264 return ERR_OK; 265 } 266 267 /* Called by PPP core */ 268 static err_t pppoe_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol) { 269 struct pppoe_softc *sc = (struct pppoe_softc *)ctx; 270 struct pbuf *pb; 271 u8_t *pl; 272 err_t err; 273 #if MIB2_STATS 274 u16_t tot_len; 275 #else /* MIB2_STATS */ 276 LWIP_UNUSED_ARG(ppp); 277 #endif /* MIB2_STATS */ 278 279 /* @todo: try to use pbuf_header() here! */ 280 pb = pbuf_alloc(PBUF_LINK, PPPOE_HEADERLEN + sizeof(protocol), PBUF_RAM); 281 if(!pb) { 282 LINK_STATS_INC(link.memerr); 283 LINK_STATS_INC(link.proterr); 284 MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); 285 return ERR_MEM; 286 } 287 288 pbuf_remove_header(pb, PPPOE_HEADERLEN); 289 290 pl = (u8_t*)pb->payload; 291 PUTSHORT(protocol, pl); 292 293 pbuf_chain(pb, p); 294 #if MIB2_STATS 295 tot_len = pb->tot_len; 296 #endif /* MIB2_STATS */ 297 298 if( (err = pppoe_xmit(sc, pb)) != ERR_OK) { 299 LINK_STATS_INC(link.err); 300 MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); 301 return err; 302 } 303 304 MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, tot_len); 305 MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); 306 LINK_STATS_INC(link.xmit); 307 return ERR_OK; 308 } 309 310 static err_t 311 pppoe_destroy(ppp_pcb *ppp, void *ctx) 312 { 313 struct pppoe_softc *sc = (struct pppoe_softc *)ctx; 314 struct pppoe_softc **copp, *freep; 315 LWIP_UNUSED_ARG(ppp); 316 317 sys_untimeout(pppoe_timeout, sc); 318 319 /* remove interface from list */ 320 for (copp = &pppoe_softc_list; (freep = *copp); copp = &freep->next) { 321 if (freep == sc) { 322 *copp = freep->next; 323 break; 324 } 325 } 326 LWIP_MEMPOOL_FREE(PPPOE_IF, sc); 327 328 return ERR_OK; 329 } 330 331 /* 332 * Find the interface handling the specified session. 333 * Note: O(number of sessions open), this is a client-side only, mean 334 * and lean implementation, so number of open sessions typically should 335 * be 1. 336 */ 337 static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif) { 338 struct pppoe_softc *sc; 339 340 for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { 341 if (sc->sc_state == PPPOE_STATE_SESSION 342 && sc->sc_session == session 343 && sc->sc_ethif == rcvif) { 344 return sc; 345 } 346 } 347 return NULL; 348 } 349 350 /* Check host unique token passed and return appropriate softc pointer, 351 * or NULL if token is bogus. */ 352 static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) { 353 struct pppoe_softc *sc, *t; 354 355 if (len != sizeof sc) { 356 return NULL; 357 } 358 MEMCPY(&t, token, len); 359 360 for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { 361 if (sc == t) { 362 break; 363 } 364 } 365 366 if (sc == NULL) { 367 PPPDEBUG(LOG_DEBUG, ("pppoe: alien host unique tag, no session found\n")); 368 return NULL; 369 } 370 371 /* should be safe to access *sc now */ 372 if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) { 373 PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n", 374 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state)); 375 return NULL; 376 } 377 if (sc->sc_ethif != rcvif) { 378 PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": wrong interface, not accepting host unique\n", 379 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); 380 return NULL; 381 } 382 return sc; 383 } 384 385 /* analyze and handle a single received packet while not in session state */ 386 void 387 pppoe_disc_input(struct netif *netif, struct pbuf *pb) 388 { 389 u16_t tag, len, off; 390 u16_t session, plen; 391 struct pppoe_softc *sc; 392 #if PPP_DEBUG 393 const char *err_msg = NULL; 394 #endif /* PPP_DEBUG */ 395 u8_t *ac_cookie; 396 u16_t ac_cookie_len; 397 #ifdef PPPOE_SERVER 398 u8_t *hunique; 399 size_t hunique_len; 400 #endif 401 struct pppoehdr *ph; 402 struct pppoetag pt; 403 int err; 404 struct eth_hdr *ethhdr; 405 406 /* don't do anything if there is not a single PPPoE instance */ 407 if (pppoe_softc_list == NULL) { 408 pbuf_free(pb); 409 return; 410 } 411 412 pb = pbuf_coalesce(pb, PBUF_RAW); 413 if (pb->next != NULL) { 414 PPPDEBUG(LOG_DEBUG, ("pppoe: pbuf_coalesce failed: %d\n", pb->tot_len)); 415 goto done; 416 } 417 418 ethhdr = (struct eth_hdr *)pb->payload; 419 420 ac_cookie = NULL; 421 ac_cookie_len = 0; 422 #ifdef PPPOE_SERVER 423 hunique = NULL; 424 hunique_len = 0; 425 #endif 426 session = 0; 427 off = sizeof(struct eth_hdr) + sizeof(struct pppoehdr); 428 if (pb->len < off) { 429 PPPDEBUG(LOG_DEBUG, ("pppoe: packet too short: %d\n", pb->len)); 430 goto done; 431 } 432 433 ph = (struct pppoehdr *) (ethhdr + 1); 434 if (ph->vertype != PPPOE_VERTYPE) { 435 PPPDEBUG(LOG_DEBUG, ("pppoe: unknown version/type packet: 0x%x\n", ph->vertype)); 436 goto done; 437 } 438 session = lwip_ntohs(ph->session); 439 plen = lwip_ntohs(ph->plen); 440 441 if (plen > (pb->len - off)) { 442 PPPDEBUG(LOG_DEBUG, ("pppoe: packet content does not fit: data available = %d, packet size = %u\n", 443 pb->len - off, plen)); 444 goto done; 445 } 446 if(pb->tot_len == pb->len) { 447 u16_t framelen = off + plen; 448 if (framelen < pb->len) { 449 /* ignore trailing garbage */ 450 pb->tot_len = pb->len = framelen; 451 } 452 } 453 tag = 0; 454 len = 0; 455 sc = NULL; 456 while (off + sizeof(pt) <= pb->len) { 457 MEMCPY(&pt, (u8_t*)pb->payload + off, sizeof(pt)); 458 tag = lwip_ntohs(pt.tag); 459 len = lwip_ntohs(pt.len); 460 if (off + sizeof(pt) + len > pb->len) { 461 PPPDEBUG(LOG_DEBUG, ("pppoe: tag 0x%x len 0x%x is too long\n", tag, len)); 462 goto done; 463 } 464 switch (tag) { 465 case PPPOE_TAG_EOL: 466 goto breakbreak; 467 case PPPOE_TAG_SNAME: 468 break; /* ignored */ 469 case PPPOE_TAG_ACNAME: 470 break; /* ignored */ 471 case PPPOE_TAG_HUNIQUE: 472 if (sc != NULL) { 473 break; 474 } 475 #ifdef PPPOE_SERVER 476 hunique = (u8_t*)pb->payload + off + sizeof(pt); 477 hunique_len = len; 478 #endif 479 sc = pppoe_find_softc_by_hunique((u8_t*)pb->payload + off + sizeof(pt), len, netif); 480 break; 481 case PPPOE_TAG_ACCOOKIE: 482 if (ac_cookie == NULL) { 483 if (len > PPPOE_MAX_AC_COOKIE_LEN) { 484 PPPDEBUG(LOG_DEBUG, ("pppoe: AC cookie is too long: len = %d, max = %d\n", len, PPPOE_MAX_AC_COOKIE_LEN)); 485 goto done; 486 } 487 ac_cookie = (u8_t*)pb->payload + off + sizeof(pt); 488 ac_cookie_len = len; 489 } 490 break; 491 #if PPP_DEBUG 492 case PPPOE_TAG_SNAME_ERR: 493 err_msg = "SERVICE NAME ERROR"; 494 break; 495 case PPPOE_TAG_ACSYS_ERR: 496 err_msg = "AC SYSTEM ERROR"; 497 break; 498 case PPPOE_TAG_GENERIC_ERR: 499 err_msg = "GENERIC ERROR"; 500 break; 501 #endif /* PPP_DEBUG */ 502 default: 503 break; 504 } 505 #if PPP_DEBUG 506 if (err_msg != NULL) { 507 char error_tmp[PPPOE_ERRORSTRING_LEN]; 508 u16_t error_len = LWIP_MIN(len, sizeof(error_tmp)-1); 509 strncpy(error_tmp, (char*)pb->payload + off + sizeof(pt), error_len); 510 error_tmp[error_len] = '\0'; 511 if (sc) { 512 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": %s: %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err_msg, error_tmp)); 513 } else { 514 PPPDEBUG(LOG_DEBUG, ("pppoe: %s: %s\n", err_msg, error_tmp)); 515 } 516 } 517 #endif /* PPP_DEBUG */ 518 off += sizeof(pt) + len; 519 } 520 521 breakbreak:; 522 switch (ph->code) { 523 case PPPOE_CODE_PADI: 524 #ifdef PPPOE_SERVER 525 /* 526 * got service name, concentrator name, and/or host unique. 527 * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP. 528 */ 529 if (LIST_EMPTY(&pppoe_softc_list)) { 530 goto done; 531 } 532 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { 533 if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) { 534 continue; 535 } 536 if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { 537 continue; 538 } 539 if (sc->sc_state == PPPOE_STATE_INITIAL) { 540 break; 541 } 542 } 543 if (sc == NULL) { 544 /* PPPDEBUG(LOG_DEBUG, ("pppoe: free passive interface is not found\n")); */ 545 goto done; 546 } 547 if (hunique) { 548 if (sc->sc_hunique) { 549 mem_free(sc->sc_hunique); 550 } 551 sc->sc_hunique = mem_malloc(hunique_len); 552 if (sc->sc_hunique == NULL) { 553 goto done; 554 } 555 sc->sc_hunique_len = hunique_len; 556 MEMCPY(sc->sc_hunique, hunique, hunique_len); 557 } 558 MEMCPY(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest); 559 sc->sc_state = PPPOE_STATE_PADO_SENT; 560 pppoe_send_pado(sc); 561 break; 562 #endif /* PPPOE_SERVER */ 563 case PPPOE_CODE_PADR: 564 #ifdef PPPOE_SERVER 565 /* 566 * get sc from ac_cookie if IFF_PASSIVE 567 */ 568 if (ac_cookie == NULL) { 569 /* be quiet if there is not a single pppoe instance */ 570 PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but not includes ac_cookie\n")); 571 goto done; 572 } 573 sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, netif); 574 if (sc == NULL) { 575 /* be quiet if there is not a single pppoe instance */ 576 if (!LIST_EMPTY(&pppoe_softc_list)) { 577 PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but could not find request for it\n")); 578 } 579 goto done; 580 } 581 if (sc->sc_state != PPPOE_STATE_PADO_SENT) { 582 PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); 583 goto done; 584 } 585 if (hunique) { 586 if (sc->sc_hunique) { 587 mem_free(sc->sc_hunique); 588 } 589 sc->sc_hunique = mem_malloc(hunique_len); 590 if (sc->sc_hunique == NULL) { 591 goto done; 592 } 593 sc->sc_hunique_len = hunique_len; 594 MEMCPY(sc->sc_hunique, hunique, hunique_len); 595 } 596 pppoe_send_pads(sc); 597 sc->sc_state = PPPOE_STATE_SESSION; 598 ppp_start(sc->pcb); /* notify upper layers */ 599 break; 600 #else 601 /* ignore, we are no access concentrator */ 602 goto done; 603 #endif /* PPPOE_SERVER */ 604 case PPPOE_CODE_PADO: 605 if (sc == NULL) { 606 /* be quiet if there is not a single pppoe instance */ 607 if (pppoe_softc_list != NULL) { 608 PPPDEBUG(LOG_DEBUG, ("pppoe: received PADO but could not find request for it\n")); 609 } 610 goto done; 611 } 612 if (sc->sc_state != PPPOE_STATE_PADI_SENT) { 613 PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); 614 goto done; 615 } 616 if (ac_cookie) { 617 sc->sc_ac_cookie_len = ac_cookie_len; 618 MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len); 619 } 620 MEMCPY(&sc->sc_dest, ethhdr->src.addr, sizeof(sc->sc_dest.addr)); 621 sys_untimeout(pppoe_timeout, sc); 622 sc->sc_padr_retried = 0; 623 sc->sc_state = PPPOE_STATE_PADR_SENT; 624 if ((err = pppoe_send_padr(sc)) != 0) { 625 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); 626 LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ 627 } 628 sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); 629 break; 630 case PPPOE_CODE_PADS: 631 if (sc == NULL) { 632 goto done; 633 } 634 sc->sc_session = session; 635 sys_untimeout(pppoe_timeout, sc); 636 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session)); 637 sc->sc_state = PPPOE_STATE_SESSION; 638 ppp_start(sc->pcb); /* notify upper layers */ 639 break; 640 case PPPOE_CODE_PADT: 641 /* Don't disconnect here, we let the LCP Echo/Reply find the fact 642 * that PPP session is down. Asking the PPP stack to end the session 643 * require strict checking about the PPP phase to prevent endless 644 * disconnection loops. 645 */ 646 #if 0 /* UNUSED */ 647 if (sc == NULL) { /* PADT frames are rarely sent with a hunique tag, this is actually almost always true */ 648 goto done; 649 } 650 pppoe_clear_softc(sc, "received PADT"); 651 #endif /* UNUSED */ 652 break; 653 default: 654 if(sc) { 655 PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n", 656 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, 657 (u16_t)ph->code, session)); 658 } else { 659 PPPDEBUG(LOG_DEBUG, ("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session)); 660 } 661 break; 662 } 663 664 done: 665 pbuf_free(pb); 666 return; 667 } 668 669 void 670 pppoe_data_input(struct netif *netif, struct pbuf *pb) 671 { 672 u16_t session, plen; 673 struct pppoe_softc *sc; 674 struct pppoehdr *ph; 675 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS 676 u8_t shost[ETHER_ADDR_LEN]; 677 #endif 678 679 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS 680 MEMCPY(shost, ((struct eth_hdr *)pb->payload)->src.addr, sizeof(shost)); 681 #endif 682 if (pbuf_remove_header(pb, sizeof(struct eth_hdr)) != 0) { 683 /* bail out */ 684 PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_remove_header failed\n")); 685 LINK_STATS_INC(link.lenerr); 686 goto drop; 687 } 688 689 if (pb->len < sizeof(*ph)) { 690 PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: could not get PPPoE header\n")); 691 goto drop; 692 } 693 ph = (struct pppoehdr *)pb->payload; 694 695 if (ph->vertype != PPPOE_VERTYPE) { 696 PPPDEBUG(LOG_DEBUG, ("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype)); 697 goto drop; 698 } 699 if (ph->code != 0) { 700 goto drop; 701 } 702 703 session = lwip_ntohs(ph->session); 704 sc = pppoe_find_softc_by_session(session, netif); 705 if (sc == NULL) { 706 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS 707 PPPDEBUG(LOG_DEBUG, ("pppoe: input for unknown session 0x%x, sending PADT\n", session)); 708 pppoe_send_padt(netif, session, shost); 709 #endif 710 goto drop; 711 } 712 713 plen = lwip_ntohs(ph->plen); 714 715 if (pbuf_remove_header(pb, PPPOE_HEADERLEN) != 0) { 716 /* bail out */ 717 PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_remove_header PPPOE_HEADERLEN failed\n")); 718 LINK_STATS_INC(link.lenerr); 719 goto drop; 720 } 721 722 PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n", 723 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, 724 pb->len, plen)); 725 726 if (pb->tot_len < plen) { 727 goto drop; 728 } 729 730 /* Dispatch the packet thereby consuming it. */ 731 ppp_input(sc->pcb, pb); 732 return; 733 734 drop: 735 pbuf_free(pb); 736 } 737 738 static err_t 739 pppoe_output(struct pppoe_softc *sc, struct pbuf *pb) 740 { 741 struct eth_hdr *ethhdr; 742 u16_t etype; 743 err_t res; 744 745 /* make room for Ethernet header - should not fail */ 746 if (pbuf_add_header(pb, sizeof(struct eth_hdr)) != 0) { 747 /* bail out */ 748 PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_output: could not allocate room for Ethernet header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); 749 LINK_STATS_INC(link.lenerr); 750 pbuf_free(pb); 751 return ERR_BUF; 752 } 753 ethhdr = (struct eth_hdr *)pb->payload; 754 etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC; 755 ethhdr->type = lwip_htons(etype); 756 MEMCPY(ðhdr->dest.addr, &sc->sc_dest.addr, sizeof(ethhdr->dest.addr)); 757 MEMCPY(ðhdr->src.addr, &sc->sc_ethif->hwaddr, sizeof(ethhdr->src.addr)); 758 759 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n", 760 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype, 761 sc->sc_state, sc->sc_session, 762 sc->sc_dest.addr[0], sc->sc_dest.addr[1], sc->sc_dest.addr[2], sc->sc_dest.addr[3], sc->sc_dest.addr[4], sc->sc_dest.addr[5], 763 pb->tot_len)); 764 765 res = sc->sc_ethif->linkoutput(sc->sc_ethif, pb); 766 767 pbuf_free(pb); 768 769 return res; 770 } 771 772 static err_t 773 pppoe_send_padi(struct pppoe_softc *sc) 774 { 775 struct pbuf *pb; 776 u8_t *p; 777 size_t len; 778 #if PPPOE_SCNAME_SUPPORT 779 size_t l1 = 0, l2 = 0; /* XXX: gcc */ 780 #endif /* PPPOE_SCNAME_SUPPORT */ 781 782 /* calculate length of frame (excluding ethernet header + pppoe header) */ 783 len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ 784 #if PPPOE_SCNAME_SUPPORT 785 if (sc->sc_service_name != NULL) { 786 l1 = strlen(sc->sc_service_name); 787 len += l1; 788 } 789 if (sc->sc_concentrator_name != NULL) { 790 l2 = strlen(sc->sc_concentrator_name); 791 len += 2 + 2 + l2; 792 } 793 #endif /* PPPOE_SCNAME_SUPPORT */ 794 LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", 795 sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); 796 797 /* allocate a buffer */ 798 pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); 799 if (!pb) { 800 return ERR_MEM; 801 } 802 LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); 803 804 p = (u8_t*)pb->payload; 805 /* fill in pkt */ 806 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len); 807 PPPOE_ADD_16(p, PPPOE_TAG_SNAME); 808 #if PPPOE_SCNAME_SUPPORT 809 if (sc->sc_service_name != NULL) { 810 PPPOE_ADD_16(p, l1); 811 MEMCPY(p, sc->sc_service_name, l1); 812 p += l1; 813 } else 814 #endif /* PPPOE_SCNAME_SUPPORT */ 815 { 816 PPPOE_ADD_16(p, 0); 817 } 818 #if PPPOE_SCNAME_SUPPORT 819 if (sc->sc_concentrator_name != NULL) { 820 PPPOE_ADD_16(p, PPPOE_TAG_ACNAME); 821 PPPOE_ADD_16(p, l2); 822 MEMCPY(p, sc->sc_concentrator_name, l2); 823 p += l2; 824 } 825 #endif /* PPPOE_SCNAME_SUPPORT */ 826 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); 827 PPPOE_ADD_16(p, sizeof(sc)); 828 MEMCPY(p, &sc, sizeof sc); 829 830 /* send pkt */ 831 return pppoe_output(sc, pb); 832 } 833 834 static void 835 pppoe_timeout(void *arg) 836 { 837 u32_t retry_wait; 838 int err; 839 struct pppoe_softc *sc = (struct pppoe_softc*)arg; 840 841 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); 842 843 switch (sc->sc_state) { 844 case PPPOE_STATE_PADI_SENT: 845 /* 846 * We have two basic ways of retrying: 847 * - Quick retry mode: try a few times in short sequence 848 * - Slow retry mode: we already had a connection successfully 849 * established and will try infinitely (without user 850 * intervention) 851 * We only enter slow retry mode if IFF_LINK1 (aka autodial) 852 * is not set. 853 */ 854 if (sc->sc_padi_retried < 0xff) { 855 sc->sc_padi_retried++; 856 } 857 if (!sc->pcb->settings.persist && sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { 858 #if 0 859 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { 860 /* slow retry mode */ 861 retry_wait = PPPOE_SLOW_RETRY; 862 } else 863 #endif 864 { 865 pppoe_abort_connect(sc); 866 return; 867 } 868 } 869 /* initialize for quick retry mode */ 870 retry_wait = LWIP_MIN(PPPOE_DISC_TIMEOUT * sc->sc_padi_retried, PPPOE_SLOW_RETRY); 871 if ((err = pppoe_send_padi(sc)) != 0) { 872 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); 873 LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ 874 } 875 sys_timeout(retry_wait, pppoe_timeout, sc); 876 break; 877 878 case PPPOE_STATE_PADR_SENT: 879 sc->sc_padr_retried++; 880 if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) { 881 MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); 882 sc->sc_state = PPPOE_STATE_PADI_SENT; 883 sc->sc_padr_retried = 0; 884 if ((err = pppoe_send_padi(sc)) != 0) { 885 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); 886 LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ 887 } 888 sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); 889 return; 890 } 891 if ((err = pppoe_send_padr(sc)) != 0) { 892 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); 893 LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ 894 } 895 sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); 896 break; 897 default: 898 return; /* all done, work in peace */ 899 } 900 } 901 902 /* Start a connection (i.e. initiate discovery phase) */ 903 static void 904 pppoe_connect(ppp_pcb *ppp, void *ctx) 905 { 906 err_t err; 907 struct pppoe_softc *sc = (struct pppoe_softc *)ctx; 908 lcp_options *lcp_wo; 909 lcp_options *lcp_ao; 910 #if PPP_IPV4_SUPPORT && VJ_SUPPORT 911 ipcp_options *ipcp_wo; 912 ipcp_options *ipcp_ao; 913 #endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */ 914 915 sc->sc_session = 0; 916 sc->sc_ac_cookie_len = 0; 917 sc->sc_padi_retried = 0; 918 sc->sc_padr_retried = 0; 919 /* changed to real address later */ 920 MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); 921 #ifdef PPPOE_SERVER 922 /* wait PADI if IFF_PASSIVE */ 923 if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { 924 return 0; 925 } 926 #endif 927 928 lcp_wo = &ppp->lcp_wantoptions; 929 lcp_wo->mru = sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ 930 lcp_wo->neg_asyncmap = 0; 931 lcp_wo->neg_pcompression = 0; 932 lcp_wo->neg_accompression = 0; 933 lcp_wo->passive = 0; 934 lcp_wo->silent = 0; 935 936 lcp_ao = &ppp->lcp_allowoptions; 937 lcp_ao->mru = sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ 938 lcp_ao->neg_asyncmap = 0; 939 lcp_ao->neg_pcompression = 0; 940 lcp_ao->neg_accompression = 0; 941 942 #if PPP_IPV4_SUPPORT && VJ_SUPPORT 943 ipcp_wo = &ppp->ipcp_wantoptions; 944 ipcp_wo->neg_vj = 0; 945 ipcp_wo->old_vj = 0; 946 947 ipcp_ao = &ppp->ipcp_allowoptions; 948 ipcp_ao->neg_vj = 0; 949 ipcp_ao->old_vj = 0; 950 #endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */ 951 952 /* save state, in case we fail to send PADI */ 953 sc->sc_state = PPPOE_STATE_PADI_SENT; 954 if ((err = pppoe_send_padi(sc)) != 0) { 955 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); 956 } 957 sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); 958 } 959 960 /* disconnect */ 961 static void 962 pppoe_disconnect(ppp_pcb *ppp, void *ctx) 963 { 964 struct pppoe_softc *sc = (struct pppoe_softc *)ctx; 965 966 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); 967 if (sc->sc_state == PPPOE_STATE_SESSION) { 968 pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest); 969 } 970 971 /* stop any timer, disconnect can be called while initiating is in progress */ 972 sys_untimeout(pppoe_timeout, sc); 973 sc->sc_state = PPPOE_STATE_INITIAL; 974 #ifdef PPPOE_SERVER 975 if (sc->sc_hunique) { 976 mem_free(sc->sc_hunique); 977 sc->sc_hunique = NULL; /* probably not necessary, if state is initial we shouldn't have to access hunique anyway */ 978 } 979 sc->sc_hunique_len = 0; /* probably not necessary, if state is initial we shouldn't have to access hunique anyway */ 980 #endif 981 ppp_link_end(ppp); /* notify upper layers */ 982 return; 983 } 984 985 /* Connection attempt aborted */ 986 static void 987 pppoe_abort_connect(struct pppoe_softc *sc) 988 { 989 PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); 990 sc->sc_state = PPPOE_STATE_INITIAL; 991 ppp_link_failed(sc->pcb); /* notify upper layers */ 992 } 993 994 /* Send a PADR packet */ 995 static err_t 996 pppoe_send_padr(struct pppoe_softc *sc) 997 { 998 struct pbuf *pb; 999 u8_t *p; 1000 size_t len; 1001 #if PPPOE_SCNAME_SUPPORT 1002 size_t l1 = 0; /* XXX: gcc */ 1003 #endif /* PPPOE_SCNAME_SUPPORT */ 1004 1005 len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ 1006 #if PPPOE_SCNAME_SUPPORT 1007 if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ 1008 l1 = strlen(sc->sc_service_name); 1009 len += l1; 1010 } 1011 #endif /* PPPOE_SCNAME_SUPPORT */ 1012 if (sc->sc_ac_cookie_len > 0) { 1013 len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ 1014 } 1015 LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", 1016 sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); 1017 pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); 1018 if (!pb) { 1019 return ERR_MEM; 1020 } 1021 LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); 1022 p = (u8_t*)pb->payload; 1023 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); 1024 PPPOE_ADD_16(p, PPPOE_TAG_SNAME); 1025 #if PPPOE_SCNAME_SUPPORT 1026 if (sc->sc_service_name != NULL) { 1027 PPPOE_ADD_16(p, l1); 1028 MEMCPY(p, sc->sc_service_name, l1); 1029 p += l1; 1030 } else 1031 #endif /* PPPOE_SCNAME_SUPPORT */ 1032 { 1033 PPPOE_ADD_16(p, 0); 1034 } 1035 if (sc->sc_ac_cookie_len > 0) { 1036 PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); 1037 PPPOE_ADD_16(p, sc->sc_ac_cookie_len); 1038 MEMCPY(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len); 1039 p += sc->sc_ac_cookie_len; 1040 } 1041 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); 1042 PPPOE_ADD_16(p, sizeof(sc)); 1043 MEMCPY(p, &sc, sizeof sc); 1044 1045 return pppoe_output(sc, pb); 1046 } 1047 1048 /* send a PADT packet */ 1049 static err_t 1050 pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest) 1051 { 1052 struct pbuf *pb; 1053 struct eth_hdr *ethhdr; 1054 err_t res; 1055 u8_t *p; 1056 1057 pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM); 1058 if (!pb) { 1059 return ERR_MEM; 1060 } 1061 LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); 1062 1063 if (pbuf_add_header(pb, sizeof(struct eth_hdr))) { 1064 PPPDEBUG(LOG_ERR, ("pppoe: pppoe_send_padt: could not allocate room for PPPoE header\n")); 1065 LINK_STATS_INC(link.lenerr); 1066 pbuf_free(pb); 1067 return ERR_BUF; 1068 } 1069 ethhdr = (struct eth_hdr *)pb->payload; 1070 ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC); 1071 MEMCPY(ðhdr->dest.addr, dest, sizeof(ethhdr->dest.addr)); 1072 MEMCPY(ðhdr->src.addr, &outgoing_if->hwaddr, sizeof(ethhdr->src.addr)); 1073 1074 p = (u8_t*)(ethhdr + 1); 1075 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); 1076 1077 res = outgoing_if->linkoutput(outgoing_if, pb); 1078 1079 pbuf_free(pb); 1080 1081 return res; 1082 } 1083 1084 #ifdef PPPOE_SERVER 1085 static err_t 1086 pppoe_send_pado(struct pppoe_softc *sc) 1087 { 1088 struct pbuf *pb; 1089 u8_t *p; 1090 size_t len; 1091 1092 /* calc length */ 1093 len = 0; 1094 /* include ac_cookie */ 1095 len += 2 + 2 + sizeof(sc); 1096 /* include hunique */ 1097 len += 2 + 2 + sc->sc_hunique_len; 1098 pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); 1099 if (!pb) { 1100 return ERR_MEM; 1101 } 1102 LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); 1103 p = (u8_t*)pb->payload; 1104 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len); 1105 PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); 1106 PPPOE_ADD_16(p, sizeof(sc)); 1107 MEMCPY(p, &sc, sizeof(sc)); 1108 p += sizeof(sc); 1109 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); 1110 PPPOE_ADD_16(p, sc->sc_hunique_len); 1111 MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); 1112 return pppoe_output(sc, pb); 1113 } 1114 1115 static err_t 1116 pppoe_send_pads(struct pppoe_softc *sc) 1117 { 1118 struct pbuf *pb; 1119 u8_t *p; 1120 size_t len, l1 = 0; /* XXX: gcc */ 1121 1122 sc->sc_session = mono_time.tv_sec % 0xff + 1; 1123 /* calc length */ 1124 len = 0; 1125 /* include hunique */ 1126 len += 2 + 2 + 2 + 2 + sc->sc_hunique_len; /* service name, host unique*/ 1127 if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ 1128 l1 = strlen(sc->sc_service_name); 1129 len += l1; 1130 } 1131 pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); 1132 if (!pb) { 1133 return ERR_MEM; 1134 } 1135 LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); 1136 p = (u8_t*)pb->payload; 1137 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len); 1138 PPPOE_ADD_16(p, PPPOE_TAG_SNAME); 1139 if (sc->sc_service_name != NULL) { 1140 PPPOE_ADD_16(p, l1); 1141 MEMCPY(p, sc->sc_service_name, l1); 1142 p += l1; 1143 } else { 1144 PPPOE_ADD_16(p, 0); 1145 } 1146 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); 1147 PPPOE_ADD_16(p, sc->sc_hunique_len); 1148 MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); 1149 return pppoe_output(sc, pb); 1150 } 1151 #endif 1152 1153 static err_t 1154 pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb) 1155 { 1156 u8_t *p; 1157 size_t len; 1158 1159 len = pb->tot_len; 1160 1161 /* make room for PPPoE header - should not fail */ 1162 if (pbuf_add_header(pb, PPPOE_HEADERLEN) != 0) { 1163 /* bail out */ 1164 PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for PPPoE header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); 1165 LINK_STATS_INC(link.lenerr); 1166 pbuf_free(pb); 1167 return ERR_BUF; 1168 } 1169 1170 p = (u8_t*)pb->payload; 1171 PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); 1172 1173 return pppoe_output(sc, pb); 1174 } 1175 1176 #if 0 /*def PFIL_HOOKS*/ 1177 static int 1178 pppoe_ifattach_hook(void *arg, struct pbuf **mp, struct netif *ifp, int dir) 1179 { 1180 struct pppoe_softc *sc; 1181 int s; 1182 1183 if (mp != (struct pbuf **)PFIL_IFNET_DETACH) { 1184 return 0; 1185 } 1186 1187 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { 1188 if (sc->sc_ethif != ifp) { 1189 continue; 1190 } 1191 if (sc->sc_sppp.pp_if.if_flags & IFF_UP) { 1192 sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING); 1193 PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": ethernet interface detached, going down\n", 1194 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); 1195 } 1196 sc->sc_ethif = NULL; 1197 pppoe_clear_softc(sc, "ethernet interface detached"); 1198 } 1199 1200 return 0; 1201 } 1202 #endif 1203 1204 #if 0 /* UNUSED */ 1205 static void 1206 pppoe_clear_softc(struct pppoe_softc *sc, const char *message) 1207 { 1208 LWIP_UNUSED_ARG(message); 1209 1210 /* stop timer */ 1211 sys_untimeout(pppoe_timeout, sc); 1212 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message)); 1213 sc->sc_state = PPPOE_STATE_INITIAL; 1214 ppp_link_end(sc->pcb); /* notify upper layers - /!\ dangerous /!\ - see pppoe_disc_input() */ 1215 } 1216 #endif /* UNUSED */ 1217 #endif /* PPP_SUPPORT && PPPOE_SUPPORT */ 1218