Jonathan Caes / InetTest-8d87bc453349

Dependencies:   DS1307 TextLCD mbed

Committer:
JonathanCaes
Date:
Mon Dec 29 13:37:45 2014 +0000
Revision:
2:63849bb30db0
Parent:
0:a16f60a71395
Project

Who changed what in which revision?

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