dcomShow.cpp
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:40k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* dcomShow.cpp - DCOM extended show routines */
  2. /* Copyright (c) 2001 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01j,22apr02,nel  SPR#76087. Make read routine return 0 when buffer empty
  7.                  instead of ee to make sure that long loops don't occur.
  8. 01i,18feb02,nel  SPR#73368. Add mutex to packet processing routines to prevent
  9.                  mixed output to telnet/serial port.
  10. 01h,17dec01,nel  Add include symbol for diab build.
  11. 01g,10dec01,dbs  diab build
  12. 01f,06dec01,nel  Add listener socket to enable retrieval of information via
  13.                  telnet.
  14. 01e,19oct01,nel  Correct minor typo.
  15. 01d,03oct01,nel  Add in direction indication.
  16. 01c,28sep01,nel  Add remaining code comments.
  17. 01b,25sep01,nel  Correct logic in ReadBytes routine.
  18. 01a,20aug01,nel  written
  19. */
  20. /*
  21. DESCRIPTION
  22. This module implements a packet decoding mechanism that allows VxDCOM network
  23. traffic to be displayed. Network data is captured directly before any
  24. marshalling/unmarshalling. This data is then decoded by a separate algorithm
  25. from the VxDCOM marshalling/unmarshalling code.
  26. All system GUIDs are decoded into their symbolic representations. To have
  27. GUIDs decoded for user CoClasses the COM Track mechanism must be enabled. The
  28. following should be added to the build settings for each CoClass:
  29. -DVXDCOM_COMTRACK_LEVEL=1
  30. There are no user callable functions in this module. Including the symbol
  31. INCLUDE_DCOM_SHOW in the kernel will enable the facility and all received
  32. DCOM network traffic will be decoded and output. Output goes by default
  33. to the console device.
  34. If the configuration parameter VXDCOM_DCOM_SHOW_PORT is set to a valid,
  35. unused port number a telnet style client can be connected to this port
  36. and all output will be directed to this client. Only one client can be
  37. connected at one time. If a port number of zero is given then this facility
  38. will be disabled and all output will be directed to the console device.
  39. This facility carries a high performance penalty and is only intended
  40. to provide debug information to Wind River Customer Support. It should
  41. not be included otherwise.
  42. */
  43. /* includes */
  44. #include <stdio.h>
  45. #include <string>
  46. #include <iostream>
  47. #include "ReactorTypes.h"
  48. #include "vxidl.h"
  49. #include "private/comMisc.h"
  50. #include "private/DebugHooks.h"
  51. #include "rpcDceProto.h"
  52. #include "comShow.h"
  53. #include "private/comStl.h"
  54. #include "dcomLib.h"
  55. #include "taskLib.h"
  56. #include "opccomn.h"
  57. #include "opcda.h"
  58. #include "opc_ae.h"
  59. #include "orpc.h"
  60. #include "OxidResolver.h"
  61. #include "RemoteActivation.h"
  62. #include "RemUnknown.h"
  63. #include "rpcDceProto.h"
  64. /* Include symbol for diab */
  65. extern "C" int include_vxdcom_dcomShow (void)
  66.     {
  67.     return 0;
  68.     }
  69. /* defines */
  70. /* Entry in the lookup table */
  71. #define TABLE_ENTRY(name) {#name, name}
  72. /* Entry in common GUID search table */
  73. #define GUID_STR(c) {&c, #c}
  74. /* Output and indented packet header */
  75. #define NAME(n) RpcIndentBlock _name (n)
  76. /* Output a field name, doesn't increase indent */
  77. #define FIELD(n,v) {RpcName _name(n); output(v, false); _name.dummy (); }
  78. /* Common virtual functions defined in all the base classes of DataPacket */
  79. #define COMMON_VIRTUALS()   
  80.     private:   
  81.     virtual BYTE ReadBYTE   
  82.      (   
  83. const char * pName,   
  84. TABLE * pDecodeTable = NULL   
  85. ) = NULL;   
  86.     virtual void ReadARRAY   
  87.      (   
  88. const char *  pName,   
  89. ULONG   number) = NULL;   
  90.     virtual USHORT ReadUSHORT   
  91. (   
  92. const char * pName,   
  93. bool swap = true,   
  94. TABLE * pDecodeTable = NULL,   
  95. bool doEndOfLine = true   
  96. ) = NULL;   
  97.     virtual ULONG ReadULONG   
  98. (   
  99. const char * name,   
  100. bool swap = true,   
  101. TABLE * pDecodeTable = NULL   
  102. ) = NULL;   
  103.     virtual void setFlags (const BYTE flags) = NULL;   
  104.     virtual BYTE getFlags () = NULL;   
  105.     virtual BYTE * ReadBytes (DWORD number, bool swap = true) = NULL;   
  106.     virtual const char * getChannelBinding () = NULL;   
  107.     virtual DWORD BytesRemaining () = NULL;
  108. #define PRINT_STR(str)   
  109.     if CHECKHOOK(pDcomShowPrintStr)   
  110. HOOK(pDcomShowPrintStr)(str);   
  111.     else   
  112. printf (str)
  113. /* typedefs */
  114. typedef STL_MAP(string, GUID) CTXID_MAP;
  115. typedef struct tagTable
  116.     {
  117.     char * m_name;
  118.     ULONG m_value;
  119.     } TABLE;
  120. typedef struct _GUID_ELEM
  121.     {
  122.     const GUID * guid;
  123.     const char * pName;
  124.     } GUID_ELEM;
  125. /* locals */
  126. /* Mutext used to lock critcal sections */
  127. static VxMutex s_mutex;
  128. /* presCtxID lookp table */
  129. static CTXID_MAP ctxIdMap;
  130. /* Message name lookup table */
  131. static TABLE rpcCnTypesTable [] = {
  132.     TABLE_ENTRY(RPC_CN_PKT_REQUEST),
  133.     TABLE_ENTRY(RPC_CN_PKT_RESPONSE),
  134.     TABLE_ENTRY(RPC_CN_PKT_FAULT),
  135.     TABLE_ENTRY(RPC_CN_PKT_BIND),
  136.     TABLE_ENTRY(RPC_CN_PKT_BIND_ACK),
  137.     TABLE_ENTRY(RPC_CN_PKT_BIND_NAK),
  138.     TABLE_ENTRY(RPC_CN_PKT_ALTER_CONTEXT),
  139.     TABLE_ENTRY(RPC_CN_PKT_ALTER_CONTEXT_RESP),
  140.     TABLE_ENTRY(RPC_CN_PKT_AUTH3),
  141.     TABLE_ENTRY(RPC_CN_PKT_SHUTDOWN),
  142.     TABLE_ENTRY(RPC_CN_PKT_REMOTE_ALERT),
  143.     TABLE_ENTRY(RPC_CN_PKT_ORPHANED),
  144.     {NULL, 0}
  145.    };
  146. /* Common GUID lookup table */
  147. static GUID_ELEM guidList [] = 
  148.                     { GUID_STR(GUID_NULL),
  149.       GUID_STR(CLSID_StdMarshal),
  150.       GUID_STR(IID_IWindTypes),
  151.       GUID_STR(IID_IUnknown),
  152.       GUID_STR(IID_IClassFactory),
  153.       GUID_STR(IID_IMultiQI),
  154.       GUID_STR(IID_IRegistry),
  155.       GUID_STR(IID_IEnumGUID),
  156.       GUID_STR(IID_IEnumString),
  157.       GUID_STR(IID_IEnumUnknown),
  158.       GUID_STR(IID_IMalloc),
  159.       GUID_STR(IID_IConnectionPoint),
  160.       GUID_STR(IID_IConnectionPointContainer),
  161.       GUID_STR(IID_IEnumConnections),
  162.       GUID_STR(IID_IEnumConnectionPoints),
  163.       GUID_STR(IID_IOPCEventServer),
  164.       GUID_STR(IID_IOPCEventSubscriptionMgt),
  165.       GUID_STR(IID_IOPCEventAreaBrowser),
  166.       GUID_STR(IID_IOPCEventSink),
  167.       GUID_STR(IID_IOPCShutdown),
  168.       GUID_STR(IID_IOPCCommon),
  169.       GUID_STR(IID_IOPCServerList),
  170.       GUID_STR(IID_IOPCServer),
  171.       GUID_STR(IID_IOPCServerPublicGroups),
  172.       GUID_STR(IID_IOPCBrowseServerAddressSpace),
  173.       GUID_STR(IID_IOPCGroupStateMgt),
  174.       GUID_STR(IID_IOPCPublicGroupStateMgt),
  175.       GUID_STR(IID_IOPCSyncIO),
  176.       GUID_STR(IID_IOPCAsyncIO),
  177.       GUID_STR(IID_IOPCItemMgt),
  178.       GUID_STR(IID_IEnumOPCItemAttributes),
  179.       GUID_STR(IID_IOPCDataCallback),
  180.       GUID_STR(IID_IOPCAsyncIO2),
  181.       GUID_STR(IID_IOPCItemProperties),
  182.       GUID_STR(IID_IMarshal),
  183.       GUID_STR(IID_ISequentialStream),
  184.       GUID_STR(IID_IStream),
  185.       GUID_STR(IID_ORPCTypes),
  186.       GUID_STR(IID_IOrpcProxy),
  187.       GUID_STR(IID_IOrpcClientChannel),
  188.       GUID_STR(IID_IOXIDResolver),
  189.       GUID_STR(IID_ISystemActivator),
  190.       GUID_STR(IID_IRemoteActivation),
  191.       GUID_STR(IID_IRemUnknown),
  192.       GUID_STR(IID_IRpcDceTypes),
  193.       {{0,}, NULL}};
  194. /* Current level of indentation */
  195. static int indentLevel = 0;
  196. static int s_listenPort = 0;
  197. static int s_outputSocket = 0;
  198. /* Forwards definitions */
  199. extern "C" void networkPrint (const char * str);
  200. extern "C" void startListenerTask (void);
  201. /* Common functions */
  202. /**************************************************************************
  203. *
  204. * findGuid - finds a symbolic rep of a GUID.
  205. *
  206. * Looks up the supplied GUID and returns a symbolic rep of it. The lookup
  207. * first looks in an internal table of well known GUIDs. If it isn't found 
  208. * in this it then looks it up in the list of GUIDs collected by the COM Track
  209. * mechanism. If it isn't found in this then the GUID is converted into a 
  210. * string and returned.
  211. *
  212. * RETURNS: a symbolic string rep of the given GUID.
  213. * NOMANUAL
  214. */
  215. static const char * findGuid 
  216.     (
  217.     REFGUID  value /* GUID to find */
  218.     )
  219.     {
  220.     GUID_ELEM * pPtr = &(guidList [0]);
  221.     /* search list of well known GUIDS */
  222.     while (pPtr->pName)
  223. {
  224. if (value == *(pPtr->guid))
  225.     {
  226.     return pPtr->pName;
  227.     }
  228. pPtr++;
  229. }
  230.     /* Not in well known list so search the COMTRACK list */
  231.     const char * pStr = VxComTrack::theInstance ()->findGUID (value);
  232.     if (pStr)
  233. return pStr;
  234.     /* All else has failed, return the GUID as a string */
  235.     return vxcomGUID2String (value);
  236.     }
  237. /**************************************************************************
  238. *
  239. * updateCtxTable - Adds/updates a ip/port/ctx id to the table.
  240. *
  241. * This function adds an ip/port/ctx id to the table. The ip/port combination
  242. * is unique to a channel and the ctx id is unique to a channel.
  243. *
  244. * RETURNS: nothing.
  245. * NOMANUAL
  246. */
  247. static void updateCtxTable 
  248.     (
  249.     USHORT presCtxId,  /* context id */
  250.     GUID id,  /* GUID attached to ctx id */
  251.     const char * pChannelBinding /* ip/port combination */
  252.     )
  253.     {
  254.     string key;
  255.     key += pChannelBinding;
  256.     key += ":";
  257.     key += presCtxId;
  258.     ctxIdMap [key] = id;
  259.     }
  260. /**************************************************************************
  261. *
  262. * getFromCtxTable - get's the GUID from the map.
  263. *
  264. * This function retrieves a GUID from the map based on ip/port/ctx id. If 
  265. * the combination isn't present the string "UNKNOWN" is returned,
  266. * otherwise the output from findGUID is returned.
  267. *
  268. * RETURNS: The symbolic rep of the GUID or "UNKNOWN".
  269. * NOMANUAL
  270. */
  271. static const char * getFromCtxTable
  272.     (
  273.     USHORT presCtxId, /* Context id */
  274.     const char * pChannelBinding /* ip/port binding */
  275.     )
  276.     {
  277.     string key;
  278.     CTXID_MAP::iterator it;
  279.     key = pChannelBinding;
  280.     key += ":";
  281.     key += presCtxId;
  282.     it = ctxIdMap.find (key);
  283.     if (it == ctxIdMap.end ())
  284. {
  285. return "UNKNOWN";
  286. }
  287.     return findGuid (it->second);
  288.     }
  289. /* Output functions */
  290. /**************************************************************************
  291. *
  292. * indent - output the correct number of spaces to indent a line.
  293. *
  294. * Output the correct number of spaces to indent a line.
  295. *
  296. * RETURNS: None.
  297. * NOMANUAL
  298. */
  299. static void indent ()
  300.     {
  301.     int i;
  302.     for (i = 0; i < indentLevel; i++)
  303. {
  304. PRINT_STR(" ");
  305. }
  306.     }
  307. /**************************************************************************
  308. *
  309. * indent - increases the current indent level by four.
  310. *
  311. * Increases the current indent level by four.
  312. *
  313. * RETURNS: None.
  314. * NOMANUAL
  315. */
  316. static void padUp ()
  317.     {
  318.     indentLevel += 4;
  319.     }
  320. /**************************************************************************
  321. *
  322. * padDown - decreases the current indent level by four.
  323. *
  324. * Decreases the current indent level by four.
  325. *
  326. * RETURNS: None.
  327. * NOMANUAL
  328. */
  329. static void padDown ()
  330.     {
  331.     indentLevel -= 4;
  332.     if (indentLevel < 0)
  333. indentLevel = 0;
  334.     }
  335. /**************************************************************************
  336. *
  337. * output - output a string, with optional indent.
  338. *
  339. * This function output's a string. If the indentLine parameter is set the
  340. * current indent number of spaces are output.
  341. *
  342. * RETURNS: None.
  343. * NOMANUAL
  344. */
  345. static void output
  346.     (
  347.     const char *  pValue,  /* Data to output */
  348.     bool  indentLine = false /* Indent line or not */
  349.     )
  350.     {
  351.     if (indentLine)
  352. indent ();
  353.     PRINT_STR(pValue);
  354.     }
  355. /**************************************************************************
  356. *
  357. * output - output a BYTE, with optional indent.
  358. *
  359. * This function output's a BYTE. If the indentLine parameter is set the
  360. * current indent number of spaces are output.
  361. *
  362. * RETURNS: None.
  363. * NOMANUAL
  364. */
  365. static void output
  366.     (
  367.     const BYTE  value,  /* Data to output */
  368.     bool  indentLine = false /* Indent line or not */
  369.     )
  370.     {
  371.     char line [3];
  372.     if (indentLine)
  373. indent ();
  374.     sprintf (line, "%02X", ((int)value) & 0xFF);
  375.     PRINT_STR(line);
  376.     }
  377. /**************************************************************************
  378. *
  379. * output - output an array of BYTE, with optional indent.
  380. *
  381. * This function output's an array of BYTE. If the indentLine parameter is 
  382. * set the current indent number of spaces are output.
  383. *
  384. * RETURNS: None.
  385. * NOMANUAL
  386. */
  387. static void output
  388.     (
  389.     const BYTE  value [],  /* Data to output */
  390.     int  length,  /* Number of elements */
  391.     bool  indentLine = false /* Indent line or not */
  392.     )
  393.     {
  394.     int i;
  395.     if (indentLine)
  396. indent ();
  397.     for (i = 0; i < length; i++)
  398. output (value [i]);
  399.     }
  400. /**************************************************************************
  401. *
  402. * output - output a USHORT, with optional indent.
  403. *
  404. * This function output's a USHORT. If the indentLine parameter is set the
  405. * current indent number of spaces are output.
  406. *
  407. * RETURNS: None.
  408. * NOMANUAL
  409. */
  410. static void output
  411.     (
  412.     const USHORT  value,  /* Data to output */
  413.     bool  indentLine = false /* Indent line or not */
  414.     )
  415.     {
  416.     char line [5];
  417.     if (indentLine)
  418. indent ();
  419.     sprintf (line, "%04X", ((int)value) & 0xFFFF);
  420.     PRINT_STR(line);
  421.     }
  422. /**************************************************************************
  423. *
  424. * output - output a ULONG, with optional indent.
  425. *
  426. * This function output's a ULONG. If the indentLine parameter is set the
  427. * current indent number of spaces are output.
  428. *
  429. * RETURNS: None.
  430. * NOMANUAL
  431. */
  432. static void output
  433.     (
  434.     const ULONG  value,  /* Data to output */
  435.     bool  indentLine = false /* Indent line or not */
  436.     )
  437.     {
  438.     char line [9];
  439.     if (indentLine)
  440. indent ();
  441.     sprintf (line, "%08lX", value);
  442.     PRINT_STR(line);
  443.     }
  444. /**************************************************************************
  445. *
  446. * output - output an end of line.
  447. *
  448. * Output's an end of line character.
  449. *
  450. * RETURNS: None.
  451. * NOMANUAL
  452. */
  453. static void endOfLine ()
  454.     {
  455.     PRINT_STR ("n");
  456.     }
  457. /**************************************************************************
  458. *
  459. * output - output a space.
  460. *
  461. * Output's a space.
  462. *
  463. * RETURNS: None.
  464. * NOMANUAL
  465. */
  466. static void outputSpace ()
  467.     {
  468.     PRINT_STR (" ");
  469.     }
  470. /**************************************************************************
  471. *
  472. * output - output a dash.
  473. *
  474. * Output's a dash.
  475. *
  476. * RETURNS: None.
  477. * NOMANUAL
  478. */
  479. static void outputDash ()
  480.     {
  481.     PRINT_STR ("-");
  482.     }
  483. /* Utility class to display and indent a field name */
  484. class RpcName
  485.     {
  486.     public:
  487. /*****************************************************************
  488. *
  489. * RpcName::RpcName - Constructor.
  490. *
  491. * Output's the given name and indents if required.
  492. *
  493. * RETURNS: None.
  494. * NOMANUAL
  495. */
  496. RpcName
  497.     (
  498.     const char * pName,  /* Field name */
  499.     bool  indent = false /* Indent this name? */
  500.     )
  501.     {
  502.     output (pName, true);
  503.     output (":", false);
  504.     if (indent)
  505. padUp ();
  506.     }
  507. /*****************************************************************
  508. *
  509. * RpcName::RpcName - dummy.
  510. *
  511. * Dummy function that is used to get rid of a compiler warning.
  512. *
  513. * RETURNS: None.
  514. * NOMANUAL
  515. */
  516. void dummy () {}
  517.     };
  518. /*
  519. Utility class to display and indent a field name. The indentation is 
  520. removed by the destructor
  521. */
  522.    
  523. class RpcIndentBlock : RpcName
  524.     {
  525.     public:
  526. /*****************************************************************
  527. *
  528. * RpcIndentBlock::RpcIndentBlock - Constructor.
  529. *
  530. * Output's the given name and indents it.
  531. *
  532. * RETURNS: None.
  533. * NOMANUAL
  534. */
  535. RpcIndentBlock (const char * pName) : 
  536.     RpcName (pName, true)
  537.     {
  538.     endOfLine ();
  539.     }
  540. /*****************************************************************
  541. *
  542. * RpcIndentBlock::~RpcIndentBlock - Destructor.
  543. *
  544. * Removes the indentation that the constructor applied.
  545. *
  546. * RETURNS: None.
  547. * NOMANUAL
  548. */
  549. ~RpcIndentBlock ()
  550.     {
  551.     padDown ();
  552.     }
  553.     };
  554. /* DCE packet classes */
  555. /*
  556. These classes all have one method called Read which decodes a part of the
  557. packet. 
  558. */
  559. class RpcGUID 
  560.     {
  561.     public:
  562.     const GUID * Read (const char * pName)
  563. {
  564. static GUID value;
  565. value.Data1 = *(DWORD *)ReadBytes (sizeof(DWORD));
  566. value.Data2 = *(USHORT *)ReadBytes (sizeof (USHORT));
  567. value.Data3 = *(USHORT *)ReadBytes (sizeof (USHORT));
  568. memcpy (value.Data4, ReadBytes (8), 8);
  569. FIELD(pName, findGuid (value));
  570. endOfLine ();
  571. return &value;
  572. }
  573.     COMMON_VIRTUALS();
  574.     };
  575. class RpcCnPresSyntaxId : RpcGUID
  576.     {
  577.     public:
  578.     const rpc_cn_pres_syntax_id_t * Read (const char * pName)
  579. {
  580. static rpc_cn_pres_syntax_id_t value;
  581. NAME(pName);
  582. value.id = *RpcGUID::Read ("id");
  583. value.version = ReadULONG ("version");
  584. return &value;
  585. }
  586.     COMMON_VIRTUALS();
  587.     };
  588. class RpcCnPresCtxElem : RpcCnPresSyntaxId
  589.     {
  590.     public:
  591.     void Read (const char * pName)
  592. {
  593. NAME(pName);
  594. BYTE i;
  595. USHORT presCtxId = ReadUSHORT ("presCtxId");
  596.      BYTE count = ReadBYTE ("nTransferSyntaxes");
  597. ReadBYTE ("reserved");
  598. updateCtxTable (presCtxId, 
  599.         RpcCnPresSyntaxId::Read("abstractSyntax")->id,
  600.         getChannelBinding ());
  601. for (i = 0; i < count; i++)
  602.         {
  603. char line [25];
  604. sprintf (line, "transferSyntax [%d]", i);
  605.      RpcCnPresSyntaxId::Read (line);
  606. }
  607.      }
  608.     COMMON_VIRTUALS();
  609.     };
  610. class RpcCnPresCtxList : RpcCnPresCtxElem
  611.     {
  612.     public:
  613.     void Read (const char * pName)
  614. {
  615. NAME(pName);
  616. BYTE i;
  617.      BYTE count = ReadBYTE ("numCtxElems");
  618. ReadBYTE ("reserved");
  619. ReadUSHORT ("reserved2");
  620. for (i = 0; i < count; i++)
  621.     RpcCnPresCtxElem::Read ("presCtxElem [1]");
  622.      }
  623.     COMMON_VIRTUALS();
  624.     };
  625. class RpcCnBindHdr : RpcCnPresCtxList
  626.     {
  627.     public:
  628.     void Read (const char * pName)
  629. {
  630. NAME(pName);
  631. ReadUSHORT ("maxTxFrag");
  632. ReadUSHORT ("maxRxFrag");
  633. ReadULONG  ("assocGroupId");
  634. RpcCnPresCtxList::Read ("presCtxList");
  635.      };
  636.     COMMON_VIRTUALS();
  637.     };
  638. class RpcCnPresCtxId
  639.     {
  640.     public:
  641.     USHORT Read (const char * pName)
  642. {
  643.      USHORT presCtxId = ReadUSHORT (pName, true, NULL, false);
  644. output (" - ");
  645. output (getFromCtxTable (presCtxId, getChannelBinding ()));
  646. endOfLine ();
  647. return presCtxId;
  648. }
  649.     COMMON_VIRTUALS ();
  650.     };
  651. class RpcCnResponseHdr : RpcCnPresCtxId
  652.     {
  653.     public:
  654.     void Read (const char * pName)
  655. {
  656. NAME(pName);
  657.      ReadULONG ("allocHint");
  658. RpcCnPresCtxId::Read ("presCtxId");
  659.      ReadBYTE ("alertCount");
  660.      ReadBYTE ("reserved");
  661. }
  662.     COMMON_VIRTUALS();
  663.     };
  664. class RpcCnRequestHdr : RpcGUID, RpcCnPresCtxId
  665.     {
  666.     public:
  667.     void Read (const char * pName)
  668. {
  669. NAME(pName);
  670.      ReadULONG ("allocHint");
  671. RpcCnPresCtxId::Read ("presCtxId");
  672. ReadUSHORT ("methodNum");
  673. if (getFlags () & RPC_CN_FLAGS_OBJECT_UUID)
  674.     {
  675.     RpcGUID::Read ("objectId");
  676.     }
  677. }
  678.     COMMON_VIRTUALS();
  679.     };
  680. class RpcCnPortAny
  681.     {
  682.     public:
  683.     void Read (const char * pName)
  684. {
  685. NAME(pName);
  686.      ReadUSHORT ("len");
  687.      ReadARRAY ("addr", 6);
  688. }
  689.     COMMON_VIRTUALS();
  690.     };
  691. class  RpcCnPresResult : RpcCnPresSyntaxId
  692.     {
  693.     public:
  694.     void Read (const char * pName)
  695. {
  696. NAME(pName);
  697.      ReadUSHORT ("result");
  698.      ReadUSHORT ("reason");
  699. RpcCnPresSyntaxId::Read ("transferSyntax");
  700. }
  701.     COMMON_VIRTUALS();
  702.     };
  703. class RpcCnPresResultList : RpcCnPresResult
  704.     {
  705.     public:
  706.     void Read (const char * pName)
  707. {
  708. NAME(pName);
  709. BYTE  i;
  710.      BYTE  numResults = ReadBYTE ("numResults");
  711.         ReadBYTE ("reserved");
  712.      ReadUSHORT ("reserved2");
  713. for (i = 0; i < numResults; i++)
  714.     {
  715.     char line [20];
  716.     sprintf (line, "presResult [%d]", i);
  717.     RpcCnPresResult::Read (line);
  718.     }
  719. }
  720.     COMMON_VIRTUALS();
  721.     };
  722. class  RpcCnBindAckHdr : RpcCnPortAny, RpcCnPresResultList
  723.     {
  724.     public:
  725.     void Read (const char * pName)
  726. {
  727. NAME(pName);
  728. ReadUSHORT ("maxTxFrag");
  729. ReadUSHORT ("maxRxFrag");
  730. ReadULONG ("assocGroupId");
  731. RpcCnPortAny::Read ("secAddr");
  732. RpcCnPresResultList::Read ("resultList");
  733. }
  734.     COMMON_VIRTUALS();
  735.     };
  736. class  RpcCnAlterContextRespHdr : RpcCnPresResultList
  737.     {
  738.     public:
  739.     void Read (const char * pName)
  740. {
  741. NAME(pName);
  742.      ReadUSHORT ("maxTxFrag");
  743.      ReadUSHORT ("maxRxFrag");
  744.      ReadULONG  ("assocGroupId");
  745.      ReadUSHORT ("secAddr");
  746.      ReadUSHORT ("pad");
  747. RpcCnPresResultList::Read ("resultList");
  748. }
  749.     COMMON_VIRTUALS();
  750.     };
  751. class RpcCnFaultHdr : RpcCnPresCtxId
  752.     {
  753.     public:
  754.     void Read (const char * pName)
  755. {
  756. NAME(pName);
  757. ReadULONG ("allocHint");
  758. RpcCnPresCtxId::Read ("presCtxId");
  759. ReadBYTE ("alertCount");
  760. ReadBYTE ("reserved");
  761. ReadULONG ("status");
  762. ReadULONG ("reserved2");
  763. }
  764.     COMMON_VIRTUALS ();
  765.     };
  766. class RpcCnBindNakHdr
  767.     {
  768.     public:
  769.     void Read (const char * pName)
  770. {
  771. NAME(pName);
  772. ReadUSHORT ("reason");
  773. ReadBYTE ("numProtocols");
  774. ReadBYTE ("verMajor");
  775. ReadBYTE ("verMinor");
  776. }
  777.     COMMON_VIRTUALS ();
  778.     };
  779. class RpcCnAuth3Hdr
  780.     {
  781.     public:
  782.     void Read (const char * pName)
  783. {
  784.         ReadUSHORT ("maxTxFrag");
  785. ReadUSHORT ("maxRxFrag");
  786. }
  787.     COMMON_VIRTUALS ();
  788.     };
  789. class RpcCnBody
  790.     {
  791.     public:
  792.     void Read (const char * pName)
  793. {
  794. NAME(pName);
  795. BYTE * pBlock;
  796. DWORD remain;
  797. while ((remain = BytesRemaining ()) > 0)
  798.     {
  799.     DWORD blockSize = (remain < BLOCK_SIZE)?remain:BLOCK_SIZE;
  800.     DWORD i;
  801.     pBlock = ReadBytes (blockSize, false);
  802.     /* Dump out numeric */
  803.     output (pBlock [0], true);
  804.     outputSpace ();
  805.     for (i = 1; i < blockSize; i++)
  806. {
  807. output (pBlock [i]);
  808. outputSpace ();
  809. }
  810.     if (blockSize < BLOCK_SIZE)
  811. for (i = blockSize; i < BLOCK_SIZE; i++)
  812.     output ("   ");
  813.     /* Dump out text */
  814.     output ("t");
  815.     for (i = 0; i < blockSize; i++)
  816. {
  817. if (isprint (pBlock [i]))
  818.     {
  819.     char line [2];
  820.     sprintf (line, "%c", pBlock [i]);
  821.     PRINT_STR(line);
  822.     }
  823. else
  824.     output (".");
  825. }
  826.     endOfLine ();
  827.     }
  828. endOfLine ();
  829. }
  830.     COMMON_VIRTUALS ();
  831.     private:
  832.      enum {BLOCK_SIZE = 16};
  833.     };
  834. class RpcCnCommonHdr : 
  835. RpcCnBindHdr, 
  836. RpcCnBindAckHdr, 
  837. RpcCnAlterContextRespHdr, 
  838. RpcCnRequestHdr, 
  839. RpcCnResponseHdr,
  840. RpcCnFaultHdr,
  841. RpcCnBindNakHdr,
  842. RpcCnAuth3Hdr,
  843. RpcCnBody
  844.     {
  845.     public:
  846.     void Read (const char * pName)
  847. {
  848. NAME(pName);
  849. BYTE type;
  850. /* Decode common header */
  851. ReadBYTE ("rpcVersion");
  852. ReadBYTE ("rpcMinorVersion");
  853.      type = ReadBYTE ("packetType", rpcCnTypesTable);
  854. setFlags(ReadBYTE ("flags"));
  855. ReadARRAY ("drep", 4);
  856. ReadUSHORT ("fragLen");
  857. ReadUSHORT ("authLen");
  858. ReadULONG ("callId");
  859. /* Decode type header */
  860. switch (type)
  861.     {
  862.     case RPC_CN_PKT_REQUEST:
  863. RpcCnRequestHdr::Read("request");
  864. break;
  865.     case RPC_CN_PKT_RESPONSE:
  866. RpcCnResponseHdr::Read("response");
  867. break;
  868.     case RPC_CN_PKT_FAULT:
  869. RpcCnFaultHdr::Read ("fault");
  870. break;
  871.     case RPC_CN_PKT_BIND:
  872. RpcCnBindHdr::Read ("bind");
  873. break;
  874.     case RPC_CN_PKT_BIND_ACK:
  875. RpcCnBindAckHdr::Read ("bind ack");
  876. break;
  877.     case RPC_CN_PKT_BIND_NAK:
  878. RpcCnBindNakHdr::Read ("bind nak");
  879. break;
  880.     case RPC_CN_PKT_ALTER_CONTEXT:
  881. RpcCnBindHdr::Read ("alter context");
  882. break;
  883.     case RPC_CN_PKT_ALTER_CONTEXT_RESP:
  884. RpcCnAlterContextRespHdr::Read ("alter context resp");
  885. break;
  886.     case RPC_CN_PKT_AUTH3:
  887. RpcCnAuth3Hdr::Read ("auth3");
  888. break;
  889.     case RPC_CN_PKT_SHUTDOWN:
  890.     case RPC_CN_PKT_REMOTE_ALERT:
  891.     case RPC_CN_PKT_ORPHANED:
  892.     default:
  893. /* no body to these packets, just a common hdr */
  894. break;
  895.     }
  896. /* Dump out remaining data */
  897. RpcCnBody::Read ("body");
  898. }
  899.     COMMON_VIRTUALS();
  900.     };
  901. /* Class to encapsulate the data packet */
  902. class DataPacket : RpcCnCommonHdr
  903.     {
  904.     public:
  905.     /*************************************************************************
  906.     *
  907.     * DataPacket::DataPacket - Constructor
  908.     *
  909.     * This constructor initializes the class, works out the endianess of the 
  910.     * target for byte swapping and stores a copy of the data buffer.
  911.     *
  912.     * RETURNS: None.
  913.     * NOMANUAL
  914.     */
  915.     DataPacket 
  916. (
  917. const BYTE *  pData,  /* The packet */
  918. DWORD  length,  /* The length of the packet */
  919. const char *  pHost,  /* The ip address of the end point */
  920. int  hostPort,  /* The port on the target */
  921. int peerPort, /* The port on the end point */
  922. bool outbound /* Direction of connection, */
  923. /* true is outbound */
  924. ) : m_hostPort (hostPort),
  925.             m_peerPort (peerPort),
  926.     m_outbound (outbound),
  927.     m_pResult (0),
  928.     m_pBinding (0)
  929.         {
  930. /* Work out byte swap order */
  931. USHORT testOrder = 0x1234;
  932. BYTE * pTestOrder = (BYTE *)(&testOrder);
  933.         if (*pTestOrder == 0x12)
  934.     {
  935.     m_byteSwap = true;
  936.     }
  937. else
  938.     {
  939.     m_byteSwap = false;
  940.     }
  941. /* Store data and work out the end of the buffer */
  942. m_pData = pData;
  943. m_pEnd = const_cast<BYTE *>(m_pData) + length;
  944. m_pHost = new char [strlen (pHost) + 1];
  945. strcpy (m_pHost, pHost);
  946. }
  947.     /*************************************************************************
  948.     *
  949.     * DataPacket::~DataPacket - Destructor
  950.     *
  951.     * Deletes any temp buffers
  952.     *
  953.     * RETURNS: None.
  954.     * NOMANUAL
  955.     */
  956.     virtual ~DataPacket ()
  957.         {
  958. /* Clean up any allocated temp buffer */
  959. if (m_pResult)
  960.     {
  961.     delete [] m_pResult;
  962.     m_pResult = NULL;
  963.     }
  964. if (m_pBinding)
  965.     {
  966.     delete [] m_pBinding;
  967.     m_pBinding = NULL;
  968.     }
  969. delete [] m_pHost;
  970. }
  971.     /*************************************************************************
  972.     *
  973.     * DataPacket::Read - Starts decode of the packet.
  974.     *
  975.     * This method starts the decode of the packet. It actually just starts a 
  976.     * new line and then passes the rest of the job to the common header class.
  977.     *
  978.     * RETURNS: None.
  979.     * NOMANUAL
  980.     */
  981.     void Read 
  982. (
  983. const char *  pName /* Name to print out  for this step */
  984. )
  985. {
  986. endOfLine ();
  987. RpcCnCommonHdr::Read (pName);
  988. }
  989.     /**************************************************************************
  990.     *
  991.     * DataPacket::getDesc - Returns the binding ip/port binding for this
  992.     * packet.
  993.     *
  994.     * This method gives a channel binding as a string containing ip and port
  995.     * addresses. For outbound bindings it is of the format:
  996.     *     ip:host port:peer port
  997.     * and for inbound transactions it is of the form:
  998.     *     ip:peer port:host port
  999.     *
  1000.     * RETURNS: The ip/port binding for the packet as a string.
  1001.     * NOMANUAL
  1002.     */
  1003.     const char * getDesc ()
  1004. {
  1005. if (m_pBinding)
  1006.     {
  1007.     delete [] m_pBinding;
  1008.     m_pBinding = NULL;
  1009.     }
  1010. m_pBinding = new char [strlen (m_pHost) + 50];
  1011. if (m_outbound)
  1012.     {
  1013.     sprintf (m_pBinding,
  1014.     "From target port %d to %s port %d",
  1015.     m_hostPort, m_pHost, m_peerPort);
  1016.     }
  1017. else
  1018.     {
  1019.     sprintf (m_pBinding,
  1020.     "From %s port %d to target port %d",
  1021.     m_pHost, m_peerPort, m_hostPort);
  1022.     }
  1023. return m_pBinding;
  1024. }
  1025.     /*************************************************************************
  1026.     *
  1027.     * DataPacket::getChannelBinding - Returns the binding ip/port binding for 
  1028.     * this packet.
  1029.     *
  1030.     * This method gives a channel binding as a string containing ip and port
  1031.     * addresses. It is always of the form:
  1032.     *     ip:host port:peer port
  1033.     * so that easy string comps can be done. It is virtual so that the base 
  1034.     * classes can access it.
  1035.     *
  1036.     * RETURNS: The ip/port binding for the packet as a string.
  1037.     * NOMANUAL
  1038.     */
  1039.     virtual const char * getChannelBinding ()
  1040. {
  1041. if (m_pBinding)
  1042.     {
  1043.     delete [] m_pBinding;
  1044.     m_pBinding = NULL;
  1045.     }
  1046. m_pBinding = new char [strlen (m_pHost) + 32];
  1047. sprintf (m_pBinding, "%s:%d:%d", m_pHost, m_hostPort, m_peerPort);
  1048. return m_pBinding;
  1049. }
  1050.     /*************************************************************************
  1051.     *
  1052.     * DataPacket::getFlags - Return the stored flags BYTE.
  1053.     *
  1054.     * Return the stored flags BYTE.
  1055.     *
  1056.     * RETURNS: The DCE header flags byte.
  1057.     * NOMANUAL
  1058.     */
  1059.     BYTE getFlags ()
  1060. {
  1061. return m_DceFlags;
  1062. }
  1063.     /*************************************************************************
  1064.     *
  1065.     * DataPacket::setFlags - Set the stored flags BYTE.
  1066.     *
  1067.     * Set the stored flags BYTE.
  1068.     *
  1069.     * RETURNS: Nothing.
  1070.     * NOMANUAL
  1071.     */
  1072.     void setFlags (const BYTE flags)
  1073. {
  1074. m_DceFlags = flags;
  1075. }
  1076.     private:
  1077.     /*************************************************************************
  1078.     *
  1079.     * DataPacket::ReadBYTE - Read a BYTE from the packet.
  1080.     *
  1081.     * This method reads a BYTE from the packet and advances the current byte
  1082.     * pointer by one BYTE. The value is also displayed. If a decode table is 
  1083.     * given the value is matched against the table and the symbolic value is
  1084.     * displayed.
  1085.     *
  1086.     * RETURNS: The value read from the packet.
  1087.     * NOMANUAL
  1088.     */
  1089.     virtual BYTE ReadBYTE
  1090.         (
  1091. const char * pName,  /* The field name to */
  1092. /* display */
  1093. TABLE * pDecodeTable = NULL /* The decode table, */
  1094. /* or NULL for none. */
  1095. )
  1096. {
  1097. BYTE * pValue = ReadBytes (sizeof (BYTE));
  1098. FIELD(pName, *pValue);
  1099. if (pDecodeTable)
  1100.     {
  1101.     outputSpace ();
  1102.     outputDash ();
  1103.     outputSpace ();
  1104.     output (DecodeFromTable ((ULONG)(*pValue), pDecodeTable));
  1105.     }
  1106. endOfLine ();
  1107. return *pValue;
  1108. }
  1109.     /*************************************************************************
  1110.     *
  1111.     * DataPacket::ReadARRAY - Read an array of BYTE from the packet.
  1112.     *
  1113.     * This method reads an array of BYTE from the packet and advances the 
  1114.     * current byte pointer by the length of the read array. The data is also 
  1115.     * displayed.
  1116.     *
  1117.     * RETURNS: Nothing.
  1118.     * NOMANUAL
  1119.     */
  1120.     virtual void ReadARRAY
  1121.         (
  1122. const char *  pName,  /* The field name to display */
  1123. ULONG  number /* The number of BYTEs to read. */
  1124. )
  1125. {
  1126. ULONG count;
  1127. BYTE * pValue = ReadBytes (number, false);
  1128. FIELD(pName, "");
  1129. for (count = 0; count < number; count++)
  1130.     {
  1131.     outputSpace ();
  1132.     output (pValue [count]);
  1133.     }
  1134. endOfLine ();
  1135. }
  1136.     /*************************************************************************
  1137.     *
  1138.     * DataPacket::ReadUSHORT - Read a USHORT from the packet.
  1139.     *
  1140.     * This method reads a USHORT from the packet and advances the current byte
  1141.     * pointer by one USHORT. The value is also displayed. If a decode table 
  1142.     * is given the value is matched against the table and the symbolic value
  1143.     * is displayed. The data is correctly byte swapped if required and an EOL
  1144.     * is emited if required.
  1145.     *
  1146.     * RETURNS: The value read from the packet.
  1147.     * NOMANUAL
  1148.     */
  1149.     virtual USHORT ReadUSHORT
  1150. (
  1151. const char * pName,  /* Name of the field */
  1152. bool swap = true,  /* If true swap data */
  1153. TABLE * pDecodeTable = NULL, /* Pointer to the decode */
  1154. /* table, or NULL for none */
  1155. bool doEndOfLine = true /* If false emit and EOL */
  1156. )
  1157. {
  1158. USHORT * pValue = (USHORT *)ReadBytes (sizeof (USHORT), swap);
  1159. FIELD(pName, *pValue);
  1160. if (pDecodeTable)
  1161.     {
  1162.     outputSpace ();
  1163.     outputDash ();
  1164.     outputSpace ();
  1165.     output (DecodeFromTable ((ULONG)(*pValue), pDecodeTable));
  1166.     }
  1167. if (doEndOfLine)
  1168.     endOfLine ();
  1169. return *pValue;
  1170. }
  1171.     /**************************************************************************
  1172.     *
  1173.     * DataPacket::ReadULONG - Read a ULONG from the packet.
  1174.     *
  1175.     * This method reads a ULONG from the packet and advances the current byte
  1176.     * pointer by one ULONG. The value is also displayed. If a decode table is 
  1177.     * given the value is matched against the table and the symbolic value is
  1178.     * displayed. The data is correctly byte swapped if required.
  1179.     *
  1180.     * RETURNS: The value read from the packet.
  1181.     * NOMANUAL
  1182.     */
  1183.     virtual ULONG ReadULONG
  1184. (
  1185. const char *  pName,  /* Name of the field */
  1186. bool  swap = true,  /* If PURE swap data */
  1187. TABLE *  pDecodeTable = NULL /* Pointer to the decode */
  1188. /* table, or NULL for none */
  1189. )
  1190. {
  1191. ULONG * pValue = (ULONG *)ReadBytes (sizeof (ULONG), swap);
  1192. FIELD(pName, *pValue);
  1193. if (pDecodeTable)
  1194.     {
  1195.     outputSpace ();
  1196.     outputDash ();
  1197.     outputSpace ();
  1198.     output (DecodeFromTable (*pValue, pDecodeTable));
  1199.     }
  1200. endOfLine ();
  1201. return *pValue;
  1202. }
  1203.     /**************************************************************************
  1204.     *
  1205.     * DataPacket::ReadBytes - Reads n bytes from the packet
  1206.     *
  1207.     * Reads n bytes from the packet and performs byte swamping if swap is set 
  1208.     * to true. If all data has been read 0x00 bytes are returned in the buffer.
  1209.     *
  1210.     * RETURNS: A pointer to a temp buffer containing the formated bytes.
  1211.     * NOMANUAL
  1212.     */
  1213.     virtual BYTE * ReadBytes
  1214.      (
  1215. DWORD number,  /* Number of BYTEs to read */
  1216. bool  swap = true /* Swap bytes if true. */
  1217. )
  1218.         {
  1219. if (m_pResult)
  1220.     {
  1221.     delete [] m_pResult;
  1222.     m_pResult = NULL;
  1223.     }
  1224. m_pResult = new BYTE [number];
  1225. COM_ASSERT (m_pResult != NULL);
  1226. memset (m_pResult, 0x00, number);
  1227. BYTE * ptr;
  1228. DWORD count;
  1229. /* since we're copying data we can swap data 'in-place',    */
  1230. /* so we may need to start filling in the buffer at the end */
  1231. if (m_byteSwap && swap)
  1232.     {
  1233.     ptr = m_pResult + number - 1;
  1234.     }
  1235. else
  1236.     {
  1237.     ptr = m_pResult;
  1238.     }
  1239.         for (count = 0; count < number; count++)
  1240.     {
  1241.     if (m_pData < m_pEnd)
  1242. {
  1243. *ptr = *m_pData;
  1244. m_pData++;
  1245. /* increment/decrement count depending on swap order */
  1246. /* and whether we want to swap. */
  1247. if (m_byteSwap && swap)
  1248.     {
  1249.     ptr--;
  1250.     }
  1251. else
  1252.     {
  1253.     ptr++;
  1254.     }
  1255. }
  1256.     else
  1257. {
  1258. return m_pResult;
  1259. }
  1260.     }
  1261. return m_pResult;
  1262. }
  1263.     /**************************************************************************
  1264.     *
  1265.     * DataPacket::BytesRemaining - Number of BYTEs unread in buffer.
  1266.     *
  1267.     * Returns number of unread BYTEs in the buffer.
  1268.     *
  1269.     * RETURNS: Bytes remaining.
  1270.     * NOMANUAL
  1271.     */
  1272.     virtual DWORD BytesRemaining ()
  1273. {
  1274. return m_pEnd - m_pData;
  1275. }
  1276.     /**************************************************************************
  1277.     *
  1278.     * DataPacket::DecodeFromTable - Converts a numeric value to a string via
  1279.     * a table.
  1280.     *
  1281.     * Converts a numeric value to a string via a lookup table. If the value 
  1282.     * doesn't exist in the table "Unknown Value" is returned.
  1283.     *
  1284.     * RETURNS: The string contained in the lookup table or "Unknown Value" 
  1285.     * if not found.
  1286.     * NOMANUAL
  1287.     */
  1288.     const char * DecodeFromTable
  1289.      (
  1290. ULONG  value,  /* Value to decode */
  1291. TABLE *  pDecodeTable /* Decode table */
  1292. )
  1293. {
  1294. TABLE * ptr = pDecodeTable;
  1295. while (ptr->m_name)
  1296.     {
  1297.     if (ptr->m_value == value)
  1298. {
  1299. return ptr->m_name;
  1300. }
  1301.     ptr++;
  1302.     }
  1303. return "Unknown value";
  1304. }
  1305.     const BYTE * m_pData;
  1306.     BYTE * m_pEnd;
  1307.     bool m_byteSwap;
  1308.     BYTE m_DceFlags;
  1309.     char * m_pHost;
  1310.     int m_hostPort;
  1311.     int m_peerPort;
  1312.     bool m_outbound;
  1313.     BYTE * m_pResult;
  1314.     char * m_pBinding;
  1315.     };
  1316. /**************************************************************************
  1317. *
  1318. * dcomShowClientOutput - Processes packet sent from a client object to
  1319. * a server.
  1320. *
  1321. * Processes an outbound packet from a client object.
  1322. *
  1323. * RETURNS: Nothing.
  1324. * NOMANUAL
  1325. */
  1326. extern "C" void dcomShowClientOutput
  1327.     (
  1328.     const BYTE *  pPacket,  /* Packet to be sent */
  1329.     DWORD  length,  /* Length of packet */
  1330.     const char *  pHost,  /* Hostname */
  1331.     int hostPort, /* Host endpoint */
  1332.     int peerPort /* Peer endpoint */
  1333.     )
  1334.     {
  1335.     VxCritSec exclude (s_mutex);
  1336.     DataPacket data(pPacket, length, pHost, hostPort, peerPort, true);
  1337.     data.Read (data.getDesc ());
  1338.     }
  1339. /**************************************************************************
  1340. *
  1341. * dcomShowClientInput - Processes packet sent to a client object from a
  1342. * server object.
  1343. *
  1344. * Processes an inbound packet to a client object.
  1345. *
  1346. * RETURNS: Nothing.
  1347. * NOMANUAL
  1348. */
  1349. extern "C" void dcomShowClientInput
  1350.     (
  1351.     const BYTE *  pPacket,  /* Packet to be sent */
  1352.     DWORD  length,  /* Length of packet */
  1353.     const char *  pHost,  /* Hostname */
  1354.     int hostPort, /* Host endpoint */
  1355.     int peerPort /* Peer endpoint */
  1356.     )
  1357.     {
  1358.     VxCritSec exclude (s_mutex);
  1359.     DataPacket data(pPacket, length, pHost, hostPort, peerPort, false);
  1360.     data.Read (data.getDesc ());
  1361.     }
  1362. /**************************************************************************
  1363. *
  1364. * dcomShowServerOutput - Processes packet sent from a server object to a
  1365. * client object.
  1366. *
  1367. * Processes an outbound packet from a server object.
  1368. *
  1369. * RETURNS: Nothing.
  1370. * NOMANUAL
  1371. */
  1372. extern "C" void dcomShowServerOutput
  1373.     (
  1374.     const BYTE *  pPacket,  /* Packet to be sent */
  1375.     DWORD  length,  /* Length of packet */
  1376.     const char *  pHost,  /* Hostname */
  1377.     int hostPort, /* Host endpoint */
  1378.     int peerPort /* Peer endpoint */
  1379.     )
  1380.     { 
  1381.     VxCritSec exclude (s_mutex);
  1382.     DataPacket data(pPacket, length, pHost, hostPort, peerPort, true);
  1383.     data.Read (data.getDesc ());
  1384.     }
  1385. /**************************************************************************
  1386. *
  1387. * dcomShowServerInput - Processes packet sent to a server object.
  1388. *
  1389. * Processes an inbound packet from a server object.
  1390. *
  1391. * RETURNS: Nothing.
  1392. * NOMANUAL
  1393. */
  1394. extern "C" void dcomShowServerInput
  1395.     (
  1396.     const BYTE *  pPacket,  /* Packet to be sent */
  1397.     DWORD  length,  /* Length of packet */
  1398.     const char *  pHost,  /* Hostname */
  1399.     int hostPort, /* Host endpoint */
  1400.     int peerPort /* Peer endpoint */
  1401.     )
  1402.     {
  1403.     VxCritSec exclude (s_mutex);
  1404.     DataPacket data(pPacket, length, pHost, hostPort, peerPort, false);
  1405.     data.Read (data.getDesc ());
  1406.     }
  1407. /**************************************************************************
  1408. *
  1409. * listenerTask - task that listens for network connections
  1410. *
  1411. * Task that listens for network connections. If a socket is successfully
  1412. * established the appropriate debug hook is initialized.
  1413. *
  1414. * RETURNS: Nothing.
  1415. * NOMANUAL
  1416. */
  1417. extern "C" void listenerTask
  1418.     (
  1419.     int arg1,
  1420.     int arg2,
  1421.     int arg3,
  1422.     int arg4,
  1423.     int arg5,
  1424.     int arg6,
  1425.     int arg7,
  1426.     int arg8,
  1427.     int arg9,
  1428.     int arg10
  1429.     )
  1430.     {
  1431. #ifdef VXDCOM_PLATFORM_VXWORKS
  1432.     int fromLen;
  1433. #else
  1434.     socklen_t fromLen;
  1435. #endif
  1436.     int s;
  1437.     int ns;
  1438.     struct sockaddr_in s_addr;
  1439.     PRINT_STR("DCOM_SHOW setting up socketn");
  1440.     if ((s = ::socket(PF_INET, SOCK_STREAM, 0)) < 0)
  1441. {
  1442. PRINT_STR("DCOM_SHOW can't open a socketn");
  1443.         return;
  1444. }
  1445.     s_addr.sin_family = AF_INET;
  1446.     s_addr.sin_port = htons(s_listenPort);
  1447.     s_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  1448.     PRINT_STR("DCOM_SHOW binding socket to portn");
  1449.     if (bind(s, (struct sockaddr *)(&s_addr), sizeof (s_addr)) < 0)
  1450. {
  1451. PRINT_STR("DCOM_SHOW can't bind to specified portn");
  1452. close (s);
  1453. return;
  1454. }
  1455.     
  1456.     PRINT_STR("DCOM_SHOW listening for a connectionn");
  1457.     if (listen(s, 5) < 0)
  1458. {
  1459.         PRINT_STR("DCOM_SHOW can't listen on specified portn");
  1460. close (s);
  1461. return;
  1462. }
  1463.     fromLen = sizeof (s_addr);
  1464.     if ((ns = accept(s, (struct sockaddr *)(&s_addr), &fromLen)) < 0)
  1465. {
  1466. PRINT_STR("DCOM_SHOW has dropped out of accept without connectingn");
  1467. close (s);
  1468. startListenerTask ();
  1469. return;
  1470. }
  1471.     close(s);
  1472.     s_outputSocket = ns;
  1473.     PRINT_STR("DCOM_SHOW has set up a connectionn");
  1474.     SETDEBUGHOOK(pDcomShowPrintStr, networkPrint);
  1475.     }
  1476. /**************************************************************************
  1477. *
  1478. * networkPrint - output a string to a socket
  1479. *
  1480. * Output's a string to a network socket. If an error occurs it is assumed
  1481. * that the socket has been closed by the client and so a new connection
  1482. * listener is started.
  1483. *
  1484. * RETURNS: Nothing.
  1485. * NOMANUAL
  1486. */
  1487. extern "C" void networkPrint (const char * str)
  1488.     {
  1489.     if (write (s_outputSocket, const_cast<char *>(str), strlen (str)) < 0)
  1490. {
  1491. CLEARDEBUGHOOK(pDcomShowPrintStr);
  1492. close (s_outputSocket);
  1493. s_outputSocket = 0;
  1494. PRINT_STR(str);
  1495. PRINT_STR("DCOM_SHOW has disconnected from output clientn");
  1496. startListenerTask ();
  1497. }
  1498.     }
  1499. /**************************************************************************
  1500. *
  1501. * startListenerTask - starts the task to listen for connections
  1502. *
  1503. * Starts a task to listen for network connections.
  1504. *
  1505. * RETURNS: Nothing.
  1506. * NOMANUAL
  1507. */
  1508. extern "C" void startListenerTask (void)
  1509.     {
  1510.     COM_ASSERT (taskSpawn ("tDcomShow", 55, VX_FP_TASK, 10240,
  1511.  (FUNCPTR)listenerTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) != ERROR);
  1512.     }
  1513. /**************************************************************************
  1514. *
  1515. * dcomShowInit - Init routine for the DCOM Show routines. 
  1516. *
  1517. * This initializes the module and installs the required hooks into the
  1518. * client/server structure to capture and process the network data.
  1519. * This routine takes one parameter which defines a network port to listen
  1520. * for telnet style connections on. If a telnet style client is connected to
  1521. * this port all output will be sent via this network connection, rather than
  1522. * to the system console.
  1523. *
  1524. * RETURNS: Nothing.
  1525. */
  1526. extern "C" void dcomShowInit
  1527.     (
  1528.     int listenPort /* Port number to listen for */
  1529.      /* connections on, 0 to disable. */
  1530.     )
  1531.     {
  1532.     SETDEBUGHOOK(pRpcClientOutput, dcomShowClientOutput);
  1533.     SETDEBUGHOOK(pRpcClientInput, dcomShowClientInput);
  1534.     SETDEBUGHOOK(pRpcServerOutput, dcomShowServerOutput);
  1535.     SETDEBUGHOOK(pRpcServerInput, dcomShowServerInput);
  1536.     /* Initialize listen port */
  1537.     if (listenPort != 0)
  1538. {
  1539. s_listenPort = listenPort;
  1540. startListenerTask ();
  1541. }
  1542.     }