Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ppp_debug.c Source File

ppp_debug.c

Go to the documentation of this file.
00001 /**
00002  * @file ppp_debug.c
00003  * @brief Data logging functions for debugging purpose (PPP)
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 //Dependencies
00030 #include "core/net.h"
00031 #include "ppp/ppp_debug.h"
00032 #include "debug.h"
00033 
00034 //Check TCP/IP stack configuration
00035 #if (PPP_SUPPORT == ENABLED && PPP_TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
00036 
00037 //LCP codes
00038 static const char_t *lcpCodeLabel[] =
00039 {
00040    "",                  //0
00041    "Configure-Request", //1
00042    "Configure-Ack",     //2
00043    "Configure-Nak",     //3
00044    "Configure-Reject",  //4
00045    "Terminate-Request", //5
00046    "Terminate-Ack",     //6
00047    "Code-Reject",       //7
00048    "Protocol-Reject",   //8
00049    "Echo-Request",      //9
00050    "Echo-Reply",        //10
00051    "Discard-Request"    //11
00052 };
00053 
00054 //NCP codes
00055 static const char_t *ncpCodeLabel[] =
00056 {
00057    "",                  //0
00058    "Configure-Request", //1
00059    "Configure-Ack",     //2
00060    "Configure-Nak",     //3
00061    "Configure-Reject",  //4
00062    "Terminate-Request", //5
00063    "Terminate-Ack",     //6
00064    "Code-Reject"        //7
00065 };
00066 
00067 //PAP codes
00068 static const char_t *papCodeLabel[] =
00069 {
00070    "",                     //0
00071    "Authenticate-Request", //1
00072    "Authenticate-Ack",     //2
00073    "Authenticate-Nak"      //3
00074 };
00075 
00076 //CHAP codes
00077 static const char_t *chapCodeLabel[] =
00078 {
00079    "",          //0
00080    "Challenge", //1
00081    "Response",  //2
00082    "Success",   //3
00083    "Failure"    //4
00084 };
00085 
00086 //LCP options
00087 static const char_t *lcpOptionLabel[] =
00088 {
00089    "",                                      //0
00090    "Maximum-Receive-Unit",                  //1
00091    "Async-Control-Character-Map",           //2
00092    "Authentication-Protocol",               //3
00093    "Quality-Protocol",                      //4
00094    "Magic-Number",                          //5
00095    "",                                      //6
00096    "Protocol-Field-Compression",            //7
00097    "Address-and-Control-Field-Compression", //8
00098    "FCS-Alternatives",                      //9
00099    "Self-Describing-Pad",                   //10
00100    "Numbered-Mode",                         //11
00101    "",                                      //12
00102    "Callback"                               //13
00103 };
00104 
00105 //IPCP options
00106 static const char_t *ipcpOptionLabel[] =
00107 {
00108    "",                        //0
00109    "IP-Addresses",            //1
00110    "IP-Compression-Protocol", //2
00111    "IP-Address",              //3
00112    "Mobile-IPv4",             //4
00113 };
00114 
00115 static const char_t *ipcpOptionLabel2[] =
00116 {
00117    "",                             //128
00118    "Primary-DNS-Server-Address",   //129
00119    "Primary-NBNS-Server-Address",  //130
00120    "Secondary-DNS-Server-Address", //131
00121    "Secondary-NBNS-Server-Address" //132
00122 };
00123 
00124 //IPV6CP options
00125 static const char_t *ipv6cpOptionLabel[] =
00126 {
00127    "",                         //0
00128    "Interface-Identifier",     //1
00129    "IPv6-Compression-Protocol" //2
00130 };
00131 
00132 
00133 /**
00134  * @brief Dump LCP/NCP packet for debugging purpose
00135  * @param[in] packet Pointer to the LCP packet
00136  * @param[in] length Length of the packet, in bytes
00137  * @param[in] protocol Protocol field
00138  * @return Error code
00139  **/
00140 
00141 error_t pppDumpPacket(const PppPacket *packet, size_t length, PppProtocol protocol)
00142 {
00143    error_t error;
00144 
00145    //Check protocol field
00146    switch(protocol)
00147    {
00148       //LCP packet?
00149       case PPP_PROTOCOL_LCP:
00150          error = lcpDumpPacket(packet, length);
00151          break;
00152       //NCP packet?
00153       case PPP_PROTOCOL_IPCP:
00154       case PPP_PROTOCOL_IPV6CP:
00155          error = ncpDumpPacket(packet, length, protocol);
00156          break;
00157       //PAP packet?
00158       case PPP_PROTOCOL_PAP:
00159          error = papDumpPacket(packet, length);
00160          break;
00161       //CHAP packet?
00162       case PPP_PROTOCOL_CHAP:
00163          error = chapDumpPacket(packet, length);
00164          break;
00165       //Unknown protocol?
00166       default:
00167          error = ERROR_FAILURE;
00168          break;
00169    }
00170 
00171    //Return status code
00172    return error;
00173 }
00174 
00175 
00176 /**
00177  * @brief Dump LCP packet for debugging purpose
00178  * @param[in] packet Pointer to the LCP packet
00179  * @param[in] length Length of the packet, in bytes
00180  * @return Error code
00181  **/
00182 
00183 error_t lcpDumpPacket(const PppPacket *packet, size_t length)
00184 {
00185    error_t error;
00186    const char_t *label;
00187 
00188    //Make sure the LCP packet is valid
00189    if(length < sizeof(PppPacket))
00190       return ERROR_INVALID_LENGTH;
00191 
00192    //Check the length field
00193    if(ntohs(packet->length) > length)
00194       return ERROR_INVALID_LENGTH;
00195    if(ntohs(packet->length) < sizeof(PppPacket))
00196       return ERROR_INVALID_LENGTH;
00197 
00198    //Save the length of the LCP packet
00199    length = ntohs(packet->length);
00200 
00201    //Retrieve the name of the LCP packet
00202    if(packet->code < arraysize(lcpCodeLabel))
00203       label = lcpCodeLabel[packet->code];
00204    else
00205       label = "Unknown";
00206 
00207    //Dump LCP packet header
00208    TRACE_DEBUG("  Code = %" PRIu8 " (%s)\r\n", packet->code, label);
00209    TRACE_DEBUG("  Identifier = %" PRIu8  "\r\n", packet->identifier);
00210    TRACE_DEBUG("  Length = %" PRIu16 "\r\n", ntohs(packet->length));
00211 
00212    //Configure-Request, Configure-Ack, Configure-Nak or Configure-Reject packet?
00213    if(packet->code == PPP_CODE_CONFIGURE_REQ ||
00214       packet->code == PPP_CODE_CONFIGURE_ACK ||
00215       packet->code == PPP_CODE_CONFIGURE_NAK ||
00216       packet->code == PPP_CODE_CONFIGURE_REJ)
00217    {
00218       //Cast LCP packet
00219       PppConfigurePacket *p = (PppConfigurePacket *) packet;
00220 
00221       //Valid packet length?
00222       if(length < sizeof(PppConfigurePacket))
00223          return ERROR_INVALID_LENGTH;
00224 
00225       //Retrieve the length of the option list
00226       length -= sizeof(PppConfigurePacket);
00227 
00228       //Dump options
00229       error = lcpDumpOptions((PppOption *) p->options, length);
00230       //Any error to report?
00231       if(error)
00232          return error;
00233    }
00234    //Terminate-Request or Terminate-Ack packet?
00235    else if(packet->code == PPP_CODE_TERMINATE_REQ ||
00236       packet->code == PPP_CODE_TERMINATE_ACK)
00237    {
00238       //Cast LCP packet
00239       PppTerminatePacket *p = (PppTerminatePacket *) packet;
00240 
00241       //Valid packet length?
00242       if(length < sizeof(PppTerminatePacket))
00243          return ERROR_INVALID_LENGTH;
00244 
00245       //Retrieve the length of data
00246       length -= sizeof(PppTerminatePacket);
00247 
00248       //Any data?
00249       if(length > 0)
00250       {
00251          //Dump data
00252          TRACE_DEBUG("  Data (%" PRIuSIZE " bytes)\r\n", length);
00253          TRACE_DEBUG_ARRAY("    ", p->data, length);
00254       }
00255    }
00256    //Code-Reject packet?
00257    else if(packet->code == PPP_CODE_CODE_REJ)
00258    {
00259       //Cast LCP packet
00260       PppCodeRejPacket *p = (PppCodeRejPacket *) packet;
00261 
00262       //Valid packet length?
00263       if(length < sizeof(PppCodeRejPacket))
00264          return ERROR_INVALID_LENGTH;
00265 
00266       //Retrieve the length of Rejected-Packet field
00267       length -= sizeof(PppCodeRejPacket);
00268 
00269       //Rejected-Packet
00270       TRACE_DEBUG("  Rejected-Packet (%" PRIuSIZE " bytes)\r\n", length);
00271       TRACE_DEBUG_ARRAY("    ", p->rejectedPacket, length);
00272    }
00273    //Protocol-Reject packet?
00274    else if(packet->code == PPP_CODE_PROTOCOL_REJ)
00275    {
00276       //Cast LCP packet
00277       PppProtocolRejPacket *p = (PppProtocolRejPacket *) packet;
00278 
00279       //Valid packet length?
00280       if(length < sizeof(PppProtocolRejPacket))
00281          return ERROR_INVALID_LENGTH;
00282 
00283       //Retrieve the length of Rejected-Information field
00284       length -= sizeof(PppProtocolRejPacket);
00285 
00286       //Rejected-Protocol
00287       TRACE_DEBUG("  Rejected-Protocol = %" PRIu16 "\r\n", htons(p->rejectedProtocol));
00288       //Rejected-Information
00289       TRACE_DEBUG("  Rejected-Information (%" PRIuSIZE " bytes)\r\n", length);
00290       TRACE_DEBUG_ARRAY("    ", p->rejectedInfo, length);
00291    }
00292    //Echo-Request, Echo-Reply or Discard-Request packet?
00293    else if(packet->code == PPP_CODE_ECHO_REQ ||
00294       packet->code == PPP_CODE_ECHO_REP ||
00295       packet->code == PPP_CODE_DISCARD_REQ)
00296    {
00297       //Cast LCP packet
00298       PppEchoPacket *p = (PppEchoPacket *) packet;
00299 
00300       //Valid packet length?
00301       if(length < sizeof(PppEchoPacket))
00302          return ERROR_INVALID_LENGTH;
00303 
00304       //Retrieve the length of data
00305       length -= sizeof(PppEchoPacket);
00306 
00307       //Magic-Number
00308       TRACE_DEBUG("  Magic-Number = %" PRIu32 "\r\n", htonl(p->magicNumber));
00309       //Data
00310       TRACE_DEBUG("  Data (%" PRIuSIZE " bytes)\r\n", length);
00311       TRACE_DEBUG_ARRAY("    ", p->data, length);
00312    }
00313    //Unknown packet?
00314    else
00315    {
00316       //Retrieve the length of data
00317       length -= sizeof(PppPacket);
00318 
00319       //Any data?
00320       if(length > 0)
00321       {
00322          //Dump data
00323          TRACE_DEBUG("  Data (%" PRIuSIZE " bytes)\r\n", length);
00324          TRACE_DEBUG_ARRAY("    ", packet->data, length);
00325       }
00326    }
00327 
00328    //No error to report
00329    return NO_ERROR;
00330 }
00331 
00332 
00333 /**
00334  * @brief Dump NCP packet for debugging purpose
00335  * @param[in] packet Pointer to the NCP packet
00336  * @param[in] length Length of the packet, in bytes
00337  * @param[in] protocol Protocol field
00338  * @return Error code
00339  **/
00340 
00341 error_t ncpDumpPacket(const PppPacket *packet, size_t length, PppProtocol protocol)
00342 {
00343    error_t error;
00344    const char_t *label;
00345 
00346    //Make sure the NDP packet is valid
00347    if(length < sizeof(PppPacket))
00348       return ERROR_INVALID_LENGTH;
00349 
00350    //Check the length field
00351    if(ntohs(packet->length) > length)
00352       return ERROR_INVALID_LENGTH;
00353    if(ntohs(packet->length) < sizeof(PppPacket))
00354       return ERROR_INVALID_LENGTH;
00355 
00356    //Save the length of the NDP packet
00357    length = ntohs(packet->length);
00358 
00359    //Retrieve the name of the NDP packet
00360    if(packet->code < arraysize(ncpCodeLabel))
00361       label = ncpCodeLabel[packet->code];
00362    else
00363       label = "Unknown";
00364 
00365    //Dump NDP packet header
00366    TRACE_DEBUG("  Code = %" PRIu8 " (%s)\r\n", packet->code, label);
00367    TRACE_DEBUG("  Identifier = %" PRIu8  "\r\n", packet->identifier);
00368    TRACE_DEBUG("  Length = %" PRIu16 "\r\n", ntohs(packet->length));
00369 
00370    //Configure-Request, Configure-Ack, Configure-Nak or Configure-Reject packet?
00371    if(packet->code == PPP_CODE_CONFIGURE_REQ ||
00372       packet->code == PPP_CODE_CONFIGURE_ACK ||
00373       packet->code == PPP_CODE_CONFIGURE_NAK ||
00374       packet->code == PPP_CODE_CONFIGURE_REJ)
00375    {
00376       //Cast NDP packet
00377       PppConfigurePacket *p = (PppConfigurePacket *) packet;
00378 
00379       //Valid packet length?
00380       if(length < sizeof(PppConfigurePacket))
00381          return ERROR_INVALID_LENGTH;
00382 
00383       //Retrieve the length of the option list
00384       length -= sizeof(PppConfigurePacket);
00385 
00386       //IPCP protocol?
00387       if(protocol == PPP_PROTOCOL_IPCP)
00388       {
00389          //Dump options
00390          error = ipcpDumpOptions((PppOption *) p->options, length);
00391          //Any error to report?
00392          if(error)
00393             return error;
00394       }
00395       //IPV6CP protocol?
00396       else if(protocol == PPP_PROTOCOL_IPV6CP)
00397       {
00398          //Dump options
00399          error = ipv6cpDumpOptions((PppOption *) p->options, length);
00400          //Any error to report?
00401          if(error)
00402             return error;
00403       }
00404    }
00405    //Terminate-Request or Terminate-Ack packet?
00406    else if(packet->code == PPP_CODE_TERMINATE_REQ ||
00407       packet->code == PPP_CODE_TERMINATE_ACK)
00408    {
00409       //Cast NDP packet
00410       PppTerminatePacket *p = (PppTerminatePacket *) packet;
00411 
00412       //Valid packet length?
00413       if(length < sizeof(PppTerminatePacket))
00414          return ERROR_INVALID_LENGTH;
00415 
00416       //Retrieve the length of data
00417       length -= sizeof(PppTerminatePacket);
00418 
00419       //Any data?
00420       if(length > 0)
00421       {
00422          //Dump data
00423          TRACE_DEBUG("  Data (%" PRIuSIZE " bytes)\r\n", length);
00424          TRACE_DEBUG_ARRAY("    ", p->data, length);
00425       }
00426    }
00427    //Code-Reject packet?
00428    else if(packet->code == PPP_CODE_CODE_REJ)
00429    {
00430       //Cast NDP packet
00431       PppCodeRejPacket *p = (PppCodeRejPacket *) packet;
00432 
00433       //Valid packet length?
00434       if(length < sizeof(PppCodeRejPacket))
00435          return ERROR_INVALID_LENGTH;
00436 
00437       //Retrieve the length of Rejected-Packet field
00438       length -= sizeof(PppCodeRejPacket);
00439 
00440       //Rejected-Packet
00441       TRACE_DEBUG("  Rejected-Packet (%" PRIuSIZE " bytes)\r\n", length);
00442       TRACE_DEBUG_ARRAY("    ", p->rejectedPacket, length);
00443    }
00444    //Unknown packet?
00445    else
00446    {
00447       //Retrieve the length of data
00448       length -= sizeof(PppPacket);
00449 
00450       //Any data?
00451       if(length > 0)
00452       {
00453          //Dump data
00454          TRACE_DEBUG("  Data (%" PRIuSIZE " bytes)\r\n", length);
00455          TRACE_DEBUG_ARRAY("    ", packet->data, length);
00456       }
00457    }
00458 
00459    //No error to report
00460    return NO_ERROR;
00461 }
00462 
00463 
00464 /**
00465  * @brief Dump PAP packet for debugging purpose
00466  * @param[in] packet Pointer to the PAP packet
00467  * @param[in] length Length of the packet, in bytes
00468  * @return Error code
00469  **/
00470 
00471 error_t papDumpPacket(const PppPacket *packet, size_t length)
00472 {
00473    const char_t *label;
00474 
00475    //Make sure the PAP packet is valid
00476    if(length < sizeof(PppPacket))
00477       return ERROR_INVALID_LENGTH;
00478 
00479    //Check the length field
00480    if(ntohs(packet->length) > length)
00481       return ERROR_INVALID_LENGTH;
00482    if(ntohs(packet->length) < sizeof(PppPacket))
00483       return ERROR_INVALID_LENGTH;
00484 
00485    //Save the length of the PAP packet
00486    length = ntohs(packet->length);
00487 
00488    //Retrieve the name of the PAP packet
00489    if(packet->code < arraysize(papCodeLabel))
00490       label = papCodeLabel[packet->code];
00491    else
00492       label = "Unknown";
00493 
00494    //Dump PAP packet header
00495    TRACE_DEBUG("  Code = %" PRIu8 " (%s)\r\n", packet->code, label);
00496    TRACE_DEBUG("  Identifier = %" PRIu8  "\r\n", packet->identifier);
00497    TRACE_DEBUG("  Length = %" PRIu16 "\r\n", ntohs(packet->length));
00498 
00499    //Authenticate-Request packet?
00500    if(packet->code == PAP_CODE_AUTH_REQ)
00501    {
00502       uint8_t *q;
00503       PapAuthReqPacket *p;
00504 
00505       //Cast PAP packet
00506       p = (PapAuthReqPacket *) packet;
00507 
00508       //Valid packet length?
00509       if(length < sizeof(PapAuthReqPacket))
00510          return ERROR_INVALID_LENGTH;
00511 
00512       //Peer-ID-Length field
00513       TRACE_DEBUG("  Peer-ID-Length = %" PRIu8 "\r\n", p->peerIdLength);
00514 
00515       //Check the length of the Peer-ID field
00516       if(length < (sizeof(PapAuthAckPacket) + 1 + p->peerIdLength))
00517          return ERROR_INVALID_LENGTH;
00518 
00519       //Peer-ID field
00520       TRACE_DEBUG("  Peer-ID\r\n");
00521       TRACE_DEBUG_ARRAY("    ", p->peerId, p->peerIdLength);
00522 
00523       //Point to the Passwd-Length field
00524       q = p->peerId + p->peerIdLength;
00525 
00526       //Passwd-Length field
00527       TRACE_DEBUG("  Passwd-Length = %" PRIu8 "\r\n", q[0]);
00528 
00529       //Check the length of the Password field
00530       if(length < (sizeof(PapAuthAckPacket) + 1 + p->peerIdLength + q[0]))
00531          return ERROR_INVALID_LENGTH;
00532 
00533       //Password field
00534       TRACE_DEBUG("  Password\r\n");
00535       TRACE_DEBUG_ARRAY("    ", q + 1, q[0]);
00536    }
00537    //Authenticate-Ack or Authenticate-Nak packet?
00538    else if(packet->code == PAP_CODE_AUTH_ACK ||
00539       packet->code == PAP_CODE_AUTH_NAK)
00540    {
00541       PapAuthAckPacket *p;
00542 
00543       //Cast PAP packet
00544       p = (PapAuthAckPacket *) packet;
00545 
00546       //Valid packet length?
00547       if(length < sizeof(PapAuthAckPacket))
00548          return ERROR_INVALID_LENGTH;
00549 
00550       //Msg-Length field
00551       TRACE_DEBUG("  Msg-Length = %" PRIu8 "\r\n", p->msgLength);
00552 
00553       //Check the length of the Message field
00554       if(length < (sizeof(PapAuthAckPacket) + p->msgLength))
00555          return ERROR_INVALID_LENGTH;
00556 
00557       if(length > 0)
00558       {
00559          //Message field
00560          TRACE_DEBUG("  Message\r\n");
00561          TRACE_DEBUG_ARRAY("    ", p->message, p->msgLength);
00562       }
00563    }
00564    //Unknown packet?
00565    else
00566    {
00567       //Retrieve the length of data
00568       length -= sizeof(PppPacket);
00569 
00570       //Any data?
00571       if(length > 0)
00572       {
00573          //Dump data
00574          TRACE_DEBUG("  Data (%" PRIuSIZE " bytes)\r\n", length);
00575          TRACE_DEBUG_ARRAY("    ", packet->data, length);
00576       }
00577    }
00578 
00579    //No error to report
00580    return NO_ERROR;
00581 }
00582 
00583 
00584 /**
00585  * @brief Dump CHAP packet for debugging purpose
00586  * @param[in] packet Pointer to the PAP packet
00587  * @param[in] length Length of the packet, in bytes
00588  * @return Error code
00589  **/
00590 
00591 error_t chapDumpPacket(const PppPacket *packet, size_t length)
00592 {
00593    const char_t *label;
00594 
00595    //Make sure the CHAP packet is valid
00596    if(length < sizeof(PppPacket))
00597       return ERROR_INVALID_LENGTH;
00598 
00599    //Check the length field
00600    if(ntohs(packet->length) > length)
00601       return ERROR_INVALID_LENGTH;
00602    if(ntohs(packet->length) < sizeof(PppPacket))
00603       return ERROR_INVALID_LENGTH;
00604 
00605    //Save the length of the CHAP packet
00606    length = ntohs(packet->length);
00607 
00608    //Retrieve the name of the CHAP packet
00609    if(packet->code < arraysize(chapCodeLabel))
00610       label = chapCodeLabel[packet->code];
00611    else
00612       label = "Unknown";
00613 
00614    //Dump CHAP packet header
00615    TRACE_DEBUG("  Code = %" PRIu8 " (%s)\r\n", packet->code, label);
00616    TRACE_DEBUG("  Identifier = %" PRIu8  "\r\n", packet->identifier);
00617    TRACE_DEBUG("  Length = %" PRIu16 "\r\n", ntohs(packet->length));
00618 
00619    //Challenge or Response packet?
00620    if(packet->code == CHAP_CODE_CHALLENGE ||
00621       packet->code == CHAP_CODE_RESPONSE)
00622    {
00623       uint8_t *q;
00624       ChapChallengePacket *p;
00625 
00626       //Cast CHAP packet
00627       p = (ChapChallengePacket *) packet;
00628 
00629       //Valid packet length?
00630       if(length < sizeof(ChapChallengePacket))
00631          return ERROR_INVALID_LENGTH;
00632 
00633       //Value-Size field
00634       TRACE_DEBUG("  Value-Size = %" PRIu8 "\r\n", p->valueSize);
00635 
00636       //Check the length of the Value field
00637       if(length < (sizeof(ChapChallengePacket) + p->valueSize))
00638          return ERROR_INVALID_LENGTH;
00639 
00640       //Value field
00641       TRACE_DEBUG("  Value\r\n");
00642       TRACE_DEBUG_ARRAY("    ", p->value, p->valueSize);
00643 
00644       //Point to the Name field
00645       q = p->value + p->valueSize;
00646       //Retrieve the length of the Name field
00647       length -= sizeof(ChapChallengePacket) + p->valueSize;
00648 
00649       //Name field
00650       TRACE_DEBUG("  Name (%" PRIuSIZE " bytes)\r\n", length);
00651       TRACE_DEBUG_ARRAY("    ", q, length);
00652    }
00653    //Success or Failure packet?
00654    else if(packet->code == CHAP_CODE_SUCCESS ||
00655       packet->code == CHAP_CODE_FAILURE)
00656    {
00657       ChapSuccessPacket *p;
00658 
00659       //Cast CHAP packet
00660       p = (ChapSuccessPacket *) packet;
00661 
00662       //Valid packet length?
00663       if(length < sizeof(ChapSuccessPacket))
00664          return ERROR_INVALID_LENGTH;
00665 
00666       //Retrieve the length of Message field
00667       length -= sizeof(ChapSuccessPacket);
00668 
00669       //Message field
00670       TRACE_DEBUG("  Message (%" PRIuSIZE " bytes)\r\n", length);
00671       TRACE_DEBUG_ARRAY("    ", p->message, length);
00672    }
00673    //Unknown packet?
00674    else
00675    {
00676       //Retrieve the length of data
00677       length -= sizeof(PppPacket);
00678 
00679       //Any data?
00680       if(length > 0)
00681       {
00682          //Dump data
00683          TRACE_DEBUG("  Data (%" PRIuSIZE " bytes)\r\n", length);
00684          TRACE_DEBUG_ARRAY("    ", packet->data, length);
00685       }
00686    }
00687 
00688    //No error to report
00689    return NO_ERROR;
00690 }
00691 
00692 
00693 /**
00694  * @brief Dump LCP options for debugging purpose
00695  * @param[in] option Pointer to the option list
00696  * @param[in] length Length of the option list, in bytes
00697  * @return Error code
00698  **/
00699 
00700 error_t lcpDumpOptions(const PppOption *option, size_t length)
00701 {
00702    uint32_t value;
00703 
00704    //Parse options
00705    while(length > 0)
00706    {
00707       //Malformed LCP packet?
00708       if(length < sizeof(PppOption))
00709          return ERROR_INVALID_LENGTH;
00710 
00711       //Check option length
00712       if(option->length < sizeof(PppOption))
00713          return ERROR_INVALID_LENGTH;
00714       if(option->length > length)
00715          return ERROR_INVALID_LENGTH;
00716 
00717       //Display the name of the current option
00718       if(option->type < arraysize(lcpOptionLabel))
00719          TRACE_DEBUG("  %s option (%" PRIu8 " bytes)\r\n", lcpOptionLabel[option->type], option->length);
00720       else
00721          TRACE_DEBUG("  Option %" PRIu8 " (%" PRIu8 " bytes)\r\n", option->type, option->length);
00722 
00723       //Check option code
00724       switch(option->type)
00725       {
00726       //16-bit unsigned value?
00727       case LCP_OPTION_MRU:
00728          //Check length field
00729          if(option->length != (sizeof(PppOption) + sizeof(uint16_t)))
00730             return ERROR_INVALID_OPTION;
00731          //Retrieve 16-bit value
00732          value = LOAD16BE(option->data);
00733          //Dump option contents
00734          TRACE_DEBUG("    %" PRIu32 "\r\n", value);
00735          break;
00736 
00737       //32-bit unsigned value?
00738       case LCP_OPTION_ACCM:
00739       case LCP_OPTION_MAGIC_NUMBER:
00740          //Check length field
00741          if(option->length != (sizeof(PppOption) + sizeof(uint32_t)))
00742             return ERROR_INVALID_OPTION;
00743          //Retrieve 32-bit value
00744          value = LOAD32BE(option->data);
00745          //Dump option contents
00746          TRACE_DEBUG("    0x%08" PRIX32 "\r\n", value);
00747          break;
00748 
00749       //Raw data?
00750       default:
00751          //Dump option contents
00752          TRACE_DEBUG_ARRAY("    ", option->data, option->length - sizeof(PppOption));
00753          break;
00754       }
00755 
00756       //Remaining bytes to process
00757       length -= option->length;
00758       //Jump to the next option
00759       option = (PppOption *) ((uint8_t *) option + option->length);
00760    }
00761 
00762    //No error to report
00763    return NO_ERROR;
00764 }
00765 
00766 /**
00767  * @brief Dump IPCP options for debugging purpose
00768  * @param[in] option Pointer to the option list
00769  * @param[in] length Length of the option list, in bytes
00770  * @return Error code
00771  **/
00772 
00773 error_t ipcpDumpOptions(const PppOption *option, size_t length)
00774 {
00775 #if (IPV4_SUPPORT == ENABLED)
00776    Ipv4Addr ipAddr;
00777 #endif
00778 
00779    //Parse options
00780    while(length > 0)
00781    {
00782       //Malformed IPCP packet?
00783       if(length < sizeof(PppOption))
00784          return ERROR_INVALID_LENGTH;
00785 
00786       //Check option length
00787       if(option->length < sizeof(PppOption))
00788          return ERROR_INVALID_LENGTH;
00789       if(option->length > length)
00790          return ERROR_INVALID_LENGTH;
00791 
00792       //Display the name of the current option
00793       if(option->type < arraysize(ipcpOptionLabel))
00794          TRACE_DEBUG("  %s option (%" PRIu8 " bytes)\r\n", ipcpOptionLabel[option->type], option->length);
00795       else if(option->type >= 128 && option->type < (128 + arraysize(ipcpOptionLabel2)))
00796          TRACE_DEBUG("  %s option (%" PRIu8 " bytes)\r\n", ipcpOptionLabel2[option->type - 128], option->length);
00797       else
00798          TRACE_DEBUG("  Option %" PRIu8 " (%" PRIu8 " bytes)\r\n", option->type, option->length);
00799 
00800       //Check option code
00801       switch(option->type)
00802       {
00803 #if (IPV4_SUPPORT == ENABLED)
00804       //IP address?
00805       case IPCP_OPTION_IP_ADDRESS:
00806       case IPCP_OPTION_PRIMARY_DNS:
00807       case IPCP_OPTION_PRIMARY_NBNS:
00808       case IPCP_OPTION_SECONDARY_DNS:
00809       case IPCP_OPTION_SECONDARY_NBNS:
00810          //Check length field
00811          if(option->length != (sizeof(PppOption) + sizeof(Ipv4Addr)))
00812             return ERROR_INVALID_OPTION;
00813          //Retrieve IPv4 address
00814          ipv4CopyAddr(&ipAddr, option->data);
00815          //Dump option contents
00816          TRACE_DEBUG("    %s\r\n", ipv4AddrToString(ipAddr, NULL));
00817          break;
00818 #endif
00819       //Raw data?
00820       default:
00821          //Dump option contents
00822          TRACE_DEBUG_ARRAY("    ", option->data, option->length - sizeof(PppOption));
00823          break;
00824       }
00825 
00826       //Remaining bytes to process
00827       length -= option->length;
00828       //Jump to the next option
00829       option = (PppOption *) ((uint8_t *) option + option->length);
00830    }
00831 
00832    //No error to report
00833    return NO_ERROR;
00834 }
00835 
00836 
00837 /**
00838  * @brief Dump IPV6CP options for debugging purpose
00839  * @param[in] option Pointer to the option list
00840  * @param[in] length Length of the option list, in bytes
00841  * @return Error code
00842  **/
00843 
00844 error_t ipv6cpDumpOptions(const PppOption *option, size_t length)
00845 {
00846    //Parse options
00847    while(length > 0)
00848    {
00849       //Malformed IPV6CP packet?
00850       if(length < sizeof(PppOption))
00851          return ERROR_INVALID_LENGTH;
00852 
00853       //Check option length
00854       if(option->length < sizeof(PppOption))
00855          return ERROR_INVALID_LENGTH;
00856       if(option->length > length)
00857          return ERROR_INVALID_LENGTH;
00858 
00859       //Display the name of the current option
00860       if(option->type < arraysize(ipv6cpOptionLabel))
00861          TRACE_DEBUG("  %s option (%" PRIu8 " bytes)\r\n", ipv6cpOptionLabel[option->type], option->length);
00862       else
00863          TRACE_DEBUG("  Option %" PRIu8 " (%" PRIu8 " bytes)\r\n", option->type, option->length);
00864 
00865       //Check option code
00866       switch(option->type)
00867       {
00868       //Raw data?
00869       default:
00870          //Dump option contents
00871          TRACE_DEBUG_ARRAY("    ", option->data, option->length - sizeof(PppOption));
00872          break;
00873       }
00874 
00875       //Remaining bytes to process
00876       length -= option->length;
00877       //Jump to the next option
00878       option = (PppOption *) ((uint8_t *) option + option->length);
00879    }
00880 
00881    //No error to report
00882    return NO_ERROR;
00883 }
00884 
00885 #endif
00886