Port to C027 (using AppShield and Ethernet)

Dependencies:   C12832 EthernetInterface LM75B MMA7660 MQTT mbed-rtos mbed

Fork of IBMIoTClientEthernetExample by IBM Watson IoT

Committer:
samdanbury
Date:
Wed Aug 20 12:45:14 2014 +0000
Revision:
6:37b6d0d56190
Code completely changed to improve the structure, flow and memory usage of the application

Who changed what in which revision?

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