Official mbed lwIP library (version 1.4.0)

Dependents:   LwIPNetworking NetServicesMin EthernetInterface EthernetInterface_RSF ... more

Legacy Networking Libraries

This is an mbed 2 networking library. For mbed OS 5, lwip has been integrated with built-in networking interfaces. The networking libraries have been revised to better support additional network stacks and thread safety here.

This library is based on the code of lwIP v1.4.0

Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
All rights reserved. 

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
Committer:
mbed_official
Date:
Fri Jun 22 09:25:39 2012 +0000
Revision:
0:51ac1d130fd4
Initial import from lwip-1.4.0: http://download.savannah.gnu.org/releases/lwip/lwip-1.4.0.zip

Who changed what in which revision?

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