Пример #1
0
void chapProcessPacket(PppContext *context,
   const PppPacket *packet, size_t length)
{
   //Ensure the length of the incoming CHAP packet is valid
   if(length < sizeof(PppPacket))
      return;

   //Check the length field
   if(ntohs(packet->length) > length)
      return;
   if(ntohs(packet->length) < sizeof(PppPacket))
      return;

   //Save the length of the CHAP packet
   length = ntohs(packet->length);

   //Debug message
   TRACE_INFO("CHAP packet received (%" PRIuSIZE " bytes)...\r\n", length);
   //Dump CHAP packet contents for debugging purpose
   pppDumpPacket(packet, length, PPP_PROTOCOL_CHAP);

   //CHAP is done at initial link establishment, and could also be
   //requested after link establishment
   if(context->pppPhase != PPP_PHASE_AUTHENTICATE &&
      context->pppPhase != PPP_PHASE_NETWORK)
   {
      //Any packets received during any other phase must be silently discarded
      return;
   }

   //Check CHAP code field
   switch(packet->code)
   {
   //Challenge packet?
   case CHAP_CODE_CHALLENGE:
      //Process Challenge packet
      chapProcessChallenge(context, (ChapChallengePacket *) packet, length);
      break;
   //Response packet?
   case CHAP_CODE_RESPONSE:
      //Process Response packet
      chapProcessResponse(context, (ChapResponsePacket *) packet, length);
      break;
   //Success packet?
   case CHAP_CODE_SUCCESS:
      //Process Success packet
      chapProcessSuccess(context, (ChapSuccessPacket *) packet, length);
      break;
   //Failure packet?
   case CHAP_CODE_FAILURE:
      //Process Failure packet
      chapProcessFailure(context, (ChapFailurePacket *) packet, length);
      break;
   //Unknown code field
   default:
      //Silently drop the incoming packet
      break;
   }
}
Пример #2
0
error_t chapSendResponse(PppContext *context, const uint8_t *value)
{
   error_t error;
   size_t n;
   size_t length;
   size_t offset;
   NetBuffer *buffer;
   ChapResponsePacket *responsePacket;

   //Retrieve the length of the username
   n = strlen(context->username);
   //Calculate the length of the Response packet
   length = sizeof(ChapResponsePacket) + MD5_DIGEST_SIZE + n;

   //Allocate a buffer memory to hold the Response packet
   buffer = pppAllocBuffer(length, &offset);
   //Failed to allocate memory?
   if(!buffer) return ERROR_OUT_OF_MEMORY;

   //Point to the Response packet
   responsePacket = netBufferAt(buffer, offset);

   //Format packet header
   responsePacket->code = CHAP_CODE_RESPONSE;
   responsePacket->identifier = context->chapFsm.peerIdentifier;
   responsePacket->length = htons(length);
   responsePacket->valueSize = MD5_DIGEST_SIZE;

   //Copy the Response value
   memcpy(responsePacket->value, value, MD5_DIGEST_SIZE);

   //The Name field is one or more octets representing the
   //identification of the system transmitting the packet
   memcpy(responsePacket->value + MD5_DIGEST_SIZE, context->username, n);

   //Debug message
   TRACE_INFO("Sending CHAP Response packet (%" PRIuSIZE " bytes)...\r\n", length);
   //Dump packet contents for debugging purpose
   pppDumpPacket((PppPacket *) responsePacket, length, PPP_PROTOCOL_CHAP);

   //Send PPP frame
   error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);

   //Free previously allocated memory block
   netBufferFree(buffer);
   //Return status code
   return error;
}
Пример #3
0
error_t pppSendTerminateAck(PppContext *context,
                            uint8_t identifier, PppProtocol protocol)
{
    error_t error;
    size_t length;
    size_t offset;
    NetBuffer *buffer;
    PppTerminatePacket *terminateAckPacket;

    //Length of the Terminate-Ack packet
    length = sizeof(PppTerminatePacket);

    //Allocate a buffer memory to hold the Terminate-Ack packet
    buffer = pppAllocBuffer(length, &offset);
    //Failed to allocate memory?
    if(!buffer) return ERROR_OUT_OF_MEMORY;

    //Point to the Terminate-Ack packet
    terminateAckPacket = netBufferAt(buffer, offset);

    //Format packet header
    terminateAckPacket->code = PPP_CODE_TERMINATE_ACK;
    terminateAckPacket->identifier = identifier;
    terminateAckPacket->length = htons(length);

    //Debug message
    TRACE_INFO("Sending Terminate-Ack packet (%" PRIuSIZE " bytes)...\r\n", length);
    //Dump packet contents for debugging purpose
    pppDumpPacket((PppPacket *) terminateAckPacket, length, protocol);

    //Send PPP frame
    error = pppSendFrame(context->interface, buffer, offset, protocol);

    //Free previously allocated memory block
    netBufferFree(buffer);
    //Return status code
    return error;
}
Пример #4
0
error_t chapSendFailure(PppContext *context)
{
   error_t error;
   size_t length;
   size_t offset;
   NetBuffer *buffer;
   PppPacket *failurePacket;

   //Retrieve the length of the Failure packet
   length = sizeof(PppPacket);

   //Allocate a buffer memory to hold the Failure packet
   buffer = pppAllocBuffer(length, &offset);
   //Failed to allocate memory?
   if(!buffer) return ERROR_OUT_OF_MEMORY;

   //Point to the Failure packet
   failurePacket = netBufferAt(buffer, offset);

   //Format packet header
   failurePacket->code = CHAP_CODE_FAILURE;
   failurePacket->identifier = context->chapFsm.localIdentifier;
   failurePacket->length = htons(length);

   //Debug message
   TRACE_INFO("Sending CHAP Failure packet (%" PRIuSIZE " bytes)...\r\n", length);
   //Dump packet contents for debugging purpose
   pppDumpPacket((PppPacket *) failurePacket, length, PPP_PROTOCOL_CHAP);

   //Send PPP frame
   error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);

   //Free previously allocated memory block
   netBufferFree(buffer);
   //Return status code
   return error;
}
Пример #5
0
error_t lcpSendConfigureReq(PppContext *context)
{
   error_t error;
   size_t length;
   size_t offset;
   NetBuffer *buffer;
   PppConfigurePacket *configureReqPacket;

   //Debug message
   TRACE_INFO("LCP Send-Configure-Request callback\r\n");

   //Calculate the maximum size of the Configure-Request packet
   length = sizeof(PppConfigurePacket) +
      sizeof(LcpMruOption) + sizeof(LcpAccmOption);

   //Allocate a buffer memory to hold the packet
   buffer = pppAllocBuffer(length, &offset);
   //Failed to allocate memory?
   if(!buffer) return ERROR_OUT_OF_MEMORY;

   //Point to the Configure-Request packet
   configureReqPacket = netBufferAt(buffer, offset);

   //Format packet header
   configureReqPacket->code = PPP_CODE_CONFIGURE_REQ;
   configureReqPacket->identifier = ++context->lcpFsm.identifier;
   configureReqPacket->length = sizeof(PppConfigurePacket);

   //Make sure the Maximum-Receive-Unit option has not been previously rejected
   if(!context->localConfig.mruRejected)
   {
      //Convert MRU to network byte order
      uint16_t value = htons(context->localConfig.mru);
      //Add option
      pppAddOption(configureReqPacket, LCP_OPTION_MRU, &value, sizeof(uint16_t));
   }

   //Make sure the Async-Control-Character-Map option has not been previously rejected
   if(!context->localConfig.accmRejected)
   {
      //Convert ACCM to network byte order
      uint32_t value = htonl(context->localConfig.accm);
      //Add option
      pppAddOption(configureReqPacket, LCP_OPTION_ACCM, &value, sizeof(uint32_t));
   }

   //Save packet length
   length = configureReqPacket->length;
   //Convert length field to network byte order
   configureReqPacket->length = htons(length);

   //Adjust the length of the multi-part buffer
   netBufferSetLength(buffer, offset + length);

   //Debug message
   TRACE_INFO("Sending Configure-Request packet (%" PRIuSIZE " bytes)...\r\n", length);
   //Dump packet contents for debugging purpose
   pppDumpPacket((PppPacket *) configureReqPacket, length, PPP_PROTOCOL_LCP);

   //Send PPP frame
   error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_LCP);

   //The restart counter is decremented each time a Configure-Request is sent
   if(context->lcpFsm.restartCounter > 0)
      context->lcpFsm.restartCounter--;

   //Save the time at which the packet was sent
   context->lcpFsm.timestamp = osGetSystemTime();

   //Free previously allocated memory block
   netBufferFree(buffer);
   //Return status code
   return error;
}
Пример #6
0
void lcpProcessPacket(PppContext *context, const PppPacket *packet, size_t length)
{
   //Ensure the length of the incoming LCP packet is valid
   if(length < sizeof(PppPacket))
      return;

   //Check the length field
   if(ntohs(packet->length) > length)
      return;
   if(ntohs(packet->length) < sizeof(PppPacket))
      return;

   //Save the length of the LCP packet
   length = ntohs(packet->length);

   //Debug message
   TRACE_INFO("LCP packet received (%" PRIuSIZE " bytes)...\r\n", length);
   //Dump LCP packet contents for debugging purpose
   pppDumpPacket(packet, length, PPP_PROTOCOL_LCP);

   //Check LCP code field
   switch(packet->code)
   {
   //Configure-Request packet?
   case PPP_CODE_CONFIGURE_REQ:
      //Process Configure-Request packet
      lcpProcessConfigureReq(context, (PppConfigurePacket *) packet);
      break;
   //Configure-Ack packet?
   case PPP_CODE_CONFIGURE_ACK:
      //Process Configure-Ack packet
      lcpProcessConfigureAck(context, (PppConfigurePacket *) packet);
      break;
   //Configure-Nak packet?
   case PPP_CODE_CONFIGURE_NAK:
      //Process Configure-Nak packet
      lcpProcessConfigureNak(context, (PppConfigurePacket *) packet);
      break;
   //Configure-Reject packet?
   case PPP_CODE_CONFIGURE_REJ:
      //Process Configure-Reject packet
      lcpProcessConfigureReject(context, (PppConfigurePacket *) packet);
      break;
   //Terminate-Request packet?
   case PPP_CODE_TERMINATE_REQ:
      //Process Terminate-Request packet
      lcpProcessTerminateReq(context, (PppTerminatePacket *) packet);
      break;
   //Terminate-Ack packet?
   case PPP_CODE_TERMINATE_ACK:
      //Process Terminate-Ack packet
      lcpProcessTerminateAck(context, (PppTerminatePacket *) packet);
      break;
   //Code-Reject packet?
   case PPP_CODE_CODE_REJ:
      //Process Code-Reject packet
      lcpProcessCodeRej(context, (PppCodeRejPacket *) packet);
      break;
   //Protocol-Reject packet?
   case PPP_CODE_PROTOCOL_REJ:
      //Process Protocol-Reject packet
      lcpProcessProtocolRej(context, (PppProtocolRejPacket *) packet);
      break;
   //Echo-Request packet?
   case PPP_CODE_ECHO_REQ:
      //Process Echo-Request packet
      lcpProcessEchoReq(context, (PppEchoPacket *) packet);
      break;
   //Echo-Reply packet?
   case PPP_CODE_ECHO_REP:
      //Process Echo-Reply packet
      lcpProcessEchoRep(context, (PppEchoPacket *) packet);
      break;
   //Discard-Request packet?
   case PPP_CODE_DISCARD_REQ:
      //Process Discard-Request packet
      lcpProcessDiscardReq(context, (PppDiscardReqPacket *) packet);
      break;
   //Unknown code field
   default:
      //The packet is un-interpretable
      lcpProcessUnknownCode(context, packet);
      break;
   }
}
Пример #7
0
error_t pppSendConfigureAckNak(PppContext *context,
                               const PppConfigurePacket *configureReqPacket, PppProtocol protocol, PppCode code)
{
    error_t error;
    size_t length;
    size_t offset;
    NetBuffer *buffer;
    PppConfigurePacket *configureAckNakPacket;
    PppOption *option;

    //Initialize status code
    error = NO_ERROR;
    //Retrieve the length of the Configure-Request packet
    length = ntohs(configureReqPacket->length);

    //Allocate a buffer memory to hold the Configure-Ack, Nak or Reject packet
    buffer = pppAllocBuffer(length, &offset);
    //Failed to allocate memory?
    if(!buffer) return ERROR_OUT_OF_MEMORY;

    //Point to the beginning of the packet
    configureAckNakPacket = netBufferAt(buffer, offset);

    //Format packet header
    configureAckNakPacket->code = code;
    configureAckNakPacket->identifier = configureReqPacket->identifier;
    configureAckNakPacket->length = sizeof(PppConfigurePacket);

    //Retrieve the length of the option list
    length -= sizeof(PppConfigurePacket);
    //Point to the first option
    option = (PppOption *) configureReqPacket->options;

    //Parse configuration options
    while(length > 0)
    {
        //LCP protocol?
        if(protocol == PPP_PROTOCOL_LCP)
        {
            //Parse LCP option
            lcpParseOption(context, option, length, configureAckNakPacket);
        }
#if (IPV4_SUPPORT)
        //IPCP protocol?
        else if(protocol == PPP_PROTOCOL_IPCP)
        {
            //Parse IPCP option
            ipcpParseOption(context, option, length, configureAckNakPacket);
        }
#endif

        //Remaining bytes to process
        length -= option->length;
        //Jump to the next option
        option = (PppOption *) ((uint8_t *) option + option->length);
    }

    //Adjust the length of the multi-part buffer
    netBufferSetLength(buffer, offset + configureAckNakPacket->length);
    //Convert length field to network byte order
    configureAckNakPacket->length = htons(configureAckNakPacket->length);

    //Debug message
    if(code == PPP_CODE_CONFIGURE_ACK)
    {
        TRACE_INFO("Sending Configure-Ack packet (%" PRIuSIZE " bytes)...\r\n",
                   ntohs(configureAckNakPacket->length));
    }
    else if(code == PPP_CODE_CONFIGURE_NAK)
    {
        TRACE_INFO("Sending Configure-Nak packet (%" PRIuSIZE " bytes)...\r\n",
                   ntohs(configureAckNakPacket->length));
    }
    else if(code == PPP_CODE_CONFIGURE_REJ)
    {
        TRACE_INFO("Sending Configure-Reject packet (%" PRIuSIZE " bytes)...\r\n",
                   ntohs(configureAckNakPacket->length));
    }

    //Dump packet contents for debugging purpose
    pppDumpPacket((PppPacket *) configureAckNakPacket,
                  ntohs(configureAckNakPacket->length), protocol);

    //Send PPP frame
    error = pppSendFrame(context->interface, buffer, offset, protocol);

    //Free previously allocated memory block
    netBufferFree(buffer);
    //Return status code
    return error;
}
Пример #8
0
error_t chapSendChallenge(PppContext *context)
{
   error_t error;
   size_t n;
   size_t length;
   size_t offset;
   NetBuffer *buffer;
   ChapChallengePacket *challengePacket;

   //Retrieve the length of the username
   n = strlen(context->username);
   //Calculate the length of the Challenge packet
   length = sizeof(ChapChallengePacket) + MD5_DIGEST_SIZE + n;

   //Allocate a buffer memory to hold the Challenge packet
   buffer = pppAllocBuffer(length, &offset);
   //Failed to allocate memory?
   if(!buffer) return ERROR_OUT_OF_MEMORY;

   //Point to the Challenge packet
   challengePacket = netBufferAt(buffer, offset);

   //Format packet header
   challengePacket->code = CHAP_CODE_CHALLENGE;
   challengePacket->identifier = ++context->chapFsm.localIdentifier;
   challengePacket->length = htons(length);
   challengePacket->valueSize = MD5_DIGEST_SIZE;

   //Make sure that the callback function has been registered
   if(context->settings.randCallback != NULL)
   {
      //Generate a random challenge value
      error = context->settings.randCallback(
         context->chapFsm.challenge, MD5_DIGEST_SIZE);
   }
   else
   {
      //Report an error
      error = ERROR_FAILURE;
   }

   //Check status code
   if(!error)
   {
      //Copy the challenge value
      memcpy(challengePacket->value, context->chapFsm.challenge, MD5_DIGEST_SIZE);

      //The Name field is one or more octets representing the
      //identification of the system transmitting the packet
      memcpy(challengePacket->value + MD5_DIGEST_SIZE, context->username, n);

      //Debug message
      TRACE_INFO("Sending CHAP Challenge packet (%" PRIuSIZE " bytes)...\r\n", length);
      //Dump packet contents for debugging purpose
      pppDumpPacket((PppPacket *) challengePacket, length, PPP_PROTOCOL_CHAP);

      //Send PPP frame
      error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);

      //The restart counter is decremented each time a Challenge packet is sent
      if(context->chapFsm.restartCounter > 0)
         context->chapFsm.restartCounter--;

      //Save the time at which the packet was sent
      context->chapFsm.timestamp = osGetSystemTime();
   }

   //Free previously allocated memory block
   netBufferFree(buffer);
   //Return status code
   return error;
}