diff -r 000000000000 -r af10295192d8 networkprotocols/ipeventnotifier/src/DHCPUnicastTranslator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networkprotocols/ipeventnotifier/src/DHCPUnicastTranslator.cpp Tue Jan 26 15:23:49 2010 +0200 @@ -0,0 +1,147 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +/** + @file DHCPUnicastTranslator.cpp + @internalComponent +*/ + +#include +#include +#include +#include "in6_opt.h" +#include + +#include "DHCPUnicastTranslator.h" +#include "HookLog.h" +#include "ipeventlistener.h" + + + + +CDHCPUnicastTranslator::CDHCPUnicastTranslator(CProtocolInet6Binder& aParent): + iParent(aParent) + { + } + +CDHCPUnicastTranslator::~CDHCPUnicastTranslator() + { +// iParent.Unbind(this, 0); + } + +void CDHCPUnicastTranslator::FillIdentification(TServerProtocolDesc& anEntry) +/** + * Fills in an existing protocol description structure with details of this protocol. + * + * @param aProtocolDesc: reference to the structure to be filled in + */ + { + anEntry.iName=_S("dhcpunicasttranslator"); + anEntry.iAddrFamily=KAfInet; + anEntry.iSockType=0; + anEntry.iProtocol=1; // not in a family so doesn't really matter + anEntry.iVersion=TVersion(1, 0, 0); + anEntry.iByteOrder=EBigEndian; + anEntry.iServiceInfo=0; + anEntry.iNamingServices=0; + anEntry.iSecurity=0; + anEntry.iMessageSize=0; + anEntry.iServiceTypeInfo=0; + anEntry.iNumSockets=0; + } + + +void CDHCPUnicastTranslator::Identify(TServerProtocolDesc* aProtocolDesc) const +/** + * Fills in an existing protocol description structure with details of this protocol. + * + * @param aProtocolDesc: pointer to the structure to be filled in + */ + { + FillIdentification(*aProtocolDesc); + } + + + +/** + * Incoming packet + */ +TInt CDHCPUnicastTranslator::ApplyL(RMBufHookPacket& aPacket, RMBufRecvInfo& aInfo) + { + + LOG ( + _LIT(KHookNotifyStr,"CDHCPUnicastTranslator::ApplyL hit with protocol: %d"); + HookLog::Printf( KHookNotifyStr , aInfo.iProtocol ); + ) + + /** Fix for INC079832 - DHCP must be able to receive unicast replies from + * DHCP server (to an address that hasn't been set yet! chicken and egg). + * + * Without this, a DHCP reply unicast to an address which isn't yet assigned + * to the inbound interface will be dropped. + * + * So we need to detect BOOTP packets which are about to be dropped. This is + * done by installing this object as a "forwarding hook". + * + * DHCP packets are detected as follows: + * - packet is UDP + * - UDP destination port is 0x0044 + * + * Modification is performed by setting dest address to broadcast address + * (and updating checksum) + * + * Then we return KIp6Hook_DONE (which signals to the stack to re-inject + * the packet into the incoming data path). + * + * Note: this trick isn't needed for IPv6 as link-local unicast is always + * possible before network/global address has been assigned. + */ + if (aInfo.iVersion != 4 || aInfo.iProtocol != KProtocolInetUdp) + return KIp6Hook_PASS; // Only interested in IPv4 and UDP. + + TInetAddr& dst = TInetAddr::Cast(aInfo.iDstAddr); + + if (!dst.IsUnicast()) + return KIp6Hook_PASS; // Only the unicast case really needs fixing + + // Need to examine the UDP header + TInet6Packet udp(aPacket, aInfo.iOffset); + if (udp.iHdr == NULL) + return KIp6Hook_PASS; // Oops, short packet, let someone else worry about it. + + // To cause least distruption, one could try to check that this really is + // DCHP address configuration message with packet destination address + // matching the offered address inside DCHP message (but this would need + // more extensive packet snooping here) +#ifndef _DEBUG + if (udp.iHdr->DstPort() == 68) +#else + if (udp.iHdr->DstPort() == 68 || udp.iHdr->DstPort() == 127 || udp.iHdr->DstPort() == 119 || udp.iHdr->DstPort() == 125 + #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS + || udp.iHdr->DstPort() == 92 || udp.iHdr->DstPort() == 99 + #endif//SYMBIAN_NETWORKING_DHCP_MSG_HEADERS + ) // debug mode, src port 127, 119, 125, 91, 98 +#endif + { + static const TIp6Addr broadcast = {{{0,0,0,0,0,0,0,0,0,0,0xff,0xff,255,255,255,255}}}; + + dst.SetAddress(broadcast); + udp.iHdr->SetChecksum(0); // Either this or recompute the UDP checksum for broadcast address. + return KIp6Hook_DONE; + } + return KIp6Hook_PASS; + } + +