Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ppp_misc.c Source File

ppp_misc.c

Go to the documentation of this file.
00001 /**
00002  * @file ppp_misc.c
00003  * @brief PPP miscellaneous functions
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This file is part of CycloneTCP Open.
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software Foundation,
00023  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00024  *
00025  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00026  * @version 1.7.6
00027  **/
00028 
00029 //Switch to the appropriate trace level
00030 #define TRACE_LEVEL PPP_TRACE_LEVEL
00031 
00032 //Dependencies
00033 #include "core/net.h"
00034 #include "ppp/ppp_misc.h"
00035 #include "ppp/ppp_debug.h"
00036 #include "ppp/lcp.h"
00037 #include "ppp/ipcp.h"
00038 #include "ppp/ipv6cp.h"
00039 #include "debug.h"
00040 
00041 //Check TCP/IP stack configuration
00042 #if (PPP_SUPPORT == ENABLED)
00043 
00044 
00045 /**
00046  * @brief Send Configure-Ack, Nak or Reject packet
00047  * @param[in] context PPP context
00048  * @param[in] configureReqPacket Pointer to the incoming Configure-Request
00049  * @param[in] protocol Protocol field
00050  * @param[in] code Code field
00051  * @return Error code
00052  **/
00053 
00054 error_t pppSendConfigureAckNak(PppContext *context,
00055    const PppConfigurePacket *configureReqPacket, PppProtocol protocol, PppCode code)
00056 {
00057    error_t error;
00058    size_t length;
00059    size_t offset;
00060    NetBuffer *buffer;
00061    PppConfigurePacket *configureAckNakPacket;
00062    PppOption *option;
00063 
00064    //Initialize status code
00065    error = NO_ERROR;
00066    //Retrieve the length of the Configure-Request packet
00067    length = ntohs(configureReqPacket->length);
00068 
00069    //Allocate a buffer memory to hold the Configure-Ack, Nak or Reject packet
00070    buffer = pppAllocBuffer(length, &offset);
00071    //Failed to allocate memory?
00072    if(buffer == NULL)
00073       return ERROR_OUT_OF_MEMORY;
00074 
00075    //Point to the beginning of the packet
00076    configureAckNakPacket = netBufferAt(buffer, offset);
00077 
00078    //Format packet header
00079    configureAckNakPacket->code = code;
00080    configureAckNakPacket->identifier = configureReqPacket->identifier;
00081    configureAckNakPacket->length = sizeof(PppConfigurePacket);
00082 
00083    //Retrieve the length of the option list
00084    length -= sizeof(PppConfigurePacket);
00085    //Point to the first option
00086    option = (PppOption *) configureReqPacket->options;
00087 
00088    //Parse configuration options
00089    while(length > 0)
00090    {
00091       //LCP protocol?
00092       if(protocol == PPP_PROTOCOL_LCP)
00093       {
00094          //Parse LCP option
00095          lcpParseOption(context, option, length, configureAckNakPacket);
00096       }
00097 #if (IPV4_SUPPORT == ENABLED)
00098       //IPCP protocol?
00099       else if(protocol == PPP_PROTOCOL_IPCP)
00100       {
00101          //Parse IPCP option
00102          ipcpParseOption(context, option, length, configureAckNakPacket);
00103       }
00104 #endif
00105 #if (IPV6_SUPPORT == ENABLED)
00106       //IPV6CP protocol?
00107       else if(protocol == PPP_PROTOCOL_IPV6CP)
00108       {
00109          //Parse IPV6CP option
00110          ipv6cpParseOption(context, option, length, configureAckNakPacket);
00111       }
00112 #endif
00113 
00114       //Remaining bytes to process
00115       length -= option->length;
00116       //Jump to the next option
00117       option = (PppOption *) ((uint8_t *) option + option->length);
00118    }
00119 
00120    //Adjust the length of the multi-part buffer
00121    netBufferSetLength(buffer, offset + configureAckNakPacket->length);
00122    //Convert length field to network byte order
00123    configureAckNakPacket->length = htons(configureAckNakPacket->length);
00124 
00125    //Debug message
00126    if(code == PPP_CODE_CONFIGURE_ACK)
00127    {
00128       TRACE_INFO("Sending Configure-Ack packet (%" PRIuSIZE " bytes)...\r\n",
00129          ntohs(configureAckNakPacket->length));
00130    }
00131    else if(code == PPP_CODE_CONFIGURE_NAK)
00132    {
00133       TRACE_INFO("Sending Configure-Nak packet (%" PRIuSIZE " bytes)...\r\n",
00134          ntohs(configureAckNakPacket->length));
00135    }
00136    else if(code == PPP_CODE_CONFIGURE_REJ)
00137    {
00138       TRACE_INFO("Sending Configure-Reject packet (%" PRIuSIZE " bytes)...\r\n",
00139          ntohs(configureAckNakPacket->length));
00140    }
00141 
00142    //Dump packet contents for debugging purpose
00143    pppDumpPacket((PppPacket *) configureAckNakPacket,
00144       ntohs(configureAckNakPacket->length), protocol);
00145 
00146    //Send PPP frame
00147    error = pppSendFrame(context->interface, buffer, offset, protocol);
00148 
00149    //Free previously allocated memory block
00150    netBufferFree(buffer);
00151    //Return status code
00152    return error;
00153 }
00154 
00155 
00156 /**
00157  * @brief Send Terminate-Request packet
00158  * @param[in] context PPP context
00159  * @param[in] identifier Identifier field
00160  * @param[in] protocol Protocol field
00161  * @return Error code
00162  **/
00163 
00164 error_t pppSendTerminateReq(PppContext *context,
00165    uint8_t identifier, PppProtocol protocol)
00166 {
00167    error_t error;
00168    size_t length;
00169    size_t offset;
00170    NetBuffer *buffer;
00171    PppTerminatePacket *terminateReqPacket;
00172 
00173    //Length of the Terminate-Request packet
00174    length = sizeof(PppTerminatePacket);
00175 
00176    //Allocate a buffer memory to hold the Terminate-Request packet
00177    buffer = pppAllocBuffer(length, &offset);
00178    //Failed to allocate memory?
00179    if(buffer == NULL)
00180       return ERROR_OUT_OF_MEMORY;
00181 
00182    //Point to the Terminate-Request packet
00183    terminateReqPacket = netBufferAt(buffer, offset);
00184 
00185    //Format packet header
00186    terminateReqPacket->code = PPP_CODE_TERMINATE_REQ;
00187    terminateReqPacket->identifier = identifier;
00188    terminateReqPacket->length = htons(length);
00189 
00190    //Debug message
00191    TRACE_INFO("Sending Terminate-Request packet (%" PRIuSIZE " bytes)...\r\n", length);
00192    //Dump packet contents for debugging purpose
00193    pppDumpPacket((PppPacket *) terminateReqPacket, length, protocol);
00194 
00195    //Send PPP frame
00196    error = pppSendFrame(context->interface, buffer, offset, protocol);
00197 
00198    //Free previously allocated memory block
00199    netBufferFree(buffer);
00200    //Return status code
00201    return error;
00202 }
00203 
00204 
00205 /**
00206  * @brief Send Terminate-Ack packet
00207  * @param[in] context PPP context
00208  * @param[in] identifier Identifier field
00209  * @param[in] protocol Protocol field
00210  * @return Error code
00211  **/
00212 
00213 error_t pppSendTerminateAck(PppContext *context,
00214    uint8_t identifier, PppProtocol protocol)
00215 {
00216    error_t error;
00217    size_t length;
00218    size_t offset;
00219    NetBuffer *buffer;
00220    PppTerminatePacket *terminateAckPacket;
00221 
00222    //Length of the Terminate-Ack packet
00223    length = sizeof(PppTerminatePacket);
00224 
00225    //Allocate a buffer memory to hold the Terminate-Ack packet
00226    buffer = pppAllocBuffer(length, &offset);
00227    //Failed to allocate memory?
00228    if(buffer == NULL)
00229       return ERROR_OUT_OF_MEMORY;
00230 
00231    //Point to the Terminate-Ack packet
00232    terminateAckPacket = netBufferAt(buffer, offset);
00233 
00234    //Format packet header
00235    terminateAckPacket->code = PPP_CODE_TERMINATE_ACK;
00236    terminateAckPacket->identifier = identifier;
00237    terminateAckPacket->length = htons(length);
00238 
00239    //Debug message
00240    TRACE_INFO("Sending Terminate-Ack packet (%" PRIuSIZE " bytes)...\r\n", length);
00241    //Dump packet contents for debugging purpose
00242    pppDumpPacket((PppPacket *) terminateAckPacket, length, protocol);
00243 
00244    //Send PPP frame
00245    error = pppSendFrame(context->interface, buffer, offset, protocol);
00246 
00247    //Free previously allocated memory block
00248    netBufferFree(buffer);
00249    //Return status code
00250    return error;
00251 }
00252 
00253 
00254 /**
00255  * @brief Send Code-Reject packet
00256  * @param[in] context PPP context
00257  * @param[in] packet Un-interpretable packet received from the peer
00258  * @param[in] identifier Identifier field
00259  * @param[in] protocol Protocol field
00260  * @return Error code
00261  **/
00262 
00263 error_t pppSendCodeRej(PppContext *context, const PppPacket *packet,
00264    uint8_t identifier, PppProtocol protocol)
00265 {
00266    error_t error;
00267    size_t length;
00268    size_t offset;
00269    NetBuffer *buffer;
00270    PppCodeRejPacket *codeRejPacket;
00271 
00272    //Calculate the length of the Code-Reject packet
00273    length = ntohs(packet->length) + sizeof(PppCodeRejPacket);
00274 
00275    //The rejected packet must be truncated to comply with
00276    //the peer's established MRU
00277    length = MIN(length, context->peerConfig.mru);
00278 
00279    //Allocate a buffer memory to hold the Code-Reject packet
00280    buffer = pppAllocBuffer(sizeof(PppCodeRejPacket), &offset);
00281    //Failed to allocate memory?
00282    if(buffer == NULL)
00283       return ERROR_OUT_OF_MEMORY;
00284 
00285    //Point to the Code-Reject packet
00286    codeRejPacket = netBufferAt(buffer, offset);
00287 
00288    //Format packet header
00289    codeRejPacket->code = PPP_CODE_CODE_REJ;
00290    codeRejPacket->identifier = identifier;
00291    codeRejPacket->length = htons(length);
00292 
00293    //The Rejected-Packet field contains a copy of the packet which is being rejected
00294    error = netBufferAppend(buffer, packet, length - sizeof(PppCodeRejPacket));
00295 
00296    //Check status code
00297    if(!error)
00298    {
00299       //Debug message
00300       TRACE_INFO("Sending Code-Reject packet (%" PRIuSIZE " bytes)...\r\n", length);
00301 
00302       //Send PPP frame
00303       error = pppSendFrame(context->interface, buffer, offset, protocol);
00304    }
00305 
00306    //Free previously allocated memory block
00307    netBufferFree(buffer);
00308    //Return status code
00309    return error;
00310 }
00311 
00312 
00313 /**
00314  * @brief Send Protocol-Reject packet
00315  * @param[in] context PPP context
00316  * @param[in] identifier Identifier field
00317  * @param[in] protocol Rejected protocol
00318  * @param[in] information Rejected information
00319  * @param[in] length Length of the rejected information
00320  * @return Error code
00321  **/
00322 
00323 error_t pppSendProtocolRej(PppContext *context, uint8_t identifier,
00324    uint16_t protocol, const uint8_t *information, size_t length)
00325 {
00326    error_t error;
00327    size_t offset;
00328    NetBuffer *buffer;
00329    PppProtocolRejPacket *protocolRejPacket;
00330 
00331    //Calculate the length of the Protocol-Reject packet
00332    length += sizeof(PppProtocolRejPacket);
00333 
00334    //The Rejected-Information must be truncated to comply with
00335    //the peer's established MRU
00336    length = MIN(length, context->peerConfig.mru);
00337 
00338    //Allocate a buffer memory to hold the Protocol-Reject packet
00339    buffer = pppAllocBuffer(sizeof(PppProtocolRejPacket), &offset);
00340    //Failed to allocate memory?
00341    if(buffer == NULL)
00342       return ERROR_OUT_OF_MEMORY;
00343 
00344    //Point to the Protocol-Reject packet
00345    protocolRejPacket = netBufferAt(buffer, offset);
00346 
00347    //Format packet header
00348    protocolRejPacket->code = PPP_CODE_PROTOCOL_REJ;
00349    protocolRejPacket->identifier = identifier;
00350    protocolRejPacket->length = htons(length);
00351    protocolRejPacket->rejectedProtocol = htons(protocol);
00352 
00353    //The Rejected-Information field contains a copy of the
00354    //packet which is being rejected
00355    error = netBufferAppend(buffer, information,
00356       length - sizeof(PppProtocolRejPacket));
00357 
00358    //Check status code
00359    if(!error)
00360    {
00361       //Debug message
00362       TRACE_INFO("Sending Protocol-Reject packet (%" PRIuSIZE " bytes)...\r\n", length);
00363 
00364       //Send PPP frame
00365       error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_LCP);
00366    }
00367 
00368    //Free previously allocated memory block
00369    netBufferFree(buffer);
00370    //Return status code
00371    return error;
00372 }
00373 
00374 
00375 /**
00376  * @brief Send Echo-Reply packet
00377  * @param[in] context PPP context
00378  * @param[in] echoReqPacket Echo-Request packet received from the peer
00379  * @param[in] protocol Protocol field
00380  * @return Error code
00381  **/
00382 
00383 error_t pppSendEchoRep(PppContext *context,
00384    const PppEchoPacket *echoReqPacket, PppProtocol protocol)
00385 {
00386    error_t error;
00387    size_t length;
00388    size_t offset;
00389    NetBuffer *buffer;
00390    PppEchoPacket *echoRepPacket;
00391 
00392    //Retrieve the length of the Echo-Request packet
00393    length = ntohs(echoReqPacket->length);
00394 
00395    //Make sure the length is valid
00396    if(length < sizeof(PppEchoPacket))
00397       return ERROR_INVALID_LENGTH;
00398    if(length > context->peerConfig.mru)
00399       return ERROR_INVALID_LENGTH;
00400 
00401    //Allocate a buffer memory to hold the Echo-Reply packet
00402    buffer = pppAllocBuffer(sizeof(PppEchoPacket), &offset);
00403    //Failed to allocate memory?
00404    if(buffer == NULL)
00405       return ERROR_OUT_OF_MEMORY;
00406 
00407    //Point to the Echo-Reply packet
00408    echoRepPacket = netBufferAt(buffer, offset);
00409 
00410    //Format packet header
00411    echoRepPacket->code = PPP_CODE_ECHO_REP;
00412    echoRepPacket->identifier = echoReqPacket->identifier;
00413    echoRepPacket->length = htons(length);
00414    echoRepPacket->magicNumber = context->localConfig.magicNumber;
00415 
00416    //The data field of the Echo-Request packet is copied into the data
00417    //field of the Echo-Reply packet
00418    error = netBufferAppend(buffer, echoReqPacket->data, length - sizeof(PppEchoPacket));
00419 
00420    //Check status code
00421    if(!error)
00422    {
00423       //Debug message
00424       TRACE_INFO("Sending Echo-Reply packet (%" PRIuSIZE " bytes)...\r\n", length);
00425 
00426       //Send PPP frame
00427       error = pppSendFrame(context->interface, buffer, offset, protocol);
00428    }
00429 
00430    //Free previously allocated memory block
00431    netBufferFree(buffer);
00432    //Return status code
00433    return error;
00434 }
00435 
00436 
00437 /**
00438  * @brief Add an option to a Configure packet
00439  * @param[in,out] packet Pointer to the Configure packet
00440  * @param[in] optionType Option type
00441  * @param[in] optionValue Option value
00442  * @param[in] optionLen Length of the option value
00443  * @return Error code
00444  **/
00445 
00446 error_t pppAddOption(PppConfigurePacket *packet, uint8_t optionType,
00447    const void *optionValue, uint8_t optionLen)
00448 {
00449    PppOption *option;
00450 
00451    //Make sure the length is valid
00452    if(optionLen > (UINT8_MAX - sizeof(PppOption)))
00453       return ERROR_INVALID_LENGTH;
00454 
00455    //Point to the end of the Configure packet
00456    option = (PppOption *) ((uint8_t *) packet + packet->length);
00457 
00458    //Write specified option at current location
00459    option->type = optionType;
00460    option->length = optionLen + sizeof(PppOption);
00461    //Copy option data
00462    memcpy(option->data, optionValue, optionLen);
00463 
00464    //Update the length of the Configure packet
00465    packet->length += optionLen + sizeof(PppOption);
00466 
00467    //Successful processing
00468    return NO_ERROR;
00469 }
00470 
00471 #endif
00472