|
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file DHCPUnicastTranslator.cpp |
|
18 @internalComponent |
|
19 */ |
|
20 |
|
21 #include <in_chk.h> |
|
22 #include <in_sock.h> |
|
23 #include <in_bind.h> |
|
24 #include "in6_opt.h" |
|
25 #include <udp_hdr.h> |
|
26 |
|
27 #include "DHCPUnicastTranslator.h" |
|
28 #include "HookLog.h" |
|
29 #include "ipeventlistener.h" |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 CDHCPUnicastTranslator::CDHCPUnicastTranslator(CProtocolInet6Binder& aParent): |
|
35 iParent(aParent) |
|
36 { |
|
37 } |
|
38 |
|
39 CDHCPUnicastTranslator::~CDHCPUnicastTranslator() |
|
40 { |
|
41 // iParent.Unbind(this, 0); |
|
42 } |
|
43 |
|
44 void CDHCPUnicastTranslator::FillIdentification(TServerProtocolDesc& anEntry) |
|
45 /** |
|
46 * Fills in an existing protocol description structure with details of this protocol. |
|
47 * |
|
48 * @param aProtocolDesc: reference to the structure to be filled in |
|
49 */ |
|
50 { |
|
51 anEntry.iName=_S("dhcpunicasttranslator"); |
|
52 anEntry.iAddrFamily=KAfInet; |
|
53 anEntry.iSockType=0; |
|
54 anEntry.iProtocol=1; // not in a family so doesn't really matter |
|
55 anEntry.iVersion=TVersion(1, 0, 0); |
|
56 anEntry.iByteOrder=EBigEndian; |
|
57 anEntry.iServiceInfo=0; |
|
58 anEntry.iNamingServices=0; |
|
59 anEntry.iSecurity=0; |
|
60 anEntry.iMessageSize=0; |
|
61 anEntry.iServiceTypeInfo=0; |
|
62 anEntry.iNumSockets=0; |
|
63 } |
|
64 |
|
65 |
|
66 void CDHCPUnicastTranslator::Identify(TServerProtocolDesc* aProtocolDesc) const |
|
67 /** |
|
68 * Fills in an existing protocol description structure with details of this protocol. |
|
69 * |
|
70 * @param aProtocolDesc: pointer to the structure to be filled in |
|
71 */ |
|
72 { |
|
73 FillIdentification(*aProtocolDesc); |
|
74 } |
|
75 |
|
76 |
|
77 |
|
78 /** |
|
79 * Incoming packet |
|
80 */ |
|
81 TInt CDHCPUnicastTranslator::ApplyL(RMBufHookPacket& aPacket, RMBufRecvInfo& aInfo) |
|
82 { |
|
83 |
|
84 LOG ( |
|
85 _LIT(KHookNotifyStr,"CDHCPUnicastTranslator::ApplyL hit with protocol: %d"); |
|
86 HookLog::Printf( KHookNotifyStr , aInfo.iProtocol ); |
|
87 ) |
|
88 |
|
89 /** Fix for INC079832 - DHCP must be able to receive unicast replies from |
|
90 * DHCP server (to an address that hasn't been set yet! chicken and egg). |
|
91 * |
|
92 * Without this, a DHCP reply unicast to an address which isn't yet assigned |
|
93 * to the inbound interface will be dropped. |
|
94 * |
|
95 * So we need to detect BOOTP packets which are about to be dropped. This is |
|
96 * done by installing this object as a "forwarding hook". |
|
97 * |
|
98 * DHCP packets are detected as follows: |
|
99 * - packet is UDP |
|
100 * - UDP destination port is 0x0044 |
|
101 * |
|
102 * Modification is performed by setting dest address to broadcast address |
|
103 * (and updating checksum) |
|
104 * |
|
105 * Then we return KIp6Hook_DONE (which signals to the stack to re-inject |
|
106 * the packet into the incoming data path). |
|
107 * |
|
108 * Note: this trick isn't needed for IPv6 as link-local unicast is always |
|
109 * possible before network/global address has been assigned. |
|
110 */ |
|
111 if (aInfo.iVersion != 4 || aInfo.iProtocol != KProtocolInetUdp) |
|
112 return KIp6Hook_PASS; // Only interested in IPv4 and UDP. |
|
113 |
|
114 TInetAddr& dst = TInetAddr::Cast(aInfo.iDstAddr); |
|
115 |
|
116 if (!dst.IsUnicast()) |
|
117 return KIp6Hook_PASS; // Only the unicast case really needs fixing |
|
118 |
|
119 // Need to examine the UDP header |
|
120 TInet6Packet<TInet6HeaderUDP> udp(aPacket, aInfo.iOffset); |
|
121 if (udp.iHdr == NULL) |
|
122 return KIp6Hook_PASS; // Oops, short packet, let someone else worry about it. |
|
123 |
|
124 // To cause least distruption, one could try to check that this really is |
|
125 // DCHP address configuration message with packet destination address |
|
126 // matching the offered address inside DCHP message (but this would need |
|
127 // more extensive packet snooping here) |
|
128 #ifndef _DEBUG |
|
129 if (udp.iHdr->DstPort() == 68) |
|
130 #else |
|
131 if (udp.iHdr->DstPort() == 68 || udp.iHdr->DstPort() == 127 || udp.iHdr->DstPort() == 119 || udp.iHdr->DstPort() == 125 |
|
132 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS |
|
133 || udp.iHdr->DstPort() == 92 || udp.iHdr->DstPort() == 99 |
|
134 #endif//SYMBIAN_NETWORKING_DHCP_MSG_HEADERS |
|
135 ) // debug mode, src port 127, 119, 125, 91, 98 |
|
136 #endif |
|
137 { |
|
138 static const TIp6Addr broadcast = {{{0,0,0,0,0,0,0,0,0,0,0xff,0xff,255,255,255,255}}}; |
|
139 |
|
140 dst.SetAddress(broadcast); |
|
141 udp.iHdr->SetChecksum(0); // Either this or recompute the UDP checksum for broadcast address. |
|
142 return KIp6Hook_DONE; |
|
143 } |
|
144 return KIp6Hook_PASS; |
|
145 } |
|
146 |
|
147 |