|
1 /* |
|
2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: IKEv2 Mobility and Multihoming Protocol. |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <es_sock.h> |
|
19 #include <in_sock.h> |
|
20 #include "ikedebug.h" |
|
21 #include "ikev2mobike.h" |
|
22 #include "ikev2SAdata.h" |
|
23 #include "ikemsgrec.h" |
|
24 #include "ikev2payloads.h" |
|
25 #include "ikev2const.h" |
|
26 #include "ikev2Negotiation.h" |
|
27 #include "ikev2plugin.h" |
|
28 #include "ikev2natt.h" |
|
29 #include "ikev2proposal.h" |
|
30 #include "ikev2pluginsession.h" |
|
31 |
|
32 _LIT8(KZeroDesc, ""); |
|
33 |
|
34 TBool Ikev2MobIke::ProcessNotifysL(CIkev2Negotiation* aNegotiation, |
|
35 const CArrayFixFlat<TNotifPayloadIkev2*>& aNotifys, |
|
36 TBool aRequest, TInt aExchange) |
|
37 { |
|
38 __ASSERT_DEBUG(aNegotiation, User::Invariant()); |
|
39 if ( !aNegotiation->iHdr.iIkeData->iUseMobIke ) |
|
40 { |
|
41 return EFalse; |
|
42 } |
|
43 |
|
44 TInt MsgType; |
|
45 TNotifPayloadIkev2* Payload; |
|
46 TPtrC8 Cookie2(NULL,0); |
|
47 TBool NatDetection = EFalse; |
|
48 TBool Status = EFalse; |
|
49 TInt Count = aNotifys.Count(); |
|
50 TInt i = 0; |
|
51 |
|
52 while ( i < Count ) |
|
53 { |
|
54 |
|
55 Payload = aNotifys.At(i); |
|
56 MsgType = (TInt)Payload->GetMsgType(); |
|
57 // |
|
58 // Process possible MOBIKE Notify messages |
|
59 // |
|
60 switch ( MsgType ) |
|
61 { |
|
62 |
|
63 case MOBIKE_SUPPORTED: |
|
64 // |
|
65 // Remote end supports MOBIKE protocol |
|
66 // |
|
67 aNegotiation->iHdr.iMobikeUsed = ETrue; |
|
68 aNegotiation->iHdr.iFloatedPort = ETrue; // Floated port used for now |
|
69 aNegotiation->iHdr.iDestinAddr.SetPort(FLOATED_IKE_PORT); |
|
70 break; |
|
71 |
|
72 case ADDITIONAL_IPV4_ADDRESS: |
|
73 case ADDITIONAL_IPV6_ADDRESS: |
|
74 // |
|
75 // Additional IP addresses Notify |
|
76 // |
|
77 if ( aNegotiation->iHdr.iMobikeUsed && (aExchange == INFORMATIONAL) ) |
|
78 { |
|
79 Status = ETrue; |
|
80 } |
|
81 break; |
|
82 |
|
83 case UPDATE_SA_ADDRESS: |
|
84 // |
|
85 // Peer informs about the IP address change |
|
86 // |
|
87 if ( aNegotiation->iHdr.iMobikeUsed && aRequest && (aExchange == INFORMATIONAL) ) |
|
88 { |
|
89 aNegotiation->iIkeV2PlugInSession.RemoteAddrChanged(&aNegotiation->iHdr, aNegotiation->iHdr.iDestinAddr); |
|
90 Status = ETrue; |
|
91 } |
|
92 break; |
|
93 |
|
94 case COOKIE2: |
|
95 // |
|
96 // Peer informs about the IP address change |
|
97 // |
|
98 if ( aNegotiation->iHdr.iMobikeUsed && aRequest && (aExchange == INFORMATIONAL) ) |
|
99 { |
|
100 Cookie2.Set(Payload->NotifData(), Payload->NotifDataLength()); |
|
101 Status = ETrue; |
|
102 } |
|
103 break; |
|
104 |
|
105 case NAT_PREVENTION: |
|
106 // |
|
107 // NAT Prevention Notify |
|
108 // |
|
109 if ( aNegotiation->iHdr.iMobikeUsed ) |
|
110 { |
|
111 if ( aExchange == INFORMATIONAL ) |
|
112 Status = ETrue; |
|
113 } |
|
114 break; |
|
115 |
|
116 case UNACCPETABLE_ADDRESSES: |
|
117 case NAT_PREVENTED: |
|
118 if ( aNegotiation->iHdr.iMobikeUsed ) |
|
119 { |
|
120 if ( aExchange == INFORMATIONAL ) |
|
121 Status = ETrue; |
|
122 } |
|
123 break; |
|
124 |
|
125 case NAT_DETECTION_SOURCE_IP: |
|
126 case NAT_DETECTION_DESTINATION_IP: |
|
127 if ( aNegotiation->iHdr.iMobikeUsed && (aExchange == INFORMATIONAL)) |
|
128 { |
|
129 NatDetection = ETrue; |
|
130 Status = ETrue; |
|
131 } |
|
132 break; |
|
133 |
|
134 default: |
|
135 break; |
|
136 } |
|
137 |
|
138 i ++; |
|
139 } |
|
140 |
|
141 if ( Status && aRequest && (aExchange == INFORMATIONAL) ) |
|
142 { |
|
143 // |
|
144 // Build informational response to MOBIKE request |
|
145 // |
|
146 CIkeV2Message* ikeMsg = CIkeV2Message::NewL(aNegotiation->iHdr.SpiI(), |
|
147 aNegotiation->iHdr.SpiR(), |
|
148 INFORMATIONAL, |
|
149 aNegotiation->iHdr.iInitiator, |
|
150 ETrue, |
|
151 aNegotiation->iHdr.ExpectedRequestId(), |
|
152 aNegotiation->iDebug); |
|
153 |
|
154 ikeMsg->AppendEncryptedPayloadL(aNegotiation->iHdr.iCipherBlkLth); |
|
155 |
|
156 if ( Cookie2.Ptr() ) |
|
157 { |
|
158 // |
|
159 // Peer is using COOKIE2. Return COOKIE2 payload data as such |
|
160 // |
|
161 ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, COOKIE, Cookie2); |
|
162 } |
|
163 if ( NatDetection ) |
|
164 { |
|
165 // |
|
166 // Peer is using NAT_DETECTION_*_IP payloads. Build corresponding response |
|
167 // |
|
168 TBool NatDetectOk; |
|
169 TInetAddr DummyIp; |
|
170 DummyIp.SetAddress(KInetAddrNone); // 0.0.0.0 |
|
171 TUint32 NATFlags = CIkev2NatT::CheckPeerNotifysL(aNotifys, DummyIp, aNegotiation->iHdr.iDestinAddr, FLOATED_IKE_PORT, |
|
172 ikeMsg->InitiatorSpi(), ikeMsg->ResponderSpi(), |
|
173 NatDetectOk); |
|
174 if ( NatDetectOk ) |
|
175 { |
|
176 aNegotiation->iHdr.iNATFlags = NATFlags; |
|
177 aNegotiation->GetNatStatus(NatDetectOk, aNegotiation->iHdr.iDestinAddr); |
|
178 } |
|
179 CIkev2NatT* NatNotify = CIkev2NatT::NewL(DummyIp, aNegotiation->iHdr.iDestinAddr, |
|
180 FLOATED_IKE_PORT, |
|
181 ikeMsg->InitiatorSpi(), ikeMsg->ResponderSpi()); |
|
182 CleanupStack::PushL(NatNotify); |
|
183 |
|
184 ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_SOURCE_IP, |
|
185 NatNotify->SourceNofify()); |
|
186 ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_DESTINATION_IP, |
|
187 NatNotify->DestinNofify()); |
|
188 |
|
189 CleanupStack::PopAndDestroy(NatNotify); |
|
190 } |
|
191 |
|
192 aNegotiation->SendIkeMsgL(ikeMsg); |
|
193 aNegotiation->iIkeV2PlugInSession.UpdateIkev2SAL(&aNegotiation->iHdr, NULL); |
|
194 if ( (aNegotiation->iState != KStateIkeInfoRequest) && (aNegotiation->iState != KStateIkeDeleteRequest) && (aNegotiation->iState != KStateIkeDeleteResponse) ) |
|
195 aNegotiation->iState = KStateIkeInfoResponse; |
|
196 } |
|
197 // |
|
198 // else |
|
199 // Currently there is no need to examine any MOBIKE Notify payloads |
|
200 // present in Informational response |
|
201 // |
|
202 |
|
203 return Status; |
|
204 } |
|
205 |
|
206 TBool Ikev2MobIke::SendUpdateSaAddrNotifyL(CIkev2Negotiation* aNegotiation) |
|
207 { |
|
208 ASSERT(aNegotiation); |
|
209 |
|
210 //we support only changing of our address. |
|
211 CIkeV2Message* ikeMsg = CIkeV2Message::NewL(aNegotiation->iHdr.SpiI(), |
|
212 aNegotiation->iHdr.SpiR(), |
|
213 INFORMATIONAL, |
|
214 aNegotiation->iHdr.iInitiator, |
|
215 EFalse, |
|
216 aNegotiation->iHdr.NextRequestId(), |
|
217 aNegotiation->iDebug); |
|
218 |
|
219 ikeMsg->AppendEncryptedPayloadL(aNegotiation->iHdr.iCipherBlkLth); |
|
220 ikeMsg->AppendNotifyPayloadL(IKEV2_PROT_NONE, KZeroDesc, UPDATE_SA_ADDRESS, KZeroDesc); |
|
221 |
|
222 aNegotiation->SendIkeMsgL(ikeMsg); |
|
223 |
|
224 aNegotiation->iState = KStateIkeInfoRequest; |
|
225 |
|
226 return ETrue; |
|
227 } |