176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** In contrast to pppd 2.3.1, DNS support has been added, proxy-ARP and 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dial-on-demand has been stripped. */ 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/***************************************************************************** 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* ipcp.c - Network PPP IP Control Protocol program file. 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* portions Copyright (c) 1997 by Global Election Systems Inc. 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* The authors hereby grant permission to use, copy, modify, distribute, 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* and license this software and its documentation for any purpose, provided 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* that existing copyright notices are retained in all copies and that this 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* notice and the following disclaimer are included verbatim in any 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* distributions. No written agreement, license, or royalty fee is required 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* for any of the authorized uses. 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman****************************************************************************** 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* REVISION HISTORY 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 03-01-01 Marc Boucher <marc@mbsi.ca> 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* Ported to lwIP. 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc. 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* Original. 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*****************************************************************************/ 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp.c - PPP IP Control Protocol. 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (c) 1989 Carnegie Mellon University. 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * All rights reserved. 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Redistribution and use in source and binary forms are permitted 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * provided that the above copyright notice and this paragraph are 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * duplicated in all such forms and that any documentation, 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * advertising materials, and other materials related to such 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * distribution and use acknowledge that the software was developed 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * by Carnegie Mellon University. The name of the 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * University may not be used to endorse or promote products derived 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * from this software without specific prior written permission. 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lwip/opt.h" 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "ppp.h" 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "pppdebug.h" 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "auth.h" 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "fsm.h" 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "vj.h" 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "ipcp.h" 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lwip/inet.h" 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h> 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* #define OLD_CI_ADDRS 1 */ /* Support deprecated address negotiation. */ 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* global vars */ 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* local vars */ 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int default_route_set[NUM_PPP]; /* Have set up a default route */ 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int cis_received[NUM_PPP]; /* # Conf-Reqs received */ 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Callbacks for fsm code. (CI = Configuration Information) 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_resetci (fsm *); /* Reset our CI */ 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ipcp_cilen (fsm *); /* Return length of our CI */ 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */ 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */ 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ipcp_nakci (fsm *, u_char *, int); /* Peer nak'd our CI */ 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */ 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */ 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_up (fsm *); /* We're UP */ 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_down (fsm *); /* We're DOWN */ 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if PPP_ADDITIONAL_CALLBACKS 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_script (fsm *, char *); /* Run an up/down script */ 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_finished (fsm *); /* Don't need lower layer */ 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_resetci, /* Reset our Configuration Information */ 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_cilen, /* Length of our Configuration Information */ 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_addci, /* Add our Configuration Information */ 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_ackci, /* ACK our Configuration Information */ 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_nakci, /* NAK our Configuration Information */ 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_rejci, /* Reject our Configuration Information */ 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_reqci, /* Request peer's Configuration Information */ 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_up, /* Called when fsm reaches LS_OPENED state */ 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_down, /* Called when fsm leaves LS_OPENED state */ 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NULL, /* Called when we want the lower layer up */ 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_finished, /* Called when we want the lower layer down */ 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NULL, /* Called when Protocol-Reject received */ 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NULL, /* Retransmission is necessary */ 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NULL, /* Called to handle protocol-specific codes */ 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "IPCP" /* String name of protocol */ 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Protocol entry points from main code. 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_init (int); 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_open (int); 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_close (int, char *); 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_lowerup (int); 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_lowerdown (int); 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_input (int, u_char *, int); 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_protrej (int); 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct protent ipcp_protent = { 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PPP_IPCP, 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_init, 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_input, 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_protrej, 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_lowerup, 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_lowerdown, 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_open, 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_close, 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if PPP_ADDITIONAL_CALLBACKS 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_printpkt, 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NULL, 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* PPP_ADDITIONAL_CALLBACKS */ 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1, 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "IPCP", 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if PPP_ADDITIONAL_CALLBACKS 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ip_check_options, 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NULL, 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ip_active_pkt 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* PPP_ADDITIONAL_CALLBACKS */ 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void ipcp_clear_addrs (int); 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Lengths of configuration options. 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define CILEN_VOID 2 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define CILEN_ADDR 6 /* new-style single address option */ 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define CILEN_ADDRS 10 /* old-style dual address option */ 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (x) == CONFNAK ? "NAK" : "REJ") 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_init - Initialize IPCP. 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_init(int unit) 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fsm *f = &ipcp_fsm[unit]; 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *wo = &ipcp_wantoptions[unit]; 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *ao = &ipcp_allowoptions[unit]; 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman f->unit = unit; 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman f->protocol = PPP_IPCP; 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman f->callbacks = &ipcp_callbacks; 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fsm_init(&ipcp_fsm[unit]); 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset(wo, 0, sizeof(*wo)); 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset(ao, 0, sizeof(*ao)); 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->neg_addr = 1; 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->ouraddr = 0; 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if VJ_SUPPORT 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->neg_vj = 1; 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#else /* VJ_SUPPORT */ 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->neg_vj = 0; 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* VJ_SUPPORT */ 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->vj_protocol = IPCP_VJ_COMP; 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->maxslotindex = MAX_SLOTS - 1; 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->cflag = 0; 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->default_route = 1; 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ao->neg_addr = 1; 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if VJ_SUPPORT 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ao->neg_vj = 1; 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#else /* VJ_SUPPORT */ 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ao->neg_vj = 0; 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* VJ_SUPPORT */ 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ao->maxslotindex = MAX_SLOTS - 1; 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ao->cflag = 1; 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ao->default_route = 1; 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_open - IPCP is allowed to come up. 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_open(int unit) 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fsm_open(&ipcp_fsm[unit]); 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_close - Take IPCP down. 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_close(int unit, char *reason) 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fsm_close(&ipcp_fsm[unit], reason); 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_lowerup - The lower layer is up. 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_lowerup(int unit) 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fsm_lowerup(&ipcp_fsm[unit]); 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_lowerdown - The lower layer is down. 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_lowerdown(int unit) 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fsm_lowerdown(&ipcp_fsm[unit]); 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_input - Input IPCP packet. 25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_input(int unit, u_char *p, int len) 25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fsm_input(&ipcp_fsm[unit], p, len); 26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_protrej - A Protocol-Reject was received for IPCP. 26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Pretend the lower layer went down, so we shut up. 26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_protrej(int unit) 27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fsm_lowerdown(&ipcp_fsm[unit]); 27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_resetci - Reset our CI. 27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_resetci(fsm *f) 28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *wo = &ipcp_wantoptions[f->unit]; 28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr; 28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (wo->ouraddr == 0) { 28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->accept_local = 1; 28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (wo->hisaddr == 0) { 28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->accept_remote = 1; 29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Request DNS addresses from the peer */ 29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->req_dns1 = ppp_settings.usepeerdns; 29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->req_dns2 = ppp_settings.usepeerdns; 29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_gotoptions[f->unit] = *wo; 29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cis_received[f->unit] = 0; 29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_cilen - Return length of our CI. 30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_cilen(fsm *f) 30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *go = &ipcp_gotoptions[f->unit]; 30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *wo = &ipcp_wantoptions[f->unit]; 30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *ho = &ipcp_hisoptions[f->unit]; 30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) 31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0) 31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0) 31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * First see if we want to change our options to the old 31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * forms because we have received old forms from the peer. 31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (wo->neg_addr && !go->neg_addr && !go->old_addrs) { 31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* use the old style of address negotiation */ 31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->neg_addr = 1; 32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->old_addrs = 1; 32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (wo->neg_vj && !go->neg_vj && !go->old_vj) { 32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* try an older style of VJ negotiation */ 32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cis_received[f->unit] == 0) { 32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* keep trying the new style until we see some CI from the peer */ 32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->neg_vj = 1; 32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* use the old style only if the peer did */ 32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ho->neg_vj && ho->old_vj) { 33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->neg_vj = 1; 33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->old_vj = 1; 33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->vj_protocol = ho->vj_protocol; 33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (LENCIADDR(go->neg_addr, go->old_addrs) + 33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LENCIVJ(go->neg_vj, go->old_vj) + 33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LENCIDNS(go->req_dns1) + 34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LENCIDNS(go->req_dns2)); 34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_addci - Add our desired CIs to a packet. 34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_addci(fsm *f, u_char *ucp, int *lenp) 34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *go = &ipcp_gotoptions[f->unit]; 35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int len = *lenp; 35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ 35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (neg) { \ 35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ 35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (len >= vjlen) { \ 35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(opt, ucp); \ 35876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(vjlen, ucp); \ 35976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTSHORT(val, ucp); \ 36076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!old) { \ 36176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(maxslotindex, ucp); \ 36276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(cflag, ucp); \ 36376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 36476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len -= vjlen; \ 36576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { \ 36676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman neg = 0; \ 36776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 36876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 36976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 37076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ADDCIADDR(opt, neg, old, val1, val2) \ 37176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (neg) { \ 37276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ 37376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (len >= addrlen) { \ 37476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t l; \ 37576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(opt, ucp); \ 37676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(addrlen, ucp); \ 37776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman l = ntohl(val1); \ 37876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTLONG(l, ucp); \ 37976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (old) { \ 38076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman l = ntohl(val2); \ 38176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTLONG(l, ucp); \ 38276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 38376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len -= addrlen; \ 38476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { \ 38576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman neg = 0; \ 38676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 38776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 38876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 38976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ADDCIDNS(opt, neg, addr) \ 39076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (neg) { \ 39176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (len >= CILEN_ADDR) { \ 39276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t l; \ 39376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(opt, ucp); \ 39476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(CILEN_ADDR, ucp); \ 39576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman l = ntohl(addr); \ 39676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTLONG(l, ucp); \ 39776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len -= CILEN_ADDR; \ 39876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { \ 39976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman neg = 0; \ 40076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 40176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 40276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 40376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, 40476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->old_addrs, go->ouraddr, go->hisaddr); 40576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 40676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, 40776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->maxslotindex, go->cflag); 40876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 40976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); 41076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 41176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); 41276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 41376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *lenp -= len; 41476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 41576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 41676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 41776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 41876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_ackci - Ack our CIs. 41976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 42076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Returns: 42176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 0 - Ack was bad. 42276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1 - Ack was good. 42376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 42476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 42576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_ackci(fsm *f, u_char *p, int len) 42676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 42776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *go = &ipcp_gotoptions[f->unit]; 42876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_short cilen, citype, cishort; 42976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t cilong; 43076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_char cimaxslotindex, cicflag; 43176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 43276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 43376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * CIs must be in exactly the same order that we sent... 43476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Check packet length and CI length at each step. 43576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If we find any deviations, then this packet is bad. 43676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 43776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 43876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ 43976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (neg) { \ 44076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ 44176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((len -= vjlen) < 0) { \ 44276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 44376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 44476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(citype, p); \ 44576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(cilen, p); \ 44676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cilen != vjlen || \ 44776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman citype != opt) { \ 44876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 44976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 45076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETSHORT(cishort, p); \ 45176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cishort != val) { \ 45276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 45376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 45476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!old) { \ 45576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(cimaxslotindex, p); \ 45676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cimaxslotindex != maxslotindex) { \ 45776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 45876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 45976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(cicflag, p); \ 46076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cicflag != cflag) { \ 46176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 46276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 46376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 46476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 46576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 46676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ACKCIADDR(opt, neg, old, val1, val2) \ 46776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (neg) { \ 46876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ 46976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t l; \ 47076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((len -= addrlen) < 0) { \ 47176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 47276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 47376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(citype, p); \ 47476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(cilen, p); \ 47576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cilen != addrlen || \ 47676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman citype != opt) { \ 47776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 47876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 47976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); \ 48076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cilong = htonl(l); \ 48176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (val1 != cilong) { \ 48276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 48376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 48476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (old) { \ 48576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); \ 48676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cilong = htonl(l); \ 48776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (val2 != cilong) { \ 48876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 48976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 49076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 49176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 49276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 49376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ACKCIDNS(opt, neg, addr) \ 49476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (neg) { \ 49576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t l; \ 49676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((len -= CILEN_ADDR) < 0) { \ 49776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 49876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 49976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(citype, p); \ 50076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(cilen, p); \ 50176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cilen != CILEN_ADDR || \ 50276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman citype != opt) { \ 50376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 50476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 50576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); \ 50676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cilong = htonl(l); \ 50776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (addr != cilong) { \ 50876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 50976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 51076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 51176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 51276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, 51376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->old_addrs, go->ouraddr, go->hisaddr); 51476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 51576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, 51676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->maxslotindex, go->cflag); 51776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 51876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); 51976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 52076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); 52176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 52276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 52376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If there are any remaining CIs, then this packet is bad. 52476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 52576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (len != 0) { 52676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; 52776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 52876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (1); 52976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 53076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbad: 53176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_ackci: received bad Ack!\n")); 53276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (0); 53376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 53476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 53576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 53676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_nakci - Peer has sent a NAK for some of our CIs. 53776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This should not modify any state if the Nak is bad 53876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * or if IPCP is in the LS_OPENED state. 53976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 54076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Returns: 54176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 0 - Nak was bad. 54276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1 - Nak was good. 54376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 54476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 54576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_nakci(fsm *f, u_char *p, int len) 54676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 54776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *go = &ipcp_gotoptions[f->unit]; 54876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_char cimaxslotindex, cicflag; 54976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_char citype, cilen, *next; 55076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_short cishort; 55176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t ciaddr1, ciaddr2, l, cidnsaddr; 55276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options no; /* options we've seen Naks for */ 55376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options try; /* options to request next time */ 55476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 55576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman BZERO(&no, sizeof(no)); 55676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try = *go; 55776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 55876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 55976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Any Nak'd CIs must be in exactly the same order that we sent. 56076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Check packet length and CI length at each step. 56176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If we find any deviations, then this packet is bad. 56276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 56376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define NAKCIADDR(opt, neg, old, code) \ 56476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->neg && \ 56576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \ 56676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p[1] == cilen && \ 56776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p[0] == opt) { \ 56876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len -= cilen; \ 56976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman INCPTR(2, p); \ 57076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); \ 57176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ciaddr1 = htonl(l); \ 57276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (old) { \ 57376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); \ 57476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ciaddr2 = htonl(l); \ 57576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman no.old_addrs = 1; \ 57676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { \ 57776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ciaddr2 = 0; \ 57876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 57976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman no.neg = 1; \ 58076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman code \ 58176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 58276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 58376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define NAKCIVJ(opt, neg, code) \ 58476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->neg && \ 58576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ 58676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len >= cilen && \ 58776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p[0] == opt) { \ 58876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len -= cilen; \ 58976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman INCPTR(2, p); \ 59076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETSHORT(cishort, p); \ 59176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman no.neg = 1; \ 59276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman code \ 59376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 59476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 59576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define NAKCIDNS(opt, neg, code) \ 59676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->neg && \ 59776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ((cilen = p[1]) == CILEN_ADDR) && \ 59876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len >= cilen && \ 59976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p[0] == opt) { \ 60076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len -= cilen; \ 60176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman INCPTR(2, p); \ 60276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); \ 60376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cidnsaddr = htonl(l); \ 60476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman no.neg = 1; \ 60576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman code \ 60676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 60776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 60876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 60976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Accept the peer's idea of {our,his} address, if different 61076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * from our idea, only if the accept_{local,remote} flag is set. 61176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 61276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs, 61376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->accept_local && ciaddr1) { /* Do we know our address? */ 61476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.ouraddr = ciaddr1; 61576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("local IP address %s\n", 61676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman inet_ntoa(ciaddr1))); 61776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 61876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->accept_remote && ciaddr2) { /* Does he know his? */ 61976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.hisaddr = ciaddr2; 62076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("remote IP address %s\n", 62176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman inet_ntoa(ciaddr2))); 62276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 62376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ); 62476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 62576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 62676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Accept the peer's value of maxslotindex provided that it 62776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * is less than what we asked for. Turn off slot-ID compression 62876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * if the peer wants. Send old-style compress-type option if 62976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * the peer wants. 63076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 63176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NAKCIVJ(CI_COMPRESSTYPE, neg_vj, 63276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cilen == CILEN_VJ) { 63376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(cimaxslotindex, p); 63476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(cicflag, p); 63576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cishort == IPCP_VJ_COMP) { 63676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.old_vj = 0; 63776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cimaxslotindex < go->maxslotindex) { 63876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.maxslotindex = cimaxslotindex; 63976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 64076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!cicflag) { 64176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.cflag = 0; 64276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 64376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 64476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.neg_vj = 0; 64576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 64676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 64776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { 64876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.old_vj = 1; 64976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.vj_protocol = cishort; 65076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 65176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.neg_vj = 0; 65276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 65376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 65476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ); 65576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 65676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NAKCIDNS(CI_MS_DNS1, req_dns1, 65776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.dnsaddr[0] = cidnsaddr; 65876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("primary DNS address %s\n", inet_ntoa(cidnsaddr))); 65976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ); 66076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 66176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NAKCIDNS(CI_MS_DNS2, req_dns2, 66276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.dnsaddr[1] = cidnsaddr; 66376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("secondary DNS address %s\n", inet_ntoa(cidnsaddr))); 66476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ); 66576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 66676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 66776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * There may be remaining CIs, if the peer is requesting negotiation 66876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * on an option that we didn't include in our request packet. 66976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If they want to negotiate about IP addresses, we comply. 67076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If they want us to ask for compression, we refuse. 67176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 67276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while (len > CILEN_VOID) { 67376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(citype, p); 67476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(cilen, p); 67576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if( (len -= cilen) < 0 ) { 67676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; 67776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 67876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman next = p + cilen - 2; 67976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 68076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman switch (citype) { 68176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case CI_COMPRESSTYPE: 68276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->neg_vj || no.neg_vj || 68376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { 68476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; 68576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 68676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman no.neg_vj = 1; 68776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 68876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case CI_ADDRS: 68976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((go->neg_addr && go->old_addrs) || no.old_addrs 69076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman || cilen != CILEN_ADDRS) { 69176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; 69276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 69376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.neg_addr = 1; 69476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.old_addrs = 1; 69576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); 69676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ciaddr1 = htonl(l); 69776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ciaddr1 && go->accept_local) { 69876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.ouraddr = ciaddr1; 69976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 70076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); 70176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ciaddr2 = htonl(l); 70276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ciaddr2 && go->accept_remote) { 70376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.hisaddr = ciaddr2; 70476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 70576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman no.old_addrs = 1; 70676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 70776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case CI_ADDR: 70876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) { 70976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; 71076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 71176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.old_addrs = 0; 71276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); 71376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ciaddr1 = htonl(l); 71476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ciaddr1 && go->accept_local) { 71576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.ouraddr = ciaddr1; 71676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 71776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (try.ouraddr != 0) { 71876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.neg_addr = 1; 71976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 72076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman no.neg_addr = 1; 72176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 72276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 72376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = next; 72476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 72576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 72676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* If there is still anything left, this packet is bad. */ 72776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (len != 0) { 72876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; 72976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 73076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 73176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 73276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * OK, the Nak is good. Now we can update state. 73376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 73476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (f->state != LS_OPENED) { 73576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *go = try; 73676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 73776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 73876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 73976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 74076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbad: 74176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_nakci: received bad Nak!\n")); 74276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 74376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 74476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 74576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 74676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 74776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_rejci - Reject some of our CIs. 74876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 74976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 75076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_rejci(fsm *f, u_char *p, int len) 75176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 75276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *go = &ipcp_gotoptions[f->unit]; 75376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_char cimaxslotindex, ciflag, cilen; 75476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_short cishort; 75576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t cilong; 75676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options try; /* options to request next time */ 75776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 75876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try = *go; 75976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 76076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Any Rejected CIs must be in exactly the same order that we sent. 76176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Check packet length and CI length at each step. 76276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If we find any deviations, then this packet is bad. 76376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 76476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define REJCIADDR(opt, neg, old, val1, val2) \ 76576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->neg && \ 76676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \ 76776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p[1] == cilen && \ 76876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p[0] == opt) { \ 76976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t l; \ 77076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len -= cilen; \ 77176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman INCPTR(2, p); \ 77276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); \ 77376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cilong = htonl(l); \ 77476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Check rejected value. */ \ 77576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cilong != val1) { \ 77676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 77776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 77876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (old) { \ 77976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); \ 78076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cilong = htonl(l); \ 78176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Check rejected value. */ \ 78276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cilong != val2) { \ 78376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 78476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 78576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 78676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.neg = 0; \ 78776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 78876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 78976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ 79076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->neg && \ 79176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ 79276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len >= p[1] && \ 79376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p[0] == opt) { \ 79476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len -= p[1]; \ 79576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman INCPTR(2, p); \ 79676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETSHORT(cishort, p); \ 79776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Check rejected value. */ \ 79876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cishort != val) { \ 79976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 80076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 80176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!old) { \ 80276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(cimaxslotindex, p); \ 80376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cimaxslotindex != maxslot) { \ 80476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 80576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 80676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(ciflag, p); \ 80776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ciflag != cflag) { \ 80876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 80976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 81076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 81176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.neg = 0; \ 81276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 81376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 81476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define REJCIDNS(opt, neg, dnsaddr) \ 81576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->neg && \ 81676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ((cilen = p[1]) == CILEN_ADDR) && \ 81776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len >= cilen && \ 81876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p[0] == opt) { \ 81976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t l; \ 82076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len -= cilen; \ 82176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman INCPTR(2, p); \ 82276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(l, p); \ 82376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cilong = htonl(l); \ 82476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Check rejected value. */ \ 82576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cilong != dnsaddr) { \ 82676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; \ 82776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } \ 82876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try.neg = 0; \ 82976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 83076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 83176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, 83276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->old_addrs, go->ouraddr, go->hisaddr); 83376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 83476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, 83576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->maxslotindex, go->cflag); 83676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 83776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); 83876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 83976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); 84076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 84176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 84276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If there are any remaining CIs, then this packet is bad. 84376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 84476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (len != 0) { 84576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bad; 84676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 84776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 84876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Now we can update state. 84976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 85076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (f->state != LS_OPENED) { 85176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *go = try; 85276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 85376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 85476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 85576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbad: 85676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_rejci: received bad Reject!\n")); 85776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 85876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 85976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 86076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 86176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 86276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_reqci - Check the peer's requested CIs and send appropriate response. 86376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 86476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified 86576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * appropriately. If reject_if_disagree is non-zero, doesn't return 86676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * CONFNAK; returns CONFREJ if it can't return CONFACK. 86776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 86876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 86976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested CIs */,int reject_if_disagree) 87076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 87176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *wo = &ipcp_wantoptions[f->unit]; 87276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *ho = &ipcp_hisoptions[f->unit]; 87376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *ao = &ipcp_allowoptions[f->unit]; 87476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef OLD_CI_ADDRS 87576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *go = &ipcp_gotoptions[f->unit]; 87676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 87776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_char *cip, *next; /* Pointer to current and next CIs */ 87876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_short cilen, citype; /* Parsed len, type */ 87976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_short cishort; /* Parsed short value */ 88076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t tl, ciaddr1; /* Parsed address values */ 88176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef OLD_CI_ADDRS 88276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t ciaddr2; /* Parsed address values */ 88376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 88476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int rc = CONFACK; /* Final packet return code */ 88576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int orc; /* Individual option return code */ 88676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_char *p; /* Pointer to next char to parse */ 88776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_char *ucp = inp; /* Pointer to current output char */ 88876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int l = *len; /* Length left */ 88976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_char maxslotindex, cflag; 89076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int d; 89176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 89276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cis_received[f->unit] = 1; 89376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 89476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 89576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Reset all his options. 89676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 89776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman BZERO(ho, sizeof(*ho)); 89876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 89976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 90076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Process all his options. 90176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 90276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman next = inp; 90376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while (l) { 90476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFACK; /* Assume success */ 90576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cip = p = next; /* Remember begining of CI */ 90676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (l < 2 || /* Not enough data for CI header or */ 90776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p[1] < 2 || /* CI length too small or */ 90876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p[1] > l) { /* CI length too big? */ 90976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: bad CI length!\n")); 91076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; /* Reject bad CI */ 91176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cilen = (u_short)l;/* Reject till end of packet */ 91276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman l = 0; /* Don't loop again */ 91376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto endswitch; 91476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 91576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(citype, p); /* Parse CI type */ 91676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(cilen, p); /* Parse CI length */ 91776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman l -= cilen; /* Adjust remaining length */ 91876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman next += cilen; /* Step to next CI */ 91976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 92076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman switch (citype) { /* Check CI type */ 92176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef OLD_CI_ADDRS /* Need to save space... */ 92276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case CI_ADDRS: 92376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received ADDRS\n")); 92476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!ao->neg_addr || 92576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cilen != CILEN_ADDRS) { /* Check CI length */ 92676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; /* Reject CI */ 92776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 92876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 92976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 93076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 93176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If he has no address, or if we both have his address but 93276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * disagree about it, then NAK it with our idea. 93376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * In particular, if we don't know his address, but he does, 93476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * then accept it. 93576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 93676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(tl, p); /* Parse source address (his) */ 93776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ciaddr1 = htonl(tl); 93876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("his addr %s\n", inet_ntoa(ciaddr1))); 93976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ciaddr1 != wo->hisaddr 94076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman && (ciaddr1 == 0 || !wo->accept_remote)) { 94176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFNAK; 94276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!reject_if_disagree) { 94376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DECPTR(sizeof(u32_t), p); 94476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tl = ntohl(wo->hisaddr); 94576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTLONG(tl, p); 94676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 94776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if (ciaddr1 == 0 && wo->hisaddr == 0) { 94876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 94976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If neither we nor he knows his address, reject the option. 95076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 95176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; 95276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ 95376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 95476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 95576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 95676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 95776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If he doesn't know our address, or if we both have our address 95876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * but disagree about it, then NAK it with our idea. 95976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 96076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(tl, p); /* Parse desination address (ours) */ 96176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ciaddr2 = htonl(tl); 96276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("our addr %s\n", inet_ntoa(ciaddr2))); 96376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ciaddr2 != wo->ouraddr) { 96476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ciaddr2 == 0 || !wo->accept_local) { 96576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFNAK; 96676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!reject_if_disagree) { 96776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DECPTR(sizeof(u32_t), p); 96876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tl = ntohl(wo->ouraddr); 96976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTLONG(tl, p); 97076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 97176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 97276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman go->ouraddr = ciaddr2; /* accept peer's idea */ 97376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 97476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 97576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 97676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->neg_addr = 1; 97776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->old_addrs = 1; 97876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->hisaddr = ciaddr1; 97976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->ouraddr = ciaddr2; 98076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 98176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 98276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 98376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case CI_ADDR: 98476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!ao->neg_addr) { 98576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR not allowed\n")); 98676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; /* Reject CI */ 98776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 98876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if (cilen != CILEN_ADDR) { /* Check CI length */ 98976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR bad len\n")); 99076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; /* Reject CI */ 99176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 99276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 99376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 99476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 99576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If he has no address, or if we both have his address but 99676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * disagree about it, then NAK it with our idea. 99776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * In particular, if we don't know his address, but he does, 99876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * then accept it. 99976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 100076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(tl, p); /* Parse source address (his) */ 100176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ciaddr1 = htonl(tl); 100276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ciaddr1 != wo->hisaddr 100376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman && (ciaddr1 == 0 || !wo->accept_remote)) { 100476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFNAK; 100576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!reject_if_disagree) { 100676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DECPTR(sizeof(u32_t), p); 100776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tl = ntohl(wo->hisaddr); 100876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTLONG(tl, p); 100976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 101076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1))); 101176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if (ciaddr1 == 0 && wo->hisaddr == 0) { 101276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 101376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Don't ACK an address of 0.0.0.0 - reject it instead. 101476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 101576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1))); 101676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; 101776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ 101876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 101976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 102076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 102176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->neg_addr = 1; 102276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->hisaddr = ciaddr1; 102376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1))); 102476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 102576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 102676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case CI_MS_DNS1: 102776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case CI_MS_DNS2: 102876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Microsoft primary or secondary DNS request */ 102976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman d = citype == CI_MS_DNS2; 103076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 103176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* If we do not have a DNS address then we cannot send it */ 103276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ao->dnsaddr[d] == 0 || 103376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cilen != CILEN_ADDR) { /* Check CI length */ 103476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting DNS%d Request\n", d+1)); 103576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; /* Reject CI */ 103676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 103776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 103876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(tl, p); 103976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (htonl(tl) != ao->dnsaddr[d]) { 104076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking DNS%d Request %s\n", 104176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman d+1, inet_ntoa(tl))); 104276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DECPTR(sizeof(u32_t), p); 104376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tl = ntohl(ao->dnsaddr[d]); 104476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTLONG(tl, p); 104576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFNAK; 104676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 104776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received DNS%d Request\n", d+1)); 104876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 104976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 105076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case CI_MS_WINS1: 105176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case CI_MS_WINS2: 105276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Microsoft primary or secondary WINS request */ 105376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman d = citype == CI_MS_WINS2; 105476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received WINS%d Request\n", d+1)); 105576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 105676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* If we do not have a DNS address then we cannot send it */ 105776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ao->winsaddr[d] == 0 || 105876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cilen != CILEN_ADDR) { /* Check CI length */ 105976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; /* Reject CI */ 106076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 106176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 106276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETLONG(tl, p); 106376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (htonl(tl) != ao->winsaddr[d]) { 106476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DECPTR(sizeof(u32_t), p); 106576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tl = ntohl(ao->winsaddr[d]); 106676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTLONG(tl, p); 106776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFNAK; 106876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 106976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 107076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 107176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case CI_COMPRESSTYPE: 107276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!ao->neg_vj) { 107376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n")); 107476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; 107576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 107676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) { 107776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen)); 107876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; 107976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 108076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 108176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETSHORT(cishort, p); 108276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 108376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!(cishort == IPCP_VJ_COMP || 108476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { 108576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort)); 108676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; 108776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 108876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 108976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 109076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->neg_vj = 1; 109176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->vj_protocol = cishort; 109276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cilen == CILEN_VJ) { 109376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(maxslotindex, p); 109476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (maxslotindex > ao->maxslotindex) { 109576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ max slot %d\n", maxslotindex)); 109676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFNAK; 109776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!reject_if_disagree) { 109876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DECPTR(1, p); 109976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(ao->maxslotindex, p); 110076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 110176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 110276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman GETCHAR(cflag, p); 110376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cflag && !ao->cflag) { 110476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ cflag %d\n", cflag)); 110576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFNAK; 110676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!reject_if_disagree) { 110776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DECPTR(1, p); 110876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(wo->cflag, p); 110976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 111076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 111176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->maxslotindex = maxslotindex; 111276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->cflag = cflag; 111376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 111476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->old_vj = 1; 111576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->maxslotindex = MAX_SLOTS - 1; 111676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->cflag = 1; 111776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 111876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ( 111976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n", 112076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag)); 112176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 112276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 112376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman default: 112476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting unknown CI type %d\n", citype)); 112576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; 112676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 112776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 112876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 112976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanendswitch: 113076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (orc == CONFACK && /* Good CI */ 113176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc != CONFACK) { /* but prior CI wasnt? */ 113276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman continue; /* Don't send this one */ 113376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 113476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 113576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (orc == CONFNAK) { /* Nak this CI? */ 113676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (reject_if_disagree) { /* Getting fed up with sending NAKs? */ 113776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting too many naks\n")); 113876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman orc = CONFREJ; /* Get tough if so */ 113976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 114076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (rc == CONFREJ) { /* Rejecting prior CI? */ 114176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman continue; /* Don't send this one */ 114276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 114376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (rc == CONFACK) { /* Ack'd all prior CIs? */ 114476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc = CONFNAK; /* Not anymore... */ 114576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ucp = inp; /* Backup */ 114676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 114776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 114876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 114976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 115076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (orc == CONFREJ && /* Reject this CI */ 115176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc != CONFREJ) { /* but no prior ones? */ 115276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc = CONFREJ; 115376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ucp = inp; /* Backup */ 115476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 115576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 115676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Need to move CI? */ 115776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ucp != cip) { 115876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman BCOPY(cip, ucp, cilen); /* Move it */ 115976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 116076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 116176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Update output pointer */ 116276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman INCPTR(cilen, ucp); 116376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 116476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 116576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 116676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If we aren't rejecting this packet, and we want to negotiate 116776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * their address, and they didn't send their address, then we 116876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * send a NAK with a CI_ADDR option appended. We assume the 116976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * input buffer is long enough that we can append the extra 117076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * option safely. 117176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 117276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (rc != CONFREJ && !ho->neg_addr && 117376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->req_addr && !reject_if_disagree) { 117476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Requesting peer address\n")); 117576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (rc == CONFACK) { 117676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc = CONFNAK; 117776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ucp = inp; /* reset pointer */ 117876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->req_addr = 0; /* don't ask again */ 117976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 118076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(CI_ADDR, ucp); 118176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTCHAR(CILEN_ADDR, ucp); 118276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tl = ntohl(wo->hisaddr); 118376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PUTLONG(tl, ucp); 118476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 118576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 118676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *len = (int)(ucp - inp); /* Compute output length */ 118776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp_reqci: returning Configure-%s\n", CODENAME(rc))); 118876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (rc); /* Return final code */ 118976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 119076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 119176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 119276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if 0 119376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 119476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ip_check_options - check that any IP-related options are OK, 119576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * and assign appropriate defaults. 119676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 119776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 119876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanip_check_options(u_long localAddr) 119976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 120076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *wo = &ipcp_wantoptions[0]; 120176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 120276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 120376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Load our default IP address but allow the remote host to give us 120476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * a new address. 120576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 120676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) { 120776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->accept_local = 1; /* don't insist on this default value */ 120876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wo->ouraddr = htonl(localAddr); 120976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 121076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 121176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 121276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 121376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 121476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 121576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_up - IPCP has come UP. 121676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 121776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Configure the IP network interface appropriately and bring it up. 121876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 121976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 122076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_up(fsm *f) 122176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 122276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t mask; 122376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *ho = &ipcp_hisoptions[f->unit]; 122476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *go = &ipcp_gotoptions[f->unit]; 122576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_options *wo = &ipcp_wantoptions[f->unit]; 122676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 122776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman np_up(f->unit, PPP_IP); 122876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp: up\n")); 122976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 123076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 123176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * We must have a non-zero IP address for both ends of the link. 123276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 123376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!ho->neg_addr) { 123476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ho->hisaddr = wo->hisaddr; 123576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 123676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 123776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ho->hisaddr == 0) { 123876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_ERR, ("Could not determine remote IP address\n")); 123976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_close(f->unit, "Could not determine remote IP address"); 124076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 124176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 124276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->ouraddr == 0) { 124376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_ERR, ("Could not determine local IP address\n")); 124476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_close(f->unit, "Could not determine local IP address"); 124576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 124676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 124776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 124876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { 124976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/ 125076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 125176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 125276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 125376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Check that the peer is allowed to use the IP address it wants. 125476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 125576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!auth_ip_addr(f->unit, ho->hisaddr)) { 125676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_ERR, ("Peer is not authorized to use remote address %s\n", 125776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman inet_ntoa(ho->hisaddr))); 125876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_close(f->unit, "Unauthorized remote IP address"); 125976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 126076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 126176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 126276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* set tcp compression */ 126376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); 126476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 126576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 126676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Set IP addresses and (if specified) netmask. 126776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 126876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mask = GetMask(go->ouraddr); 126976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 127076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) { 127176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_WARNING, ("sifaddr failed\n")); 127276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_close(f->unit, "Interface configuration failed"); 127376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 127476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 127576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 127676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* bring the interface up for IP */ 127776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!sifup(f->unit)) { 127876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_WARNING, ("sifup failed\n")); 127976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_close(f->unit, "Interface configuration failed"); 128076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 128176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 128276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 128376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sifnpmode(f->unit, PPP_IP, NPMODE_PASS); 128476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 128576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* assign a default route through the interface if required */ 128676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ipcp_wantoptions[f->unit].default_route) { 128776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) { 128876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman default_route_set[f->unit] = 1; 128976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 129076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 129176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 129276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_NOTICE, ("local IP address %s\n", inet_ntoa(go->ouraddr))); 129376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_NOTICE, ("remote IP address %s\n", inet_ntoa(ho->hisaddr))); 129476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->dnsaddr[0]) { 129576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_NOTICE, ("primary DNS address %s\n", inet_ntoa(go->dnsaddr[0]))); 129676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 129776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (go->dnsaddr[1]) { 129876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_NOTICE, ("secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1]))); 129976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 130076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 130176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 130276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 130376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 130476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_down - IPCP has gone DOWN. 130576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 130676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Take the IP network interface down, clear its addresses 130776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * and delete routes through it. 130876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 130976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 131076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_down(fsm *f) 131176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 131276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IPCPDEBUG(LOG_INFO, ("ipcp: down\n")); 131376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman np_down(f->unit, PPP_IP); 131476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sifvjcomp(f->unit, 0, 0, 0); 131576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 131676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sifdown(f->unit); 131776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ipcp_clear_addrs(f->unit); 131876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 131976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 132076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 132176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 132276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_clear_addrs() - clear the interface addresses, routes, etc. 132376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 132476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 132576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_clear_addrs(int unit) 132676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 132776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t ouraddr, hisaddr; 132876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 132976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ouraddr = ipcp_gotoptions[unit].ouraddr; 133076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman hisaddr = ipcp_hisoptions[unit].hisaddr; 133176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (default_route_set[unit]) { 133276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cifdefaultroute(unit, ouraddr, hisaddr); 133376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman default_route_set[unit] = 0; 133476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 133576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cifaddr(unit, ouraddr, hisaddr); 133676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 133776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 133876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 133976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 134076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ipcp_finished - possibly shut down the lower layers. 134176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 134276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 134376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_finished(fsm *f) 134476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 134576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman np_finished(f->unit, PPP_IP); 134676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 134776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 134876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if PPP_ADDITIONAL_CALLBACKS 134976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 135076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) 135176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 135276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LWIP_UNUSED_ARG(p); 135376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LWIP_UNUSED_ARG(plen); 135476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LWIP_UNUSED_ARG(printer); 135576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LWIP_UNUSED_ARG(arg); 135676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 135776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 135876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 135976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 136076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ip_active_pkt - see if this IP packet is worth bringing the link up for. 136176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * We don't bring the link up for IP fragments or for TCP FIN packets 136276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * with no data. 136376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 136476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define IP_HDRLEN 20 /* bytes */ 136576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define IP_OFFMASK 0x1fff 136676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define IPPROTO_TCP 6 136776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TCP_HDRLEN 20 136876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TH_FIN 0x01 136976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 137076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 137176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * We use these macros because the IP header may be at an odd address, 137276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * and some compilers might use word loads to get th_off or ip_hl. 137376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 137476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 137576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define net_short(x) (((x)[0] << 8) + (x)[1]) 137676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) 137776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define get_ipoff(x) net_short((unsigned char *)(x) + 6) 137876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define get_ipproto(x) (((unsigned char *)(x))[9]) 137976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) 138076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define get_tcpflags(x) (((unsigned char *)(x))[13]) 138176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 138276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 138376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanip_active_pkt(u_char *pkt, int len) 138476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 138576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u_char *tcp; 138676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int hlen; 138776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 138876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len -= PPP_HDRLEN; 138976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pkt += PPP_HDRLEN; 139076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (len < IP_HDRLEN) { 139176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 139276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 139376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((get_ipoff(pkt) & IP_OFFMASK) != 0) { 139476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 139576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 139676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (get_ipproto(pkt) != IPPROTO_TCP) { 139776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 139876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 139976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman hlen = get_iphl(pkt) * 4; 140076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (len < hlen + TCP_HDRLEN) { 140176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 140276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 140376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tcp = pkt + hlen; 140476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) { 140576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 140676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 140776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 140876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 140976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* PPP_ADDITIONAL_CALLBACKS */ 141076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 141176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* PPP_SUPPORT */ 1412