Used in Live Traffic Update Nokia LCD Display Project

Fork of NetServices by Segundo Equipo

Committer:
rrajan8
Date:
Wed Mar 06 19:07:23 2013 +0000
Revision:
8:92b57208ab99
Parent:
0:ac1725ba162c
This project utilizes mbed's networking features to display live traffic updates on the Nokia LCD using the MapQuest API's Traffic Web Service.

Who changed what in which revision?

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