Official mbed lwIP library (version 1.4.0)

Dependents:   LwIPNetworking NetServicesMin EthernetInterface EthernetInterface_RSF ... more

Legacy Networking Libraries

This is an mbed 2 networking library. For mbed OS 5, lwip has been integrated with built-in networking interfaces. The networking libraries have been revised to better support additional network stacks and thread safety here.

This library is based on the code of lwIP v1.4.0

Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
All rights reserved. 

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
Committer:
donatien
Date:
Fri Jun 22 15:08:59 2012 +0000
Revision:
4:f71f5d9d5846
Parent:
0:51ac1d130fd4
Put PPP Buffers in AHBSRAM1; pppOverSerialOpen() thread leak removed; Does not fail if remote end does not advertise its IP address

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:51ac1d130fd4 1 /** In contrast to pppd 2.3.1, DNS support has been added, proxy-ARP and
mbed_official 0:51ac1d130fd4 2 dial-on-demand has been stripped. */
mbed_official 0:51ac1d130fd4 3 /*****************************************************************************
mbed_official 0:51ac1d130fd4 4 * ipcp.c - Network PPP IP Control Protocol program file.
mbed_official 0:51ac1d130fd4 5 *
mbed_official 0:51ac1d130fd4 6 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
mbed_official 0:51ac1d130fd4 7 * portions Copyright (c) 1997 by Global Election Systems Inc.
mbed_official 0:51ac1d130fd4 8 *
mbed_official 0:51ac1d130fd4 9 * The authors hereby grant permission to use, copy, modify, distribute,
mbed_official 0:51ac1d130fd4 10 * and license this software and its documentation for any purpose, provided
mbed_official 0:51ac1d130fd4 11 * that existing copyright notices are retained in all copies and that this
mbed_official 0:51ac1d130fd4 12 * notice and the following disclaimer are included verbatim in any
mbed_official 0:51ac1d130fd4 13 * distributions. No written agreement, license, or royalty fee is required
mbed_official 0:51ac1d130fd4 14 * for any of the authorized uses.
mbed_official 0:51ac1d130fd4 15 *
mbed_official 0:51ac1d130fd4 16 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
mbed_official 0:51ac1d130fd4 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
mbed_official 0:51ac1d130fd4 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
mbed_official 0:51ac1d130fd4 19 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
mbed_official 0:51ac1d130fd4 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
mbed_official 0:51ac1d130fd4 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
mbed_official 0:51ac1d130fd4 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
mbed_official 0:51ac1d130fd4 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
mbed_official 0:51ac1d130fd4 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
mbed_official 0:51ac1d130fd4 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
mbed_official 0:51ac1d130fd4 26 *
mbed_official 0:51ac1d130fd4 27 ******************************************************************************
mbed_official 0:51ac1d130fd4 28 * REVISION HISTORY
mbed_official 0:51ac1d130fd4 29 *
mbed_official 0:51ac1d130fd4 30 * 03-01-01 Marc Boucher <marc@mbsi.ca>
mbed_official 0:51ac1d130fd4 31 * Ported to lwIP.
mbed_official 0:51ac1d130fd4 32 * 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
mbed_official 0:51ac1d130fd4 33 * Original.
mbed_official 0:51ac1d130fd4 34 *****************************************************************************/
mbed_official 0:51ac1d130fd4 35 /*
mbed_official 0:51ac1d130fd4 36 * ipcp.c - PPP IP Control Protocol.
mbed_official 0:51ac1d130fd4 37 *
mbed_official 0:51ac1d130fd4 38 * Copyright (c) 1989 Carnegie Mellon University.
mbed_official 0:51ac1d130fd4 39 * All rights reserved.
mbed_official 0:51ac1d130fd4 40 *
mbed_official 0:51ac1d130fd4 41 * Redistribution and use in source and binary forms are permitted
mbed_official 0:51ac1d130fd4 42 * provided that the above copyright notice and this paragraph are
mbed_official 0:51ac1d130fd4 43 * duplicated in all such forms and that any documentation,
mbed_official 0:51ac1d130fd4 44 * advertising materials, and other materials related to such
mbed_official 0:51ac1d130fd4 45 * distribution and use acknowledge that the software was developed
mbed_official 0:51ac1d130fd4 46 * by Carnegie Mellon University. The name of the
mbed_official 0:51ac1d130fd4 47 * University may not be used to endorse or promote products derived
mbed_official 0:51ac1d130fd4 48 * from this software without specific prior written permission.
mbed_official 0:51ac1d130fd4 49 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
mbed_official 0:51ac1d130fd4 50 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
mbed_official 0:51ac1d130fd4 51 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
mbed_official 0:51ac1d130fd4 52 */
mbed_official 0:51ac1d130fd4 53
mbed_official 0:51ac1d130fd4 54 #include "lwip/opt.h"
mbed_official 0:51ac1d130fd4 55
mbed_official 0:51ac1d130fd4 56 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
mbed_official 0:51ac1d130fd4 57
mbed_official 0:51ac1d130fd4 58 #include "ppp.h"
mbed_official 0:51ac1d130fd4 59 #include "pppdebug.h"
mbed_official 0:51ac1d130fd4 60
mbed_official 0:51ac1d130fd4 61 #include "auth.h"
mbed_official 0:51ac1d130fd4 62 #include "fsm.h"
mbed_official 0:51ac1d130fd4 63 #include "vj.h"
mbed_official 0:51ac1d130fd4 64 #include "ipcp.h"
mbed_official 0:51ac1d130fd4 65
mbed_official 0:51ac1d130fd4 66 #include "lwip/inet.h"
mbed_official 0:51ac1d130fd4 67
mbed_official 0:51ac1d130fd4 68 #include <string.h>
mbed_official 0:51ac1d130fd4 69
mbed_official 0:51ac1d130fd4 70 /* #define OLD_CI_ADDRS 1 */ /* Support deprecated address negotiation. */
mbed_official 0:51ac1d130fd4 71
mbed_official 0:51ac1d130fd4 72 /* global vars */
mbed_official 0:51ac1d130fd4 73 ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
mbed_official 0:51ac1d130fd4 74 ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
mbed_official 0:51ac1d130fd4 75 ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
mbed_official 0:51ac1d130fd4 76 ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
mbed_official 0:51ac1d130fd4 77
mbed_official 0:51ac1d130fd4 78 /* local vars */
mbed_official 0:51ac1d130fd4 79 static int default_route_set[NUM_PPP]; /* Have set up a default route */
mbed_official 0:51ac1d130fd4 80 static int cis_received[NUM_PPP]; /* # Conf-Reqs received */
mbed_official 0:51ac1d130fd4 81
mbed_official 0:51ac1d130fd4 82
mbed_official 0:51ac1d130fd4 83 /*
mbed_official 0:51ac1d130fd4 84 * Callbacks for fsm code. (CI = Configuration Information)
mbed_official 0:51ac1d130fd4 85 */
mbed_official 0:51ac1d130fd4 86 static void ipcp_resetci (fsm *); /* Reset our CI */
mbed_official 0:51ac1d130fd4 87 static int ipcp_cilen (fsm *); /* Return length of our CI */
mbed_official 0:51ac1d130fd4 88 static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */
mbed_official 0:51ac1d130fd4 89 static int ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */
mbed_official 0:51ac1d130fd4 90 static int ipcp_nakci (fsm *, u_char *, int); /* Peer nak'd our CI */
mbed_official 0:51ac1d130fd4 91 static int ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */
mbed_official 0:51ac1d130fd4 92 static int ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */
mbed_official 0:51ac1d130fd4 93 static void ipcp_up (fsm *); /* We're UP */
mbed_official 0:51ac1d130fd4 94 static void ipcp_down (fsm *); /* We're DOWN */
mbed_official 0:51ac1d130fd4 95 #if PPP_ADDITIONAL_CALLBACKS
mbed_official 0:51ac1d130fd4 96 static void ipcp_script (fsm *, char *); /* Run an up/down script */
mbed_official 0:51ac1d130fd4 97 #endif
mbed_official 0:51ac1d130fd4 98 static void ipcp_finished (fsm *); /* Don't need lower layer */
mbed_official 0:51ac1d130fd4 99
mbed_official 0:51ac1d130fd4 100
mbed_official 0:51ac1d130fd4 101 fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
mbed_official 0:51ac1d130fd4 102
mbed_official 0:51ac1d130fd4 103
mbed_official 0:51ac1d130fd4 104 static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
mbed_official 0:51ac1d130fd4 105 ipcp_resetci, /* Reset our Configuration Information */
mbed_official 0:51ac1d130fd4 106 ipcp_cilen, /* Length of our Configuration Information */
mbed_official 0:51ac1d130fd4 107 ipcp_addci, /* Add our Configuration Information */
mbed_official 0:51ac1d130fd4 108 ipcp_ackci, /* ACK our Configuration Information */
mbed_official 0:51ac1d130fd4 109 ipcp_nakci, /* NAK our Configuration Information */
mbed_official 0:51ac1d130fd4 110 ipcp_rejci, /* Reject our Configuration Information */
mbed_official 0:51ac1d130fd4 111 ipcp_reqci, /* Request peer's Configuration Information */
mbed_official 0:51ac1d130fd4 112 ipcp_up, /* Called when fsm reaches LS_OPENED state */
mbed_official 0:51ac1d130fd4 113 ipcp_down, /* Called when fsm leaves LS_OPENED state */
mbed_official 0:51ac1d130fd4 114 NULL, /* Called when we want the lower layer up */
mbed_official 0:51ac1d130fd4 115 ipcp_finished, /* Called when we want the lower layer down */
mbed_official 0:51ac1d130fd4 116 NULL, /* Called when Protocol-Reject received */
mbed_official 0:51ac1d130fd4 117 NULL, /* Retransmission is necessary */
mbed_official 0:51ac1d130fd4 118 NULL, /* Called to handle protocol-specific codes */
mbed_official 0:51ac1d130fd4 119 "IPCP" /* String name of protocol */
mbed_official 0:51ac1d130fd4 120 };
mbed_official 0:51ac1d130fd4 121
mbed_official 0:51ac1d130fd4 122 /*
mbed_official 0:51ac1d130fd4 123 * Protocol entry points from main code.
mbed_official 0:51ac1d130fd4 124 */
mbed_official 0:51ac1d130fd4 125 static void ipcp_init (int);
mbed_official 0:51ac1d130fd4 126 static void ipcp_open (int);
mbed_official 0:51ac1d130fd4 127 static void ipcp_close (int, char *);
mbed_official 0:51ac1d130fd4 128 static void ipcp_lowerup (int);
mbed_official 0:51ac1d130fd4 129 static void ipcp_lowerdown (int);
mbed_official 0:51ac1d130fd4 130 static void ipcp_input (int, u_char *, int);
mbed_official 0:51ac1d130fd4 131 static void ipcp_protrej (int);
mbed_official 0:51ac1d130fd4 132
mbed_official 0:51ac1d130fd4 133
mbed_official 0:51ac1d130fd4 134 struct protent ipcp_protent = {
mbed_official 0:51ac1d130fd4 135 PPP_IPCP,
mbed_official 0:51ac1d130fd4 136 ipcp_init,
mbed_official 0:51ac1d130fd4 137 ipcp_input,
mbed_official 0:51ac1d130fd4 138 ipcp_protrej,
mbed_official 0:51ac1d130fd4 139 ipcp_lowerup,
mbed_official 0:51ac1d130fd4 140 ipcp_lowerdown,
mbed_official 0:51ac1d130fd4 141 ipcp_open,
mbed_official 0:51ac1d130fd4 142 ipcp_close,
mbed_official 0:51ac1d130fd4 143 #if PPP_ADDITIONAL_CALLBACKS
mbed_official 0:51ac1d130fd4 144 ipcp_printpkt,
mbed_official 0:51ac1d130fd4 145 NULL,
mbed_official 0:51ac1d130fd4 146 #endif /* PPP_ADDITIONAL_CALLBACKS */
mbed_official 0:51ac1d130fd4 147 1,
mbed_official 0:51ac1d130fd4 148 "IPCP",
mbed_official 0:51ac1d130fd4 149 #if PPP_ADDITIONAL_CALLBACKS
mbed_official 0:51ac1d130fd4 150 ip_check_options,
mbed_official 0:51ac1d130fd4 151 NULL,
mbed_official 0:51ac1d130fd4 152 ip_active_pkt
mbed_official 0:51ac1d130fd4 153 #endif /* PPP_ADDITIONAL_CALLBACKS */
mbed_official 0:51ac1d130fd4 154 };
mbed_official 0:51ac1d130fd4 155
mbed_official 0:51ac1d130fd4 156 static void ipcp_clear_addrs (int);
mbed_official 0:51ac1d130fd4 157
mbed_official 0:51ac1d130fd4 158 /*
mbed_official 0:51ac1d130fd4 159 * Lengths of configuration options.
mbed_official 0:51ac1d130fd4 160 */
mbed_official 0:51ac1d130fd4 161 #define CILEN_VOID 2
mbed_official 0:51ac1d130fd4 162 #define CILEN_COMPRESS 4 /* min length for compression protocol opt. */
mbed_official 0:51ac1d130fd4 163 #define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */
mbed_official 0:51ac1d130fd4 164 #define CILEN_ADDR 6 /* new-style single address option */
mbed_official 0:51ac1d130fd4 165 #define CILEN_ADDRS 10 /* old-style dual address option */
mbed_official 0:51ac1d130fd4 166
mbed_official 0:51ac1d130fd4 167
mbed_official 0:51ac1d130fd4 168 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \
mbed_official 0:51ac1d130fd4 169 (x) == CONFNAK ? "NAK" : "REJ")
mbed_official 0:51ac1d130fd4 170
mbed_official 0:51ac1d130fd4 171
mbed_official 0:51ac1d130fd4 172 /*
mbed_official 0:51ac1d130fd4 173 * ipcp_init - Initialize IPCP.
mbed_official 0:51ac1d130fd4 174 */
mbed_official 0:51ac1d130fd4 175 static void
mbed_official 0:51ac1d130fd4 176 ipcp_init(int unit)
mbed_official 0:51ac1d130fd4 177 {
mbed_official 0:51ac1d130fd4 178 fsm *f = &ipcp_fsm[unit];
mbed_official 0:51ac1d130fd4 179 ipcp_options *wo = &ipcp_wantoptions[unit];
mbed_official 0:51ac1d130fd4 180 ipcp_options *ao = &ipcp_allowoptions[unit];
mbed_official 0:51ac1d130fd4 181
mbed_official 0:51ac1d130fd4 182 f->unit = unit;
mbed_official 0:51ac1d130fd4 183 f->protocol = PPP_IPCP;
mbed_official 0:51ac1d130fd4 184 f->callbacks = &ipcp_callbacks;
mbed_official 0:51ac1d130fd4 185 fsm_init(&ipcp_fsm[unit]);
mbed_official 0:51ac1d130fd4 186
mbed_official 0:51ac1d130fd4 187 memset(wo, 0, sizeof(*wo));
mbed_official 0:51ac1d130fd4 188 memset(ao, 0, sizeof(*ao));
mbed_official 0:51ac1d130fd4 189
mbed_official 0:51ac1d130fd4 190 wo->neg_addr = 1;
mbed_official 0:51ac1d130fd4 191 wo->ouraddr = 0;
mbed_official 0:51ac1d130fd4 192 #if VJ_SUPPORT
mbed_official 0:51ac1d130fd4 193 wo->neg_vj = 1;
mbed_official 0:51ac1d130fd4 194 #else /* VJ_SUPPORT */
mbed_official 0:51ac1d130fd4 195 wo->neg_vj = 0;
mbed_official 0:51ac1d130fd4 196 #endif /* VJ_SUPPORT */
mbed_official 0:51ac1d130fd4 197 wo->vj_protocol = IPCP_VJ_COMP;
mbed_official 0:51ac1d130fd4 198 wo->maxslotindex = MAX_SLOTS - 1;
mbed_official 0:51ac1d130fd4 199 wo->cflag = 0;
mbed_official 0:51ac1d130fd4 200 wo->default_route = 1;
mbed_official 0:51ac1d130fd4 201
mbed_official 0:51ac1d130fd4 202 ao->neg_addr = 1;
mbed_official 0:51ac1d130fd4 203 #if VJ_SUPPORT
mbed_official 0:51ac1d130fd4 204 ao->neg_vj = 1;
mbed_official 0:51ac1d130fd4 205 #else /* VJ_SUPPORT */
mbed_official 0:51ac1d130fd4 206 ao->neg_vj = 0;
mbed_official 0:51ac1d130fd4 207 #endif /* VJ_SUPPORT */
mbed_official 0:51ac1d130fd4 208 ao->maxslotindex = MAX_SLOTS - 1;
mbed_official 0:51ac1d130fd4 209 ao->cflag = 1;
mbed_official 0:51ac1d130fd4 210 ao->default_route = 1;
mbed_official 0:51ac1d130fd4 211 }
mbed_official 0:51ac1d130fd4 212
mbed_official 0:51ac1d130fd4 213
mbed_official 0:51ac1d130fd4 214 /*
mbed_official 0:51ac1d130fd4 215 * ipcp_open - IPCP is allowed to come up.
mbed_official 0:51ac1d130fd4 216 */
mbed_official 0:51ac1d130fd4 217 static void
mbed_official 0:51ac1d130fd4 218 ipcp_open(int unit)
mbed_official 0:51ac1d130fd4 219 {
mbed_official 0:51ac1d130fd4 220 fsm_open(&ipcp_fsm[unit]);
mbed_official 0:51ac1d130fd4 221 }
mbed_official 0:51ac1d130fd4 222
mbed_official 0:51ac1d130fd4 223
mbed_official 0:51ac1d130fd4 224 /*
mbed_official 0:51ac1d130fd4 225 * ipcp_close - Take IPCP down.
mbed_official 0:51ac1d130fd4 226 */
mbed_official 0:51ac1d130fd4 227 static void
mbed_official 0:51ac1d130fd4 228 ipcp_close(int unit, char *reason)
mbed_official 0:51ac1d130fd4 229 {
mbed_official 0:51ac1d130fd4 230 fsm_close(&ipcp_fsm[unit], reason);
mbed_official 0:51ac1d130fd4 231 }
mbed_official 0:51ac1d130fd4 232
mbed_official 0:51ac1d130fd4 233
mbed_official 0:51ac1d130fd4 234 /*
mbed_official 0:51ac1d130fd4 235 * ipcp_lowerup - The lower layer is up.
mbed_official 0:51ac1d130fd4 236 */
mbed_official 0:51ac1d130fd4 237 static void
mbed_official 0:51ac1d130fd4 238 ipcp_lowerup(int unit)
mbed_official 0:51ac1d130fd4 239 {
mbed_official 0:51ac1d130fd4 240 fsm_lowerup(&ipcp_fsm[unit]);
mbed_official 0:51ac1d130fd4 241 }
mbed_official 0:51ac1d130fd4 242
mbed_official 0:51ac1d130fd4 243
mbed_official 0:51ac1d130fd4 244 /*
mbed_official 0:51ac1d130fd4 245 * ipcp_lowerdown - The lower layer is down.
mbed_official 0:51ac1d130fd4 246 */
mbed_official 0:51ac1d130fd4 247 static void
mbed_official 0:51ac1d130fd4 248 ipcp_lowerdown(int unit)
mbed_official 0:51ac1d130fd4 249 {
mbed_official 0:51ac1d130fd4 250 fsm_lowerdown(&ipcp_fsm[unit]);
mbed_official 0:51ac1d130fd4 251 }
mbed_official 0:51ac1d130fd4 252
mbed_official 0:51ac1d130fd4 253
mbed_official 0:51ac1d130fd4 254 /*
mbed_official 0:51ac1d130fd4 255 * ipcp_input - Input IPCP packet.
mbed_official 0:51ac1d130fd4 256 */
mbed_official 0:51ac1d130fd4 257 static void
mbed_official 0:51ac1d130fd4 258 ipcp_input(int unit, u_char *p, int len)
mbed_official 0:51ac1d130fd4 259 {
mbed_official 0:51ac1d130fd4 260 fsm_input(&ipcp_fsm[unit], p, len);
mbed_official 0:51ac1d130fd4 261 }
mbed_official 0:51ac1d130fd4 262
mbed_official 0:51ac1d130fd4 263
mbed_official 0:51ac1d130fd4 264 /*
mbed_official 0:51ac1d130fd4 265 * ipcp_protrej - A Protocol-Reject was received for IPCP.
mbed_official 0:51ac1d130fd4 266 *
mbed_official 0:51ac1d130fd4 267 * Pretend the lower layer went down, so we shut up.
mbed_official 0:51ac1d130fd4 268 */
mbed_official 0:51ac1d130fd4 269 static void
mbed_official 0:51ac1d130fd4 270 ipcp_protrej(int unit)
mbed_official 0:51ac1d130fd4 271 {
mbed_official 0:51ac1d130fd4 272 fsm_lowerdown(&ipcp_fsm[unit]);
mbed_official 0:51ac1d130fd4 273 }
mbed_official 0:51ac1d130fd4 274
mbed_official 0:51ac1d130fd4 275
mbed_official 0:51ac1d130fd4 276 /*
mbed_official 0:51ac1d130fd4 277 * ipcp_resetci - Reset our CI.
mbed_official 0:51ac1d130fd4 278 */
mbed_official 0:51ac1d130fd4 279 static void
mbed_official 0:51ac1d130fd4 280 ipcp_resetci(fsm *f)
mbed_official 0:51ac1d130fd4 281 {
mbed_official 0:51ac1d130fd4 282 ipcp_options *wo = &ipcp_wantoptions[f->unit];
mbed_official 0:51ac1d130fd4 283
mbed_official 0:51ac1d130fd4 284 wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;
mbed_official 0:51ac1d130fd4 285 if (wo->ouraddr == 0) {
mbed_official 0:51ac1d130fd4 286 wo->accept_local = 1;
mbed_official 0:51ac1d130fd4 287 }
mbed_official 0:51ac1d130fd4 288 if (wo->hisaddr == 0) {
mbed_official 0:51ac1d130fd4 289 wo->accept_remote = 1;
mbed_official 0:51ac1d130fd4 290 }
mbed_official 0:51ac1d130fd4 291 /* Request DNS addresses from the peer */
mbed_official 0:51ac1d130fd4 292 wo->req_dns1 = ppp_settings.usepeerdns;
mbed_official 0:51ac1d130fd4 293 wo->req_dns2 = ppp_settings.usepeerdns;
mbed_official 0:51ac1d130fd4 294 ipcp_gotoptions[f->unit] = *wo;
mbed_official 0:51ac1d130fd4 295 cis_received[f->unit] = 0;
mbed_official 0:51ac1d130fd4 296 }
mbed_official 0:51ac1d130fd4 297
mbed_official 0:51ac1d130fd4 298
mbed_official 0:51ac1d130fd4 299 /*
mbed_official 0:51ac1d130fd4 300 * ipcp_cilen - Return length of our CI.
mbed_official 0:51ac1d130fd4 301 */
mbed_official 0:51ac1d130fd4 302 static int
mbed_official 0:51ac1d130fd4 303 ipcp_cilen(fsm *f)
mbed_official 0:51ac1d130fd4 304 {
mbed_official 0:51ac1d130fd4 305 ipcp_options *go = &ipcp_gotoptions[f->unit];
mbed_official 0:51ac1d130fd4 306 ipcp_options *wo = &ipcp_wantoptions[f->unit];
mbed_official 0:51ac1d130fd4 307 ipcp_options *ho = &ipcp_hisoptions[f->unit];
mbed_official 0:51ac1d130fd4 308
mbed_official 0:51ac1d130fd4 309 #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
mbed_official 0:51ac1d130fd4 310 #define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)
mbed_official 0:51ac1d130fd4 311 #define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0)
mbed_official 0:51ac1d130fd4 312
mbed_official 0:51ac1d130fd4 313 /*
mbed_official 0:51ac1d130fd4 314 * First see if we want to change our options to the old
mbed_official 0:51ac1d130fd4 315 * forms because we have received old forms from the peer.
mbed_official 0:51ac1d130fd4 316 */
mbed_official 0:51ac1d130fd4 317 if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {
mbed_official 0:51ac1d130fd4 318 /* use the old style of address negotiation */
mbed_official 0:51ac1d130fd4 319 go->neg_addr = 1;
mbed_official 0:51ac1d130fd4 320 go->old_addrs = 1;
mbed_official 0:51ac1d130fd4 321 }
mbed_official 0:51ac1d130fd4 322 if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
mbed_official 0:51ac1d130fd4 323 /* try an older style of VJ negotiation */
mbed_official 0:51ac1d130fd4 324 if (cis_received[f->unit] == 0) {
mbed_official 0:51ac1d130fd4 325 /* keep trying the new style until we see some CI from the peer */
mbed_official 0:51ac1d130fd4 326 go->neg_vj = 1;
mbed_official 0:51ac1d130fd4 327 } else {
mbed_official 0:51ac1d130fd4 328 /* use the old style only if the peer did */
mbed_official 0:51ac1d130fd4 329 if (ho->neg_vj && ho->old_vj) {
mbed_official 0:51ac1d130fd4 330 go->neg_vj = 1;
mbed_official 0:51ac1d130fd4 331 go->old_vj = 1;
mbed_official 0:51ac1d130fd4 332 go->vj_protocol = ho->vj_protocol;
mbed_official 0:51ac1d130fd4 333 }
mbed_official 0:51ac1d130fd4 334 }
mbed_official 0:51ac1d130fd4 335 }
mbed_official 0:51ac1d130fd4 336
mbed_official 0:51ac1d130fd4 337 return (LENCIADDR(go->neg_addr, go->old_addrs) +
mbed_official 0:51ac1d130fd4 338 LENCIVJ(go->neg_vj, go->old_vj) +
mbed_official 0:51ac1d130fd4 339 LENCIDNS(go->req_dns1) +
mbed_official 0:51ac1d130fd4 340 LENCIDNS(go->req_dns2));
mbed_official 0:51ac1d130fd4 341 }
mbed_official 0:51ac1d130fd4 342
mbed_official 0:51ac1d130fd4 343
mbed_official 0:51ac1d130fd4 344 /*
mbed_official 0:51ac1d130fd4 345 * ipcp_addci - Add our desired CIs to a packet.
mbed_official 0:51ac1d130fd4 346 */
mbed_official 0:51ac1d130fd4 347 static void
mbed_official 0:51ac1d130fd4 348 ipcp_addci(fsm *f, u_char *ucp, int *lenp)
mbed_official 0:51ac1d130fd4 349 {
mbed_official 0:51ac1d130fd4 350 ipcp_options *go = &ipcp_gotoptions[f->unit];
mbed_official 0:51ac1d130fd4 351 int len = *lenp;
mbed_official 0:51ac1d130fd4 352
mbed_official 0:51ac1d130fd4 353 #define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
mbed_official 0:51ac1d130fd4 354 if (neg) { \
mbed_official 0:51ac1d130fd4 355 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
mbed_official 0:51ac1d130fd4 356 if (len >= vjlen) { \
mbed_official 0:51ac1d130fd4 357 PUTCHAR(opt, ucp); \
mbed_official 0:51ac1d130fd4 358 PUTCHAR(vjlen, ucp); \
mbed_official 0:51ac1d130fd4 359 PUTSHORT(val, ucp); \
mbed_official 0:51ac1d130fd4 360 if (!old) { \
mbed_official 0:51ac1d130fd4 361 PUTCHAR(maxslotindex, ucp); \
mbed_official 0:51ac1d130fd4 362 PUTCHAR(cflag, ucp); \
mbed_official 0:51ac1d130fd4 363 } \
mbed_official 0:51ac1d130fd4 364 len -= vjlen; \
mbed_official 0:51ac1d130fd4 365 } else { \
mbed_official 0:51ac1d130fd4 366 neg = 0; \
mbed_official 0:51ac1d130fd4 367 } \
mbed_official 0:51ac1d130fd4 368 }
mbed_official 0:51ac1d130fd4 369
mbed_official 0:51ac1d130fd4 370 #define ADDCIADDR(opt, neg, old, val1, val2) \
mbed_official 0:51ac1d130fd4 371 if (neg) { \
mbed_official 0:51ac1d130fd4 372 int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
mbed_official 0:51ac1d130fd4 373 if (len >= addrlen) { \
mbed_official 0:51ac1d130fd4 374 u32_t l; \
mbed_official 0:51ac1d130fd4 375 PUTCHAR(opt, ucp); \
mbed_official 0:51ac1d130fd4 376 PUTCHAR(addrlen, ucp); \
mbed_official 0:51ac1d130fd4 377 l = ntohl(val1); \
mbed_official 0:51ac1d130fd4 378 PUTLONG(l, ucp); \
mbed_official 0:51ac1d130fd4 379 if (old) { \
mbed_official 0:51ac1d130fd4 380 l = ntohl(val2); \
mbed_official 0:51ac1d130fd4 381 PUTLONG(l, ucp); \
mbed_official 0:51ac1d130fd4 382 } \
mbed_official 0:51ac1d130fd4 383 len -= addrlen; \
mbed_official 0:51ac1d130fd4 384 } else { \
mbed_official 0:51ac1d130fd4 385 neg = 0; \
mbed_official 0:51ac1d130fd4 386 } \
mbed_official 0:51ac1d130fd4 387 }
mbed_official 0:51ac1d130fd4 388
mbed_official 0:51ac1d130fd4 389 #define ADDCIDNS(opt, neg, addr) \
mbed_official 0:51ac1d130fd4 390 if (neg) { \
mbed_official 0:51ac1d130fd4 391 if (len >= CILEN_ADDR) { \
mbed_official 0:51ac1d130fd4 392 u32_t l; \
mbed_official 0:51ac1d130fd4 393 PUTCHAR(opt, ucp); \
mbed_official 0:51ac1d130fd4 394 PUTCHAR(CILEN_ADDR, ucp); \
mbed_official 0:51ac1d130fd4 395 l = ntohl(addr); \
mbed_official 0:51ac1d130fd4 396 PUTLONG(l, ucp); \
mbed_official 0:51ac1d130fd4 397 len -= CILEN_ADDR; \
mbed_official 0:51ac1d130fd4 398 } else { \
mbed_official 0:51ac1d130fd4 399 neg = 0; \
mbed_official 0:51ac1d130fd4 400 } \
mbed_official 0:51ac1d130fd4 401 }
mbed_official 0:51ac1d130fd4 402
mbed_official 0:51ac1d130fd4 403 ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
mbed_official 0:51ac1d130fd4 404 go->old_addrs, go->ouraddr, go->hisaddr);
mbed_official 0:51ac1d130fd4 405
mbed_official 0:51ac1d130fd4 406 ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
mbed_official 0:51ac1d130fd4 407 go->maxslotindex, go->cflag);
mbed_official 0:51ac1d130fd4 408
mbed_official 0:51ac1d130fd4 409 ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
mbed_official 0:51ac1d130fd4 410
mbed_official 0:51ac1d130fd4 411 ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
mbed_official 0:51ac1d130fd4 412
mbed_official 0:51ac1d130fd4 413 *lenp -= len;
mbed_official 0:51ac1d130fd4 414 }
mbed_official 0:51ac1d130fd4 415
mbed_official 0:51ac1d130fd4 416
mbed_official 0:51ac1d130fd4 417 /*
mbed_official 0:51ac1d130fd4 418 * ipcp_ackci - Ack our CIs.
mbed_official 0:51ac1d130fd4 419 *
mbed_official 0:51ac1d130fd4 420 * Returns:
mbed_official 0:51ac1d130fd4 421 * 0 - Ack was bad.
mbed_official 0:51ac1d130fd4 422 * 1 - Ack was good.
mbed_official 0:51ac1d130fd4 423 */
mbed_official 0:51ac1d130fd4 424 static int
mbed_official 0:51ac1d130fd4 425 ipcp_ackci(fsm *f, u_char *p, int len)
mbed_official 0:51ac1d130fd4 426 {
mbed_official 0:51ac1d130fd4 427 ipcp_options *go = &ipcp_gotoptions[f->unit];
mbed_official 0:51ac1d130fd4 428 u_short cilen, citype, cishort;
mbed_official 0:51ac1d130fd4 429 u32_t cilong;
mbed_official 0:51ac1d130fd4 430 u_char cimaxslotindex, cicflag;
mbed_official 0:51ac1d130fd4 431
mbed_official 0:51ac1d130fd4 432 /*
mbed_official 0:51ac1d130fd4 433 * CIs must be in exactly the same order that we sent...
mbed_official 0:51ac1d130fd4 434 * Check packet length and CI length at each step.
mbed_official 0:51ac1d130fd4 435 * If we find any deviations, then this packet is bad.
mbed_official 0:51ac1d130fd4 436 */
mbed_official 0:51ac1d130fd4 437
mbed_official 0:51ac1d130fd4 438 #define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
mbed_official 0:51ac1d130fd4 439 if (neg) { \
mbed_official 0:51ac1d130fd4 440 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
mbed_official 0:51ac1d130fd4 441 if ((len -= vjlen) < 0) { \
mbed_official 0:51ac1d130fd4 442 goto bad; \
mbed_official 0:51ac1d130fd4 443 } \
mbed_official 0:51ac1d130fd4 444 GETCHAR(citype, p); \
mbed_official 0:51ac1d130fd4 445 GETCHAR(cilen, p); \
mbed_official 0:51ac1d130fd4 446 if (cilen != vjlen || \
mbed_official 0:51ac1d130fd4 447 citype != opt) { \
mbed_official 0:51ac1d130fd4 448 goto bad; \
mbed_official 0:51ac1d130fd4 449 } \
mbed_official 0:51ac1d130fd4 450 GETSHORT(cishort, p); \
mbed_official 0:51ac1d130fd4 451 if (cishort != val) { \
mbed_official 0:51ac1d130fd4 452 goto bad; \
mbed_official 0:51ac1d130fd4 453 } \
mbed_official 0:51ac1d130fd4 454 if (!old) { \
mbed_official 0:51ac1d130fd4 455 GETCHAR(cimaxslotindex, p); \
mbed_official 0:51ac1d130fd4 456 if (cimaxslotindex != maxslotindex) { \
mbed_official 0:51ac1d130fd4 457 goto bad; \
mbed_official 0:51ac1d130fd4 458 } \
mbed_official 0:51ac1d130fd4 459 GETCHAR(cicflag, p); \
mbed_official 0:51ac1d130fd4 460 if (cicflag != cflag) { \
mbed_official 0:51ac1d130fd4 461 goto bad; \
mbed_official 0:51ac1d130fd4 462 } \
mbed_official 0:51ac1d130fd4 463 } \
mbed_official 0:51ac1d130fd4 464 }
mbed_official 0:51ac1d130fd4 465
mbed_official 0:51ac1d130fd4 466 #define ACKCIADDR(opt, neg, old, val1, val2) \
mbed_official 0:51ac1d130fd4 467 if (neg) { \
mbed_official 0:51ac1d130fd4 468 int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
mbed_official 0:51ac1d130fd4 469 u32_t l; \
mbed_official 0:51ac1d130fd4 470 if ((len -= addrlen) < 0) { \
mbed_official 0:51ac1d130fd4 471 goto bad; \
mbed_official 0:51ac1d130fd4 472 } \
mbed_official 0:51ac1d130fd4 473 GETCHAR(citype, p); \
mbed_official 0:51ac1d130fd4 474 GETCHAR(cilen, p); \
mbed_official 0:51ac1d130fd4 475 if (cilen != addrlen || \
mbed_official 0:51ac1d130fd4 476 citype != opt) { \
mbed_official 0:51ac1d130fd4 477 goto bad; \
mbed_official 0:51ac1d130fd4 478 } \
mbed_official 0:51ac1d130fd4 479 GETLONG(l, p); \
mbed_official 0:51ac1d130fd4 480 cilong = htonl(l); \
mbed_official 0:51ac1d130fd4 481 if (val1 != cilong) { \
mbed_official 0:51ac1d130fd4 482 goto bad; \
mbed_official 0:51ac1d130fd4 483 } \
mbed_official 0:51ac1d130fd4 484 if (old) { \
mbed_official 0:51ac1d130fd4 485 GETLONG(l, p); \
mbed_official 0:51ac1d130fd4 486 cilong = htonl(l); \
mbed_official 0:51ac1d130fd4 487 if (val2 != cilong) { \
mbed_official 0:51ac1d130fd4 488 goto bad; \
mbed_official 0:51ac1d130fd4 489 } \
mbed_official 0:51ac1d130fd4 490 } \
mbed_official 0:51ac1d130fd4 491 }
mbed_official 0:51ac1d130fd4 492
mbed_official 0:51ac1d130fd4 493 #define ACKCIDNS(opt, neg, addr) \
mbed_official 0:51ac1d130fd4 494 if (neg) { \
mbed_official 0:51ac1d130fd4 495 u32_t l; \
mbed_official 0:51ac1d130fd4 496 if ((len -= CILEN_ADDR) < 0) { \
mbed_official 0:51ac1d130fd4 497 goto bad; \
mbed_official 0:51ac1d130fd4 498 } \
mbed_official 0:51ac1d130fd4 499 GETCHAR(citype, p); \
mbed_official 0:51ac1d130fd4 500 GETCHAR(cilen, p); \
mbed_official 0:51ac1d130fd4 501 if (cilen != CILEN_ADDR || \
mbed_official 0:51ac1d130fd4 502 citype != opt) { \
mbed_official 0:51ac1d130fd4 503 goto bad; \
mbed_official 0:51ac1d130fd4 504 } \
mbed_official 0:51ac1d130fd4 505 GETLONG(l, p); \
mbed_official 0:51ac1d130fd4 506 cilong = htonl(l); \
mbed_official 0:51ac1d130fd4 507 if (addr != cilong) { \
mbed_official 0:51ac1d130fd4 508 goto bad; \
mbed_official 0:51ac1d130fd4 509 } \
mbed_official 0:51ac1d130fd4 510 }
mbed_official 0:51ac1d130fd4 511
mbed_official 0:51ac1d130fd4 512 ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
mbed_official 0:51ac1d130fd4 513 go->old_addrs, go->ouraddr, go->hisaddr);
mbed_official 0:51ac1d130fd4 514
mbed_official 0:51ac1d130fd4 515 ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
mbed_official 0:51ac1d130fd4 516 go->maxslotindex, go->cflag);
mbed_official 0:51ac1d130fd4 517
mbed_official 0:51ac1d130fd4 518 ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
mbed_official 0:51ac1d130fd4 519
mbed_official 0:51ac1d130fd4 520 ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
mbed_official 0:51ac1d130fd4 521
mbed_official 0:51ac1d130fd4 522 /*
mbed_official 0:51ac1d130fd4 523 * If there are any remaining CIs, then this packet is bad.
mbed_official 0:51ac1d130fd4 524 */
mbed_official 0:51ac1d130fd4 525 if (len != 0) {
mbed_official 0:51ac1d130fd4 526 goto bad;
mbed_official 0:51ac1d130fd4 527 }
mbed_official 0:51ac1d130fd4 528 return (1);
mbed_official 0:51ac1d130fd4 529
mbed_official 0:51ac1d130fd4 530 bad:
mbed_official 0:51ac1d130fd4 531 IPCPDEBUG(LOG_INFO, ("ipcp_ackci: received bad Ack!\n"));
mbed_official 0:51ac1d130fd4 532 return (0);
mbed_official 0:51ac1d130fd4 533 }
mbed_official 0:51ac1d130fd4 534
mbed_official 0:51ac1d130fd4 535 /*
mbed_official 0:51ac1d130fd4 536 * ipcp_nakci - Peer has sent a NAK for some of our CIs.
mbed_official 0:51ac1d130fd4 537 * This should not modify any state if the Nak is bad
mbed_official 0:51ac1d130fd4 538 * or if IPCP is in the LS_OPENED state.
mbed_official 0:51ac1d130fd4 539 *
mbed_official 0:51ac1d130fd4 540 * Returns:
mbed_official 0:51ac1d130fd4 541 * 0 - Nak was bad.
mbed_official 0:51ac1d130fd4 542 * 1 - Nak was good.
mbed_official 0:51ac1d130fd4 543 */
mbed_official 0:51ac1d130fd4 544 static int
mbed_official 0:51ac1d130fd4 545 ipcp_nakci(fsm *f, u_char *p, int len)
mbed_official 0:51ac1d130fd4 546 {
mbed_official 0:51ac1d130fd4 547 ipcp_options *go = &ipcp_gotoptions[f->unit];
mbed_official 0:51ac1d130fd4 548 u_char cimaxslotindex, cicflag;
mbed_official 0:51ac1d130fd4 549 u_char citype, cilen, *next;
mbed_official 0:51ac1d130fd4 550 u_short cishort;
mbed_official 0:51ac1d130fd4 551 u32_t ciaddr1, ciaddr2, l, cidnsaddr;
mbed_official 0:51ac1d130fd4 552 ipcp_options no; /* options we've seen Naks for */
mbed_official 0:51ac1d130fd4 553 ipcp_options try; /* options to request next time */
mbed_official 0:51ac1d130fd4 554
mbed_official 0:51ac1d130fd4 555 BZERO(&no, sizeof(no));
mbed_official 0:51ac1d130fd4 556 try = *go;
mbed_official 0:51ac1d130fd4 557
mbed_official 0:51ac1d130fd4 558 /*
mbed_official 0:51ac1d130fd4 559 * Any Nak'd CIs must be in exactly the same order that we sent.
mbed_official 0:51ac1d130fd4 560 * Check packet length and CI length at each step.
mbed_official 0:51ac1d130fd4 561 * If we find any deviations, then this packet is bad.
mbed_official 0:51ac1d130fd4 562 */
mbed_official 0:51ac1d130fd4 563 #define NAKCIADDR(opt, neg, old, code) \
mbed_official 0:51ac1d130fd4 564 if (go->neg && \
mbed_official 0:51ac1d130fd4 565 len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \
mbed_official 0:51ac1d130fd4 566 p[1] == cilen && \
mbed_official 0:51ac1d130fd4 567 p[0] == opt) { \
mbed_official 0:51ac1d130fd4 568 len -= cilen; \
mbed_official 0:51ac1d130fd4 569 INCPTR(2, p); \
mbed_official 0:51ac1d130fd4 570 GETLONG(l, p); \
mbed_official 0:51ac1d130fd4 571 ciaddr1 = htonl(l); \
mbed_official 0:51ac1d130fd4 572 if (old) { \
mbed_official 0:51ac1d130fd4 573 GETLONG(l, p); \
mbed_official 0:51ac1d130fd4 574 ciaddr2 = htonl(l); \
mbed_official 0:51ac1d130fd4 575 no.old_addrs = 1; \
mbed_official 0:51ac1d130fd4 576 } else { \
mbed_official 0:51ac1d130fd4 577 ciaddr2 = 0; \
mbed_official 0:51ac1d130fd4 578 } \
mbed_official 0:51ac1d130fd4 579 no.neg = 1; \
mbed_official 0:51ac1d130fd4 580 code \
mbed_official 0:51ac1d130fd4 581 }
mbed_official 0:51ac1d130fd4 582
mbed_official 0:51ac1d130fd4 583 #define NAKCIVJ(opt, neg, code) \
mbed_official 0:51ac1d130fd4 584 if (go->neg && \
mbed_official 0:51ac1d130fd4 585 ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
mbed_official 0:51ac1d130fd4 586 len >= cilen && \
mbed_official 0:51ac1d130fd4 587 p[0] == opt) { \
mbed_official 0:51ac1d130fd4 588 len -= cilen; \
mbed_official 0:51ac1d130fd4 589 INCPTR(2, p); \
mbed_official 0:51ac1d130fd4 590 GETSHORT(cishort, p); \
mbed_official 0:51ac1d130fd4 591 no.neg = 1; \
mbed_official 0:51ac1d130fd4 592 code \
mbed_official 0:51ac1d130fd4 593 }
mbed_official 0:51ac1d130fd4 594
mbed_official 0:51ac1d130fd4 595 #define NAKCIDNS(opt, neg, code) \
mbed_official 0:51ac1d130fd4 596 if (go->neg && \
mbed_official 0:51ac1d130fd4 597 ((cilen = p[1]) == CILEN_ADDR) && \
mbed_official 0:51ac1d130fd4 598 len >= cilen && \
mbed_official 0:51ac1d130fd4 599 p[0] == opt) { \
mbed_official 0:51ac1d130fd4 600 len -= cilen; \
mbed_official 0:51ac1d130fd4 601 INCPTR(2, p); \
mbed_official 0:51ac1d130fd4 602 GETLONG(l, p); \
mbed_official 0:51ac1d130fd4 603 cidnsaddr = htonl(l); \
mbed_official 0:51ac1d130fd4 604 no.neg = 1; \
mbed_official 0:51ac1d130fd4 605 code \
mbed_official 0:51ac1d130fd4 606 }
mbed_official 0:51ac1d130fd4 607
mbed_official 0:51ac1d130fd4 608 /*
mbed_official 0:51ac1d130fd4 609 * Accept the peer's idea of {our,his} address, if different
mbed_official 0:51ac1d130fd4 610 * from our idea, only if the accept_{local,remote} flag is set.
mbed_official 0:51ac1d130fd4 611 */
mbed_official 0:51ac1d130fd4 612 NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
mbed_official 0:51ac1d130fd4 613 if (go->accept_local && ciaddr1) { /* Do we know our address? */
mbed_official 0:51ac1d130fd4 614 try.ouraddr = ciaddr1;
mbed_official 0:51ac1d130fd4 615 IPCPDEBUG(LOG_INFO, ("local IP address %s\n",
mbed_official 0:51ac1d130fd4 616 inet_ntoa(ciaddr1)));
mbed_official 0:51ac1d130fd4 617 }
mbed_official 0:51ac1d130fd4 618 if (go->accept_remote && ciaddr2) { /* Does he know his? */
mbed_official 0:51ac1d130fd4 619 try.hisaddr = ciaddr2;
mbed_official 0:51ac1d130fd4 620 IPCPDEBUG(LOG_INFO, ("remote IP address %s\n",
mbed_official 0:51ac1d130fd4 621 inet_ntoa(ciaddr2)));
mbed_official 0:51ac1d130fd4 622 }
mbed_official 0:51ac1d130fd4 623 );
mbed_official 0:51ac1d130fd4 624
mbed_official 0:51ac1d130fd4 625 /*
mbed_official 0:51ac1d130fd4 626 * Accept the peer's value of maxslotindex provided that it
mbed_official 0:51ac1d130fd4 627 * is less than what we asked for. Turn off slot-ID compression
mbed_official 0:51ac1d130fd4 628 * if the peer wants. Send old-style compress-type option if
mbed_official 0:51ac1d130fd4 629 * the peer wants.
mbed_official 0:51ac1d130fd4 630 */
mbed_official 0:51ac1d130fd4 631 NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
mbed_official 0:51ac1d130fd4 632 if (cilen == CILEN_VJ) {
mbed_official 0:51ac1d130fd4 633 GETCHAR(cimaxslotindex, p);
mbed_official 0:51ac1d130fd4 634 GETCHAR(cicflag, p);
mbed_official 0:51ac1d130fd4 635 if (cishort == IPCP_VJ_COMP) {
mbed_official 0:51ac1d130fd4 636 try.old_vj = 0;
mbed_official 0:51ac1d130fd4 637 if (cimaxslotindex < go->maxslotindex) {
mbed_official 0:51ac1d130fd4 638 try.maxslotindex = cimaxslotindex;
mbed_official 0:51ac1d130fd4 639 }
mbed_official 0:51ac1d130fd4 640 if (!cicflag) {
mbed_official 0:51ac1d130fd4 641 try.cflag = 0;
mbed_official 0:51ac1d130fd4 642 }
mbed_official 0:51ac1d130fd4 643 } else {
mbed_official 0:51ac1d130fd4 644 try.neg_vj = 0;
mbed_official 0:51ac1d130fd4 645 }
mbed_official 0:51ac1d130fd4 646 } else {
mbed_official 0:51ac1d130fd4 647 if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
mbed_official 0:51ac1d130fd4 648 try.old_vj = 1;
mbed_official 0:51ac1d130fd4 649 try.vj_protocol = cishort;
mbed_official 0:51ac1d130fd4 650 } else {
mbed_official 0:51ac1d130fd4 651 try.neg_vj = 0;
mbed_official 0:51ac1d130fd4 652 }
mbed_official 0:51ac1d130fd4 653 }
mbed_official 0:51ac1d130fd4 654 );
mbed_official 0:51ac1d130fd4 655
mbed_official 0:51ac1d130fd4 656 NAKCIDNS(CI_MS_DNS1, req_dns1,
mbed_official 0:51ac1d130fd4 657 try.dnsaddr[0] = cidnsaddr;
mbed_official 0:51ac1d130fd4 658 IPCPDEBUG(LOG_INFO, ("primary DNS address %s\n", inet_ntoa(cidnsaddr)));
mbed_official 0:51ac1d130fd4 659 );
mbed_official 0:51ac1d130fd4 660
mbed_official 0:51ac1d130fd4 661 NAKCIDNS(CI_MS_DNS2, req_dns2,
mbed_official 0:51ac1d130fd4 662 try.dnsaddr[1] = cidnsaddr;
mbed_official 0:51ac1d130fd4 663 IPCPDEBUG(LOG_INFO, ("secondary DNS address %s\n", inet_ntoa(cidnsaddr)));
mbed_official 0:51ac1d130fd4 664 );
mbed_official 0:51ac1d130fd4 665
mbed_official 0:51ac1d130fd4 666 /*
mbed_official 0:51ac1d130fd4 667 * There may be remaining CIs, if the peer is requesting negotiation
mbed_official 0:51ac1d130fd4 668 * on an option that we didn't include in our request packet.
mbed_official 0:51ac1d130fd4 669 * If they want to negotiate about IP addresses, we comply.
mbed_official 0:51ac1d130fd4 670 * If they want us to ask for compression, we refuse.
mbed_official 0:51ac1d130fd4 671 */
mbed_official 0:51ac1d130fd4 672 while (len > CILEN_VOID) {
mbed_official 0:51ac1d130fd4 673 GETCHAR(citype, p);
mbed_official 0:51ac1d130fd4 674 GETCHAR(cilen, p);
mbed_official 0:51ac1d130fd4 675 if( (len -= cilen) < 0 ) {
mbed_official 0:51ac1d130fd4 676 goto bad;
mbed_official 0:51ac1d130fd4 677 }
mbed_official 0:51ac1d130fd4 678 next = p + cilen - 2;
mbed_official 0:51ac1d130fd4 679
mbed_official 0:51ac1d130fd4 680 switch (citype) {
mbed_official 0:51ac1d130fd4 681 case CI_COMPRESSTYPE:
mbed_official 0:51ac1d130fd4 682 if (go->neg_vj || no.neg_vj ||
mbed_official 0:51ac1d130fd4 683 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {
mbed_official 0:51ac1d130fd4 684 goto bad;
mbed_official 0:51ac1d130fd4 685 }
mbed_official 0:51ac1d130fd4 686 no.neg_vj = 1;
mbed_official 0:51ac1d130fd4 687 break;
mbed_official 0:51ac1d130fd4 688 case CI_ADDRS:
mbed_official 0:51ac1d130fd4 689 if ((go->neg_addr && go->old_addrs) || no.old_addrs
mbed_official 0:51ac1d130fd4 690 || cilen != CILEN_ADDRS) {
mbed_official 0:51ac1d130fd4 691 goto bad;
mbed_official 0:51ac1d130fd4 692 }
mbed_official 0:51ac1d130fd4 693 try.neg_addr = 1;
mbed_official 0:51ac1d130fd4 694 try.old_addrs = 1;
mbed_official 0:51ac1d130fd4 695 GETLONG(l, p);
mbed_official 0:51ac1d130fd4 696 ciaddr1 = htonl(l);
mbed_official 0:51ac1d130fd4 697 if (ciaddr1 && go->accept_local) {
mbed_official 0:51ac1d130fd4 698 try.ouraddr = ciaddr1;
mbed_official 0:51ac1d130fd4 699 }
mbed_official 0:51ac1d130fd4 700 GETLONG(l, p);
mbed_official 0:51ac1d130fd4 701 ciaddr2 = htonl(l);
mbed_official 0:51ac1d130fd4 702 if (ciaddr2 && go->accept_remote) {
mbed_official 0:51ac1d130fd4 703 try.hisaddr = ciaddr2;
mbed_official 0:51ac1d130fd4 704 }
mbed_official 0:51ac1d130fd4 705 no.old_addrs = 1;
mbed_official 0:51ac1d130fd4 706 break;
mbed_official 0:51ac1d130fd4 707 case CI_ADDR:
mbed_official 0:51ac1d130fd4 708 if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) {
mbed_official 0:51ac1d130fd4 709 goto bad;
mbed_official 0:51ac1d130fd4 710 }
mbed_official 0:51ac1d130fd4 711 try.old_addrs = 0;
mbed_official 0:51ac1d130fd4 712 GETLONG(l, p);
mbed_official 0:51ac1d130fd4 713 ciaddr1 = htonl(l);
mbed_official 0:51ac1d130fd4 714 if (ciaddr1 && go->accept_local) {
mbed_official 0:51ac1d130fd4 715 try.ouraddr = ciaddr1;
mbed_official 0:51ac1d130fd4 716 }
mbed_official 0:51ac1d130fd4 717 if (try.ouraddr != 0) {
mbed_official 0:51ac1d130fd4 718 try.neg_addr = 1;
mbed_official 0:51ac1d130fd4 719 }
mbed_official 0:51ac1d130fd4 720 no.neg_addr = 1;
mbed_official 0:51ac1d130fd4 721 break;
mbed_official 0:51ac1d130fd4 722 }
mbed_official 0:51ac1d130fd4 723 p = next;
mbed_official 0:51ac1d130fd4 724 }
mbed_official 0:51ac1d130fd4 725
mbed_official 0:51ac1d130fd4 726 /* If there is still anything left, this packet is bad. */
mbed_official 0:51ac1d130fd4 727 if (len != 0) {
mbed_official 0:51ac1d130fd4 728 goto bad;
mbed_official 0:51ac1d130fd4 729 }
mbed_official 0:51ac1d130fd4 730
mbed_official 0:51ac1d130fd4 731 /*
mbed_official 0:51ac1d130fd4 732 * OK, the Nak is good. Now we can update state.
mbed_official 0:51ac1d130fd4 733 */
mbed_official 0:51ac1d130fd4 734 if (f->state != LS_OPENED) {
mbed_official 0:51ac1d130fd4 735 *go = try;
mbed_official 0:51ac1d130fd4 736 }
mbed_official 0:51ac1d130fd4 737
mbed_official 0:51ac1d130fd4 738 return 1;
mbed_official 0:51ac1d130fd4 739
mbed_official 0:51ac1d130fd4 740 bad:
mbed_official 0:51ac1d130fd4 741 IPCPDEBUG(LOG_INFO, ("ipcp_nakci: received bad Nak!\n"));
mbed_official 0:51ac1d130fd4 742 return 0;
mbed_official 0:51ac1d130fd4 743 }
mbed_official 0:51ac1d130fd4 744
mbed_official 0:51ac1d130fd4 745
mbed_official 0:51ac1d130fd4 746 /*
mbed_official 0:51ac1d130fd4 747 * ipcp_rejci - Reject some of our CIs.
mbed_official 0:51ac1d130fd4 748 */
mbed_official 0:51ac1d130fd4 749 static int
mbed_official 0:51ac1d130fd4 750 ipcp_rejci(fsm *f, u_char *p, int len)
mbed_official 0:51ac1d130fd4 751 {
mbed_official 0:51ac1d130fd4 752 ipcp_options *go = &ipcp_gotoptions[f->unit];
mbed_official 0:51ac1d130fd4 753 u_char cimaxslotindex, ciflag, cilen;
mbed_official 0:51ac1d130fd4 754 u_short cishort;
mbed_official 0:51ac1d130fd4 755 u32_t cilong;
mbed_official 0:51ac1d130fd4 756 ipcp_options try; /* options to request next time */
mbed_official 0:51ac1d130fd4 757
mbed_official 0:51ac1d130fd4 758 try = *go;
mbed_official 0:51ac1d130fd4 759 /*
mbed_official 0:51ac1d130fd4 760 * Any Rejected CIs must be in exactly the same order that we sent.
mbed_official 0:51ac1d130fd4 761 * Check packet length and CI length at each step.
mbed_official 0:51ac1d130fd4 762 * If we find any deviations, then this packet is bad.
mbed_official 0:51ac1d130fd4 763 */
mbed_official 0:51ac1d130fd4 764 #define REJCIADDR(opt, neg, old, val1, val2) \
mbed_official 0:51ac1d130fd4 765 if (go->neg && \
mbed_official 0:51ac1d130fd4 766 len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \
mbed_official 0:51ac1d130fd4 767 p[1] == cilen && \
mbed_official 0:51ac1d130fd4 768 p[0] == opt) { \
mbed_official 0:51ac1d130fd4 769 u32_t l; \
mbed_official 0:51ac1d130fd4 770 len -= cilen; \
mbed_official 0:51ac1d130fd4 771 INCPTR(2, p); \
mbed_official 0:51ac1d130fd4 772 GETLONG(l, p); \
mbed_official 0:51ac1d130fd4 773 cilong = htonl(l); \
mbed_official 0:51ac1d130fd4 774 /* Check rejected value. */ \
mbed_official 0:51ac1d130fd4 775 if (cilong != val1) { \
mbed_official 0:51ac1d130fd4 776 goto bad; \
mbed_official 0:51ac1d130fd4 777 } \
mbed_official 0:51ac1d130fd4 778 if (old) { \
mbed_official 0:51ac1d130fd4 779 GETLONG(l, p); \
mbed_official 0:51ac1d130fd4 780 cilong = htonl(l); \
mbed_official 0:51ac1d130fd4 781 /* Check rejected value. */ \
mbed_official 0:51ac1d130fd4 782 if (cilong != val2) { \
mbed_official 0:51ac1d130fd4 783 goto bad; \
mbed_official 0:51ac1d130fd4 784 } \
mbed_official 0:51ac1d130fd4 785 } \
mbed_official 0:51ac1d130fd4 786 try.neg = 0; \
mbed_official 0:51ac1d130fd4 787 }
mbed_official 0:51ac1d130fd4 788
mbed_official 0:51ac1d130fd4 789 #define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
mbed_official 0:51ac1d130fd4 790 if (go->neg && \
mbed_official 0:51ac1d130fd4 791 p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
mbed_official 0:51ac1d130fd4 792 len >= p[1] && \
mbed_official 0:51ac1d130fd4 793 p[0] == opt) { \
mbed_official 0:51ac1d130fd4 794 len -= p[1]; \
mbed_official 0:51ac1d130fd4 795 INCPTR(2, p); \
mbed_official 0:51ac1d130fd4 796 GETSHORT(cishort, p); \
mbed_official 0:51ac1d130fd4 797 /* Check rejected value. */ \
mbed_official 0:51ac1d130fd4 798 if (cishort != val) { \
mbed_official 0:51ac1d130fd4 799 goto bad; \
mbed_official 0:51ac1d130fd4 800 } \
mbed_official 0:51ac1d130fd4 801 if (!old) { \
mbed_official 0:51ac1d130fd4 802 GETCHAR(cimaxslotindex, p); \
mbed_official 0:51ac1d130fd4 803 if (cimaxslotindex != maxslot) { \
mbed_official 0:51ac1d130fd4 804 goto bad; \
mbed_official 0:51ac1d130fd4 805 } \
mbed_official 0:51ac1d130fd4 806 GETCHAR(ciflag, p); \
mbed_official 0:51ac1d130fd4 807 if (ciflag != cflag) { \
mbed_official 0:51ac1d130fd4 808 goto bad; \
mbed_official 0:51ac1d130fd4 809 } \
mbed_official 0:51ac1d130fd4 810 } \
mbed_official 0:51ac1d130fd4 811 try.neg = 0; \
mbed_official 0:51ac1d130fd4 812 }
mbed_official 0:51ac1d130fd4 813
mbed_official 0:51ac1d130fd4 814 #define REJCIDNS(opt, neg, dnsaddr) \
mbed_official 0:51ac1d130fd4 815 if (go->neg && \
mbed_official 0:51ac1d130fd4 816 ((cilen = p[1]) == CILEN_ADDR) && \
mbed_official 0:51ac1d130fd4 817 len >= cilen && \
mbed_official 0:51ac1d130fd4 818 p[0] == opt) { \
mbed_official 0:51ac1d130fd4 819 u32_t l; \
mbed_official 0:51ac1d130fd4 820 len -= cilen; \
mbed_official 0:51ac1d130fd4 821 INCPTR(2, p); \
mbed_official 0:51ac1d130fd4 822 GETLONG(l, p); \
mbed_official 0:51ac1d130fd4 823 cilong = htonl(l); \
mbed_official 0:51ac1d130fd4 824 /* Check rejected value. */ \
mbed_official 0:51ac1d130fd4 825 if (cilong != dnsaddr) { \
mbed_official 0:51ac1d130fd4 826 goto bad; \
mbed_official 0:51ac1d130fd4 827 } \
mbed_official 0:51ac1d130fd4 828 try.neg = 0; \
mbed_official 0:51ac1d130fd4 829 }
mbed_official 0:51ac1d130fd4 830
mbed_official 0:51ac1d130fd4 831 REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,
mbed_official 0:51ac1d130fd4 832 go->old_addrs, go->ouraddr, go->hisaddr);
mbed_official 0:51ac1d130fd4 833
mbed_official 0:51ac1d130fd4 834 REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
mbed_official 0:51ac1d130fd4 835 go->maxslotindex, go->cflag);
mbed_official 0:51ac1d130fd4 836
mbed_official 0:51ac1d130fd4 837 REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
mbed_official 0:51ac1d130fd4 838
mbed_official 0:51ac1d130fd4 839 REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
mbed_official 0:51ac1d130fd4 840
mbed_official 0:51ac1d130fd4 841 /*
mbed_official 0:51ac1d130fd4 842 * If there are any remaining CIs, then this packet is bad.
mbed_official 0:51ac1d130fd4 843 */
mbed_official 0:51ac1d130fd4 844 if (len != 0) {
mbed_official 0:51ac1d130fd4 845 goto bad;
mbed_official 0:51ac1d130fd4 846 }
mbed_official 0:51ac1d130fd4 847 /*
mbed_official 0:51ac1d130fd4 848 * Now we can update state.
mbed_official 0:51ac1d130fd4 849 */
mbed_official 0:51ac1d130fd4 850 if (f->state != LS_OPENED) {
mbed_official 0:51ac1d130fd4 851 *go = try;
mbed_official 0:51ac1d130fd4 852 }
mbed_official 0:51ac1d130fd4 853 return 1;
mbed_official 0:51ac1d130fd4 854
mbed_official 0:51ac1d130fd4 855 bad:
mbed_official 0:51ac1d130fd4 856 IPCPDEBUG(LOG_INFO, ("ipcp_rejci: received bad Reject!\n"));
mbed_official 0:51ac1d130fd4 857 return 0;
mbed_official 0:51ac1d130fd4 858 }
mbed_official 0:51ac1d130fd4 859
mbed_official 0:51ac1d130fd4 860
mbed_official 0:51ac1d130fd4 861 /*
mbed_official 0:51ac1d130fd4 862 * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
mbed_official 0:51ac1d130fd4 863 *
mbed_official 0:51ac1d130fd4 864 * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
mbed_official 0:51ac1d130fd4 865 * appropriately. If reject_if_disagree is non-zero, doesn't return
mbed_official 0:51ac1d130fd4 866 * CONFNAK; returns CONFREJ if it can't return CONFACK.
mbed_official 0:51ac1d130fd4 867 */
mbed_official 0:51ac1d130fd4 868 static int
mbed_official 0:51ac1d130fd4 869 ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested CIs */,int reject_if_disagree)
mbed_official 0:51ac1d130fd4 870 {
mbed_official 0:51ac1d130fd4 871 ipcp_options *wo = &ipcp_wantoptions[f->unit];
mbed_official 0:51ac1d130fd4 872 ipcp_options *ho = &ipcp_hisoptions[f->unit];
mbed_official 0:51ac1d130fd4 873 ipcp_options *ao = &ipcp_allowoptions[f->unit];
mbed_official 0:51ac1d130fd4 874 #ifdef OLD_CI_ADDRS
mbed_official 0:51ac1d130fd4 875 ipcp_options *go = &ipcp_gotoptions[f->unit];
mbed_official 0:51ac1d130fd4 876 #endif
mbed_official 0:51ac1d130fd4 877 u_char *cip, *next; /* Pointer to current and next CIs */
mbed_official 0:51ac1d130fd4 878 u_short cilen, citype; /* Parsed len, type */
mbed_official 0:51ac1d130fd4 879 u_short cishort; /* Parsed short value */
mbed_official 0:51ac1d130fd4 880 u32_t tl, ciaddr1; /* Parsed address values */
mbed_official 0:51ac1d130fd4 881 #ifdef OLD_CI_ADDRS
mbed_official 0:51ac1d130fd4 882 u32_t ciaddr2; /* Parsed address values */
mbed_official 0:51ac1d130fd4 883 #endif
mbed_official 0:51ac1d130fd4 884 int rc = CONFACK; /* Final packet return code */
mbed_official 0:51ac1d130fd4 885 int orc; /* Individual option return code */
mbed_official 0:51ac1d130fd4 886 u_char *p; /* Pointer to next char to parse */
mbed_official 0:51ac1d130fd4 887 u_char *ucp = inp; /* Pointer to current output char */
mbed_official 0:51ac1d130fd4 888 int l = *len; /* Length left */
mbed_official 0:51ac1d130fd4 889 u_char maxslotindex, cflag;
mbed_official 0:51ac1d130fd4 890 int d;
mbed_official 0:51ac1d130fd4 891
mbed_official 0:51ac1d130fd4 892 cis_received[f->unit] = 1;
mbed_official 0:51ac1d130fd4 893
mbed_official 0:51ac1d130fd4 894 /*
mbed_official 0:51ac1d130fd4 895 * Reset all his options.
mbed_official 0:51ac1d130fd4 896 */
mbed_official 0:51ac1d130fd4 897 BZERO(ho, sizeof(*ho));
mbed_official 0:51ac1d130fd4 898
mbed_official 0:51ac1d130fd4 899 /*
mbed_official 0:51ac1d130fd4 900 * Process all his options.
mbed_official 0:51ac1d130fd4 901 */
mbed_official 0:51ac1d130fd4 902 next = inp;
mbed_official 0:51ac1d130fd4 903 while (l) {
mbed_official 0:51ac1d130fd4 904 orc = CONFACK; /* Assume success */
mbed_official 0:51ac1d130fd4 905 cip = p = next; /* Remember begining of CI */
mbed_official 0:51ac1d130fd4 906 if (l < 2 || /* Not enough data for CI header or */
mbed_official 0:51ac1d130fd4 907 p[1] < 2 || /* CI length too small or */
mbed_official 0:51ac1d130fd4 908 p[1] > l) { /* CI length too big? */
mbed_official 0:51ac1d130fd4 909 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: bad CI length!\n"));
mbed_official 0:51ac1d130fd4 910 orc = CONFREJ; /* Reject bad CI */
mbed_official 0:51ac1d130fd4 911 cilen = (u_short)l;/* Reject till end of packet */
mbed_official 0:51ac1d130fd4 912 l = 0; /* Don't loop again */
mbed_official 0:51ac1d130fd4 913 goto endswitch;
mbed_official 0:51ac1d130fd4 914 }
mbed_official 0:51ac1d130fd4 915 GETCHAR(citype, p); /* Parse CI type */
mbed_official 0:51ac1d130fd4 916 GETCHAR(cilen, p); /* Parse CI length */
mbed_official 0:51ac1d130fd4 917 l -= cilen; /* Adjust remaining length */
mbed_official 0:51ac1d130fd4 918 next += cilen; /* Step to next CI */
mbed_official 0:51ac1d130fd4 919
mbed_official 0:51ac1d130fd4 920 switch (citype) { /* Check CI type */
mbed_official 0:51ac1d130fd4 921 #ifdef OLD_CI_ADDRS /* Need to save space... */
mbed_official 0:51ac1d130fd4 922 case CI_ADDRS:
mbed_official 0:51ac1d130fd4 923 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received ADDRS\n"));
mbed_official 0:51ac1d130fd4 924 if (!ao->neg_addr ||
mbed_official 0:51ac1d130fd4 925 cilen != CILEN_ADDRS) { /* Check CI length */
mbed_official 0:51ac1d130fd4 926 orc = CONFREJ; /* Reject CI */
mbed_official 0:51ac1d130fd4 927 break;
mbed_official 0:51ac1d130fd4 928 }
mbed_official 0:51ac1d130fd4 929
mbed_official 0:51ac1d130fd4 930 /*
mbed_official 0:51ac1d130fd4 931 * If he has no address, or if we both have his address but
mbed_official 0:51ac1d130fd4 932 * disagree about it, then NAK it with our idea.
mbed_official 0:51ac1d130fd4 933 * In particular, if we don't know his address, but he does,
mbed_official 0:51ac1d130fd4 934 * then accept it.
mbed_official 0:51ac1d130fd4 935 */
mbed_official 0:51ac1d130fd4 936 GETLONG(tl, p); /* Parse source address (his) */
mbed_official 0:51ac1d130fd4 937 ciaddr1 = htonl(tl);
mbed_official 0:51ac1d130fd4 938 IPCPDEBUG(LOG_INFO, ("his addr %s\n", inet_ntoa(ciaddr1)));
mbed_official 0:51ac1d130fd4 939 if (ciaddr1 != wo->hisaddr
mbed_official 0:51ac1d130fd4 940 && (ciaddr1 == 0 || !wo->accept_remote)) {
mbed_official 0:51ac1d130fd4 941 orc = CONFNAK;
mbed_official 0:51ac1d130fd4 942 if (!reject_if_disagree) {
mbed_official 0:51ac1d130fd4 943 DECPTR(sizeof(u32_t), p);
mbed_official 0:51ac1d130fd4 944 tl = ntohl(wo->hisaddr);
mbed_official 0:51ac1d130fd4 945 PUTLONG(tl, p);
mbed_official 0:51ac1d130fd4 946 }
mbed_official 0:51ac1d130fd4 947 } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
mbed_official 0:51ac1d130fd4 948 /*
mbed_official 0:51ac1d130fd4 949 * If neither we nor he knows his address, reject the option.
mbed_official 0:51ac1d130fd4 950 */
mbed_official 0:51ac1d130fd4 951 orc = CONFREJ;
mbed_official 0:51ac1d130fd4 952 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
mbed_official 0:51ac1d130fd4 953 break;
mbed_official 0:51ac1d130fd4 954 }
mbed_official 0:51ac1d130fd4 955
mbed_official 0:51ac1d130fd4 956 /*
mbed_official 0:51ac1d130fd4 957 * If he doesn't know our address, or if we both have our address
mbed_official 0:51ac1d130fd4 958 * but disagree about it, then NAK it with our idea.
mbed_official 0:51ac1d130fd4 959 */
mbed_official 0:51ac1d130fd4 960 GETLONG(tl, p); /* Parse desination address (ours) */
mbed_official 0:51ac1d130fd4 961 ciaddr2 = htonl(tl);
mbed_official 0:51ac1d130fd4 962 IPCPDEBUG(LOG_INFO, ("our addr %s\n", inet_ntoa(ciaddr2)));
mbed_official 0:51ac1d130fd4 963 if (ciaddr2 != wo->ouraddr) {
mbed_official 0:51ac1d130fd4 964 if (ciaddr2 == 0 || !wo->accept_local) {
mbed_official 0:51ac1d130fd4 965 orc = CONFNAK;
mbed_official 0:51ac1d130fd4 966 if (!reject_if_disagree) {
mbed_official 0:51ac1d130fd4 967 DECPTR(sizeof(u32_t), p);
mbed_official 0:51ac1d130fd4 968 tl = ntohl(wo->ouraddr);
mbed_official 0:51ac1d130fd4 969 PUTLONG(tl, p);
mbed_official 0:51ac1d130fd4 970 }
mbed_official 0:51ac1d130fd4 971 } else {
mbed_official 0:51ac1d130fd4 972 go->ouraddr = ciaddr2; /* accept peer's idea */
mbed_official 0:51ac1d130fd4 973 }
mbed_official 0:51ac1d130fd4 974 }
mbed_official 0:51ac1d130fd4 975
mbed_official 0:51ac1d130fd4 976 ho->neg_addr = 1;
mbed_official 0:51ac1d130fd4 977 ho->old_addrs = 1;
mbed_official 0:51ac1d130fd4 978 ho->hisaddr = ciaddr1;
mbed_official 0:51ac1d130fd4 979 ho->ouraddr = ciaddr2;
mbed_official 0:51ac1d130fd4 980 break;
mbed_official 0:51ac1d130fd4 981 #endif
mbed_official 0:51ac1d130fd4 982
mbed_official 0:51ac1d130fd4 983 case CI_ADDR:
mbed_official 0:51ac1d130fd4 984 if (!ao->neg_addr) {
mbed_official 0:51ac1d130fd4 985 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR not allowed\n"));
mbed_official 0:51ac1d130fd4 986 orc = CONFREJ; /* Reject CI */
mbed_official 0:51ac1d130fd4 987 break;
mbed_official 0:51ac1d130fd4 988 } else if (cilen != CILEN_ADDR) { /* Check CI length */
mbed_official 0:51ac1d130fd4 989 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR bad len\n"));
mbed_official 0:51ac1d130fd4 990 orc = CONFREJ; /* Reject CI */
mbed_official 0:51ac1d130fd4 991 break;
mbed_official 0:51ac1d130fd4 992 }
mbed_official 0:51ac1d130fd4 993
mbed_official 0:51ac1d130fd4 994 /*
mbed_official 0:51ac1d130fd4 995 * If he has no address, or if we both have his address but
mbed_official 0:51ac1d130fd4 996 * disagree about it, then NAK it with our idea.
mbed_official 0:51ac1d130fd4 997 * In particular, if we don't know his address, but he does,
mbed_official 0:51ac1d130fd4 998 * then accept it.
mbed_official 0:51ac1d130fd4 999 */
mbed_official 0:51ac1d130fd4 1000 GETLONG(tl, p); /* Parse source address (his) */
mbed_official 0:51ac1d130fd4 1001 ciaddr1 = htonl(tl);
mbed_official 0:51ac1d130fd4 1002 if (ciaddr1 != wo->hisaddr
mbed_official 0:51ac1d130fd4 1003 && (ciaddr1 == 0 || !wo->accept_remote)) {
mbed_official 0:51ac1d130fd4 1004 orc = CONFNAK;
mbed_official 0:51ac1d130fd4 1005 if (!reject_if_disagree) {
mbed_official 0:51ac1d130fd4 1006 DECPTR(sizeof(u32_t), p);
mbed_official 0:51ac1d130fd4 1007 tl = ntohl(wo->hisaddr);
mbed_official 0:51ac1d130fd4 1008 PUTLONG(tl, p);
mbed_official 0:51ac1d130fd4 1009 }
mbed_official 0:51ac1d130fd4 1010 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1)));
mbed_official 0:51ac1d130fd4 1011 } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
mbed_official 0:51ac1d130fd4 1012 /*
mbed_official 0:51ac1d130fd4 1013 * Don't ACK an address of 0.0.0.0 - reject it instead.
mbed_official 0:51ac1d130fd4 1014 */
mbed_official 0:51ac1d130fd4 1015 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1)));
mbed_official 0:51ac1d130fd4 1016 orc = CONFREJ;
mbed_official 0:51ac1d130fd4 1017 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
mbed_official 0:51ac1d130fd4 1018 break;
mbed_official 0:51ac1d130fd4 1019 }
mbed_official 0:51ac1d130fd4 1020
mbed_official 0:51ac1d130fd4 1021 ho->neg_addr = 1;
mbed_official 0:51ac1d130fd4 1022 ho->hisaddr = ciaddr1;
mbed_official 0:51ac1d130fd4 1023 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1)));
mbed_official 0:51ac1d130fd4 1024 break;
mbed_official 0:51ac1d130fd4 1025
mbed_official 0:51ac1d130fd4 1026 case CI_MS_DNS1:
mbed_official 0:51ac1d130fd4 1027 case CI_MS_DNS2:
mbed_official 0:51ac1d130fd4 1028 /* Microsoft primary or secondary DNS request */
mbed_official 0:51ac1d130fd4 1029 d = citype == CI_MS_DNS2;
mbed_official 0:51ac1d130fd4 1030
mbed_official 0:51ac1d130fd4 1031 /* If we do not have a DNS address then we cannot send it */
mbed_official 0:51ac1d130fd4 1032 if (ao->dnsaddr[d] == 0 ||
mbed_official 0:51ac1d130fd4 1033 cilen != CILEN_ADDR) { /* Check CI length */
mbed_official 0:51ac1d130fd4 1034 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting DNS%d Request\n", d+1));
mbed_official 0:51ac1d130fd4 1035 orc = CONFREJ; /* Reject CI */
mbed_official 0:51ac1d130fd4 1036 break;
mbed_official 0:51ac1d130fd4 1037 }
mbed_official 0:51ac1d130fd4 1038 GETLONG(tl, p);
mbed_official 0:51ac1d130fd4 1039 if (htonl(tl) != ao->dnsaddr[d]) {
mbed_official 0:51ac1d130fd4 1040 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking DNS%d Request %s\n",
mbed_official 0:51ac1d130fd4 1041 d+1, inet_ntoa(tl)));
mbed_official 0:51ac1d130fd4 1042 DECPTR(sizeof(u32_t), p);
mbed_official 0:51ac1d130fd4 1043 tl = ntohl(ao->dnsaddr[d]);
mbed_official 0:51ac1d130fd4 1044 PUTLONG(tl, p);
mbed_official 0:51ac1d130fd4 1045 orc = CONFNAK;
mbed_official 0:51ac1d130fd4 1046 }
mbed_official 0:51ac1d130fd4 1047 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received DNS%d Request\n", d+1));
mbed_official 0:51ac1d130fd4 1048 break;
mbed_official 0:51ac1d130fd4 1049
mbed_official 0:51ac1d130fd4 1050 case CI_MS_WINS1:
mbed_official 0:51ac1d130fd4 1051 case CI_MS_WINS2:
mbed_official 0:51ac1d130fd4 1052 /* Microsoft primary or secondary WINS request */
mbed_official 0:51ac1d130fd4 1053 d = citype == CI_MS_WINS2;
mbed_official 0:51ac1d130fd4 1054 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received WINS%d Request\n", d+1));
mbed_official 0:51ac1d130fd4 1055
mbed_official 0:51ac1d130fd4 1056 /* If we do not have a DNS address then we cannot send it */
mbed_official 0:51ac1d130fd4 1057 if (ao->winsaddr[d] == 0 ||
mbed_official 0:51ac1d130fd4 1058 cilen != CILEN_ADDR) { /* Check CI length */
mbed_official 0:51ac1d130fd4 1059 orc = CONFREJ; /* Reject CI */
mbed_official 0:51ac1d130fd4 1060 break;
mbed_official 0:51ac1d130fd4 1061 }
mbed_official 0:51ac1d130fd4 1062 GETLONG(tl, p);
mbed_official 0:51ac1d130fd4 1063 if (htonl(tl) != ao->winsaddr[d]) {
mbed_official 0:51ac1d130fd4 1064 DECPTR(sizeof(u32_t), p);
mbed_official 0:51ac1d130fd4 1065 tl = ntohl(ao->winsaddr[d]);
mbed_official 0:51ac1d130fd4 1066 PUTLONG(tl, p);
mbed_official 0:51ac1d130fd4 1067 orc = CONFNAK;
mbed_official 0:51ac1d130fd4 1068 }
mbed_official 0:51ac1d130fd4 1069 break;
mbed_official 0:51ac1d130fd4 1070
mbed_official 0:51ac1d130fd4 1071 case CI_COMPRESSTYPE:
mbed_official 0:51ac1d130fd4 1072 if (!ao->neg_vj) {
mbed_official 0:51ac1d130fd4 1073 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n"));
mbed_official 0:51ac1d130fd4 1074 orc = CONFREJ;
mbed_official 0:51ac1d130fd4 1075 break;
mbed_official 0:51ac1d130fd4 1076 } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {
mbed_official 0:51ac1d130fd4 1077 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen));
mbed_official 0:51ac1d130fd4 1078 orc = CONFREJ;
mbed_official 0:51ac1d130fd4 1079 break;
mbed_official 0:51ac1d130fd4 1080 }
mbed_official 0:51ac1d130fd4 1081 GETSHORT(cishort, p);
mbed_official 0:51ac1d130fd4 1082
mbed_official 0:51ac1d130fd4 1083 if (!(cishort == IPCP_VJ_COMP ||
mbed_official 0:51ac1d130fd4 1084 (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
mbed_official 0:51ac1d130fd4 1085 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort));
mbed_official 0:51ac1d130fd4 1086 orc = CONFREJ;
mbed_official 0:51ac1d130fd4 1087 break;
mbed_official 0:51ac1d130fd4 1088 }
mbed_official 0:51ac1d130fd4 1089
mbed_official 0:51ac1d130fd4 1090 ho->neg_vj = 1;
mbed_official 0:51ac1d130fd4 1091 ho->vj_protocol = cishort;
mbed_official 0:51ac1d130fd4 1092 if (cilen == CILEN_VJ) {
mbed_official 0:51ac1d130fd4 1093 GETCHAR(maxslotindex, p);
mbed_official 0:51ac1d130fd4 1094 if (maxslotindex > ao->maxslotindex) {
mbed_official 0:51ac1d130fd4 1095 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ max slot %d\n", maxslotindex));
mbed_official 0:51ac1d130fd4 1096 orc = CONFNAK;
mbed_official 0:51ac1d130fd4 1097 if (!reject_if_disagree) {
mbed_official 0:51ac1d130fd4 1098 DECPTR(1, p);
mbed_official 0:51ac1d130fd4 1099 PUTCHAR(ao->maxslotindex, p);
mbed_official 0:51ac1d130fd4 1100 }
mbed_official 0:51ac1d130fd4 1101 }
mbed_official 0:51ac1d130fd4 1102 GETCHAR(cflag, p);
mbed_official 0:51ac1d130fd4 1103 if (cflag && !ao->cflag) {
mbed_official 0:51ac1d130fd4 1104 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ cflag %d\n", cflag));
mbed_official 0:51ac1d130fd4 1105 orc = CONFNAK;
mbed_official 0:51ac1d130fd4 1106 if (!reject_if_disagree) {
mbed_official 0:51ac1d130fd4 1107 DECPTR(1, p);
mbed_official 0:51ac1d130fd4 1108 PUTCHAR(wo->cflag, p);
mbed_official 0:51ac1d130fd4 1109 }
mbed_official 0:51ac1d130fd4 1110 }
mbed_official 0:51ac1d130fd4 1111 ho->maxslotindex = maxslotindex;
mbed_official 0:51ac1d130fd4 1112 ho->cflag = cflag;
mbed_official 0:51ac1d130fd4 1113 } else {
mbed_official 0:51ac1d130fd4 1114 ho->old_vj = 1;
mbed_official 0:51ac1d130fd4 1115 ho->maxslotindex = MAX_SLOTS - 1;
mbed_official 0:51ac1d130fd4 1116 ho->cflag = 1;
mbed_official 0:51ac1d130fd4 1117 }
mbed_official 0:51ac1d130fd4 1118 IPCPDEBUG(LOG_INFO, (
mbed_official 0:51ac1d130fd4 1119 "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n",
mbed_official 0:51ac1d130fd4 1120 ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag));
mbed_official 0:51ac1d130fd4 1121 break;
mbed_official 0:51ac1d130fd4 1122
mbed_official 0:51ac1d130fd4 1123 default:
mbed_official 0:51ac1d130fd4 1124 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting unknown CI type %d\n", citype));
mbed_official 0:51ac1d130fd4 1125 orc = CONFREJ;
mbed_official 0:51ac1d130fd4 1126 break;
mbed_official 0:51ac1d130fd4 1127 }
mbed_official 0:51ac1d130fd4 1128
mbed_official 0:51ac1d130fd4 1129 endswitch:
mbed_official 0:51ac1d130fd4 1130 if (orc == CONFACK && /* Good CI */
mbed_official 0:51ac1d130fd4 1131 rc != CONFACK) { /* but prior CI wasnt? */
mbed_official 0:51ac1d130fd4 1132 continue; /* Don't send this one */
mbed_official 0:51ac1d130fd4 1133 }
mbed_official 0:51ac1d130fd4 1134
mbed_official 0:51ac1d130fd4 1135 if (orc == CONFNAK) { /* Nak this CI? */
mbed_official 0:51ac1d130fd4 1136 if (reject_if_disagree) { /* Getting fed up with sending NAKs? */
mbed_official 0:51ac1d130fd4 1137 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting too many naks\n"));
mbed_official 0:51ac1d130fd4 1138 orc = CONFREJ; /* Get tough if so */
mbed_official 0:51ac1d130fd4 1139 } else {
mbed_official 0:51ac1d130fd4 1140 if (rc == CONFREJ) { /* Rejecting prior CI? */
mbed_official 0:51ac1d130fd4 1141 continue; /* Don't send this one */
mbed_official 0:51ac1d130fd4 1142 }
mbed_official 0:51ac1d130fd4 1143 if (rc == CONFACK) { /* Ack'd all prior CIs? */
mbed_official 0:51ac1d130fd4 1144 rc = CONFNAK; /* Not anymore... */
mbed_official 0:51ac1d130fd4 1145 ucp = inp; /* Backup */
mbed_official 0:51ac1d130fd4 1146 }
mbed_official 0:51ac1d130fd4 1147 }
mbed_official 0:51ac1d130fd4 1148 }
mbed_official 0:51ac1d130fd4 1149
mbed_official 0:51ac1d130fd4 1150 if (orc == CONFREJ && /* Reject this CI */
mbed_official 0:51ac1d130fd4 1151 rc != CONFREJ) { /* but no prior ones? */
mbed_official 0:51ac1d130fd4 1152 rc = CONFREJ;
mbed_official 0:51ac1d130fd4 1153 ucp = inp; /* Backup */
mbed_official 0:51ac1d130fd4 1154 }
mbed_official 0:51ac1d130fd4 1155
mbed_official 0:51ac1d130fd4 1156 /* Need to move CI? */
mbed_official 0:51ac1d130fd4 1157 if (ucp != cip) {
mbed_official 0:51ac1d130fd4 1158 BCOPY(cip, ucp, cilen); /* Move it */
mbed_official 0:51ac1d130fd4 1159 }
mbed_official 0:51ac1d130fd4 1160
mbed_official 0:51ac1d130fd4 1161 /* Update output pointer */
mbed_official 0:51ac1d130fd4 1162 INCPTR(cilen, ucp);
mbed_official 0:51ac1d130fd4 1163 }
mbed_official 0:51ac1d130fd4 1164
mbed_official 0:51ac1d130fd4 1165 /*
mbed_official 0:51ac1d130fd4 1166 * If we aren't rejecting this packet, and we want to negotiate
mbed_official 0:51ac1d130fd4 1167 * their address, and they didn't send their address, then we
mbed_official 0:51ac1d130fd4 1168 * send a NAK with a CI_ADDR option appended. We assume the
mbed_official 0:51ac1d130fd4 1169 * input buffer is long enough that we can append the extra
mbed_official 0:51ac1d130fd4 1170 * option safely.
mbed_official 0:51ac1d130fd4 1171 */
mbed_official 0:51ac1d130fd4 1172 if (rc != CONFREJ && !ho->neg_addr &&
mbed_official 0:51ac1d130fd4 1173 wo->req_addr && !reject_if_disagree) {
mbed_official 0:51ac1d130fd4 1174 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Requesting peer address\n"));
mbed_official 0:51ac1d130fd4 1175 if (rc == CONFACK) {
mbed_official 0:51ac1d130fd4 1176 rc = CONFNAK;
mbed_official 0:51ac1d130fd4 1177 ucp = inp; /* reset pointer */
mbed_official 0:51ac1d130fd4 1178 wo->req_addr = 0; /* don't ask again */
mbed_official 0:51ac1d130fd4 1179 }
mbed_official 0:51ac1d130fd4 1180 PUTCHAR(CI_ADDR, ucp);
mbed_official 0:51ac1d130fd4 1181 PUTCHAR(CILEN_ADDR, ucp);
mbed_official 0:51ac1d130fd4 1182 tl = ntohl(wo->hisaddr);
mbed_official 0:51ac1d130fd4 1183 PUTLONG(tl, ucp);
mbed_official 0:51ac1d130fd4 1184 }
mbed_official 0:51ac1d130fd4 1185
mbed_official 0:51ac1d130fd4 1186 *len = (int)(ucp - inp); /* Compute output length */
mbed_official 0:51ac1d130fd4 1187 IPCPDEBUG(LOG_INFO, ("ipcp_reqci: returning Configure-%s\n", CODENAME(rc)));
mbed_official 0:51ac1d130fd4 1188 return (rc); /* Return final code */
mbed_official 0:51ac1d130fd4 1189 }
mbed_official 0:51ac1d130fd4 1190
mbed_official 0:51ac1d130fd4 1191
mbed_official 0:51ac1d130fd4 1192 #if 0
mbed_official 0:51ac1d130fd4 1193 /*
mbed_official 0:51ac1d130fd4 1194 * ip_check_options - check that any IP-related options are OK,
mbed_official 0:51ac1d130fd4 1195 * and assign appropriate defaults.
mbed_official 0:51ac1d130fd4 1196 */
mbed_official 0:51ac1d130fd4 1197 static void
mbed_official 0:51ac1d130fd4 1198 ip_check_options(u_long localAddr)
mbed_official 0:51ac1d130fd4 1199 {
mbed_official 0:51ac1d130fd4 1200 ipcp_options *wo = &ipcp_wantoptions[0];
mbed_official 0:51ac1d130fd4 1201
mbed_official 0:51ac1d130fd4 1202 /*
mbed_official 0:51ac1d130fd4 1203 * Load our default IP address but allow the remote host to give us
mbed_official 0:51ac1d130fd4 1204 * a new address.
mbed_official 0:51ac1d130fd4 1205 */
mbed_official 0:51ac1d130fd4 1206 if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) {
mbed_official 0:51ac1d130fd4 1207 wo->accept_local = 1; /* don't insist on this default value */
mbed_official 0:51ac1d130fd4 1208 wo->ouraddr = htonl(localAddr);
mbed_official 0:51ac1d130fd4 1209 }
mbed_official 0:51ac1d130fd4 1210 }
mbed_official 0:51ac1d130fd4 1211 #endif
mbed_official 0:51ac1d130fd4 1212
mbed_official 0:51ac1d130fd4 1213
mbed_official 0:51ac1d130fd4 1214 /*
mbed_official 0:51ac1d130fd4 1215 * ipcp_up - IPCP has come UP.
mbed_official 0:51ac1d130fd4 1216 *
mbed_official 0:51ac1d130fd4 1217 * Configure the IP network interface appropriately and bring it up.
mbed_official 0:51ac1d130fd4 1218 */
mbed_official 0:51ac1d130fd4 1219 static void
mbed_official 0:51ac1d130fd4 1220 ipcp_up(fsm *f)
mbed_official 0:51ac1d130fd4 1221 {
mbed_official 0:51ac1d130fd4 1222 u32_t mask;
mbed_official 0:51ac1d130fd4 1223 ipcp_options *ho = &ipcp_hisoptions[f->unit];
mbed_official 0:51ac1d130fd4 1224 ipcp_options *go = &ipcp_gotoptions[f->unit];
mbed_official 0:51ac1d130fd4 1225 ipcp_options *wo = &ipcp_wantoptions[f->unit];
mbed_official 0:51ac1d130fd4 1226
mbed_official 0:51ac1d130fd4 1227 np_up(f->unit, PPP_IP);
mbed_official 0:51ac1d130fd4 1228 IPCPDEBUG(LOG_INFO, ("ipcp: up\n"));
mbed_official 0:51ac1d130fd4 1229
mbed_official 0:51ac1d130fd4 1230 /*
mbed_official 0:51ac1d130fd4 1231 * We must have a non-zero IP address for both ends of the link.
mbed_official 0:51ac1d130fd4 1232 */
mbed_official 0:51ac1d130fd4 1233 if (!ho->neg_addr) {
mbed_official 0:51ac1d130fd4 1234 ho->hisaddr = wo->hisaddr;
mbed_official 0:51ac1d130fd4 1235 }
mbed_official 0:51ac1d130fd4 1236
mbed_official 0:51ac1d130fd4 1237 if (ho->hisaddr == 0) {
donatien 4:f71f5d9d5846 1238 #if 0
mbed_official 0:51ac1d130fd4 1239 IPCPDEBUG(LOG_ERR, ("Could not determine remote IP address\n"));
mbed_official 0:51ac1d130fd4 1240 ipcp_close(f->unit, "Could not determine remote IP address");
mbed_official 0:51ac1d130fd4 1241 return;
donatien 4:f71f5d9d5846 1242 #else //Kludge
donatien 4:f71f5d9d5846 1243 ho->hisaddr = 0; //Set remote IP to 0.0.0.0, this is needed as most 3g providers do not advertise the remote IP to the user
donatien 4:f71f5d9d5846 1244 #endif
mbed_official 0:51ac1d130fd4 1245 }
mbed_official 0:51ac1d130fd4 1246 if (go->ouraddr == 0) {
mbed_official 0:51ac1d130fd4 1247 IPCPDEBUG(LOG_ERR, ("Could not determine local IP address\n"));
mbed_official 0:51ac1d130fd4 1248 ipcp_close(f->unit, "Could not determine local IP address");
mbed_official 0:51ac1d130fd4 1249 return;
mbed_official 0:51ac1d130fd4 1250 }
mbed_official 0:51ac1d130fd4 1251
mbed_official 0:51ac1d130fd4 1252 if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
mbed_official 0:51ac1d130fd4 1253 /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/
mbed_official 0:51ac1d130fd4 1254 }
mbed_official 0:51ac1d130fd4 1255
mbed_official 0:51ac1d130fd4 1256 /*
mbed_official 0:51ac1d130fd4 1257 * Check that the peer is allowed to use the IP address it wants.
mbed_official 0:51ac1d130fd4 1258 */
mbed_official 0:51ac1d130fd4 1259 if (!auth_ip_addr(f->unit, ho->hisaddr)) {
mbed_official 0:51ac1d130fd4 1260 IPCPDEBUG(LOG_ERR, ("Peer is not authorized to use remote address %s\n",
mbed_official 0:51ac1d130fd4 1261 inet_ntoa(ho->hisaddr)));
mbed_official 0:51ac1d130fd4 1262 ipcp_close(f->unit, "Unauthorized remote IP address");
mbed_official 0:51ac1d130fd4 1263 return;
mbed_official 0:51ac1d130fd4 1264 }
mbed_official 0:51ac1d130fd4 1265
mbed_official 0:51ac1d130fd4 1266 /* set tcp compression */
mbed_official 0:51ac1d130fd4 1267 sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);
mbed_official 0:51ac1d130fd4 1268
mbed_official 0:51ac1d130fd4 1269 /*
mbed_official 0:51ac1d130fd4 1270 * Set IP addresses and (if specified) netmask.
mbed_official 0:51ac1d130fd4 1271 */
mbed_official 0:51ac1d130fd4 1272 mask = GetMask(go->ouraddr);
mbed_official 0:51ac1d130fd4 1273
mbed_official 0:51ac1d130fd4 1274 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) {
mbed_official 0:51ac1d130fd4 1275 IPCPDEBUG(LOG_WARNING, ("sifaddr failed\n"));
mbed_official 0:51ac1d130fd4 1276 ipcp_close(f->unit, "Interface configuration failed");
mbed_official 0:51ac1d130fd4 1277 return;
mbed_official 0:51ac1d130fd4 1278 }
mbed_official 0:51ac1d130fd4 1279
mbed_official 0:51ac1d130fd4 1280 /* bring the interface up for IP */
mbed_official 0:51ac1d130fd4 1281 if (!sifup(f->unit)) {
mbed_official 0:51ac1d130fd4 1282 IPCPDEBUG(LOG_WARNING, ("sifup failed\n"));
mbed_official 0:51ac1d130fd4 1283 ipcp_close(f->unit, "Interface configuration failed");
mbed_official 0:51ac1d130fd4 1284 return;
mbed_official 0:51ac1d130fd4 1285 }
mbed_official 0:51ac1d130fd4 1286
mbed_official 0:51ac1d130fd4 1287 sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
mbed_official 0:51ac1d130fd4 1288
mbed_official 0:51ac1d130fd4 1289 /* assign a default route through the interface if required */
mbed_official 0:51ac1d130fd4 1290 if (ipcp_wantoptions[f->unit].default_route) {
mbed_official 0:51ac1d130fd4 1291 if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) {
mbed_official 0:51ac1d130fd4 1292 default_route_set[f->unit] = 1;
mbed_official 0:51ac1d130fd4 1293 }
mbed_official 0:51ac1d130fd4 1294 }
mbed_official 0:51ac1d130fd4 1295
mbed_official 0:51ac1d130fd4 1296 IPCPDEBUG(LOG_NOTICE, ("local IP address %s\n", inet_ntoa(go->ouraddr)));
mbed_official 0:51ac1d130fd4 1297 IPCPDEBUG(LOG_NOTICE, ("remote IP address %s\n", inet_ntoa(ho->hisaddr)));
mbed_official 0:51ac1d130fd4 1298 if (go->dnsaddr[0]) {
mbed_official 0:51ac1d130fd4 1299 IPCPDEBUG(LOG_NOTICE, ("primary DNS address %s\n", inet_ntoa(go->dnsaddr[0])));
mbed_official 0:51ac1d130fd4 1300 }
mbed_official 0:51ac1d130fd4 1301 if (go->dnsaddr[1]) {
mbed_official 0:51ac1d130fd4 1302 IPCPDEBUG(LOG_NOTICE, ("secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1])));
mbed_official 0:51ac1d130fd4 1303 }
mbed_official 0:51ac1d130fd4 1304 }
mbed_official 0:51ac1d130fd4 1305
mbed_official 0:51ac1d130fd4 1306
mbed_official 0:51ac1d130fd4 1307 /*
mbed_official 0:51ac1d130fd4 1308 * ipcp_down - IPCP has gone DOWN.
mbed_official 0:51ac1d130fd4 1309 *
mbed_official 0:51ac1d130fd4 1310 * Take the IP network interface down, clear its addresses
mbed_official 0:51ac1d130fd4 1311 * and delete routes through it.
mbed_official 0:51ac1d130fd4 1312 */
mbed_official 0:51ac1d130fd4 1313 static void
mbed_official 0:51ac1d130fd4 1314 ipcp_down(fsm *f)
mbed_official 0:51ac1d130fd4 1315 {
mbed_official 0:51ac1d130fd4 1316 IPCPDEBUG(LOG_INFO, ("ipcp: down\n"));
mbed_official 0:51ac1d130fd4 1317 np_down(f->unit, PPP_IP);
mbed_official 0:51ac1d130fd4 1318 sifvjcomp(f->unit, 0, 0, 0);
mbed_official 0:51ac1d130fd4 1319
mbed_official 0:51ac1d130fd4 1320 sifdown(f->unit);
mbed_official 0:51ac1d130fd4 1321 ipcp_clear_addrs(f->unit);
mbed_official 0:51ac1d130fd4 1322 }
mbed_official 0:51ac1d130fd4 1323
mbed_official 0:51ac1d130fd4 1324
mbed_official 0:51ac1d130fd4 1325 /*
mbed_official 0:51ac1d130fd4 1326 * ipcp_clear_addrs() - clear the interface addresses, routes, etc.
mbed_official 0:51ac1d130fd4 1327 */
mbed_official 0:51ac1d130fd4 1328 static void
mbed_official 0:51ac1d130fd4 1329 ipcp_clear_addrs(int unit)
mbed_official 0:51ac1d130fd4 1330 {
mbed_official 0:51ac1d130fd4 1331 u32_t ouraddr, hisaddr;
mbed_official 0:51ac1d130fd4 1332
mbed_official 0:51ac1d130fd4 1333 ouraddr = ipcp_gotoptions[unit].ouraddr;
mbed_official 0:51ac1d130fd4 1334 hisaddr = ipcp_hisoptions[unit].hisaddr;
mbed_official 0:51ac1d130fd4 1335 if (default_route_set[unit]) {
mbed_official 0:51ac1d130fd4 1336 cifdefaultroute(unit, ouraddr, hisaddr);
mbed_official 0:51ac1d130fd4 1337 default_route_set[unit] = 0;
mbed_official 0:51ac1d130fd4 1338 }
mbed_official 0:51ac1d130fd4 1339 cifaddr(unit, ouraddr, hisaddr);
mbed_official 0:51ac1d130fd4 1340 }
mbed_official 0:51ac1d130fd4 1341
mbed_official 0:51ac1d130fd4 1342
mbed_official 0:51ac1d130fd4 1343 /*
mbed_official 0:51ac1d130fd4 1344 * ipcp_finished - possibly shut down the lower layers.
mbed_official 0:51ac1d130fd4 1345 */
mbed_official 0:51ac1d130fd4 1346 static void
mbed_official 0:51ac1d130fd4 1347 ipcp_finished(fsm *f)
mbed_official 0:51ac1d130fd4 1348 {
mbed_official 0:51ac1d130fd4 1349 np_finished(f->unit, PPP_IP);
mbed_official 0:51ac1d130fd4 1350 }
mbed_official 0:51ac1d130fd4 1351
mbed_official 0:51ac1d130fd4 1352 #if PPP_ADDITIONAL_CALLBACKS
mbed_official 0:51ac1d130fd4 1353 static int
mbed_official 0:51ac1d130fd4 1354 ipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg)
mbed_official 0:51ac1d130fd4 1355 {
mbed_official 0:51ac1d130fd4 1356 LWIP_UNUSED_ARG(p);
mbed_official 0:51ac1d130fd4 1357 LWIP_UNUSED_ARG(plen);
mbed_official 0:51ac1d130fd4 1358 LWIP_UNUSED_ARG(printer);
mbed_official 0:51ac1d130fd4 1359 LWIP_UNUSED_ARG(arg);
mbed_official 0:51ac1d130fd4 1360 return 0;
mbed_official 0:51ac1d130fd4 1361 }
mbed_official 0:51ac1d130fd4 1362
mbed_official 0:51ac1d130fd4 1363 /*
mbed_official 0:51ac1d130fd4 1364 * ip_active_pkt - see if this IP packet is worth bringing the link up for.
mbed_official 0:51ac1d130fd4 1365 * We don't bring the link up for IP fragments or for TCP FIN packets
mbed_official 0:51ac1d130fd4 1366 * with no data.
mbed_official 0:51ac1d130fd4 1367 */
mbed_official 0:51ac1d130fd4 1368 #define IP_HDRLEN 20 /* bytes */
mbed_official 0:51ac1d130fd4 1369 #define IP_OFFMASK 0x1fff
mbed_official 0:51ac1d130fd4 1370 #define IPPROTO_TCP 6
mbed_official 0:51ac1d130fd4 1371 #define TCP_HDRLEN 20
mbed_official 0:51ac1d130fd4 1372 #define TH_FIN 0x01
mbed_official 0:51ac1d130fd4 1373
mbed_official 0:51ac1d130fd4 1374 /*
mbed_official 0:51ac1d130fd4 1375 * We use these macros because the IP header may be at an odd address,
mbed_official 0:51ac1d130fd4 1376 * and some compilers might use word loads to get th_off or ip_hl.
mbed_official 0:51ac1d130fd4 1377 */
mbed_official 0:51ac1d130fd4 1378
mbed_official 0:51ac1d130fd4 1379 #define net_short(x) (((x)[0] << 8) + (x)[1])
mbed_official 0:51ac1d130fd4 1380 #define get_iphl(x) (((unsigned char *)(x))[0] & 0xF)
mbed_official 0:51ac1d130fd4 1381 #define get_ipoff(x) net_short((unsigned char *)(x) + 6)
mbed_official 0:51ac1d130fd4 1382 #define get_ipproto(x) (((unsigned char *)(x))[9])
mbed_official 0:51ac1d130fd4 1383 #define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4)
mbed_official 0:51ac1d130fd4 1384 #define get_tcpflags(x) (((unsigned char *)(x))[13])
mbed_official 0:51ac1d130fd4 1385
mbed_official 0:51ac1d130fd4 1386 static int
mbed_official 0:51ac1d130fd4 1387 ip_active_pkt(u_char *pkt, int len)
mbed_official 0:51ac1d130fd4 1388 {
mbed_official 0:51ac1d130fd4 1389 u_char *tcp;
mbed_official 0:51ac1d130fd4 1390 int hlen;
mbed_official 0:51ac1d130fd4 1391
mbed_official 0:51ac1d130fd4 1392 len -= PPP_HDRLEN;
mbed_official 0:51ac1d130fd4 1393 pkt += PPP_HDRLEN;
mbed_official 0:51ac1d130fd4 1394 if (len < IP_HDRLEN) {
mbed_official 0:51ac1d130fd4 1395 return 0;
mbed_official 0:51ac1d130fd4 1396 }
mbed_official 0:51ac1d130fd4 1397 if ((get_ipoff(pkt) & IP_OFFMASK) != 0) {
mbed_official 0:51ac1d130fd4 1398 return 0;
mbed_official 0:51ac1d130fd4 1399 }
mbed_official 0:51ac1d130fd4 1400 if (get_ipproto(pkt) != IPPROTO_TCP) {
mbed_official 0:51ac1d130fd4 1401 return 1;
mbed_official 0:51ac1d130fd4 1402 }
mbed_official 0:51ac1d130fd4 1403 hlen = get_iphl(pkt) * 4;
mbed_official 0:51ac1d130fd4 1404 if (len < hlen + TCP_HDRLEN) {
mbed_official 0:51ac1d130fd4 1405 return 0;
mbed_official 0:51ac1d130fd4 1406 }
mbed_official 0:51ac1d130fd4 1407 tcp = pkt + hlen;
mbed_official 0:51ac1d130fd4 1408 if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) {
mbed_official 0:51ac1d130fd4 1409 return 0;
mbed_official 0:51ac1d130fd4 1410 }
mbed_official 0:51ac1d130fd4 1411 return 1;
mbed_official 0:51ac1d130fd4 1412 }
mbed_official 0:51ac1d130fd4 1413 #endif /* PPP_ADDITIONAL_CALLBACKS */
mbed_official 0:51ac1d130fd4 1414
mbed_official 0:51ac1d130fd4 1415 #endif /* PPP_SUPPORT */