initial checkin

This commit is contained in:
Kelvin Sherlock 2019-01-14 23:06:45 -05:00
commit fe5b75d4ac
7 changed files with 1216 additions and 0 deletions

211
cda.asm Normal file
View File

@ -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

378
debug.c Normal file
View File

@ -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 <gsos.h>
#include <tcpip.h>
#include <tcpipx.h>
#include <memory.h>
#include <intmath.h>
#include <loader.h>
#include <misctool.h>
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

47
makefile.mk Normal file
View File

@ -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

273
netstat.c Normal file
View File

@ -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 <intmath.h>
//#include <texttool.h>
#include <tcpip.h>
#include <gsos.h>
//#include <unistd.h>
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

182
nscda.c Normal file
View File

@ -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 <intmath.h>
#include <texttool.h>
#include <tcpip.h>
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();
}

41
readme Normal file
View File

@ -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

84
ur.c Normal file
View File

@ -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]);