--- /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 <in_chk.h>
+#include <in_sock.h>
+#include <in_bind.h>
+#include "in6_opt.h"
+#include <udp_hdr.h>
+
+#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<TInet6HeaderUDP> 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;
+ }
+
+