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

📄 ipcp.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 3 页
字号:
    } \    GETCHAR(citype, p); \    GETCHAR(cilen, p); \    if (cilen != addrlen || \        citype != opt) { \      goto bad; \    } \    GETLONG(l, p); \    cilong = htonl(l); \    if (val1 != cilong) { \      goto bad; \    } \    if (old) { \      GETLONG(l, p); \      cilong = htonl(l); \      if (val2 != cilong) { \        goto bad; \      } \    } \  }#define ACKCIDNS(opt, neg, addr) \  if (neg) { \    u32_t l; \    if ((len -= CILEN_ADDR) < 0) { \      goto bad; \    } \    GETCHAR(citype, p); \    GETCHAR(cilen, p); \    if (cilen != CILEN_ADDR || \        citype != opt) { \      goto bad; \    } \    GETLONG(l, p); \    cilong = htonl(l); \    if (addr != cilong) { \      goto bad; \    } \  }  ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,        go->old_addrs, go->ouraddr, go->hisaddr);  ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,      go->maxslotindex, go->cflag);  ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);  ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);  /*   * If there are any remaining CIs, then this packet is bad.   */  if (len != 0) {    goto bad;  }  return (1);bad:  IPCPDEBUG(LOG_INFO, ("ipcp_ackci: received bad Ack!\n"));  return (0);}/* * ipcp_nakci - Peer has sent a NAK for some of our CIs. * This should not modify any state if the Nak is bad * or if IPCP is in the LS_OPENED state. * * Returns: *  0 - Nak was bad. *  1 - Nak was good. */static intipcp_nakci(fsm *f, u_char *p, int len){  ipcp_options *go = &ipcp_gotoptions[f->unit];  u_char cimaxslotindex, cicflag;  u_char citype, cilen, *next;  u_short cishort;  u32_t ciaddr1, ciaddr2, l, cidnsaddr;  ipcp_options no;    /* options we've seen Naks for */  ipcp_options try;    /* options to request next time */  BZERO(&no, sizeof(no));  try = *go;  /*   * Any Nak'd 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 NAKCIADDR(opt, neg, old, code) \  if (go->neg && \      len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \      p[1] == cilen && \      p[0] == opt) { \    len -= cilen; \    INCPTR(2, p); \    GETLONG(l, p); \    ciaddr1 = htonl(l); \    if (old) { \      GETLONG(l, p); \      ciaddr2 = htonl(l); \      no.old_addrs = 1; \    } else { \      ciaddr2 = 0; \    } \    no.neg = 1; \    code \  }#define NAKCIVJ(opt, neg, code) \  if (go->neg && \      ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \      len >= cilen && \      p[0] == opt) { \    len -= cilen; \    INCPTR(2, p); \    GETSHORT(cishort, p); \    no.neg = 1; \    code \  }  #define NAKCIDNS(opt, neg, code) \  if (go->neg && \      ((cilen = p[1]) == CILEN_ADDR) && \      len >= cilen && \      p[0] == opt) { \    len -= cilen; \    INCPTR(2, p); \    GETLONG(l, p); \    cidnsaddr = htonl(l); \    no.neg = 1; \    code \  }  /*   * Accept the peer's idea of {our,his} address, if different   * from our idea, only if the accept_{local,remote} flag is set.   */  NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,    if (go->accept_local && ciaddr1) { /* Do we know our address? */      try.ouraddr = ciaddr1;      IPCPDEBUG(LOG_INFO, ("local IP address %s\n",           inet_ntoa(ciaddr1)));    }    if (go->accept_remote && ciaddr2) { /* Does he know his? */      try.hisaddr = ciaddr2;      IPCPDEBUG(LOG_INFO, ("remote IP address %s\n",           inet_ntoa(ciaddr2)));    }  );  /*   * Accept the peer's value of maxslotindex provided that it   * is less than what we asked for.  Turn off slot-ID compression   * if the peer wants.  Send old-style compress-type option if   * the peer wants.   */  NAKCIVJ(CI_COMPRESSTYPE, neg_vj,    if (cilen == CILEN_VJ) {      GETCHAR(cimaxslotindex, p);      GETCHAR(cicflag, p);      if (cishort == IPCP_VJ_COMP) {        try.old_vj = 0;        if (cimaxslotindex < go->maxslotindex) {          try.maxslotindex = cimaxslotindex;        }        if (!cicflag) {          try.cflag = 0;        }      } else {        try.neg_vj = 0;      }    } else {      if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {        try.old_vj = 1;        try.vj_protocol = cishort;      } else {        try.neg_vj = 0;      }    }  );  NAKCIDNS(CI_MS_DNS1, req_dns1,      try.dnsaddr[0] = cidnsaddr;        IPCPDEBUG(LOG_INFO, ("primary DNS address %s\n", inet_ntoa(cidnsaddr)));      );  NAKCIDNS(CI_MS_DNS2, req_dns2,      try.dnsaddr[1] = cidnsaddr;        IPCPDEBUG(LOG_INFO, ("secondary DNS address %s\n", inet_ntoa(cidnsaddr)));      );  /*  * There may be remaining CIs, if the peer is requesting negotiation  * on an option that we didn't include in our request packet.  * If they want to negotiate about IP addresses, we comply.  * If they want us to ask for compression, we refuse.  */  while (len > CILEN_VOID) {    GETCHAR(citype, p);    GETCHAR(cilen, p);    if( (len -= cilen) < 0 ) {      goto bad;    }    next = p + cilen - 2;    switch (citype) {      case CI_COMPRESSTYPE:        if (go->neg_vj || no.neg_vj ||            (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {          goto bad;        }        no.neg_vj = 1;        break;      case CI_ADDRS:        if ((go->neg_addr && go->old_addrs) || no.old_addrs            || cilen != CILEN_ADDRS) {          goto bad;        }        try.neg_addr = 1;        try.old_addrs = 1;        GETLONG(l, p);        ciaddr1 = htonl(l);        if (ciaddr1 && go->accept_local) {          try.ouraddr = ciaddr1;        }        GETLONG(l, p);        ciaddr2 = htonl(l);        if (ciaddr2 && go->accept_remote) {          try.hisaddr = ciaddr2;        }        no.old_addrs = 1;        break;      case CI_ADDR:        if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) {          goto bad;        }        try.old_addrs = 0;        GETLONG(l, p);        ciaddr1 = htonl(l);        if (ciaddr1 && go->accept_local) {          try.ouraddr = ciaddr1;        }        if (try.ouraddr != 0) {          try.neg_addr = 1;        }        no.neg_addr = 1;        break;    }    p = next;  }  /* If there is still anything left, this packet is bad. */  if (len != 0) {    goto bad;  }  /*   * OK, the Nak is good.  Now we can update state.   */  if (f->state != LS_OPENED) {    *go = try;  }  return 1;bad:  IPCPDEBUG(LOG_INFO, ("ipcp_nakci: received bad Nak!\n"));  return 0;}/* * ipcp_rejci - Reject some of our CIs. */static intipcp_rejci(fsm *f, u_char *p, int len){  ipcp_options *go = &ipcp_gotoptions[f->unit];  u_char cimaxslotindex, ciflag, cilen;  u_short cishort;  u32_t cilong;  ipcp_options try;    /* options to request next time */  try = *go;  /*   * Any Rejected 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 REJCIADDR(opt, neg, old, val1, val2) \  if (go->neg && \      len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \      p[1] == cilen && \      p[0] == opt) { \    u32_t l; \    len -= cilen; \    INCPTR(2, p); \    GETLONG(l, p); \    cilong = htonl(l); \    /* Check rejected value. */ \    if (cilong != val1) { \      goto bad; \    } \    if (old) { \      GETLONG(l, p); \      cilong = htonl(l); \      /* Check rejected value. */ \      if (cilong != val2) { \        goto bad; \      } \    } \    try.neg = 0; \  }#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \  if (go->neg && \      p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \      len >= p[1] && \      p[0] == opt) { \    len -= p[1]; \    INCPTR(2, p); \    GETSHORT(cishort, p); \    /* Check rejected value. */  \    if (cishort != val) { \      goto bad; \    } \    if (!old) { \      GETCHAR(cimaxslotindex, p); \      if (cimaxslotindex != maxslot) { \        goto bad; \      } \      GETCHAR(ciflag, p); \      if (ciflag != cflag) { \        goto bad; \      } \    } \    try.neg = 0; \  }#define REJCIDNS(opt, neg, dnsaddr) \  if (go->neg && \      ((cilen = p[1]) == CILEN_ADDR) && \      len >= cilen && \      p[0] == opt) { \    u32_t l; \    len -= cilen; \    INCPTR(2, p); \    GETLONG(l, p); \    cilong = htonl(l); \    /* Check rejected value. */ \    if (cilong != dnsaddr) { \      goto bad; \    } \    try.neg = 0; \  }  REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,        go->old_addrs, go->ouraddr, go->hisaddr);  REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,      go->maxslotindex, go->cflag);  REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);  REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);  /*   * If there are any remaining CIs, then this packet is bad.   */  if (len != 0) {    goto bad;  }  /*   * Now we can update state.   */  if (f->state != LS_OPENED) {    *go = try;  }  return 1;bad:  IPCPDEBUG(LOG_INFO, ("ipcp_rejci: received bad Reject!\n"));  return 0;}/* * ipcp_reqci - Check the peer's requested CIs and send appropriate response. * * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified * appropriately.  If reject_if_disagree is non-zero, doesn't return * CONFNAK; returns CONFREJ if it can't return CONFACK. */static intipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested CIs */,int reject_if_disagree){  ipcp_options *wo = &ipcp_wantoptions[f->unit];  ipcp_options *ho = &ipcp_hisoptions[f->unit];  ipcp_options *ao = &ipcp_allowoptions[f->unit];#ifdef OLD_CI_ADDRS  ipcp_options *go = &ipcp_gotoptions[f->unit];#endif  u_char *cip, *next;     /* Pointer to current and next CIs */  u_short cilen, citype;  /* Parsed len, type */  u_short cishort;        /* Parsed short value */  u32_t tl, ciaddr1;      /* Parsed address values */#ifdef OLD_CI_ADDRS  u32_t ciaddr2;          /* Parsed address values */#endif  int rc = CONFACK;       /* Final packet return code */  int orc;                /* Individual option return code */  u_char *p;              /* Pointer to next char to parse */  u_char *ucp = inp;      /* Pointer to current output char */  int l = *len;           /* Length left */  u_char maxslotindex, cflag;  int d;  cis_received[f->unit] = 1;  /*   * Reset all his options.   */  BZERO(ho, sizeof(*ho));  /*   * Process all his options.   */  next = inp;  while (l) {    orc = CONFACK;       /* Assume success */    cip = p = next;      /* Remember begining of CI */    if (l < 2 ||         /* Not enough data for CI header or */        p[1] < 2 ||      /*  CI length too small or */        p[1] > l) {      /*  CI length too big? */      IPCPDEBUG(LOG_INFO, ("ipcp_reqci: bad CI length!\n"));      orc = CONFREJ;     /* Reject bad CI */      cilen = (u_short)l;/* Reject till end of packet */      l = 0;             /* Don't loop again */      goto endswitch;    }    GETCHAR(citype, p);  /* Parse CI type */    GETCHAR(cilen, p);   /* Parse CI length */    l -= cilen;          /* Adjust remaining length */    next += cilen;       /* Step to next CI */    switch (citype) {      /* Check CI type */#ifdef OLD_CI_ADDRS /* Need to save space... */      case CI_ADDRS:        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received ADDRS\n"));        if (!ao->neg_addr ||            cilen != CILEN_ADDRS) {  /* Check CI length */          orc = CONFREJ;    /* Reject CI */          break;        }        /*         * If he has no address, or if we both have his address but         * disagree about it, then NAK it with our idea.         * In particular, if we don't know his address, but he does,         * then accept it.         */        GETLONG(tl, p);    /* Parse source address (his) */        ciaddr1 = htonl(tl);        IPCPDEBUG(LOG_INFO, ("his addr %s\n", inet_ntoa(ciaddr1)));        if (ciaddr1 != wo->hisaddr            && (ciaddr1 == 0 || !wo->accept_remote)) {          orc = CONFNAK;          if (!reject_if_disagree) {

⌨️ 快捷键说明

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