xref: /onnv-gate/usr/src/cmd/lms/LMEConnection.cpp (revision 9203:3ebffd0a1b10)
1*9203SMark.Logan@Sun.COM /*******************************************************************************
2*9203SMark.Logan@Sun.COM  * Copyright (C) 2004-2008 Intel Corp. All rights reserved.
3*9203SMark.Logan@Sun.COM  *
4*9203SMark.Logan@Sun.COM  * Redistribution and use in source and binary forms, with or without
5*9203SMark.Logan@Sun.COM  * modification, are permitted provided that the following conditions are met:
6*9203SMark.Logan@Sun.COM  *
7*9203SMark.Logan@Sun.COM  *  - Redistributions of source code must retain the above copyright notice,
8*9203SMark.Logan@Sun.COM  *    this list of conditions and the following disclaimer.
9*9203SMark.Logan@Sun.COM  *
10*9203SMark.Logan@Sun.COM  *  - Redistributions in binary form must reproduce the above copyright notice,
11*9203SMark.Logan@Sun.COM  *    this list of conditions and the following disclaimer in the documentation
12*9203SMark.Logan@Sun.COM  *    and/or other materials provided with the distribution.
13*9203SMark.Logan@Sun.COM  *
14*9203SMark.Logan@Sun.COM  *  - Neither the name of Intel Corp. nor the names of its
15*9203SMark.Logan@Sun.COM  *    contributors may be used to endorse or promote products derived from this
16*9203SMark.Logan@Sun.COM  *    software without specific prior written permission.
17*9203SMark.Logan@Sun.COM  *
18*9203SMark.Logan@Sun.COM  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19*9203SMark.Logan@Sun.COM  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*9203SMark.Logan@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*9203SMark.Logan@Sun.COM  * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
22*9203SMark.Logan@Sun.COM  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*9203SMark.Logan@Sun.COM  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*9203SMark.Logan@Sun.COM  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25*9203SMark.Logan@Sun.COM  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26*9203SMark.Logan@Sun.COM  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27*9203SMark.Logan@Sun.COM  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28*9203SMark.Logan@Sun.COM  * POSSIBILITY OF SUCH DAMAGE.
29*9203SMark.Logan@Sun.COM  *******************************************************************************/
30*9203SMark.Logan@Sun.COM 
31*9203SMark.Logan@Sun.COM #ifdef HAVE_CONFIG_H
32*9203SMark.Logan@Sun.COM #include "config.h"
33*9203SMark.Logan@Sun.COM #endif
34*9203SMark.Logan@Sun.COM #include <cerrno>
35*9203SMark.Logan@Sun.COM #include "types.h"
36*9203SMark.Logan@Sun.COM #include "LMEConnection.h"
37*9203SMark.Logan@Sun.COM #include "LMS_if.h"
38*9203SMark.Logan@Sun.COM #include "Lock.h"
39*9203SMark.Logan@Sun.COM #include "glue.h"
40*9203SMark.Logan@Sun.COM 
41*9203SMark.Logan@Sun.COM #if defined(__sun) || defined(_LINUX)
42*9203SMark.Logan@Sun.COM #include <netinet/in.h>
43*9203SMark.Logan@Sun.COM #define _strnicmp strncasecmp
44*9203SMark.Logan@Sun.COM #endif	// __sun || _LINUX
45*9203SMark.Logan@Sun.COM 
46*9203SMark.Logan@Sun.COM #define HECI_IO_TIMEOUT 5000
47*9203SMark.Logan@Sun.COM 
48*9203SMark.Logan@Sun.COM extern glue plugin;
49*9203SMark.Logan@Sun.COM 
50*9203SMark.Logan@Sun.COM const GUID LMEConnection::_guid = {0x6733a4db, 0x0476, 0x4e7b, {0xb3, 0xaf, 0xbc, 0xfc, 0x29, 0xbe, 0xe7, 0xa7}};
51*9203SMark.Logan@Sun.COM 
52*9203SMark.Logan@Sun.COM const UINT32 LMEConnection::RX_WINDOW_SIZE = 1024;
53*9203SMark.Logan@Sun.COM 
LMEConnection(bool verbose)54*9203SMark.Logan@Sun.COM LMEConnection::LMEConnection(bool verbose) :
55*9203SMark.Logan@Sun.COM _reqID(0),
56*9203SMark.Logan@Sun.COM _txBuffer(NULL),
57*9203SMark.Logan@Sun.COM _rxThread(NULL),
58*9203SMark.Logan@Sun.COM _cb(NULL),
59*9203SMark.Logan@Sun.COM _cbParam(NULL),
60*9203SMark.Logan@Sun.COM _initState(INIT_STATE_DISCONNECTED),
61*9203SMark.Logan@Sun.COM _heci(_guid, verbose),
62*9203SMark.Logan@Sun.COM _heciCompat(_guidCompat, verbose),
63*9203SMark.Logan@Sun.COM _pHeci(NULL)
64*9203SMark.Logan@Sun.COM {
65*9203SMark.Logan@Sun.COM }
66*9203SMark.Logan@Sun.COM 
~LMEConnection()67*9203SMark.Logan@Sun.COM LMEConnection::~LMEConnection()
68*9203SMark.Logan@Sun.COM {
69*9203SMark.Logan@Sun.COM }
70*9203SMark.Logan@Sun.COM 
IsInitialized()71*9203SMark.Logan@Sun.COM bool LMEConnection::IsInitialized()
72*9203SMark.Logan@Sun.COM {
73*9203SMark.Logan@Sun.COM 	Lock il(_initLock);
74*9203SMark.Logan@Sun.COM 	return ((_initState == INIT_STATE_CONNECTED) ? true : false);
75*9203SMark.Logan@Sun.COM }
76*9203SMark.Logan@Sun.COM 
Init(HECICallback cb,void * param)77*9203SMark.Logan@Sun.COM bool LMEConnection::Init(HECICallback cb, void *param)
78*9203SMark.Logan@Sun.COM {
79*9203SMark.Logan@Sun.COM 	Lock il(_initLock);
80*9203SMark.Logan@Sun.COM 
81*9203SMark.Logan@Sun.COM 	if (_initState == INIT_STATE_CONNECTING) {
82*9203SMark.Logan@Sun.COM 		return false;
83*9203SMark.Logan@Sun.COM 	}
84*9203SMark.Logan@Sun.COM 	_initState = INIT_STATE_CONNECTING;
85*9203SMark.Logan@Sun.COM 
86*9203SMark.Logan@Sun.COM 	_cb = cb;
87*9203SMark.Logan@Sun.COM 	_cbParam = param;
88*9203SMark.Logan@Sun.COM 
89*9203SMark.Logan@Sun.COM 	if (_heci.Init(LMS_PROCOL_VERSION)) {
90*9203SMark.Logan@Sun.COM 		protocolVer = _heci.GetProtocolVersion();
91*9203SMark.Logan@Sun.COM 		_pHeci = &_heci;
92*9203SMark.Logan@Sun.COM 	} else if (_heciCompat.Init()) {
93*9203SMark.Logan@Sun.COM 		protocolVer = _heciCompat.GetProtocolVersion();
94*9203SMark.Logan@Sun.COM 		if (protocolVer > LMS_PROCOL_VERSION_COMPAT) {
95*9203SMark.Logan@Sun.COM 			_heciCompat.Deinit();
96*9203SMark.Logan@Sun.COM 			_initState = INIT_STATE_DISCONNECTED;
97*9203SMark.Logan@Sun.COM 			return false;
98*9203SMark.Logan@Sun.COM 		}
99*9203SMark.Logan@Sun.COM 		_pHeci = &_heciCompat;
100*9203SMark.Logan@Sun.COM 	} else {
101*9203SMark.Logan@Sun.COM 		_initState = INIT_STATE_DISCONNECTED;
102*9203SMark.Logan@Sun.COM 		return false;
103*9203SMark.Logan@Sun.COM 	}
104*9203SMark.Logan@Sun.COM 
105*9203SMark.Logan@Sun.COM 	_initState = INIT_STATE_CONNECTED;
106*9203SMark.Logan@Sun.COM 
107*9203SMark.Logan@Sun.COM 	plugin.version(protocolVer);
108*9203SMark.Logan@Sun.COM 
109*9203SMark.Logan@Sun.COM 	// launch RX thread
110*9203SMark.Logan@Sun.COM 	_txBuffer = new unsigned char[_pHeci->GetBufferSize()];
111*9203SMark.Logan@Sun.COM 	_rxThread = new Thread(_rxThreadFunc, this);
112*9203SMark.Logan@Sun.COM 	_rxThread->start();
113*9203SMark.Logan@Sun.COM 
114*9203SMark.Logan@Sun.COM 	_threadStartedEvent.wait();
115*9203SMark.Logan@Sun.COM 	return true;
116*9203SMark.Logan@Sun.COM }
117*9203SMark.Logan@Sun.COM 
Deinit()118*9203SMark.Logan@Sun.COM void LMEConnection::Deinit()
119*9203SMark.Logan@Sun.COM {
120*9203SMark.Logan@Sun.COM 	Lock il(_initLock);
121*9203SMark.Logan@Sun.COM 
122*9203SMark.Logan@Sun.COM 	_initState = INIT_STATE_DISCONNECTED;
123*9203SMark.Logan@Sun.COM 
124*9203SMark.Logan@Sun.COM 	if (_pHeci != NULL) {
125*9203SMark.Logan@Sun.COM 		_pHeci->Deinit();
126*9203SMark.Logan@Sun.COM 		_pHeci = NULL;
127*9203SMark.Logan@Sun.COM 	}
128*9203SMark.Logan@Sun.COM 
129*9203SMark.Logan@Sun.COM 	if (_rxThread != NULL) {
130*9203SMark.Logan@Sun.COM 		delete _rxThread;
131*9203SMark.Logan@Sun.COM 		_rxThread = NULL;
132*9203SMark.Logan@Sun.COM 	}
133*9203SMark.Logan@Sun.COM 
134*9203SMark.Logan@Sun.COM 	if (_txBuffer != NULL) {
135*9203SMark.Logan@Sun.COM 		delete[] _txBuffer;
136*9203SMark.Logan@Sun.COM 		_txBuffer = NULL;
137*9203SMark.Logan@Sun.COM 	}
138*9203SMark.Logan@Sun.COM }
139*9203SMark.Logan@Sun.COM 
Disconnect(APF_DISCONNECT_REASON_CODE reasonCode)140*9203SMark.Logan@Sun.COM bool LMEConnection::Disconnect(APF_DISCONNECT_REASON_CODE reasonCode)
141*9203SMark.Logan@Sun.COM {
142*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
143*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
144*9203SMark.Logan@Sun.COM 		return false;
145*9203SMark.Logan@Sun.COM 	}
146*9203SMark.Logan@Sun.COM 
147*9203SMark.Logan@Sun.COM 	unsigned char buf[sizeof(APF_DISCONNECT_MESSAGE)];
148*9203SMark.Logan@Sun.COM 
149*9203SMark.Logan@Sun.COM 	APF_DISCONNECT_MESSAGE *disconnectMessage = (APF_DISCONNECT_MESSAGE *)buf;
150*9203SMark.Logan@Sun.COM 
151*9203SMark.Logan@Sun.COM 	memset(disconnectMessage, 0, sizeof(buf));
152*9203SMark.Logan@Sun.COM 	disconnectMessage->MessageType = APF_DISCONNECT;
153*9203SMark.Logan@Sun.COM 	disconnectMessage->ReasonCode = htonl(reasonCode);
154*9203SMark.Logan@Sun.COM 
155*9203SMark.Logan@Sun.COM 	PRINT("Sending disconnect to LME.\n");
156*9203SMark.Logan@Sun.COM 	int res = _sendMessage(buf, sizeof(buf));
157*9203SMark.Logan@Sun.COM 
158*9203SMark.Logan@Sun.COM 	return (res == sizeof(buf));
159*9203SMark.Logan@Sun.COM }
160*9203SMark.Logan@Sun.COM 
ServiceAccept(std::string serviceName)161*9203SMark.Logan@Sun.COM bool LMEConnection::ServiceAccept(std::string serviceName)
162*9203SMark.Logan@Sun.COM {
163*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
164*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
165*9203SMark.Logan@Sun.COM 		return false;
166*9203SMark.Logan@Sun.COM 	}
167*9203SMark.Logan@Sun.COM 
168*9203SMark.Logan@Sun.COM 	//APF_SERVICE_ACCEPT_MESSAGE
169*9203SMark.Logan@Sun.COM 	//memcpy(pCurrent, "127.0.0.1", APF_STR_SIZE_OF("127.0.0.1"));
170*9203SMark.Logan@Sun.COM 	//pCurrent += APF_STR_SIZE_OF("127.0.0.1");
171*9203SMark.Logan@Sun.COM 	unsigned char *buf = new unsigned char[sizeof(APF_SERVICE_ACCEPT_MESSAGE) + serviceName.length()];
172*9203SMark.Logan@Sun.COM 	if (buf == NULL) {
173*9203SMark.Logan@Sun.COM 		PRINT("Failed to allocate memory for ServiceAccept.\n");
174*9203SMark.Logan@Sun.COM 		return false;
175*9203SMark.Logan@Sun.COM 	}
176*9203SMark.Logan@Sun.COM 
177*9203SMark.Logan@Sun.COM 	unsigned char *pCurrent = buf;
178*9203SMark.Logan@Sun.COM 	*pCurrent = APF_SERVICE_ACCEPT;
179*9203SMark.Logan@Sun.COM 	++pCurrent;
180*9203SMark.Logan@Sun.COM 	*((UINT32 *)pCurrent) = htonl(serviceName.size());
181*9203SMark.Logan@Sun.COM 	pCurrent += 4;
182*9203SMark.Logan@Sun.COM 
183*9203SMark.Logan@Sun.COM 	memcpy(pCurrent, serviceName.c_str(), serviceName.size());
184*9203SMark.Logan@Sun.COM 	pCurrent += serviceName.size();
185*9203SMark.Logan@Sun.COM 
186*9203SMark.Logan@Sun.COM 	PRINT("Sending service accept to LME: %s\n", serviceName.c_str());
187*9203SMark.Logan@Sun.COM 	int len = pCurrent - buf;
188*9203SMark.Logan@Sun.COM 	int res = _sendMessage(buf, len);
189*9203SMark.Logan@Sun.COM 
190*9203SMark.Logan@Sun.COM 	delete [] buf;
191*9203SMark.Logan@Sun.COM 
192*9203SMark.Logan@Sun.COM 	return (res == len);
193*9203SMark.Logan@Sun.COM }
194*9203SMark.Logan@Sun.COM 
UserAuthSuccess()195*9203SMark.Logan@Sun.COM bool LMEConnection::UserAuthSuccess()
196*9203SMark.Logan@Sun.COM {
197*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
198*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
199*9203SMark.Logan@Sun.COM 		return false;
200*9203SMark.Logan@Sun.COM 	}
201*9203SMark.Logan@Sun.COM 
202*9203SMark.Logan@Sun.COM 	unsigned char buf = APF_USERAUTH_SUCCESS;
203*9203SMark.Logan@Sun.COM 
204*9203SMark.Logan@Sun.COM 	PRINT("Sending user authentication success to LME.\n");
205*9203SMark.Logan@Sun.COM 	int res = _sendMessage(&buf, sizeof(buf));
206*9203SMark.Logan@Sun.COM 
207*9203SMark.Logan@Sun.COM 	return (res == sizeof(buf));
208*9203SMark.Logan@Sun.COM }
209*9203SMark.Logan@Sun.COM 
ProtocolVersion(const LMEProtocolVersionMessage versionMessage)210*9203SMark.Logan@Sun.COM bool LMEConnection::ProtocolVersion(const LMEProtocolVersionMessage versionMessage)
211*9203SMark.Logan@Sun.COM {
212*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
213*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
214*9203SMark.Logan@Sun.COM 		return false;
215*9203SMark.Logan@Sun.COM 	}
216*9203SMark.Logan@Sun.COM 
217*9203SMark.Logan@Sun.COM 	APF_PROTOCOL_VERSION_MESSAGE protVersion;
218*9203SMark.Logan@Sun.COM 	memset(&protVersion, 0, sizeof(protVersion));
219*9203SMark.Logan@Sun.COM 
220*9203SMark.Logan@Sun.COM 	protVersion.MessageType = APF_PROTOCOLVERSION;
221*9203SMark.Logan@Sun.COM 	protVersion.MajorVersion = htonl(versionMessage.MajorVersion);
222*9203SMark.Logan@Sun.COM 	protVersion.MinorVersion = htonl(versionMessage.MinorVersion);
223*9203SMark.Logan@Sun.COM 	protVersion.TriggerReason = htonl(versionMessage.TriggerReason);
224*9203SMark.Logan@Sun.COM 
225*9203SMark.Logan@Sun.COM 	PRINT("Sending protocol version to LME: %d.%d\n", versionMessage.MajorVersion, versionMessage.MinorVersion);
226*9203SMark.Logan@Sun.COM 	int res = _sendMessage((unsigned char *)&protVersion, sizeof(protVersion));
227*9203SMark.Logan@Sun.COM 
228*9203SMark.Logan@Sun.COM 	return (res == sizeof(protVersion));
229*9203SMark.Logan@Sun.COM }
230*9203SMark.Logan@Sun.COM 
TcpForwardReplySuccess(UINT32 port)231*9203SMark.Logan@Sun.COM bool LMEConnection::TcpForwardReplySuccess(UINT32 port)
232*9203SMark.Logan@Sun.COM {
233*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
234*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
235*9203SMark.Logan@Sun.COM 		return false;
236*9203SMark.Logan@Sun.COM 	}
237*9203SMark.Logan@Sun.COM 
238*9203SMark.Logan@Sun.COM 	APF_TCP_FORWARD_REPLY_MESSAGE message;
239*9203SMark.Logan@Sun.COM 
240*9203SMark.Logan@Sun.COM 	message.MessageType = APF_REQUEST_SUCCESS;
241*9203SMark.Logan@Sun.COM 	message.PortBound = htonl(port);
242*9203SMark.Logan@Sun.COM 
243*9203SMark.Logan@Sun.COM 	PRINT("Sending TCP forward replay success to LME: Port %d.\n", port);
244*9203SMark.Logan@Sun.COM 	int res = _sendMessage((unsigned char *)&message, sizeof(message));
245*9203SMark.Logan@Sun.COM 
246*9203SMark.Logan@Sun.COM 	return (res == sizeof(message));
247*9203SMark.Logan@Sun.COM }
248*9203SMark.Logan@Sun.COM 
TcpForwardReplyFailure()249*9203SMark.Logan@Sun.COM bool LMEConnection::TcpForwardReplyFailure()
250*9203SMark.Logan@Sun.COM {
251*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
252*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
253*9203SMark.Logan@Sun.COM 		return false;
254*9203SMark.Logan@Sun.COM 	}
255*9203SMark.Logan@Sun.COM 
256*9203SMark.Logan@Sun.COM 	unsigned char buf = APF_REQUEST_FAILURE;
257*9203SMark.Logan@Sun.COM 
258*9203SMark.Logan@Sun.COM 	PRINT("Sending TCP forward replay failure to LME.\n");
259*9203SMark.Logan@Sun.COM 	int res = _sendMessage(&buf, sizeof(buf));
260*9203SMark.Logan@Sun.COM 
261*9203SMark.Logan@Sun.COM 	return (res == sizeof(buf));
262*9203SMark.Logan@Sun.COM }
263*9203SMark.Logan@Sun.COM 
TcpForwardCancelReplySuccess()264*9203SMark.Logan@Sun.COM bool LMEConnection::TcpForwardCancelReplySuccess()
265*9203SMark.Logan@Sun.COM {
266*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
267*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
268*9203SMark.Logan@Sun.COM 		return false;
269*9203SMark.Logan@Sun.COM 	}
270*9203SMark.Logan@Sun.COM 
271*9203SMark.Logan@Sun.COM 	unsigned char buf = APF_REQUEST_SUCCESS;
272*9203SMark.Logan@Sun.COM 
273*9203SMark.Logan@Sun.COM 	PRINT("Sending TCP forward cancel replay success to LME.\n");
274*9203SMark.Logan@Sun.COM 	int res = _sendMessage(&buf, sizeof(buf));
275*9203SMark.Logan@Sun.COM 
276*9203SMark.Logan@Sun.COM 	return (res == sizeof(buf));
277*9203SMark.Logan@Sun.COM }
278*9203SMark.Logan@Sun.COM 
TcpForwardCancelReplyFailure()279*9203SMark.Logan@Sun.COM bool LMEConnection::TcpForwardCancelReplyFailure()
280*9203SMark.Logan@Sun.COM {
281*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
282*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
283*9203SMark.Logan@Sun.COM 		return false;
284*9203SMark.Logan@Sun.COM 	}
285*9203SMark.Logan@Sun.COM 
286*9203SMark.Logan@Sun.COM 	unsigned char buf = APF_REQUEST_FAILURE;
287*9203SMark.Logan@Sun.COM 
288*9203SMark.Logan@Sun.COM 	PRINT("Sending TCP forward cancel replay failure to LME.\n");
289*9203SMark.Logan@Sun.COM 	int res = _sendMessage(&buf, sizeof(buf));
290*9203SMark.Logan@Sun.COM 
291*9203SMark.Logan@Sun.COM 	return (res == sizeof(buf));
292*9203SMark.Logan@Sun.COM }
293*9203SMark.Logan@Sun.COM 
ChannelOpenForwardedRequest(UINT32 senderChannel,UINT32 connectedPort,std::string originatorIP,UINT32 originatorPort)294*9203SMark.Logan@Sun.COM bool LMEConnection::ChannelOpenForwardedRequest(UINT32 senderChannel,
295*9203SMark.Logan@Sun.COM 						UINT32 connectedPort,
296*9203SMark.Logan@Sun.COM 						std::string originatorIP,
297*9203SMark.Logan@Sun.COM 						UINT32 originatorPort)
298*9203SMark.Logan@Sun.COM {
299*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
300*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
301*9203SMark.Logan@Sun.COM 		return false;
302*9203SMark.Logan@Sun.COM 	}
303*9203SMark.Logan@Sun.COM 
304*9203SMark.Logan@Sun.COM 	unsigned char buf[5 + APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED) + 16 +
305*9203SMark.Logan@Sun.COM 		APF_STR_SIZE_OF("127.0.0.1") + 8 +  16  + 4];
306*9203SMark.Logan@Sun.COM 	unsigned char *pCurrent = buf;
307*9203SMark.Logan@Sun.COM 
308*9203SMark.Logan@Sun.COM 	if (originatorIP.size() > 16) {
309*9203SMark.Logan@Sun.COM 		return false;
310*9203SMark.Logan@Sun.COM 	}
311*9203SMark.Logan@Sun.COM 
312*9203SMark.Logan@Sun.COM 	*pCurrent = APF_CHANNEL_OPEN;
313*9203SMark.Logan@Sun.COM 	++pCurrent;
314*9203SMark.Logan@Sun.COM 
315*9203SMark.Logan@Sun.COM 	*((UINT32 *)pCurrent) = htonl(APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED));
316*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
317*9203SMark.Logan@Sun.COM 
318*9203SMark.Logan@Sun.COM 	memcpy(pCurrent, APF_OPEN_CHANNEL_REQUEST_FORWARDED, APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED));
319*9203SMark.Logan@Sun.COM 	pCurrent += APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED);
320*9203SMark.Logan@Sun.COM 
321*9203SMark.Logan@Sun.COM 	*((UINT32 *)pCurrent) = htonl(senderChannel);
322*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
323*9203SMark.Logan@Sun.COM 
324*9203SMark.Logan@Sun.COM 	*((UINT32 *)pCurrent) = htonl(RX_WINDOW_SIZE);
325*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
326*9203SMark.Logan@Sun.COM 
327*9203SMark.Logan@Sun.COM 	*((UINT32 *)pCurrent) = 0xFFFFFFFF;
328*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
329*9203SMark.Logan@Sun.COM 
330*9203SMark.Logan@Sun.COM 	*((UINT32 *)pCurrent) = htonl(APF_STR_SIZE_OF("127.0.0.1"));
331*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
332*9203SMark.Logan@Sun.COM 
333*9203SMark.Logan@Sun.COM 	memcpy(pCurrent, "127.0.0.1", APF_STR_SIZE_OF("127.0.0.1"));
334*9203SMark.Logan@Sun.COM 	pCurrent += APF_STR_SIZE_OF("127.0.0.1");
335*9203SMark.Logan@Sun.COM 
336*9203SMark.Logan@Sun.COM 	*((UINT32 *)pCurrent) = htonl(connectedPort);
337*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
338*9203SMark.Logan@Sun.COM 
339*9203SMark.Logan@Sun.COM 	*((UINT32 *)pCurrent) = htonl((UINT32)originatorIP.size());
340*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
341*9203SMark.Logan@Sun.COM 
342*9203SMark.Logan@Sun.COM 	memcpy(pCurrent, originatorIP.c_str(), originatorIP.size());
343*9203SMark.Logan@Sun.COM 	pCurrent += originatorIP.size();
344*9203SMark.Logan@Sun.COM 
345*9203SMark.Logan@Sun.COM 	*((UINT32 *)pCurrent) = htonl(originatorPort);
346*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
347*9203SMark.Logan@Sun.COM 
348*9203SMark.Logan@Sun.COM 	PRINT("Sending channel open request to LME. Address: %s, requested port: %d.\n",
349*9203SMark.Logan@Sun.COM 		originatorIP.c_str(), connectedPort);
350*9203SMark.Logan@Sun.COM 	int res = _sendMessage(buf, (int)(pCurrent - buf));
351*9203SMark.Logan@Sun.COM 
352*9203SMark.Logan@Sun.COM 	return (res == pCurrent - buf);
353*9203SMark.Logan@Sun.COM }
354*9203SMark.Logan@Sun.COM 
ChannelOpenReplaySuccess(UINT32 recipientChannel,UINT32 senderChannel)355*9203SMark.Logan@Sun.COM bool LMEConnection::ChannelOpenReplaySuccess(UINT32 recipientChannel,
356*9203SMark.Logan@Sun.COM 					     UINT32 senderChannel)
357*9203SMark.Logan@Sun.COM {
358*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
359*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
360*9203SMark.Logan@Sun.COM 		return false;
361*9203SMark.Logan@Sun.COM 	}
362*9203SMark.Logan@Sun.COM 
363*9203SMark.Logan@Sun.COM 	APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE message;
364*9203SMark.Logan@Sun.COM 
365*9203SMark.Logan@Sun.COM 	message.MessageType = APF_CHANNEL_OPEN_CONFIRMATION;
366*9203SMark.Logan@Sun.COM 	message.RecipientChannel = htonl(recipientChannel);
367*9203SMark.Logan@Sun.COM 	message.SenderChannel = htonl(senderChannel);
368*9203SMark.Logan@Sun.COM 	message.InitialWindowSize = htonl(RX_WINDOW_SIZE);
369*9203SMark.Logan@Sun.COM 	message.Reserved = 0xFFFFFFFF;
370*9203SMark.Logan@Sun.COM 
371*9203SMark.Logan@Sun.COM 	PRINT("Sending channel open replay success to LME. Recipient: %d.\n", recipientChannel);
372*9203SMark.Logan@Sun.COM 	int res = _sendMessage((unsigned char *)&message, sizeof(message));
373*9203SMark.Logan@Sun.COM 
374*9203SMark.Logan@Sun.COM 	return (res == sizeof(message));
375*9203SMark.Logan@Sun.COM }
376*9203SMark.Logan@Sun.COM 
ChannelOpenReplayFailure(UINT32 recipientChannel,UINT32 reason)377*9203SMark.Logan@Sun.COM bool LMEConnection::ChannelOpenReplayFailure(UINT32 recipientChannel,
378*9203SMark.Logan@Sun.COM 					     UINT32 reason)
379*9203SMark.Logan@Sun.COM {
380*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
381*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
382*9203SMark.Logan@Sun.COM 		return false;
383*9203SMark.Logan@Sun.COM 	}
384*9203SMark.Logan@Sun.COM 
385*9203SMark.Logan@Sun.COM 	APF_CHANNEL_OPEN_FAILURE_MESSAGE message;
386*9203SMark.Logan@Sun.COM 
387*9203SMark.Logan@Sun.COM 	message.MessageType = APF_CHANNEL_OPEN_FAILURE;
388*9203SMark.Logan@Sun.COM 	message.RecipientChannel = htonl(recipientChannel);
389*9203SMark.Logan@Sun.COM 	message.ReasonCode = htonl(reason);
390*9203SMark.Logan@Sun.COM 	message.Reserved = 0x00000000;
391*9203SMark.Logan@Sun.COM 	message.Reserved2 = 0x00000000;
392*9203SMark.Logan@Sun.COM 
393*9203SMark.Logan@Sun.COM 	PRINT("Sending channel open replay failure to LME. Recipient: %d, Reason: %d.\n", recipientChannel, reason);
394*9203SMark.Logan@Sun.COM 	int res = _sendMessage((unsigned char *)&message, sizeof(message));
395*9203SMark.Logan@Sun.COM 
396*9203SMark.Logan@Sun.COM 	return (res == sizeof(message));
397*9203SMark.Logan@Sun.COM }
398*9203SMark.Logan@Sun.COM 
ChannelClose(UINT32 recipientChannel)399*9203SMark.Logan@Sun.COM bool LMEConnection::ChannelClose(UINT32 recipientChannel)
400*9203SMark.Logan@Sun.COM {
401*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
402*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
403*9203SMark.Logan@Sun.COM 		return false;
404*9203SMark.Logan@Sun.COM 	}
405*9203SMark.Logan@Sun.COM 
406*9203SMark.Logan@Sun.COM 	APF_CHANNEL_CLOSE_MESSAGE message;
407*9203SMark.Logan@Sun.COM 
408*9203SMark.Logan@Sun.COM 	message.MessageType = APF_CHANNEL_CLOSE;
409*9203SMark.Logan@Sun.COM 	message.RecipientChannel = htonl(recipientChannel);
410*9203SMark.Logan@Sun.COM 
411*9203SMark.Logan@Sun.COM 	PRINT("Sending channel close to LME. Recipient: %d.\n", recipientChannel);
412*9203SMark.Logan@Sun.COM 	int res = _sendMessage((unsigned char *)&message, sizeof(message));
413*9203SMark.Logan@Sun.COM 
414*9203SMark.Logan@Sun.COM 	return (res == sizeof(message));
415*9203SMark.Logan@Sun.COM }
416*9203SMark.Logan@Sun.COM 
ChannelData(UINT32 recipientChannel,UINT32 len,unsigned char * buffer)417*9203SMark.Logan@Sun.COM int LMEConnection::ChannelData(UINT32 recipientChannel,
418*9203SMark.Logan@Sun.COM 			       UINT32 len, unsigned char *buffer)
419*9203SMark.Logan@Sun.COM {
420*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
421*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
422*9203SMark.Logan@Sun.COM 		return false;
423*9203SMark.Logan@Sun.COM 	}
424*9203SMark.Logan@Sun.COM 
425*9203SMark.Logan@Sun.COM 	APF_CHANNEL_DATA_MESSAGE *message;
426*9203SMark.Logan@Sun.COM 
427*9203SMark.Logan@Sun.COM 	if (len > _heci.GetBufferSize() - sizeof(APF_CHANNEL_DATA_MESSAGE)) {
428*9203SMark.Logan@Sun.COM 		return -1;
429*9203SMark.Logan@Sun.COM 	}
430*9203SMark.Logan@Sun.COM 
431*9203SMark.Logan@Sun.COM 	message = (APF_CHANNEL_DATA_MESSAGE *)_txBuffer;
432*9203SMark.Logan@Sun.COM 	message->MessageType = APF_CHANNEL_DATA;
433*9203SMark.Logan@Sun.COM 	message->RecipientChannel = htonl(recipientChannel);
434*9203SMark.Logan@Sun.COM 	message->DataLength = htonl(len);
435*9203SMark.Logan@Sun.COM 	memcpy(message->Data, buffer, len);
436*9203SMark.Logan@Sun.COM 
437*9203SMark.Logan@Sun.COM 	PRINT("Sending %d bytes to recipient channel %d.\n", len, recipientChannel);
438*9203SMark.Logan@Sun.COM 	return _sendMessage((unsigned char *)message, sizeof(APF_CHANNEL_DATA_MESSAGE) + len);
439*9203SMark.Logan@Sun.COM }
440*9203SMark.Logan@Sun.COM 
ChannelWindowAdjust(UINT32 recipientChannel,UINT32 len)441*9203SMark.Logan@Sun.COM bool LMEConnection::ChannelWindowAdjust(UINT32 recipientChannel, UINT32 len)
442*9203SMark.Logan@Sun.COM {
443*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
444*9203SMark.Logan@Sun.COM 		PRINT("State: not connected to HECI.\n");
445*9203SMark.Logan@Sun.COM 		return false;
446*9203SMark.Logan@Sun.COM 	}
447*9203SMark.Logan@Sun.COM 
448*9203SMark.Logan@Sun.COM 	APF_WINDOW_ADJUST_MESSAGE message;
449*9203SMark.Logan@Sun.COM 
450*9203SMark.Logan@Sun.COM 	message.MessageType = APF_CHANNEL_WINDOW_ADJUST;
451*9203SMark.Logan@Sun.COM 	message.RecipientChannel = htonl(recipientChannel);
452*9203SMark.Logan@Sun.COM 	message.BytesToAdd = htonl(len);
453*9203SMark.Logan@Sun.COM 
454*9203SMark.Logan@Sun.COM 	PRINT("Sending Window Adjust with %d bytes to recipient channel %d.\n", len, recipientChannel);
455*9203SMark.Logan@Sun.COM 	int res = _sendMessage((unsigned char *)&message, sizeof(message));
456*9203SMark.Logan@Sun.COM 
457*9203SMark.Logan@Sun.COM 	return (res == sizeof(message));
458*9203SMark.Logan@Sun.COM }
459*9203SMark.Logan@Sun.COM 
_receiveMessage(unsigned char * buffer,int len)460*9203SMark.Logan@Sun.COM int LMEConnection::_receiveMessage(unsigned char *buffer, int len)
461*9203SMark.Logan@Sun.COM {
462*9203SMark.Logan@Sun.COM 	int result;
463*9203SMark.Logan@Sun.COM 
464*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
465*9203SMark.Logan@Sun.COM 		return -1;
466*9203SMark.Logan@Sun.COM 	}
467*9203SMark.Logan@Sun.COM 
468*9203SMark.Logan@Sun.COM 	result = _pHeci->ReceiveMessage(buffer, len, WAIT_INFINITE);
469*9203SMark.Logan@Sun.COM 
470*9203SMark.Logan@Sun.COM 	if (result < 0 && errno == ENOENT) {
471*9203SMark.Logan@Sun.COM 		Lock il(_initLock);
472*9203SMark.Logan@Sun.COM 		_initState = INIT_STATE_DISCONNECTED;
473*9203SMark.Logan@Sun.COM 	}
474*9203SMark.Logan@Sun.COM 
475*9203SMark.Logan@Sun.COM 	return result;
476*9203SMark.Logan@Sun.COM }
477*9203SMark.Logan@Sun.COM 
_sendMessage(unsigned char * buffer,int len)478*9203SMark.Logan@Sun.COM int LMEConnection::_sendMessage(unsigned char *buffer, int len)
479*9203SMark.Logan@Sun.COM {
480*9203SMark.Logan@Sun.COM 	int result;
481*9203SMark.Logan@Sun.COM 
482*9203SMark.Logan@Sun.COM 	if (!IsInitialized()) {
483*9203SMark.Logan@Sun.COM 		return -1;
484*9203SMark.Logan@Sun.COM 	}
485*9203SMark.Logan@Sun.COM 
486*9203SMark.Logan@Sun.COM 	_sendMessageLock.acquire();
487*9203SMark.Logan@Sun.COM 	result = _pHeci->SendMessage(buffer, len, HECI_IO_TIMEOUT);
488*9203SMark.Logan@Sun.COM 	_sendMessageLock.release();
489*9203SMark.Logan@Sun.COM 
490*9203SMark.Logan@Sun.COM 	if (result < 0 && errno == ENOENT) {
491*9203SMark.Logan@Sun.COM 		Lock il(_initLock);
492*9203SMark.Logan@Sun.COM 		_initState = INIT_STATE_DISCONNECTED;
493*9203SMark.Logan@Sun.COM 	}
494*9203SMark.Logan@Sun.COM 
495*9203SMark.Logan@Sun.COM 	return result;
496*9203SMark.Logan@Sun.COM }
497*9203SMark.Logan@Sun.COM 
_rxThreadFunc(void * param)498*9203SMark.Logan@Sun.COM void LMEConnection::_rxThreadFunc(void *param)
499*9203SMark.Logan@Sun.COM {
500*9203SMark.Logan@Sun.COM 	LMEConnection *connection = (LMEConnection *)param;
501*9203SMark.Logan@Sun.COM 
502*9203SMark.Logan@Sun.COM 	try {
503*9203SMark.Logan@Sun.COM 		if (LMS_PROCOL_VERSION == connection->protocolVer) {
504*9203SMark.Logan@Sun.COM 			connection->_doRX();
505*9203SMark.Logan@Sun.COM 		} else if (LMS_PROCOL_VERSION_COMPAT == connection->protocolVer) {
506*9203SMark.Logan@Sun.COM 			connection->_doRXCompat();
507*9203SMark.Logan@Sun.COM 		}
508*9203SMark.Logan@Sun.COM 	}
509*9203SMark.Logan@Sun.COM 	catch (...) {
510*9203SMark.Logan@Sun.COM 		PRINT("LMEConnection do RX exception\n");
511*9203SMark.Logan@Sun.COM 	}
512*9203SMark.Logan@Sun.COM 	pthread_exit(NULL);
513*9203SMark.Logan@Sun.COM }
514*9203SMark.Logan@Sun.COM 
_checkMinMsgSize(unsigned char * buf,unsigned int bytesRead)515*9203SMark.Logan@Sun.COM bool LMEConnection::_checkMinMsgSize(unsigned char *buf, unsigned int bytesRead)
516*9203SMark.Logan@Sun.COM {
517*9203SMark.Logan@Sun.COM 	switch (buf[0]) {
518*9203SMark.Logan@Sun.COM 	case APF_DISCONNECT:
519*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(APF_DISCONNECT_MESSAGE)) {
520*9203SMark.Logan@Sun.COM 			return false;
521*9203SMark.Logan@Sun.COM 		}
522*9203SMark.Logan@Sun.COM 		break;
523*9203SMark.Logan@Sun.COM 	case APF_SERVICE_REQUEST:
524*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(APF_SERVICE_REQUEST)) {
525*9203SMark.Logan@Sun.COM 			return false;
526*9203SMark.Logan@Sun.COM 		}
527*9203SMark.Logan@Sun.COM 		if (bytesRead < (sizeof(APF_SERVICE_REQUEST) +
528*9203SMark.Logan@Sun.COM 			ntohl(((APF_SERVICE_REQUEST_MESSAGE *)buf)->ServiceNameLength))) {
529*9203SMark.Logan@Sun.COM 			return false;
530*9203SMark.Logan@Sun.COM 		}
531*9203SMark.Logan@Sun.COM 		break;
532*9203SMark.Logan@Sun.COM 	case APF_USERAUTH_REQUEST:
533*9203SMark.Logan@Sun.COM 		if (bytesRead < (3 * sizeof(UINT32))) {
534*9203SMark.Logan@Sun.COM 			return false;
535*9203SMark.Logan@Sun.COM 		}
536*9203SMark.Logan@Sun.COM 		break;
537*9203SMark.Logan@Sun.COM 	case APF_GLOBAL_REQUEST:
538*9203SMark.Logan@Sun.COM 		if (bytesRead < (sizeof(APF_GENERIC_HEADER) + sizeof(UINT8))) {
539*9203SMark.Logan@Sun.COM 			return false;
540*9203SMark.Logan@Sun.COM 		}
541*9203SMark.Logan@Sun.COM 		if (bytesRead < (sizeof(APF_GENERIC_HEADER) + sizeof(UINT8) +
542*9203SMark.Logan@Sun.COM 			ntohl(((APF_GENERIC_HEADER *)buf)->StringLength))) {
543*9203SMark.Logan@Sun.COM 			return false;
544*9203SMark.Logan@Sun.COM 		}
545*9203SMark.Logan@Sun.COM 		break;
546*9203SMark.Logan@Sun.COM 	case APF_CHANNEL_OPEN:
547*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(APF_GENERIC_HEADER)) {
548*9203SMark.Logan@Sun.COM 			return false;
549*9203SMark.Logan@Sun.COM 		}
550*9203SMark.Logan@Sun.COM 		if (bytesRead < (sizeof(APF_GENERIC_HEADER) +
551*9203SMark.Logan@Sun.COM 			ntohl(((APF_GENERIC_HEADER *)buf)->StringLength))) {
552*9203SMark.Logan@Sun.COM 			return false;
553*9203SMark.Logan@Sun.COM 		}
554*9203SMark.Logan@Sun.COM 		break;
555*9203SMark.Logan@Sun.COM 	case APF_CHANNEL_OPEN_CONFIRMATION:
556*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE)) {
557*9203SMark.Logan@Sun.COM 			return false;
558*9203SMark.Logan@Sun.COM 		}
559*9203SMark.Logan@Sun.COM 		break;
560*9203SMark.Logan@Sun.COM 	case APF_CHANNEL_OPEN_FAILURE:
561*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(APF_CHANNEL_OPEN_FAILURE_MESSAGE)) {
562*9203SMark.Logan@Sun.COM 			return false;
563*9203SMark.Logan@Sun.COM 		}
564*9203SMark.Logan@Sun.COM 		break;
565*9203SMark.Logan@Sun.COM 	case APF_CHANNEL_CLOSE:
566*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(APF_CHANNEL_CLOSE_MESSAGE)) {
567*9203SMark.Logan@Sun.COM 			return false;
568*9203SMark.Logan@Sun.COM 		}
569*9203SMark.Logan@Sun.COM 		break;
570*9203SMark.Logan@Sun.COM 	case APF_CHANNEL_DATA:
571*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(APF_CHANNEL_DATA_MESSAGE)) {
572*9203SMark.Logan@Sun.COM 			return false;
573*9203SMark.Logan@Sun.COM 		}
574*9203SMark.Logan@Sun.COM 		if (bytesRead < (sizeof(APF_CHANNEL_DATA_MESSAGE) +
575*9203SMark.Logan@Sun.COM 			ntohl(((APF_CHANNEL_DATA_MESSAGE *)buf)->DataLength))) {
576*9203SMark.Logan@Sun.COM 			return false;
577*9203SMark.Logan@Sun.COM 		}
578*9203SMark.Logan@Sun.COM 		break;
579*9203SMark.Logan@Sun.COM 	case APF_CHANNEL_WINDOW_ADJUST:
580*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(APF_WINDOW_ADJUST_MESSAGE)) {
581*9203SMark.Logan@Sun.COM 			return false;
582*9203SMark.Logan@Sun.COM 		}
583*9203SMark.Logan@Sun.COM 		break;
584*9203SMark.Logan@Sun.COM 	case APF_PROTOCOLVERSION:
585*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(APF_PROTOCOL_VERSION_MESSAGE)) {
586*9203SMark.Logan@Sun.COM 			return false;
587*9203SMark.Logan@Sun.COM 		}
588*9203SMark.Logan@Sun.COM 		break;
589*9203SMark.Logan@Sun.COM 	default:
590*9203SMark.Logan@Sun.COM 		return false;
591*9203SMark.Logan@Sun.COM 	}
592*9203SMark.Logan@Sun.COM 	return true;
593*9203SMark.Logan@Sun.COM }
594*9203SMark.Logan@Sun.COM 
_doRX()595*9203SMark.Logan@Sun.COM void LMEConnection::_doRX()
596*9203SMark.Logan@Sun.COM {
597*9203SMark.Logan@Sun.COM 	unsigned int bytesRead;
598*9203SMark.Logan@Sun.COM 	int status = 1;
599*9203SMark.Logan@Sun.COM 
600*9203SMark.Logan@Sun.COM 	_threadStartedEvent.set();
601*9203SMark.Logan@Sun.COM 
602*9203SMark.Logan@Sun.COM 	unsigned char *rxBuffer = new unsigned char[_heci.GetBufferSize()];
603*9203SMark.Logan@Sun.COM 
604*9203SMark.Logan@Sun.COM 	while (true) {
605*9203SMark.Logan@Sun.COM 		bytesRead = (unsigned int)_receiveMessage(rxBuffer, _heci.GetBufferSize());
606*9203SMark.Logan@Sun.COM 
607*9203SMark.Logan@Sun.COM 		if ((int)bytesRead < 0) {
608*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
609*9203SMark.Logan@Sun.COM 			Deinit();
610*9203SMark.Logan@Sun.COM 			break;
611*9203SMark.Logan@Sun.COM 		}
612*9203SMark.Logan@Sun.COM 
613*9203SMark.Logan@Sun.COM 		if (bytesRead == 0) {
614*9203SMark.Logan@Sun.COM 			// ERROR
615*9203SMark.Logan@Sun.COM 			continue;
616*9203SMark.Logan@Sun.COM 		}
617*9203SMark.Logan@Sun.COM 
618*9203SMark.Logan@Sun.COM 		PRINT("Received from LME %d bytes (msg type %02d)\n", bytesRead, rxBuffer[0]);
619*9203SMark.Logan@Sun.COM 
620*9203SMark.Logan@Sun.COM 		if (!_checkMinMsgSize(rxBuffer, bytesRead)) {
621*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
622*9203SMark.Logan@Sun.COM 			Deinit();
623*9203SMark.Logan@Sun.COM 			break;
624*9203SMark.Logan@Sun.COM 		}
625*9203SMark.Logan@Sun.COM 
626*9203SMark.Logan@Sun.COM 		if (plugin.preprocess(rxBuffer, bytesRead) == LMS_DROPPED) {
627*9203SMark.Logan@Sun.COM 			continue;
628*9203SMark.Logan@Sun.COM 		}
629*9203SMark.Logan@Sun.COM 
630*9203SMark.Logan@Sun.COM 		switch (rxBuffer[0]) {
631*9203SMark.Logan@Sun.COM 		case APF_DISCONNECT:
632*9203SMark.Logan@Sun.COM 			{
633*9203SMark.Logan@Sun.COM 				LMEDisconnectMessage disconnectMessage(
634*9203SMark.Logan@Sun.COM 				    (APF_DISCONNECT_REASON_CODE)ntohl(
635*9203SMark.Logan@Sun.COM 					((APF_DISCONNECT_MESSAGE *)rxBuffer)->ReasonCode));
636*9203SMark.Logan@Sun.COM 
637*9203SMark.Logan@Sun.COM 				_cb(_cbParam, &disconnectMessage, sizeof(disconnectMessage), &status);
638*9203SMark.Logan@Sun.COM 			}
639*9203SMark.Logan@Sun.COM 			break;
640*9203SMark.Logan@Sun.COM 
641*9203SMark.Logan@Sun.COM 		case APF_SERVICE_REQUEST:
642*9203SMark.Logan@Sun.COM 			{
643*9203SMark.Logan@Sun.COM 				APF_SERVICE_REQUEST_MESSAGE *pMessage =
644*9203SMark.Logan@Sun.COM 					(APF_SERVICE_REQUEST_MESSAGE *)rxBuffer;
645*9203SMark.Logan@Sun.COM 				LMEServiceRequestMessage serviceRequestMessage;
646*9203SMark.Logan@Sun.COM 
647*9203SMark.Logan@Sun.COM 				serviceRequestMessage.ServiceName.append(
648*9203SMark.Logan@Sun.COM 					(char *)(pMessage->ServiceName),
649*9203SMark.Logan@Sun.COM 					ntohl(pMessage->ServiceNameLength));
650*9203SMark.Logan@Sun.COM 
651*9203SMark.Logan@Sun.COM 				_cb(_cbParam, &serviceRequestMessage, sizeof(serviceRequestMessage), &status);
652*9203SMark.Logan@Sun.COM 			}
653*9203SMark.Logan@Sun.COM 			break;
654*9203SMark.Logan@Sun.COM 
655*9203SMark.Logan@Sun.COM 		case APF_USERAUTH_REQUEST:
656*9203SMark.Logan@Sun.COM 			_apfUserAuthRequest(rxBuffer, bytesRead, &status);
657*9203SMark.Logan@Sun.COM 			break;
658*9203SMark.Logan@Sun.COM 
659*9203SMark.Logan@Sun.COM 		case APF_GLOBAL_REQUEST:
660*9203SMark.Logan@Sun.COM 			_apfGlobalRequest(rxBuffer, bytesRead, &status);
661*9203SMark.Logan@Sun.COM 			break;
662*9203SMark.Logan@Sun.COM 
663*9203SMark.Logan@Sun.COM 		case APF_CHANNEL_OPEN:
664*9203SMark.Logan@Sun.COM 			_apfChannelOpen(rxBuffer, bytesRead, &status);
665*9203SMark.Logan@Sun.COM 			break;
666*9203SMark.Logan@Sun.COM 
667*9203SMark.Logan@Sun.COM 		case APF_CHANNEL_OPEN_CONFIRMATION:
668*9203SMark.Logan@Sun.COM 			{
669*9203SMark.Logan@Sun.COM 				APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE *pMessage =
670*9203SMark.Logan@Sun.COM 				    (APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE *)rxBuffer;
671*9203SMark.Logan@Sun.COM 				LMEChannelOpenReplaySuccessMessage channelOpenReply;
672*9203SMark.Logan@Sun.COM 
673*9203SMark.Logan@Sun.COM 				channelOpenReply.RecipientChannel = ntohl(pMessage->RecipientChannel);
674*9203SMark.Logan@Sun.COM 				channelOpenReply.SenderChannel = ntohl(pMessage->SenderChannel);
675*9203SMark.Logan@Sun.COM 				channelOpenReply.InitialWindow = ntohl(pMessage->InitialWindowSize);
676*9203SMark.Logan@Sun.COM 				_cb(_cbParam, &channelOpenReply, sizeof(channelOpenReply), &status);
677*9203SMark.Logan@Sun.COM 			}
678*9203SMark.Logan@Sun.COM 			break;
679*9203SMark.Logan@Sun.COM 
680*9203SMark.Logan@Sun.COM 		case APF_CHANNEL_OPEN_FAILURE:
681*9203SMark.Logan@Sun.COM 			{
682*9203SMark.Logan@Sun.COM 				APF_CHANNEL_OPEN_FAILURE_MESSAGE *pMessage =
683*9203SMark.Logan@Sun.COM 				    (APF_CHANNEL_OPEN_FAILURE_MESSAGE *)rxBuffer;
684*9203SMark.Logan@Sun.COM 				LMEChannelOpenReplayFailureMessage channelOpenReply;
685*9203SMark.Logan@Sun.COM 
686*9203SMark.Logan@Sun.COM 				channelOpenReply.RecipientChannel = ntohl(pMessage->RecipientChannel);
687*9203SMark.Logan@Sun.COM 				channelOpenReply.ReasonCode =
688*9203SMark.Logan@Sun.COM 					(OPEN_FAILURE_REASON)(ntohl(pMessage->ReasonCode));
689*9203SMark.Logan@Sun.COM 				_cb(_cbParam, &channelOpenReply, sizeof(channelOpenReply), &status);
690*9203SMark.Logan@Sun.COM 			}
691*9203SMark.Logan@Sun.COM 			break;
692*9203SMark.Logan@Sun.COM 
693*9203SMark.Logan@Sun.COM 		case APF_CHANNEL_CLOSE:
694*9203SMark.Logan@Sun.COM 			{
695*9203SMark.Logan@Sun.COM 				APF_CHANNEL_CLOSE_MESSAGE *pMessage =
696*9203SMark.Logan@Sun.COM 				    (APF_CHANNEL_CLOSE_MESSAGE *)rxBuffer;
697*9203SMark.Logan@Sun.COM 				LMEChannelCloseMessage channelClose;
698*9203SMark.Logan@Sun.COM 
699*9203SMark.Logan@Sun.COM 				channelClose.RecipientChannel = ntohl(pMessage->RecipientChannel);
700*9203SMark.Logan@Sun.COM 				_cb(_cbParam, &channelClose, sizeof(channelClose), &status);
701*9203SMark.Logan@Sun.COM 			}
702*9203SMark.Logan@Sun.COM 			break;
703*9203SMark.Logan@Sun.COM 
704*9203SMark.Logan@Sun.COM 		case APF_CHANNEL_DATA:
705*9203SMark.Logan@Sun.COM 			{
706*9203SMark.Logan@Sun.COM 				APF_CHANNEL_DATA_MESSAGE *pMessage =
707*9203SMark.Logan@Sun.COM 				    (APF_CHANNEL_DATA_MESSAGE *)rxBuffer;
708*9203SMark.Logan@Sun.COM 				LMEChannelDataMessage channelData(ntohl(pMessage->RecipientChannel),
709*9203SMark.Logan@Sun.COM 								  ntohl(pMessage->DataLength),
710*9203SMark.Logan@Sun.COM 								  pMessage->Data);
711*9203SMark.Logan@Sun.COM 				_cb(_cbParam, &channelData, sizeof(channelData), &status);
712*9203SMark.Logan@Sun.COM 			}
713*9203SMark.Logan@Sun.COM 			break;
714*9203SMark.Logan@Sun.COM 
715*9203SMark.Logan@Sun.COM 		case APF_CHANNEL_WINDOW_ADJUST:
716*9203SMark.Logan@Sun.COM 			{
717*9203SMark.Logan@Sun.COM 				APF_WINDOW_ADJUST_MESSAGE *pMessage =
718*9203SMark.Logan@Sun.COM 				    (APF_WINDOW_ADJUST_MESSAGE *)rxBuffer;
719*9203SMark.Logan@Sun.COM 				LMEChannelWindowAdjustMessage channelWindowAdjust;
720*9203SMark.Logan@Sun.COM 
721*9203SMark.Logan@Sun.COM 				channelWindowAdjust.RecipientChannel = ntohl(pMessage->RecipientChannel);
722*9203SMark.Logan@Sun.COM 				channelWindowAdjust.BytesToAdd = ntohl(pMessage->BytesToAdd);
723*9203SMark.Logan@Sun.COM 				_cb(_cbParam, &channelWindowAdjust, sizeof(channelWindowAdjust), &status);
724*9203SMark.Logan@Sun.COM 			}
725*9203SMark.Logan@Sun.COM 			break;
726*9203SMark.Logan@Sun.COM 
727*9203SMark.Logan@Sun.COM 		case APF_PROTOCOLVERSION:
728*9203SMark.Logan@Sun.COM 			{
729*9203SMark.Logan@Sun.COM 				APF_PROTOCOL_VERSION_MESSAGE *pMessage =
730*9203SMark.Logan@Sun.COM 				    (APF_PROTOCOL_VERSION_MESSAGE *)rxBuffer;
731*9203SMark.Logan@Sun.COM 				LMEProtocolVersionMessage protVersion;
732*9203SMark.Logan@Sun.COM 
733*9203SMark.Logan@Sun.COM 				protVersion.MajorVersion = ntohl(pMessage->MajorVersion);
734*9203SMark.Logan@Sun.COM 				protVersion.MinorVersion = ntohl(pMessage->MinorVersion);
735*9203SMark.Logan@Sun.COM 				protVersion.TriggerReason =
736*9203SMark.Logan@Sun.COM 					(APF_TRIGGER_REASON)ntohl(pMessage->TriggerReason);
737*9203SMark.Logan@Sun.COM 				_cb(_cbParam, &protVersion, sizeof(protVersion), &status);
738*9203SMark.Logan@Sun.COM 			}
739*9203SMark.Logan@Sun.COM 			break;
740*9203SMark.Logan@Sun.COM 
741*9203SMark.Logan@Sun.COM 		default:
742*9203SMark.Logan@Sun.COM 			// Uknown request. Ignore
743*9203SMark.Logan@Sun.COM 			break;
744*9203SMark.Logan@Sun.COM 		}
745*9203SMark.Logan@Sun.COM 
746*9203SMark.Logan@Sun.COM 		if (IsInitialized()) {
747*9203SMark.Logan@Sun.COM 			plugin.postprocess(rxBuffer, bytesRead, status);
748*9203SMark.Logan@Sun.COM 		}
749*9203SMark.Logan@Sun.COM 	}
750*9203SMark.Logan@Sun.COM 
751*9203SMark.Logan@Sun.COM 	if (rxBuffer != NULL) {
752*9203SMark.Logan@Sun.COM 		delete[] rxBuffer;
753*9203SMark.Logan@Sun.COM 	}
754*9203SMark.Logan@Sun.COM }
755*9203SMark.Logan@Sun.COM 
_apfChannelOpen(unsigned char * rxBuffer,unsigned int bytesRead,int * status)756*9203SMark.Logan@Sun.COM void LMEConnection::_apfChannelOpen(unsigned char *rxBuffer, unsigned int bytesRead, int *status)
757*9203SMark.Logan@Sun.COM {
758*9203SMark.Logan@Sun.COM 	APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer;
759*9203SMark.Logan@Sun.COM 
760*9203SMark.Logan@Sun.COM 	if (_strnicmp((char *)pHeader->String,
761*9203SMark.Logan@Sun.COM 		APF_OPEN_CHANNEL_REQUEST_DIRECT,
762*9203SMark.Logan@Sun.COM 		APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_DIRECT)) == 0) {
763*9203SMark.Logan@Sun.COM 
764*9203SMark.Logan@Sun.COM 		UINT32 senderChannel = 0;
765*9203SMark.Logan@Sun.COM 
766*9203SMark.Logan@Sun.COM 		_apfChannelOpenDirect(rxBuffer, bytesRead, &senderChannel, status);
767*9203SMark.Logan@Sun.COM 		if (IsInitialized() && (*status == 1)) {
768*9203SMark.Logan@Sun.COM 			if (plugin.retry(rxBuffer, bytesRead) != LMS_DROPPED) {
769*9203SMark.Logan@Sun.COM 				_apfChannelOpenDirect(rxBuffer, bytesRead, NULL, status);
770*9203SMark.Logan@Sun.COM 			}
771*9203SMark.Logan@Sun.COM 		}
772*9203SMark.Logan@Sun.COM 		if (IsInitialized() && (*status == 1)) {
773*9203SMark.Logan@Sun.COM 			ChannelOpenReplayFailure(senderChannel,
774*9203SMark.Logan@Sun.COM 			    OPEN_FAILURE_REASON_CONNECT_FAILED);
775*9203SMark.Logan@Sun.COM 		}
776*9203SMark.Logan@Sun.COM 	}
777*9203SMark.Logan@Sun.COM }
778*9203SMark.Logan@Sun.COM 
_apfChannelOpenDirect(unsigned char * rxBuffer,unsigned int bytesRead,UINT32 * senderChannel,int * status)779*9203SMark.Logan@Sun.COM void LMEConnection::_apfChannelOpenDirect(unsigned char *rxBuffer, unsigned int bytesRead, UINT32 *senderChannel, int *status)
780*9203SMark.Logan@Sun.COM {
781*9203SMark.Logan@Sun.COM 	unsigned char *pCurrent;
782*9203SMark.Logan@Sun.COM 	APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer;
783*9203SMark.Logan@Sun.COM 
784*9203SMark.Logan@Sun.COM 	if (bytesRead < sizeof(APF_GENERIC_HEADER) +
785*9203SMark.Logan@Sun.COM 	    ntohl(pHeader->StringLength) +
786*9203SMark.Logan@Sun.COM 	    7 + (5 * sizeof(UINT32))) {
787*9203SMark.Logan@Sun.COM 		PRINT("Error receiving data from HECI\n");
788*9203SMark.Logan@Sun.COM 		Deinit();
789*9203SMark.Logan@Sun.COM 		return;
790*9203SMark.Logan@Sun.COM 	}
791*9203SMark.Logan@Sun.COM 
792*9203SMark.Logan@Sun.COM 	pCurrent = rxBuffer + sizeof(APF_GENERIC_HEADER) +
793*9203SMark.Logan@Sun.COM 		APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_DIRECT);
794*9203SMark.Logan@Sun.COM 
795*9203SMark.Logan@Sun.COM 	LMEChannelOpenRequestMessage channelOpenRequest;
796*9203SMark.Logan@Sun.COM 	channelOpenRequest.ChannelType = LMEChannelOpenRequestMessage::DIRECT;
797*9203SMark.Logan@Sun.COM 
798*9203SMark.Logan@Sun.COM 	channelOpenRequest.SenderChannel = ntohl(*((UINT32 *)pCurrent));
799*9203SMark.Logan@Sun.COM 	if (senderChannel) {
800*9203SMark.Logan@Sun.COM 		*senderChannel = channelOpenRequest.SenderChannel;
801*9203SMark.Logan@Sun.COM 	}
802*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
803*9203SMark.Logan@Sun.COM 	channelOpenRequest.InitialWindow = ntohl(*((UINT32 *)pCurrent));
804*9203SMark.Logan@Sun.COM 	pCurrent += 2 * sizeof(UINT32);
805*9203SMark.Logan@Sun.COM 
806*9203SMark.Logan@Sun.COM 	UINT32 len = ntohl(*((UINT32 *)pCurrent));
807*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
808*9203SMark.Logan@Sun.COM 	channelOpenRequest.Address.append((char *)pCurrent, len);
809*9203SMark.Logan@Sun.COM 	pCurrent += len;
810*9203SMark.Logan@Sun.COM 	channelOpenRequest.Port = ntohl(*((UINT32 *)pCurrent));
811*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
812*9203SMark.Logan@Sun.COM 
813*9203SMark.Logan@Sun.COM 	_cb(_cbParam, &channelOpenRequest, sizeof(channelOpenRequest), status);
814*9203SMark.Logan@Sun.COM }
815*9203SMark.Logan@Sun.COM 
_apfGlobalRequest(unsigned char * rxBuffer,unsigned int bytesRead,int * status)816*9203SMark.Logan@Sun.COM void LMEConnection::_apfGlobalRequest(unsigned char *rxBuffer, unsigned int bytesRead, int *status)
817*9203SMark.Logan@Sun.COM {
818*9203SMark.Logan@Sun.COM 	unsigned char *pCurrent;
819*9203SMark.Logan@Sun.COM 	APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer;
820*9203SMark.Logan@Sun.COM 
821*9203SMark.Logan@Sun.COM 	if (_strnicmp((char *)pHeader->String,
822*9203SMark.Logan@Sun.COM 	    APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST,
823*9203SMark.Logan@Sun.COM 	    APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST)) == 0) {
824*9203SMark.Logan@Sun.COM 		LMETcpForwardRequestMessage tcpForwardRequest;
825*9203SMark.Logan@Sun.COM 		unsigned int hsize = sizeof(APF_GENERIC_HEADER) +
826*9203SMark.Logan@Sun.COM 		    APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST) +
827*9203SMark.Logan@Sun.COM 		    sizeof(UINT8);
828*9203SMark.Logan@Sun.COM 		pCurrent = rxBuffer + hsize;
829*9203SMark.Logan@Sun.COM 		bytesRead -= hsize;
830*9203SMark.Logan@Sun.COM 
831*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(UINT32)) {
832*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
833*9203SMark.Logan@Sun.COM 			Deinit();
834*9203SMark.Logan@Sun.COM 			return;
835*9203SMark.Logan@Sun.COM 		}
836*9203SMark.Logan@Sun.COM 
837*9203SMark.Logan@Sun.COM 		UINT32 len = ntohl(*((UINT32 *)pCurrent));
838*9203SMark.Logan@Sun.COM 		pCurrent += sizeof(UINT32);
839*9203SMark.Logan@Sun.COM 
840*9203SMark.Logan@Sun.COM 		if (bytesRead < (sizeof(UINT32) + len + sizeof(UINT32))) {
841*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
842*9203SMark.Logan@Sun.COM 			Deinit();
843*9203SMark.Logan@Sun.COM 			return;
844*9203SMark.Logan@Sun.COM 		}
845*9203SMark.Logan@Sun.COM 
846*9203SMark.Logan@Sun.COM 		tcpForwardRequest.Address.append((char *)pCurrent, len);
847*9203SMark.Logan@Sun.COM 		pCurrent += len;
848*9203SMark.Logan@Sun.COM 		tcpForwardRequest.Port = ntohl(*((UINT32 *)pCurrent));
849*9203SMark.Logan@Sun.COM 
850*9203SMark.Logan@Sun.COM 		_cb(_cbParam, &tcpForwardRequest, sizeof(tcpForwardRequest), status);
851*9203SMark.Logan@Sun.COM 	}
852*9203SMark.Logan@Sun.COM 	else if (_strnicmp((char *)pHeader->String,
853*9203SMark.Logan@Sun.COM 	    APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST,
854*9203SMark.Logan@Sun.COM 	    APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST)) == 0) {
855*9203SMark.Logan@Sun.COM 		LMETcpForwardCancelRequestMessage tcpForwardCancelRequest;
856*9203SMark.Logan@Sun.COM 		unsigned int hsize = sizeof(APF_GENERIC_HEADER) +
857*9203SMark.Logan@Sun.COM 		    APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST) +
858*9203SMark.Logan@Sun.COM 		    sizeof(UINT8);
859*9203SMark.Logan@Sun.COM 		pCurrent = rxBuffer + hsize;
860*9203SMark.Logan@Sun.COM 		bytesRead -= hsize;
861*9203SMark.Logan@Sun.COM 
862*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(UINT32)) {
863*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
864*9203SMark.Logan@Sun.COM 			Deinit();
865*9203SMark.Logan@Sun.COM 			return;
866*9203SMark.Logan@Sun.COM 		}
867*9203SMark.Logan@Sun.COM 
868*9203SMark.Logan@Sun.COM 		UINT32 len = ntohl(*((UINT32 *)pCurrent));
869*9203SMark.Logan@Sun.COM 		pCurrent += sizeof(UINT32);
870*9203SMark.Logan@Sun.COM 
871*9203SMark.Logan@Sun.COM 		if (bytesRead < (sizeof(UINT32) + len + sizeof(UINT32))) {
872*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
873*9203SMark.Logan@Sun.COM 			Deinit();
874*9203SMark.Logan@Sun.COM 			return;
875*9203SMark.Logan@Sun.COM 		}
876*9203SMark.Logan@Sun.COM 
877*9203SMark.Logan@Sun.COM 		tcpForwardCancelRequest.Address.append((char *)pCurrent, len);
878*9203SMark.Logan@Sun.COM 		pCurrent += len;
879*9203SMark.Logan@Sun.COM 		tcpForwardCancelRequest.Port = ntohl(*((UINT32 *)pCurrent));
880*9203SMark.Logan@Sun.COM 
881*9203SMark.Logan@Sun.COM 		_cb(_cbParam, &tcpForwardCancelRequest, sizeof(tcpForwardCancelRequest), status);
882*9203SMark.Logan@Sun.COM 	}
883*9203SMark.Logan@Sun.COM 	else if (_strnicmp((char *)pHeader->String,
884*9203SMark.Logan@Sun.COM 	    APF_GLOBAL_REQUEST_STR_UDP_SEND_TO,
885*9203SMark.Logan@Sun.COM 	    APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_UDP_SEND_TO)) == 0) {
886*9203SMark.Logan@Sun.COM 		unsigned int hsize = sizeof(APF_GENERIC_HEADER) +
887*9203SMark.Logan@Sun.COM 		    APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_UDP_SEND_TO) +
888*9203SMark.Logan@Sun.COM 		    sizeof(UINT8);
889*9203SMark.Logan@Sun.COM 		pCurrent = rxBuffer + hsize;
890*9203SMark.Logan@Sun.COM 		bytesRead -= hsize;
891*9203SMark.Logan@Sun.COM 
892*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(UINT32)) {
893*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
894*9203SMark.Logan@Sun.COM 			Deinit();
895*9203SMark.Logan@Sun.COM 			return;
896*9203SMark.Logan@Sun.COM 		}
897*9203SMark.Logan@Sun.COM 
898*9203SMark.Logan@Sun.COM 		UINT32 len = ntohl(*((UINT32 *)pCurrent));
899*9203SMark.Logan@Sun.COM 		pCurrent += sizeof(UINT32);
900*9203SMark.Logan@Sun.COM 
901*9203SMark.Logan@Sun.COM 		if (bytesRead < (sizeof(UINT32) + len + sizeof(UINT32))) {
902*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
903*9203SMark.Logan@Sun.COM 			Deinit();
904*9203SMark.Logan@Sun.COM 			return;
905*9203SMark.Logan@Sun.COM 		}
906*9203SMark.Logan@Sun.COM 		bytesRead -= (sizeof(UINT32) + len + sizeof(UINT32));
907*9203SMark.Logan@Sun.COM 
908*9203SMark.Logan@Sun.COM 		std::string address;
909*9203SMark.Logan@Sun.COM 		address.append((char *)pCurrent, len);
910*9203SMark.Logan@Sun.COM 		pCurrent += len;
911*9203SMark.Logan@Sun.COM 		UINT32 port = ntohl(*((UINT32 *)pCurrent));
912*9203SMark.Logan@Sun.COM 		pCurrent += sizeof(UINT32);
913*9203SMark.Logan@Sun.COM 
914*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(UINT32)) {
915*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
916*9203SMark.Logan@Sun.COM 			Deinit();
917*9203SMark.Logan@Sun.COM 			return;
918*9203SMark.Logan@Sun.COM 		}
919*9203SMark.Logan@Sun.COM 
920*9203SMark.Logan@Sun.COM 		// Skip Originator IP and Port
921*9203SMark.Logan@Sun.COM 		len = ntohl(*((UINT32 *)pCurrent));
922*9203SMark.Logan@Sun.COM 		pCurrent += sizeof(UINT32);
923*9203SMark.Logan@Sun.COM 
924*9203SMark.Logan@Sun.COM 		if (bytesRead < (sizeof(UINT32) + len + sizeof(UINT32))) {
925*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
926*9203SMark.Logan@Sun.COM 			Deinit();
927*9203SMark.Logan@Sun.COM 			return;
928*9203SMark.Logan@Sun.COM 		}
929*9203SMark.Logan@Sun.COM 		bytesRead -= (sizeof(UINT32) + len + sizeof(UINT32));
930*9203SMark.Logan@Sun.COM 
931*9203SMark.Logan@Sun.COM 		pCurrent += len;
932*9203SMark.Logan@Sun.COM 		pCurrent += sizeof(UINT32);
933*9203SMark.Logan@Sun.COM 
934*9203SMark.Logan@Sun.COM 		if (bytesRead < sizeof(UINT32)) {
935*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
936*9203SMark.Logan@Sun.COM 			Deinit();
937*9203SMark.Logan@Sun.COM 			return;
938*9203SMark.Logan@Sun.COM 		}
939*9203SMark.Logan@Sun.COM 
940*9203SMark.Logan@Sun.COM 		// Retrieve Data
941*9203SMark.Logan@Sun.COM 		len = ntohl(*((UINT32 *)pCurrent));
942*9203SMark.Logan@Sun.COM 		pCurrent += sizeof(UINT32);
943*9203SMark.Logan@Sun.COM 
944*9203SMark.Logan@Sun.COM 		if (bytesRead < (sizeof(UINT32) + len)) {
945*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
946*9203SMark.Logan@Sun.COM 			Deinit();
947*9203SMark.Logan@Sun.COM 			return;
948*9203SMark.Logan@Sun.COM 		}
949*9203SMark.Logan@Sun.COM 
950*9203SMark.Logan@Sun.COM 		LMEUdpSendToMessage udpSendTo(address, port, len, pCurrent);
951*9203SMark.Logan@Sun.COM 
952*9203SMark.Logan@Sun.COM 		_cb(_cbParam, &udpSendTo, sizeof(udpSendTo), status);
953*9203SMark.Logan@Sun.COM 	}
954*9203SMark.Logan@Sun.COM }
955*9203SMark.Logan@Sun.COM 
_apfUserAuthRequest(unsigned char * rxBuffer,unsigned int bytesRead,int * status)956*9203SMark.Logan@Sun.COM void LMEConnection::_apfUserAuthRequest(unsigned char *rxBuffer, unsigned int bytesRead, int *status)
957*9203SMark.Logan@Sun.COM {
958*9203SMark.Logan@Sun.COM 	unsigned char *pCurrent = rxBuffer;
959*9203SMark.Logan@Sun.COM 
960*9203SMark.Logan@Sun.COM 	++pCurrent;
961*9203SMark.Logan@Sun.COM 
962*9203SMark.Logan@Sun.COM 	LMEUserAuthRequestMessage userAuthRequest;
963*9203SMark.Logan@Sun.COM 
964*9203SMark.Logan@Sun.COM 	UINT32 len = ntohl(*((UINT32 *)pCurrent));
965*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
966*9203SMark.Logan@Sun.COM 
967*9203SMark.Logan@Sun.COM 	if ((bytesRead - (pCurrent - rxBuffer)) < len) {
968*9203SMark.Logan@Sun.COM 		PRINT("Error receiving data from HECI\n");
969*9203SMark.Logan@Sun.COM 		Deinit();
970*9203SMark.Logan@Sun.COM 		return;
971*9203SMark.Logan@Sun.COM 	}
972*9203SMark.Logan@Sun.COM 
973*9203SMark.Logan@Sun.COM 	userAuthRequest.Username.append((char *)pCurrent, len);
974*9203SMark.Logan@Sun.COM 	pCurrent += len;
975*9203SMark.Logan@Sun.COM 
976*9203SMark.Logan@Sun.COM 	if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(UINT32)) {
977*9203SMark.Logan@Sun.COM 		PRINT("Error receiving data from HECI\n");
978*9203SMark.Logan@Sun.COM 		Deinit();
979*9203SMark.Logan@Sun.COM 		return;
980*9203SMark.Logan@Sun.COM 	}
981*9203SMark.Logan@Sun.COM 
982*9203SMark.Logan@Sun.COM 	len = ntohl(*((UINT32 *)pCurrent));
983*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
984*9203SMark.Logan@Sun.COM 
985*9203SMark.Logan@Sun.COM 	if ((bytesRead - (pCurrent - rxBuffer)) < len) {
986*9203SMark.Logan@Sun.COM 		PRINT("Error receiving data from HECI\n");
987*9203SMark.Logan@Sun.COM 		Deinit();
988*9203SMark.Logan@Sun.COM 		return;
989*9203SMark.Logan@Sun.COM 	}
990*9203SMark.Logan@Sun.COM 
991*9203SMark.Logan@Sun.COM 	userAuthRequest.ServiceName.append((char *)pCurrent, len);
992*9203SMark.Logan@Sun.COM 	pCurrent += len;
993*9203SMark.Logan@Sun.COM 
994*9203SMark.Logan@Sun.COM 	if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(UINT32)) {
995*9203SMark.Logan@Sun.COM 		PRINT("Error receiving data from HECI\n");
996*9203SMark.Logan@Sun.COM 		Deinit();
997*9203SMark.Logan@Sun.COM 		return;
998*9203SMark.Logan@Sun.COM 	}
999*9203SMark.Logan@Sun.COM 
1000*9203SMark.Logan@Sun.COM 	len = ntohl(*((UINT32 *)pCurrent));
1001*9203SMark.Logan@Sun.COM 	pCurrent += sizeof(UINT32);
1002*9203SMark.Logan@Sun.COM 
1003*9203SMark.Logan@Sun.COM 	if ((bytesRead - (pCurrent - rxBuffer)) < len) {
1004*9203SMark.Logan@Sun.COM 		PRINT("Error receiving data from HECI\n");
1005*9203SMark.Logan@Sun.COM 		Deinit();
1006*9203SMark.Logan@Sun.COM 		return;
1007*9203SMark.Logan@Sun.COM 	}
1008*9203SMark.Logan@Sun.COM 
1009*9203SMark.Logan@Sun.COM 	userAuthRequest.MethodName.append((char *)pCurrent, len);
1010*9203SMark.Logan@Sun.COM 	pCurrent += len;
1011*9203SMark.Logan@Sun.COM 
1012*9203SMark.Logan@Sun.COM 	if (_strnicmp(userAuthRequest.MethodName.c_str(), APF_AUTH_PASSWORD,
1013*9203SMark.Logan@Sun.COM 			userAuthRequest.MethodName.size()) == 0) {
1014*9203SMark.Logan@Sun.COM 
1015*9203SMark.Logan@Sun.COM 		if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(UINT32) + 1) {
1016*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
1017*9203SMark.Logan@Sun.COM 			Deinit();
1018*9203SMark.Logan@Sun.COM 			return;
1019*9203SMark.Logan@Sun.COM 		}
1020*9203SMark.Logan@Sun.COM 
1021*9203SMark.Logan@Sun.COM 		++pCurrent;
1022*9203SMark.Logan@Sun.COM 
1023*9203SMark.Logan@Sun.COM 		len = ntohl(*((UINT32 *)pCurrent));
1024*9203SMark.Logan@Sun.COM 		pCurrent += sizeof(UINT32);
1025*9203SMark.Logan@Sun.COM 
1026*9203SMark.Logan@Sun.COM 		if ((bytesRead - (pCurrent - rxBuffer)) < len) {
1027*9203SMark.Logan@Sun.COM 			PRINT("Error receiving data from HECI\n");
1028*9203SMark.Logan@Sun.COM 			Deinit();
1029*9203SMark.Logan@Sun.COM 			return;
1030*9203SMark.Logan@Sun.COM 		}
1031*9203SMark.Logan@Sun.COM 
1032*9203SMark.Logan@Sun.COM 		AuthPasswordData authData;
1033*9203SMark.Logan@Sun.COM 		authData.Password.append((char *)pCurrent, len);
1034*9203SMark.Logan@Sun.COM 		pCurrent += len;
1035*9203SMark.Logan@Sun.COM 
1036*9203SMark.Logan@Sun.COM 		userAuthRequest.MethodData = &authData;
1037*9203SMark.Logan@Sun.COM 	}
1038*9203SMark.Logan@Sun.COM 
1039*9203SMark.Logan@Sun.COM 	_cb(_cbParam, &userAuthRequest, sizeof(userAuthRequest), status);
1040*9203SMark.Logan@Sun.COM }
1041*9203SMark.Logan@Sun.COM 
GetHeciBufferSize() const1042*9203SMark.Logan@Sun.COM unsigned int LMEConnection::GetHeciBufferSize() const
1043*9203SMark.Logan@Sun.COM {
1044*9203SMark.Logan@Sun.COM 	if (_pHeci == NULL) {
1045*9203SMark.Logan@Sun.COM 		return 0;
1046*9203SMark.Logan@Sun.COM 	}
1047*9203SMark.Logan@Sun.COM 	return _pHeci->GetBufferSize();
1048*9203SMark.Logan@Sun.COM }
1049*9203SMark.Logan@Sun.COM 
1050