commit fe5b75d4ac40c24486b41f305c4f686a2a1a616b Author: Kelvin Sherlock Date: Mon Jan 14 23:06:45 2019 -0500 initial checkin diff --git a/cda.asm b/cda.asm new file mode 100644 index 0000000..cc88657 --- /dev/null +++ b/cda.asm @@ -0,0 +1,211 @@ +*================================================= +* +* cda.asm - Main code for TCP Snooper CDA +* +* Copyright (C) 2004-2006 Kelvin Sherlock +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*================================================= +* +* 2006.12.02 KS - Initial release as open source +* +*================================================= + + case on + copy /lang/orca/libraries/ainclude/e16.gsos + copy /lang/orca/libraries/ainclude/e16.event + copy /lang/orca/libraries/ainclude/e16.memory + + mcopy cda.mac + + +OS_KIND gequ $e100bc +RD80VID gequ $e0c01f +SET80VID gequ $e0c00d + + +StackSize gequ $0300 + +CDARoot start + + dw 'TCP Snooper' + dc i4'CDAStart' + dc i4'CDAShutDown' + end + +CDAStart start + + using CDAData + + phb + phk + plb + + lda >OS_KIND ;; 00 = prodos, 01 == gsos + and #$00ff + bne gsos + brl exit + +gsos anop + +* allocate $300 of stack space. + + pha + _MMStartUp + pla + sta MyID + + pha + pha + ~NewHandle #StackSize,MyID,#attrLocked+attrFixed+attrBank+attrPage,#0 + bcc gotstack + pla + pla + brl exit + +gotstack anop + + tsc + sta OldStack + tcd + lda [1] + tcd + clc + adc #StackSize-1 + +* copy old stack to new stack + pha + sei + ldx #$fe +sloop lda >$000100,x + sta stack,x + dex + dex + bpl sloop + cli + pla + tcs + + +* short m +* sta >SET80VID +* long m + + pha + pha + pha + _GetInputDevice + + pha + pha + _GetInGlobals + + pha + pha + pha + _GetOutputDevice + + pha + pha + _GetOutGlobals +* + ~SetInputDevice #0,#3 + ~SetInGlobals #$ff,#$80 + + ~SetOutputDevice #0,#3 + ~SetOutGlobals #$ff,#$80 + + ~InitTextDev #0 + ~InitTextDev #1 + + + ~WriteChar #$0C + + jsl netstat + +* restore, arguments already on stack. + + _SetOutGlobals + _SetOutputDevice + _SetInGlobals + _SetInputDevice + + ~InitTextDev #0 + ~InitTextDev #1 + + +* restore old stack + sei + ldx #$fe +rloop lda stack,x + sta >$000100,x + dex + dex + bpl rloop + lda OldStack + tcs + cli + _DisposeHandle ; * handle still on stack. + + +exit anop + plb + +CDAShutDown entry + rtl + end + +GetKey start + using CDAData + + pea 0 + _EMStatus + pla + beq metal + +evloop anop + pha + ~GetNextEvent #keyDownMask+autoKeyMask,#Event + pla + beq evloop + lda Event+omessage + rtl + +metal anop + + short m + +mloop anop + + lda >$e0c0000 + bpl mloop + sta >$e0c010 + + long m + and #$007f + rtl + end + + + +CDAData data + +MyID ds 2 +OldStack ds 2 + +Event ds 16 +stack ds 256 + end diff --git a/debug.c b/debug.c new file mode 100644 index 0000000..29a6d5b --- /dev/null +++ b/debug.c @@ -0,0 +1,378 @@ +/*================================================= +* +* debug.c - Code to dump Marinetti internals for TCP Snooper CDA +* +* Copyright (C) 2004-2006 Kelvin Sherlock +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*================================================= +* +* 2006.12.02 KS - Initial release as open source +* +*=================================================*/ + +#pragma noroot +#pragma lint -1 +#pragma optimize -1 +#pragma debug 0x8000 + +#include +#include +#include +#include +#include +#include +#include + + +extern int fdprintf(int, const char *, ...); +extern int orca_sprintf(char *, const char *, ...); + +char *errStrings[] = +{ +"tcpDGMSTBLEN", +"tcpDGMSTOTAL", +"tcpDGMSFRAGSIN", +"tcpDGMSFRAGSLOST", +"tcpDGMSBUILT", +"tcpDGMSOK", +"tcpDGMSBADCHK", +"tcpDGMSBADHEADLEN", +"tcpDGMSBADPROTO", +"tcpDGMSBADIP", +"tcpDGMSICMP", +"tcpDGMSICMPUSER", +"tcpDGMSICMPKERNEL", +"tcpDGMSICMPBAD", +"tcpDGMSICMPBADTYPE", +"tcpDGMSICMPBADCODE", +"tcpDGMSICMPECHORQ", +"tcpDGMSICMPECHORQOUT", +"tcpDGMSICMPECHORP", +"tcpDGMSICMPECHORPBADID", + +"tcpDGMSUDP", +"tcpDGMSUDPBAD", +"tcpDGMSUDPNOPORT", + +"tcpDGMSTCP", +"tcpDGMSTCPBAD", +"tcpDGMSTCPNOPORT", +"tcpDGMSTCPQUEUED", +"tcpDGMSTCPOLD", +"tcpDGMSOFRAGMENTS" +"tcpDGMSFRAGMENTED" +}; + +char *tuneStrings[] = +{ +"tcpTUNECOUNT", +"tcpTUNEIPUSERPOLLCT", +"tcpTUNEIPRUNQFREQ", +"tcpTUNEIPRUNQCT", +"tcpTUNETCPUSERPOLL" +}; + + + +long write(Word fd, const void *data, LongWord size) +{ +static IORecGS ioDCB = { 4, 0, 0, 0}; + + ioDCB.refNum = fd; + ioDCB.dataBuffer = (Pointer)data; + ioDCB.requestCount = size; + + WriteGS(&ioDCB); + return _toolErr ? -1 : ioDCB.transferCount; +} + + +// creates a unique file and opens it. +int createFile(void) +{ +static GSString32 template = {28, "*:system:tcpip:debugxxxx.txt"}; +static CreateRecGS createDCB = {4, (GSString255Ptr)&template, 0xe3, 4, 0}; +static OpenRecGS openDCB = {4, 0, (GSString255Ptr)&template, writeEnable, 0}; + +word i; + + for (i = 0; i < 9999; i++) + { + + Int2Dec(i, &template.text[20], 4, 0); + template.text[20] |= 0x10; // convert ' ' (0x20) to '0' (0x30) + template.text[21] |= 0x10; + template.text[22] |= 0x10; + template.text[23] |= 0x10; + + + CreateGS(&createDCB); + if (_toolErr == dupPathname) continue; + break; + } + + if (_toolErr) return 0; + + OpenGS(&openDCB); + if (_toolErr) return 0; + + return openDCB.refNum; +} + +void dump(Word fd, void *data, Word length) +{ +Word i; +Word j; +Word k; +static char buffer[80]; + + + for (i = 0, j = 0; i < length; i++) + { + + k = ((char *)data)[i]; + buffer[j++] = "0123456789abcdef"[k >> 4]; + buffer[j++] = "0123456789abcdef"[k & 0x0f]; + buffer[j++] = ' '; + + if ((i & 0x0f) == 0x07) buffer[j++] = ' '; + + if ((i & 0x0f) == 0x0f) + { + buffer[j++] = 0; + + fdprintf(fd, "%04x: %s\r", i - 15, buffer); + //write(fd, buffer, j); + j = 0; + } + } + + if (i & 0x0f) + { + buffer[j++] = 0; + fdprintf(fd, "%04x: %s\r", i - 15, buffer); + //write(fd, buffer, j); + } + +} + + + +void debug(void) +{ + +Word i; +Long l; + +LongWord *lw; +variablesPtr lv; + +static Word tune[5]; +static linkInfoBlk link; +static char buffer[80]; +static DNSRec dns; +static udpVars udp; +static srBuff tcp; + + +Word count; +Handle h; +Word size; +Word fd; +Word closeDCB[2]; + + + fd = createFile(); + if (fd == 0) return; + + // version + VersionString(0, TCPIPLongVersion(), buffer); + fdprintf(fd, "Version: %b\r", buffer); + + // link layer + TCPIPGetLinkLayer(&link); + fdprintf(fd, "Link Layer:\r"); + fdprintf(fd, " MethodID: $%04x\r", link.liMethodID); + fdprintf(fd, " Name: %b\r", link.liName); + VersionString(0, link.liVersion, buffer); + fdprintf(fd, " Version: %b\r", buffer); + fdprintf(fd, " Flags: $%04x\r", link.liFlags); + + lv = TCPIPGetLinkVariables(); + fdprintf(fd, "Link Variables\r"); + fdprintf(fd, " Version: %d\r", lv->lvVersion); + fdprintf(fd, " Connected: $%04x\r", lv->lvConnected); + TCPIPConvertIPToASCII(lv->lvIPaddress, buffer, 0); + fdprintf(fd, " IP Address: %b\r", buffer); + fdprintf(fd, " RefCon: $%08lx\r", lv->lvRefCon); + fdprintf(fd, " Errors: $%08lx\r", lv->lvErrors); + fdprintf(fd, " MTU: %d\r", lv->lvMTU); + + + // connect status + fdprintf(fd, "Connect Status: $%04x\r", TCPIPGetConnectStatus()); + + // ip address + l = TCPIPGetMyIPAddress(); + TCPIPConvertIPToASCII(l, buffer, 0); + fdprintf(fd, "IP Address: %b\r", buffer); + + // dns + TCPIPGetDNS(&dns); + TCPIPConvertIPToASCII(dns.DNSMain, buffer, 0); + fdprintf(fd, "DNS 1: %b\r", buffer); + TCPIPConvertIPToASCII(dns.DNSAux, buffer, 0); + fdprintf(fd, "DNS 2: %b\r", buffer); + + // hostname + TCPIPGetHostName((hnBuffPtr)buffer); + fdprintf(fd, "Hostname: %b\r", buffer); + + //mtu + fdprintf(fd, "MTU: %d\r", TCPIPGetMTU()); + fdprintf(fd, "Alive Flag: $%04x\r", TCPIPGetAliveFlag()); + fdprintf(fd, "Alive Minutes: %d\r", TCPIPGetAliveMinutes()); + fdprintf(fd, "Login Count: %d\r", TCPIPGetLoginCount()); + + + + // error table + fdprintf(fd, "\rError Table\r"); + lw = (LongWord *)TCPIPGetErrorTable(); + count = lw[0] >> 2; + if (count > sizeof(errStrings) / 4) count = sizeof(errStrings) / 4; + + for (i = 0; i < count; i++); + { + fdprintf(fd, " %s -- $%08lx\r", errStrings[i], lw[i]); + } + + // tuning table + tune[0] = 10; + + fdprintf(fd, "\rTuning Table\r"); + TCPIPGetTuningTable((tunePtr)tune); + count = tune[0] >> 1; + if (count > sizeof(tuneStrings) / 4) count = sizeof(tuneStrings) / 4; + for (i = 0; i < count; i++) + { + fdprintf(fd, " %s -- $%04x\r", tuneStrings[i], tune[i]); + } + + fdprintf(fd, "\rDirect Page\r"); + dump(fd, (void *)TCPIPGetDP(), 0x0100); + + // dump all user records. ipid will be even numbers in the range 0..98 + for (i = 0; i < 100; i += 2) + { + h = (Handle)TCPIPGetUserRecord(i); + if (h == NULL) continue; + size = (Word)GetHandleSize(h); + if (_toolErr) continue; + + + fdprintf(fd, "\rIpid %d\r", i); + + fdprintf(fd, "Datagram count (all): %d\r", + TCPIPGetDatagramCount(i, protocolAll)); + + fdprintf(fd, "Datagram count (icmp): %d\r", + TCPIPGetDatagramCount(i, protocolICMP)); + + fdprintf(fd, "Datagram count (tcp): %d\r", + TCPIPGetDatagramCount(i, protocolTCP)); + + fdprintf(fd, "Datagram count (udp): %d\r", + TCPIPGetDatagramCount(i, protocolUDP)); + + + fdprintf(fd, "User statistic 1: $%08lx\r", + TCPIPGetUserStatistic(i, 1)); + + fdprintf(fd, "User statistic 2: $%08lx\r", + TCPIPGetUserStatistic(i, 2)); + +#if 0 // tcpipStatusUDP has a stack imbalance bug. + + TCPIPStatusUDP(i, &udp); + if (_toolErr == 0) + { + fdprintf(fd, "\rStatus UDP\r"); + fdprintf(fd, " Queue Size: %d\r", udp.uvQueueSize); + fdprintf(fd, " Error: %d\r", udp.uvError); + fdprintf(fd, " Error Tick: %ld\r", udp.uvErrorTick); + fdprintf(fd, " Count: %ld\r", udp.uvCount); + fdprintf(fd, " Total Count: %ld\r", udp.uvTotalCount); + fdprintf(fd, " Dispatch Flag: %d\r", udp.uvDispatchFlag); + + } +#endif + + TCPIPStatusTCP(i, &tcp); + if (_toolErr == 0) + { + fdprintf(fd, "\rStatus TCP\r"); + fdprintf(fd, " State: %d\r", tcp.srState); + fdprintf(fd, " Network Error: %d\r", tcp.srNetworkError); + fdprintf(fd, " Send Queued: %ld\r", tcp.srSndQueued); + fdprintf(fd, " Recv Queued: %ld\r", tcp.srRcvQueued); + TCPIPConvertIPToASCII(tcp.srDestIP, buffer, 0); + fdprintf(fd, " Dest IP: %b\r", buffer); + fdprintf(fd, " Dest Port: %d\r", tcp.srDestPort); + fdprintf(fd, " Connect Type: %d\r", tcp.srConnectType); + fdprintf(fd, " Accept Count: %d\r", tcp.srAcceptCount); + } + + + HLock(h); + if (1) // (size == sizeof(userRecord)) + { + GSString255Ptr appName; + userRecord *rec = (userRecord *)*h; + fdprintf(fd, "\rUser Record\r"); + appName = (GSString255Ptr)LGetPathname2(rec->uwUserID, 1); + if (_toolErr == 0) + { + fdprintf(fd, "\rApplication %B\r", appName); + } + #include "ur.c" + } + else dump(fd, *h, size); + HUnlock(h); + } + + closeDCB[0] = 1; + closeDCB[1] = fd; + CloseGS(closeDCB); + + +} + + + +#if 0 + +void _beginStackCheck (void); +int _endStackCheck (void); + +void main (void) +{ + _beginStackCheck(); + debug(); + fdprintf(2, "%d bytes of stack used\r", _endStackCheck()); +} +#endif diff --git a/makefile.mk b/makefile.mk new file mode 100644 index 0000000..f6aa50f --- /dev/null +++ b/makefile.mk @@ -0,0 +1,47 @@ +#================================================= +# +# makefile.mk - build file for TCP Snooper CDA and netstat command line tool +# +# Copyright (C) 2004-2006 Kelvin Sherlock +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +#================================================= +# +# 2006.12.02 KS - Initial release as open source +# +#================================================= + +#for use with dmake(1) +# for compiling netstat and tcpsnooper.cda + +# Requires Kelvin's modified Orca C library to be present in the current directory. +# Kelvin's modified Orca C library includes an implementation of fdprintf() + +CFLAGS += $(DEFINES) -v #-O +LDLIBS += -l liborca + +netstat: netstat.o + $(CC) $(LDFLAGS) netstat.o $(LDLIBS) -o $@ + +tcpsnooper.cda: cda.o nscda.o debug.o + $(CC) $(LDFLAGS) cda.o nscda.o debug.o $(LDLIBS) -o $@ + chtyp -t cda $@ + +clean: + $(RM) *.o *.root *.r + +clobber: clean + $(RM) -f netstat netstat.cda diff --git a/netstat.c b/netstat.c new file mode 100644 index 0000000..df595f0 --- /dev/null +++ b/netstat.c @@ -0,0 +1,273 @@ +/*================================================= +* +* netstat.c - Code to dump network statistics for command line +* +* Copyright (C) 2004-2006 Kelvin Sherlock +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*================================================= +* +* 2006.12.02 KS - Initial release as open source +* +*=================================================*/ + +#pragma lint -1 +#pragma optimize -1 + +#ifdef CDA +#pragma noroot +#endif + +#include +//#include +#include +#include + +//#include + +extern pascal void __gsos(void *, word) inline(0, 0xe100b0); + +#undef ReadGS +#undef WriteGS + +#define ReadGS(parm) __gsos(parm, 0x2012) +#define WriteGS(parm) __gsos(parm, 0x2013) + + +extern Word GetKey(void); + + +static IORecGS ioDCB; + +const char Header1[] = +" Ipid State Address sPort dPort RcvQueue SendQueue\r"; +const char Header2[] = +" ---- ----- ------- ----- ----- --------- ---------\r"; +///xxxxx xxxxxxxxxxx xxx.xxx.xxx.xxx xxxxx xxxxx $xxxxxxxx $xxxxxxxx + +void Display(Word ipid, srBuff *srBuffer) +{ +static char buffer[80] = +"xxxxx " // 6 ipid +"xxxxxxxxxxx " // 12 state +"xxx.xxx.xxx.xxx " // 16 address +"xxxxx " // 6 source port +"xxxxx " // 6 dest port +"$xxxxxxxx " // 10 rcv queue +"$xxxxxxxx "; // 10 send queue +static char buffer16[16]; + +static char *stateStr = +"CLOSED " +"LISTEN " +"SYNSENT " +"SYNRCVD " +"ESTABLISHED " +"FINWAIT1 " +"FINWAIT2 " +"CLOSEWAIT " +"LASTACK " +"CLOSING " +"TIMEWAIT " +"UNKOWN "; + +static destRec dest; + +char *cp; +Word i,j; + + + TCPIPGetDestination(ipid, &dest); + + for (i = 0; i < 80; i++) buffer[i] = ' '; + + Int2Dec(ipid, buffer, 5, 0); + + cp = buffer + 6; + + i = srBuffer->srState; + if (i > 10) i = 11; + + i *= 12; // sizeof the string... + for (j = 0; j < 12; j++) + *cp++ = stateStr[i + j]; + + cp = buffer + 18; + + // includes the last space, so we're ok. + + TCPIPConvertIPToCASCII(srBuffer->srDestIP, buffer16, 0); + for (j = 0; buffer16[j]; j++) + *cp++ = buffer16[j]; + + + i = TCPIPGetSourcePort(ipid); + Int2Dec(i, buffer + 34, 5, 0); + + Int2Dec(srBuffer->srDestPort, buffer + 40, 5, 0); + + buffer[46] = '$'; + Long2Hex(srBuffer->srRcvQueued, buffer + 47, 8); + + buffer[56] = '$'; + Long2Hex(srBuffer->srSndQueued, buffer + 57, 8); + + buffer[66] = '\r'; + + ioDCB.dataBuffer = buffer; + ioDCB.requestCount = 67; + WriteGS(&ioDCB); +} + +void netstat(Word fd) +{ +Word i; +Word count; + +static srBuff srBuffer; + +#ifdef CDA +Word line = 0; +char c; +#endif + + + ioDCB.pCount = 5; + ioDCB.refNum = fd; + ioDCB.cachePriority = 0; + + #ifdef CDA + + #define xstr "\x0c" // 80 column on, clear screen + ioDCB.dataBuffer = xstr; + ioDCB.requestCount = sizeof(xstr) - 1; + WriteGS(&ioDCB); + #undef xstr + + #endif + + if (TCPIPStatus() == 0 || _toolErr) + { + #define xstr "Marinetti is not active\r" + ioDCB.dataBuffer = xstr; + ioDCB.requestCount = sizeof(xstr) - 1; + WriteGS(&ioDCB); + #undef xstr + + #ifdef CDA + //ioDCB.requestCount = 1; + //ioDCB.dataBuffer = &c; + //ReadGS(&ioDCB); + c = GetKey(); + #endif + + return; + } + + ioDCB.dataBuffer = Header1; + ioDCB.requestCount = sizeof(Header1) - 1; + WriteGS(&ioDCB); + + ioDCB.dataBuffer = Header2; + ioDCB.requestCount = sizeof(Header2) - 1; + WriteGS(&ioDCB); + + #ifdef CDA + line = 2; + #endif + + count = TCPIPGetLoginCount(); + if (count) + { + Word found; + + // Marinetti v3 has a maximum table size of 100. + for (found = 0, i = 0; i < 100; i++) + { + TCPIPStatusTCP(i, &srBuffer); + if (_toolErr) continue; + + #ifdef CDA + line++; + if (line == 24) + { + #define xstr "-- more --" + ioDCB.dataBuffer = xstr; + ioDCB.requestCount = sizeof(xstr) - 1; + WriteGS(&ioDCB); + #undef xstr + + //ioDCB.requestCount = 1; + //ioDCB.dataBuffer = &c; + //ReadGS(&ioDCB); + c = GetKey(); + + //if (c == 0x0d) // return == scroll 1 line. + //{ + // // ^Z == clear line + // #define xstr "\Z" + // ioDCB.dataBuffer = xstr; + // ioDCB.requestCount = sizeof(xstr) - 1; + // WriteGS(&ioDCB); + // #undef xstr + // + // line--; + //} + if (c == ' ' || c == 0x0d) // space == scroll new page. + { + // ^L == clear screen. + #define xstr "\x0c" + ioDCB.dataBuffer = xstr; + ioDCB.requestCount = sizeof(xstr) - 1; + WriteGS(&ioDCB); + #undef xstr + + line = 2; + + ioDCB.dataBuffer = Header1; + ioDCB.requestCount = sizeof(Header1) - 1; + WriteGS(&ioDCB); + + ioDCB.dataBuffer = Header2; + ioDCB.requestCount = sizeof(Header2) - 1; + WriteGS(&ioDCB); + } + else return; + + } + #endif + + Display(i, &srBuffer); + found++; + if (found == count) break; + } + } + #ifdef CDA + //ioDCB.requestCount = 1; + //ioDCB.dataBuffer = &c; + //ReadGS(&ioDCB); + c = GetKey(); + #endif +} + + +#ifndef CDA +int main(int argc, char **argv) +{ + netstat(2); // 2 = stdout + return 0; +} +#endif diff --git a/nscda.c b/nscda.c new file mode 100644 index 0000000..6b35ebe --- /dev/null +++ b/nscda.c @@ -0,0 +1,182 @@ +/*================================================= +* +* nscda.c - Code to dump network statistics for CDA +* +* Copyright (C) 2004-2006 Kelvin Sherlock +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*================================================= +* +* 2006.12.02 KS - Initial release as open source +* +*=================================================*/ + +#pragma lint -1 +#pragma optimize -1 + +#pragma noroot + +#include +#include +#include + + +extern Word GetKey(void); +extern void debug(void); + +const char Header1[] = +" Ipid State Address sPort dPort RcvQueue SendQueue\r"; +const char Header2[] = +" ---- ----- ------- ----- ----- --------- ---------\r"; +///xxxxx xxxxxxxxxxx xxx.xxx.xxx.xxx xxxxx xxxxx $xxxxxxxx $xxxxxxxx + +void Display(Word ipid, srBuff *srBuffer) +{ +static char buffer[80] = +"xxxxx " // 6 ipid +"xxxxxxxxxxx " // 12 state +"xxx.xxx.xxx.xxx " // 16 address +"xxxxx " // 6 source port +"xxxxx " // 6 dest port +"$xxxxxxxx " // 10 rcv queue +"$xxxxxxxx "; // 10 send queue +static char buffer16[16]; + +static char *stateStr = +"CLOSED " +"LISTEN " +"SYNSENT " +"SYNRCVD " +"ESTABLISHED " +"FINWAIT1 " +"FINWAIT2 " +"CLOSEWAIT " +"LASTACK " +"CLOSING " +"TIMEWAIT " +"UNKOWN "; + +static destRec dest; + +char *cp; +Word i,j; + + + TCPIPGetDestination(ipid, &dest); + + for (i = 0; i < 80; i++) buffer[i] = ' '; + + Int2Dec(ipid, buffer, 5, 0); + + cp = buffer + 6; + + i = srBuffer->srState; + if (i > 10) i = 11; + + i *= 12; // sizeof the string... + for (j = 0; j < 12; j++) + *cp++ = stateStr[i + j]; + + cp = buffer + 18; + + // includes the last space, so we're ok. + + TCPIPConvertIPToCASCII(srBuffer->srDestIP, buffer16, 0); + for (j = 0; buffer16[j]; j++) + *cp++ = buffer16[j]; + + + i = TCPIPGetSourcePort(ipid); + Int2Dec(i, buffer + 34, 5, 0); + + Int2Dec(srBuffer->srDestPort, buffer + 40, 5, 0); + + buffer[46] = '$'; + Long2Hex(srBuffer->srRcvQueued, buffer + 47, 8); + + buffer[56] = '$'; + Long2Hex(srBuffer->srSndQueued, buffer + 57, 8); + + buffer[66] = '\r'; + buffer[67] = 0; + + WriteCString(buffer); + +} + +void netstat(void) +{ +Word i; +Word count; + +static srBuff srBuffer; + +Word line = 0; +char c; + + + if (TCPIPStatus() == 0 || _toolErr) + { + WriteCString("Marinetti is not active\r"); + c = GetKey(); + return; + } + + WriteCString(Header1); + WriteCString(Header2); + + line = 2; + + count = TCPIPGetLoginCount(); + if (count) + { + Word found; + + // Marinetti v3 has a maximum table size of 100. + for (found = 0, i = 0; i < 100; i += 2) + { + TCPIPStatusTCP(i, &srBuffer); + if (_toolErr) continue; + + line++; + if (line == 24) + { + WriteCString("-- more --"); + + c = GetKey(); + + if (c == ' ' || c == 0x0d) // space == scroll new page. + { + // ^L == clear screen. + WriteChar(0x0c); + + WriteCString(Header1); + WriteCString(Header2); + line = 2; + } + else return; + + } + + Display(i, &srBuffer); + found++; + if (found == count) break; + } + } + WriteCString("\rQ: Quit. D: Save debug file"); + c = GetKey(); + if (c == 'D' || c == 'd') debug(); +} diff --git a/readme b/readme new file mode 100644 index 0000000..48e0af6 --- /dev/null +++ b/readme @@ -0,0 +1,41 @@ +TCP Snooper + +TCP Snooper is a Classic Desk Accessory (CDA) which shows some information on all currently active Marinetti TCP connections. It is useful if youUre programming or debugging a TCP program, or if you just like to know whatUs going on with your system. + +Information shown includes the ipid, state, address. source port, destination port, and how much data is in the receive queue and send queue. + +Kelvin Sherlock, 2004-2006 + + +How To Build TCP Snooper +====================== + +TCP Snooper is written in Orca/C and Orca/M, therefore you will need both Orca/C and Orca/M to be able to build this utility. + +To be able to follow these instructions without modification, you will need to have the the GNO/ME environment installed. It should also be possible to build the utility using the Orca environment, however no instructions are provided on how to do this. + +Prerequisites +------------ +Kelvin has modified his liborca library to include an implementation of fdprintf() which is used by TCP Snooper. Kelvin's modified liborca library cannot be released as part of the Marinetti Open Source Project, but it is required to be able to build TCP Snooper. + +You can download Kelvin's Orca library from http://iigs.ksherlock.com/liborca/ +Place it in the same directory as the TCP Snooper source code. + +You also need to generate the macro file that is used by the source code. + +If you are using GNO/ME you can do this with the following command: +macgen cda.mac /lang/orca/libraries/ainclude/m16.* /lang/orca/libraries/orcainclude/m16.tools /lang/orca/libraries/ainclude/m16.orca + +If you are using Orca: +macgen cda.mac 2:ainclude:m16.= 2:orcainclude:m16.tools 2:orcainclude:m16.orca + + +Build TCPSnooper +--------------- +A makefile for use with dmake is provided. dmake should be installed in your GNO/ME environment. + +The makefile can be used to make either the command line version or the CDA version of the utility. + +dmake netstat --> creates command line version +dmake tcpsnooper.cda -->creates CDA version + diff --git a/ur.c b/ur.c new file mode 100644 index 0000000..59cb493 --- /dev/null +++ b/ur.c @@ -0,0 +1,84 @@ +/*================================================= +* +* ur.c - Code to dump Marinetti user record for TCP Snooper CDA +* +* Copyright (C) 2004-2006 Kelvin Sherlock +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*================================================= +* +* 2006.12.02 KS - Initial release as open source +* +*=================================================*/ + +fdprintf(fd, " uwUserID: %04x\r", rec->uwUserID); +fdprintf(fd, " uwDestIP: %08lx\r", rec->uwDestIP); +fdprintf(fd, " uwDestPort: %04x\r", rec->uwDestPort); +fdprintf(fd, " uwIP_TOS: %04x\r", rec->uwIP_TOS); +fdprintf(fd, " uwIP_TTL: %04x\r", rec->uwIP_TTL); + +fdprintf(fd, " uwSourcePort: %04x\r", rec->uwSourcePort); +fdprintf(fd, " uwLogoutPending: %04x\r", rec->uwLogoutPending); +fdprintf(fd, " uwICMPQueue: %08lx\r", rec->uwICMPQueue); +fdprintf(fd, " uwTCPQueue: %08lx\r", rec->uwTCPQueue); + +fdprintf(fd, " uwTCPMaxSendSeg: %04x\r", rec->uwTCPMaxSendSeg); +fdprintf(fd, " uwTCPMaxReceiveSeg: %04x\r", rec->uwTCPMaxReceiveSeg); +fdprintf(fd, " uwTCPDataInQ: %08lx\r", rec->uwTCPDataInQ); +fdprintf(fd, " uwTCPDataIn: %08lx\r", rec->uwTCPDataIn); +fdprintf(fd, " uwTCPPushInFlag: %04x\r", rec->uwTCPPushInFlag); +fdprintf(fd, " uwTCPPushInOffset: %08lx\r", rec->uwTCPPushInOffset); +fdprintf(fd, " uwTCPPushOutFlag: %04x\r", rec->uwTCPPushOutFlag); +fdprintf(fd, " uwTCPPushOutSEQ: %08lx\r", rec->uwTCPPushOutSEQ); +fdprintf(fd, " uwTCPDataOut: %08lx\r", rec->uwTCPDataOut); +fdprintf(fd, " uwSND_UNA: %08lx\r", rec->uwSND_UNA); +fdprintf(fd, " uwSND_NXT: %08lx\r", rec->uwSND_NXT); +fdprintf(fd, " uwSND_WND: %04x\r", rec->uwSND_WND); +fdprintf(fd, " uwSND_UP: %04x\r", rec->uwSND_UP); +fdprintf(fd, " uwSND_WL1: %08lx\r", rec->uwSND_WL1); +fdprintf(fd, " uwSND_WL2: %08lx\r", rec->uwSND_WL2); +fdprintf(fd, " uwISS: %08lx\r", rec->uwISS); +fdprintf(fd, " uwRCV_NXT: %08lx\r", rec->uwRCV_NXT); +fdprintf(fd, " uwRCV_WND: %04x\r", rec->uwRCV_WND); +fdprintf(fd, " uwRCV_UP: %04x\r", rec->uwRCV_UP); +fdprintf(fd, " uwIRS: %08lx\r", rec->uwIRS); +fdprintf(fd, " uwTCP_State: %04x\r", rec->uwTCP_State); +fdprintf(fd, " uwTCP_StateTick: %08lx\r", rec->uwTCP_StateTick); +fdprintf(fd, " uwTCP_ErrCode: %04x\r", rec->uwTCP_ErrCode); +fdprintf(fd, " uwTCP_ICMPError: %04x\r", rec->uwTCP_ICMPError); +fdprintf(fd, " uwTCP_Server: %04x\r", rec->uwTCP_Server); +fdprintf(fd, " uwTCP_ChildList: %08lx\r", rec->uwTCP_ChildList); +fdprintf(fd, " uwTCP_ACKPending: %04x\r", rec->uwTCP_ACKPending); +fdprintf(fd, " uwTCP_ForceFIN: %04x\r", rec->uwTCP_ForceFIN); +fdprintf(fd, " uwTCP_FINSEQ: %08lx\r", rec->uwTCP_FINSEQ); +fdprintf(fd, " uwTCP_MyFINACKed: %04x\r", rec->uwTCP_MyFINACKed); +fdprintf(fd, " uwTCP_Timer: %08lx\r", rec->uwTCP_Timer); +fdprintf(fd, " uwTCP_TimerState: %04x\r", rec->uwTCP_TimerState); +fdprintf(fd, " uwTCP_rt_timer: %04x\r", rec->uwTCP_rt_timer); +fdprintf(fd, " uwTCP_2MSL_timer: %04x\r", rec->uwTCP_2MSL_timer); +fdprintf(fd, " uwTCP_SaveTTL: %04x\r", rec->uwTCP_SaveTTL); +fdprintf(fd, " uwTCP_SaveTOS: %04x\r", rec->uwTCP_SaveTOS); +fdprintf(fd, " uwTCP_TotalIN: %08lx\r", rec->uwTCP_TotalIN); +fdprintf(fd, " uwTCP_TotalOUT: %08lx\r", rec->uwTCP_TotalOUT); + +fdprintf(fd, " uwUDP_Server : %04x\r", rec->uwUDP_Server); +fdprintf(fd, " uwUDPQueue : %08lx\r", rec->uwUDPQueue); +fdprintf(fd, " uwUDPError : %04x\r", rec->uwUDPError); +fdprintf(fd, " uwUDPErrorTick : %08lx\r", rec->uwUDPErrorTick); +fdprintf(fd, " uwUDPCount : %08lx\r", rec->uwUDPCount); + +fdprintf(fd, " uwTriggers[0]: %08lx\r", rec->uwTriggers[0]); +fdprintf(fd, " uwSysTriggers[0]: %08lx\r", rec->uwSysTriggers[0]);