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

📄 ipcp.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 3 页
字号:
            DECPTR(sizeof(u32_t), p);            tl = ntohl(wo->hisaddr);            PUTLONG(tl, p);          }        } else if (ciaddr1 == 0 && wo->hisaddr == 0) {          /*           * If neither we nor he knows his address, reject the option.           */          orc = CONFREJ;          wo->req_addr = 0;  /* don't NAK with 0.0.0.0 later */          break;        }        /*         * If he doesn't know our address, or if we both have our address         * but disagree about it, then NAK it with our idea.         */        GETLONG(tl, p);    /* Parse desination address (ours) */        ciaddr2 = htonl(tl);        IPCPDEBUG(LOG_INFO, ("our addr %s\n", inet_ntoa(ciaddr2)));        if (ciaddr2 != wo->ouraddr) {          if (ciaddr2 == 0 || !wo->accept_local) {            orc = CONFNAK;            if (!reject_if_disagree) {              DECPTR(sizeof(u32_t), p);              tl = ntohl(wo->ouraddr);              PUTLONG(tl, p);            }          } else {            go->ouraddr = ciaddr2;  /* accept peer's idea */          }        }        ho->neg_addr = 1;        ho->old_addrs = 1;        ho->hisaddr = ciaddr1;        ho->ouraddr = ciaddr2;        break;#endif      case CI_ADDR:        if (!ao->neg_addr) {          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR not allowed\n"));          orc = CONFREJ;        /* Reject CI */          break;        } else if (cilen != CILEN_ADDR) {  /* Check CI length */          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR bad len\n"));          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);        if (ciaddr1 != wo->hisaddr            && (ciaddr1 == 0 || !wo->accept_remote)) {          orc = CONFNAK;          if (!reject_if_disagree) {            DECPTR(sizeof(u32_t), p);            tl = ntohl(wo->hisaddr);            PUTLONG(tl, p);          }          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1)));        } else if (ciaddr1 == 0 && wo->hisaddr == 0) {          /*           * Don't ACK an address of 0.0.0.0 - reject it instead.           */          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1)));          orc = CONFREJ;          wo->req_addr = 0;  /* don't NAK with 0.0.0.0 later */          break;        }        ho->neg_addr = 1;        ho->hisaddr = ciaddr1;        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1)));        break;      case CI_MS_DNS1:      case CI_MS_DNS2:        /* Microsoft primary or secondary DNS request */        d = citype == CI_MS_DNS2;        /* If we do not have a DNS address then we cannot send it */        if (ao->dnsaddr[d] == 0 ||            cilen != CILEN_ADDR) {  /* Check CI length */          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting DNS%d Request\n", d+1));          orc = CONFREJ;        /* Reject CI */          break;        }        GETLONG(tl, p);        if (htonl(tl) != ao->dnsaddr[d]) {          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking DNS%d Request %s\n",                d+1, inet_ntoa(tl)));          DECPTR(sizeof(u32_t), p);          tl = ntohl(ao->dnsaddr[d]);          PUTLONG(tl, p);          orc = CONFNAK;        }        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received DNS%d Request\n", d+1));        break;      case CI_MS_WINS1:      case CI_MS_WINS2:        /* Microsoft primary or secondary WINS request */        d = citype == CI_MS_WINS2;        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received WINS%d Request\n", d+1));        /* If we do not have a DNS address then we cannot send it */        if (ao->winsaddr[d] == 0 ||          cilen != CILEN_ADDR) {  /* Check CI length */          orc = CONFREJ;      /* Reject CI */          break;        }        GETLONG(tl, p);        if (htonl(tl) != ao->winsaddr[d]) {          DECPTR(sizeof(u32_t), p);          tl = ntohl(ao->winsaddr[d]);          PUTLONG(tl, p);          orc = CONFNAK;        }        break;      case CI_COMPRESSTYPE:        if (!ao->neg_vj) {          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n"));          orc = CONFREJ;          break;        } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen));          orc = CONFREJ;          break;        }        GETSHORT(cishort, p);        if (!(cishort == IPCP_VJ_COMP ||            (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort));          orc = CONFREJ;          break;        }        ho->neg_vj = 1;        ho->vj_protocol = cishort;        if (cilen == CILEN_VJ) {          GETCHAR(maxslotindex, p);          if (maxslotindex > ao->maxslotindex) {             IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ max slot %d\n", maxslotindex));            orc = CONFNAK;            if (!reject_if_disagree) {              DECPTR(1, p);              PUTCHAR(ao->maxslotindex, p);            }          }          GETCHAR(cflag, p);          if (cflag && !ao->cflag) {            IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ cflag %d\n", cflag));            orc = CONFNAK;            if (!reject_if_disagree) {              DECPTR(1, p);              PUTCHAR(wo->cflag, p);            }          }          ho->maxslotindex = maxslotindex;          ho->cflag = cflag;        } else {          ho->old_vj = 1;          ho->maxslotindex = MAX_SLOTS - 1;          ho->cflag = 1;        }        IPCPDEBUG(LOG_INFO, (              "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n",              ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag));        break;      default:        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting unknown CI type %d\n", citype));        orc = CONFREJ;        break;    }endswitch:    if (orc == CONFACK &&    /* Good CI */        rc != CONFACK) {     /*  but prior CI wasnt? */      continue;              /* Don't send this one */    }    if (orc == CONFNAK) {    /* Nak this CI? */      if (reject_if_disagree) {  /* Getting fed up with sending NAKs? */        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting too many naks\n"));        orc = CONFREJ;       /* Get tough if so */      } else {        if (rc == CONFREJ) { /* Rejecting prior CI? */          continue;          /* Don't send this one */        }        if (rc == CONFACK) { /* Ack'd all prior CIs? */          rc = CONFNAK;      /* Not anymore... */          ucp = inp;         /* Backup */        }      }    }    if (orc == CONFREJ &&    /* Reject this CI */        rc != CONFREJ) {  /*  but no prior ones? */      rc = CONFREJ;      ucp = inp;        /* Backup */    }        /* Need to move CI? */    if (ucp != cip) {      BCOPY(cip, ucp, cilen);  /* Move it */    }    /* Update output pointer */    INCPTR(cilen, ucp);  }  /*   * If we aren't rejecting this packet, and we want to negotiate   * their address, and they didn't send their address, then we   * send a NAK with a CI_ADDR option appended.  We assume the   * input buffer is long enough that we can append the extra   * option safely.   */  if (rc != CONFREJ && !ho->neg_addr &&      wo->req_addr && !reject_if_disagree) {    IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Requesting peer address\n"));    if (rc == CONFACK) {      rc = CONFNAK;      ucp = inp;        /* reset pointer */      wo->req_addr = 0;    /* don't ask again */    }    PUTCHAR(CI_ADDR, ucp);    PUTCHAR(CILEN_ADDR, ucp);    tl = ntohl(wo->hisaddr);    PUTLONG(tl, ucp);  }  *len = (int)(ucp - inp);    /* Compute output length */  IPCPDEBUG(LOG_INFO, ("ipcp_reqci: returning Configure-%s\n", CODENAME(rc)));  return (rc);      /* Return final code */}#if 0/* * ip_check_options - check that any IP-related options are OK, * and assign appropriate defaults. */static voidip_check_options(u_long localAddr){  ipcp_options *wo = &ipcp_wantoptions[0];  /*   * Load our default IP address but allow the remote host to give us   * a new address.   */  if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) {    wo->accept_local = 1;  /* don't insist on this default value */    wo->ouraddr = htonl(localAddr);  }}#endif/* * ipcp_up - IPCP has come UP. * * Configure the IP network interface appropriately and bring it up. */static voidipcp_up(fsm *f){  u32_t mask;  ipcp_options *ho = &ipcp_hisoptions[f->unit];  ipcp_options *go = &ipcp_gotoptions[f->unit];  ipcp_options *wo = &ipcp_wantoptions[f->unit];  np_up(f->unit, PPP_IP);  IPCPDEBUG(LOG_INFO, ("ipcp: up\n"));  /*   * We must have a non-zero IP address for both ends of the link.   */  if (!ho->neg_addr) {    ho->hisaddr = wo->hisaddr;  }  if (ho->hisaddr == 0) {    IPCPDEBUG(LOG_ERR, ("Could not determine remote IP address\n"));    ipcp_close(f->unit, "Could not determine remote IP address");    return;  }  if (go->ouraddr == 0) {    IPCPDEBUG(LOG_ERR, ("Could not determine local IP address\n"));    ipcp_close(f->unit, "Could not determine local IP address");    return;  }  if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {    /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/  }  /*   * Check that the peer is allowed to use the IP address it wants.   */  if (!auth_ip_addr(f->unit, ho->hisaddr)) {    IPCPDEBUG(LOG_ERR, ("Peer is not authorized to use remote address %s\n",        inet_ntoa(ho->hisaddr)));    ipcp_close(f->unit, "Unauthorized remote IP address");    return;  }  /* set tcp compression */  sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);  /*   * Set IP addresses and (if specified) netmask.   */  mask = GetMask(go->ouraddr);  if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) {    IPCPDEBUG(LOG_WARNING, ("sifaddr failed\n"));    ipcp_close(f->unit, "Interface configuration failed");    return;  }  /* bring the interface up for IP */  if (!sifup(f->unit)) {    IPCPDEBUG(LOG_WARNING, ("sifup failed\n"));    ipcp_close(f->unit, "Interface configuration failed");    return;  }  sifnpmode(f->unit, PPP_IP, NPMODE_PASS);  /* assign a default route through the interface if required */  if (ipcp_wantoptions[f->unit].default_route) {    if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) {      default_route_set[f->unit] = 1;    }  }  IPCPDEBUG(LOG_NOTICE, ("local  IP address %s\n", inet_ntoa(go->ouraddr)));  IPCPDEBUG(LOG_NOTICE, ("remote IP address %s\n", inet_ntoa(ho->hisaddr)));  if (go->dnsaddr[0]) {    IPCPDEBUG(LOG_NOTICE, ("primary   DNS address %s\n", inet_ntoa(go->dnsaddr[0])));  }  if (go->dnsaddr[1]) {    IPCPDEBUG(LOG_NOTICE, ("secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1])));  }}/* * ipcp_down - IPCP has gone DOWN. * * Take the IP network interface down, clear its addresses * and delete routes through it. */static voidipcp_down(fsm *f){  IPCPDEBUG(LOG_INFO, ("ipcp: down\n"));  np_down(f->unit, PPP_IP);  sifvjcomp(f->unit, 0, 0, 0);  sifdown(f->unit);  ipcp_clear_addrs(f->unit);}/* * ipcp_clear_addrs() - clear the interface addresses, routes, etc. */static voidipcp_clear_addrs(int unit){  u32_t ouraddr, hisaddr;  ouraddr = ipcp_gotoptions[unit].ouraddr;  hisaddr = ipcp_hisoptions[unit].hisaddr;  if (default_route_set[unit]) {    cifdefaultroute(unit, ouraddr, hisaddr);    default_route_set[unit] = 0;  }  cifaddr(unit, ouraddr, hisaddr);}/* * ipcp_finished - possibly shut down the lower layers. */static voidipcp_finished(fsm *f){  np_finished(f->unit, PPP_IP);}#if PPP_ADDITIONAL_CALLBACKSstatic intipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg){  LWIP_UNUSED_ARG(p);  LWIP_UNUSED_ARG(plen);  LWIP_UNUSED_ARG(printer);  LWIP_UNUSED_ARG(arg);  return 0;}/* * ip_active_pkt - see if this IP packet is worth bringing the link up for. * We don't bring the link up for IP fragments or for TCP FIN packets * with no data. */#define IP_HDRLEN   20  /* bytes */#define IP_OFFMASK  0x1fff#define IPPROTO_TCP 6#define TCP_HDRLEN  20#define TH_FIN      0x01/* * We use these macros because the IP header may be at an odd address, * and some compilers might use word loads to get th_off or ip_hl. */#define net_short(x)    (((x)[0] << 8) + (x)[1])#define get_iphl(x)     (((unsigned char *)(x))[0] & 0xF)#define get_ipoff(x)    net_short((unsigned char *)(x) + 6)#define get_ipproto(x)  (((unsigned char *)(x))[9])#define get_tcpoff(x)   (((unsigned char *)(x))[12] >> 4)#define get_tcpflags(x) (((unsigned char *)(x))[13])static intip_active_pkt(u_char *pkt, int len){  u_char *tcp;  int hlen;  len -= PPP_HDRLEN;  pkt += PPP_HDRLEN;  if (len < IP_HDRLEN) {    return 0;  }  if ((get_ipoff(pkt) & IP_OFFMASK) != 0) {    return 0;  }  if (get_ipproto(pkt) != IPPROTO_TCP) {    return 1;  }  hlen = get_iphl(pkt) * 4;  if (len < hlen + TCP_HDRLEN) {    return 0;  }  tcp = pkt + hlen;  if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) {    return 0;  }  return 1;}#endif /* PPP_ADDITIONAL_CALLBACKS */#endif /* PPP_SUPPORT */

⌨️ 快捷键说明

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