⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipcp.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 3 页
字号:
/** In contrast to pppd 2.3.1, DNS support has been added, proxy-ARP and    dial-on-demand has been stripped. *//****************************************************************************** ipcp.c - Network PPP IP Control Protocol program file.** Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.* portions Copyright (c) 1997 by Global Election Systems Inc.** The authors hereby grant permission to use, copy, modify, distribute,* and license this software and its documentation for any purpose, provided* that existing copyright notices are retained in all copies and that this* notice and the following disclaimer are included verbatim in any * distributions. No written agreement, license, or royalty fee is required* for any of the authorized uses.** THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.******************************************************************************** REVISION HISTORY** 03-01-01 Marc Boucher <marc@mbsi.ca>*   Ported to lwIP.* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.*   Original.*****************************************************************************//* * ipcp.c - PPP IP Control Protocol. * * Copyright (c) 1989 Carnegie Mellon University. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by Carnegie Mellon University.  The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#include "lwip/opt.h"#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */#include "ppp.h"#include "pppdebug.h"#include "auth.h"#include "fsm.h"#include "vj.h"#include "ipcp.h"#include "lwip/inet.h"#include <string.h>/* #define OLD_CI_ADDRS 1 */ /* Support deprecated address negotiation. *//* global vars */ipcp_options ipcp_wantoptions[NUM_PPP];  /* Options that we want to request */ipcp_options ipcp_gotoptions[NUM_PPP];   /* Options that peer ack'd */ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ipcp_options ipcp_hisoptions[NUM_PPP];   /* Options that we ack'd *//* local vars */static int default_route_set[NUM_PPP]; /* Have set up a default route */static int cis_received[NUM_PPP];      /* # Conf-Reqs received *//* * Callbacks for fsm code.  (CI = Configuration Information) */static void ipcp_resetci (fsm *);                     /* Reset our CI */static int  ipcp_cilen (fsm *);                       /* Return length of our CI */static void ipcp_addci (fsm *, u_char *, int *);      /* Add our CI */static int  ipcp_ackci (fsm *, u_char *, int);        /* Peer ack'd our CI */static int  ipcp_nakci (fsm *, u_char *, int);        /* Peer nak'd our CI */static int  ipcp_rejci (fsm *, u_char *, int);        /* Peer rej'd our CI */static int  ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */static void ipcp_up (fsm *);                          /* We're UP */static void ipcp_down (fsm *);                        /* We're DOWN */#if PPP_ADDITIONAL_CALLBACKSstatic void ipcp_script (fsm *, char *); /* Run an up/down script */#endifstatic void ipcp_finished (fsm *);                    /* Don't need lower layer */fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */  ipcp_resetci,  /* Reset our Configuration Information */  ipcp_cilen,    /* Length of our Configuration Information */  ipcp_addci,    /* Add our Configuration Information */  ipcp_ackci,    /* ACK our Configuration Information */  ipcp_nakci,    /* NAK our Configuration Information */  ipcp_rejci,    /* Reject our Configuration Information */  ipcp_reqci,    /* Request peer's Configuration Information */  ipcp_up,       /* Called when fsm reaches LS_OPENED state */  ipcp_down,     /* Called when fsm leaves LS_OPENED state */  NULL,          /* Called when we want the lower layer up */  ipcp_finished, /* Called when we want the lower layer down */  NULL,          /* Called when Protocol-Reject received */  NULL,          /* Retransmission is necessary */  NULL,          /* Called to handle protocol-specific codes */  "IPCP"         /* String name of protocol */};/* * Protocol entry points from main code. */static void ipcp_init (int);static void ipcp_open (int);static void ipcp_close (int, char *);static void ipcp_lowerup (int);static void ipcp_lowerdown (int);static void ipcp_input (int, u_char *, int);static void ipcp_protrej (int);struct protent ipcp_protent = {  PPP_IPCP,  ipcp_init,  ipcp_input,  ipcp_protrej,  ipcp_lowerup,  ipcp_lowerdown,  ipcp_open,  ipcp_close,#if PPP_ADDITIONAL_CALLBACKS  ipcp_printpkt,  NULL,#endif /* PPP_ADDITIONAL_CALLBACKS */  1,  "IPCP",#if PPP_ADDITIONAL_CALLBACKS  ip_check_options,  NULL,  ip_active_pkt#endif /* PPP_ADDITIONAL_CALLBACKS */};static void ipcp_clear_addrs (int);/* * Lengths of configuration options. */#define CILEN_VOID     2#define CILEN_COMPRESS 4  /* min length for compression protocol opt. */#define CILEN_VJ       6  /* length for RFC1332 Van-Jacobson opt. */#define CILEN_ADDR     6  /* new-style single address option */#define CILEN_ADDRS    10 /* old-style dual address option */#define CODENAME(x) ((x) == CONFACK ? "ACK" : \                     (x) == CONFNAK ? "NAK" : "REJ")/* * ipcp_init - Initialize IPCP. */static voidipcp_init(int unit){  fsm           *f = &ipcp_fsm[unit];  ipcp_options *wo = &ipcp_wantoptions[unit];  ipcp_options *ao = &ipcp_allowoptions[unit];  f->unit      = unit;  f->protocol  = PPP_IPCP;  f->callbacks = &ipcp_callbacks;  fsm_init(&ipcp_fsm[unit]);  memset(wo, 0, sizeof(*wo));  memset(ao, 0, sizeof(*ao));  wo->neg_addr      = 1;  wo->ouraddr       = 0;#if VJ_SUPPORT  wo->neg_vj        = 1;#else  /* VJ_SUPPORT */  wo->neg_vj        = 0;#endif /* VJ_SUPPORT */  wo->vj_protocol   = IPCP_VJ_COMP;  wo->maxslotindex  = MAX_SLOTS - 1;  wo->cflag         = 0;  wo->default_route = 1;  ao->neg_addr      = 1;#if VJ_SUPPORT  ao->neg_vj        = 1;#else  /* VJ_SUPPORT */  ao->neg_vj        = 0;#endif /* VJ_SUPPORT */  ao->maxslotindex  = MAX_SLOTS - 1;  ao->cflag         = 1;  ao->default_route = 1;}/* * ipcp_open - IPCP is allowed to come up. */static voidipcp_open(int unit){  fsm_open(&ipcp_fsm[unit]);}/* * ipcp_close - Take IPCP down. */static voidipcp_close(int unit, char *reason){  fsm_close(&ipcp_fsm[unit], reason);}/* * ipcp_lowerup - The lower layer is up. */static voidipcp_lowerup(int unit){  fsm_lowerup(&ipcp_fsm[unit]);}/* * ipcp_lowerdown - The lower layer is down. */static voidipcp_lowerdown(int unit){  fsm_lowerdown(&ipcp_fsm[unit]);}/* * ipcp_input - Input IPCP packet. */static voidipcp_input(int unit, u_char *p, int len){  fsm_input(&ipcp_fsm[unit], p, len);}/* * ipcp_protrej - A Protocol-Reject was received for IPCP. * * Pretend the lower layer went down, so we shut up. */static voidipcp_protrej(int unit){  fsm_lowerdown(&ipcp_fsm[unit]);}/* * ipcp_resetci - Reset our CI. */static voidipcp_resetci(fsm *f){  ipcp_options *wo = &ipcp_wantoptions[f->unit];    wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;  if (wo->ouraddr == 0) {    wo->accept_local = 1;  }  if (wo->hisaddr == 0) {    wo->accept_remote = 1;  }  /* Request DNS addresses from the peer */  wo->req_dns1 = ppp_settings.usepeerdns;  wo->req_dns2 = ppp_settings.usepeerdns;  ipcp_gotoptions[f->unit] = *wo;  cis_received[f->unit] = 0;}/* * ipcp_cilen - Return length of our CI. */static intipcp_cilen(fsm *f){  ipcp_options *go = &ipcp_gotoptions[f->unit];  ipcp_options *wo = &ipcp_wantoptions[f->unit];  ipcp_options *ho = &ipcp_hisoptions[f->unit];#define LENCIVJ(neg, old)   (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)#define LENCIDNS(neg)       (neg ? (CILEN_ADDR) : 0)  /*   * First see if we want to change our options to the old   * forms because we have received old forms from the peer.   */  if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {    /* use the old style of address negotiation */    go->neg_addr = 1;    go->old_addrs = 1;  }  if (wo->neg_vj && !go->neg_vj && !go->old_vj) {    /* try an older style of VJ negotiation */    if (cis_received[f->unit] == 0) {      /* keep trying the new style until we see some CI from the peer */      go->neg_vj = 1;    } else {      /* use the old style only if the peer did */      if (ho->neg_vj && ho->old_vj) {        go->neg_vj = 1;        go->old_vj = 1;        go->vj_protocol = ho->vj_protocol;      }    }  }  return (LENCIADDR(go->neg_addr, go->old_addrs) +          LENCIVJ(go->neg_vj, go->old_vj) +          LENCIDNS(go->req_dns1) +          LENCIDNS(go->req_dns2));}/* * ipcp_addci - Add our desired CIs to a packet. */static voidipcp_addci(fsm *f, u_char *ucp, int *lenp){  ipcp_options *go = &ipcp_gotoptions[f->unit];  int len = *lenp;#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \  if (neg) { \    int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \    if (len >= vjlen) { \      PUTCHAR(opt, ucp); \      PUTCHAR(vjlen, ucp); \      PUTSHORT(val, ucp); \      if (!old) { \        PUTCHAR(maxslotindex, ucp); \        PUTCHAR(cflag, ucp); \      } \      len -= vjlen; \    } else { \      neg = 0; \    } \  }#define ADDCIADDR(opt, neg, old, val1, val2) \  if (neg) { \    int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \    if (len >= addrlen) { \      u32_t l; \      PUTCHAR(opt, ucp); \      PUTCHAR(addrlen, ucp); \      l = ntohl(val1); \      PUTLONG(l, ucp); \      if (old) { \        l = ntohl(val2); \        PUTLONG(l, ucp); \      } \      len -= addrlen; \    } else { \      neg = 0; \    } \  }#define ADDCIDNS(opt, neg, addr) \  if (neg) { \    if (len >= CILEN_ADDR) { \      u32_t l; \      PUTCHAR(opt, ucp); \      PUTCHAR(CILEN_ADDR, ucp); \      l = ntohl(addr); \      PUTLONG(l, ucp); \      len -= CILEN_ADDR; \    } else { \      neg = 0; \    } \  }  ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,      go->old_addrs, go->ouraddr, go->hisaddr);  ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,      go->maxslotindex, go->cflag);  ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);  ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);  *lenp -= len;}/* * ipcp_ackci - Ack our CIs. * * Returns: *  0 - Ack was bad. *  1 - Ack was good. */static intipcp_ackci(fsm *f, u_char *p, int len){  ipcp_options *go = &ipcp_gotoptions[f->unit];  u_short cilen, citype, cishort;  u32_t cilong;  u_char cimaxslotindex, cicflag;  /*   * CIs must be in exactly the same order that we sent...   * Check packet length and CI length at each step.   * If we find any deviations, then this packet is bad.   */#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \  if (neg) { \    int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \    if ((len -= vjlen) < 0) { \      goto bad; \    } \    GETCHAR(citype, p); \    GETCHAR(cilen, p); \    if (cilen != vjlen || \        citype != opt) { \      goto bad; \    } \    GETSHORT(cishort, p); \    if (cishort != val) { \      goto bad; \    } \    if (!old) { \      GETCHAR(cimaxslotindex, p); \      if (cimaxslotindex != maxslotindex) { \        goto bad; \      } \      GETCHAR(cicflag, p); \      if (cicflag != cflag) { \        goto bad; \      } \    } \  }  #define ACKCIADDR(opt, neg, old, val1, val2) \  if (neg) { \    int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \    u32_t l; \    if ((len -= addrlen) < 0) { \      goto bad; \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -