Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 12 2022 17:10:15 by
