Forked from the DieterGraef Library

Fork of F7_Ethernet by Dieter Graef

Committer:
DieterGraef
Date:
Sun Jun 19 16:23:40 2016 +0000
Revision:
0:d26c1b55cfca
Ethernet Library for Nucleo stm32f746ZG and Disco stm32f746NG  works under arm and gcc environment

Who changed what in which revision?

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