--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linklayerprotocols/pppnif/SPPP/PPPLOG.CPP Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,2517 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "PPPLOG.H"
+
+#if defined (ESOCK_LOGGING_ACTIVE)
+
+#include "PPPHDLC.H"
+#include "ncpip.h"
+#include "ncpip6.h"
+#include "VJ.H"
+#include "PPPCCP.H"
+
+#include "PPPCHAP.H"
+
+static const TUint KDnsPort = 53;
+
+_LIT(KPppLogFolder,"Ppp");
+_LIT(KPppLogFile,"Ppp.txt");
+_LIT8(KTcpDumpFirstTag,"TcpDump");
+_LIT8(KPppTcpDump,"TcpDump.log");
+
+_LIT(KEndOfLine,"\n");
+_LIT(KStateString1,"%s State -> %s");
+_LIT(KStateString2,"%s State %s -> %s");
+_LIT(KPhaseString1,"PPP Phase -> %s");
+_LIT(KPhaseString2,"PPP Phase %s -> %s");
+_LIT(KCodeTextString," %s [0x%02x]");
+_LIT(KCodeTextWithoutSpacesString," %s [0x%02x]");
+_LIT(KIdentifierLengthString," Id = 0x%02x, Len = %d");
+_LIT(KLengthString," Length = %d");
+_LIT(KLengthString2," Length = 0x%02x");
+_LIT(KTCPLengthString," Length = %d, Hdr len = %d");
+_LIT(KUDPLengthPortString," Length = %d, Src port = %d, Dst port = %d");
+_LIT(KBytesRemainingString," %d byte(s) remaining");
+_LIT(KLcpCodeString," Code = %s [0x%02x]");
+_LIT(KCodeString," Code = 0x%02x");
+_LIT(KCodeString2," Code = 0x%04x");
+_LIT(KProtocolString," Protocol = 0x%04x");
+_LIT(KNumberString," Number = 0x%08x");
+_LIT(KSecondsString," Seconds = %d");
+_LIT(KSizeString," Size = %d");
+_LIT(KMapString," Map = 0x%08x");
+_LIT(KProtocolTextString," Protocol = %s [0x%04x]");
+_LIT(KLcpOptFcsTypeString," Types =%s%s%s");
+_LIT(KMaximumBytesString," Maximum bytes = %d");
+_LIT(KUserNameString," Username = \"%S\"");
+_LIT(KPasswordString," Password = \"%S\"");
+_LIT(KMessageString," Message = \"%S\"");
+_LIT(KDelayString," Delay=%d\n");
+_LIT(KNameString," Name = \"%S\"");
+_LIT(KChangeMaskString," Change Mask = 0x%x: ");
+_LIT(KChecksumString," Checksum = 0x%x");
+//_LIT(KChecksumString2," Checksum = 0x%04x");
+_LIT(KChecksumString3," Chksum = 0x%04x (0x%04x) !!!");
+_LIT(KConnectionString," Connection = 0x%x");
+_LIT(KHdrLengthString," Length = %d, Hdr len = %d");
+//_LIT(KTOSTTLChksumString," TOS = 0x%02x, TTL = %d, Chksum = 0x%04x");
+_LIT(KIDFragmentString," Id = 0x%04x, Fragment = %d %s%s%s");
+_LIT(KSrcDstAddrString," Src = %d.%d.%d.%d, Dst = %d.%d.%d.%d");
+_LIT(KIpv6SrcAddress," Src = %x:%x:%x:%x:%x:%x:%x:%x");
+_LIT(KIpv6DstAddress," Dst = %x:%x:%x:%x:%x:%x:%x:%x");
+_LIT(KIpv6IfIdent," EUI64 = %x:%x:%x:%x");
+_LIT(KIpv6Class," Class = %d");
+_LIT(KIpv6FlowLabel," FlowLabel = %d");
+_LIT(KIpv6PayloadLen," Payload = %d words");
+_LIT(KIpv6NextHeadType," Next Header type is [%d]");
+_LIT(KIpv6HopLimit," Hop Limit is %d");
+_LIT(KIpv6UnknownHeadType," Unknown next header: [%d]");
+_LIT(KConnectionNoString," Connection number [0x%02x]");
+_LIT(KRemoteAddrString," Remote Address = %d.%d.%d.%d");
+_LIT(KOurAddrString," Our Address = %d.%d.%d.%d");
+_LIT(KMaxSlotString," Max Slot Id = %d");
+_LIT(KCompSlotString," Comp Slot Id = %d");
+_LIT(KAddrString," Address = %d.%d.%d.%d");
+_LIT(KPortString," Src port = %d, Dst port = %d");
+_LIT(KWindowUrgentString," Window = %d, Urgent = %d");
+_LIT(KSeqAckString," Seq = 0x%08x, Ack = 0x%08x");
+_LIT(KFlagsString," Flags = 0x%04x (%s%s%s%s%s%s%s%s)");
+
+#define EIGHT_SPACE_MARGIN _S(" ")
+#define FOURTEEN_SPACE_MARGIN _S(" ")
+
+
+/** Record types in the pppdump log file */
+enum
+ {
+ EpppDumpLogRecSentData = 1,
+ EpppDumpLogRecRcvData = 2,
+ EpppDumpLogRecRcvDelim = 4,
+ EpppDumpLogRecTimeStepLong = 5,
+ EpppDumpLogRecTimeStepShort = 6,
+ EpppDumpLogRecResetTime = 7
+ };
+
+//
+// PppLog
+//
+
+CPppLog::CPppLog()
+ {}
+
+CPppLog::~CPppLog()
+ {
+ __FLOG_CLOSE;
+ delete iLogFileName;
+ }
+
+CPppLog* CPppLog::NewL()
+ {
+ CPppLog* self = new (ELeave) CPppLog;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(); // self
+ return self;
+ }
+
+void CPppLog::ConstructL()
+ {
+ TFileName defFileName(KPppLogFile);
+ iTcpDumpLogFileName = KPppTcpDump;
+ iLogFileName = defFileName.AllocL();
+ iTimeOrigin.UniversalTime();
+ __FLOG_OPEN(KTcpDumpFirstTag,KPppTcpDump);
+ }
+
+void CPppLog::SetLogFileNameL(const TDesC& aName)
+ {
+ if(aName.Length() == 0)
+ //Nothing to do, keep logging to ppp.txt
+ return;
+ delete iLogFileName;
+
+ // Create ppp log file name
+ TFileName logFileName(aName);
+ const TChar KColonChar(':');
+ TInt colonPos = logFileName.Locate(KColonChar);
+ _LIT(KHyphenChar, "-");
+ if (colonPos != KErrNotFound)
+ {
+ logFileName.Replace(colonPos, 2, KHyphenChar);
+ }
+ _LIT(KLogFileExtension, ".txt");
+ logFileName.Append(KLogFileExtension);
+ logFileName.LowerCase();
+ iLogFileName = logFileName.AllocL();
+
+ //Set tcpdump log file name
+ iTcpDumpLogFileName = _L8("");
+ iTcpDumpLogFileName.Append(aName);
+ colonPos = iTcpDumpLogFileName.Locate(KColonChar);
+ _LIT8(KHyphenChar8, "-");
+ if (colonPos != KErrNotFound)
+ {
+ iTcpDumpLogFileName.Replace(colonPos, 2, KHyphenChar8);
+ }
+ _LIT8(KTcpDumpLogFileExtension, ".log");
+ iTcpDumpLogFileName.Append(KTcpDumpLogFileExtension);
+ iTcpDumpLogFileName.LowerCase();
+
+ __FLOG_SET_TAGS(KTcpDumpFirstTag,iTcpDumpLogFileName);
+ }
+
+void CPppLog::Write(const TDesC& aDes)
+/**
+Writes aDes to the log.
+
+@param aDes String descriptor
+*/
+ {
+#ifdef __FLOG_ACTIVE
+ RFileLogger::Write(KPppLogFolder(), *iLogFileName, EFileLoggingModeAppend, aDes);
+#else
+ // Preventing unused variable warnings.
+ (void)aDes;
+#endif //__FLOG_ACTIVE
+ }
+
+void CPppLog::Printf(const TRefByValue<const TDesC> aFmt,...)
+/**
+Writes a multiple argument list to the log, trapping and ignoring any leave.
+
+@param aFmt printf-style format string
+*/
+ {
+#ifdef __FLOG_ACTIVE
+ VA_LIST list;
+ VA_START(list,aFmt);
+ RFileLogger::WriteFormat(KPppLogFolder(), *iLogFileName, EFileLoggingModeAppend, aFmt, list);
+ VA_END(list);
+#else
+ // Preventing unused variable warnings.
+ (void)aFmt;
+#endif //__FLOG_ACTIVE
+ }
+
+//First attempt below was following the libcap
+//packet capture format. This format was originally used to facilitate
+//running a tcptrace stream analysis on the captured data, but further
+//investigation revealed that raw HDLC frames are not decoded by libpcap
+//programs (even type 50 libpcap data files). Improvements to Ethereal also
+//allowed its tcptrace to be run using pppdump format capture files,
+//making libpcap format files pretty well unnecessary.
+//void PppLog::LibcapDumpFileHeader()
+/*
+Dumps file header in a format compatible with Libcap.
+Unfortunately, Ethereal cannot cope with HDLC packet including
+0x7e flag char and 0x7d escape char.
+Format is:
+@code
+struct FileHeader {
+ TUint32 magic;
+ TUint16 version_major;
+ TUint16 version_minor;
+ TUint32 thiszone; // gmt to local correction
+ TUint32 sigfigs; // accuracy of timestamps
+ TUint32 snaplen; // max length saved portion of each pkt
+ TUint32 linktype; // data link type (LINKTYPE_*)
+ 9 PPP, 50 PPP HDLC, 12 Raw IP
+};
+@endcode
+Note LINKTYPE specified in libpcap/bpf/net/bpf.h (see www.tcpdump.org)
+byte ordering is little endian.
+*/
+// {
+// TBuf8<sizeof(TUint32)*5+sizeof(TUint16)*2> fileHeader;
+// *((TUint32*) &(fileHeader.Ptr()[0])) = 0xa1b2c3d4;
+// *((TUint16*) &(fileHeader.Ptr()[4])) = 0x02;
+// *((TUint16*) &(fileHeader.Ptr()[6])) = 0x04;
+// *((TUint32*) &(fileHeader.Ptr()[8])) = 0x00;
+// *((TUint32*) &(fileHeader.Ptr()[12])) = 0x00;
+// *((TUint32*) &(fileHeader.Ptr()[16])) = 0xffff;
+// *((TUint32*) &(fileHeader.Ptr()[20])) = 50;
+// fileHeader.SetLength(fileHeader.MaxLength());
+// RFileLogger::Write(KPppLogFolder(),KPppTcpDump(),EFileLoggingModeOverwriteRaw,fileHeader);
+// }
+
+//void PppLog::LibcapDump(TPppHdlcBuf& aBuffer)
+/*
+Dumps a packet in a format compatible with Libcap.
+For each record the format is:
+@code
+struct record
+{
+ TUint32 sec; // time stamp - secs
+ TUint32 usec; // time stamp - microsecs
+ TUint32 captureLen; // length packet captured
+ TUint32 packetLen; // total length of packet
+};
+@endcode
+Byte ordering of the header is little endian
+Byte ordering of the packet is network byte order (big endian)
+
+@param aBuffer Buffer to dump
+*/
+// {
+ //
+ //Unfortunately ethereal gets confused by the 0x7e separator
+ //So we need to strip it from the buffer before logging it
+// TInt startOffset = 0;
+// TInt endOffset =0;
+// if(aBuffer[0] == 0x7e)
+// startOffset = 1;
+// if(aBuffer[aBuffer.Length()-1] == 0x7e)
+// endOffset = 1;
+// if(startOffset && aBuffer.Length() ==1)
+// return;
+// TPppHdlcBuf dumpBuf;
+// dumpBuf.Copy(aBuffer.Ptr()+startOffset,aBuffer.Length()-startOffset-endOffset);
+//
+// TBuf8<sizeof(TUint32)*4> recordHeader;
+// *((TUint32*) &(recordHeader.Ptr()[0])) = 0x01;
+// *((TUint32*) &(recordHeader.Ptr()[4])) = 0x0;
+// *((TUint32*) &(recordHeader.Ptr()[8])) = dumpBuf.Length();
+// *((TUint32*) &(recordHeader.Ptr()[12])) = dumpBuf.Length();
+// recordHeader.SetLength(recordHeader.MaxLength());
+// RFileLogger::Write(KPppLogFolder(),KPppTcpDump(),EFileLoggingModeAppendRaw,recordHeader);
+//
+// RFileLogger::Write(KPppLogFolder(),KPppTcpDump(),EFileLoggingModeAppendRaw,dumpBuf);
+// }
+
+
+//Second attempt wih pppdump packet dump format
+void CPppLog::PppDumpFileHeader()
+/**
+Dumps file header in a format compatible with pppdump.
+As a file header just drop a 0x07|t3|t2|t1|t0 record followed by a
+0x05|t3|t2|t1|t0 record, that seems common practice.
+Since this "header" is actually a regular record, it can be
+appended to an existing file.
+*/
+ {
+ _LIT(Ktime_tOrigin,"19700000:000000.000000");
+ TTime time_t_Origin(Ktime_tOrigin);
+ TTimeIntervalSeconds secs;
+ TTime timeNow;
+ timeNow.UniversalTime();
+ timeNow.SecondsFrom(time_t_Origin,secs);
+ TBuf8<10> fileHeader;
+ fileHeader.SetLength(fileHeader.MaxLength());
+
+ fileHeader[0] = EpppDumpLogRecResetTime;
+ BigEndian::Put32(&fileHeader[1], secs.Int());
+
+ fileHeader[5] = EpppDumpLogRecTimeStepLong;
+ BigEndian::Put32(&fileHeader[6], 0);
+
+ __FLOG_BINARY(fileHeader);
+ }
+
+void CPppLog::PppDumpFrame(TInt aDirection, TUint32 aTimeStep, const TDesC8& aBuffer)
+/**
+Dumps a packet in a pppdump format (see www.ethereal.com)
+For each record the format is:
+@code
+0x07|t3|t2|t1|t0 Reset time t = time_t (UNIX: secs since 01/01/1970)
+0x06|t0 Time step (short) - ts = time step (tenths)
+0x05|t3|t2|t1|t0 Time step (short) - ts = time step (tenths)
+0x04 Receive deliminator (not seen in practice)
+0x02|n1|n0 Received data - n = number of bytes following
+0x01|n1|n0 Sent data - n = number of bytes following
+@endcode
+Byte ordering of the header is little endian
+Byte ordering of the packet is network byte order (big endian)
+
+@param aDirection 01:in/02:out (as documented by pppdump packet trace format)
+@param aTimeStep Delta time from last dumped frame
+@param aBuffer Buffer to dump
+*/
+ {
+ TBuf8<2+6> recordHeader;
+ int i=0;
+ if (aTimeStep > 0xff)
+ {
+ // 32-bit differential time record
+ recordHeader.SetLength(8);
+ recordHeader[i++] = EpppDumpLogRecTimeStepLong;
+ BigEndian::Put32(&recordHeader[i], aTimeStep);
+ i += 4;
+ }
+ else if (aTimeStep > 0)
+ {
+ // 8-bit differential time record
+ recordHeader.SetLength(5);
+ recordHeader[i++] = EpppDumpLogRecTimeStepShort;
+ recordHeader[i++] = (TUint8) aTimeStep;
+ }
+ else
+ {
+ recordHeader.SetLength(3);
+ }
+ recordHeader[i++] = (TUint8) aDirection;
+ BigEndian::Put16(&recordHeader[i], (TUint16)aBuffer.Length());
+ i += 2;
+ __FLOG_BINARY(recordHeader);
+ __FLOG_BINARY(aBuffer);
+ }
+
+void CPppLog::DumpFrameFileHeader(TInt aLogFormat, TInt aLogType)
+/**
+Specifies the file format to use for the frame log and writes the file header.
+
+@param aLogFormat Network log file format; EpppDumpLogFormat for pppdump
+@param aLogType EpppLogLinkFormat to log all frames,
+ ErawIpLogLinkFormat to just log IP frames
+*/
+ {
+ iLogFormat = aLogFormat;
+ iLogType = aLogType;
+ if (iLogFormat == EpppDumpLogFormat)
+ {
+ PppDumpFileHeader();
+ }
+ // else unknown format
+
+ Printf(_L("Note: the format of PPP log has changed\n"));
+ Printf(_L("The level of logging is now specified in the file: \\system\\data\\ppp.ini\n"));
+ Printf(_L("In the section [log], the entry: level= n specifies the level of logging\n"));
+ Printf(_L("n=0 :\tFinite State Machine transition are logged\n"));
+ Printf(_L("n=1 :\tReserved for future use\n"));
+ Printf(_L("n=2 :\tReserved for future use\n"));
+ Printf(_L("n=3 :\tReserved for future use\n"));
+ Printf(_L("n=4 :\tLog parsed PPP packets *SLOW* (superseded by TcpDump)\n"));
+ Printf(_L("n=5 :\tHexDump of PPP packets *VERY SLOW* (superseded by TcpDump)\n"));
+ Printf(_L("\tA new binary log is generated with the TcpDump tag, and after being\n"));
+ Printf(_L("\textracted with splitlog.bat, it can be used as an input file for Ethereal.\n"));
+ Printf(_L("Ethereal is a general purpose packet analyser that can parse a wide variety of protocols.\n"));
+ Printf(_L("\tIt is freeware and can be fetched from: http://www.ethereal.com\n"));
+
+ iLogHeaderDone=ETrue;
+ }
+
+void CPppLog::DumpFrame(TInt aDirection, const TDesC8& aBuffer)
+/**
+Dumps frame in the configured format.
+
+@param aDirection EpppDirectionSend or EpppDirectionReceive
+(as documented by pppdump packet trace format)
+@param aBuffer Buffer to dump
+*/
+ {
+ if(iLogFormat==EpppDumpLogFormat)
+ {
+ if(!iLogHeaderDone)
+ {
+ PppDumpFileHeader();
+ iLogHeaderDone=ETrue;
+ }
+ //Find absolute time now
+ TUint32 timeStep;
+ TTime timeNow;
+ timeNow.UniversalTime();
+ TTimeIntervalMicroSeconds us= timeNow.MicroSecondsFrom(iTimeOrigin);
+ //Round to the number of 1/10 secs within the hour
+ timeStep = I64LOW(us.Int64());
+ timeStep /= 100000;
+ if(timeStep)
+ iTimeOrigin=timeNow;
+ PppDumpFrame(aDirection,timeStep,aBuffer);
+ }
+ // else unknown log format
+ }
+
+void CPppLog::HexDump(const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen, TInt aWidth)
+ {
+
+ TBuf<0x100> buf;
+ TInt i = 0;
+ const TText* p = aHeader;
+ while (aLen>0)
+ {
+ TInt n = aLen>aWidth ? aWidth : aLen;
+ if (p!=NULL)
+ {
+ _LIT(string1,"%s%04x : ");
+ buf.AppendFormat(string1, p, i);
+ }
+ TInt j;
+ _LIT(string2,"%02x ");
+ for (j=0; j<n; j++)
+ buf.AppendFormat(string2, aPtr[i+j]);
+ _LIT(string3," ");
+ while (j++<KHexDumpWidth)
+ buf.Append(string3);
+ _LIT(string4," ");
+ buf.Append(string4);
+ _LIT(string5,"%c");
+ for (j=0; j<n; j++)
+ buf.AppendFormat(string5, aPtr[i+j]<32 || aPtr[i+j]>126 ? '.' : aPtr[i+j]);
+ buf.Append(KEndOfLine);
+ Write(buf);
+ buf.SetLength(0);
+ aLen -= n;
+ i += n;
+ p = aMargin;
+ }
+ }
+
+void CPppLog::Dump(RMBufChain& aPacket, TInt aChannel)
+ {
+ RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(aPacket);
+ TUint prot = TPppAddr::Cast(info->iDstAddr).GetProtocol();
+
+ HBufC8* hbuf = 0;
+ TRAPD(err, hbuf = HBufC8::NewL(aPacket.Length()+1));
+ if(err != KErrNone)
+ {
+ _LIT(string0,"CPppLog::Dump error = %d");
+ Printf(string0, err);
+ }
+ else
+ {
+ TPtr8 buf = hbuf->Des();
+ buf.SetMax();
+ aPacket.CopyOut(buf, aPacket.First()->Length());
+
+ if (aChannel==KPppHdlcSendChannel)
+ {
+ _LIT(string1,"PPP Send %d bytes");
+ Printf(string1, info->iLength);
+ }
+ else if (aChannel==KPppHdlcRecvChannel)
+ {
+ _LIT(string2,"PPP Recv %d bytes");
+ Printf(string2, info->iLength);
+ }
+ else
+ {
+ _LIT(string3,"PPP %d bytes");
+ Printf(string3, info->iLength);
+ }
+
+ _LIT(string4," %s [0x%04x] ");
+ Printf(string4, ProtocolToText(prot), prot);
+
+ TPtrC8 des(buf);
+ switch (prot)
+ {
+ case KPppIdLcp:
+ DumpLcp(des);
+ break;
+ case KPppIdPap:
+ DumpPap(des);
+ break;
+ case KPppIdChap:
+ DumpChap(des);
+ break;
+ case KPppIdIpcp:
+ DumpIpcp(des);
+ break;
+ case KPppIdIp6cp:
+ DumpIp6cp(des);
+ break;
+ case KPppIdIp:
+ DumpIp(des);
+ break;
+ case KPppIdIp6:
+ DumpIp6(des);
+ break;
+ case KPppIdVjCompTcp:
+ DumpVjCompTcp(des);
+ break;
+ case KPppIdVjUncompTcp:
+ DumpVjUncompTcp(des);
+ break;
+ case KPppIdMsCbcp:
+ DumpCbcp(des);
+ break;
+ case KPppIdCcp:
+ DumpCcp(des);
+ break;
+ case KPppIdCompressed:
+ break;
+ default:
+ Printf(_L("Raw Bytes:"));
+ DumpBytes(_S(""), des.Ptr(), des.Length());
+ Write(KEndOfLine);
+ break;
+ }
+ }
+ delete hbuf;
+ }
+
+void CPppLog::DumpState(const TText* aFsm, TPppFsmState aOldState, TPppFsmState aNewState)
+ {
+
+ if (aNewState==aOldState)
+ Printf(KStateString1, aFsm, StateToText(aNewState));
+ else
+ Printf(KStateString2, aFsm, StateToText(aOldState), StateToText(aNewState));
+ }
+
+void CPppLog::DumpPhase(TPppPhase aOldPhase, TPppPhase aNewPhase)
+ {
+
+ if (aNewPhase==aOldPhase)
+ Printf(KPhaseString1, PhaseToText(aNewPhase));
+ else
+ Printf(KPhaseString2, PhaseToText(aOldPhase), PhaseToText(aNewPhase));
+ }
+
+// Private functions
+
+void CPppLog::DumpChapType(const TUint8* aPtr)
+ {
+
+ switch (*aPtr)
+ {
+ case 5:
+ {
+ _LIT(string1," Algorithm=MD5");
+ Write(string1);
+ }
+ break;
+
+ case 0x80:
+ {
+ _LIT(string2," Algorithm=MS-CHAP-V1");
+ Write(string2);
+ }
+ break;
+
+ case 0x81:
+ {
+ _LIT(string2," Algorithm=MS-CHAP-V2");
+ Write(string2);
+ }
+ break;
+
+ default:
+ {
+ _LIT(string3," Algorithm=Unknown");
+ Write(string3);
+ }
+ break;
+ }
+ }
+
+void CPppLog::DumpBytes(const TText* aMargin, const TUint8* aPtr, TInt aLen)
+ {
+
+ HexDump(NULL,aMargin,aPtr,aLen,8);
+ }
+
+
+TInt CPppLog::DumpLcp(TPtrC8& aDes)
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 code = *ptr++;
+ TUint8 id = *ptr++;
+ TInt len = BigEndian::Get16(ptr);
+ if(len>aDes.Length())
+ {
+ Printf(_L("WARNING: Length reported in header was more than actual frame length"));
+ return len;
+ }
+ else if (len<aDes.Length())
+ Printf(_L("WARNING: Length reported in header was less than actual frame length!"));
+
+ ptr += 2;
+ aDes.Set(ptr, aDes.Length()-4);
+
+ Printf(KCodeTextString, LcpCodeToText(code), code);
+ Printf(KIdentifierLengthString, id, len);
+
+ switch (code)
+ {
+ case KPppLcpConfigRequest:
+ case KPppLcpConfigAck:
+ case KPppLcpConfigNak:
+ case KPppLcpConfigReject:
+ {
+ TInt n = len-4;
+ TInt tmp = 0;
+ while (n>0 && aDes.Length()>0)
+ {
+ tmp = DumpLcpOption(aDes);
+ if (tmp == 0) //Check for an error in the DumpLcpOption (0 is interpreted as an error)
+ {
+ Printf(_L("WARNING: Length reported in LCP Option was incorrect! Dumping data instead"));
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+ break;
+ }
+ n=n-tmp;
+ }
+
+ if (n>0)
+ Printf(KBytesRemainingString, n);
+ }
+
+ break;
+ case KPppLcpTerminateRequest:
+ case KPppLcpTerminateAck:
+ {
+ if (len>4)
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+ }
+ break;
+ case KPppLcpCodeReject:
+ {
+ TUint val = *ptr;
+ Printf(KCodeString, val);
+ }
+ break;
+ case KPppLcpProtocolReject:
+ {
+ TUint val = BigEndian::Get16(ptr);
+ Printf(KProtocolString, val);
+ }
+ break;
+ case KPppLcpEchoRequest:
+ {
+ TUint val = BigEndian::Get32(ptr);
+ Printf(KNumberString, val);
+ if (len>0)
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr+4, len-8);
+ }
+ break;
+ case KPppLcpEchoReply:
+ {
+ TUint val = BigEndian::Get32(ptr);
+ Printf(KNumberString, val);
+ if (len>0)
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr+4, len-8);
+ }
+ break;
+ case KPppLcpDiscardRequest:
+ {
+ TUint val = BigEndian::Get32(ptr);
+ Printf(KNumberString, val);
+ if (len>0)
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr+4, len-8);
+ }
+ break;
+ case KPppLcpIdentification:
+ {
+ TUint val = BigEndian::Get32(ptr);
+ Printf(KNumberString, val);
+ if (len>0)
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr+4, len-8);
+ }
+ break;
+ case KPppLcpTimeRemaining:
+ {
+ TUint val = BigEndian::Get32(ptr);
+ ptr+=4;
+ Printf(KNumberString, val);
+ val = BigEndian::Get32(ptr);
+ Printf(KSecondsString, val);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return len;
+ }
+
+TInt CPppLog::DumpLcpOption(TPtrC8& aDes)
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 opt = *ptr++;
+ TUint8 len = *ptr++;
+
+ if(len > aDes.Length())
+ {
+ Printf(_L("WARNING: Length reported in option header was more than actual frame length"));
+ return 0; //Return an incorrect length to flag this error.
+ }
+
+ if(len < 2)
+ {
+ Printf(_L("WARNING: Length reported in option header was less than a correct frame length"));
+ return 0; //Return an incorrect length. (the minimum correct length of an option is 2)
+ }
+
+ Printf(KLcpCodeString, LcpOptToText(opt), opt);
+ Printf(KLengthString, len);
+
+ switch (opt)
+ {
+ case KPppLcpOptMaxRecvUnit:
+ {
+ TUint val = BigEndian::Get16(ptr);
+ Printf(KSizeString, val);
+ }
+ break;
+ case KPppLcpOptEscapeCharMap:
+ {
+ TUint val = BigEndian::Get32(ptr);
+ Printf(KMapString, val);
+ }
+ break;
+ case KPppLcpOptAuthenticationProtocol:
+ {
+ TUint val = BigEndian::Get16(ptr);
+
+ Printf(KProtocolTextString, ProtocolToText(val), val);
+ if (val != KPppIdChap)
+ {
+ if (len>4)
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr+2, len-4);
+ }
+ else
+ {
+ if(len>4)
+ DumpChapType(ptr+2);
+ }
+ }
+ break;
+ case KPppLcpOptQualityProtocol:
+ {
+ TUint val = BigEndian::Get16(ptr);
+ Printf(KProtocolTextString, ProtocolToText(val), val);
+ if (len>4)
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr+2, len-4);
+ }
+ break;
+ case KPppLcpOptMagicNumber:
+ {
+ TUint val = BigEndian::Get32(ptr);
+ Printf(KNumberString, val);
+ }
+ break;
+ case KPppLcpOptProtocolCompress:
+ case KPppLcpOptAddrCtrlCompress:
+ break;
+ case KPppLcpOptFcsType:
+ {
+ TUint val = *ptr++;
+ Printf(KLcpOptFcsTypeString, (val&KPppHdlcFcs0Flag)?_S(" None"):_S(""), (val&KPppHdlcFcs16Flag)?_S(" 16 bit"):_S(""), (val&KPppHdlcFcs32Flag)?_S(" 32 bit"):_S(""));
+ }
+ break;
+ case KPppLcpOptPadding:
+ {
+ TUint val = *ptr++;
+ Printf(KMaximumBytesString, val);
+ }
+ break;
+ case KPppLcpOptCallback:
+ {
+ TUint val = *ptr++;
+ Printf(KCodeTextString, CallbackOpToText(val), val);
+ if (len>3)
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr+3, len-3);
+ }
+ break;
+ case KPppLcpOptCompoundFrames:
+ break;
+ default:
+ break;
+ }
+ aDes.Set((TUint8*)aDes.Ptr()+len, aDes.Length()-len);
+ return len;
+ }
+
+TInt CPppLog::DumpPap(TPtrC8& aDes)
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 code = *ptr++;
+ TUint8 id = *ptr++;
+ TInt len = BigEndian::Get16(ptr);
+ ptr += 2;
+
+ Printf(KCodeTextString, PapCodeToText(code), code);
+ Printf(KIdentifierLengthString, id, len);
+
+ if (code==1)
+ {
+ TInt n = *ptr++;
+ TPtrC8 v;
+ v.Set(ptr, n); ptr += n;
+ TBuf16<KLogBufferSize> temp;
+ temp.Copy(v.Left(Min(v.Length(),KLogBufferSize)));
+ Printf(KUserNameString, &temp);
+ n = *ptr++;
+ v.Set(ptr, n); ptr += n;
+ temp.Copy(v.Left(Min(v.Length(),KLogBufferSize)));
+ Printf(KPasswordString, &temp);
+ }
+ else if (code==2 || code==3)
+ {
+ TInt n = *ptr++;
+ TPtrC8 v;
+ v.Set(ptr, n); ptr += n;
+ TBuf16<KLogBufferSize> temp;
+ temp.Copy(v.Left(Min(v.Length(),KLogBufferSize)));
+ Printf(KMessageString, &temp);
+ }
+
+ aDes.Set(aDes.Ptr()+len, aDes.Length()-len);
+ return len;
+ }
+
+TInt CPppLog::DumpCbcp(TPtrC8& aDes)
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 code = *ptr++;
+ TUint8 id = *ptr++;
+ TInt len = BigEndian::Get16(ptr);
+ TInt length = len;
+ ptr += 2;
+
+ Printf(KCodeTextString, CbcpCodeToText(code), code);
+ Printf(KIdentifierLengthString, id, len);
+
+ //
+ // OK we can be offered many options at once, so
+ // loop for the length and decode them.
+ //
+ len -= 4; // Subtract the stuff we know about
+
+ TUint8 type;
+ TUint typeLen;
+ while (len)
+ {
+ // Yes I know we can have a permanent loop but I just don't care
+ type = *ptr++;
+ switch(type)
+ {
+ case 1:
+ {
+ _LIT(string1," No CallBack");
+ Write(string1);
+ }
+ break;
+ case 2:
+ {
+ _LIT(string2," Callback to a user specified No.");
+ Write(string2);
+ }
+ break;
+ case 3:
+ {
+ _LIT(string3," Callback to a pre specified No.");
+ Write(string3);
+ }
+ break;
+ case 4:
+ {
+ _LIT(string4," Callback to one of a list of numbers");
+ Write(string4);
+ }
+ break;
+ default:
+ {
+ _LIT(string5," Unknown Callback type");
+ Write(string5);
+ }
+ break;
+ }
+
+ if (len == 1)
+ len = 0;
+
+ typeLen = *ptr++;
+ Printf(KLengthString,typeLen);
+
+ if (typeLen > 2)
+ Printf(KDelayString,*ptr++);
+
+ if (typeLen > 3)
+ {
+ //
+ // Dump the Address Type field
+ //
+ if (*ptr++ == 1)
+ {
+ _LIT(string6," PSTN/ISDN");
+ Write(string6);
+ }
+ else
+ {
+ _LIT(string7," Other");
+ Write(string7);
+ }
+ }
+
+ //
+ // Dump the NUL-terminated ASCII string
+ //
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr, (typeLen-4));
+ len -= typeLen;
+ }
+
+ aDes.Set(aDes.Ptr()+length, aDes.Length()-length);
+ return length;
+ }
+
+TInt Advance(TPtrC8& aPacket, const TUint8* aPos)
+ {
+ aPacket.Set(aPos, aPacket.Length() - (aPacket.Ptr() - aPos));
+ return aPacket.Ptr() - aPos;
+ }
+
+TInt CPppLog::DumpChap(TPtrC8& aPacket)
+ {
+ if (aPacket.Length() < KPppChapCodeFieldSize)
+ return 0;
+
+ const TUint8* ptr = aPacket.Ptr();
+ TInt packLength = aPacket.Length();
+ TUint8 code = *ptr;
+
+ Printf(KCodeTextWithoutSpacesString,ChapCodeToText(code), code);
+ ptr += KPppChapCodeFieldSize;
+
+ if (packLength < KPppChapCodeFieldSize +
+ KPppChapIdFieldSize +
+ KPppChapLengthFieldSize)
+ return Advance(aPacket, ptr);
+
+ TUint8 id = *ptr;
+ ptr += KPppChapIdFieldSize;
+ TUint16 length = BigEndian::Get16(ptr);
+ ptr += KPppChapLengthFieldSize;
+
+ Printf(KIdentifierLengthString, id, length);
+
+ if (packLength > length)
+ packLength = length;
+
+ if (code == KPppChapChallengeCode || code == KPppChapResponseCode)
+ {
+ if (packLength < KPppChapCodeFieldSize +
+ KPppChapIdFieldSize +
+ KPppChapLengthFieldSize +
+ KPppChapValueSizeFieldSize +
+ KPppChapMinValueSize)
+ return Advance(aPacket, ptr);
+
+ TUint8 valueSize = *ptr;
+ if (valueSize < KPppChapMinValueSize)
+ return Advance(aPacket, ptr);
+ ptr += KPppChapValueSizeFieldSize;
+ if (valueSize > packLength -
+ KPppChapCodeFieldSize -
+ KPppChapIdFieldSize -
+ KPppChapLengthFieldSize -
+ KPppChapValueSizeFieldSize)
+ return Advance(aPacket, ptr);
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr, valueSize);
+ ptr += valueSize;
+
+// length will contain the length of the CHAP Name field next
+ ASSERT(packLength <= length);
+ length = static_cast<TUint16>(packLength -
+ KPppChapCodeFieldSize -
+ KPppChapIdFieldSize -
+ KPppChapLengthFieldSize -
+ KPppChapValueSizeFieldSize -
+ valueSize);
+ if (length < KPppChapMinNameSize)
+ return Advance(aPacket, ptr);
+
+ if (length > KLogBufferSize)
+ length = KLogBufferSize;
+
+ TPtrC8 name(ptr, length);
+
+ HBufC16* uniName=NULL;
+ TRAPD(err, uniName = HBufC16::NewL(length));
+ if (err==KErrNone)
+ {
+ // Convert the string to a 16 bit descriptor
+ uniName->Des().Copy(name);
+ Printf(KNameString, uniName);
+ delete uniName;
+ }
+ ptr += length;
+ }
+ else if (code == KPppChapSuccessCode || code == KPppChapFailureCode)
+ {
+// length will contain the length of the message next
+ ASSERT(packLength <= length);
+ length = static_cast<TUint16>(packLength -
+ KPppChapCodeFieldSize -
+ KPppChapIdFieldSize -
+ KPppChapLengthFieldSize);
+ if (length == 0)
+ return Advance(aPacket, ptr);
+
+ TPtrC8 msg(ptr, length);
+
+ HBufC16* uniMsg=NULL;
+ TRAPD(err, uniMsg = HBufC16::NewL(length));
+ if (err==KErrNone)
+ {
+ // Convert the string to a 16 bit descriptor
+ uniMsg->Des().Copy(msg);
+ Printf(KMessageString, uniMsg);
+ delete uniMsg;
+ }
+ ptr += length;
+ }
+
+ return Advance(aPacket, ptr);
+ }
+
+
+TInt CPppLog::DumpCcp(TPtrC8& aDes)
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 code = *ptr++;
+ TUint8 id = *ptr++;
+ TInt len = BigEndian::Get16(ptr);
+ ptr += 2;
+ aDes.Set(ptr, aDes.Length()-4);
+
+ Printf(KCodeTextWithoutSpacesString,FsmCodeToText(code), code);
+ Printf(KIdentifierLengthString, id, len);
+
+ switch (code)
+ {
+ case KPppLcpConfigRequest:
+ case KPppLcpConfigAck:
+ case KPppLcpConfigNak:
+ case KPppLcpConfigReject:
+ {
+ TInt n = len-4;
+ TInt tmp = 0;
+ while (n>0 && aDes.Length()>0)
+ {
+ tmp = DumpCcpOption(aDes);
+ if (tmp == 0) //Check for an error in the DumpCcpOption (0 is interpreted as an error)
+ {
+ Printf(_L("WARNING: Length reported in CCP Option was incorrect! Dumping data instead"));
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+ break;
+ }
+ n=n-tmp;
+ }
+
+ if (n>0)
+ Printf(KBytesRemainingString, n);
+ }
+ break;
+ case KPppLcpTerminateRequest:
+ case KPppLcpTerminateAck:
+ {
+ if (len>4)
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+ }
+ break;
+ case KPppLcpCodeReject:
+ {
+ TUint val = BigEndian::Get16(ptr);
+ Printf(KCodeString, val);
+ }
+ break;
+ case KPppLcpProtocolReject:
+ {
+ TUint val = BigEndian::Get16(ptr);
+ Printf(KProtocolString, val);
+ }
+ break;
+ default:
+ break;
+ }
+ return len;
+ }
+
+TInt CPppLog::DumpCcpOption(TPtrC8& aDes)
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 opt = *ptr++;
+ TUint8 len = *ptr++;
+
+ if(len > aDes.Length())
+ {
+ Printf(_L("WARNING: Length reported in option header was more than actual frame length"));
+ return 0; //Return an incorrect length to flag this error.
+ }
+
+ if(len < 2)
+ {
+ Printf(_L("WARNING: Length reported in option header was less than a correct frame length"));
+ return 0; //Return an incorrect length. (the minimum correct length of an option is 2)
+ }
+
+ Printf(KCodeTextString, CcpCodeToText(opt), opt);
+ Printf(KLengthString, len);
+
+ DumpBytes(FOURTEEN_SPACE_MARGIN, ptr, len-2);
+ aDes.Set((TUint8*)aDes.Ptr()+len, aDes.Length()-len);
+ return len;
+ }
+
+const TText* CPppLog::CcpCodeToText(TUint aValue)
+ {
+
+ // CCP Codes
+ switch (aValue)
+ {
+ case KPppCcpOptOui:
+ return _S("OUI");
+ case KPppCcpOptPred1:
+ return _S("Predictor type1");
+ case KPppCcpOptPred2:
+ return _S("Predictor type2");
+ case KPppCcpOptPuddle:
+ return _S("Puddle");
+ case KPppCcpOptHP:
+ return _S("HP PPC");
+ case KPppCcpOptStac:
+ return _S("Stac LZS");
+ case KPppCcpOptMsoft:
+ return _S("Microsoft PPC");
+ case KPppCcpOptGandalf:
+ return _S("Gandalf");
+ case KPppCcpOptV42bis:
+ return _S("V42bis");
+ case KPppCcpOptBSDLzw:
+ return _S("BSD LZW");
+ case KPppCcpOptMagnalink:
+ return _S("Magnalink (or bad deflate)");
+ case KPppCcpOptDeflate:
+ return _S("Deflate");
+ case KPppCcpOptReserved:
+ return _S("Reserved");
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ return _S("unassigned");
+ default:
+ return _S("Unknown");
+ }
+ }
+
+TInt CPppLog::DumpVjCompTcp(TPtrC8& aDes)
+/**
+Dump a Van Jacobson compressed TCP/IP packet.
+@see DumpVjUncompTcp
+*/
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint16 change = *ptr++;
+ TUint8 urgent=0;
+ TInt16 window=0;
+ TUint16 ack=0;
+ TUint16 sequence=0;
+ TBuf<50> changeMaskBuf;
+ TUint8 connection=0;
+
+ changeMaskBuf.Append(KChangeMaskString);
+
+ if (change & KVjCompMaskConn)
+ {
+ _LIT(string7,"C");
+ changeMaskBuf.Append(string7);
+ connection = *ptr++;
+ }
+
+ TUint16 checksum = BigEndian::Get16(ptr);
+ ptr += 2;
+
+ if (change & KVjCompMaskPush)
+ {
+ _LIT(string8,"P");
+ changeMaskBuf.Append(string8);
+ }
+
+ /*
+ * Don't reorder SpecialI && SpecialD, they are like this
+ * as SpecialD is the SWAU bits and SpecialI is SWU
+ *
+ */
+
+ if ((change & KVjCompMaskSpecials) == KVjCompMaskSpecialD)
+ {
+ _LIT(string1," Special D");
+ Write(string1);
+ }
+ else if ((change & KVjCompMaskSpecials) == KVjCompMaskSpecialI)
+ {
+ _LIT(string2," Special I");
+ Write(string2);
+ }
+ else
+ {
+ if (change & KVjCompMaskUrgent)
+ {
+ _LIT(string3,"U");
+ changeMaskBuf.Append(string3);
+ urgent = *ptr++;
+ }
+
+ if (change & KVjCompMaskWindow )
+ {
+ window = (TInt16)DecodeSignedDelta(ptr);
+ _LIT(string4,"W");
+ changeMaskBuf.Append(string4);
+ }
+
+ if (change & KVjCompMaskAck )
+ {
+ ack = DecodeDelta(ptr);
+ _LIT(string5,"A");
+ changeMaskBuf.Append(string5);
+ }
+
+ if (change & KVjCompMaskSeq)
+ {
+ sequence = DecodeDelta(ptr);
+ _LIT(string6,"S");
+ changeMaskBuf.Append(string6);
+ }
+ }
+
+
+ TUint16 ipId=0;
+ if (change & KVjCompMaskIp)
+ {
+ ipId = DecodeDelta(ptr);
+ _LIT(string9,"I");
+ changeMaskBuf.Append(string9);
+ }
+
+ Printf(TRefByValue<const TDesC>(changeMaskBuf), change);
+
+ Printf(KChecksumString, checksum);
+
+ if (change & KVjCompMaskConn)
+ {
+ Printf(KConnectionString,connection);
+ }
+
+ if (urgent)
+ {
+ _LIT(string10," Urgent Delta = 0x%x");
+ Printf(string10,urgent);
+ }
+
+ if (window)
+ {
+ _LIT(string11," Window Delta = %d");
+ Printf(string11,window);
+ }
+
+ if (ack)
+ {
+ _LIT(string12," Ack Delta = 0x%x");
+ Printf(string12,ack);
+ }
+
+ if (sequence)
+ {
+ _LIT(string13," Sequence Delta = 0x%x");
+ Printf(string13,sequence);
+ }
+
+ if (ipId)
+ {
+ _LIT(string14," IPId = 0x%x");
+ Printf(string14,ipId);
+ }
+
+ return 1;
+ }
+
+TUint16 CPppLog::DecodeDelta(TUint8*& aPtr)
+ {
+
+ TUint16 wordValue;
+ TUint8 byteValue = *aPtr++;
+ if (byteValue != 0)
+ return (TUint16)byteValue;
+ else
+ {
+ /*
+ * Zero is an extender
+ */
+ wordValue = BigEndian::Get16(aPtr);
+ aPtr += 2;
+ return wordValue;
+ }
+ }
+
+TInt16 CPppLog::DecodeSignedDelta(TUint8*& aPtr)
+ {
+
+ TInt16 wordValue;
+ TUint8 byteValue = *aPtr++;
+ if (byteValue != 0)
+ return (TInt16)byteValue;
+ else
+ {
+ /*
+ * Zero is an extender
+ */
+ wordValue = BigEndian::Get16(aPtr);
+ aPtr += 2;
+ return wordValue;
+ }
+ }
+
+TInt CPppLog::DumpVjUncompTcp(TPtrC8& aDes)
+/**
+Dump a Van Jacobson uncompressed TCP/IP packet.
+@see DumpIp is almost identical
+@see DumpVjCompTcp
+*/
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 c = *ptr++;
+// TUint ver = c >> 4;
+ TUint hlen = (c & 0xf) << 2;
+// TUint8 tos = *ptr;
+ ptr++;
+ TUint16 len = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+ ptr+=2;
+ TUint16 id = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+ ptr+=2;
+ TUint16 frag = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+ ptr+=2;
+ TBool zf = (frag & 0x8000);
+ TBool df = (frag & 0x4000);
+ TBool mf = (frag & 0x2000);
+ frag = (TUint16)((frag & 0x1fff)<<3);
+// TUint8 ttl = *ptr;
+ ptr++;
+ TUint8 proto = *ptr++;
+// TUint16 chksum = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+ ptr+=2;
+ TUint32 srca = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+ ptr+=4;
+ TUint32 dsta = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+ ptr+=4;
+// TBool opts = (hlen>20);
+
+ Printf(KHdrLengthString, len, hlen);
+ Printf(KSrcDstAddrString, (srca&0xff000000)>>24,(srca&0x00ff0000)>>16,(srca&0x0000ff00)>>8,(srca&0x000000ff),
+ (dsta&0xff000000)>>24,(dsta&0x00ff0000)>>16,(dsta&0x0000ff00)>>8,(dsta&0x000000ff));
+ Printf(KIDFragmentString, id, frag, df?_S("<DF>"):_S(""), mf?_S("<MF>"):_S(""), zf?_S("<Z>"):_S(""));
+// Printf(KTOSTTLChksumString, tos, ttl, chksum);
+ Printf(KConnectionNoString, proto);
+
+ if (hlen>20)
+ ptr += (hlen-20);
+
+ TInt n = (TInt)ptr-(TInt)aDes.Ptr();
+ TInt tlen = aDes.Length()-n;
+ aDes.Set(ptr, tlen);
+
+ Printf(KCodeTextString, IpProtocolToText(6), 6);
+ return n+DumpTcp(aDes, srca, dsta, tlen);
+ }
+
+TInt CPppLog::DumpIp6cp(TPtrC8& aDes)
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 code = *ptr++;
+ TUint8 id = *ptr++;
+ TInt len = BigEndian::Get16(ptr);
+ ptr += 2;
+ aDes.Set(ptr, aDes.Length()-4);
+
+ Printf(KCodeTextWithoutSpacesString, FsmCodeToText(code), code);
+ Printf(KIdentifierLengthString, id, len);
+
+ switch (code)
+ {
+ case KPppLcpConfigRequest:
+ case KPppLcpConfigAck:
+ case KPppLcpConfigNak:
+ case KPppLcpConfigReject:
+ {
+ TInt n = len-4;
+ while (n>0 && aDes.Length()>0)
+ n -= DumpIp6cpOption(aDes);
+ if (n>0)
+ Printf(KBytesRemainingString, n);
+ }
+ break;
+ case KPppLcpTerminateRequest:
+ case KPppLcpTerminateAck:
+ {
+ if (len>4)
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+ }
+ break;
+ case KPppLcpCodeReject:
+ {
+ TUint val = BigEndian::Get16(ptr);
+ Printf(KCodeString2, val);
+ }
+ break;
+ case KPppLcpProtocolReject:
+ {
+ TUint val = BigEndian::Get16(ptr);
+ Printf(KProtocolString, val);
+ }
+ break;
+ default:
+ break;
+ }
+ return len;
+ }
+
+TInt CPppLog::DumpIpcp(TPtrC8& aDes)
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 code = *ptr++;
+ TUint8 id = *ptr++;
+ TInt len = BigEndian::Get16(ptr);
+ ptr += 2;
+ aDes.Set(ptr, aDes.Length()-4);
+
+ Printf(KCodeTextWithoutSpacesString, FsmCodeToText(code), code);
+ Printf(KIdentifierLengthString, id, len);
+
+ switch (code)
+ {
+ case KPppLcpConfigRequest:
+ case KPppLcpConfigAck:
+ case KPppLcpConfigNak:
+ case KPppLcpConfigReject:
+ {
+ TInt n = len-4;
+ TInt tmp = 0;
+ while (n>0 && aDes.Length()>0)
+ {
+ tmp = DumpIpcpOption(aDes);
+ if (tmp == 0) //Check for an error in the DumpIpcpOption (0 is interpreted as an error)
+ {
+ Printf(_L("WARNING: Length reported in IPCP Option was incorrect! Dumping data instead"));
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+ break;
+ }
+ n=n-tmp;
+ }
+
+ if (n>0)
+ Printf(KBytesRemainingString, n);
+ }
+ break;
+ case KPppLcpTerminateRequest:
+ case KPppLcpTerminateAck:
+ {
+ if (len>4)
+ DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+ }
+ break;
+ case KPppLcpCodeReject:
+ {
+ TUint val = BigEndian::Get16(ptr);
+ Printf(KCodeString2, val);
+ }
+ break;
+ case KPppLcpProtocolReject:
+ {
+ TUint val = BigEndian::Get16(ptr);
+ Printf(KProtocolString, val);
+ }
+ break;
+ default:
+ break;
+ }
+ return len;
+ }
+
+TInt CPppLog::DumpIpcpOption(TPtrC8& aDes)
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 opt = *ptr++;
+ TUint8 len = *ptr++;
+
+ if(len > aDes.Length())
+ {
+ Printf(_L("WARNING: Length reported in option header was more than actual frame length"));
+ return 0; //Return an incorrect length to flag this error.
+ }
+
+ if(len < 2)
+ {
+ Printf(_L("WARNING: Length reported in option header was less than a correct frame length"));
+ return 0; //Return an incorrect length. (the minimum correct length of an option is 2)
+ }
+
+ Printf(KCodeTextString, IpcpCodeToText(opt), opt);
+ Printf(KLengthString2, len);
+
+ TUint32 val;
+
+ switch (opt)
+ {
+ case KPppIpcpOptIpAddresses:
+ val = BigEndian::Get32(ptr);
+ Printf(KRemoteAddrString,(val&0xff000000)>>24,(val&0x00ff0000)>>16,(val&0x0000ff00)>>8,(val&0x000000ff));
+ val = BigEndian::Get32(ptr+4);
+ Printf(KOurAddrString,(val&0xff000000)>>24,(val&0x00ff0000)>>16,(val&0x0000ff00)>>8,(val&0x000000ff));
+ break;
+ case KPppIpcpOptIpCompressionProtocol:
+ {
+ TUint prot = BigEndian::Get16(ptr);
+ ptr += 2;
+ Printf(KProtocolTextString, ProtocolToText(prot), prot);
+ if (len>4)
+ {
+ switch (prot)
+ {
+ case KPppIdVjCompTcp:
+ Printf(KMaxSlotString, *ptr++);
+ Printf(KCompSlotString, *ptr++);
+ break;
+ default:
+ DumpBytes(FOURTEEN_SPACE_MARGIN, ptr+4, len-4);
+ break;
+ }
+ }
+ }
+ break;
+ case KPppIpcpOptIpAddress:
+ case KPppIpcpOptPrimaryDnsAddress:
+ case KPppIpcpOptSecondaryDnsAddress:
+ case KPppIpcpOptPrimaryNbnsAddress:
+ case KPppIpcpOptSecondaryNbnsAddress:
+ {
+ val = BigEndian::Get32(ptr);
+ Printf(KAddrString,(val&0xff000000)>>24,(val&0x00ff0000)>>16,(val&0x0000ff00)>>8,(val&0x000000ff));
+ }
+ break;
+ default:
+ break;
+ }
+ aDes.Set((TUint8*)aDes.Ptr()+len, aDes.Length()-len);
+ return len;
+ }
+
+
+TInt CPppLog::DumpIp6cpOption(TPtrC8& aDes)
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 opt = *ptr++;
+ TUint8 len = *ptr++;
+
+ Printf(KCodeTextString, Ip6cpCodeToText(opt), opt);
+ Printf(KLengthString2, len);
+
+
+ switch (opt)
+ {
+ case KPppIp6cpOptInterfaceIdentifier:
+ {
+ TUint16 s1 = BigEndian::Get16( ptr );
+ ptr+=2;
+ TUint16 s2 = BigEndian::Get16( ptr );
+ ptr+=2;
+ TUint16 s3 = BigEndian::Get16( ptr );
+ ptr+=2;
+ TUint16 s4 = BigEndian::Get16( ptr );
+ ptr+=2;
+ Printf(KIpv6IfIdent, s1,s2,s3,s4);
+ break;
+ }
+ case KPppIp6cpOptCompressionProtocol:
+ {
+ TUint16 prot = BigEndian::Get16(ptr);
+ ptr += 2;
+ Printf(KProtocolTextString, ProtocolToText(prot), prot);
+ if (len>4)
+ {
+ switch (prot)
+ {
+ case KPppIdVjCompTcp:
+ Printf(KMaxSlotString, *ptr++);
+ Printf(KCompSlotString, *ptr++);
+ break;
+ default:
+ DumpBytes(FOURTEEN_SPACE_MARGIN, ptr+4, len-4);
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ aDes.Set((TUint8*)aDes.Ptr()+len, aDes.Length()-len);
+ return len;
+ }
+
+const TText* CPppLog::ProtocolToText(TUint aValue)
+ {
+
+ // Protocols
+ switch (aValue)
+ {
+ case KPppIdLcp:
+ return _S("LCP");
+ case KPppIdPap:
+ return _S("PAP");
+ case KPppIdChap:
+ return _S("CHAP");
+ case KPppIdMsCbcp:
+ return _S("MSCBCP");
+ case KPppIdIpcp:
+ return _S("IPCP");
+ case KPppIdIp6cp:
+ return _S("IP6CP");
+ case KPppIdIp:
+ return _S("IP");
+ case KPppIdIp6:
+ return _S("IPv6");
+ case KPppIdVjCompTcp:
+ return _S("VJ Comp tcp");
+ case KPppIdVjUncompTcp:
+ return _S("VJ Uncomp tcp");
+ case KPppIdCcp:
+ return _S("CCP");
+ case KPppIdCompressed:
+ return _S("PPP Compressed");
+ default:
+ return _S("Unknown");
+ }
+ }
+
+const TText* CPppLog::StateToText(TPppFsmState aState)
+ {
+
+ // States
+ switch (aState)
+ {
+ case EPppFsmInitial:
+ return _S("INITIAL");
+ case EPppFsmStarting:
+ return _S("STARTING");
+ case EPppFsmClosed:
+ return _S("CLOSED");
+ case EPppFsmStopped:
+ return _S("STOPPED");
+ case EPppFsmStopping:
+ return _S("STOPPING");
+ case EPppFsmClosing:
+ return _S("CLOSING");
+ case EPppFsmReqSent:
+ return _S("REQUEST SENT");
+ case EPppFsmAckRecvd:
+ return _S("ACK RECEIVED");
+ case EPppFsmAckSent:
+ return _S("ACK SENT");
+ case EPppFsmOpened:
+ return _S("OPENED");
+ default: // Should never happen in theory!
+ return _S("UNKNOWN");
+ }
+ }
+
+const TText* CPppLog::PhaseToText(TPppPhase aPhase)
+ {
+
+ // Phases
+ switch (aPhase)
+ {
+ case EPppPhaseTerminate:
+ return _S("TERMINATE");
+ case EPppPhaseEstablish:
+ return _S("ESTABLISH");
+ case EPppPhaseEarlyCallback:
+ return _S("EARLY CALLBACK");
+ case EPppPhaseAuthenticate:
+ return _S("AUTHENTICATE");
+ case EPppPhaseLateCallback:
+ return _S("LATE CALLBACK");
+ case EPppPhaseNetwork:
+ return _S("NETWORK");
+ default: // Should never happen in theory!
+ return _S("UNKNOWN");
+ }
+ }
+
+const TText* CPppLog::LcpCodeToText(TUint aValue)
+ {
+
+ // LCP Codes
+ switch (aValue)
+ {
+ case KPppLcpEchoRequest:
+ return _S("Echo request");
+ case KPppLcpEchoReply:
+ return _S("Echo reply");
+ case KPppLcpDiscardRequest:
+ return _S("Discard request");
+ case KPppLcpIdentification:
+ return _S("Identification");
+ case KPppLcpTimeRemaining:
+ return _S("Time remaining");
+ default:
+ return FsmCodeToText(aValue);
+ }
+ }
+
+const TText* CPppLog::FsmCodeToText(TUint aValue)
+ {
+
+ // LCP Codes
+ switch (aValue)
+ {
+ case KPppLcpConfigRequest:
+ return _S("Config Request");
+ case KPppLcpConfigAck:
+ return _S("Config ACK");
+ case KPppLcpConfigNak:
+ return _S("Config NAK");
+ case KPppLcpConfigReject:
+ return _S("Config Reject");
+ case KPppLcpTerminateRequest:
+ return _S("Terminate request");
+ case KPppLcpTerminateAck:
+ return _S("Terminate ACK");
+ case KPppLcpCodeReject:
+ return _S("Code Reject");
+ case KPppLcpProtocolReject:
+ return _S("Protocol Reject");
+ case KPppCcpResetReq:
+ // Only used by CCP, but this is the easiest place to put it
+ return _S("Reset Request");
+ case KPppCcpResetAck:
+ // Only used by CCP, but this is the easiest place to put it
+ //__DEBUGGER();
+ return _S("Reset Ack");
+ default:
+ return _S("Unknown");
+ }
+ }
+
+const TText* CPppLog::LcpOptToText(TUint aValue)
+ {
+
+ // LCP Options
+ switch (aValue)
+ {
+ case KPppLcpOptMaxRecvUnit:
+ return _S("Max receive size");
+ case KPppLcpOptEscapeCharMap:
+ return _S("Escape char map");
+ case KPppLcpOptAuthenticationProtocol:
+ return _S("Authentication protocol");
+ case KPppLcpOptQualityProtocol:
+ return _S("Quality protocol");
+ case KPppLcpOptMagicNumber:
+ return _S("Magic number");
+ case KPppLcpOptProtocolCompress:
+ return _S("Protocol field compression");
+ case KPppLcpOptAddrCtrlCompress:
+ return _S("Addr & Ctrl field compression");
+ case KPppLcpOptFcsType:
+ return _S("Fcs Type");
+ case KPppLcpOptPadding:
+ return _S("Padding");
+ case KPppLcpOptCallback:
+ return _S("Callback protocol");
+ case KPppLcpOptCompoundFrames:
+ return _S("Compound frames");
+ case KPppLcpOptMRRU:
+ return _S("MRRU");
+ case KPppLcpOptMultiLinkEndPointDescriminator:
+ return _S("Multi-link End-Point Descriminator");
+ default:
+ return _S("Unknown");
+ }
+ }
+
+const TText* CPppLog::CallbackOpToText(TUint aValue)
+ {
+
+ // CB Codes
+ switch (aValue)
+ {
+ case 0:
+ return _S("Location preset");
+ case 1:
+ return _S("Dialing string");
+ case 2:
+ return _S("Location identifier");
+ case 3:
+ return _S("E.164 number");
+ case 4:
+ return _S("Distinguished name");
+ case 5:
+ return _S("E.165 number");
+ case 6:
+ return _S("MS CBCP");
+ default:
+ return _S("Unknown operation");
+ }
+ }
+
+const TText* CPppLog::PapCodeToText(TUint aValue)
+ {
+
+ // PAP Codes
+ switch (aValue)
+ {
+ case 1:
+ return _S("Authenticate Request");
+ case 2:
+ return _S("Authenticate ACK");
+ case 3:
+ return _S("Authenticate NAK");
+ default:
+ return _S("Unknown");
+ }
+ }
+
+const TText* CPppLog::CbcpCodeToText(TUint aValue)
+ {
+
+ // CBCP Codes
+ switch (aValue)
+ {
+ case 1:
+ return _S("Callback Request");
+ case 2:
+ return _S("Callback Response");
+ case 3:
+ return _S("Callback Ack");
+ default:
+ return _S("Unknown");
+ }
+ }
+
+const TText* CPppLog::ChapCodeToText(TUint aValue)
+ {
+
+ // CHAP Codes
+ switch (aValue)
+ {
+ case 1:
+ return _S("Challenge");
+ case 2:
+ return _S("Response");
+ case 3:
+ return _S("Success");
+ case 4:
+ return _S("Failure");
+ default:
+ return _S("Unknown");
+ }
+ }
+
+const TText* CPppLog::IpProtocolToText(TUint aValue)
+ {
+
+ // IP Protocols
+ switch (aValue)
+ {
+ case 1:
+ return _S("ICMP");
+ case 58:
+ return _S("ICMPv6");
+ case 17:
+ return _S("UDP");
+ case 6:
+ return _S("TCP");
+
+ default:
+ return _S("Unknown");
+ }
+ }
+
+const TText* CPppLog::IpcpCodeToText(TUint aValue)
+ {
+
+ // IPCP Codes
+ switch (aValue)
+ {
+ case KPppIpcpOptIpAddresses:
+ return _S("IP Addresses");
+ case KPppIpcpOptIpCompressionProtocol:
+ return _S("IP Compression Protocol");
+ case KPppIpcpOptIpAddress:
+ return _S("IP Address");
+ case KPppIpcpOptPrimaryDnsAddress:
+ return _S("Primary DNS Address");
+ case KPppIpcpOptSecondaryDnsAddress:
+ return _S("Secondary DNS Address");
+ case KPppIpcpOptPrimaryNbnsAddress:
+ return _S("Primary NBNS Address");
+ case KPppIpcpOptSecondaryNbnsAddress:
+ return _S("Secondary NBNS Address");
+ default:
+ return _S("Unknown");
+ }
+ }
+
+const TText* CPppLog::Ip6cpCodeToText(TUint aValue)
+ {
+ // IP6CP Codes
+ switch (aValue)
+ {
+ case KPppIp6cpOptInterfaceIdentifier:
+ return _S("Interface Identifier");
+ case KPppIp6cpOptCompressionProtocol:
+ return _S("Compression Protocol");
+ default:
+ return _S("Unknown");
+ }
+ }
+
+TInt CPppLog::DumpIp(TPtrC8& aDes)
+ {
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 c = *ptr++;
+// TUint ver = c >> 4;
+ TUint hlen = (c & 0xf) << 2;
+// TUint8 tos = *ptr;
+ ptr++;
+ TUint16 len = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+ ptr+=2;
+ TUint16 id = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+ ptr+=2;
+ TUint16 frag = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+ ptr+=2;
+ TBool zf = (frag & 0x8000);
+ TBool df = (frag & 0x4000);
+ TBool mf = (frag & 0x2000);
+ frag = (TUint16)((frag & 0x1fff)<<3);
+// TUint8 ttl = *ptr;
+ ptr++;
+ TUint8 proto = *ptr++;
+// TUint16 chksum = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+ ptr+=2;
+ TUint32 srca = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+ ptr+=4;
+ TUint32 dsta = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+ ptr+=4;
+// TBool opts = (hlen>20);
+
+ Printf(KHdrLengthString, len, hlen);
+ Printf(KSrcDstAddrString,(srca&0xff000000)>>24,(srca&0x00ff0000)>>16,(srca&0x0000ff00)>>8,(srca&0x000000ff),
+ (dsta&0xff000000)>>24,(dsta&0x00ff0000)>>16,(dsta&0x0000ff00)>>8,(dsta&0x000000ff));
+ Printf(KIDFragmentString, id, frag, df?_S("<DF>"):_S(""), mf?_S("<MF>"):_S(""), zf?_S("<Z>"):_S(""));
+// Printf(KTOSTTLChksumString, tos, ttl, chksum);
+ Printf(KCodeTextString, IpProtocolToText(proto), proto);
+
+ if (hlen>20)
+ ptr += (hlen-20);
+
+ TInt n = (TInt)ptr-(TInt)aDes.Ptr();
+ TInt tlen = aDes.Length()-n;
+ aDes.Set(ptr, tlen);
+
+ if (tlen > 0)
+ {
+ switch (proto)
+ {
+ case 1:
+ return n+DumpIcmp(aDes, tlen);
+ case 6:
+ return n+DumpTcp(aDes, srca, dsta, tlen);
+ case 17:
+ return n+DumpUdp(aDes, srca, dsta, tlen);
+ default:
+ break;
+ }
+ }
+ return n;
+ }
+
+TInt CPppLog::DumpIp6(TPtrC8& aDes)
+ {
+ // This dumps the main IPv6 Header, no support for option headers
+ // IPv6 Headers are FIXED length, but are chainable...
+ TUint16* ptr = (TUint16*)aDes.Ptr();
+
+ // First 32 bits contain version(4), class(8), Flow Label(20)
+
+ TUint32 first = ByteOrder::Swap32((TUint32) *ptr);
+ //TUint8 ver = (TUint8)((first >> 28) & 0xf);
+ TUint8 cls = (TUint8)((first >> 20) & 0xff);
+ TUint32 flowLab = (first & 0xfffff);
+ ptr+=2;
+
+ // Second 32 bits contain payload length (16), next header type (8), hop limit (8)
+ TUint16 payLoadLen = ByteOrder::Swap16( *ptr++ );
+ TUint16 next = ByteOrder::Swap16( *ptr++ );
+ TUint8 nextHead = (TUint8)((next >> 8) & 0xff);
+ TUint8 hopLimit = (TUint8)(next & 0xff);
+
+ // Source address (128 bits)
+ TUint16 s1 = ByteOrder::Swap16( *ptr++ );
+ TUint16 s2 = ByteOrder::Swap16( *ptr++ );
+ TUint16 s3 = ByteOrder::Swap16( *ptr++ );
+ TUint16 s4 = ByteOrder::Swap16( *ptr++ );
+ TUint16 s5 = ByteOrder::Swap16( *ptr++ );
+ TUint16 s6 = ByteOrder::Swap16( *ptr++ );
+ TUint16 s7 = ByteOrder::Swap16( *ptr++ );
+ TUint16 s8 = ByteOrder::Swap16( *ptr++ );
+
+ // Destination address (128 bits)
+ TUint16 a1 = ByteOrder::Swap16( *ptr++ );
+ TUint16 a2 = ByteOrder::Swap16( *ptr++ );
+ TUint16 a3 = ByteOrder::Swap16( *ptr++ );
+ TUint16 a4 = ByteOrder::Swap16( *ptr++ );
+ TUint16 a5 = ByteOrder::Swap16( *ptr++ );
+ TUint16 a6 = ByteOrder::Swap16( *ptr++ );
+ TUint16 a7 = ByteOrder::Swap16( *ptr++ );
+ TUint16 a8 = ByteOrder::Swap16( *ptr++ );
+
+ //Printf(_L(" Version is %d"),ver); // Should be 6 for IPv6 !!
+ Printf(KIpv6Class, cls);
+ Printf(KIpv6FlowLabel, flowLab);
+ Printf(KIpv6PayloadLen, payLoadLen);
+ Printf(KIpv6NextHeadType, nextHead);
+ Printf(KIpv6HopLimit, hopLimit);
+ Printf(KIpv6SrcAddress, s1,s2,s3,s4,s5,s6,s7,s8);
+ Printf(KIpv6DstAddress, a1,a2,a3,a4,a5,a6,a7,a8);
+
+ TInt n = (TInt)ptr-(TInt)aDes.Ptr();
+ TInt tlen = aDes.Length()-n;
+ aDes.Set( (TUint8*) ptr, tlen);
+
+ switch (nextHead)
+ {
+ case 6: // TCP Packet
+ Printf(_L(" TCP Data"));
+ //DumpTcp(aDes);
+ HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+ break;
+ case 17: // UDP Packet
+ Printf(_L(" UDP Data"));
+ DumpUdp(aDes,s8,a8,tlen);
+ break;
+ case 43: // Routing Header
+ Printf(_L(" Routing Header"));
+ //DumpRouter
+ HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+ break;
+ case 44: // Fragment Header
+ Printf(_L(" Packet Fragment"));
+ //DumpFragment
+ HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+ break;
+ case 50: // ESP Payload
+ Printf(_L(" ESP Payload"));
+ HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+ break;
+ case 58: // ICMPv6
+ Printf(_L(" ICMPv6"));
+ DumpIcmp(aDes,tlen);
+ break;
+ case 59: // No Next Header
+ Printf(_L(" NO NEXT HEADER"));
+ HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+ break;
+ default:
+ Printf(KIpv6UnknownHeadType, nextHead);
+ HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+ }
+
+ return n;
+ }
+
+TInt CPppLog::DumpTcp(TPtrC8& aDes, TUint32 aSrcA, TUint32 aDstA, TInt aLength)
+ {
+
+ TInt n = Min(aLength, aDes.Length());
+ TInt len = n;
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint8 osum0 = ptr[16];
+ ptr[16] = 0;
+ TUint8 osum1 = ptr[17];
+ ptr[17] = 0;
+
+ TUint32 sum = 0;
+ sum += (aSrcA >> 16);
+ sum += (aSrcA & 0xffff);
+ sum += (aDstA >> 16);
+ sum += (aDstA & 0xffff);
+ sum += 6;
+ sum += n;
+ while (n>1)
+ {
+ sum += (ptr[0]<<8);
+ sum += (ptr[1]);
+ ptr += 2;
+ n -= 2;
+ }
+ if (n>0)
+ sum += (ptr[0]<<8);
+ while (sum>0xffff)
+ {
+ sum = (sum & 0xffff) + (sum>>16);
+ }
+ sum = ~sum & 0xffff;
+ ptr = (TUint8*)aDes.Ptr();
+ ptr[16] = osum0;
+ ptr[17] = osum1;
+
+ TUint srcp = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr +=2;
+ TUint dstp = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr +=2;
+ TUint32 seqnum = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+ ptr+=4;
+ TUint32 acknum = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+ ptr+=4;
+
+ TUint16 hlenflag = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+
+ TUint hlen = (hlenflag>>12)<<2;
+ TUint flag = (hlenflag & 0x0fff);
+ TBool cwrf = (hlenflag & 0x0080);
+ TBool ecef = (hlenflag & 0x0040);
+ TBool urgf = (hlenflag & 0x0020);
+ TBool ackf = (hlenflag & 0x0010);
+ TBool pshf = (hlenflag & 0x0008);
+ TBool rstf = (hlenflag & 0x0004);
+ TBool synf = (hlenflag & 0x0002);
+ TBool finf = (hlenflag & 0x0001);
+ ptr+=2;
+ TUint window = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr+=2;
+ TUint chksum = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr+=2;
+ TUint urgptr = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr+=2;
+
+ Printf(KTCPLengthString, len, hlen);
+ Printf(KPortString, srcp, dstp);
+// Printf(KDestPortString, dstp);
+// Printf(KTCPHeaderLengthString, hlen);
+ Printf(KSeqAckString, seqnum, acknum);
+ Printf(KFlagsString, flag, cwrf?_S(" <CWR>"):_S(""),ecef?_S(" <ECE>"):_S(""),urgf?_S(" <URG>"):_S(""), ackf?_S(" <ACK>"):_S(""), pshf?_S(" <PSH>"):_S(""),
+ rstf?_S(" <RST>"):_S(""), synf?_S(" <SYN>"):_S(""), finf?_S(" <FIN>"):_S(""));
+ Printf(KWindowUrgentString, window, urgptr);
+ if (chksum != sum)
+ Printf(KChecksumString3, chksum, sum);
+
+ if (hlen>20)
+ {
+ _LIT(string2," TCP Options %d bytes");
+ Printf(string2, hlen-20);
+ TInt h, i, opt, optlen=0;
+ h = hlen-20;
+ for (i=0; i<h; i+=optlen)
+ {
+ opt = ptr[i];
+ if (opt == 0) // KTcpOptEol
+ break;
+ if (opt == 1) // KTcpOptNop
+ optlen = 1;
+ else
+ {
+ if (i+1 >= h)
+ break;
+ optlen = ptr[i+1];
+ if (optlen < 2)
+ optlen = 2;
+ }
+
+ switch (opt)
+ {
+ case 1:
+ {
+ _LIT(string3," NOP");
+ Write(string3);
+ }
+ break;
+ case 2:
+ {
+ _LIT(string4," Max Seg Size = %d");
+ Printf(string4, BigEndian::Get16(ptr+i+2));
+ }
+ break;
+ default:
+ {
+ _LIT(string5," Unknown [0x%02x]");
+ Printf(string5, opt);
+ }
+ break;
+ }
+ }
+ }
+
+ ptr += (hlen-20);
+ TInt n1 = (TInt)aDes.Ptr()-(TInt)ptr;
+ aDes.Set(ptr, aDes.Length()-n1);
+ return n1;
+ }
+
+TInt CPppLog::DumpIcmp(TPtrC8& aDes, TInt aLength)
+ {
+
+ if (aLength < 2)
+ return 0;
+
+ const TUint8* ptr = aDes.Ptr();
+
+ _LIT(string1," Type = %d, Code = %d");
+ Printf(string1, *ptr, *(ptr+1));
+ HexDump(FOURTEEN_SPACE_MARGIN, FOURTEEN_SPACE_MARGIN, ptr, aLength);
+ return 0;
+ }
+
+TInt CPppLog::DumpUdp(TPtrC8& aDes, TUint32 /* aSrcA */, TUint32 /*aDstA */, TInt aLength)
+ {
+ if (aLength < 6)
+ return 0;
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TUint srcp = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr +=2;
+ TUint dstp = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr +=2;
+ TUint16 len = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr += 2;
+
+ ptr += 2; // skip checksum
+ Printf(KUDPLengthPortString, len, srcp, dstp);
+ //Printf(KPortString, srcp, dstp);
+
+ if (srcp == KDnsPort || dstp == KDnsPort)
+ {
+ UpdatePtr(aDes, ptr);
+ return DumpDns(aDes);
+ }
+
+ // aDes.Set(remptr, remlen);
+ return 0;
+ }
+
+TInt CPppLog::UpdatePtr(TPtrC8& aDes, TUint8* ptr)
+ {
+ TInt n = (TInt)ptr - (TInt)aDes.Ptr();
+ TInt tlen = aDes.Length() - n;
+ aDes.Set(ptr, tlen);
+ return tlen;
+ }
+
+//
+// Dump DNS request/response
+//
+
+TInt CPppLog::DumpDns(TPtrC8& aDes)
+ {
+ if (aDes.Length()< 12)
+ return 0;
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+
+ _LIT(KDnsHdrString, "\t\tDNS Id = 0x%02x, Flags = 0x%02x");
+ _LIT(KDnsQuestionString, "\t\tQuestions = %d");
+ _LIT(KDnsAnswerString, "\t\tAnswers = %d");
+ _LIT(KDnsAuthAddString, "\t\tAuthorities = %d, Additionals = %d");
+
+ TUint Id = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr += 2;
+ TUint Flags = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr += 2;
+
+ Printf(KDnsHdrString, Id, Flags);
+
+ TUint nques = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr += 2;
+ TUint nans = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr += 2;
+ TUint nauth = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr += 2;
+ TUint nadd = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr += 2;
+
+ UpdatePtr(aDes, ptr);
+
+ // Only deal with one query for now due to difficulty of testing
+
+ if (nques > 0)
+ {
+ Printf(KDnsQuestionString, nques);
+ if (DumpDnsQuery(aDes) < 0)
+ return 0;
+ }
+
+ if (nques > 1)
+ return 0;
+
+ if (nans > 0)
+ {
+ Printf(KDnsAnswerString, nans);
+ while (nans-- > 0)
+ if (DumpDnsAnswer(aDes) < 0)
+ return 0;
+ }
+
+ if (nauth > 0 || nadd > 0)
+ Printf(KDnsAuthAddString, nauth, nadd);
+
+ // Write(KEndOfLine);
+
+ // aDes.Set(remptr, remlen);
+ return 0;
+ }
+
+TInt CPppLog::DumpDnsQuery(TPtrC8& aDes)
+ {
+ if (DumpDnsNameAndType(aDes) < 0 || aDes.Length() < 2)
+ return -1;
+
+ UpdatePtr(aDes, (TUint8*) aDes.Ptr() + 2); // skip over class
+
+ return 0;
+ }
+
+TInt CPppLog::DumpDnsAnswer(TPtrC8& aDes)
+ {
+ _LIT(KDnsAnswerResource, "\t\t Resource = %d.%d.%d.%d");
+
+ if (DumpDnsNameAndType(aDes) < 0 || aDes.Length() < 8)
+ return -1;
+
+ // above check guarantees at least Class, TTL and Resource Data Length
+ // fields are present
+
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+
+ ptr += 6; // skip over class and ttl
+
+ TUint resourceLen = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr += 2;
+
+ if ((TUint) aDes.Length() < 8 + resourceLen)
+ return -1;
+
+ if (resourceLen == 4)
+ {
+ // IPv4 address
+ TUint addr = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+ Printf(KDnsAnswerResource, (addr&0xff000000)>>24,(addr&0x00ff0000)>>16,(addr&0x0000ff00)>>8,(addr&0x000000ff));
+ }
+
+ ptr += resourceLen;
+
+ UpdatePtr(aDes, ptr);
+
+ return 0;
+ }
+
+TInt CPppLog::DumpDnsNameAndType(TPtrC8& aDes)
+ {
+ TBuf<120>buf;
+ TUint8* ptr = (TUint8*)aDes.Ptr();
+ TInt length = aDes.Length();
+ TUint count;
+
+ _LIT(KDnsNameString, "\t\t Name = ");
+ _LIT(KDnsDot, ".");
+ _LIT(KDnsNameCompString, "<%d>");
+ _LIT(KDnsType, ", Type = %d");
+
+ const TInt KDnsNameCompStringMaxLen = 7;
+ buf.Append(KDnsNameString);
+
+ if (length < 1)
+ return -1;
+
+ count = *ptr++;
+ length--;
+
+ while (count > 0)
+ {
+
+ // Not dealing with compression yet
+
+ if (count & 0xc0)
+ {
+ if (length > 0)
+ {
+ count = ((count & ~0xc0) << 8) | *ptr++;
+ length--;
+ if (buf.Length() + KDnsNameCompStringMaxLen >= buf.MaxLength())
+ return -1;
+ else
+ {
+ buf.AppendFormat(KDnsNameCompString, count);
+ break;
+ }
+ }
+ else
+ return -1;
+ }
+
+ if (count > 63)
+ return -1;
+
+ if ((TUint)length < count)
+ return -1;
+ length -= count;
+
+ while (count-- > 0)
+ {
+ if (buf.Length() >= buf.MaxLength())
+ return -1;
+ buf.Append(*ptr);
+ ptr++;
+ }
+
+ if (length > 0)
+ {
+ count = *ptr++;
+ length--;
+ if (count > 0)
+ {
+ if (buf.Length() >= buf.MaxLength())
+ return -1;
+ buf.Append(KDnsDot);
+ }
+ }
+ }
+
+ TUint type = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+ ptr += 2;
+ buf.AppendFormat(KDnsType, type);
+
+ Write(buf);
+
+ UpdatePtr(aDes, ptr);
+
+ return 0;
+ }
+
+#endif //ESOCK_LOGGING_ACTIVE