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