Webserver+3d print

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergunb 0:8918a71cdbe9 1 /**
Sergunb 0:8918a71cdbe9 2 * @file ipv6cp.c
Sergunb 0:8918a71cdbe9 3 * @brief IPV6CP (PPP IPv6 Control Protocol)
Sergunb 0:8918a71cdbe9 4 *
Sergunb 0:8918a71cdbe9 5 * @section License
Sergunb 0:8918a71cdbe9 6 *
Sergunb 0:8918a71cdbe9 7 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
Sergunb 0:8918a71cdbe9 8 *
Sergunb 0:8918a71cdbe9 9 * This file is part of CycloneTCP Open.
Sergunb 0:8918a71cdbe9 10 *
Sergunb 0:8918a71cdbe9 11 * This program is free software; you can redistribute it and/or
Sergunb 0:8918a71cdbe9 12 * modify it under the terms of the GNU General Public License
Sergunb 0:8918a71cdbe9 13 * as published by the Free Software Foundation; either version 2
Sergunb 0:8918a71cdbe9 14 * of the License, or (at your option) any later version.
Sergunb 0:8918a71cdbe9 15 *
Sergunb 0:8918a71cdbe9 16 * This program is distributed in the hope that it will be useful,
Sergunb 0:8918a71cdbe9 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Sergunb 0:8918a71cdbe9 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Sergunb 0:8918a71cdbe9 19 * GNU General Public License for more details.
Sergunb 0:8918a71cdbe9 20 *
Sergunb 0:8918a71cdbe9 21 * You should have received a copy of the GNU General Public License
Sergunb 0:8918a71cdbe9 22 * along with this program; if not, write to the Free Software Foundation,
Sergunb 0:8918a71cdbe9 23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Sergunb 0:8918a71cdbe9 24 *
Sergunb 0:8918a71cdbe9 25 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 26 * @version 1.7.6
Sergunb 0:8918a71cdbe9 27 **/
Sergunb 0:8918a71cdbe9 28
Sergunb 0:8918a71cdbe9 29 //Switch to the appropriate trace level
Sergunb 0:8918a71cdbe9 30 #define TRACE_LEVEL PPP_TRACE_LEVEL
Sergunb 0:8918a71cdbe9 31
Sergunb 0:8918a71cdbe9 32 //Dependencies
Sergunb 0:8918a71cdbe9 33 #include "core/net.h"
Sergunb 0:8918a71cdbe9 34 #include "ipv6/ipv6.h"
Sergunb 0:8918a71cdbe9 35 #include "ipv6/ipv6_misc.h"
Sergunb 0:8918a71cdbe9 36 #include "ppp/ppp_fsm.h"
Sergunb 0:8918a71cdbe9 37 #include "ppp/ppp_misc.h"
Sergunb 0:8918a71cdbe9 38 #include "ppp/ppp_debug.h"
Sergunb 0:8918a71cdbe9 39 #include "ppp/ipv6cp.h"
Sergunb 0:8918a71cdbe9 40 #include "debug.h"
Sergunb 0:8918a71cdbe9 41
Sergunb 0:8918a71cdbe9 42 //Check TCP/IP stack configuration
Sergunb 0:8918a71cdbe9 43 #if (PPP_SUPPORT == ENABLED && IPV6_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 44
Sergunb 0:8918a71cdbe9 45
Sergunb 0:8918a71cdbe9 46 /**
Sergunb 0:8918a71cdbe9 47 * @brief IPV6CP FSM callbacks
Sergunb 0:8918a71cdbe9 48 **/
Sergunb 0:8918a71cdbe9 49
Sergunb 0:8918a71cdbe9 50 const PppCallbacks ipv6cpCallbacks =
Sergunb 0:8918a71cdbe9 51 {
Sergunb 0:8918a71cdbe9 52 ipv6cpThisLayerUp,
Sergunb 0:8918a71cdbe9 53 ipv6cpThisLayerDown,
Sergunb 0:8918a71cdbe9 54 ipv6cpThisLayerStarted,
Sergunb 0:8918a71cdbe9 55 ipv6cpThisLayerFinished,
Sergunb 0:8918a71cdbe9 56 ipv6cpInitRestartCount,
Sergunb 0:8918a71cdbe9 57 ipv6cpZeroRestartCount,
Sergunb 0:8918a71cdbe9 58 ipv6cpSendConfigureReq,
Sergunb 0:8918a71cdbe9 59 ipv6cpSendConfigureAck,
Sergunb 0:8918a71cdbe9 60 ipv6cpSendConfigureNak,
Sergunb 0:8918a71cdbe9 61 ipv6cpSendConfigureRej,
Sergunb 0:8918a71cdbe9 62 ipv6cpSendTerminateReq,
Sergunb 0:8918a71cdbe9 63 ipv6cpSendTerminateAck,
Sergunb 0:8918a71cdbe9 64 ipv6cpSendCodeRej,
Sergunb 0:8918a71cdbe9 65 NULL
Sergunb 0:8918a71cdbe9 66 };
Sergunb 0:8918a71cdbe9 67
Sergunb 0:8918a71cdbe9 68
Sergunb 0:8918a71cdbe9 69 /**
Sergunb 0:8918a71cdbe9 70 * @brief IPV6CP Open event
Sergunb 0:8918a71cdbe9 71 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 72 * @return Error code
Sergunb 0:8918a71cdbe9 73 **/
Sergunb 0:8918a71cdbe9 74
Sergunb 0:8918a71cdbe9 75 error_t ipv6cpOpen(PppContext *context)
Sergunb 0:8918a71cdbe9 76 {
Sergunb 0:8918a71cdbe9 77 //Debug message
Sergunb 0:8918a71cdbe9 78 TRACE_INFO("\r\nIPV6CP Open event\r\n");
Sergunb 0:8918a71cdbe9 79
Sergunb 0:8918a71cdbe9 80 //The link is administratively available for traffic
Sergunb 0:8918a71cdbe9 81 pppOpenEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks);
Sergunb 0:8918a71cdbe9 82 //The lower layer is ready to carry packets
Sergunb 0:8918a71cdbe9 83 pppUpEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks);
Sergunb 0:8918a71cdbe9 84
Sergunb 0:8918a71cdbe9 85 //Successful processing
Sergunb 0:8918a71cdbe9 86 return NO_ERROR;
Sergunb 0:8918a71cdbe9 87 }
Sergunb 0:8918a71cdbe9 88
Sergunb 0:8918a71cdbe9 89
Sergunb 0:8918a71cdbe9 90 /**
Sergunb 0:8918a71cdbe9 91 * @brief IPV6CP Close event
Sergunb 0:8918a71cdbe9 92 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 93 * @return Error code
Sergunb 0:8918a71cdbe9 94 **/
Sergunb 0:8918a71cdbe9 95
Sergunb 0:8918a71cdbe9 96 error_t ipv6cpClose(PppContext *context)
Sergunb 0:8918a71cdbe9 97 {
Sergunb 0:8918a71cdbe9 98 //Debug message
Sergunb 0:8918a71cdbe9 99 TRACE_INFO("\r\nIPV6CP Close event\r\n");
Sergunb 0:8918a71cdbe9 100
Sergunb 0:8918a71cdbe9 101 //The lower layer is no longer ready to carry packets
Sergunb 0:8918a71cdbe9 102 pppDownEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks);
Sergunb 0:8918a71cdbe9 103 //The link is no longer available for traffic
Sergunb 0:8918a71cdbe9 104 pppCloseEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks);
Sergunb 0:8918a71cdbe9 105
Sergunb 0:8918a71cdbe9 106 //Successful processing
Sergunb 0:8918a71cdbe9 107 return NO_ERROR;
Sergunb 0:8918a71cdbe9 108 }
Sergunb 0:8918a71cdbe9 109
Sergunb 0:8918a71cdbe9 110
Sergunb 0:8918a71cdbe9 111 /**
Sergunb 0:8918a71cdbe9 112 * @brief IPV6CP timer handler
Sergunb 0:8918a71cdbe9 113 *
Sergunb 0:8918a71cdbe9 114 * This routine must be periodically called by the TCP/IP stack to
Sergunb 0:8918a71cdbe9 115 * manage retransmissions
Sergunb 0:8918a71cdbe9 116 *
Sergunb 0:8918a71cdbe9 117 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 118 **/
Sergunb 0:8918a71cdbe9 119
Sergunb 0:8918a71cdbe9 120 void ipv6cpTick(PppContext *context)
Sergunb 0:8918a71cdbe9 121 {
Sergunb 0:8918a71cdbe9 122 //Check whether the restart timer is running
Sergunb 0:8918a71cdbe9 123 if(context->ipv6cpFsm.state >= PPP_STATE_4_CLOSING &&
Sergunb 0:8918a71cdbe9 124 context->ipv6cpFsm.state <= PPP_STATE_8_ACK_SENT)
Sergunb 0:8918a71cdbe9 125 {
Sergunb 0:8918a71cdbe9 126 //Get current time
Sergunb 0:8918a71cdbe9 127 systime_t time = osGetSystemTime();
Sergunb 0:8918a71cdbe9 128
Sergunb 0:8918a71cdbe9 129 //Check restart timer
Sergunb 0:8918a71cdbe9 130 if((time - context->ipv6cpFsm.timestamp) >= PPP_RESTART_TIMER)
Sergunb 0:8918a71cdbe9 131 {
Sergunb 0:8918a71cdbe9 132 //Debug message
Sergunb 0:8918a71cdbe9 133 TRACE_INFO("\r\nIPV6CP Timeout event\r\n");
Sergunb 0:8918a71cdbe9 134
Sergunb 0:8918a71cdbe9 135 //The restart timer is used to retransmit Configure-Request
Sergunb 0:8918a71cdbe9 136 //and Terminate-Request packets
Sergunb 0:8918a71cdbe9 137 pppTimeoutEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks);
Sergunb 0:8918a71cdbe9 138 }
Sergunb 0:8918a71cdbe9 139 }
Sergunb 0:8918a71cdbe9 140 }
Sergunb 0:8918a71cdbe9 141
Sergunb 0:8918a71cdbe9 142
Sergunb 0:8918a71cdbe9 143 /**
Sergunb 0:8918a71cdbe9 144 * @brief Process an incoming IPV6CP packet
Sergunb 0:8918a71cdbe9 145 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 146 * @param[in] packet IPV6CP packet received from the peer
Sergunb 0:8918a71cdbe9 147 * @param[in] length Length of the packet, in bytes
Sergunb 0:8918a71cdbe9 148 **/
Sergunb 0:8918a71cdbe9 149
Sergunb 0:8918a71cdbe9 150 void ipv6cpProcessPacket(PppContext *context, const PppPacket *packet, size_t length)
Sergunb 0:8918a71cdbe9 151 {
Sergunb 0:8918a71cdbe9 152 //Ensure the length of the incoming IPV6CP packet is valid
Sergunb 0:8918a71cdbe9 153 if(length < sizeof(PppPacket))
Sergunb 0:8918a71cdbe9 154 return;
Sergunb 0:8918a71cdbe9 155
Sergunb 0:8918a71cdbe9 156 //Check the length field
Sergunb 0:8918a71cdbe9 157 if(ntohs(packet->length) > length)
Sergunb 0:8918a71cdbe9 158 return;
Sergunb 0:8918a71cdbe9 159 if(ntohs(packet->length) < sizeof(PppPacket))
Sergunb 0:8918a71cdbe9 160 return;
Sergunb 0:8918a71cdbe9 161
Sergunb 0:8918a71cdbe9 162 //Save the length of the IPV6CP packet
Sergunb 0:8918a71cdbe9 163 length = ntohs(packet->length);
Sergunb 0:8918a71cdbe9 164
Sergunb 0:8918a71cdbe9 165 //Debug message
Sergunb 0:8918a71cdbe9 166 TRACE_INFO("IPV6CP packet received (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 167 //Dump IPV6CP packet contents for debugging purpose
Sergunb 0:8918a71cdbe9 168 pppDumpPacket(packet, length, PPP_PROTOCOL_IPV6CP);
Sergunb 0:8918a71cdbe9 169
Sergunb 0:8918a71cdbe9 170 //Check IPV6CP code field
Sergunb 0:8918a71cdbe9 171 switch(packet->code)
Sergunb 0:8918a71cdbe9 172 {
Sergunb 0:8918a71cdbe9 173 //Configure-Request packet?
Sergunb 0:8918a71cdbe9 174 case PPP_CODE_CONFIGURE_REQ:
Sergunb 0:8918a71cdbe9 175 //Process Configure-Request packet
Sergunb 0:8918a71cdbe9 176 ipv6cpProcessConfigureReq(context, (PppConfigurePacket *) packet);
Sergunb 0:8918a71cdbe9 177 break;
Sergunb 0:8918a71cdbe9 178 //Configure-Ack packet?
Sergunb 0:8918a71cdbe9 179 case PPP_CODE_CONFIGURE_ACK:
Sergunb 0:8918a71cdbe9 180 //Process Configure-Ack packet
Sergunb 0:8918a71cdbe9 181 ipv6cpProcessConfigureAck(context, (PppConfigurePacket *) packet);
Sergunb 0:8918a71cdbe9 182 break;
Sergunb 0:8918a71cdbe9 183 //Configure-Nak packet?
Sergunb 0:8918a71cdbe9 184 case PPP_CODE_CONFIGURE_NAK:
Sergunb 0:8918a71cdbe9 185 //Process Configure-Nak packet
Sergunb 0:8918a71cdbe9 186 ipv6cpProcessConfigureNak(context, (PppConfigurePacket *) packet);
Sergunb 0:8918a71cdbe9 187 break;
Sergunb 0:8918a71cdbe9 188 //Configure-Reject packet?
Sergunb 0:8918a71cdbe9 189 case PPP_CODE_CONFIGURE_REJ:
Sergunb 0:8918a71cdbe9 190 //Process Configure-Reject packet
Sergunb 0:8918a71cdbe9 191 ipv6cpProcessConfigureReject(context, (PppConfigurePacket *) packet);
Sergunb 0:8918a71cdbe9 192 break;
Sergunb 0:8918a71cdbe9 193 //Terminate-Request packet?
Sergunb 0:8918a71cdbe9 194 case PPP_CODE_TERMINATE_REQ:
Sergunb 0:8918a71cdbe9 195 //Process Terminate-Request packet
Sergunb 0:8918a71cdbe9 196 ipv6cpProcessTerminateReq(context, (PppTerminatePacket *) packet);
Sergunb 0:8918a71cdbe9 197 break;
Sergunb 0:8918a71cdbe9 198 //Terminate-Ack packet?
Sergunb 0:8918a71cdbe9 199 case PPP_CODE_TERMINATE_ACK:
Sergunb 0:8918a71cdbe9 200 //Process Terminate-Ack packet
Sergunb 0:8918a71cdbe9 201 ipv6cpProcessTerminateAck(context, (PppTerminatePacket *) packet);
Sergunb 0:8918a71cdbe9 202 break;
Sergunb 0:8918a71cdbe9 203 //Code-Reject packet?
Sergunb 0:8918a71cdbe9 204 case PPP_CODE_CODE_REJ:
Sergunb 0:8918a71cdbe9 205 //Process Code-Reject packet
Sergunb 0:8918a71cdbe9 206 ipv6cpProcessCodeRej(context, (PppCodeRejPacket *) packet);
Sergunb 0:8918a71cdbe9 207 break;
Sergunb 0:8918a71cdbe9 208 //Unknown code field
Sergunb 0:8918a71cdbe9 209 default:
Sergunb 0:8918a71cdbe9 210 //The packet is un-interpretable
Sergunb 0:8918a71cdbe9 211 ipv6cpProcessUnknownCode(context, packet);
Sergunb 0:8918a71cdbe9 212 break;
Sergunb 0:8918a71cdbe9 213 }
Sergunb 0:8918a71cdbe9 214 }
Sergunb 0:8918a71cdbe9 215
Sergunb 0:8918a71cdbe9 216
Sergunb 0:8918a71cdbe9 217 /**
Sergunb 0:8918a71cdbe9 218 * @brief Process Configure-Request packet
Sergunb 0:8918a71cdbe9 219 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 220 * @param[in] configureReqPacket Packet received from the peer
Sergunb 0:8918a71cdbe9 221 * @return Error code
Sergunb 0:8918a71cdbe9 222 **/
Sergunb 0:8918a71cdbe9 223
Sergunb 0:8918a71cdbe9 224 error_t ipv6cpProcessConfigureReq(PppContext *context,
Sergunb 0:8918a71cdbe9 225 const PppConfigurePacket *configureReqPacket)
Sergunb 0:8918a71cdbe9 226 {
Sergunb 0:8918a71cdbe9 227 error_t error;
Sergunb 0:8918a71cdbe9 228 size_t length;
Sergunb 0:8918a71cdbe9 229 bool_t notRecognizable;
Sergunb 0:8918a71cdbe9 230 bool_t notAcceptable;
Sergunb 0:8918a71cdbe9 231 PppOption *option;
Sergunb 0:8918a71cdbe9 232
Sergunb 0:8918a71cdbe9 233 //Debug message
Sergunb 0:8918a71cdbe9 234 TRACE_INFO("\r\nIPV6CP Receive-Configure-Request event\r\n");
Sergunb 0:8918a71cdbe9 235
Sergunb 0:8918a71cdbe9 236 //Initialize variables
Sergunb 0:8918a71cdbe9 237 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 238 notRecognizable = FALSE;
Sergunb 0:8918a71cdbe9 239 notAcceptable = FALSE;
Sergunb 0:8918a71cdbe9 240
Sergunb 0:8918a71cdbe9 241 //Retrieve the length of the option list
Sergunb 0:8918a71cdbe9 242 length = ntohs(configureReqPacket->length) - sizeof(PppConfigurePacket);
Sergunb 0:8918a71cdbe9 243 //Point to the first option
Sergunb 0:8918a71cdbe9 244 option = (PppOption *) configureReqPacket->options;
Sergunb 0:8918a71cdbe9 245
Sergunb 0:8918a71cdbe9 246 //Parse configuration options
Sergunb 0:8918a71cdbe9 247 while(length > 0)
Sergunb 0:8918a71cdbe9 248 {
Sergunb 0:8918a71cdbe9 249 //Parse current option
Sergunb 0:8918a71cdbe9 250 error = ipv6cpParseOption(context, option, length, NULL);
Sergunb 0:8918a71cdbe9 251
Sergunb 0:8918a71cdbe9 252 //Any error to report?
Sergunb 0:8918a71cdbe9 253 if(error == ERROR_INVALID_TYPE)
Sergunb 0:8918a71cdbe9 254 {
Sergunb 0:8918a71cdbe9 255 //Option not recognizable
Sergunb 0:8918a71cdbe9 256 notRecognizable = TRUE;
Sergunb 0:8918a71cdbe9 257 //Catch error
Sergunb 0:8918a71cdbe9 258 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 259 }
Sergunb 0:8918a71cdbe9 260 else if(error == ERROR_INVALID_VALUE)
Sergunb 0:8918a71cdbe9 261 {
Sergunb 0:8918a71cdbe9 262 //Option not acceptable for configuration
Sergunb 0:8918a71cdbe9 263 notAcceptable = TRUE;
Sergunb 0:8918a71cdbe9 264 //Catch error
Sergunb 0:8918a71cdbe9 265 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 266 }
Sergunb 0:8918a71cdbe9 267 else if(error)
Sergunb 0:8918a71cdbe9 268 {
Sergunb 0:8918a71cdbe9 269 //Malformed Configure-Request packet
Sergunb 0:8918a71cdbe9 270 break;
Sergunb 0:8918a71cdbe9 271 }
Sergunb 0:8918a71cdbe9 272
Sergunb 0:8918a71cdbe9 273 //Remaining bytes to process
Sergunb 0:8918a71cdbe9 274 length -= option->length;
Sergunb 0:8918a71cdbe9 275 //Jump to the next option
Sergunb 0:8918a71cdbe9 276 option = (PppOption *) ((uint8_t *) option + option->length);
Sergunb 0:8918a71cdbe9 277 }
Sergunb 0:8918a71cdbe9 278
Sergunb 0:8918a71cdbe9 279 //Valid Configure-Request packet received from the peer?
Sergunb 0:8918a71cdbe9 280 if(!error)
Sergunb 0:8918a71cdbe9 281 {
Sergunb 0:8918a71cdbe9 282 //Check flags
Sergunb 0:8918a71cdbe9 283 if(notRecognizable)
Sergunb 0:8918a71cdbe9 284 {
Sergunb 0:8918a71cdbe9 285 //If some configuration options received in the Configure-Request are not
Sergunb 0:8918a71cdbe9 286 //recognizable or not acceptable for negotiation, then the implementation
Sergunb 0:8918a71cdbe9 287 //must transmit a Configure-Reject
Sergunb 0:8918a71cdbe9 288 pppRcvConfigureReqEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks,
Sergunb 0:8918a71cdbe9 289 configureReqPacket, PPP_CODE_CONFIGURE_REJ);
Sergunb 0:8918a71cdbe9 290 }
Sergunb 0:8918a71cdbe9 291 else if(notAcceptable)
Sergunb 0:8918a71cdbe9 292 {
Sergunb 0:8918a71cdbe9 293 //If all configuration options are recognizable, but some values are not
Sergunb 0:8918a71cdbe9 294 //acceptable, then the implementation must transmit a Configure-Nak
Sergunb 0:8918a71cdbe9 295 pppRcvConfigureReqEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks,
Sergunb 0:8918a71cdbe9 296 configureReqPacket, PPP_CODE_CONFIGURE_NAK);
Sergunb 0:8918a71cdbe9 297 }
Sergunb 0:8918a71cdbe9 298 else
Sergunb 0:8918a71cdbe9 299 {
Sergunb 0:8918a71cdbe9 300 //If every configuration option received in the Configure-Request is
Sergunb 0:8918a71cdbe9 301 //recognizable and all values are acceptable, then the implementation
Sergunb 0:8918a71cdbe9 302 //must transmit a Configure-Ack
Sergunb 0:8918a71cdbe9 303 pppRcvConfigureReqEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks,
Sergunb 0:8918a71cdbe9 304 configureReqPacket, PPP_CODE_CONFIGURE_ACK);
Sergunb 0:8918a71cdbe9 305 }
Sergunb 0:8918a71cdbe9 306 }
Sergunb 0:8918a71cdbe9 307
Sergunb 0:8918a71cdbe9 308 //Return status code
Sergunb 0:8918a71cdbe9 309 return error;
Sergunb 0:8918a71cdbe9 310 }
Sergunb 0:8918a71cdbe9 311
Sergunb 0:8918a71cdbe9 312
Sergunb 0:8918a71cdbe9 313 /**
Sergunb 0:8918a71cdbe9 314 * @brief Process Configure-Ack packet
Sergunb 0:8918a71cdbe9 315 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 316 * @param[in] configureAckPacket Packet received from the peer
Sergunb 0:8918a71cdbe9 317 * @return Error code
Sergunb 0:8918a71cdbe9 318 **/
Sergunb 0:8918a71cdbe9 319
Sergunb 0:8918a71cdbe9 320 error_t ipv6cpProcessConfigureAck(PppContext *context,
Sergunb 0:8918a71cdbe9 321 const PppConfigurePacket *configureAckPacket)
Sergunb 0:8918a71cdbe9 322 {
Sergunb 0:8918a71cdbe9 323 //Debug message
Sergunb 0:8918a71cdbe9 324 TRACE_INFO("\r\nIPV6CP Receive-Configure-Ack event\r\n");
Sergunb 0:8918a71cdbe9 325
Sergunb 0:8918a71cdbe9 326 //When a packet is received with an invalid Identifier field, the
Sergunb 0:8918a71cdbe9 327 //packet is silently discarded without affecting the automaton
Sergunb 0:8918a71cdbe9 328 if(configureAckPacket->identifier != context->ipv6cpFsm.identifier)
Sergunb 0:8918a71cdbe9 329 return ERROR_WRONG_IDENTIFIER;
Sergunb 0:8918a71cdbe9 330
Sergunb 0:8918a71cdbe9 331 //A valid Configure-Ack packet has been received from the peer
Sergunb 0:8918a71cdbe9 332 pppRcvConfigureAckEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks);
Sergunb 0:8918a71cdbe9 333
Sergunb 0:8918a71cdbe9 334 //Successful processing
Sergunb 0:8918a71cdbe9 335 return NO_ERROR;
Sergunb 0:8918a71cdbe9 336 }
Sergunb 0:8918a71cdbe9 337
Sergunb 0:8918a71cdbe9 338
Sergunb 0:8918a71cdbe9 339 /**
Sergunb 0:8918a71cdbe9 340 * @brief Process Configure-Nak packet
Sergunb 0:8918a71cdbe9 341 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 342 * @param[in] configureNakPacket Packet received from the peer
Sergunb 0:8918a71cdbe9 343 * @return Error code
Sergunb 0:8918a71cdbe9 344 **/
Sergunb 0:8918a71cdbe9 345
Sergunb 0:8918a71cdbe9 346 error_t ipv6cpProcessConfigureNak(PppContext *context,
Sergunb 0:8918a71cdbe9 347 const PppConfigurePacket *configureNakPacket)
Sergunb 0:8918a71cdbe9 348 {
Sergunb 0:8918a71cdbe9 349 size_t length;
Sergunb 0:8918a71cdbe9 350 PppOption *option;
Sergunb 0:8918a71cdbe9 351
Sergunb 0:8918a71cdbe9 352 //Debug message
Sergunb 0:8918a71cdbe9 353 TRACE_INFO("IPV6CP Receive-Configure-Nak event\r\n");
Sergunb 0:8918a71cdbe9 354
Sergunb 0:8918a71cdbe9 355 //When a packet is received with an invalid Identifier field, the
Sergunb 0:8918a71cdbe9 356 //packet is silently discarded without affecting the automaton
Sergunb 0:8918a71cdbe9 357 if(configureNakPacket->identifier != context->ipv6cpFsm.identifier)
Sergunb 0:8918a71cdbe9 358 return ERROR_WRONG_IDENTIFIER;
Sergunb 0:8918a71cdbe9 359
Sergunb 0:8918a71cdbe9 360 //Retrieve the length of the option list
Sergunb 0:8918a71cdbe9 361 length = ntohs(configureNakPacket->length) - sizeof(PppConfigurePacket);
Sergunb 0:8918a71cdbe9 362 //Point to the first option
Sergunb 0:8918a71cdbe9 363 option = (PppOption *) configureNakPacket->options;
Sergunb 0:8918a71cdbe9 364
Sergunb 0:8918a71cdbe9 365 //Parse configuration options
Sergunb 0:8918a71cdbe9 366 while(length > 0)
Sergunb 0:8918a71cdbe9 367 {
Sergunb 0:8918a71cdbe9 368 //Check option length
Sergunb 0:8918a71cdbe9 369 if(option->length < sizeof(PppOption))
Sergunb 0:8918a71cdbe9 370 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 371 if(option->length > length)
Sergunb 0:8918a71cdbe9 372 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 373
Sergunb 0:8918a71cdbe9 374 //Interface-Identifier option?
Sergunb 0:8918a71cdbe9 375 if(option->type == IPV6CP_OPTION_INTERFACE_ID)
Sergunb 0:8918a71cdbe9 376 {
Sergunb 0:8918a71cdbe9 377 //Cast option
Sergunb 0:8918a71cdbe9 378 Ipv6cpInterfaceIdOption *interfaceIdOption = (Ipv6cpInterfaceIdOption *) option;
Sergunb 0:8918a71cdbe9 379
Sergunb 0:8918a71cdbe9 380 //Check option length
Sergunb 0:8918a71cdbe9 381 if(interfaceIdOption->length != sizeof(Ipv6cpInterfaceIdOption))
Sergunb 0:8918a71cdbe9 382 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 383
Sergunb 0:8918a71cdbe9 384 //Save interface identifier
Sergunb 0:8918a71cdbe9 385 context->localConfig.interfaceId = interfaceIdOption->interfaceId;
Sergunb 0:8918a71cdbe9 386 }
Sergunb 0:8918a71cdbe9 387
Sergunb 0:8918a71cdbe9 388 //Remaining bytes to process
Sergunb 0:8918a71cdbe9 389 length -= option->length;
Sergunb 0:8918a71cdbe9 390 //Jump to the next option
Sergunb 0:8918a71cdbe9 391 option = (PppOption *) ((uint8_t *) option + option->length);
Sergunb 0:8918a71cdbe9 392 }
Sergunb 0:8918a71cdbe9 393
Sergunb 0:8918a71cdbe9 394 //A valid Configure-Nak or Configure-Reject packet has been received from the peer
Sergunb 0:8918a71cdbe9 395 pppRcvConfigureNakEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks);
Sergunb 0:8918a71cdbe9 396
Sergunb 0:8918a71cdbe9 397 //Successful processing
Sergunb 0:8918a71cdbe9 398 return NO_ERROR;
Sergunb 0:8918a71cdbe9 399 }
Sergunb 0:8918a71cdbe9 400
Sergunb 0:8918a71cdbe9 401
Sergunb 0:8918a71cdbe9 402 /**
Sergunb 0:8918a71cdbe9 403 * @brief Process Configure-Reject packet
Sergunb 0:8918a71cdbe9 404 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 405 * @param[in] configureRejPacket Packet received from the peer
Sergunb 0:8918a71cdbe9 406 * @return Error code
Sergunb 0:8918a71cdbe9 407 **/
Sergunb 0:8918a71cdbe9 408
Sergunb 0:8918a71cdbe9 409 error_t ipv6cpProcessConfigureReject(PppContext *context,
Sergunb 0:8918a71cdbe9 410 const PppConfigurePacket *configureRejPacket)
Sergunb 0:8918a71cdbe9 411 {
Sergunb 0:8918a71cdbe9 412 size_t length;
Sergunb 0:8918a71cdbe9 413 PppOption *option;
Sergunb 0:8918a71cdbe9 414
Sergunb 0:8918a71cdbe9 415 //Debug message
Sergunb 0:8918a71cdbe9 416 TRACE_INFO("\r\nIPV6CP Receive-Configure-Reject event\r\n");
Sergunb 0:8918a71cdbe9 417
Sergunb 0:8918a71cdbe9 418 //When a packet is received with an invalid Identifier field, the
Sergunb 0:8918a71cdbe9 419 //packet is silently discarded without affecting the automaton
Sergunb 0:8918a71cdbe9 420 if(configureRejPacket->identifier != context->ipv6cpFsm.identifier)
Sergunb 0:8918a71cdbe9 421 return ERROR_WRONG_IDENTIFIER;
Sergunb 0:8918a71cdbe9 422
Sergunb 0:8918a71cdbe9 423 //Retrieve the length of the option list
Sergunb 0:8918a71cdbe9 424 length = ntohs(configureRejPacket->length) - sizeof(PppConfigurePacket);
Sergunb 0:8918a71cdbe9 425 //Point to the first option
Sergunb 0:8918a71cdbe9 426 option = (PppOption *) configureRejPacket->options;
Sergunb 0:8918a71cdbe9 427
Sergunb 0:8918a71cdbe9 428 //Parse configuration options
Sergunb 0:8918a71cdbe9 429 while(length > 0)
Sergunb 0:8918a71cdbe9 430 {
Sergunb 0:8918a71cdbe9 431 //Check option length
Sergunb 0:8918a71cdbe9 432 if(option->length < sizeof(PppOption))
Sergunb 0:8918a71cdbe9 433 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 434 if(option->length > length)
Sergunb 0:8918a71cdbe9 435 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 436
Sergunb 0:8918a71cdbe9 437 //Interface-Identifier option?
Sergunb 0:8918a71cdbe9 438 if(option->type == IPV6CP_OPTION_INTERFACE_ID)
Sergunb 0:8918a71cdbe9 439 {
Sergunb 0:8918a71cdbe9 440 //The option is not recognized by the peer
Sergunb 0:8918a71cdbe9 441 context->localConfig.interfaceIdRejected = TRUE;
Sergunb 0:8918a71cdbe9 442 }
Sergunb 0:8918a71cdbe9 443
Sergunb 0:8918a71cdbe9 444 //Remaining bytes to process
Sergunb 0:8918a71cdbe9 445 length -= option->length;
Sergunb 0:8918a71cdbe9 446 //Jump to the next option
Sergunb 0:8918a71cdbe9 447 option = (PppOption *) ((uint8_t *) option + option->length);
Sergunb 0:8918a71cdbe9 448 }
Sergunb 0:8918a71cdbe9 449
Sergunb 0:8918a71cdbe9 450 //A valid Configure-Nak or Configure-Reject packet has been received from the peer
Sergunb 0:8918a71cdbe9 451 pppRcvConfigureNakEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks);
Sergunb 0:8918a71cdbe9 452
Sergunb 0:8918a71cdbe9 453 //Successful processing
Sergunb 0:8918a71cdbe9 454 return NO_ERROR;
Sergunb 0:8918a71cdbe9 455 }
Sergunb 0:8918a71cdbe9 456
Sergunb 0:8918a71cdbe9 457
Sergunb 0:8918a71cdbe9 458 /**
Sergunb 0:8918a71cdbe9 459 * @brief Process Terminate-Request packet
Sergunb 0:8918a71cdbe9 460 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 461 * @param[in] terminateReqPacket Packet received from the peer
Sergunb 0:8918a71cdbe9 462 * @return Error code
Sergunb 0:8918a71cdbe9 463 **/
Sergunb 0:8918a71cdbe9 464
Sergunb 0:8918a71cdbe9 465 error_t ipv6cpProcessTerminateReq(PppContext *context,
Sergunb 0:8918a71cdbe9 466 const PppTerminatePacket *terminateReqPacket)
Sergunb 0:8918a71cdbe9 467 {
Sergunb 0:8918a71cdbe9 468 //Debug message
Sergunb 0:8918a71cdbe9 469 TRACE_INFO("\r\nIPV6CP Receive-Terminate-Request event\r\n");
Sergunb 0:8918a71cdbe9 470
Sergunb 0:8918a71cdbe9 471 //The Terminate-Request indicates the desire of the peer to close the connection
Sergunb 0:8918a71cdbe9 472 pppRcvTerminateReqEvent(context, &context->ipv6cpFsm,
Sergunb 0:8918a71cdbe9 473 &ipv6cpCallbacks, terminateReqPacket);
Sergunb 0:8918a71cdbe9 474
Sergunb 0:8918a71cdbe9 475 //Successful processing
Sergunb 0:8918a71cdbe9 476 return NO_ERROR;
Sergunb 0:8918a71cdbe9 477 }
Sergunb 0:8918a71cdbe9 478
Sergunb 0:8918a71cdbe9 479
Sergunb 0:8918a71cdbe9 480 /**
Sergunb 0:8918a71cdbe9 481 * @brief Process Terminate-Ack packet
Sergunb 0:8918a71cdbe9 482 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 483 * @param[in] terminateAckPacket Packet received from the peer
Sergunb 0:8918a71cdbe9 484 * @return Error code
Sergunb 0:8918a71cdbe9 485 **/
Sergunb 0:8918a71cdbe9 486
Sergunb 0:8918a71cdbe9 487 error_t ipv6cpProcessTerminateAck(PppContext *context,
Sergunb 0:8918a71cdbe9 488 const PppTerminatePacket *terminateAckPacket)
Sergunb 0:8918a71cdbe9 489 {
Sergunb 0:8918a71cdbe9 490 //Debug message
Sergunb 0:8918a71cdbe9 491 TRACE_INFO("\r\nIPV6CP Receive-Terminate-Ack event\r\n");
Sergunb 0:8918a71cdbe9 492
Sergunb 0:8918a71cdbe9 493 //The Terminate-Ack packet is usually a response to a Terminate-Request
Sergunb 0:8918a71cdbe9 494 //packet. This packet may also indicate that the peer is in Closed or
Sergunb 0:8918a71cdbe9 495 //Stopped states, and serves to re-synchronize the link configuration
Sergunb 0:8918a71cdbe9 496 pppRcvTerminateAckEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks);
Sergunb 0:8918a71cdbe9 497
Sergunb 0:8918a71cdbe9 498 //Successful processing
Sergunb 0:8918a71cdbe9 499 return NO_ERROR;
Sergunb 0:8918a71cdbe9 500 }
Sergunb 0:8918a71cdbe9 501
Sergunb 0:8918a71cdbe9 502
Sergunb 0:8918a71cdbe9 503 /**
Sergunb 0:8918a71cdbe9 504 * @brief Process Code-Reject packet
Sergunb 0:8918a71cdbe9 505 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 506 * @param[in] codeRejPacket Packet received from the peer
Sergunb 0:8918a71cdbe9 507 * @return Error code
Sergunb 0:8918a71cdbe9 508 **/
Sergunb 0:8918a71cdbe9 509
Sergunb 0:8918a71cdbe9 510 error_t ipv6cpProcessCodeRej(PppContext *context,
Sergunb 0:8918a71cdbe9 511 const PppCodeRejPacket *codeRejPacket)
Sergunb 0:8918a71cdbe9 512 {
Sergunb 0:8918a71cdbe9 513 size_t length;
Sergunb 0:8918a71cdbe9 514 PppPacket *packet;
Sergunb 0:8918a71cdbe9 515
Sergunb 0:8918a71cdbe9 516 //Debug message
Sergunb 0:8918a71cdbe9 517 TRACE_INFO("\r\nIPV6CP Receive-Code-Reject event\r\n");
Sergunb 0:8918a71cdbe9 518
Sergunb 0:8918a71cdbe9 519 //Point to the rejected packet
Sergunb 0:8918a71cdbe9 520 packet = (PppPacket *) codeRejPacket->rejectedPacket;
Sergunb 0:8918a71cdbe9 521 //Retrieve the length of the rejected packet
Sergunb 0:8918a71cdbe9 522 length = ntohs(codeRejPacket->length) - sizeof(PppCodeRejPacket);
Sergunb 0:8918a71cdbe9 523
Sergunb 0:8918a71cdbe9 524 //Make sure the length of the rejected packet is valid
Sergunb 0:8918a71cdbe9 525 if(length < sizeof(PppPacket))
Sergunb 0:8918a71cdbe9 526 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 527
Sergunb 0:8918a71cdbe9 528 //Check whether the rejected value is acceptable or catastrophic
Sergunb 0:8918a71cdbe9 529 if(packet->code < PPP_CODE_CONFIGURE_REQ ||
Sergunb 0:8918a71cdbe9 530 packet->code > PPP_CODE_CODE_REJ)
Sergunb 0:8918a71cdbe9 531 {
Sergunb 0:8918a71cdbe9 532 //The RXJ+ event arises when the rejected value is acceptable, such
Sergunb 0:8918a71cdbe9 533 //as a Code-Reject of an extended code, or a Protocol-Reject of a
Sergunb 0:8918a71cdbe9 534 //NCP. These are within the scope of normal operation
Sergunb 0:8918a71cdbe9 535 pppRcvCodeRejEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks, TRUE);
Sergunb 0:8918a71cdbe9 536 }
Sergunb 0:8918a71cdbe9 537 else
Sergunb 0:8918a71cdbe9 538 {
Sergunb 0:8918a71cdbe9 539 //The RXJ- event arises when the rejected value is catastrophic, such
Sergunb 0:8918a71cdbe9 540 //as a Code-Reject of Configure-Request! This event communicates an
Sergunb 0:8918a71cdbe9 541 //unrecoverable error that terminates the connection
Sergunb 0:8918a71cdbe9 542 pppRcvCodeRejEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks, FALSE);
Sergunb 0:8918a71cdbe9 543 }
Sergunb 0:8918a71cdbe9 544
Sergunb 0:8918a71cdbe9 545 //Successful processing
Sergunb 0:8918a71cdbe9 546 return NO_ERROR;
Sergunb 0:8918a71cdbe9 547 }
Sergunb 0:8918a71cdbe9 548
Sergunb 0:8918a71cdbe9 549
Sergunb 0:8918a71cdbe9 550 /**
Sergunb 0:8918a71cdbe9 551 * @brief Process packet with unknown code
Sergunb 0:8918a71cdbe9 552 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 553 * @param[in] packet Un-interpretable packet received from the peer
Sergunb 0:8918a71cdbe9 554 * @return Error code
Sergunb 0:8918a71cdbe9 555 **/
Sergunb 0:8918a71cdbe9 556
Sergunb 0:8918a71cdbe9 557 error_t ipv6cpProcessUnknownCode(PppContext *context,
Sergunb 0:8918a71cdbe9 558 const PppPacket *packet)
Sergunb 0:8918a71cdbe9 559 {
Sergunb 0:8918a71cdbe9 560 //Debug message
Sergunb 0:8918a71cdbe9 561 TRACE_INFO("\r\nIPV6CP Receive-Unknown-Code event\r\n");
Sergunb 0:8918a71cdbe9 562
Sergunb 0:8918a71cdbe9 563 //This event occurs when an un-interpretable packet is received from
Sergunb 0:8918a71cdbe9 564 //the peer. A Code-Reject packet is sent in response
Sergunb 0:8918a71cdbe9 565 pppRcvUnknownCodeEvent(context, &context->ipv6cpFsm, &ipv6cpCallbacks, packet);
Sergunb 0:8918a71cdbe9 566
Sergunb 0:8918a71cdbe9 567 //Successful processing
Sergunb 0:8918a71cdbe9 568 return NO_ERROR;
Sergunb 0:8918a71cdbe9 569 }
Sergunb 0:8918a71cdbe9 570
Sergunb 0:8918a71cdbe9 571
Sergunb 0:8918a71cdbe9 572 /**
Sergunb 0:8918a71cdbe9 573 * @brief This-Layer-Up callback function
Sergunb 0:8918a71cdbe9 574 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 575 **/
Sergunb 0:8918a71cdbe9 576
Sergunb 0:8918a71cdbe9 577 void ipv6cpThisLayerUp(PppContext *context)
Sergunb 0:8918a71cdbe9 578 {
Sergunb 0:8918a71cdbe9 579 NetInterface *interface;
Sergunb 0:8918a71cdbe9 580 Ipv6Addr ipAddr;
Sergunb 0:8918a71cdbe9 581
Sergunb 0:8918a71cdbe9 582 //Debug message
Sergunb 0:8918a71cdbe9 583 TRACE_INFO("IPV6CP This-Layer-Up callback\r\n");
Sergunb 0:8918a71cdbe9 584
Sergunb 0:8918a71cdbe9 585 //Debug message
Sergunb 0:8918a71cdbe9 586 TRACE_INFO(" Local Interface Id = %s\r\n",
Sergunb 0:8918a71cdbe9 587 eui64AddrToString(&context->localConfig.interfaceId, NULL));
Sergunb 0:8918a71cdbe9 588 TRACE_INFO(" Peer Interface Id = %s\r\n",
Sergunb 0:8918a71cdbe9 589 eui64AddrToString(&context->peerConfig.interfaceId, NULL));
Sergunb 0:8918a71cdbe9 590
Sergunb 0:8918a71cdbe9 591 //Point to the underlying interface
Sergunb 0:8918a71cdbe9 592 interface = context->interface;
Sergunb 0:8918a71cdbe9 593
Sergunb 0:8918a71cdbe9 594 //Generate an IPv6 address from the local interface identifier
Sergunb 0:8918a71cdbe9 595 ipv6GenerateLinkLocalAddr(&context->localConfig.interfaceId, &ipAddr);
Sergunb 0:8918a71cdbe9 596
Sergunb 0:8918a71cdbe9 597 //Update IPv6 configuration
Sergunb 0:8918a71cdbe9 598 ipv6SetAddr(interface, 0, &ipAddr, IPV6_ADDR_STATE_PREFERRED,
Sergunb 0:8918a71cdbe9 599 NDP_INFINITE_LIFETIME, NDP_INFINITE_LIFETIME, TRUE);
Sergunb 0:8918a71cdbe9 600
Sergunb 0:8918a71cdbe9 601 //Generate an IPv6 address from the remote interface identifier
Sergunb 0:8918a71cdbe9 602 ipv6GenerateLinkLocalAddr(&context->peerConfig.interfaceId, &ipAddr);
Sergunb 0:8918a71cdbe9 603
Sergunb 0:8918a71cdbe9 604 //Update IPv6 configuration
Sergunb 0:8918a71cdbe9 605 interface->ipv6Context.routerList[0].addr = ipAddr;
Sergunb 0:8918a71cdbe9 606 interface->ipv6Context.routerList[0].permanent = TRUE;
Sergunb 0:8918a71cdbe9 607
Sergunb 0:8918a71cdbe9 608 //Link is up
Sergunb 0:8918a71cdbe9 609 interface->linkState = TRUE;
Sergunb 0:8918a71cdbe9 610
Sergunb 0:8918a71cdbe9 611 //Disable interrupts
Sergunb 0:8918a71cdbe9 612 interface->nicDriver->disableIrq(interface);
Sergunb 0:8918a71cdbe9 613 //Process link state change event
Sergunb 0:8918a71cdbe9 614 nicNotifyLinkChange(interface);
Sergunb 0:8918a71cdbe9 615 //Re-enable interrupts
Sergunb 0:8918a71cdbe9 616 interface->nicDriver->enableIrq(interface);
Sergunb 0:8918a71cdbe9 617 }
Sergunb 0:8918a71cdbe9 618
Sergunb 0:8918a71cdbe9 619
Sergunb 0:8918a71cdbe9 620 /**
Sergunb 0:8918a71cdbe9 621 * @brief This-Layer-Down callback function
Sergunb 0:8918a71cdbe9 622 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 623 **/
Sergunb 0:8918a71cdbe9 624
Sergunb 0:8918a71cdbe9 625 void ipv6cpThisLayerDown(PppContext *context)
Sergunb 0:8918a71cdbe9 626 {
Sergunb 0:8918a71cdbe9 627 NetInterface *interface;
Sergunb 0:8918a71cdbe9 628
Sergunb 0:8918a71cdbe9 629 //Debug message
Sergunb 0:8918a71cdbe9 630 TRACE_INFO("IPV6CP This-Layer-Down callback\r\n");
Sergunb 0:8918a71cdbe9 631
Sergunb 0:8918a71cdbe9 632 //Point to the underlying interface
Sergunb 0:8918a71cdbe9 633 interface = context->interface;
Sergunb 0:8918a71cdbe9 634
Sergunb 0:8918a71cdbe9 635 //Link is up
Sergunb 0:8918a71cdbe9 636 interface->linkState = FALSE;
Sergunb 0:8918a71cdbe9 637
Sergunb 0:8918a71cdbe9 638 //Disable interrupts
Sergunb 0:8918a71cdbe9 639 interface->nicDriver->disableIrq(interface);
Sergunb 0:8918a71cdbe9 640 //Process link state change event
Sergunb 0:8918a71cdbe9 641 nicNotifyLinkChange(interface);
Sergunb 0:8918a71cdbe9 642 //Re-enable interrupts
Sergunb 0:8918a71cdbe9 643 interface->nicDriver->enableIrq(interface);
Sergunb 0:8918a71cdbe9 644 }
Sergunb 0:8918a71cdbe9 645
Sergunb 0:8918a71cdbe9 646
Sergunb 0:8918a71cdbe9 647 /**
Sergunb 0:8918a71cdbe9 648 * @brief This-Layer-Started callback function
Sergunb 0:8918a71cdbe9 649 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 650 **/
Sergunb 0:8918a71cdbe9 651
Sergunb 0:8918a71cdbe9 652 void ipv6cpThisLayerStarted(PppContext *context)
Sergunb 0:8918a71cdbe9 653 {
Sergunb 0:8918a71cdbe9 654 //Debug message
Sergunb 0:8918a71cdbe9 655 TRACE_INFO("IPV6CP This-Layer-Started callback\r\n");
Sergunb 0:8918a71cdbe9 656 }
Sergunb 0:8918a71cdbe9 657
Sergunb 0:8918a71cdbe9 658
Sergunb 0:8918a71cdbe9 659 /**
Sergunb 0:8918a71cdbe9 660 * @brief This-Layer-Finished callback function
Sergunb 0:8918a71cdbe9 661 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 662 **/
Sergunb 0:8918a71cdbe9 663
Sergunb 0:8918a71cdbe9 664 void ipv6cpThisLayerFinished(PppContext *context)
Sergunb 0:8918a71cdbe9 665 {
Sergunb 0:8918a71cdbe9 666 //Debug message
Sergunb 0:8918a71cdbe9 667 TRACE_INFO("IPV6CP This-Layer-Finished callback\r\n");
Sergunb 0:8918a71cdbe9 668 }
Sergunb 0:8918a71cdbe9 669
Sergunb 0:8918a71cdbe9 670
Sergunb 0:8918a71cdbe9 671 /**
Sergunb 0:8918a71cdbe9 672 * @brief Initialize-Restart-Count callback function
Sergunb 0:8918a71cdbe9 673 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 674 * @param[in] value Restart counter value
Sergunb 0:8918a71cdbe9 675 **/
Sergunb 0:8918a71cdbe9 676
Sergunb 0:8918a71cdbe9 677 void ipv6cpInitRestartCount(PppContext *context, uint_t value)
Sergunb 0:8918a71cdbe9 678 {
Sergunb 0:8918a71cdbe9 679 //Debug message
Sergunb 0:8918a71cdbe9 680 TRACE_INFO("IPV6CP Initialize-Restart-Count callback\r\n");
Sergunb 0:8918a71cdbe9 681
Sergunb 0:8918a71cdbe9 682 //Initialize restart counter
Sergunb 0:8918a71cdbe9 683 context->ipv6cpFsm.restartCounter = value;
Sergunb 0:8918a71cdbe9 684 }
Sergunb 0:8918a71cdbe9 685
Sergunb 0:8918a71cdbe9 686
Sergunb 0:8918a71cdbe9 687 /**
Sergunb 0:8918a71cdbe9 688 * @brief Zero-Restart-Count callback function
Sergunb 0:8918a71cdbe9 689 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 690 **/
Sergunb 0:8918a71cdbe9 691
Sergunb 0:8918a71cdbe9 692 void ipv6cpZeroRestartCount(PppContext *context)
Sergunb 0:8918a71cdbe9 693 {
Sergunb 0:8918a71cdbe9 694 //Debug message
Sergunb 0:8918a71cdbe9 695 TRACE_INFO("IPV6CP Zero-Restart-Count callback\r\n");
Sergunb 0:8918a71cdbe9 696
Sergunb 0:8918a71cdbe9 697 //Zero restart counter
Sergunb 0:8918a71cdbe9 698 context->ipv6cpFsm.restartCounter = 0;
Sergunb 0:8918a71cdbe9 699
Sergunb 0:8918a71cdbe9 700 //The receiver of a Terminate-Request should wait for the peer to
Sergunb 0:8918a71cdbe9 701 //disconnect, and must not disconnect until at least one Restart
Sergunb 0:8918a71cdbe9 702 //time has passed after sending a Terminate-Ack
Sergunb 0:8918a71cdbe9 703 context->ipv6cpFsm.timestamp = osGetSystemTime();
Sergunb 0:8918a71cdbe9 704 }
Sergunb 0:8918a71cdbe9 705
Sergunb 0:8918a71cdbe9 706
Sergunb 0:8918a71cdbe9 707 /**
Sergunb 0:8918a71cdbe9 708 * @brief Send-Configure-Request callback function
Sergunb 0:8918a71cdbe9 709 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 710 * @return Error code
Sergunb 0:8918a71cdbe9 711 **/
Sergunb 0:8918a71cdbe9 712
Sergunb 0:8918a71cdbe9 713 error_t ipv6cpSendConfigureReq(PppContext *context)
Sergunb 0:8918a71cdbe9 714 {
Sergunb 0:8918a71cdbe9 715 error_t error;
Sergunb 0:8918a71cdbe9 716 size_t length;
Sergunb 0:8918a71cdbe9 717 size_t offset;
Sergunb 0:8918a71cdbe9 718 NetBuffer *buffer;
Sergunb 0:8918a71cdbe9 719 PppConfigurePacket *configureReqPacket;
Sergunb 0:8918a71cdbe9 720
Sergunb 0:8918a71cdbe9 721 //Debug message
Sergunb 0:8918a71cdbe9 722 TRACE_INFO("IPV6CP Send-Configure-Request callback\r\n");
Sergunb 0:8918a71cdbe9 723
Sergunb 0:8918a71cdbe9 724 //Allocate a buffer memory to hold the Configure-Request packet
Sergunb 0:8918a71cdbe9 725 buffer = pppAllocBuffer(PPP_MAX_CONF_REQ_SIZE, &offset);
Sergunb 0:8918a71cdbe9 726 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 727 if(buffer == NULL)
Sergunb 0:8918a71cdbe9 728 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 729
Sergunb 0:8918a71cdbe9 730 //Point to the Configure-Request packet
Sergunb 0:8918a71cdbe9 731 configureReqPacket = netBufferAt(buffer, offset);
Sergunb 0:8918a71cdbe9 732
Sergunb 0:8918a71cdbe9 733 //Format packet header
Sergunb 0:8918a71cdbe9 734 configureReqPacket->code = PPP_CODE_CONFIGURE_REQ;
Sergunb 0:8918a71cdbe9 735 configureReqPacket->identifier = ++context->ipv6cpFsm.identifier;
Sergunb 0:8918a71cdbe9 736 configureReqPacket->length = sizeof(PppConfigurePacket);
Sergunb 0:8918a71cdbe9 737
Sergunb 0:8918a71cdbe9 738 //Make sure the Interface-Identifier option has not been previously rejected
Sergunb 0:8918a71cdbe9 739 if(!context->localConfig.interfaceIdRejected)
Sergunb 0:8918a71cdbe9 740 {
Sergunb 0:8918a71cdbe9 741 //Add option
Sergunb 0:8918a71cdbe9 742 pppAddOption(configureReqPacket, IPV6CP_OPTION_INTERFACE_ID,
Sergunb 0:8918a71cdbe9 743 &context->localConfig.interfaceId, sizeof(Eui64));
Sergunb 0:8918a71cdbe9 744 }
Sergunb 0:8918a71cdbe9 745
Sergunb 0:8918a71cdbe9 746 //Save packet length
Sergunb 0:8918a71cdbe9 747 length = configureReqPacket->length;
Sergunb 0:8918a71cdbe9 748 //Convert length field to network byte order
Sergunb 0:8918a71cdbe9 749 configureReqPacket->length = htons(length);
Sergunb 0:8918a71cdbe9 750
Sergunb 0:8918a71cdbe9 751 //Adjust the length of the multi-part buffer
Sergunb 0:8918a71cdbe9 752 netBufferSetLength(buffer, offset + length);
Sergunb 0:8918a71cdbe9 753
Sergunb 0:8918a71cdbe9 754 //Debug message
Sergunb 0:8918a71cdbe9 755 TRACE_INFO("Sending Configure-Request packet (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 756 //Dump packet contents for debugging purpose
Sergunb 0:8918a71cdbe9 757 pppDumpPacket((PppPacket *) configureReqPacket, length, PPP_PROTOCOL_IPV6CP);
Sergunb 0:8918a71cdbe9 758
Sergunb 0:8918a71cdbe9 759 //Send PPP frame
Sergunb 0:8918a71cdbe9 760 error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_IPV6CP);
Sergunb 0:8918a71cdbe9 761
Sergunb 0:8918a71cdbe9 762 //The restart counter is decremented each time a Configure-Request is sent
Sergunb 0:8918a71cdbe9 763 if(context->ipv6cpFsm.restartCounter > 0)
Sergunb 0:8918a71cdbe9 764 context->ipv6cpFsm.restartCounter--;
Sergunb 0:8918a71cdbe9 765
Sergunb 0:8918a71cdbe9 766 //Save the time at which the packet was sent
Sergunb 0:8918a71cdbe9 767 context->ipv6cpFsm.timestamp = osGetSystemTime();
Sergunb 0:8918a71cdbe9 768
Sergunb 0:8918a71cdbe9 769 //Free previously allocated memory block
Sergunb 0:8918a71cdbe9 770 netBufferFree(buffer);
Sergunb 0:8918a71cdbe9 771 //Return status code
Sergunb 0:8918a71cdbe9 772 return error;
Sergunb 0:8918a71cdbe9 773 }
Sergunb 0:8918a71cdbe9 774
Sergunb 0:8918a71cdbe9 775
Sergunb 0:8918a71cdbe9 776 /**
Sergunb 0:8918a71cdbe9 777 * @brief Send-Configure-Ack callback function
Sergunb 0:8918a71cdbe9 778 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 779 * @param[in] configureReqPacket Configure-Request packet received from the peer
Sergunb 0:8918a71cdbe9 780 * @return Error code
Sergunb 0:8918a71cdbe9 781 **/
Sergunb 0:8918a71cdbe9 782
Sergunb 0:8918a71cdbe9 783 error_t ipv6cpSendConfigureAck(PppContext *context,
Sergunb 0:8918a71cdbe9 784 const PppConfigurePacket *configureReqPacket)
Sergunb 0:8918a71cdbe9 785 {
Sergunb 0:8918a71cdbe9 786 //Debug message
Sergunb 0:8918a71cdbe9 787 TRACE_INFO("IPV6CP Send-Configure-Ack callback\r\n");
Sergunb 0:8918a71cdbe9 788
Sergunb 0:8918a71cdbe9 789 //Send Configure-Ack packet
Sergunb 0:8918a71cdbe9 790 return pppSendConfigureAckNak(context, configureReqPacket,
Sergunb 0:8918a71cdbe9 791 PPP_PROTOCOL_IPV6CP, PPP_CODE_CONFIGURE_ACK);
Sergunb 0:8918a71cdbe9 792 }
Sergunb 0:8918a71cdbe9 793
Sergunb 0:8918a71cdbe9 794
Sergunb 0:8918a71cdbe9 795 /**
Sergunb 0:8918a71cdbe9 796 * @brief Send-Configure-Nak callback function
Sergunb 0:8918a71cdbe9 797 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 798 * @param[in] configureReqPacket Configure-Request packet received from the peer
Sergunb 0:8918a71cdbe9 799 * @return Error code
Sergunb 0:8918a71cdbe9 800 **/
Sergunb 0:8918a71cdbe9 801
Sergunb 0:8918a71cdbe9 802 error_t ipv6cpSendConfigureNak(PppContext *context,
Sergunb 0:8918a71cdbe9 803 const PppConfigurePacket *configureReqPacket)
Sergunb 0:8918a71cdbe9 804 {
Sergunb 0:8918a71cdbe9 805 //Debug message
Sergunb 0:8918a71cdbe9 806 TRACE_INFO("IPV6CP Send-Configure-Nak callback\r\n");
Sergunb 0:8918a71cdbe9 807
Sergunb 0:8918a71cdbe9 808 //Send Configure-Nak packet
Sergunb 0:8918a71cdbe9 809 return pppSendConfigureAckNak(context, configureReqPacket,
Sergunb 0:8918a71cdbe9 810 PPP_PROTOCOL_IPV6CP, PPP_CODE_CONFIGURE_NAK);
Sergunb 0:8918a71cdbe9 811 }
Sergunb 0:8918a71cdbe9 812
Sergunb 0:8918a71cdbe9 813
Sergunb 0:8918a71cdbe9 814 /**
Sergunb 0:8918a71cdbe9 815 * @brief Send-Configure-Reject callback function
Sergunb 0:8918a71cdbe9 816 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 817 * @param[in] configureReqPacket Configure-Request packet received from the peer
Sergunb 0:8918a71cdbe9 818 * @return Error code
Sergunb 0:8918a71cdbe9 819 **/
Sergunb 0:8918a71cdbe9 820
Sergunb 0:8918a71cdbe9 821 error_t ipv6cpSendConfigureRej(PppContext *context,
Sergunb 0:8918a71cdbe9 822 const PppConfigurePacket *configureReqPacket)
Sergunb 0:8918a71cdbe9 823 {
Sergunb 0:8918a71cdbe9 824 //Debug message
Sergunb 0:8918a71cdbe9 825 TRACE_INFO("IPV6CP Send-Configure-Reject callback\r\n");
Sergunb 0:8918a71cdbe9 826
Sergunb 0:8918a71cdbe9 827 //Send Configure-Reject packet
Sergunb 0:8918a71cdbe9 828 return pppSendConfigureAckNak(context, configureReqPacket,
Sergunb 0:8918a71cdbe9 829 PPP_PROTOCOL_IPV6CP, PPP_CODE_CONFIGURE_REJ);
Sergunb 0:8918a71cdbe9 830 }
Sergunb 0:8918a71cdbe9 831
Sergunb 0:8918a71cdbe9 832
Sergunb 0:8918a71cdbe9 833 /**
Sergunb 0:8918a71cdbe9 834 * @brief Send-Terminate-Request callback function
Sergunb 0:8918a71cdbe9 835 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 836 * @return Error code
Sergunb 0:8918a71cdbe9 837 **/
Sergunb 0:8918a71cdbe9 838
Sergunb 0:8918a71cdbe9 839 error_t ipv6cpSendTerminateReq(PppContext *context)
Sergunb 0:8918a71cdbe9 840 {
Sergunb 0:8918a71cdbe9 841 error_t error;
Sergunb 0:8918a71cdbe9 842
Sergunb 0:8918a71cdbe9 843 //Debug message
Sergunb 0:8918a71cdbe9 844 TRACE_INFO("IPV6CP Send-Terminate-Request callback\r\n");
Sergunb 0:8918a71cdbe9 845
Sergunb 0:8918a71cdbe9 846 //On transmission, the Identifier field must be changed
Sergunb 0:8918a71cdbe9 847 context->ipv6cpFsm.identifier++;
Sergunb 0:8918a71cdbe9 848
Sergunb 0:8918a71cdbe9 849 //Send Terminate-Request packet
Sergunb 0:8918a71cdbe9 850 error = pppSendTerminateReq(context, context->ipv6cpFsm.identifier, PPP_PROTOCOL_IPV6CP);
Sergunb 0:8918a71cdbe9 851
Sergunb 0:8918a71cdbe9 852 //The restart counter is decremented each time a Terminate-Request is sent
Sergunb 0:8918a71cdbe9 853 if(context->ipv6cpFsm.restartCounter > 0)
Sergunb 0:8918a71cdbe9 854 context->ipv6cpFsm.restartCounter--;
Sergunb 0:8918a71cdbe9 855
Sergunb 0:8918a71cdbe9 856 //Save the time at which the packet was sent
Sergunb 0:8918a71cdbe9 857 context->ipv6cpFsm.timestamp = osGetSystemTime();
Sergunb 0:8918a71cdbe9 858
Sergunb 0:8918a71cdbe9 859 //Return status code
Sergunb 0:8918a71cdbe9 860 return error;
Sergunb 0:8918a71cdbe9 861 }
Sergunb 0:8918a71cdbe9 862
Sergunb 0:8918a71cdbe9 863
Sergunb 0:8918a71cdbe9 864 /**
Sergunb 0:8918a71cdbe9 865 * @brief Send-Terminate-Ack callback function
Sergunb 0:8918a71cdbe9 866 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 867 * @param[in] terminateReqPacket Terminate-Request packet received from the peer
Sergunb 0:8918a71cdbe9 868 * @return Error code
Sergunb 0:8918a71cdbe9 869 **/
Sergunb 0:8918a71cdbe9 870
Sergunb 0:8918a71cdbe9 871 error_t ipv6cpSendTerminateAck(PppContext *context,
Sergunb 0:8918a71cdbe9 872 const PppTerminatePacket *terminateReqPacket)
Sergunb 0:8918a71cdbe9 873 {
Sergunb 0:8918a71cdbe9 874 uint8_t identifier;
Sergunb 0:8918a71cdbe9 875
Sergunb 0:8918a71cdbe9 876 //Debug message
Sergunb 0:8918a71cdbe9 877 TRACE_INFO("IPV6CP Send-Terminate-Ack callback\r\n");
Sergunb 0:8918a71cdbe9 878
Sergunb 0:8918a71cdbe9 879 //Check whether this Terminate-Ack acknowledges the reception of a
Sergunb 0:8918a71cdbe9 880 //Terminate-Request packet
Sergunb 0:8918a71cdbe9 881 if(terminateReqPacket != NULL)
Sergunb 0:8918a71cdbe9 882 {
Sergunb 0:8918a71cdbe9 883 //The Identifier field of the Terminate-Request is copied into the
Sergunb 0:8918a71cdbe9 884 //Identifier field of the Terminate-Ack packet
Sergunb 0:8918a71cdbe9 885 identifier = terminateReqPacket->identifier;
Sergunb 0:8918a71cdbe9 886 }
Sergunb 0:8918a71cdbe9 887 else
Sergunb 0:8918a71cdbe9 888 {
Sergunb 0:8918a71cdbe9 889 //This Terminate-Ack packet serves to synchronize the automatons
Sergunb 0:8918a71cdbe9 890 identifier = ++context->ipv6cpFsm.identifier;
Sergunb 0:8918a71cdbe9 891 }
Sergunb 0:8918a71cdbe9 892
Sergunb 0:8918a71cdbe9 893 //Send Terminate-Ack packet
Sergunb 0:8918a71cdbe9 894 return pppSendTerminateAck(context, identifier, PPP_PROTOCOL_IPV6CP);
Sergunb 0:8918a71cdbe9 895 }
Sergunb 0:8918a71cdbe9 896
Sergunb 0:8918a71cdbe9 897
Sergunb 0:8918a71cdbe9 898 /**
Sergunb 0:8918a71cdbe9 899 * @brief Send-Code-Reject callback function
Sergunb 0:8918a71cdbe9 900 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 901 * @param[in] packet Un-interpretable packet received from the peer
Sergunb 0:8918a71cdbe9 902 * @return Error code
Sergunb 0:8918a71cdbe9 903 **/
Sergunb 0:8918a71cdbe9 904
Sergunb 0:8918a71cdbe9 905 error_t ipv6cpSendCodeRej(PppContext *context, const PppPacket *packet)
Sergunb 0:8918a71cdbe9 906 {
Sergunb 0:8918a71cdbe9 907 //Debug message
Sergunb 0:8918a71cdbe9 908 TRACE_INFO("IPV6CP Send-Code-Reject callback\r\n");
Sergunb 0:8918a71cdbe9 909
Sergunb 0:8918a71cdbe9 910 //The Identifier field must be changed for each Code-Reject sent
Sergunb 0:8918a71cdbe9 911 context->ipv6cpFsm.identifier++;
Sergunb 0:8918a71cdbe9 912
Sergunb 0:8918a71cdbe9 913 //Send Code-Reject packet
Sergunb 0:8918a71cdbe9 914 return pppSendCodeRej(context, packet, context->ipv6cpFsm.identifier, PPP_PROTOCOL_IPV6CP);
Sergunb 0:8918a71cdbe9 915 }
Sergunb 0:8918a71cdbe9 916
Sergunb 0:8918a71cdbe9 917
Sergunb 0:8918a71cdbe9 918 /**
Sergunb 0:8918a71cdbe9 919 * @brief Parse IPV6CP configuration option
Sergunb 0:8918a71cdbe9 920 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 921 * @param[in] option Option to be checked
Sergunb 0:8918a71cdbe9 922 * @param[in] inPacketLen Remaining bytes to process in the incoming packet
Sergunb 0:8918a71cdbe9 923 * @param[out] outPacket Pointer to the Configure-Ack, Nak or Reject packet
Sergunb 0:8918a71cdbe9 924 * @return Error code
Sergunb 0:8918a71cdbe9 925 **/
Sergunb 0:8918a71cdbe9 926
Sergunb 0:8918a71cdbe9 927 error_t ipv6cpParseOption(PppContext *context, PppOption *option,
Sergunb 0:8918a71cdbe9 928 size_t inPacketLen, PppConfigurePacket *outPacket)
Sergunb 0:8918a71cdbe9 929 {
Sergunb 0:8918a71cdbe9 930 error_t error;
Sergunb 0:8918a71cdbe9 931
Sergunb 0:8918a71cdbe9 932 //Malformed IPV6CP packet?
Sergunb 0:8918a71cdbe9 933 if(inPacketLen < sizeof(PppOption))
Sergunb 0:8918a71cdbe9 934 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 935
Sergunb 0:8918a71cdbe9 936 //Check option length
Sergunb 0:8918a71cdbe9 937 if(option->length < sizeof(PppOption))
Sergunb 0:8918a71cdbe9 938 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 939 if(option->length > inPacketLen)
Sergunb 0:8918a71cdbe9 940 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 941
Sergunb 0:8918a71cdbe9 942 //Check option type
Sergunb 0:8918a71cdbe9 943 switch(option->type)
Sergunb 0:8918a71cdbe9 944 {
Sergunb 0:8918a71cdbe9 945 case IPV6CP_OPTION_INTERFACE_ID:
Sergunb 0:8918a71cdbe9 946 //Check Interface-Identifier option
Sergunb 0:8918a71cdbe9 947 error = ipv6cpParseInterfaceIdOption(context, (Ipv6cpInterfaceIdOption *) option, outPacket);
Sergunb 0:8918a71cdbe9 948 break;
Sergunb 0:8918a71cdbe9 949 default:
Sergunb 0:8918a71cdbe9 950 //If some configuration options received in the Configure-Request are not
Sergunb 0:8918a71cdbe9 951 //recognizable or not acceptable for negotiation, then the implementation
Sergunb 0:8918a71cdbe9 952 //must transmit a Configure-Reject
Sergunb 0:8918a71cdbe9 953 if(outPacket->code == PPP_CODE_CONFIGURE_REJ)
Sergunb 0:8918a71cdbe9 954 {
Sergunb 0:8918a71cdbe9 955 //The options field of the Configure-Reject packet is filled
Sergunb 0:8918a71cdbe9 956 //with the unrecognized options from the Configure-Request
Sergunb 0:8918a71cdbe9 957 pppAddOption(outPacket, option->type, option->data,
Sergunb 0:8918a71cdbe9 958 option->length - sizeof(PppOption));
Sergunb 0:8918a71cdbe9 959 }
Sergunb 0:8918a71cdbe9 960
Sergunb 0:8918a71cdbe9 961 //The option is not acceptable for negotiation
Sergunb 0:8918a71cdbe9 962 error = ERROR_INVALID_TYPE;
Sergunb 0:8918a71cdbe9 963 break;
Sergunb 0:8918a71cdbe9 964 }
Sergunb 0:8918a71cdbe9 965
Sergunb 0:8918a71cdbe9 966 //Return status code
Sergunb 0:8918a71cdbe9 967 return error;
Sergunb 0:8918a71cdbe9 968 }
Sergunb 0:8918a71cdbe9 969
Sergunb 0:8918a71cdbe9 970
Sergunb 0:8918a71cdbe9 971 /**
Sergunb 0:8918a71cdbe9 972 * @brief Parse Interface-Identifier option
Sergunb 0:8918a71cdbe9 973 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 974 * @param[in] option Option to be checked
Sergunb 0:8918a71cdbe9 975 * @param[out] outPacket Pointer to the Configure-Nak or Configure-Reject packet
Sergunb 0:8918a71cdbe9 976 * @return Error code
Sergunb 0:8918a71cdbe9 977 **/
Sergunb 0:8918a71cdbe9 978
Sergunb 0:8918a71cdbe9 979 error_t ipv6cpParseInterfaceIdOption(PppContext *context,
Sergunb 0:8918a71cdbe9 980 Ipv6cpInterfaceIdOption *option, PppConfigurePacket *outPacket)
Sergunb 0:8918a71cdbe9 981 {
Sergunb 0:8918a71cdbe9 982 error_t error;
Sergunb 0:8918a71cdbe9 983
Sergunb 0:8918a71cdbe9 984 //Check length field
Sergunb 0:8918a71cdbe9 985 if(option->length == sizeof(Ipv6cpInterfaceIdOption))
Sergunb 0:8918a71cdbe9 986 {
Sergunb 0:8918a71cdbe9 987 //Check whether the option value is acceptable
Sergunb 0:8918a71cdbe9 988 if(!eui64CompAddr(&option->interfaceId, &EUI64_UNSPECIFIED_ADDR))
Sergunb 0:8918a71cdbe9 989 {
Sergunb 0:8918a71cdbe9 990 //If every configuration option received in the Configure-Request is
Sergunb 0:8918a71cdbe9 991 //recognizable and all values are acceptable, then the implementation
Sergunb 0:8918a71cdbe9 992 //must transmit a Configure-Ack
Sergunb 0:8918a71cdbe9 993 if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_ACK)
Sergunb 0:8918a71cdbe9 994 {
Sergunb 0:8918a71cdbe9 995 //Save interface identifier
Sergunb 0:8918a71cdbe9 996 context->peerConfig.interfaceId = option->interfaceId;
Sergunb 0:8918a71cdbe9 997
Sergunb 0:8918a71cdbe9 998 //The options field of the Configure-Ack packet contains the
Sergunb 0:8918a71cdbe9 999 //configuration options that the sender is acknowledging
Sergunb 0:8918a71cdbe9 1000 pppAddOption(outPacket, IPV6CP_OPTION_INTERFACE_ID,
Sergunb 0:8918a71cdbe9 1001 &option->interfaceId, option->length - sizeof(PppOption));
Sergunb 0:8918a71cdbe9 1002 }
Sergunb 0:8918a71cdbe9 1003
Sergunb 0:8918a71cdbe9 1004 //The value is acceptable
Sergunb 0:8918a71cdbe9 1005 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 1006 }
Sergunb 0:8918a71cdbe9 1007 else
Sergunb 0:8918a71cdbe9 1008 {
Sergunb 0:8918a71cdbe9 1009 //If all configuration options are recognizable, but some values are not
Sergunb 0:8918a71cdbe9 1010 //acceptable, then the implementation must transmit a Configure-Nak
Sergunb 0:8918a71cdbe9 1011 if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_NAK)
Sergunb 0:8918a71cdbe9 1012 {
Sergunb 0:8918a71cdbe9 1013 //The option must be modified to a value acceptable to the
Sergunb 0:8918a71cdbe9 1014 //Configure-Nak sender
Sergunb 0:8918a71cdbe9 1015 pppAddOption(outPacket, IPV6CP_OPTION_INTERFACE_ID,
Sergunb 0:8918a71cdbe9 1016 &context->peerConfig.interfaceId, sizeof(Eui64));
Sergunb 0:8918a71cdbe9 1017 }
Sergunb 0:8918a71cdbe9 1018
Sergunb 0:8918a71cdbe9 1019 //The value is not acceptable
Sergunb 0:8918a71cdbe9 1020 error = ERROR_INVALID_VALUE;
Sergunb 0:8918a71cdbe9 1021 }
Sergunb 0:8918a71cdbe9 1022 }
Sergunb 0:8918a71cdbe9 1023 else
Sergunb 0:8918a71cdbe9 1024 {
Sergunb 0:8918a71cdbe9 1025 //Invalid length field
Sergunb 0:8918a71cdbe9 1026 error = ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 1027 }
Sergunb 0:8918a71cdbe9 1028
Sergunb 0:8918a71cdbe9 1029 //Return status code
Sergunb 0:8918a71cdbe9 1030 return error;
Sergunb 0:8918a71cdbe9 1031 }
Sergunb 0:8918a71cdbe9 1032
Sergunb 0:8918a71cdbe9 1033 #endif
Sergunb 0:8918a71cdbe9 1034