diff --git a/src/Cedar/IPC.c b/src/Cedar/IPC.c index 0dd554a3..e87f4ce0 100644 --- a/src/Cedar/IPC.c +++ b/src/Cedar/IPC.c @@ -2128,7 +2128,7 @@ void IPCIPv6Init(IPC *ipc) ipc->IPv6RouterAdvs = NewList(NULL); ipc->IPv6ClientEUI = 0; - ipc->IPv6ServerEUI = 0; + GenerateEui64Address6((UCHAR *)&ipc->IPv6ServerEUI, ipc->MacAddress); ipc->IPv6State = IPC_PROTO_STATUS_CLOSED; } @@ -2364,6 +2364,12 @@ bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVER UINT i; IPC_IPV6_ROUTER_ADVERTISEMENT *matchingRA = NULL; bool isInPrefix = false; + + if (LIST_NUM(ipc->IPv6RouterAdvs) == 0 && IPCSendIPv6RouterSoliciation(ipc) == false) + { + return false; + } + for (i = 0; i < LIST_NUM(ipc->IPv6RouterAdvs); i++) { IPC_IPV6_ROUTER_ADVERTISEMENT *ra = LIST_DATA(ipc->IPv6RouterAdvs, i); @@ -2383,19 +2389,13 @@ bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVER return isInPrefix; } -// Send router solicitation and then eventually populate the info from Router Advertisements -UINT64 IPCIPv6GetServerEui(IPC *ipc) +// Send router solicitation to find a router +bool IPCSendIPv6RouterSoliciation(IPC *ipc) { - // It is already configured, nothing to do here - if (ipc->IPv6ServerEUI != 0) - { - return ipc->IPv6ServerEUI; - } - // If we don't have a valid client EUI, we can't generate a correct link local if (ipc->IPv6ClientEUI == 0) { - return ipc->IPv6ServerEUI; + return false; } if (LIST_NUM(ipc->IPv6RouterAdvs) == 0) @@ -2440,7 +2440,8 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc) if (Tick64() >= giveup_time) { // We failed to receive any router advertisements - break; + FreeBuf(packet); + return false; } // The processing should populate the received RAs by itself @@ -2450,24 +2451,7 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc) FreeBuf(packet); } - // Populating the IPv6 Server EUI for IPV6CP - if (LIST_NUM(ipc->IPv6RouterAdvs) > 0) - { - IPC_IPV6_ROUTER_ADVERTISEMENT *ra = LIST_DATA(ipc->IPv6RouterAdvs, 0); - Copy(&ipc->IPv6ServerEUI, &ra->RouterAddress.address[8], sizeof(ipc->IPv6ServerEUI)); - } - - // If it is still not defined, let's just generate something random - while (ipc->IPv6ServerEUI == 0) - { - ipc->IPv6ServerEUI = Rand64(); - if (ipc->IPv6ClientEUI == ipc->IPv6ServerEUI) - { - ipc->IPv6ServerEUI = 0; - } - } - - return ipc->IPv6ServerEUI; + return true; } // Data flow diff --git a/src/Cedar/IPC.h b/src/Cedar/IPC.h index ed9ae24d..ad0e8c04 100644 --- a/src/Cedar/IPC.h +++ b/src/Cedar/IPC.h @@ -155,7 +155,7 @@ struct IPC LIST *IPv6NeighborTable; // Neighbor Discovery Table LIST *IPv6RouterAdvs; // Router offered prefixes UINT64 IPv6ClientEUI; // The EUI of the client (for the SLAAC autoconf) - UINT64 IPv6ServerEUI; // The EUI of the server (from the RA discovery) + UINT64 IPv6ServerEUI; // The EUI of the server (from the IPC Mac address) }; // MS-CHAPv2 authentication information @@ -233,7 +233,7 @@ bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui); // RA void IPCIPv6AddRouterPrefixes(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip); bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA); -UINT64 IPCIPv6GetServerEui(IPC *ipc); +bool IPCSendIPv6RouterSoliciation(IPC *ipc); // Data flow BLOCK *IPCIPv6Recv(IPC *ipc); void IPCIPv6Send(IPC *ipc, void *data, UINT size); diff --git a/src/Cedar/Proto_PPP.c b/src/Cedar/Proto_PPP.c index 96094b70..f3cac27d 100644 --- a/src/Cedar/Proto_PPP.c +++ b/src/Cedar/Proto_PPP.c @@ -2191,7 +2191,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) { UINT64 newValue = 0; UINT64 value = READ_UINT64(t->Data); - if (value != 0 && IPCIPv6CheckExistingLinkLocal(p->Ipc, value) == false) + if (value != 0 && value != p->Ipc->IPv6ServerEUI && IPCIPv6CheckExistingLinkLocal(p->Ipc, value) == false) { t->IsAccepted = true; p->Ipc->IPv6ClientEUI = value; @@ -2199,23 +2199,14 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) else { t->IsAccepted = false; - GenerateEui64Address6((UCHAR *)&newValue, p->Ipc->MacAddress); - if (newValue != value && IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false) + while (true) { - WRITE_UINT64(t->AltData, newValue); - t->AltDataSize = sizeof(UINT64); - } - else - { - while (true) + newValue = Rand64(); + if (newValue != 0 && newValue != p->Ipc->IPv6ServerEUI && IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false) { - newValue = Rand64(); - if (IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false) - { - WRITE_UINT64(t->AltData, newValue); - t->AltDataSize = sizeof(UINT64); - break; - } + WRITE_UINT64(t->AltData, newValue); + t->AltDataSize = sizeof(UINT64); + break; } } } @@ -2242,11 +2233,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) if (p->Ipc->IPv6ClientEUI != 0 && IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CLOSED) { PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); - UINT64 serverEui = IPCIPv6GetServerEui(p->Ipc); - if (serverEui != 0 && serverEui != p->Ipc->IPv6ClientEUI) - { - Add(c->OptionList, NewPPPOption(PPP_IPV6CP_OPTION_EUI, &serverEui, sizeof(UINT64))); - } + Add(c->OptionList, NewPPPOption(PPP_IPV6CP_OPTION_EUI, &p->Ipc->IPv6ServerEUI, sizeof(UINT64))); if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPV6CP, c) == false) { PPPSetStatus(p, PPP_STATUS_FAIL);