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

📄 pppipcp.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
  int option_result;            /* option reply */  uint desired = 0;             /* desired to negotiate */  OptHdr option;                /* option header storage */  /*-------------------------------------------------------------------*/  /* Attempt to allocate buffer. Return NULL if unable.                */  /*-------------------------------------------------------------------*/  buf = tcpGetBuf(NIMHLEN + PPP_MTU + CRC16_LEN);  if (buf == NULL)    return -1;  /*-------------------------------------------------------------------*/  /* Establish those options that need to reset.                       */  /*-------------------------------------------------------------------*/  ipcp->remote.options = 0;         /* negotiation flags */  ipcp->remote.address = 0;         /* remote IP address */  ipcp->remote.comp_proto = 0;      /* compression protocol */  ipcp->remote.slots = 0;           /* number of slots (0-n) */  ipcp->remote.comp_slot = 0;       /* slots may be compressed (flag) */  /*-------------------------------------------------------------------*/  /* Process each option requested by the peer.                        */  /*-------------------------------------------------------------------*/  while ((signed_length > 0) && (pppRdOpt(&option) != -1))  {    /*-----------------------------------------------------------------*/    /* Verify configuration header length is not too short.            */    /*-----------------------------------------------------------------*/    if ((signed_length -= option.len) < 0)    {#if PPP_TRACE      pppLog("IPCP REQ: bad header length");#endif      tcpRetBuf(&buf);      return -1;    }    /*-----------------------------------------------------------------*/    /* Verify option value is acceptable and packet length is okay.    */    /*-----------------------------------------------------------------*/    option_result = check_req_opt(&ipcp->remote, &option);    if (option_result == -1)    {#if PPP_TRACE      pppLog("IPCP REQ: ran out of data");#endif      tcpRetBuf(&buf);      return -1;    }#if PPP_TRACE    pppLog("IPCP REQ: result=%s, option=%02X, length=%u",           fsmCodes[option_result], option.type, option.len);#endif    /*-----------------------------------------------------------------*/    /* If NAK reached, ignore ACK options. If REJ reached, ignore ACK  */    /* and NAK options.                                                */    /*-----------------------------------------------------------------*/    if (option_result < reply_result)    {      continue;    }    /*-----------------------------------------------------------------*/    /* On transition to NAK or REJ, discard current reply list.        */    /*-----------------------------------------------------------------*/    else if (option_result > reply_result)    {      NetRstBuf(buf);      reply_result = option_result;    }    /*-----------------------------------------------------------------*/    /* Remember those option requests we have received.                */    /*-----------------------------------------------------------------*/    ipcp->remote.options |= (1 << option.type);    /*-----------------------------------------------------------------*/    /* Add option response to the return list.                         */    /*-----------------------------------------------------------------*/    add_option(buf, &ipcp->remote, option.type);  }  /*-------------------------------------------------------------------*/  /* If remote address is 0 and we're not default GW, need IP_ADDRESS. */  /*-------------------------------------------------------------------*/  if ((ipcp->remote.address == 0) && !(Ppp->public.flags & PPPF_DEF_GW))    desired = IPCP_N_ADDRESS;  /*-------------------------------------------------------------------*/  /* If not at NAK limit, append any missing options that are desired. */  /*-------------------------------------------------------------------*/  desired &= ~ipcp->remote.options;  if ((fsm->rcn_cnt < fsm->pdc->nak_limit) && desired)  {    switch (reply_result)    {      case CONFIG_ACK:        NetRstBuf(buf);        reply_result = CONFIG_NAK;        /*lint -fallthrough */      case CONFIG_NAK:        make_opts(buf, &ipcp->remote, desired);        break;      case CONFIG_REJ:        /* do nothing */        break;    }  }  /*-------------------------------------------------------------------*/  /* Else if result is NAK and too many already sent, reject instead.  */  /*-------------------------------------------------------------------*/  else if ((reply_result == CONFIG_NAK) &&           (fsm->rcn_cnt >= fsm->pdc->nak_limit))  {    reply_result = CONFIG_REJ;  }  /*-------------------------------------------------------------------*/  /* Send ACK, NAK, or REJ to the peer.                                */  /*-------------------------------------------------------------------*/  pppFsmSend(fsm, reply_result, config->id, buf);  return reply_result;}/***********************************************************************//*   check_ack: Process configuration ACK sent by the peer             *//*                                                                     *//*     Returns: 0 if acknowledgment is acceptable, else -1             *//*                                                                     *//***********************************************************************/static int check_ack(FSM *fsm, ConfigHdr *config){  NetBuf *buf;  int error = FALSE;  /*-------------------------------------------------------------------*/  /* The ID field must match the last request we sent.                 */  /*-------------------------------------------------------------------*/  if (config->id != fsm->lastid)  {#if PPP_TRACE    pppLog("IPCP ACK: wrong ID");#endif    return -1;  }  /*-------------------------------------------------------------------*/  /* Get a copy of the last request we sent.                           */  /*-------------------------------------------------------------------*/  buf = make_req(fsm);  if (buf == NULL)    return -1;  /*-------------------------------------------------------------------*/  /* Overall buffer length should match.                               */  /*-------------------------------------------------------------------*/  if (config->len != buf->length)  {#if PPP_TRACE    pppLog("IPCP ACK: buffer length mismatch");#endif    error = TRUE;  }  /*-------------------------------------------------------------------*/  /* Each byte should match.                                           */  /*-------------------------------------------------------------------*/  else  {    int req_char;    int ack_char;    while ((req_char = pullchar(buf)) != -1)    {      ack_char = pullchar(pppRcvBuf);      if (ack_char != req_char)      {#if PPP_TRACE        pppLog("IPCP ACK: data mismatch");#endif        error = TRUE;        break;      }    }  }  /*-------------------------------------------------------------------*/  /* Free temporarily allocated request buffer.                        */  /*-------------------------------------------------------------------*/  tcpRetBuf(&buf);  /*-------------------------------------------------------------------*/  /* Return success or failure code.                                   */  /*-------------------------------------------------------------------*/  if (error)    return -1;  else  {#if PPP_TRACE    pppLog("IPCP ACK: valid");#endif    return 0;  }}/***********************************************************************//* check_nak_opt: Check a NAKed option, updating its local value       *//*                                                                     *//*      Inputs: local = negotiation parameters for local side          *//*              opt = pointer to received option header                *//*                                                                     *//*     Returns: -1 if ran out of data, else 0                          *//*                                                                     *//*        Note: Called by nak_check() to update our local values       *//*                                                                     *//***********************************************************************/static int check_nak_opt(IpcpOpts *local, OptHdr *opt){  int toss = opt->len - OPTION_HDR_LEN;  int test;  /*-------------------------------------------------------------------*/  /* Parse option type.                                                */  /*-------------------------------------------------------------------*/  switch (opt->type)  {    case IPCP_COMPRESS:      /*---------------------------------------------------------------*/      /* Read the peer's requested compression option.                 */      /*---------------------------------------------------------------*/      local->comp_proto = pull16(pppRcvBuf);      toss -= 2;#if PPP_TRACE      pppLog("   checking IP compression 0x%04X", local->comp_proto);#endif      /*---------------------------------------------------------------*/      /* Check if requested type is acceptable.                        */      /*---------------------------------------------------------------*/      switch (local->comp_proto)      {        case PPP_COMP_PROTO:          test = pullchar(pppRcvBuf);          if (test == -1)            return -1;          local->slots = test + 1;          if (local->slots < VJ_SLOT_LO)            local->slots = VJ_SLOT_LO;          else if (local->slots > VJ_SLOT_HI)            local->slots = VJ_SLOT_HI;          test = pullchar(pppRcvBuf);          if (test == -1)            return -1;          local->comp_slot = test;          if (local->comp_slot > 1)            local->comp_slot = 1;          toss -= 2;#if PPP_TRACE          pppLog("   with IP compression slots %u, flag %X",                 local->slots, local->comp_slot);#endif          break;      default:        local->comp_proto = PPP_COMP_PROTO;        local->slots = VJ_SLOT_DEF;        local->comp_slot = IPCP_COMP_SLOT;        break;      }      break;    case IPCP_ADDRESS:      /*---------------------------------------------------------------*/      /* Read the peer's suggested IP address.                         */      /*---------------------------------------------------------------*/      local->address = pull32(pppRcvBuf);      toss -= 4;#if PPP_TRACE      pppLog("   checking IP src address %s", pppIps(local->address));#endif      /*---------------------------------------------------------------*/      /* Override change if undesirable.                               */      /*---------------------------------------------------------------*/      if (Ppp->public.local_addr)        local->address = Ppp->public.local_addr;      break;    default:#if PPP_TRACE      pppLog("IPCP NAK: unknown option");#endif      break;  }  /*-------------------------------------------------------------------*/  /* Return error if buffer ran out of data.                           */  /*-------------------------------------------------------------------*/  if (toss < 0)    return -1;  /*-------------------------------------------------------------------*/  /* Toss remaining bytes in option.                                   */  /*-------------------------------------------------------------------*/  while (toss-- > 0)  {    if (pullchar(pppRcvBuf) == -1)      return -1;  }  return 0;}/***********************************************************************//*   nak_check: Process configuration NAK sent by peer                 *//*                                                                     *//*        Note: Update our config request to reflect NAKed options     *//*                                                                     *//***********************************************************************/static int nak_check(FSM *fsm, ConfigHdr *config){  IpcpCB *ipcp = &Ppp->ipcp;  int signed_length = config->len;  OptHdr option;  int result;  /*-------------------------------------------------------------------*/  /* The ID field must match the last request we sent.                 */  /*-------------------------------------------------------------------*/  if (config->id != fsm->lastid)  {#if PPP_TRACE    pppLog("IPCP NAK: wrong ID");#endif    return -1;  }  /*-------------------------------------------------------------------*/  /* Process options in the order received.                            */  /*-------------------------------------------------------------------*/  while ((signed_length > 0) && (pppRdOpt(&option) != -1))  {    /*-----------------------------------------------------------------*/    /* Verify configuration header length is not too short.            */

⌨️ 快捷键说明

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