/*================================================= * * 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 cda "TCP Snooper" StartUp ShutDown #include #include #include #include #include #include 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; fputs(buffer, stdout); } asm int ReadKey(void) { sep #0x20 loop: lda >0xe0c000 bpl loop sta >0xe0c010 rep #0x20 and #0x7f rtl } /* ORCA Console control codes */ #define CURSOR_ON 0x05 #define CURSOR_OFF 0x06 /* cursor keys */ #define LEFT 0x80 #define RIGHT 0x15 #define UP 0x0b #define DOWN 0x0a #define ESC 0x1b int ReadInt(void) { unsigned i = 0; unsigned c; unsigned rv; putchar(CURSOR_ON); while (1) { c = ReadKey(); if (c == 0x1b) { rv = -1; break; } if (c == 13) { if (i == 0) rv = -1; break; } else if ((c == 8) || (c == 0x7f)) { if (i) { putchar(8); putchar(' '); putchar(8); i--; rv /= 10; } } else if ((c >= '0') && (c <= '9')) { if (i < 5) { putchar(c); i++; rv *= 10; rv += c - '0'; } else SysBeep(); } } putchar(CURSOR_OFF); return rv; } static char buffer[80]; void DisplayLinkLayer(void) { static linkInfoBlk link; variablesPtr lv; unsigned c; TCPIPGetLinkLayer(&link); //WriteChar(0x0c); putchar(0x0c); printf("Link Layer:\r"); printf(" MethodID: $%04x\r", link.liMethodID); printf(" Name: %b\r", link.liName); VersionString(0, link.liVersion, buffer); printf(" Version: %b\r", buffer); printf(" Flags: $%04x\r", link.liFlags); fputs("\r", stdout); lv = TCPIPGetLinkVariables(); printf("Link Variables\r"); printf(" Version: %d\r", lv->lvVersion); printf(" Connected: $%04x\r", lv->lvConnected); TCPIPConvertIPToASCII(lv->lvIPaddress, buffer, 0); printf(" IP Address: %b\r", buffer); printf(" RefCon: $%08lx\r", lv->lvRefCon); printf(" Errors: $%08lx\r", lv->lvErrors); printf(" MTU: %d\r", lv->lvMTU); ReadKey(); } void DisplayTCP(void) { static DNSRec dns; Long l; unsigned c; WriteChar(0x0c); putchar(0x0c); // version VersionString(0, TCPIPLongVersion(), buffer); printf("Version: %b\r", buffer); printf("Connect Status: $%04x\r", TCPIPGetConnectStatus()); // ip address l = TCPIPGetMyIPAddress(); TCPIPConvertIPToASCII(l, buffer, 0); printf("IP Address: %b\r", buffer); // dns TCPIPGetDNS(&dns); TCPIPConvertIPToASCII(dns.DNSMain, buffer, 0); printf("DNS 1: %b\r", buffer); TCPIPConvertIPToASCII(dns.DNSAux, buffer, 0); printf("DNS 2: %b\r", buffer); // hostname TCPIPGetHostName((hnBuffPtr)buffer); printf("Hostname: %b\r", buffer); // mtu printf("MTU: %d\r", TCPIPGetMTU()); printf("Alive Flag: $%04x\r", TCPIPGetAliveFlag()); printf("Alive Minutes: %d\r", TCPIPGetAliveMinutes()); printf("Login Count: %d\r", TCPIPGetLoginCount()); ReadKey(); } unsigned DisplayIpid(unsigned ipid) { /* extended debug information */ Handle h; Word size; unsigned page = 0; putchar(0x0c); printf("IPID: %d\r", ipid); h = (Handle)TCPIPGetUserRecord(ipid); if (_toolErr) return; if (!h) return; size = (Word)GetHandleSize(h); printf("Datagram count (all): %d\r", TCPIPGetDatagramCount(ipid, protocolAll)); printf("Datagram count (icmp): %d\r", TCPIPGetDatagramCount(ipid, protocolICMP)); printf("Datagram count (tcp): %d\r", TCPIPGetDatagramCount(ipid, protocolTCP)); printf("Datagram count (udp): %d\r", TCPIPGetDatagramCount(ipid, protocolUDP)); printf("User statistic 1: $%08lx\r", TCPIPGetUserStatistic(ipid, 1)); printf("User statistic 2: $%08lx\r", TCPIPGetUserStatistic(ipid, 2)); GetKey(); } unsigned DisplayMain(void) { Word count; static srBuff srBuffer; Word line = 0; Word ipid; char c; ipid = 0; count = TCPIPGetLoginCount(); redraw: putchar(0x0c); fputs(Header1, stdout); fputs(Header2, stdout); line = 2; for (; count && ipid < 100; ipid += 2) { TCPIPStatusTCP(ipid, &srBuffer); if (_toolErr) continue; Display(ipid, &srBuffer); --count; ++line; if (line == 24) { fputs("-- more --", stdout); c = ReadKey(); if (c == 'Q' || c == 'q' || c == 0x1b) return 0; goto redraw; } } while (line < 23) { putchar('\r'); ++line; } fputs("Q: Quit. D: Save debug file T: TCP Status L: Link Layer status", stdout); for (;;) { c = ReadKey(); switch (c) { case 'q': case 'Q': case 0x1b: return 0; case 'D': case 'd': // debug(); return 1; case 'T': case 't': DisplayTCP(); return 1; case 'L': case 'l': DisplayLinkLayer(); return 1; case ' ': goto redraw; break; case 'I': case 'i': /* sigh... \r is also a line feed. */ /* reverse line feed first to negate it. */ putchar(31); putchar('\r'); putchar(29); fputs("IPID: ", stdout); c = ReadInt(); if ((int)c >= 0) DisplayIpid(c); return 1; } } } DeviceRec device_in; DeviceRec device_out; Long globals_in; Long globals_out; void StartTT(void) { device_in = GetInputDevice(); globals_in = GetInGlobals(); device_out = GetOutputDevice(); globals_out = GetOutGlobals(); SetInputDevice(0, 3); SetOutputDevice(0, 3); SetInGlobals(0x7f, 0x00); SetOutGlobals(0xff, 0x80); InitTextDev(0); InitTextDev(1); } void StopTT(void) { SetInputDevice(device_in.deviceType, device_in.ptrOrSlot); SetInGlobals(globals_in >> 16, globals_in); SetOutputDevice(device_out.deviceType, device_out.ptrOrSlot); SetOutGlobals(globals_out >> 16, globals_out); InitTextDev(0); InitTextDev(1); } void StartUp(void) { //StartTT(); putchar(CURSOR_OFF); /* turn off cursor */ if (TCPIPStatus() == 0 || _toolErr) { fputs("Marinetti is not active", stdout); ReadKey(); } else { while (DisplayMain()) /* */ ; } //StopTT(); } void ShutDown(void) {}