LwIP with PPP & Ethernet integration

Dependents:   NetworkingCoreLib

This is the mbed port of the LwIP stack: http://savannah.nongnu.org/projects/lwip/

It includes contributed content from NXP's port for LPCxxxx devices: http://www.lpcware.com/content/project/lightweight-ip-lwip-networking-stack

Licence

LwIP is licenced under the BSD licence:

Copyright (c) 2001-2004 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:
donatien
Date:
Thu May 24 15:53:48 2012 +0000
Revision:
0:8e01dca41002
Merge with Emilio's LwIp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 0:8e01dca41002 1 /*****************************************************************************
donatien 0:8e01dca41002 2 * ppp.c - Network Point to Point Protocol program file.
donatien 0:8e01dca41002 3 *
donatien 0:8e01dca41002 4 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
donatien 0:8e01dca41002 5 * portions Copyright (c) 1997 by Global Election Systems Inc.
donatien 0:8e01dca41002 6 *
donatien 0:8e01dca41002 7 * The authors hereby grant permission to use, copy, modify, distribute,
donatien 0:8e01dca41002 8 * and license this software and its documentation for any purpose, provided
donatien 0:8e01dca41002 9 * that existing copyright notices are retained in all copies and that this
donatien 0:8e01dca41002 10 * notice and the following disclaimer are included verbatim in any
donatien 0:8e01dca41002 11 * distributions. No written agreement, license, or royalty fee is required
donatien 0:8e01dca41002 12 * for any of the authorized uses.
donatien 0:8e01dca41002 13 *
donatien 0:8e01dca41002 14 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
donatien 0:8e01dca41002 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
donatien 0:8e01dca41002 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
donatien 0:8e01dca41002 17 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
donatien 0:8e01dca41002 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
donatien 0:8e01dca41002 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
donatien 0:8e01dca41002 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
donatien 0:8e01dca41002 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
donatien 0:8e01dca41002 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
donatien 0:8e01dca41002 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
donatien 0:8e01dca41002 24 *
donatien 0:8e01dca41002 25 ******************************************************************************
donatien 0:8e01dca41002 26 * REVISION HISTORY
donatien 0:8e01dca41002 27 *
donatien 0:8e01dca41002 28 * 03-01-01 Marc Boucher <marc@mbsi.ca>
donatien 0:8e01dca41002 29 * Ported to lwIP.
donatien 0:8e01dca41002 30 * 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
donatien 0:8e01dca41002 31 * Original.
donatien 0:8e01dca41002 32 *****************************************************************************/
donatien 0:8e01dca41002 33
donatien 0:8e01dca41002 34 /*
donatien 0:8e01dca41002 35 * ppp_defs.h - PPP definitions.
donatien 0:8e01dca41002 36 *
donatien 0:8e01dca41002 37 * if_pppvar.h - private structures and declarations for PPP.
donatien 0:8e01dca41002 38 *
donatien 0:8e01dca41002 39 * Copyright (c) 1994 The Australian National University.
donatien 0:8e01dca41002 40 * All rights reserved.
donatien 0:8e01dca41002 41 *
donatien 0:8e01dca41002 42 * Permission to use, copy, modify, and distribute this software and its
donatien 0:8e01dca41002 43 * documentation is hereby granted, provided that the above copyright
donatien 0:8e01dca41002 44 * notice appears in all copies. This software is provided without any
donatien 0:8e01dca41002 45 * warranty, express or implied. The Australian National University
donatien 0:8e01dca41002 46 * makes no representations about the suitability of this software for
donatien 0:8e01dca41002 47 * any purpose.
donatien 0:8e01dca41002 48 *
donatien 0:8e01dca41002 49 * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
donatien 0:8e01dca41002 50 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
donatien 0:8e01dca41002 51 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
donatien 0:8e01dca41002 52 * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
donatien 0:8e01dca41002 53 * OF SUCH DAMAGE.
donatien 0:8e01dca41002 54 *
donatien 0:8e01dca41002 55 * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
donatien 0:8e01dca41002 56 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
donatien 0:8e01dca41002 57 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
donatien 0:8e01dca41002 58 * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
donatien 0:8e01dca41002 59 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
donatien 0:8e01dca41002 60 * OR MODIFICATIONS.
donatien 0:8e01dca41002 61 */
donatien 0:8e01dca41002 62
donatien 0:8e01dca41002 63 /*
donatien 0:8e01dca41002 64 * if_ppp.h - Point-to-Point Protocol definitions.
donatien 0:8e01dca41002 65 *
donatien 0:8e01dca41002 66 * Copyright (c) 1989 Carnegie Mellon University.
donatien 0:8e01dca41002 67 * All rights reserved.
donatien 0:8e01dca41002 68 *
donatien 0:8e01dca41002 69 * Redistribution and use in source and binary forms are permitted
donatien 0:8e01dca41002 70 * provided that the above copyright notice and this paragraph are
donatien 0:8e01dca41002 71 * duplicated in all such forms and that any documentation,
donatien 0:8e01dca41002 72 * advertising materials, and other materials related to such
donatien 0:8e01dca41002 73 * distribution and use acknowledge that the software was developed
donatien 0:8e01dca41002 74 * by Carnegie Mellon University. The name of the
donatien 0:8e01dca41002 75 * University may not be used to endorse or promote products derived
donatien 0:8e01dca41002 76 * from this software without specific prior written permission.
donatien 0:8e01dca41002 77 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
donatien 0:8e01dca41002 78 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
donatien 0:8e01dca41002 79 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
donatien 0:8e01dca41002 80 */
donatien 0:8e01dca41002 81
donatien 0:8e01dca41002 82 #define __LWIP_ORIG 0
donatien 0:8e01dca41002 83
donatien 0:8e01dca41002 84 #include "lwip/opt.h"
donatien 0:8e01dca41002 85
donatien 0:8e01dca41002 86 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
donatien 0:8e01dca41002 87
donatien 0:8e01dca41002 88 #include "lwip/ip.h" /* for ip_input() */
donatien 0:8e01dca41002 89
donatien 0:8e01dca41002 90 #include "ppp.h"
donatien 0:8e01dca41002 91 #include "pppdebug.h"
donatien 0:8e01dca41002 92
donatien 0:8e01dca41002 93 #include "randm.h"
donatien 0:8e01dca41002 94 #include "fsm.h"
donatien 0:8e01dca41002 95 #if PAP_SUPPORT
donatien 0:8e01dca41002 96 #include "pap.h"
donatien 0:8e01dca41002 97 #endif /* PAP_SUPPORT */
donatien 0:8e01dca41002 98 #if CHAP_SUPPORT
donatien 0:8e01dca41002 99 #include "chap.h"
donatien 0:8e01dca41002 100 #endif /* CHAP_SUPPORT */
donatien 0:8e01dca41002 101 #include "ipcp.h"
donatien 0:8e01dca41002 102 #include "lcp.h"
donatien 0:8e01dca41002 103 #include "magic.h"
donatien 0:8e01dca41002 104 #include "auth.h"
donatien 0:8e01dca41002 105 #if VJ_SUPPORT
donatien 0:8e01dca41002 106 #include "vj.h"
donatien 0:8e01dca41002 107 #endif /* VJ_SUPPORT */
donatien 0:8e01dca41002 108 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 109 #include "netif/ppp_oe.h"
donatien 0:8e01dca41002 110 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 111
donatien 0:8e01dca41002 112 #include "lwip/tcpip.h"
donatien 0:8e01dca41002 113 #include "lwip/api.h"
donatien 0:8e01dca41002 114 #include "lwip/snmp.h"
donatien 0:8e01dca41002 115
donatien 0:8e01dca41002 116 #include <string.h>
donatien 0:8e01dca41002 117
donatien 0:8e01dca41002 118 /*************************/
donatien 0:8e01dca41002 119 /*** LOCAL DEFINITIONS ***/
donatien 0:8e01dca41002 120 /*************************/
donatien 0:8e01dca41002 121
donatien 0:8e01dca41002 122 /** PPP_INPROC_MULTITHREADED==1 call pppInput using tcpip_callback().
donatien 0:8e01dca41002 123 * Set this to 0 if pppInProc is called inside tcpip_thread or with NO_SYS==1.
donatien 0:8e01dca41002 124 * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded).
donatien 0:8e01dca41002 125 */
donatien 0:8e01dca41002 126 #ifndef PPP_INPROC_MULTITHREADED
donatien 0:8e01dca41002 127 #define PPP_INPROC_MULTITHREADED (NO_SYS==0)
donatien 0:8e01dca41002 128 #endif
donatien 0:8e01dca41002 129
donatien 0:8e01dca41002 130 /** PPP_INPROC_OWNTHREAD==1: start a dedicated RX thread per PPP session.
donatien 0:8e01dca41002 131 * Default is 0: call pppos_input() for received raw characters, charcater
donatien 0:8e01dca41002 132 * reception is up to the port */
donatien 0:8e01dca41002 133 #ifndef PPP_INPROC_OWNTHREAD
donatien 0:8e01dca41002 134 #define PPP_INPROC_OWNTHREAD PPP_INPROC_MULTITHREADED
donatien 0:8e01dca41002 135 #endif
donatien 0:8e01dca41002 136
donatien 0:8e01dca41002 137 #if PPP_INPROC_OWNTHREAD && !PPP_INPROC_MULTITHREADED
donatien 0:8e01dca41002 138 #error "PPP_INPROC_OWNTHREAD needs PPP_INPROC_MULTITHREADED==1"
donatien 0:8e01dca41002 139 #endif
donatien 0:8e01dca41002 140
donatien 0:8e01dca41002 141 /*
donatien 0:8e01dca41002 142 * The basic PPP frame.
donatien 0:8e01dca41002 143 */
donatien 0:8e01dca41002 144 #define PPP_ADDRESS(p) (((u_char *)(p))[0])
donatien 0:8e01dca41002 145 #define PPP_CONTROL(p) (((u_char *)(p))[1])
donatien 0:8e01dca41002 146 #define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])
donatien 0:8e01dca41002 147
donatien 0:8e01dca41002 148 /* PPP packet parser states. Current state indicates operation yet to be
donatien 0:8e01dca41002 149 * completed. */
donatien 0:8e01dca41002 150 typedef enum {
donatien 0:8e01dca41002 151 PDIDLE = 0, /* Idle state - waiting. */
donatien 0:8e01dca41002 152 PDSTART, /* Process start flag. */
donatien 0:8e01dca41002 153 PDADDRESS, /* Process address field. */
donatien 0:8e01dca41002 154 PDCONTROL, /* Process control field. */
donatien 0:8e01dca41002 155 PDPROTOCOL1, /* Process protocol field 1. */
donatien 0:8e01dca41002 156 PDPROTOCOL2, /* Process protocol field 2. */
donatien 0:8e01dca41002 157 PDDATA /* Process data byte. */
donatien 0:8e01dca41002 158 } PPPDevStates;
donatien 0:8e01dca41002 159
donatien 0:8e01dca41002 160 #define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07])
donatien 0:8e01dca41002 161
donatien 0:8e01dca41002 162 /************************/
donatien 0:8e01dca41002 163 /*** LOCAL DATA TYPES ***/
donatien 0:8e01dca41002 164 /************************/
donatien 0:8e01dca41002 165
donatien 0:8e01dca41002 166 /** RX buffer size: this may be configured smaller! */
donatien 0:8e01dca41002 167 #ifndef PPPOS_RX_BUFSIZE
donatien 0:8e01dca41002 168 #define PPPOS_RX_BUFSIZE (PPP_MRU + PPP_HDRLEN)
donatien 0:8e01dca41002 169 #endif
donatien 0:8e01dca41002 170
donatien 0:8e01dca41002 171 typedef struct PPPControlRx_s {
donatien 0:8e01dca41002 172 /** unit number / ppp descriptor */
donatien 0:8e01dca41002 173 int pd;
donatien 0:8e01dca41002 174 /** the rx file descriptor */
donatien 0:8e01dca41002 175 sio_fd_t fd;
donatien 0:8e01dca41002 176 /** receive buffer - encoded data is stored here */
donatien 0:8e01dca41002 177 u_char rxbuf[PPPOS_RX_BUFSIZE];
donatien 0:8e01dca41002 178
donatien 0:8e01dca41002 179 /* The input packet. */
donatien 0:8e01dca41002 180 struct pbuf *inHead, *inTail;
donatien 0:8e01dca41002 181
donatien 0:8e01dca41002 182 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 183 u16_t inProtocol; /* The input protocol code. */
donatien 0:8e01dca41002 184 u16_t inFCS; /* Input Frame Check Sequence value. */
donatien 0:8e01dca41002 185 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 186 PPPDevStates inState; /* The input process state. */
donatien 0:8e01dca41002 187 char inEscaped; /* Escape next character. */
donatien 0:8e01dca41002 188 ext_accm inACCM; /* Async-Ctl-Char-Map for input. */
donatien 0:8e01dca41002 189 } PPPControlRx;
donatien 0:8e01dca41002 190
donatien 0:8e01dca41002 191 /*
donatien 0:8e01dca41002 192 * PPP interface control block.
donatien 0:8e01dca41002 193 */
donatien 0:8e01dca41002 194 typedef struct PPPControl_s {
donatien 0:8e01dca41002 195 PPPControlRx rx;
donatien 0:8e01dca41002 196 char openFlag; /* True when in use. */
donatien 0:8e01dca41002 197 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 198 struct netif *ethif;
donatien 0:8e01dca41002 199 struct pppoe_softc *pppoe_sc;
donatien 0:8e01dca41002 200 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 201 int if_up; /* True when the interface is up. */
donatien 0:8e01dca41002 202 int errCode; /* Code indicating why interface is down. */
donatien 0:8e01dca41002 203 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 204 sio_fd_t fd; /* File device ID of port. */
donatien 0:8e01dca41002 205 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 206 u16_t mtu; /* Peer's mru */
donatien 0:8e01dca41002 207 int pcomp; /* Does peer accept protocol compression? */
donatien 0:8e01dca41002 208 int accomp; /* Does peer accept addr/ctl compression? */
donatien 0:8e01dca41002 209 u_long lastXMit; /* Time of last transmission. */
donatien 0:8e01dca41002 210 ext_accm outACCM; /* Async-Ctl-Char-Map for output. */
donatien 0:8e01dca41002 211 #if PPPOS_SUPPORT && VJ_SUPPORT
donatien 0:8e01dca41002 212 int vjEnabled; /* Flag indicating VJ compression enabled. */
donatien 0:8e01dca41002 213 struct vjcompress vjComp; /* Van Jacobson compression header. */
donatien 0:8e01dca41002 214 #endif /* PPPOS_SUPPORT && VJ_SUPPORT */
donatien 0:8e01dca41002 215
donatien 0:8e01dca41002 216 struct netif netif;
donatien 0:8e01dca41002 217
donatien 0:8e01dca41002 218 struct ppp_addrs addrs;
donatien 0:8e01dca41002 219
donatien 0:8e01dca41002 220 void (*linkStatusCB)(void *ctx, int errCode, void *arg);
donatien 0:8e01dca41002 221 void *linkStatusCtx;
donatien 0:8e01dca41002 222
donatien 0:8e01dca41002 223 } PPPControl;
donatien 0:8e01dca41002 224
donatien 0:8e01dca41002 225
donatien 0:8e01dca41002 226 /*
donatien 0:8e01dca41002 227 * Ioctl definitions.
donatien 0:8e01dca41002 228 */
donatien 0:8e01dca41002 229
donatien 0:8e01dca41002 230 struct npioctl {
donatien 0:8e01dca41002 231 int protocol; /* PPP procotol, e.g. PPP_IP */
donatien 0:8e01dca41002 232 enum NPmode mode;
donatien 0:8e01dca41002 233 };
donatien 0:8e01dca41002 234
donatien 0:8e01dca41002 235
donatien 0:8e01dca41002 236
donatien 0:8e01dca41002 237 /***********************************/
donatien 0:8e01dca41002 238 /*** LOCAL FUNCTION DECLARATIONS ***/
donatien 0:8e01dca41002 239 /***********************************/
donatien 0:8e01dca41002 240 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 241 #if PPP_INPROC_OWNTHREAD
donatien 0:8e01dca41002 242 static void pppInputThread(void *arg);
donatien 0:8e01dca41002 243 #endif /* PPP_INPROC_OWNTHREAD */
donatien 0:8e01dca41002 244 static void pppDrop(PPPControlRx *pcrx);
donatien 0:8e01dca41002 245 static void pppInProc(PPPControlRx *pcrx, u_char *s, int l);
donatien 0:8e01dca41002 246 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 247
donatien 0:8e01dca41002 248
donatien 0:8e01dca41002 249 /******************************/
donatien 0:8e01dca41002 250 /*** PUBLIC DATA STRUCTURES ***/
donatien 0:8e01dca41002 251 /******************************/
donatien 0:8e01dca41002 252 u_long subnetMask;
donatien 0:8e01dca41002 253
donatien 0:8e01dca41002 254 static PPPControl pppControl[NUM_PPP] __attribute((section("AHBSRAM1"))); //Add DG; /* The PPP interface control blocks. */
donatien 0:8e01dca41002 255
donatien 0:8e01dca41002 256 #if !__LWIP_ORIG
donatien 0:8e01dca41002 257 sys_mbox_t pppMbox; //Used to signal PPP thread that a PPP session begins
donatien 0:8e01dca41002 258 #endif
donatien 0:8e01dca41002 259
donatien 0:8e01dca41002 260 /*
donatien 0:8e01dca41002 261 * PPP Data Link Layer "protocol" table.
donatien 0:8e01dca41002 262 * One entry per supported protocol.
donatien 0:8e01dca41002 263 * The last entry must be NULL.
donatien 0:8e01dca41002 264 */
donatien 0:8e01dca41002 265 struct protent *ppp_protocols[] = {
donatien 0:8e01dca41002 266 &lcp_protent,
donatien 0:8e01dca41002 267 #if PAP_SUPPORT
donatien 0:8e01dca41002 268 &pap_protent,
donatien 0:8e01dca41002 269 #endif /* PAP_SUPPORT */
donatien 0:8e01dca41002 270 #if CHAP_SUPPORT
donatien 0:8e01dca41002 271 &chap_protent,
donatien 0:8e01dca41002 272 #endif /* CHAP_SUPPORT */
donatien 0:8e01dca41002 273 #if CBCP_SUPPORT
donatien 0:8e01dca41002 274 &cbcp_protent,
donatien 0:8e01dca41002 275 #endif /* CBCP_SUPPORT */
donatien 0:8e01dca41002 276 &ipcp_protent,
donatien 0:8e01dca41002 277 #if CCP_SUPPORT
donatien 0:8e01dca41002 278 &ccp_protent,
donatien 0:8e01dca41002 279 #endif /* CCP_SUPPORT */
donatien 0:8e01dca41002 280 NULL
donatien 0:8e01dca41002 281 };
donatien 0:8e01dca41002 282
donatien 0:8e01dca41002 283
donatien 0:8e01dca41002 284 /*
donatien 0:8e01dca41002 285 * Buffers for outgoing packets. This must be accessed only from the appropriate
donatien 0:8e01dca41002 286 * PPP task so that it doesn't need to be protected to avoid collisions.
donatien 0:8e01dca41002 287 */
donatien 0:8e01dca41002 288 u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN] __attribute((section("AHBSRAM1")));
donatien 0:8e01dca41002 289
donatien 0:8e01dca41002 290
donatien 0:8e01dca41002 291 /*****************************/
donatien 0:8e01dca41002 292 /*** LOCAL DATA STRUCTURES ***/
donatien 0:8e01dca41002 293 /*****************************/
donatien 0:8e01dca41002 294
donatien 0:8e01dca41002 295 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 296 /*
donatien 0:8e01dca41002 297 * FCS lookup table as calculated by genfcstab.
donatien 0:8e01dca41002 298 * @todo: smaller, slower implementation for lower memory footprint?
donatien 0:8e01dca41002 299 */
donatien 0:8e01dca41002 300 static const u_short fcstab[256] = {
donatien 0:8e01dca41002 301 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
donatien 0:8e01dca41002 302 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
donatien 0:8e01dca41002 303 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
donatien 0:8e01dca41002 304 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
donatien 0:8e01dca41002 305 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
donatien 0:8e01dca41002 306 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
donatien 0:8e01dca41002 307 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
donatien 0:8e01dca41002 308 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
donatien 0:8e01dca41002 309 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
donatien 0:8e01dca41002 310 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
donatien 0:8e01dca41002 311 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
donatien 0:8e01dca41002 312 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
donatien 0:8e01dca41002 313 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
donatien 0:8e01dca41002 314 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
donatien 0:8e01dca41002 315 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
donatien 0:8e01dca41002 316 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
donatien 0:8e01dca41002 317 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
donatien 0:8e01dca41002 318 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
donatien 0:8e01dca41002 319 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
donatien 0:8e01dca41002 320 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
donatien 0:8e01dca41002 321 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
donatien 0:8e01dca41002 322 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
donatien 0:8e01dca41002 323 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
donatien 0:8e01dca41002 324 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
donatien 0:8e01dca41002 325 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
donatien 0:8e01dca41002 326 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
donatien 0:8e01dca41002 327 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
donatien 0:8e01dca41002 328 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
donatien 0:8e01dca41002 329 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
donatien 0:8e01dca41002 330 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
donatien 0:8e01dca41002 331 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
donatien 0:8e01dca41002 332 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
donatien 0:8e01dca41002 333 };
donatien 0:8e01dca41002 334
donatien 0:8e01dca41002 335 /* PPP's Asynchronous-Control-Character-Map. The mask array is used
donatien 0:8e01dca41002 336 * to select the specific bit for a character. */
donatien 0:8e01dca41002 337 static u_char pppACCMMask[] = {
donatien 0:8e01dca41002 338 0x01,
donatien 0:8e01dca41002 339 0x02,
donatien 0:8e01dca41002 340 0x04,
donatien 0:8e01dca41002 341 0x08,
donatien 0:8e01dca41002 342 0x10,
donatien 0:8e01dca41002 343 0x20,
donatien 0:8e01dca41002 344 0x40,
donatien 0:8e01dca41002 345 0x80
donatien 0:8e01dca41002 346 };
donatien 0:8e01dca41002 347
donatien 0:8e01dca41002 348 /** Wake up the task blocked in reading from serial line (if any) */
donatien 0:8e01dca41002 349 static void
donatien 0:8e01dca41002 350 pppRecvWakeup(int pd)
donatien 0:8e01dca41002 351 {
donatien 0:8e01dca41002 352 PPPDEBUG(LOG_DEBUG, ("pppRecvWakeup: unit %d\n", pd));
donatien 0:8e01dca41002 353 if (pppControl[pd].openFlag != 0) {
donatien 0:8e01dca41002 354 sio_read_abort(pppControl[pd].fd);
donatien 0:8e01dca41002 355 }
donatien 0:8e01dca41002 356 }
donatien 0:8e01dca41002 357 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 358
donatien 0:8e01dca41002 359 void
donatien 0:8e01dca41002 360 pppLinkTerminated(int pd)
donatien 0:8e01dca41002 361 {
donatien 0:8e01dca41002 362 PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d\n", pd));
donatien 0:8e01dca41002 363
donatien 0:8e01dca41002 364 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 365 if (pppControl[pd].ethif) {
donatien 0:8e01dca41002 366 pppoe_disconnect(pppControl[pd].pppoe_sc);
donatien 0:8e01dca41002 367 } else
donatien 0:8e01dca41002 368 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 369 {
donatien 0:8e01dca41002 370 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 371 PPPControl* pc;
donatien 0:8e01dca41002 372 pppRecvWakeup(pd);
donatien 0:8e01dca41002 373 pc = &pppControl[pd];
donatien 0:8e01dca41002 374
donatien 0:8e01dca41002 375 PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
donatien 0:8e01dca41002 376 if (pc->linkStatusCB) {
donatien 0:8e01dca41002 377 pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);
donatien 0:8e01dca41002 378 }
donatien 0:8e01dca41002 379
donatien 0:8e01dca41002 380 pc->openFlag = 0;/**/
donatien 0:8e01dca41002 381 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 382 }
donatien 0:8e01dca41002 383 PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: finished.\n"));
donatien 0:8e01dca41002 384 }
donatien 0:8e01dca41002 385
donatien 0:8e01dca41002 386 void
donatien 0:8e01dca41002 387 pppLinkDown(int pd)
donatien 0:8e01dca41002 388 {
donatien 0:8e01dca41002 389 PPPDEBUG(LOG_DEBUG, ("pppLinkDown: unit %d\n", pd));
donatien 0:8e01dca41002 390
donatien 0:8e01dca41002 391 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 392 if (pppControl[pd].ethif) {
donatien 0:8e01dca41002 393 pppoe_disconnect(pppControl[pd].pppoe_sc);
donatien 0:8e01dca41002 394 } else
donatien 0:8e01dca41002 395 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 396 {
donatien 0:8e01dca41002 397 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 398 pppRecvWakeup(pd);
donatien 0:8e01dca41002 399 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 400 }
donatien 0:8e01dca41002 401 }
donatien 0:8e01dca41002 402
donatien 0:8e01dca41002 403 /** Initiate LCP open request */
donatien 0:8e01dca41002 404 static void
donatien 0:8e01dca41002 405 pppStart(int pd)
donatien 0:8e01dca41002 406 {
donatien 0:8e01dca41002 407 PPPDEBUG(LOG_DEBUG, ("pppStart: unit %d\n", pd));
donatien 0:8e01dca41002 408 lcp_lowerup(pd);
donatien 0:8e01dca41002 409 lcp_open(pd); /* Start protocol */
donatien 0:8e01dca41002 410 PPPDEBUG(LOG_DEBUG, ("pppStart: finished\n"));
donatien 0:8e01dca41002 411 }
donatien 0:8e01dca41002 412
donatien 0:8e01dca41002 413 /** LCP close request */
donatien 0:8e01dca41002 414 static void
donatien 0:8e01dca41002 415 pppStop(int pd)
donatien 0:8e01dca41002 416 {
donatien 0:8e01dca41002 417 PPPDEBUG(LOG_DEBUG, ("pppStop: unit %d\n", pd));
donatien 0:8e01dca41002 418 lcp_close(pd, "User request");
donatien 0:8e01dca41002 419 }
donatien 0:8e01dca41002 420
donatien 0:8e01dca41002 421 /** Called when carrier/link is lost */
donatien 0:8e01dca41002 422 static void
donatien 0:8e01dca41002 423 pppHup(int pd)
donatien 0:8e01dca41002 424 {
donatien 0:8e01dca41002 425 PPPDEBUG(LOG_DEBUG, ("pppHupCB: unit %d\n", pd));
donatien 0:8e01dca41002 426 lcp_lowerdown(pd);
donatien 0:8e01dca41002 427 link_terminated(pd);
donatien 0:8e01dca41002 428 }
donatien 0:8e01dca41002 429
donatien 0:8e01dca41002 430 /***********************************/
donatien 0:8e01dca41002 431 /*** PUBLIC FUNCTION DEFINITIONS ***/
donatien 0:8e01dca41002 432 /***********************************/
donatien 0:8e01dca41002 433 /* Initialize the PPP subsystem. */
donatien 0:8e01dca41002 434
donatien 0:8e01dca41002 435 struct ppp_settings ppp_settings;
donatien 0:8e01dca41002 436
donatien 0:8e01dca41002 437 void
donatien 0:8e01dca41002 438 pppInit(void)
donatien 0:8e01dca41002 439 {
donatien 0:8e01dca41002 440 struct protent *protp;
donatien 0:8e01dca41002 441 int i, j;
donatien 0:8e01dca41002 442
donatien 0:8e01dca41002 443 memset(&ppp_settings, 0, sizeof(ppp_settings));
donatien 0:8e01dca41002 444 ppp_settings.usepeerdns = 1;
donatien 0:8e01dca41002 445 pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL);
donatien 0:8e01dca41002 446
donatien 0:8e01dca41002 447 magicInit();
donatien 0:8e01dca41002 448
donatien 0:8e01dca41002 449 subnetMask = PP_HTONL(0xffffff00UL);
donatien 0:8e01dca41002 450
donatien 0:8e01dca41002 451 for (i = 0; i < NUM_PPP; i++) {
donatien 0:8e01dca41002 452 /* Initialize each protocol to the standard option set. */
donatien 0:8e01dca41002 453 for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j) {
donatien 0:8e01dca41002 454 (*protp->init)(i);
donatien 0:8e01dca41002 455 }
donatien 0:8e01dca41002 456 }
donatien 0:8e01dca41002 457
donatien 0:8e01dca41002 458 #if !__LWIP_ORIG
donatien 0:8e01dca41002 459 sys_mbox_new(&pppMbox, 1);
donatien 0:8e01dca41002 460 sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)NULL, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); //Create PPP thread here
donatien 0:8e01dca41002 461 #endif
donatien 0:8e01dca41002 462 }
donatien 0:8e01dca41002 463
donatien 0:8e01dca41002 464 void
donatien 0:8e01dca41002 465 pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd)
donatien 0:8e01dca41002 466 {
donatien 0:8e01dca41002 467 switch(authType) {
donatien 0:8e01dca41002 468 case PPPAUTHTYPE_NONE:
donatien 0:8e01dca41002 469 default:
donatien 0:8e01dca41002 470 #ifdef LWIP_PPP_STRICT_PAP_REJECT
donatien 0:8e01dca41002 471 ppp_settings.refuse_pap = 1;
donatien 0:8e01dca41002 472 #else /* LWIP_PPP_STRICT_PAP_REJECT */
donatien 0:8e01dca41002 473 /* some providers request pap and accept an empty login/pw */
donatien 0:8e01dca41002 474 ppp_settings.refuse_pap = 0;
donatien 0:8e01dca41002 475 #endif /* LWIP_PPP_STRICT_PAP_REJECT */
donatien 0:8e01dca41002 476 ppp_settings.refuse_chap = 1;
donatien 0:8e01dca41002 477 break;
donatien 0:8e01dca41002 478
donatien 0:8e01dca41002 479 case PPPAUTHTYPE_ANY:
donatien 0:8e01dca41002 480 /* Warning: Using PPPAUTHTYPE_ANY might have security consequences.
donatien 0:8e01dca41002 481 * RFC 1994 says:
donatien 0:8e01dca41002 482 *
donatien 0:8e01dca41002 483 * In practice, within or associated with each PPP server, there is a
donatien 0:8e01dca41002 484 * database which associates "user" names with authentication
donatien 0:8e01dca41002 485 * information ("secrets"). It is not anticipated that a particular
donatien 0:8e01dca41002 486 * named user would be authenticated by multiple methods. This would
donatien 0:8e01dca41002 487 * make the user vulnerable to attacks which negotiate the least secure
donatien 0:8e01dca41002 488 * method from among a set (such as PAP rather than CHAP). If the same
donatien 0:8e01dca41002 489 * secret was used, PAP would reveal the secret to be used later with
donatien 0:8e01dca41002 490 * CHAP.
donatien 0:8e01dca41002 491 *
donatien 0:8e01dca41002 492 * Instead, for each user name there should be an indication of exactly
donatien 0:8e01dca41002 493 * one method used to authenticate that user name. If a user needs to
donatien 0:8e01dca41002 494 * make use of different authentication methods under different
donatien 0:8e01dca41002 495 * circumstances, then distinct user names SHOULD be employed, each of
donatien 0:8e01dca41002 496 * which identifies exactly one authentication method.
donatien 0:8e01dca41002 497 *
donatien 0:8e01dca41002 498 */
donatien 0:8e01dca41002 499 ppp_settings.refuse_pap = 0;
donatien 0:8e01dca41002 500 ppp_settings.refuse_chap = 0;
donatien 0:8e01dca41002 501 break;
donatien 0:8e01dca41002 502
donatien 0:8e01dca41002 503 case PPPAUTHTYPE_PAP:
donatien 0:8e01dca41002 504 ppp_settings.refuse_pap = 0;
donatien 0:8e01dca41002 505 ppp_settings.refuse_chap = 1;
donatien 0:8e01dca41002 506 break;
donatien 0:8e01dca41002 507
donatien 0:8e01dca41002 508 case PPPAUTHTYPE_CHAP:
donatien 0:8e01dca41002 509 ppp_settings.refuse_pap = 1;
donatien 0:8e01dca41002 510 ppp_settings.refuse_chap = 0;
donatien 0:8e01dca41002 511 break;
donatien 0:8e01dca41002 512 }
donatien 0:8e01dca41002 513
donatien 0:8e01dca41002 514 if(user) {
donatien 0:8e01dca41002 515 strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1);
donatien 0:8e01dca41002 516 ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0';
donatien 0:8e01dca41002 517 } else {
donatien 0:8e01dca41002 518 ppp_settings.user[0] = '\0';
donatien 0:8e01dca41002 519 }
donatien 0:8e01dca41002 520
donatien 0:8e01dca41002 521 if(passwd) {
donatien 0:8e01dca41002 522 strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1);
donatien 0:8e01dca41002 523 ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0';
donatien 0:8e01dca41002 524 } else {
donatien 0:8e01dca41002 525 ppp_settings.passwd[0] = '\0';
donatien 0:8e01dca41002 526 }
donatien 0:8e01dca41002 527 }
donatien 0:8e01dca41002 528
donatien 0:8e01dca41002 529 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 530 /** Open a new PPP connection using the given I/O device.
donatien 0:8e01dca41002 531 * This initializes the PPP control block but does not
donatien 0:8e01dca41002 532 * attempt to negotiate the LCP session. If this port
donatien 0:8e01dca41002 533 * connects to a modem, the modem connection must be
donatien 0:8e01dca41002 534 * established before calling this.
donatien 0:8e01dca41002 535 * Return a new PPP connection descriptor on success or
donatien 0:8e01dca41002 536 * an error code (negative) on failure.
donatien 0:8e01dca41002 537 *
donatien 0:8e01dca41002 538 * pppOpen() is directly defined to this function.
donatien 0:8e01dca41002 539 */
donatien 0:8e01dca41002 540 int
donatien 0:8e01dca41002 541 pppOverSerialOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx)
donatien 0:8e01dca41002 542 {
donatien 0:8e01dca41002 543 PPPControl *pc;
donatien 0:8e01dca41002 544 int pd;
donatien 0:8e01dca41002 545
donatien 0:8e01dca41002 546 if (linkStatusCB == NULL) {
donatien 0:8e01dca41002 547 /* PPP is single-threaded: without a callback,
donatien 0:8e01dca41002 548 * there is no way to know when the link is up. */
donatien 0:8e01dca41002 549 return PPPERR_PARAM;
donatien 0:8e01dca41002 550 }
donatien 0:8e01dca41002 551
donatien 0:8e01dca41002 552 /* Find a free PPP session descriptor. */
donatien 0:8e01dca41002 553 for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);
donatien 0:8e01dca41002 554
donatien 0:8e01dca41002 555 if (pd >= NUM_PPP) {
donatien 0:8e01dca41002 556 pd = PPPERR_OPEN;
donatien 0:8e01dca41002 557 } else {
donatien 0:8e01dca41002 558 pc = &pppControl[pd];
donatien 0:8e01dca41002 559 /* @todo: is this correct or do I overwrite something? */
donatien 0:8e01dca41002 560 memset(pc, 0, sizeof(PPPControl));
donatien 0:8e01dca41002 561 pc->rx.pd = pd;
donatien 0:8e01dca41002 562 pc->rx.fd = fd;
donatien 0:8e01dca41002 563
donatien 0:8e01dca41002 564 pc->openFlag = 1;
donatien 0:8e01dca41002 565 pc->fd = fd;
donatien 0:8e01dca41002 566
donatien 0:8e01dca41002 567 #if VJ_SUPPORT
donatien 0:8e01dca41002 568 vj_compress_init(&pc->vjComp);
donatien 0:8e01dca41002 569 #endif /* VJ_SUPPORT */
donatien 0:8e01dca41002 570
donatien 0:8e01dca41002 571 /*
donatien 0:8e01dca41002 572 * Default the in and out accm so that escape and flag characters
donatien 0:8e01dca41002 573 * are always escaped.
donatien 0:8e01dca41002 574 */
donatien 0:8e01dca41002 575 pc->rx.inACCM[15] = 0x60; /* no need to protect since RX is not running */
donatien 0:8e01dca41002 576 pc->outACCM[15] = 0x60;
donatien 0:8e01dca41002 577
donatien 0:8e01dca41002 578 pc->linkStatusCB = linkStatusCB;
donatien 0:8e01dca41002 579 pc->linkStatusCtx = linkStatusCtx;
donatien 0:8e01dca41002 580
donatien 0:8e01dca41002 581 /*
donatien 0:8e01dca41002 582 * Start the connection and handle incoming events (packet or timeout).
donatien 0:8e01dca41002 583 */
donatien 0:8e01dca41002 584 PPPDEBUG(LOG_INFO, ("pppOverSerialOpen: unit %d: Connecting\n", pd));
donatien 0:8e01dca41002 585 pppStart(pd);
donatien 0:8e01dca41002 586 #if PPP_INPROC_OWNTHREAD
donatien 0:8e01dca41002 587 #if __LWIP_ORIG
donatien 0:8e01dca41002 588 sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO);
donatien 0:8e01dca41002 589 #else
donatien 0:8e01dca41002 590 sys_mbox_post(&pppMbox, (void*)&pc->rx);
donatien 0:8e01dca41002 591 #endif
donatien 0:8e01dca41002 592 #endif
donatien 0:8e01dca41002 593 }
donatien 0:8e01dca41002 594
donatien 0:8e01dca41002 595 return pd;
donatien 0:8e01dca41002 596 }
donatien 0:8e01dca41002 597 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 598
donatien 0:8e01dca41002 599 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 600 static void pppOverEthernetLinkStatusCB(int pd, int up);
donatien 0:8e01dca41002 601
donatien 0:8e01dca41002 602 void
donatien 0:8e01dca41002 603 pppOverEthernetClose(int pd)
donatien 0:8e01dca41002 604 {
donatien 0:8e01dca41002 605 PPPControl* pc = &pppControl[pd];
donatien 0:8e01dca41002 606
donatien 0:8e01dca41002 607 /* *TJL* There's no lcp_deinit */
donatien 0:8e01dca41002 608 lcp_close(pd, NULL);
donatien 0:8e01dca41002 609
donatien 0:8e01dca41002 610 pppoe_destroy(&pc->netif);
donatien 0:8e01dca41002 611 }
donatien 0:8e01dca41002 612
donatien 0:8e01dca41002 613 int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx)
donatien 0:8e01dca41002 614 {
donatien 0:8e01dca41002 615 PPPControl *pc;
donatien 0:8e01dca41002 616 int pd;
donatien 0:8e01dca41002 617
donatien 0:8e01dca41002 618 LWIP_UNUSED_ARG(service_name);
donatien 0:8e01dca41002 619 LWIP_UNUSED_ARG(concentrator_name);
donatien 0:8e01dca41002 620
donatien 0:8e01dca41002 621 if (linkStatusCB == NULL) {
donatien 0:8e01dca41002 622 /* PPP is single-threaded: without a callback,
donatien 0:8e01dca41002 623 * there is no way to know when the link is up. */
donatien 0:8e01dca41002 624 return PPPERR_PARAM;
donatien 0:8e01dca41002 625 }
donatien 0:8e01dca41002 626
donatien 0:8e01dca41002 627 /* Find a free PPP session descriptor. Critical region? */
donatien 0:8e01dca41002 628 for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);
donatien 0:8e01dca41002 629 if (pd >= NUM_PPP) {
donatien 0:8e01dca41002 630 pd = PPPERR_OPEN;
donatien 0:8e01dca41002 631 } else {
donatien 0:8e01dca41002 632 pc = &pppControl[pd];
donatien 0:8e01dca41002 633 memset(pc, 0, sizeof(PPPControl));
donatien 0:8e01dca41002 634 pc->openFlag = 1;
donatien 0:8e01dca41002 635 pc->ethif = ethif;
donatien 0:8e01dca41002 636
donatien 0:8e01dca41002 637 pc->linkStatusCB = linkStatusCB;
donatien 0:8e01dca41002 638 pc->linkStatusCtx = linkStatusCtx;
donatien 0:8e01dca41002 639
donatien 0:8e01dca41002 640 lcp_wantoptions[pd].mru = PPPOE_MAXMTU;
donatien 0:8e01dca41002 641 lcp_wantoptions[pd].neg_asyncmap = 0;
donatien 0:8e01dca41002 642 lcp_wantoptions[pd].neg_pcompression = 0;
donatien 0:8e01dca41002 643 lcp_wantoptions[pd].neg_accompression = 0;
donatien 0:8e01dca41002 644
donatien 0:8e01dca41002 645 lcp_allowoptions[pd].mru = PPPOE_MAXMTU;
donatien 0:8e01dca41002 646 lcp_allowoptions[pd].neg_asyncmap = 0;
donatien 0:8e01dca41002 647 lcp_allowoptions[pd].neg_pcompression = 0;
donatien 0:8e01dca41002 648 lcp_allowoptions[pd].neg_accompression = 0;
donatien 0:8e01dca41002 649
donatien 0:8e01dca41002 650 if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) {
donatien 0:8e01dca41002 651 pc->openFlag = 0;
donatien 0:8e01dca41002 652 return PPPERR_OPEN;
donatien 0:8e01dca41002 653 }
donatien 0:8e01dca41002 654
donatien 0:8e01dca41002 655 pppoe_connect(pc->pppoe_sc);
donatien 0:8e01dca41002 656 }
donatien 0:8e01dca41002 657
donatien 0:8e01dca41002 658 return pd;
donatien 0:8e01dca41002 659 }
donatien 0:8e01dca41002 660 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 661
donatien 0:8e01dca41002 662
donatien 0:8e01dca41002 663 /* Close a PPP connection and release the descriptor.
donatien 0:8e01dca41002 664 * Any outstanding packets in the queues are dropped.
donatien 0:8e01dca41002 665 * Return 0 on success, an error code on failure. */
donatien 0:8e01dca41002 666 int
donatien 0:8e01dca41002 667 pppClose(int pd)
donatien 0:8e01dca41002 668 {
donatien 0:8e01dca41002 669 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 670 int st = 0;
donatien 0:8e01dca41002 671
donatien 0:8e01dca41002 672 PPPDEBUG(LOG_DEBUG, ("pppClose() called\n"));
donatien 0:8e01dca41002 673
donatien 0:8e01dca41002 674 /* Disconnect */
donatien 0:8e01dca41002 675 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 676 if(pc->ethif) {
donatien 0:8e01dca41002 677 PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd));
donatien 0:8e01dca41002 678 pc->errCode = PPPERR_USER;
donatien 0:8e01dca41002 679 /* This will leave us at PHASE_DEAD. */
donatien 0:8e01dca41002 680 pppStop(pd);
donatien 0:8e01dca41002 681 } else
donatien 0:8e01dca41002 682 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 683 {
donatien 0:8e01dca41002 684 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 685 PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd));
donatien 0:8e01dca41002 686 pc->errCode = PPPERR_USER;
donatien 0:8e01dca41002 687 /* This will leave us at PHASE_DEAD. */
donatien 0:8e01dca41002 688 pppStop(pd);
donatien 0:8e01dca41002 689 pppRecvWakeup(pd);
donatien 0:8e01dca41002 690 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 691 }
donatien 0:8e01dca41002 692
donatien 0:8e01dca41002 693 return st;
donatien 0:8e01dca41002 694 }
donatien 0:8e01dca41002 695
donatien 0:8e01dca41002 696 /* This function is called when carrier is lost on the PPP channel. */
donatien 0:8e01dca41002 697 void
donatien 0:8e01dca41002 698 pppSigHUP(int pd)
donatien 0:8e01dca41002 699 {
donatien 0:8e01dca41002 700 PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd));
donatien 0:8e01dca41002 701 pppHup(pd);
donatien 0:8e01dca41002 702 }
donatien 0:8e01dca41002 703
donatien 0:8e01dca41002 704 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 705 static void
donatien 0:8e01dca41002 706 nPut(PPPControl *pc, struct pbuf *nb)
donatien 0:8e01dca41002 707 {
donatien 0:8e01dca41002 708 struct pbuf *b;
donatien 0:8e01dca41002 709 int c;
donatien 0:8e01dca41002 710
donatien 0:8e01dca41002 711 for(b = nb; b != NULL; b = b->next) {
donatien 0:8e01dca41002 712 if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) {
donatien 0:8e01dca41002 713 PPPDEBUG(LOG_WARNING,
donatien 0:8e01dca41002 714 ("PPP nPut: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c));
donatien 0:8e01dca41002 715 LINK_STATS_INC(link.err);
donatien 0:8e01dca41002 716 pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */
donatien 0:8e01dca41002 717 snmp_inc_ifoutdiscards(&pc->netif);
donatien 0:8e01dca41002 718 pbuf_free(nb);
donatien 0:8e01dca41002 719 return;
donatien 0:8e01dca41002 720 }
donatien 0:8e01dca41002 721 }
donatien 0:8e01dca41002 722
donatien 0:8e01dca41002 723 snmp_add_ifoutoctets(&pc->netif, nb->tot_len);
donatien 0:8e01dca41002 724 snmp_inc_ifoutucastpkts(&pc->netif);
donatien 0:8e01dca41002 725 pbuf_free(nb);
donatien 0:8e01dca41002 726 LINK_STATS_INC(link.xmit);
donatien 0:8e01dca41002 727 }
donatien 0:8e01dca41002 728
donatien 0:8e01dca41002 729 /*
donatien 0:8e01dca41002 730 * pppAppend - append given character to end of given pbuf. If outACCM
donatien 0:8e01dca41002 731 * is not NULL and the character needs to be escaped, do so.
donatien 0:8e01dca41002 732 * If pbuf is full, append another.
donatien 0:8e01dca41002 733 * Return the current pbuf.
donatien 0:8e01dca41002 734 */
donatien 0:8e01dca41002 735 static struct pbuf *
donatien 0:8e01dca41002 736 pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM)
donatien 0:8e01dca41002 737 {
donatien 0:8e01dca41002 738 struct pbuf *tb = nb;
donatien 0:8e01dca41002 739
donatien 0:8e01dca41002 740 /* Make sure there is room for the character and an escape code.
donatien 0:8e01dca41002 741 * Sure we don't quite fill the buffer if the character doesn't
donatien 0:8e01dca41002 742 * get escaped but is one character worth complicating this? */
donatien 0:8e01dca41002 743 /* Note: We assume no packet header. */
donatien 0:8e01dca41002 744 if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) {
donatien 0:8e01dca41002 745 tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
donatien 0:8e01dca41002 746 if (tb) {
donatien 0:8e01dca41002 747 nb->next = tb;
donatien 0:8e01dca41002 748 } else {
donatien 0:8e01dca41002 749 LINK_STATS_INC(link.memerr);
donatien 0:8e01dca41002 750 }
donatien 0:8e01dca41002 751 nb = tb;
donatien 0:8e01dca41002 752 }
donatien 0:8e01dca41002 753
donatien 0:8e01dca41002 754 if (nb) {
donatien 0:8e01dca41002 755 if (outACCM && ESCAPE_P(*outACCM, c)) {
donatien 0:8e01dca41002 756 *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE;
donatien 0:8e01dca41002 757 *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS;
donatien 0:8e01dca41002 758 } else {
donatien 0:8e01dca41002 759 *((u_char*)nb->payload + nb->len++) = c;
donatien 0:8e01dca41002 760 }
donatien 0:8e01dca41002 761 }
donatien 0:8e01dca41002 762
donatien 0:8e01dca41002 763 return tb;
donatien 0:8e01dca41002 764 }
donatien 0:8e01dca41002 765 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 766
donatien 0:8e01dca41002 767 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 768 static err_t
donatien 0:8e01dca41002 769 pppifOutputOverEthernet(int pd, struct pbuf *p)
donatien 0:8e01dca41002 770 {
donatien 0:8e01dca41002 771 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 772 struct pbuf *pb;
donatien 0:8e01dca41002 773 u_short protocol = PPP_IP;
donatien 0:8e01dca41002 774 int i=0;
donatien 0:8e01dca41002 775 u16_t tot_len;
donatien 0:8e01dca41002 776
donatien 0:8e01dca41002 777 /* @todo: try to use pbuf_header() here! */
donatien 0:8e01dca41002 778 pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM);
donatien 0:8e01dca41002 779 if(!pb) {
donatien 0:8e01dca41002 780 LINK_STATS_INC(link.memerr);
donatien 0:8e01dca41002 781 LINK_STATS_INC(link.proterr);
donatien 0:8e01dca41002 782 snmp_inc_ifoutdiscards(&pc->netif);
donatien 0:8e01dca41002 783 return ERR_MEM;
donatien 0:8e01dca41002 784 }
donatien 0:8e01dca41002 785
donatien 0:8e01dca41002 786 pbuf_header(pb, -(s16_t)PPPOE_HDRLEN);
donatien 0:8e01dca41002 787
donatien 0:8e01dca41002 788 pc->lastXMit = sys_jiffies();
donatien 0:8e01dca41002 789
donatien 0:8e01dca41002 790 if (!pc->pcomp || protocol > 0xFF) {
donatien 0:8e01dca41002 791 *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF;
donatien 0:8e01dca41002 792 }
donatien 0:8e01dca41002 793 *((u_char*)pb->payload + i) = protocol & 0xFF;
donatien 0:8e01dca41002 794
donatien 0:8e01dca41002 795 pbuf_chain(pb, p);
donatien 0:8e01dca41002 796 tot_len = pb->tot_len;
donatien 0:8e01dca41002 797
donatien 0:8e01dca41002 798 if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) {
donatien 0:8e01dca41002 799 LINK_STATS_INC(link.err);
donatien 0:8e01dca41002 800 snmp_inc_ifoutdiscards(&pc->netif);
donatien 0:8e01dca41002 801 return PPPERR_DEVICE;
donatien 0:8e01dca41002 802 }
donatien 0:8e01dca41002 803
donatien 0:8e01dca41002 804 snmp_add_ifoutoctets(&pc->netif, tot_len);
donatien 0:8e01dca41002 805 snmp_inc_ifoutucastpkts(&pc->netif);
donatien 0:8e01dca41002 806 LINK_STATS_INC(link.xmit);
donatien 0:8e01dca41002 807 return ERR_OK;
donatien 0:8e01dca41002 808 }
donatien 0:8e01dca41002 809 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 810
donatien 0:8e01dca41002 811 /* Send a packet on the given connection. */
donatien 0:8e01dca41002 812 static err_t
donatien 0:8e01dca41002 813 pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr)
donatien 0:8e01dca41002 814 {
donatien 0:8e01dca41002 815 int pd = (int)(size_t)netif->state;
donatien 0:8e01dca41002 816 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 817 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 818 u_short protocol = PPP_IP;
donatien 0:8e01dca41002 819 u_int fcsOut = PPP_INITFCS;
donatien 0:8e01dca41002 820 struct pbuf *headMB = NULL, *tailMB = NULL, *p;
donatien 0:8e01dca41002 821 u_char c;
donatien 0:8e01dca41002 822 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 823
donatien 0:8e01dca41002 824 LWIP_UNUSED_ARG(ipaddr);
donatien 0:8e01dca41002 825
donatien 0:8e01dca41002 826 /* Validate parameters. */
donatien 0:8e01dca41002 827 /* We let any protocol value go through - it can't hurt us
donatien 0:8e01dca41002 828 * and the peer will just drop it if it's not accepting it. */
donatien 0:8e01dca41002 829 if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) {
donatien 0:8e01dca41002 830 PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad parms prot=%d pb=%p\n",
donatien 0:8e01dca41002 831 pd, PPP_IP, pb));
donatien 0:8e01dca41002 832 LINK_STATS_INC(link.opterr);
donatien 0:8e01dca41002 833 LINK_STATS_INC(link.drop);
donatien 0:8e01dca41002 834 snmp_inc_ifoutdiscards(netif);
donatien 0:8e01dca41002 835 return ERR_ARG;
donatien 0:8e01dca41002 836 }
donatien 0:8e01dca41002 837
donatien 0:8e01dca41002 838 /* Check that the link is up. */
donatien 0:8e01dca41002 839 if (lcp_phase[pd] == PHASE_DEAD) {
donatien 0:8e01dca41002 840 PPPDEBUG(LOG_ERR, ("pppifOutput[%d]: link not up\n", pd));
donatien 0:8e01dca41002 841 LINK_STATS_INC(link.rterr);
donatien 0:8e01dca41002 842 LINK_STATS_INC(link.drop);
donatien 0:8e01dca41002 843 snmp_inc_ifoutdiscards(netif);
donatien 0:8e01dca41002 844 return ERR_RTE;
donatien 0:8e01dca41002 845 }
donatien 0:8e01dca41002 846
donatien 0:8e01dca41002 847 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 848 if(pc->ethif) {
donatien 0:8e01dca41002 849 return pppifOutputOverEthernet(pd, pb);
donatien 0:8e01dca41002 850 }
donatien 0:8e01dca41002 851 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 852
donatien 0:8e01dca41002 853 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 854 /* Grab an output buffer. */
donatien 0:8e01dca41002 855 headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
donatien 0:8e01dca41002 856 if (headMB == NULL) {
donatien 0:8e01dca41002 857 PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: first alloc fail\n", pd));
donatien 0:8e01dca41002 858 LINK_STATS_INC(link.memerr);
donatien 0:8e01dca41002 859 LINK_STATS_INC(link.drop);
donatien 0:8e01dca41002 860 snmp_inc_ifoutdiscards(netif);
donatien 0:8e01dca41002 861 return ERR_MEM;
donatien 0:8e01dca41002 862 }
donatien 0:8e01dca41002 863
donatien 0:8e01dca41002 864 #if VJ_SUPPORT
donatien 0:8e01dca41002 865 /*
donatien 0:8e01dca41002 866 * Attempt Van Jacobson header compression if VJ is configured and
donatien 0:8e01dca41002 867 * this is an IP packet.
donatien 0:8e01dca41002 868 */
donatien 0:8e01dca41002 869 if (protocol == PPP_IP && pc->vjEnabled) {
donatien 0:8e01dca41002 870 switch (vj_compress_tcp(&pc->vjComp, pb)) {
donatien 0:8e01dca41002 871 case TYPE_IP:
donatien 0:8e01dca41002 872 /* No change...
donatien 0:8e01dca41002 873 protocol = PPP_IP_PROTOCOL; */
donatien 0:8e01dca41002 874 break;
donatien 0:8e01dca41002 875 case TYPE_COMPRESSED_TCP:
donatien 0:8e01dca41002 876 protocol = PPP_VJC_COMP;
donatien 0:8e01dca41002 877 break;
donatien 0:8e01dca41002 878 case TYPE_UNCOMPRESSED_TCP:
donatien 0:8e01dca41002 879 protocol = PPP_VJC_UNCOMP;
donatien 0:8e01dca41002 880 break;
donatien 0:8e01dca41002 881 default:
donatien 0:8e01dca41002 882 PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad IP packet\n", pd));
donatien 0:8e01dca41002 883 LINK_STATS_INC(link.proterr);
donatien 0:8e01dca41002 884 LINK_STATS_INC(link.drop);
donatien 0:8e01dca41002 885 snmp_inc_ifoutdiscards(netif);
donatien 0:8e01dca41002 886 pbuf_free(headMB);
donatien 0:8e01dca41002 887 return ERR_VAL;
donatien 0:8e01dca41002 888 }
donatien 0:8e01dca41002 889 }
donatien 0:8e01dca41002 890 #endif /* VJ_SUPPORT */
donatien 0:8e01dca41002 891
donatien 0:8e01dca41002 892 tailMB = headMB;
donatien 0:8e01dca41002 893
donatien 0:8e01dca41002 894 /* Build the PPP header. */
donatien 0:8e01dca41002 895 if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) {
donatien 0:8e01dca41002 896 tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
donatien 0:8e01dca41002 897 }
donatien 0:8e01dca41002 898
donatien 0:8e01dca41002 899 pc->lastXMit = sys_jiffies();
donatien 0:8e01dca41002 900 if (!pc->accomp) {
donatien 0:8e01dca41002 901 fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS);
donatien 0:8e01dca41002 902 tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM);
donatien 0:8e01dca41002 903 fcsOut = PPP_FCS(fcsOut, PPP_UI);
donatien 0:8e01dca41002 904 tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM);
donatien 0:8e01dca41002 905 }
donatien 0:8e01dca41002 906 if (!pc->pcomp || protocol > 0xFF) {
donatien 0:8e01dca41002 907 c = (protocol >> 8) & 0xFF;
donatien 0:8e01dca41002 908 fcsOut = PPP_FCS(fcsOut, c);
donatien 0:8e01dca41002 909 tailMB = pppAppend(c, tailMB, &pc->outACCM);
donatien 0:8e01dca41002 910 }
donatien 0:8e01dca41002 911 c = protocol & 0xFF;
donatien 0:8e01dca41002 912 fcsOut = PPP_FCS(fcsOut, c);
donatien 0:8e01dca41002 913 tailMB = pppAppend(c, tailMB, &pc->outACCM);
donatien 0:8e01dca41002 914
donatien 0:8e01dca41002 915 /* Load packet. */
donatien 0:8e01dca41002 916 for(p = pb; p; p = p->next) {
donatien 0:8e01dca41002 917 int n;
donatien 0:8e01dca41002 918 u_char *sPtr;
donatien 0:8e01dca41002 919
donatien 0:8e01dca41002 920 sPtr = (u_char*)p->payload;
donatien 0:8e01dca41002 921 n = p->len;
donatien 0:8e01dca41002 922 while (n-- > 0) {
donatien 0:8e01dca41002 923 c = *sPtr++;
donatien 0:8e01dca41002 924
donatien 0:8e01dca41002 925 /* Update FCS before checking for special characters. */
donatien 0:8e01dca41002 926 fcsOut = PPP_FCS(fcsOut, c);
donatien 0:8e01dca41002 927
donatien 0:8e01dca41002 928 /* Copy to output buffer escaping special characters. */
donatien 0:8e01dca41002 929 tailMB = pppAppend(c, tailMB, &pc->outACCM);
donatien 0:8e01dca41002 930 }
donatien 0:8e01dca41002 931 }
donatien 0:8e01dca41002 932
donatien 0:8e01dca41002 933 /* Add FCS and trailing flag. */
donatien 0:8e01dca41002 934 c = ~fcsOut & 0xFF;
donatien 0:8e01dca41002 935 tailMB = pppAppend(c, tailMB, &pc->outACCM);
donatien 0:8e01dca41002 936 c = (~fcsOut >> 8) & 0xFF;
donatien 0:8e01dca41002 937 tailMB = pppAppend(c, tailMB, &pc->outACCM);
donatien 0:8e01dca41002 938 tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
donatien 0:8e01dca41002 939
donatien 0:8e01dca41002 940 /* If we failed to complete the packet, throw it away. */
donatien 0:8e01dca41002 941 if (!tailMB) {
donatien 0:8e01dca41002 942 PPPDEBUG(LOG_WARNING,
donatien 0:8e01dca41002 943 ("pppifOutput[%d]: Alloc err - dropping proto=%d\n",
donatien 0:8e01dca41002 944 pd, protocol));
donatien 0:8e01dca41002 945 pbuf_free(headMB);
donatien 0:8e01dca41002 946 LINK_STATS_INC(link.memerr);
donatien 0:8e01dca41002 947 LINK_STATS_INC(link.drop);
donatien 0:8e01dca41002 948 snmp_inc_ifoutdiscards(netif);
donatien 0:8e01dca41002 949 return ERR_MEM;
donatien 0:8e01dca41002 950 }
donatien 0:8e01dca41002 951
donatien 0:8e01dca41002 952 /* Send it. */
donatien 0:8e01dca41002 953 PPPDEBUG(LOG_INFO, ("pppifOutput[%d]: proto=0x%"X16_F"\n", pd, protocol));
donatien 0:8e01dca41002 954
donatien 0:8e01dca41002 955 nPut(pc, headMB);
donatien 0:8e01dca41002 956 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 957
donatien 0:8e01dca41002 958 return ERR_OK;
donatien 0:8e01dca41002 959 }
donatien 0:8e01dca41002 960
donatien 0:8e01dca41002 961 /* Get and set parameters for the given connection.
donatien 0:8e01dca41002 962 * Return 0 on success, an error code on failure. */
donatien 0:8e01dca41002 963 int
donatien 0:8e01dca41002 964 pppIOCtl(int pd, int cmd, void *arg)
donatien 0:8e01dca41002 965 {
donatien 0:8e01dca41002 966 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 967 int st = 0;
donatien 0:8e01dca41002 968
donatien 0:8e01dca41002 969 if (pd < 0 || pd >= NUM_PPP) {
donatien 0:8e01dca41002 970 st = PPPERR_PARAM;
donatien 0:8e01dca41002 971 } else {
donatien 0:8e01dca41002 972 switch(cmd) {
donatien 0:8e01dca41002 973 case PPPCTLG_UPSTATUS: /* Get the PPP up status. */
donatien 0:8e01dca41002 974 if (arg) {
donatien 0:8e01dca41002 975 *(int *)arg = (int)(pc->if_up);
donatien 0:8e01dca41002 976 } else {
donatien 0:8e01dca41002 977 st = PPPERR_PARAM;
donatien 0:8e01dca41002 978 }
donatien 0:8e01dca41002 979 break;
donatien 0:8e01dca41002 980 case PPPCTLS_ERRCODE: /* Set the PPP error code. */
donatien 0:8e01dca41002 981 if (arg) {
donatien 0:8e01dca41002 982 pc->errCode = *(int *)arg;
donatien 0:8e01dca41002 983 } else {
donatien 0:8e01dca41002 984 st = PPPERR_PARAM;
donatien 0:8e01dca41002 985 }
donatien 0:8e01dca41002 986 break;
donatien 0:8e01dca41002 987 case PPPCTLG_ERRCODE: /* Get the PPP error code. */
donatien 0:8e01dca41002 988 if (arg) {
donatien 0:8e01dca41002 989 *(int *)arg = (int)(pc->errCode);
donatien 0:8e01dca41002 990 } else {
donatien 0:8e01dca41002 991 st = PPPERR_PARAM;
donatien 0:8e01dca41002 992 }
donatien 0:8e01dca41002 993 break;
donatien 0:8e01dca41002 994 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 995 case PPPCTLG_FD: /* Get the fd associated with the ppp */
donatien 0:8e01dca41002 996 if (arg) {
donatien 0:8e01dca41002 997 *(sio_fd_t *)arg = pc->fd;
donatien 0:8e01dca41002 998 } else {
donatien 0:8e01dca41002 999 st = PPPERR_PARAM;
donatien 0:8e01dca41002 1000 }
donatien 0:8e01dca41002 1001 break;
donatien 0:8e01dca41002 1002 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 1003 default:
donatien 0:8e01dca41002 1004 st = PPPERR_PARAM;
donatien 0:8e01dca41002 1005 break;
donatien 0:8e01dca41002 1006 }
donatien 0:8e01dca41002 1007 }
donatien 0:8e01dca41002 1008
donatien 0:8e01dca41002 1009 return st;
donatien 0:8e01dca41002 1010 }
donatien 0:8e01dca41002 1011
donatien 0:8e01dca41002 1012 /*
donatien 0:8e01dca41002 1013 * Return the Maximum Transmission Unit for the given PPP connection.
donatien 0:8e01dca41002 1014 */
donatien 0:8e01dca41002 1015 u_short
donatien 0:8e01dca41002 1016 pppMTU(int pd)
donatien 0:8e01dca41002 1017 {
donatien 0:8e01dca41002 1018 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 1019 u_short st;
donatien 0:8e01dca41002 1020
donatien 0:8e01dca41002 1021 /* Validate parameters. */
donatien 0:8e01dca41002 1022 if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
donatien 0:8e01dca41002 1023 st = 0;
donatien 0:8e01dca41002 1024 } else {
donatien 0:8e01dca41002 1025 st = pc->mtu;
donatien 0:8e01dca41002 1026 }
donatien 0:8e01dca41002 1027
donatien 0:8e01dca41002 1028 return st;
donatien 0:8e01dca41002 1029 }
donatien 0:8e01dca41002 1030
donatien 0:8e01dca41002 1031 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 1032 int
donatien 0:8e01dca41002 1033 pppWriteOverEthernet(int pd, const u_char *s, int n)
donatien 0:8e01dca41002 1034 {
donatien 0:8e01dca41002 1035 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 1036 struct pbuf *pb;
donatien 0:8e01dca41002 1037
donatien 0:8e01dca41002 1038 /* skip address & flags */
donatien 0:8e01dca41002 1039 s += 2;
donatien 0:8e01dca41002 1040 n -= 2;
donatien 0:8e01dca41002 1041
donatien 0:8e01dca41002 1042 LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff);
donatien 0:8e01dca41002 1043 pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM);
donatien 0:8e01dca41002 1044 if(!pb) {
donatien 0:8e01dca41002 1045 LINK_STATS_INC(link.memerr);
donatien 0:8e01dca41002 1046 LINK_STATS_INC(link.proterr);
donatien 0:8e01dca41002 1047 snmp_inc_ifoutdiscards(&pc->netif);
donatien 0:8e01dca41002 1048 return PPPERR_ALLOC;
donatien 0:8e01dca41002 1049 }
donatien 0:8e01dca41002 1050
donatien 0:8e01dca41002 1051 pbuf_header(pb, -(s16_t)PPPOE_HDRLEN);
donatien 0:8e01dca41002 1052
donatien 0:8e01dca41002 1053 pc->lastXMit = sys_jiffies();
donatien 0:8e01dca41002 1054
donatien 0:8e01dca41002 1055 MEMCPY(pb->payload, s, n);
donatien 0:8e01dca41002 1056
donatien 0:8e01dca41002 1057 if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) {
donatien 0:8e01dca41002 1058 LINK_STATS_INC(link.err);
donatien 0:8e01dca41002 1059 snmp_inc_ifoutdiscards(&pc->netif);
donatien 0:8e01dca41002 1060 return PPPERR_DEVICE;
donatien 0:8e01dca41002 1061 }
donatien 0:8e01dca41002 1062
donatien 0:8e01dca41002 1063 snmp_add_ifoutoctets(&pc->netif, (u16_t)n);
donatien 0:8e01dca41002 1064 snmp_inc_ifoutucastpkts(&pc->netif);
donatien 0:8e01dca41002 1065 LINK_STATS_INC(link.xmit);
donatien 0:8e01dca41002 1066 return PPPERR_NONE;
donatien 0:8e01dca41002 1067 }
donatien 0:8e01dca41002 1068 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 1069
donatien 0:8e01dca41002 1070 /*
donatien 0:8e01dca41002 1071 * Write n characters to a ppp link.
donatien 0:8e01dca41002 1072 * RETURN: >= 0 Number of characters written
donatien 0:8e01dca41002 1073 * -1 Failed to write to device
donatien 0:8e01dca41002 1074 */
donatien 0:8e01dca41002 1075 int
donatien 0:8e01dca41002 1076 pppWrite(int pd, const u_char *s, int n)
donatien 0:8e01dca41002 1077 {
donatien 0:8e01dca41002 1078 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 1079 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 1080 u_char c;
donatien 0:8e01dca41002 1081 u_int fcsOut;
donatien 0:8e01dca41002 1082 struct pbuf *headMB, *tailMB;
donatien 0:8e01dca41002 1083 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 1084
donatien 0:8e01dca41002 1085 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 1086 if(pc->ethif) {
donatien 0:8e01dca41002 1087 return pppWriteOverEthernet(pd, s, n);
donatien 0:8e01dca41002 1088 }
donatien 0:8e01dca41002 1089 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 1090
donatien 0:8e01dca41002 1091 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 1092 headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
donatien 0:8e01dca41002 1093 if (headMB == NULL) {
donatien 0:8e01dca41002 1094 LINK_STATS_INC(link.memerr);
donatien 0:8e01dca41002 1095 LINK_STATS_INC(link.proterr);
donatien 0:8e01dca41002 1096 snmp_inc_ifoutdiscards(&pc->netif);
donatien 0:8e01dca41002 1097 return PPPERR_ALLOC;
donatien 0:8e01dca41002 1098 }
donatien 0:8e01dca41002 1099
donatien 0:8e01dca41002 1100 tailMB = headMB;
donatien 0:8e01dca41002 1101
donatien 0:8e01dca41002 1102 /* If the link has been idle, we'll send a fresh flag character to
donatien 0:8e01dca41002 1103 * flush any noise. */
donatien 0:8e01dca41002 1104 if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) {
donatien 0:8e01dca41002 1105 tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
donatien 0:8e01dca41002 1106 }
donatien 0:8e01dca41002 1107 pc->lastXMit = sys_jiffies();
donatien 0:8e01dca41002 1108
donatien 0:8e01dca41002 1109 fcsOut = PPP_INITFCS;
donatien 0:8e01dca41002 1110 /* Load output buffer. */
donatien 0:8e01dca41002 1111 while (n-- > 0) {
donatien 0:8e01dca41002 1112 c = *s++;
donatien 0:8e01dca41002 1113
donatien 0:8e01dca41002 1114 /* Update FCS before checking for special characters. */
donatien 0:8e01dca41002 1115 fcsOut = PPP_FCS(fcsOut, c);
donatien 0:8e01dca41002 1116
donatien 0:8e01dca41002 1117 /* Copy to output buffer escaping special characters. */
donatien 0:8e01dca41002 1118 tailMB = pppAppend(c, tailMB, &pc->outACCM);
donatien 0:8e01dca41002 1119 }
donatien 0:8e01dca41002 1120
donatien 0:8e01dca41002 1121 /* Add FCS and trailing flag. */
donatien 0:8e01dca41002 1122 c = ~fcsOut & 0xFF;
donatien 0:8e01dca41002 1123 tailMB = pppAppend(c, tailMB, &pc->outACCM);
donatien 0:8e01dca41002 1124 c = (~fcsOut >> 8) & 0xFF;
donatien 0:8e01dca41002 1125 tailMB = pppAppend(c, tailMB, &pc->outACCM);
donatien 0:8e01dca41002 1126 tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
donatien 0:8e01dca41002 1127
donatien 0:8e01dca41002 1128 /* If we failed to complete the packet, throw it away.
donatien 0:8e01dca41002 1129 * Otherwise send it. */
donatien 0:8e01dca41002 1130 if (!tailMB) {
donatien 0:8e01dca41002 1131 PPPDEBUG(LOG_WARNING,
donatien 0:8e01dca41002 1132 ("pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len));
donatien 0:8e01dca41002 1133 /*"pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */
donatien 0:8e01dca41002 1134 pbuf_free(headMB);
donatien 0:8e01dca41002 1135 LINK_STATS_INC(link.memerr);
donatien 0:8e01dca41002 1136 LINK_STATS_INC(link.proterr);
donatien 0:8e01dca41002 1137 snmp_inc_ifoutdiscards(&pc->netif);
donatien 0:8e01dca41002 1138 return PPPERR_ALLOC;
donatien 0:8e01dca41002 1139 }
donatien 0:8e01dca41002 1140
donatien 0:8e01dca41002 1141 PPPDEBUG(LOG_INFO, ("pppWrite[%d]: len=%d\n", pd, headMB->len));
donatien 0:8e01dca41002 1142 /* "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */
donatien 0:8e01dca41002 1143 nPut(pc, headMB);
donatien 0:8e01dca41002 1144 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 1145
donatien 0:8e01dca41002 1146 return PPPERR_NONE;
donatien 0:8e01dca41002 1147 }
donatien 0:8e01dca41002 1148
donatien 0:8e01dca41002 1149 /*
donatien 0:8e01dca41002 1150 * ppp_send_config - configure the transmit characteristics of
donatien 0:8e01dca41002 1151 * the ppp interface.
donatien 0:8e01dca41002 1152 */
donatien 0:8e01dca41002 1153 void
donatien 0:8e01dca41002 1154 ppp_send_config( int unit, u16_t mtu, u32_t asyncmap, int pcomp, int accomp)
donatien 0:8e01dca41002 1155 {
donatien 0:8e01dca41002 1156 PPPControl *pc = &pppControl[unit];
donatien 0:8e01dca41002 1157 int i;
donatien 0:8e01dca41002 1158
donatien 0:8e01dca41002 1159 pc->mtu = mtu;
donatien 0:8e01dca41002 1160 pc->pcomp = pcomp;
donatien 0:8e01dca41002 1161 pc->accomp = accomp;
donatien 0:8e01dca41002 1162
donatien 0:8e01dca41002 1163 /* Load the ACCM bits for the 32 control codes. */
donatien 0:8e01dca41002 1164 for (i = 0; i < 32/8; i++) {
donatien 0:8e01dca41002 1165 pc->outACCM[i] = (u_char)((asyncmap >> (8 * i)) & 0xFF);
donatien 0:8e01dca41002 1166 }
donatien 0:8e01dca41002 1167 PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n",
donatien 0:8e01dca41002 1168 unit,
donatien 0:8e01dca41002 1169 pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3]));
donatien 0:8e01dca41002 1170 }
donatien 0:8e01dca41002 1171
donatien 0:8e01dca41002 1172
donatien 0:8e01dca41002 1173 /*
donatien 0:8e01dca41002 1174 * ppp_set_xaccm - set the extended transmit ACCM for the interface.
donatien 0:8e01dca41002 1175 */
donatien 0:8e01dca41002 1176 void
donatien 0:8e01dca41002 1177 ppp_set_xaccm(int unit, ext_accm *accm)
donatien 0:8e01dca41002 1178 {
donatien 0:8e01dca41002 1179 SMEMCPY(pppControl[unit].outACCM, accm, sizeof(ext_accm));
donatien 0:8e01dca41002 1180 PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n",
donatien 0:8e01dca41002 1181 unit,
donatien 0:8e01dca41002 1182 pppControl[unit].outACCM[0],
donatien 0:8e01dca41002 1183 pppControl[unit].outACCM[1],
donatien 0:8e01dca41002 1184 pppControl[unit].outACCM[2],
donatien 0:8e01dca41002 1185 pppControl[unit].outACCM[3]));
donatien 0:8e01dca41002 1186 }
donatien 0:8e01dca41002 1187
donatien 0:8e01dca41002 1188
donatien 0:8e01dca41002 1189 /*
donatien 0:8e01dca41002 1190 * ppp_recv_config - configure the receive-side characteristics of
donatien 0:8e01dca41002 1191 * the ppp interface.
donatien 0:8e01dca41002 1192 */
donatien 0:8e01dca41002 1193 void
donatien 0:8e01dca41002 1194 ppp_recv_config( int unit, int mru, u32_t asyncmap, int pcomp, int accomp)
donatien 0:8e01dca41002 1195 {
donatien 0:8e01dca41002 1196 PPPControl *pc = &pppControl[unit];
donatien 0:8e01dca41002 1197 int i;
donatien 0:8e01dca41002 1198 SYS_ARCH_DECL_PROTECT(lev);
donatien 0:8e01dca41002 1199
donatien 0:8e01dca41002 1200 LWIP_UNUSED_ARG(accomp);
donatien 0:8e01dca41002 1201 LWIP_UNUSED_ARG(pcomp);
donatien 0:8e01dca41002 1202 LWIP_UNUSED_ARG(mru);
donatien 0:8e01dca41002 1203
donatien 0:8e01dca41002 1204 /* Load the ACCM bits for the 32 control codes. */
donatien 0:8e01dca41002 1205 SYS_ARCH_PROTECT(lev);
donatien 0:8e01dca41002 1206 for (i = 0; i < 32 / 8; i++) {
donatien 0:8e01dca41002 1207 /* @todo: does this work? ext_accm has been modified from pppd! */
donatien 0:8e01dca41002 1208 pc->rx.inACCM[i] = (u_char)(asyncmap >> (i * 8));
donatien 0:8e01dca41002 1209 }
donatien 0:8e01dca41002 1210 SYS_ARCH_UNPROTECT(lev);
donatien 0:8e01dca41002 1211 PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n",
donatien 0:8e01dca41002 1212 unit,
donatien 0:8e01dca41002 1213 pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3]));
donatien 0:8e01dca41002 1214 }
donatien 0:8e01dca41002 1215
donatien 0:8e01dca41002 1216 #if 0
donatien 0:8e01dca41002 1217 /*
donatien 0:8e01dca41002 1218 * ccp_test - ask kernel whether a given compression method
donatien 0:8e01dca41002 1219 * is acceptable for use. Returns 1 if the method and parameters
donatien 0:8e01dca41002 1220 * are OK, 0 if the method is known but the parameters are not OK
donatien 0:8e01dca41002 1221 * (e.g. code size should be reduced), or -1 if the method is unknown.
donatien 0:8e01dca41002 1222 */
donatien 0:8e01dca41002 1223 int
donatien 0:8e01dca41002 1224 ccp_test( int unit, int opt_len, int for_transmit, u_char *opt_ptr)
donatien 0:8e01dca41002 1225 {
donatien 0:8e01dca41002 1226 return 0; /* XXX Currently no compression. */
donatien 0:8e01dca41002 1227 }
donatien 0:8e01dca41002 1228
donatien 0:8e01dca41002 1229 /*
donatien 0:8e01dca41002 1230 * ccp_flags_set - inform kernel about the current state of CCP.
donatien 0:8e01dca41002 1231 */
donatien 0:8e01dca41002 1232 void
donatien 0:8e01dca41002 1233 ccp_flags_set(int unit, int isopen, int isup)
donatien 0:8e01dca41002 1234 {
donatien 0:8e01dca41002 1235 /* XXX */
donatien 0:8e01dca41002 1236 }
donatien 0:8e01dca41002 1237
donatien 0:8e01dca41002 1238 /*
donatien 0:8e01dca41002 1239 * ccp_fatal_error - returns 1 if decompression was disabled as a
donatien 0:8e01dca41002 1240 * result of an error detected after decompression of a packet,
donatien 0:8e01dca41002 1241 * 0 otherwise. This is necessary because of patent nonsense.
donatien 0:8e01dca41002 1242 */
donatien 0:8e01dca41002 1243 int
donatien 0:8e01dca41002 1244 ccp_fatal_error(int unit)
donatien 0:8e01dca41002 1245 {
donatien 0:8e01dca41002 1246 /* XXX */
donatien 0:8e01dca41002 1247 return 0;
donatien 0:8e01dca41002 1248 }
donatien 0:8e01dca41002 1249 #endif
donatien 0:8e01dca41002 1250
donatien 0:8e01dca41002 1251 /*
donatien 0:8e01dca41002 1252 * get_idle_time - return how long the link has been idle.
donatien 0:8e01dca41002 1253 */
donatien 0:8e01dca41002 1254 int
donatien 0:8e01dca41002 1255 get_idle_time(int u, struct ppp_idle *ip)
donatien 0:8e01dca41002 1256 {
donatien 0:8e01dca41002 1257 /* XXX */
donatien 0:8e01dca41002 1258 LWIP_UNUSED_ARG(u);
donatien 0:8e01dca41002 1259 LWIP_UNUSED_ARG(ip);
donatien 0:8e01dca41002 1260
donatien 0:8e01dca41002 1261 return 0;
donatien 0:8e01dca41002 1262 }
donatien 0:8e01dca41002 1263
donatien 0:8e01dca41002 1264
donatien 0:8e01dca41002 1265 /*
donatien 0:8e01dca41002 1266 * Return user specified netmask, modified by any mask we might determine
donatien 0:8e01dca41002 1267 * for address `addr' (in network byte order).
donatien 0:8e01dca41002 1268 * Here we scan through the system's list of interfaces, looking for
donatien 0:8e01dca41002 1269 * any non-point-to-point interfaces which might appear to be on the same
donatien 0:8e01dca41002 1270 * network as `addr'. If we find any, we OR in their netmask to the
donatien 0:8e01dca41002 1271 * user-specified netmask.
donatien 0:8e01dca41002 1272 */
donatien 0:8e01dca41002 1273 u32_t
donatien 0:8e01dca41002 1274 GetMask(u32_t addr)
donatien 0:8e01dca41002 1275 {
donatien 0:8e01dca41002 1276 u32_t mask, nmask;
donatien 0:8e01dca41002 1277
donatien 0:8e01dca41002 1278 htonl(addr);
donatien 0:8e01dca41002 1279 if (IP_CLASSA(addr)) { /* determine network mask for address class */
donatien 0:8e01dca41002 1280 nmask = IP_CLASSA_NET;
donatien 0:8e01dca41002 1281 } else if (IP_CLASSB(addr)) {
donatien 0:8e01dca41002 1282 nmask = IP_CLASSB_NET;
donatien 0:8e01dca41002 1283 } else {
donatien 0:8e01dca41002 1284 nmask = IP_CLASSC_NET;
donatien 0:8e01dca41002 1285 }
donatien 0:8e01dca41002 1286
donatien 0:8e01dca41002 1287 /* class D nets are disallowed by bad_ip_adrs */
donatien 0:8e01dca41002 1288 mask = subnetMask | htonl(nmask);
donatien 0:8e01dca41002 1289
donatien 0:8e01dca41002 1290 /* XXX
donatien 0:8e01dca41002 1291 * Scan through the system's network interfaces.
donatien 0:8e01dca41002 1292 * Get each netmask and OR them into our mask.
donatien 0:8e01dca41002 1293 */
donatien 0:8e01dca41002 1294
donatien 0:8e01dca41002 1295 return mask;
donatien 0:8e01dca41002 1296 }
donatien 0:8e01dca41002 1297
donatien 0:8e01dca41002 1298 /*
donatien 0:8e01dca41002 1299 * sifvjcomp - config tcp header compression
donatien 0:8e01dca41002 1300 */
donatien 0:8e01dca41002 1301 int
donatien 0:8e01dca41002 1302 sifvjcomp(int pd, int vjcomp, u8_t cidcomp, u8_t maxcid)
donatien 0:8e01dca41002 1303 {
donatien 0:8e01dca41002 1304 #if PPPOS_SUPPORT && VJ_SUPPORT
donatien 0:8e01dca41002 1305 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 1306
donatien 0:8e01dca41002 1307 pc->vjEnabled = vjcomp;
donatien 0:8e01dca41002 1308 pc->vjComp.compressSlot = cidcomp;
donatien 0:8e01dca41002 1309 pc->vjComp.maxSlotIndex = maxcid;
donatien 0:8e01dca41002 1310 PPPDEBUG(LOG_INFO, ("sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n",
donatien 0:8e01dca41002 1311 vjcomp, cidcomp, maxcid));
donatien 0:8e01dca41002 1312 #else /* PPPOS_SUPPORT && VJ_SUPPORT */
donatien 0:8e01dca41002 1313 LWIP_UNUSED_ARG(pd);
donatien 0:8e01dca41002 1314 LWIP_UNUSED_ARG(vjcomp);
donatien 0:8e01dca41002 1315 LWIP_UNUSED_ARG(cidcomp);
donatien 0:8e01dca41002 1316 LWIP_UNUSED_ARG(maxcid);
donatien 0:8e01dca41002 1317 #endif /* PPPOS_SUPPORT && VJ_SUPPORT */
donatien 0:8e01dca41002 1318
donatien 0:8e01dca41002 1319 return 0;
donatien 0:8e01dca41002 1320 }
donatien 0:8e01dca41002 1321
donatien 0:8e01dca41002 1322 /*
donatien 0:8e01dca41002 1323 * pppifNetifInit - netif init callback
donatien 0:8e01dca41002 1324 */
donatien 0:8e01dca41002 1325 static err_t
donatien 0:8e01dca41002 1326 pppifNetifInit(struct netif *netif)
donatien 0:8e01dca41002 1327 {
donatien 0:8e01dca41002 1328 netif->name[0] = 'p';
donatien 0:8e01dca41002 1329 netif->name[1] = 'p';
donatien 0:8e01dca41002 1330 netif->output = pppifOutput;
donatien 0:8e01dca41002 1331 netif->mtu = pppMTU((int)(size_t)netif->state);
donatien 0:8e01dca41002 1332 netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP;
donatien 0:8e01dca41002 1333 #if LWIP_NETIF_HOSTNAME
donatien 0:8e01dca41002 1334 /* @todo: Initialize interface hostname */
donatien 0:8e01dca41002 1335 /* netif_set_hostname(netif, "lwip"); */
donatien 0:8e01dca41002 1336 #endif /* LWIP_NETIF_HOSTNAME */
donatien 0:8e01dca41002 1337 return ERR_OK;
donatien 0:8e01dca41002 1338 }
donatien 0:8e01dca41002 1339
donatien 0:8e01dca41002 1340
donatien 0:8e01dca41002 1341 /*
donatien 0:8e01dca41002 1342 * sifup - Config the interface up and enable IP packets to pass.
donatien 0:8e01dca41002 1343 */
donatien 0:8e01dca41002 1344 int
donatien 0:8e01dca41002 1345 sifup(int pd)
donatien 0:8e01dca41002 1346 {
donatien 0:8e01dca41002 1347 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 1348 int st = 1;
donatien 0:8e01dca41002 1349
donatien 0:8e01dca41002 1350 if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
donatien 0:8e01dca41002 1351 st = 0;
donatien 0:8e01dca41002 1352 PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd));
donatien 0:8e01dca41002 1353 } else {
donatien 0:8e01dca41002 1354 netif_remove(&pc->netif);
donatien 0:8e01dca41002 1355 if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask,
donatien 0:8e01dca41002 1356 &pc->addrs.his_ipaddr, (void *)(size_t)pd, pppifNetifInit, ip_input)) {
donatien 0:8e01dca41002 1357 netif_set_up(&pc->netif);
donatien 0:8e01dca41002 1358 pc->if_up = 1;
donatien 0:8e01dca41002 1359 pc->errCode = PPPERR_NONE;
donatien 0:8e01dca41002 1360
donatien 0:8e01dca41002 1361 PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
donatien 0:8e01dca41002 1362 if (pc->linkStatusCB) {
donatien 0:8e01dca41002 1363 pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs);
donatien 0:8e01dca41002 1364 }
donatien 0:8e01dca41002 1365 } else {
donatien 0:8e01dca41002 1366 st = 0;
donatien 0:8e01dca41002 1367 PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pd));
donatien 0:8e01dca41002 1368 }
donatien 0:8e01dca41002 1369 }
donatien 0:8e01dca41002 1370
donatien 0:8e01dca41002 1371 return st;
donatien 0:8e01dca41002 1372 }
donatien 0:8e01dca41002 1373
donatien 0:8e01dca41002 1374 /*
donatien 0:8e01dca41002 1375 * sifnpmode - Set the mode for handling packets for a given NP.
donatien 0:8e01dca41002 1376 */
donatien 0:8e01dca41002 1377 int
donatien 0:8e01dca41002 1378 sifnpmode(int u, int proto, enum NPmode mode)
donatien 0:8e01dca41002 1379 {
donatien 0:8e01dca41002 1380 LWIP_UNUSED_ARG(u);
donatien 0:8e01dca41002 1381 LWIP_UNUSED_ARG(proto);
donatien 0:8e01dca41002 1382 LWIP_UNUSED_ARG(mode);
donatien 0:8e01dca41002 1383 return 0;
donatien 0:8e01dca41002 1384 }
donatien 0:8e01dca41002 1385
donatien 0:8e01dca41002 1386 /*
donatien 0:8e01dca41002 1387 * sifdown - Config the interface down and disable IP.
donatien 0:8e01dca41002 1388 */
donatien 0:8e01dca41002 1389 int
donatien 0:8e01dca41002 1390 sifdown(int pd)
donatien 0:8e01dca41002 1391 {
donatien 0:8e01dca41002 1392 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 1393 int st = 1;
donatien 0:8e01dca41002 1394
donatien 0:8e01dca41002 1395 if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
donatien 0:8e01dca41002 1396 st = 0;
donatien 0:8e01dca41002 1397 PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad parms\n", pd));
donatien 0:8e01dca41002 1398 } else {
donatien 0:8e01dca41002 1399 pc->if_up = 0;
donatien 0:8e01dca41002 1400 /* make sure the netif status callback is called */
donatien 0:8e01dca41002 1401 netif_set_down(&pc->netif);
donatien 0:8e01dca41002 1402 netif_remove(&pc->netif);
donatien 0:8e01dca41002 1403 PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
donatien 0:8e01dca41002 1404 if (pc->linkStatusCB) {
donatien 0:8e01dca41002 1405 pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL);
donatien 0:8e01dca41002 1406 }
donatien 0:8e01dca41002 1407 }
donatien 0:8e01dca41002 1408 return st;
donatien 0:8e01dca41002 1409 }
donatien 0:8e01dca41002 1410
donatien 0:8e01dca41002 1411 /**
donatien 0:8e01dca41002 1412 * sifaddr - Config the interface IP addresses and netmask.
donatien 0:8e01dca41002 1413 * @param pd Interface unit ???
donatien 0:8e01dca41002 1414 * @param o Our IP address ???
donatien 0:8e01dca41002 1415 * @param h His IP address ???
donatien 0:8e01dca41002 1416 * @param m IP subnet mask ???
donatien 0:8e01dca41002 1417 * @param ns1 Primary DNS
donatien 0:8e01dca41002 1418 * @param ns2 Secondary DNS
donatien 0:8e01dca41002 1419 */
donatien 0:8e01dca41002 1420 int
donatien 0:8e01dca41002 1421 sifaddr( int pd, u32_t o, u32_t h, u32_t m, u32_t ns1, u32_t ns2)
donatien 0:8e01dca41002 1422 {
donatien 0:8e01dca41002 1423 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 1424 int st = 1;
donatien 0:8e01dca41002 1425
donatien 0:8e01dca41002 1426 if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
donatien 0:8e01dca41002 1427 st = 0;
donatien 0:8e01dca41002 1428 PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd));
donatien 0:8e01dca41002 1429 } else {
donatien 0:8e01dca41002 1430 SMEMCPY(&pc->addrs.our_ipaddr, &o, sizeof(o));
donatien 0:8e01dca41002 1431 SMEMCPY(&pc->addrs.his_ipaddr, &h, sizeof(h));
donatien 0:8e01dca41002 1432 SMEMCPY(&pc->addrs.netmask, &m, sizeof(m));
donatien 0:8e01dca41002 1433 SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1));
donatien 0:8e01dca41002 1434 SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2));
donatien 0:8e01dca41002 1435 }
donatien 0:8e01dca41002 1436 return st;
donatien 0:8e01dca41002 1437 }
donatien 0:8e01dca41002 1438
donatien 0:8e01dca41002 1439 /**
donatien 0:8e01dca41002 1440 * cifaddr - Clear the interface IP addresses, and delete routes
donatien 0:8e01dca41002 1441 * through the interface if possible.
donatien 0:8e01dca41002 1442 * @param pd Interface unit ???
donatien 0:8e01dca41002 1443 * @param o Our IP address ???
donatien 0:8e01dca41002 1444 * @param h IP broadcast address ???
donatien 0:8e01dca41002 1445 */
donatien 0:8e01dca41002 1446 int
donatien 0:8e01dca41002 1447 cifaddr( int pd, u32_t o, u32_t h)
donatien 0:8e01dca41002 1448 {
donatien 0:8e01dca41002 1449 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 1450 int st = 1;
donatien 0:8e01dca41002 1451
donatien 0:8e01dca41002 1452 LWIP_UNUSED_ARG(o);
donatien 0:8e01dca41002 1453 LWIP_UNUSED_ARG(h);
donatien 0:8e01dca41002 1454 if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
donatien 0:8e01dca41002 1455 st = 0;
donatien 0:8e01dca41002 1456 PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd));
donatien 0:8e01dca41002 1457 } else {
donatien 0:8e01dca41002 1458 IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0);
donatien 0:8e01dca41002 1459 IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0);
donatien 0:8e01dca41002 1460 IP4_ADDR(&pc->addrs.netmask, 255,255,255,0);
donatien 0:8e01dca41002 1461 IP4_ADDR(&pc->addrs.dns1, 0,0,0,0);
donatien 0:8e01dca41002 1462 IP4_ADDR(&pc->addrs.dns2, 0,0,0,0);
donatien 0:8e01dca41002 1463 }
donatien 0:8e01dca41002 1464 return st;
donatien 0:8e01dca41002 1465 }
donatien 0:8e01dca41002 1466
donatien 0:8e01dca41002 1467 /*
donatien 0:8e01dca41002 1468 * sifdefaultroute - assign a default route through the address given.
donatien 0:8e01dca41002 1469 */
donatien 0:8e01dca41002 1470 int
donatien 0:8e01dca41002 1471 sifdefaultroute(int pd, u32_t l, u32_t g)
donatien 0:8e01dca41002 1472 {
donatien 0:8e01dca41002 1473 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 1474 int st = 1;
donatien 0:8e01dca41002 1475
donatien 0:8e01dca41002 1476 LWIP_UNUSED_ARG(l);
donatien 0:8e01dca41002 1477 LWIP_UNUSED_ARG(g);
donatien 0:8e01dca41002 1478
donatien 0:8e01dca41002 1479 if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
donatien 0:8e01dca41002 1480 st = 0;
donatien 0:8e01dca41002 1481 PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd));
donatien 0:8e01dca41002 1482 } else {
donatien 0:8e01dca41002 1483 netif_set_default(&pc->netif);
donatien 0:8e01dca41002 1484 }
donatien 0:8e01dca41002 1485
donatien 0:8e01dca41002 1486 /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */
donatien 0:8e01dca41002 1487
donatien 0:8e01dca41002 1488 return st;
donatien 0:8e01dca41002 1489 }
donatien 0:8e01dca41002 1490
donatien 0:8e01dca41002 1491 /*
donatien 0:8e01dca41002 1492 * cifdefaultroute - delete a default route through the address given.
donatien 0:8e01dca41002 1493 */
donatien 0:8e01dca41002 1494 int
donatien 0:8e01dca41002 1495 cifdefaultroute(int pd, u32_t l, u32_t g)
donatien 0:8e01dca41002 1496 {
donatien 0:8e01dca41002 1497 PPPControl *pc = &pppControl[pd];
donatien 0:8e01dca41002 1498 int st = 1;
donatien 0:8e01dca41002 1499
donatien 0:8e01dca41002 1500 LWIP_UNUSED_ARG(l);
donatien 0:8e01dca41002 1501 LWIP_UNUSED_ARG(g);
donatien 0:8e01dca41002 1502
donatien 0:8e01dca41002 1503 if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
donatien 0:8e01dca41002 1504 st = 0;
donatien 0:8e01dca41002 1505 PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd));
donatien 0:8e01dca41002 1506 } else {
donatien 0:8e01dca41002 1507 netif_set_default(NULL);
donatien 0:8e01dca41002 1508 }
donatien 0:8e01dca41002 1509
donatien 0:8e01dca41002 1510 return st;
donatien 0:8e01dca41002 1511 }
donatien 0:8e01dca41002 1512
donatien 0:8e01dca41002 1513 /**********************************/
donatien 0:8e01dca41002 1514 /*** LOCAL FUNCTION DEFINITIONS ***/
donatien 0:8e01dca41002 1515 /**********************************/
donatien 0:8e01dca41002 1516
donatien 0:8e01dca41002 1517 #if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD
donatien 0:8e01dca41002 1518 /* The main PPP process function. This implements the state machine according
donatien 0:8e01dca41002 1519 * to section 4 of RFC 1661: The Point-To-Point Protocol. */
donatien 0:8e01dca41002 1520 static void
donatien 0:8e01dca41002 1521 pppInputThread(void *arg)
donatien 0:8e01dca41002 1522 {
donatien 0:8e01dca41002 1523 int count;
donatien 0:8e01dca41002 1524 PPPControlRx *pcrx = arg;
donatien 0:8e01dca41002 1525
donatien 0:8e01dca41002 1526 #if !__LWIP_ORIG
donatien 0:8e01dca41002 1527 do
donatien 0:8e01dca41002 1528 {
donatien 0:8e01dca41002 1529 sys_arch_mbox_fetch(&pppMbox, (void**)&pcrx, 0); //Wait indefinitely
donatien 0:8e01dca41002 1530 #endif
donatien 0:8e01dca41002 1531
donatien 0:8e01dca41002 1532 while (lcp_phase[pcrx->pd] != PHASE_DEAD) {
donatien 0:8e01dca41002 1533 count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE);
donatien 0:8e01dca41002 1534 if(count > 0) {
donatien 0:8e01dca41002 1535 pppInProc(pcrx, pcrx->rxbuf, count);
donatien 0:8e01dca41002 1536 } else {
donatien 0:8e01dca41002 1537 /* nothing received, give other tasks a chance to run */
donatien 0:8e01dca41002 1538 sys_msleep(1);
donatien 0:8e01dca41002 1539 }
donatien 0:8e01dca41002 1540 }
donatien 0:8e01dca41002 1541 #if !__LWIP_ORIG
donatien 0:8e01dca41002 1542 } while(1); //Never terminates
donatien 0:8e01dca41002 1543 #endif
donatien 0:8e01dca41002 1544 }
donatien 0:8e01dca41002 1545 #endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */
donatien 0:8e01dca41002 1546
donatien 0:8e01dca41002 1547 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 1548
donatien 0:8e01dca41002 1549 void
donatien 0:8e01dca41002 1550 pppOverEthernetInitFailed(int pd)
donatien 0:8e01dca41002 1551 {
donatien 0:8e01dca41002 1552 PPPControl* pc;
donatien 0:8e01dca41002 1553
donatien 0:8e01dca41002 1554 pppHup(pd);
donatien 0:8e01dca41002 1555 pppStop(pd);
donatien 0:8e01dca41002 1556
donatien 0:8e01dca41002 1557 pc = &pppControl[pd];
donatien 0:8e01dca41002 1558 pppoe_destroy(&pc->netif);
donatien 0:8e01dca41002 1559 pc->openFlag = 0;
donatien 0:8e01dca41002 1560
donatien 0:8e01dca41002 1561 if(pc->linkStatusCB) {
donatien 0:8e01dca41002 1562 pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);
donatien 0:8e01dca41002 1563 }
donatien 0:8e01dca41002 1564 }
donatien 0:8e01dca41002 1565
donatien 0:8e01dca41002 1566 static void
donatien 0:8e01dca41002 1567 pppOverEthernetLinkStatusCB(int pd, int up)
donatien 0:8e01dca41002 1568 {
donatien 0:8e01dca41002 1569 if(up) {
donatien 0:8e01dca41002 1570 PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd));
donatien 0:8e01dca41002 1571 pppStart(pd);
donatien 0:8e01dca41002 1572 } else {
donatien 0:8e01dca41002 1573 pppOverEthernetInitFailed(pd);
donatien 0:8e01dca41002 1574 }
donatien 0:8e01dca41002 1575 }
donatien 0:8e01dca41002 1576 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 1577
donatien 0:8e01dca41002 1578 struct pbuf *
donatien 0:8e01dca41002 1579 pppSingleBuf(struct pbuf *p)
donatien 0:8e01dca41002 1580 {
donatien 0:8e01dca41002 1581 struct pbuf *q, *b;
donatien 0:8e01dca41002 1582 u_char *pl;
donatien 0:8e01dca41002 1583
donatien 0:8e01dca41002 1584 if(p->tot_len == p->len) {
donatien 0:8e01dca41002 1585 return p;
donatien 0:8e01dca41002 1586 }
donatien 0:8e01dca41002 1587
donatien 0:8e01dca41002 1588 q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
donatien 0:8e01dca41002 1589 if(!q) {
donatien 0:8e01dca41002 1590 PPPDEBUG(LOG_ERR,
donatien 0:8e01dca41002 1591 ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len));
donatien 0:8e01dca41002 1592 return p; /* live dangerously */
donatien 0:8e01dca41002 1593 }
donatien 0:8e01dca41002 1594
donatien 0:8e01dca41002 1595 for(b = p, pl = q->payload; b != NULL; b = b->next) {
donatien 0:8e01dca41002 1596 MEMCPY(pl, b->payload, b->len);
donatien 0:8e01dca41002 1597 pl += b->len;
donatien 0:8e01dca41002 1598 }
donatien 0:8e01dca41002 1599
donatien 0:8e01dca41002 1600 pbuf_free(p);
donatien 0:8e01dca41002 1601
donatien 0:8e01dca41002 1602 return q;
donatien 0:8e01dca41002 1603 }
donatien 0:8e01dca41002 1604
donatien 0:8e01dca41002 1605 struct pppInputHeader {
donatien 0:8e01dca41002 1606 int unit;
donatien 0:8e01dca41002 1607 u16_t proto;
donatien 0:8e01dca41002 1608 };
donatien 0:8e01dca41002 1609
donatien 0:8e01dca41002 1610 /*
donatien 0:8e01dca41002 1611 * Pass the processed input packet to the appropriate handler.
donatien 0:8e01dca41002 1612 * This function and all handlers run in the context of the tcpip_thread
donatien 0:8e01dca41002 1613 */
donatien 0:8e01dca41002 1614 static void
donatien 0:8e01dca41002 1615 pppInput(void *arg)
donatien 0:8e01dca41002 1616 {
donatien 0:8e01dca41002 1617 struct pbuf *nb = (struct pbuf *)arg;
donatien 0:8e01dca41002 1618 u16_t protocol;
donatien 0:8e01dca41002 1619 int pd;
donatien 0:8e01dca41002 1620
donatien 0:8e01dca41002 1621 pd = ((struct pppInputHeader *)nb->payload)->unit;
donatien 0:8e01dca41002 1622 protocol = ((struct pppInputHeader *)nb->payload)->proto;
donatien 0:8e01dca41002 1623
donatien 0:8e01dca41002 1624 if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) {
donatien 0:8e01dca41002 1625 LWIP_ASSERT("pbuf_header failed\n", 0);
donatien 0:8e01dca41002 1626 goto drop;
donatien 0:8e01dca41002 1627 }
donatien 0:8e01dca41002 1628
donatien 0:8e01dca41002 1629 LINK_STATS_INC(link.recv);
donatien 0:8e01dca41002 1630 snmp_inc_ifinucastpkts(&pppControl[pd].netif);
donatien 0:8e01dca41002 1631 snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len);
donatien 0:8e01dca41002 1632
donatien 0:8e01dca41002 1633 /*
donatien 0:8e01dca41002 1634 * Toss all non-LCP packets unless LCP is OPEN.
donatien 0:8e01dca41002 1635 * Until we get past the authentication phase, toss all packets
donatien 0:8e01dca41002 1636 * except LCP, LQR and authentication packets.
donatien 0:8e01dca41002 1637 */
donatien 0:8e01dca41002 1638 if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) {
donatien 0:8e01dca41002 1639 if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) ||
donatien 0:8e01dca41002 1640 (lcp_phase[pd] != PHASE_AUTHENTICATE)) {
donatien 0:8e01dca41002 1641 PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd]));
donatien 0:8e01dca41002 1642 goto drop;
donatien 0:8e01dca41002 1643 }
donatien 0:8e01dca41002 1644 }
donatien 0:8e01dca41002 1645
donatien 0:8e01dca41002 1646 switch(protocol) {
donatien 0:8e01dca41002 1647 case PPP_VJC_COMP: /* VJ compressed TCP */
donatien 0:8e01dca41002 1648 #if PPPOS_SUPPORT && VJ_SUPPORT
donatien 0:8e01dca41002 1649 PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len));
donatien 0:8e01dca41002 1650 /*
donatien 0:8e01dca41002 1651 * Clip off the VJ header and prepend the rebuilt TCP/IP header and
donatien 0:8e01dca41002 1652 * pass the result to IP.
donatien 0:8e01dca41002 1653 */
donatien 0:8e01dca41002 1654 if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) {
donatien 0:8e01dca41002 1655 pppControl[pd].netif.input(nb, &pppControl[pd].netif);
donatien 0:8e01dca41002 1656 return;
donatien 0:8e01dca41002 1657 }
donatien 0:8e01dca41002 1658 /* Something's wrong so drop it. */
donatien 0:8e01dca41002 1659 PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd));
donatien 0:8e01dca41002 1660 #else /* PPPOS_SUPPORT && VJ_SUPPORT */
donatien 0:8e01dca41002 1661 /* No handler for this protocol so drop the packet. */
donatien 0:8e01dca41002 1662 PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload));
donatien 0:8e01dca41002 1663 #endif /* PPPOS_SUPPORT && VJ_SUPPORT */
donatien 0:8e01dca41002 1664 break;
donatien 0:8e01dca41002 1665
donatien 0:8e01dca41002 1666 case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */
donatien 0:8e01dca41002 1667 #if PPPOS_SUPPORT && VJ_SUPPORT
donatien 0:8e01dca41002 1668 PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len));
donatien 0:8e01dca41002 1669 /*
donatien 0:8e01dca41002 1670 * Process the TCP/IP header for VJ header compression and then pass
donatien 0:8e01dca41002 1671 * the packet to IP.
donatien 0:8e01dca41002 1672 */
donatien 0:8e01dca41002 1673 if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) {
donatien 0:8e01dca41002 1674 pppControl[pd].netif.input(nb, &pppControl[pd].netif);
donatien 0:8e01dca41002 1675 return;
donatien 0:8e01dca41002 1676 }
donatien 0:8e01dca41002 1677 /* Something's wrong so drop it. */
donatien 0:8e01dca41002 1678 PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd));
donatien 0:8e01dca41002 1679 #else /* PPPOS_SUPPORT && VJ_SUPPORT */
donatien 0:8e01dca41002 1680 /* No handler for this protocol so drop the packet. */
donatien 0:8e01dca41002 1681 PPPDEBUG(LOG_INFO,
donatien 0:8e01dca41002 1682 ("pppInput[%d]: drop VJ UnComp in %d:.*H\n",
donatien 0:8e01dca41002 1683 pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload));
donatien 0:8e01dca41002 1684 #endif /* PPPOS_SUPPORT && VJ_SUPPORT */
donatien 0:8e01dca41002 1685 break;
donatien 0:8e01dca41002 1686
donatien 0:8e01dca41002 1687 case PPP_IP: /* Internet Protocol */
donatien 0:8e01dca41002 1688 PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len));
donatien 0:8e01dca41002 1689 if (pppControl[pd].netif.input) {
donatien 0:8e01dca41002 1690 pppControl[pd].netif.input(nb, &pppControl[pd].netif);
donatien 0:8e01dca41002 1691 return;
donatien 0:8e01dca41002 1692 }
donatien 0:8e01dca41002 1693 break;
donatien 0:8e01dca41002 1694
donatien 0:8e01dca41002 1695 default: {
donatien 0:8e01dca41002 1696 struct protent *protp;
donatien 0:8e01dca41002 1697 int i;
donatien 0:8e01dca41002 1698
donatien 0:8e01dca41002 1699 /*
donatien 0:8e01dca41002 1700 * Upcall the proper protocol input routine.
donatien 0:8e01dca41002 1701 */
donatien 0:8e01dca41002 1702 for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
donatien 0:8e01dca41002 1703 if (protp->protocol == protocol && protp->enabled_flag) {
donatien 0:8e01dca41002 1704 PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len));
donatien 0:8e01dca41002 1705 nb = pppSingleBuf(nb);
donatien 0:8e01dca41002 1706 (*protp->input)(pd, nb->payload, nb->len);
donatien 0:8e01dca41002 1707 PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd));
donatien 0:8e01dca41002 1708 goto out;
donatien 0:8e01dca41002 1709 }
donatien 0:8e01dca41002 1710 }
donatien 0:8e01dca41002 1711
donatien 0:8e01dca41002 1712 /* No handler for this protocol so reject the packet. */
donatien 0:8e01dca41002 1713 PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len));
donatien 0:8e01dca41002 1714 if (pbuf_header(nb, sizeof(protocol))) {
donatien 0:8e01dca41002 1715 LWIP_ASSERT("pbuf_header failed\n", 0);
donatien 0:8e01dca41002 1716 goto drop;
donatien 0:8e01dca41002 1717 }
donatien 0:8e01dca41002 1718 #if BYTE_ORDER == LITTLE_ENDIAN
donatien 0:8e01dca41002 1719 protocol = htons(protocol);
donatien 0:8e01dca41002 1720 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
donatien 0:8e01dca41002 1721 SMEMCPY(nb->payload, &protocol, sizeof(protocol));
donatien 0:8e01dca41002 1722 lcp_sprotrej(pd, nb->payload, nb->len);
donatien 0:8e01dca41002 1723 }
donatien 0:8e01dca41002 1724 break;
donatien 0:8e01dca41002 1725 }
donatien 0:8e01dca41002 1726
donatien 0:8e01dca41002 1727 drop:
donatien 0:8e01dca41002 1728 LINK_STATS_INC(link.drop);
donatien 0:8e01dca41002 1729 snmp_inc_ifindiscards(&pppControl[pd].netif);
donatien 0:8e01dca41002 1730
donatien 0:8e01dca41002 1731 out:
donatien 0:8e01dca41002 1732 pbuf_free(nb);
donatien 0:8e01dca41002 1733 return;
donatien 0:8e01dca41002 1734 }
donatien 0:8e01dca41002 1735
donatien 0:8e01dca41002 1736 #if PPPOS_SUPPORT
donatien 0:8e01dca41002 1737 /*
donatien 0:8e01dca41002 1738 * Drop the input packet.
donatien 0:8e01dca41002 1739 */
donatien 0:8e01dca41002 1740 static void
donatien 0:8e01dca41002 1741 pppDrop(PPPControlRx *pcrx)
donatien 0:8e01dca41002 1742 {
donatien 0:8e01dca41002 1743 if (pcrx->inHead != NULL) {
donatien 0:8e01dca41002 1744 #if 0
donatien 0:8e01dca41002 1745 PPPDEBUG(LOG_INFO, ("pppDrop: %d:%.*H\n", pcrx->inHead->len, min(60, pcrx->inHead->len * 2), pcrx->inHead->payload));
donatien 0:8e01dca41002 1746 #endif
donatien 0:8e01dca41002 1747 PPPDEBUG(LOG_INFO, ("pppDrop: pbuf len=%d, addr %p\n", pcrx->inHead->len, (void*)pcrx->inHead));
donatien 0:8e01dca41002 1748 if (pcrx->inTail && (pcrx->inTail != pcrx->inHead)) {
donatien 0:8e01dca41002 1749 pbuf_free(pcrx->inTail);
donatien 0:8e01dca41002 1750 }
donatien 0:8e01dca41002 1751 pbuf_free(pcrx->inHead);
donatien 0:8e01dca41002 1752 pcrx->inHead = NULL;
donatien 0:8e01dca41002 1753 pcrx->inTail = NULL;
donatien 0:8e01dca41002 1754 }
donatien 0:8e01dca41002 1755 #if VJ_SUPPORT
donatien 0:8e01dca41002 1756 vj_uncompress_err(&pppControl[pcrx->pd].vjComp);
donatien 0:8e01dca41002 1757 #endif /* VJ_SUPPORT */
donatien 0:8e01dca41002 1758
donatien 0:8e01dca41002 1759 LINK_STATS_INC(link.drop);
donatien 0:8e01dca41002 1760 snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif);
donatien 0:8e01dca41002 1761 }
donatien 0:8e01dca41002 1762
donatien 0:8e01dca41002 1763 /** Pass received raw characters to PPPoS to be decoded. This function is
donatien 0:8e01dca41002 1764 * thread-safe and can be called from a dedicated RX-thread or from a main-loop.
donatien 0:8e01dca41002 1765 *
donatien 0:8e01dca41002 1766 * @param pd PPP descriptor index, returned by pppOpen()
donatien 0:8e01dca41002 1767 * @param data received data
donatien 0:8e01dca41002 1768 * @param len length of received data
donatien 0:8e01dca41002 1769 */
donatien 0:8e01dca41002 1770 void
donatien 0:8e01dca41002 1771 pppos_input(int pd, u_char* data, int len)
donatien 0:8e01dca41002 1772 {
donatien 0:8e01dca41002 1773 pppInProc(&pppControl[pd].rx, data, len);
donatien 0:8e01dca41002 1774 }
donatien 0:8e01dca41002 1775
donatien 0:8e01dca41002 1776 /**
donatien 0:8e01dca41002 1777 * Process a received octet string.
donatien 0:8e01dca41002 1778 */
donatien 0:8e01dca41002 1779 static void
donatien 0:8e01dca41002 1780 pppInProc(PPPControlRx *pcrx, u_char *s, int l)
donatien 0:8e01dca41002 1781 {
donatien 0:8e01dca41002 1782 struct pbuf *nextNBuf;
donatien 0:8e01dca41002 1783 u_char curChar;
donatien 0:8e01dca41002 1784 u_char escaped;
donatien 0:8e01dca41002 1785 SYS_ARCH_DECL_PROTECT(lev);
donatien 0:8e01dca41002 1786
donatien 0:8e01dca41002 1787 PPPDEBUG(LOG_DEBUG, ("pppInProc[%d]: got %d bytes\n", pcrx->pd, l));
donatien 0:8e01dca41002 1788 while (l-- > 0) {
donatien 0:8e01dca41002 1789 curChar = *s++;
donatien 0:8e01dca41002 1790
donatien 0:8e01dca41002 1791 SYS_ARCH_PROTECT(lev);
donatien 0:8e01dca41002 1792 escaped = ESCAPE_P(pcrx->inACCM, curChar);
donatien 0:8e01dca41002 1793 SYS_ARCH_UNPROTECT(lev);
donatien 0:8e01dca41002 1794 /* Handle special characters. */
donatien 0:8e01dca41002 1795 if (escaped) {
donatien 0:8e01dca41002 1796 /* Check for escape sequences. */
donatien 0:8e01dca41002 1797 /* XXX Note that this does not handle an escaped 0x5d character which
donatien 0:8e01dca41002 1798 * would appear as an escape character. Since this is an ASCII ']'
donatien 0:8e01dca41002 1799 * and there is no reason that I know of to escape it, I won't complicate
donatien 0:8e01dca41002 1800 * the code to handle this case. GLL */
donatien 0:8e01dca41002 1801 if (curChar == PPP_ESCAPE) {
donatien 0:8e01dca41002 1802 pcrx->inEscaped = 1;
donatien 0:8e01dca41002 1803 /* Check for the flag character. */
donatien 0:8e01dca41002 1804 } else if (curChar == PPP_FLAG) {
donatien 0:8e01dca41002 1805 /* If this is just an extra flag character, ignore it. */
donatien 0:8e01dca41002 1806 if (pcrx->inState <= PDADDRESS) {
donatien 0:8e01dca41002 1807 /* ignore it */;
donatien 0:8e01dca41002 1808 /* If we haven't received the packet header, drop what has come in. */
donatien 0:8e01dca41002 1809 } else if (pcrx->inState < PDDATA) {
donatien 0:8e01dca41002 1810 PPPDEBUG(LOG_WARNING,
donatien 0:8e01dca41002 1811 ("pppInProc[%d]: Dropping incomplete packet %d\n",
donatien 0:8e01dca41002 1812 pcrx->pd, pcrx->inState));
donatien 0:8e01dca41002 1813 LINK_STATS_INC(link.lenerr);
donatien 0:8e01dca41002 1814 pppDrop(pcrx);
donatien 0:8e01dca41002 1815 /* If the fcs is invalid, drop the packet. */
donatien 0:8e01dca41002 1816 } else if (pcrx->inFCS != PPP_GOODFCS) {
donatien 0:8e01dca41002 1817 PPPDEBUG(LOG_INFO,
donatien 0:8e01dca41002 1818 ("pppInProc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n",
donatien 0:8e01dca41002 1819 pcrx->pd, pcrx->inFCS, pcrx->inProtocol));
donatien 0:8e01dca41002 1820 /* Note: If you get lots of these, check for UART frame errors or try different baud rate */
donatien 0:8e01dca41002 1821 LINK_STATS_INC(link.chkerr);
donatien 0:8e01dca41002 1822 pppDrop(pcrx);
donatien 0:8e01dca41002 1823 /* Otherwise it's a good packet so pass it on. */
donatien 0:8e01dca41002 1824 } else {
donatien 0:8e01dca41002 1825 struct pbuf *inp;
donatien 0:8e01dca41002 1826 /* Trim off the checksum. */
donatien 0:8e01dca41002 1827 if(pcrx->inTail->len >= 2) {
donatien 0:8e01dca41002 1828 pcrx->inTail->len -= 2;
donatien 0:8e01dca41002 1829
donatien 0:8e01dca41002 1830 pcrx->inTail->tot_len = pcrx->inTail->len;
donatien 0:8e01dca41002 1831 if (pcrx->inTail != pcrx->inHead) {
donatien 0:8e01dca41002 1832 pbuf_cat(pcrx->inHead, pcrx->inTail);
donatien 0:8e01dca41002 1833 }
donatien 0:8e01dca41002 1834 } else {
donatien 0:8e01dca41002 1835 pcrx->inTail->tot_len = pcrx->inTail->len;
donatien 0:8e01dca41002 1836 if (pcrx->inTail != pcrx->inHead) {
donatien 0:8e01dca41002 1837 pbuf_cat(pcrx->inHead, pcrx->inTail);
donatien 0:8e01dca41002 1838 }
donatien 0:8e01dca41002 1839
donatien 0:8e01dca41002 1840 pbuf_realloc(pcrx->inHead, pcrx->inHead->tot_len - 2);
donatien 0:8e01dca41002 1841 }
donatien 0:8e01dca41002 1842
donatien 0:8e01dca41002 1843 /* Dispatch the packet thereby consuming it. */
donatien 0:8e01dca41002 1844 inp = pcrx->inHead;
donatien 0:8e01dca41002 1845 /* Packet consumed, release our references. */
donatien 0:8e01dca41002 1846 pcrx->inHead = NULL;
donatien 0:8e01dca41002 1847 pcrx->inTail = NULL;
donatien 0:8e01dca41002 1848 #if PPP_INPROC_MULTITHREADED
donatien 0:8e01dca41002 1849 if(tcpip_callback_with_block(pppInput, inp, 0) != ERR_OK) {
donatien 0:8e01dca41002 1850 PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd));
donatien 0:8e01dca41002 1851 pbuf_free(inp);
donatien 0:8e01dca41002 1852 LINK_STATS_INC(link.drop);
donatien 0:8e01dca41002 1853 snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif);
donatien 0:8e01dca41002 1854 }
donatien 0:8e01dca41002 1855 #else /* PPP_INPROC_MULTITHREADED */
donatien 0:8e01dca41002 1856 pppInput(inp);
donatien 0:8e01dca41002 1857 #endif /* PPP_INPROC_MULTITHREADED */
donatien 0:8e01dca41002 1858 }
donatien 0:8e01dca41002 1859
donatien 0:8e01dca41002 1860 /* Prepare for a new packet. */
donatien 0:8e01dca41002 1861 pcrx->inFCS = PPP_INITFCS;
donatien 0:8e01dca41002 1862 pcrx->inState = PDADDRESS;
donatien 0:8e01dca41002 1863 pcrx->inEscaped = 0;
donatien 0:8e01dca41002 1864 /* Other characters are usually control characters that may have
donatien 0:8e01dca41002 1865 * been inserted by the physical layer so here we just drop them. */
donatien 0:8e01dca41002 1866 } else {
donatien 0:8e01dca41002 1867 PPPDEBUG(LOG_WARNING,
donatien 0:8e01dca41002 1868 ("pppInProc[%d]: Dropping ACCM char <%d>\n", pcrx->pd, curChar));
donatien 0:8e01dca41002 1869 }
donatien 0:8e01dca41002 1870 /* Process other characters. */
donatien 0:8e01dca41002 1871 } else {
donatien 0:8e01dca41002 1872 /* Unencode escaped characters. */
donatien 0:8e01dca41002 1873 if (pcrx->inEscaped) {
donatien 0:8e01dca41002 1874 pcrx->inEscaped = 0;
donatien 0:8e01dca41002 1875 curChar ^= PPP_TRANS;
donatien 0:8e01dca41002 1876 }
donatien 0:8e01dca41002 1877
donatien 0:8e01dca41002 1878 /* Process character relative to current state. */
donatien 0:8e01dca41002 1879 switch(pcrx->inState) {
donatien 0:8e01dca41002 1880 case PDIDLE: /* Idle state - waiting. */
donatien 0:8e01dca41002 1881 /* Drop the character if it's not 0xff
donatien 0:8e01dca41002 1882 * we would have processed a flag character above. */
donatien 0:8e01dca41002 1883 if (curChar != PPP_ALLSTATIONS) {
donatien 0:8e01dca41002 1884 break;
donatien 0:8e01dca41002 1885 }
donatien 0:8e01dca41002 1886
donatien 0:8e01dca41002 1887 /* Fall through */
donatien 0:8e01dca41002 1888 case PDSTART: /* Process start flag. */
donatien 0:8e01dca41002 1889 /* Prepare for a new packet. */
donatien 0:8e01dca41002 1890 pcrx->inFCS = PPP_INITFCS;
donatien 0:8e01dca41002 1891
donatien 0:8e01dca41002 1892 /* Fall through */
donatien 0:8e01dca41002 1893 case PDADDRESS: /* Process address field. */
donatien 0:8e01dca41002 1894 if (curChar == PPP_ALLSTATIONS) {
donatien 0:8e01dca41002 1895 pcrx->inState = PDCONTROL;
donatien 0:8e01dca41002 1896 break;
donatien 0:8e01dca41002 1897 }
donatien 0:8e01dca41002 1898 /* Else assume compressed address and control fields so
donatien 0:8e01dca41002 1899 * fall through to get the protocol... */
donatien 0:8e01dca41002 1900 case PDCONTROL: /* Process control field. */
donatien 0:8e01dca41002 1901 /* If we don't get a valid control code, restart. */
donatien 0:8e01dca41002 1902 if (curChar == PPP_UI) {
donatien 0:8e01dca41002 1903 pcrx->inState = PDPROTOCOL1;
donatien 0:8e01dca41002 1904 break;
donatien 0:8e01dca41002 1905 }
donatien 0:8e01dca41002 1906 #if 0
donatien 0:8e01dca41002 1907 else {
donatien 0:8e01dca41002 1908 PPPDEBUG(LOG_WARNING,
donatien 0:8e01dca41002 1909 ("pppInProc[%d]: Invalid control <%d>\n", pcrx->pd, curChar));
donatien 0:8e01dca41002 1910 pcrx->inState = PDSTART;
donatien 0:8e01dca41002 1911 }
donatien 0:8e01dca41002 1912 #endif
donatien 0:8e01dca41002 1913 case PDPROTOCOL1: /* Process protocol field 1. */
donatien 0:8e01dca41002 1914 /* If the lower bit is set, this is the end of the protocol
donatien 0:8e01dca41002 1915 * field. */
donatien 0:8e01dca41002 1916 if (curChar & 1) {
donatien 0:8e01dca41002 1917 pcrx->inProtocol = curChar;
donatien 0:8e01dca41002 1918 pcrx->inState = PDDATA;
donatien 0:8e01dca41002 1919 } else {
donatien 0:8e01dca41002 1920 pcrx->inProtocol = (u_int)curChar << 8;
donatien 0:8e01dca41002 1921 pcrx->inState = PDPROTOCOL2;
donatien 0:8e01dca41002 1922 }
donatien 0:8e01dca41002 1923 break;
donatien 0:8e01dca41002 1924 case PDPROTOCOL2: /* Process protocol field 2. */
donatien 0:8e01dca41002 1925 pcrx->inProtocol |= curChar;
donatien 0:8e01dca41002 1926 pcrx->inState = PDDATA;
donatien 0:8e01dca41002 1927 break;
donatien 0:8e01dca41002 1928 case PDDATA: /* Process data byte. */
donatien 0:8e01dca41002 1929 /* Make space to receive processed data. */
donatien 0:8e01dca41002 1930 if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) {
donatien 0:8e01dca41002 1931 if (pcrx->inTail != NULL) {
donatien 0:8e01dca41002 1932 pcrx->inTail->tot_len = pcrx->inTail->len;
donatien 0:8e01dca41002 1933 if (pcrx->inTail != pcrx->inHead) {
donatien 0:8e01dca41002 1934 pbuf_cat(pcrx->inHead, pcrx->inTail);
donatien 0:8e01dca41002 1935 /* give up the inTail reference now */
donatien 0:8e01dca41002 1936 pcrx->inTail = NULL;
donatien 0:8e01dca41002 1937 }
donatien 0:8e01dca41002 1938 }
donatien 0:8e01dca41002 1939 /* If we haven't started a packet, we need a packet header. */
donatien 0:8e01dca41002 1940 nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
donatien 0:8e01dca41002 1941 if (nextNBuf == NULL) {
donatien 0:8e01dca41002 1942 /* No free buffers. Drop the input packet and let the
donatien 0:8e01dca41002 1943 * higher layers deal with it. Continue processing
donatien 0:8e01dca41002 1944 * the received pbuf chain in case a new packet starts. */
donatien 0:8e01dca41002 1945 PPPDEBUG(LOG_ERR, ("pppInProc[%d]: NO FREE MBUFS!\n", pcrx->pd));
donatien 0:8e01dca41002 1946 LINK_STATS_INC(link.memerr);
donatien 0:8e01dca41002 1947 pppDrop(pcrx);
donatien 0:8e01dca41002 1948 pcrx->inState = PDSTART; /* Wait for flag sequence. */
donatien 0:8e01dca41002 1949 break;
donatien 0:8e01dca41002 1950 }
donatien 0:8e01dca41002 1951 if (pcrx->inHead == NULL) {
donatien 0:8e01dca41002 1952 struct pppInputHeader *pih = nextNBuf->payload;
donatien 0:8e01dca41002 1953
donatien 0:8e01dca41002 1954 pih->unit = pcrx->pd;
donatien 0:8e01dca41002 1955 pih->proto = pcrx->inProtocol;
donatien 0:8e01dca41002 1956
donatien 0:8e01dca41002 1957 nextNBuf->len += sizeof(*pih);
donatien 0:8e01dca41002 1958
donatien 0:8e01dca41002 1959 pcrx->inHead = nextNBuf;
donatien 0:8e01dca41002 1960 }
donatien 0:8e01dca41002 1961 pcrx->inTail = nextNBuf;
donatien 0:8e01dca41002 1962 }
donatien 0:8e01dca41002 1963 /* Load character into buffer. */
donatien 0:8e01dca41002 1964 ((u_char*)pcrx->inTail->payload)[pcrx->inTail->len++] = curChar;
donatien 0:8e01dca41002 1965 break;
donatien 0:8e01dca41002 1966 }
donatien 0:8e01dca41002 1967
donatien 0:8e01dca41002 1968 /* update the frame check sequence number. */
donatien 0:8e01dca41002 1969 pcrx->inFCS = PPP_FCS(pcrx->inFCS, curChar);
donatien 0:8e01dca41002 1970 }
donatien 0:8e01dca41002 1971 } /* while (l-- > 0), all bytes processed */
donatien 0:8e01dca41002 1972
donatien 0:8e01dca41002 1973 avRandomize();
donatien 0:8e01dca41002 1974 }
donatien 0:8e01dca41002 1975 #endif /* PPPOS_SUPPORT */
donatien 0:8e01dca41002 1976
donatien 0:8e01dca41002 1977 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 1978 void
donatien 0:8e01dca41002 1979 pppInProcOverEthernet(int pd, struct pbuf *pb)
donatien 0:8e01dca41002 1980 {
donatien 0:8e01dca41002 1981 struct pppInputHeader *pih;
donatien 0:8e01dca41002 1982 u16_t inProtocol;
donatien 0:8e01dca41002 1983
donatien 0:8e01dca41002 1984 if(pb->len < sizeof(inProtocol)) {
donatien 0:8e01dca41002 1985 PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: too small for protocol field\n"));
donatien 0:8e01dca41002 1986 goto drop;
donatien 0:8e01dca41002 1987 }
donatien 0:8e01dca41002 1988
donatien 0:8e01dca41002 1989 inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1];
donatien 0:8e01dca41002 1990
donatien 0:8e01dca41002 1991 /* make room for pppInputHeader - should not fail */
donatien 0:8e01dca41002 1992 if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) {
donatien 0:8e01dca41002 1993 PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: could not allocate room for header\n"));
donatien 0:8e01dca41002 1994 goto drop;
donatien 0:8e01dca41002 1995 }
donatien 0:8e01dca41002 1996
donatien 0:8e01dca41002 1997 pih = pb->payload;
donatien 0:8e01dca41002 1998
donatien 0:8e01dca41002 1999 pih->unit = pd;
donatien 0:8e01dca41002 2000 pih->proto = inProtocol;
donatien 0:8e01dca41002 2001
donatien 0:8e01dca41002 2002 /* Dispatch the packet thereby consuming it. */
donatien 0:8e01dca41002 2003 pppInput(pb);
donatien 0:8e01dca41002 2004 return;
donatien 0:8e01dca41002 2005
donatien 0:8e01dca41002 2006 drop:
donatien 0:8e01dca41002 2007 LINK_STATS_INC(link.drop);
donatien 0:8e01dca41002 2008 snmp_inc_ifindiscards(&pppControl[pd].netif);
donatien 0:8e01dca41002 2009 pbuf_free(pb);
donatien 0:8e01dca41002 2010 return;
donatien 0:8e01dca41002 2011 }
donatien 0:8e01dca41002 2012 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 2013
donatien 0:8e01dca41002 2014 #if LWIP_NETIF_STATUS_CALLBACK
donatien 0:8e01dca41002 2015 /** Set the status callback of a PPP's netif
donatien 0:8e01dca41002 2016 *
donatien 0:8e01dca41002 2017 * @param pd The PPP descriptor returned by pppOpen()
donatien 0:8e01dca41002 2018 * @param status_callback pointer to the status callback function
donatien 0:8e01dca41002 2019 *
donatien 0:8e01dca41002 2020 * @see netif_set_status_callback
donatien 0:8e01dca41002 2021 */
donatien 0:8e01dca41002 2022 void
donatien 0:8e01dca41002 2023 ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback)
donatien 0:8e01dca41002 2024 {
donatien 0:8e01dca41002 2025 netif_set_status_callback(&pppControl[pd].netif, status_callback);
donatien 0:8e01dca41002 2026 }
donatien 0:8e01dca41002 2027 #endif /* LWIP_NETIF_STATUS_CALLBACK */
donatien 0:8e01dca41002 2028
donatien 0:8e01dca41002 2029 #if LWIP_NETIF_LINK_CALLBACK
donatien 0:8e01dca41002 2030 /** Set the link callback of a PPP's netif
donatien 0:8e01dca41002 2031 *
donatien 0:8e01dca41002 2032 * @param pd The PPP descriptor returned by pppOpen()
donatien 0:8e01dca41002 2033 * @param link_callback pointer to the link callback function
donatien 0:8e01dca41002 2034 *
donatien 0:8e01dca41002 2035 * @see netif_set_link_callback
donatien 0:8e01dca41002 2036 */
donatien 0:8e01dca41002 2037 void
donatien 0:8e01dca41002 2038 ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback)
donatien 0:8e01dca41002 2039 {
donatien 0:8e01dca41002 2040 netif_set_link_callback(&pppControl[pd].netif, link_callback);
donatien 0:8e01dca41002 2041 }
donatien 0:8e01dca41002 2042 #endif /* LWIP_NETIF_LINK_CALLBACK */
donatien 0:8e01dca41002 2043
donatien 0:8e01dca41002 2044 #endif /* PPP_SUPPORT */