From 46adaeaa058136ac188c8e906676dd2c856daeb9 Mon Sep 17 00:00:00 2001 From: John Wiseman Date: Mon, 4 Nov 2024 07:59:10 +0000 Subject: [PATCH] 6.0.24.49 --- BBSUtilities.c | 13 +- BPQMail.c | 2 + Bpq32.c | 2 +- Cmd.c | 6 - Cmd.c.bak | 5983 ------------------------------------------------ MailDataDefs.c | 1 + Versions.h | 4 +- 7 files changed, 17 insertions(+), 5994 deletions(-) delete mode 100644 Cmd.c.bak diff --git a/BBSUtilities.c b/BBSUtilities.c index 06feafc..82344bd 100644 --- a/BBSUtilities.c +++ b/BBSUtilities.c @@ -269,6 +269,8 @@ char FilesNames[4][100] = {"", "", "", ""}; char * Logs[4] = {"BBS", "CHAT", "TCP", "DEBUG"}; +extern struct SEM ConfigSEM; + BOOL OpenLogfile(int Flags) { @@ -2209,7 +2211,7 @@ BOOL CheckValidCall(char * From) if (DontCheckFromCall) return TRUE; - if (strcmp(From, "SYSOP") == 0 || strcmp(From, "SYSTEM") == 0 || + if (strcmp(From, "SYSOP") == 0 || strcmp(From, "SYSTEM") == 0 || strcmp(From, "SERVIC") == 0 || strcmp(From, "IMPORT") == 0 || strcmp(From, "SMTP:") == 0 || strcmp(From, "RMS:") == 0) return TRUE; @@ -9531,6 +9533,8 @@ VOID SaveConfig(char * ConfigName) char FBBString[8192]= ""; FBBFilter * p = Filters; char * ptr = FBBString; + + GetSemaphore(&ConfigSEM, 60); if (configSaved == 0) { @@ -9954,10 +9958,11 @@ VOID SaveConfig(char * ConfigName) #ifdef LINBPQ - if(! config_write_file(&cfg,"/dev/shm/linmail.cfg.temp" )) + if(!config_write_file(&cfg,"/dev/shm/linmail.cfg.temp" )) { print("Error while writing file.\n"); config_destroy(&cfg); + FreeSemaphore(&ConfigSEM); return; } @@ -9969,6 +9974,8 @@ VOID SaveConfig(char * ConfigName) { fprintf(stderr, "Error while writing file.\n"); config_destroy(&cfg); + FreeSemaphore(&ConfigSEM); + return; } @@ -9997,6 +10004,8 @@ VOID SaveConfig(char * ConfigName) } #endif */ + + FreeSemaphore(&ConfigSEM); } int GetIntValue(config_setting_t * group, char * name) diff --git a/BPQMail.c b/BPQMail.c index 289592d..51216bc 100644 --- a/BPQMail.c +++ b/BPQMail.c @@ -1140,6 +1140,8 @@ // Rewrite PG server code on Lunux (41) // Fix SendPToMultiple not stopping at Implied AT match (45) // Log Our HA when checking for flood bulls (45) +// Semaphore calls to SaveConfig +// Include SERVIC as valid from call (for Winlink Service messages) (49) #include "bpqmail.h" #include "winstdint.h" diff --git a/Bpq32.c b/Bpq32.c index 2250d1f..2916d7c 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1229,7 +1229,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Add support for Qtsm Mgmt Interface (45) // NodeAPI improvements (46) // Add MQTT Interface (46) -// Fix buffer leak in ARDOP codev(46) +// Fix buffer leak in ARDOP code(46) // Fix possible crash if MQTT not in use (47) // Add optional ATTACH time limit for VARA (48) // API format fixes (48) diff --git a/Cmd.c b/Cmd.c index 60c4003..5a194cf 100644 --- a/Cmd.c +++ b/Cmd.c @@ -2838,12 +2838,6 @@ noFlip3: RESET2(LINK); // RESET ALL FLAGS - toCall[ConvFromAX25(LINK->LINKCALL, toCall)] = 0; - fromCall[ConvFromAX25(LINK->OURCALL, fromCall)] = 0; - - hookL2SessionAttempt(CONNECTPORT, fromCall, toCall, LINK); - - if (CMD->String[0] == 'N' && SUPPORT2point2) LINK->L2STATE = 1; // New (2.2) send XID else diff --git a/Cmd.c.bak b/Cmd.c.bak deleted file mode 100644 index 5a194cf..0000000 --- a/Cmd.c.bak +++ /dev/null @@ -1,5983 +0,0 @@ -/* -Copyright 2001-2022 John Wiseman G8BPQ - -This file is part of LinBPQ/BPQ32. - -LinBPQ/BPQ32 is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -LinBPQ/BPQ32 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. S"paclenee the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses -*/ - -// -// C replacement for cmd.asm -// -#define Kernel - -#define _CRT_SECURE_NO_DEPRECATE -#pragma data_seg("_BPQDATA") - -//#include "windows.h" -//#include "winerror.h" - - -#include "time.h" -#include "stdio.h" -#include -//#include "vmm.h" -//#include "SHELLAPI.H" - -#include "CHeaders.h" -#include "bpqaprs.h" -#include "kiss.h" - -#pragma pack() - -#include "tncinfo.h" -#include "telnetserver.h" - -//#include "GetVersion.h" - -//#define DllImport __declspec( dllimport ) -//#define DllExport __declspec( dllexport ) - -BOOL DecodeCallString(char * Calls, BOOL * Stay, BOOL * Spy, UCHAR *AXCalls); -VOID Send_AX_Datagram(PDIGIMESSAGE Block, DWORD Len, UCHAR Port); -int APIENTRY ClearNodes(); -VOID GetJSONValue(char * _REPLYBUFFER, char * Name, char * Value); -VOID SendHTTPRequest(SOCKET sock, char * Host, int Port, char * Request, char * Params, int Len, char * Return); -SOCKET OpenWL2KHTTPSock(); -VOID FormatTime3(char * Time, time_t cTime); -VOID Format_Addr(unsigned char * Addr, char * Output, BOOL IPV6); -VOID Tel_Format_Addr(struct ConnectionInfo * sockptr, char * dst); -VOID FindLostBuffers(); -BOOL CheckCMS(struct TNCINFO * TNC); -VOID L2SENDXID(struct _LINKTABLE * LINK); -int CountBits(unsigned long in); -VOID SaveMH(); -BOOL RestartTNC(struct TNCINFO * TNC); -void GetPortCTEXT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID WriteMiniDump(); -int CheckKissInterlock(struct PORTCONTROL * PORT, int Exclusive); -int seeifInterlockneeded(struct PORTCONTROL * PORT); - -extern VOID KISSTX(); - -char COMMANDBUFFER[81] = ""; // Command Hander input buffer -char OrigCmdBuffer[81] = ""; // Command Hander input buffer before toupper - -struct DATAMESSAGE * REPLYBUFFER = NULL; -UINT APPLMASK = 0; -UCHAR SAVEDAPPLFLAGS = 0; - -UCHAR ALIASINVOKED = 0; - - -VOID * CMDPTR = 0; - -short CMDPACLEN = 0; - -char OKMSG[] = "Ok\r"; - -char CMDERRMSG[] = "Invalid command - Enter ? for command list\r"; -#define CMDERRLEN sizeof(CMDERRMSG) - 1 - -char PASSWORDMSG[] = "Command requires SYSOP status - enter password\r"; -#define LPASSMSG sizeof(PASSWORDMSG) - 1 - -char CMDLIST[] = "CONNECT BYE INFO NODES PORTS ROUTES USERS MHEARD"; - -#define CMDLISTLEN sizeof(CMDLIST) - 1 - -char BADMSG[] = "Bad Parameter\r"; -char BADPORT[] = "Invalid Port Number\r"; -char NOTEXTPORT[] = "Only valid on EXT ports\r"; -char NOVALCALLS[] = "No Valid Calls defined on this port\r"; - -char BADVALUEMSG[] = "Invalid parameter\r"; - -char BADCONFIGMSG[] = "Configuration File check falled - will continue with old config\r"; -#ifdef LINBPQ -char REBOOTOK[] = "Rebooting\r"; -#else -char REBOOTOK[] = "Rebooting in 20 secs\r"; -#endif -char REBOOTFAILED[] = "Shutdown failed\r"; - -char RESTARTOK[] = "Restarting\r"; -char RESTARTFAILED[] = "Restart failed\r"; - -UCHAR ARDOP[7] = {'A'+'A','R'+'R','D'+'D','O'+'O','P'+'P',' '+' '}; // ARDOP IN AX25 -UCHAR VARA[7] = {'V'+'V','A'+'A','R'+'R','A'+'A',' '+' ',' '+' '}; // VARA IN AX25 - -int STATSTIME = 0; -int MAXBUFFS = 0; -int QCOUNT = 0; -int MINBUFFCOUNT = 65535; -int NOBUFFCOUNT = 0; -int BUFFERWAITS = 0; -int MAXDESTS = 0; -int NUMBEROFNODES = 0; -int L4CONNECTSOUT = 0; -int L4CONNECTSIN = 0; -int L4FRAMESTX = 0; -int L4FRAMESRX = 0; -int L4FRAMESRETRIED = 0; -int OLDFRAMES = 0; -int L3FRAMES = 0; - -VOID SENDSABM(); -VOID RESET2(); - -int APPL1 = 0; -int PASSCMD = 0; - -#pragma pack(1) - -struct _EXTPORTDATA DP; // Only way I can think of to get offets to port data into cmd table - -char CMDALIAS[ALIASLEN][NumberofAppls] = {0}; -char * ALIASPTR = &CMDALIAS[0][0]; - -extern int RigReconfigFlag; - -CMDX COMMANDS[]; - -int CMDXLEN = sizeof (CMDX); - -VOID SENDNODESMSG(); -VOID KISSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID STOPCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID STARTCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID STOPPORT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID STARTPORT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID FINDBUFFS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID WL2KSYSOP(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID AXRESOLVER(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID AXMHEARD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID SHOWTELNET(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID SHOWAGW(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID SHOWARP(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID SHOWNAT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID PING(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID SHOWIPROUTE(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID FLMSG(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * UserCMD); -void ListExcludedCalls(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID APRSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID RECONFIGTELNET (TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID HELPCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); -VOID UZ7HOCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * UserCMD); -VOID QTSMCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * UserCMD); -void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK); - - - -char * __cdecl Cmdprintf(TRANSPORTENTRY * Session, char * Bufferptr, const char * format, ...) -{ - // Send Command response checking PACLEN - - char Mess[4096]; - va_list(arglist); - int OldLen; - int MsgLen; - struct DATAMESSAGE * Buffer; - char * Messptr = Mess; - int Paclen = Session->SESSPACLEN; - - if (Paclen == 0) - Paclen = 255; - - va_start(arglist, format); - - MsgLen = vsprintf(Mess, format, arglist); - - OldLen = (int)(Bufferptr - (char *)REPLYBUFFER->L2DATA); - - while ((OldLen + MsgLen) > Paclen) - { - // Have to send Paclen then get a new buffer - - int ThisBit = Paclen - OldLen; // What we can send this time - - if (ThisBit < 0) - ThisBit = 0; // How can this happen?? - - memcpy(Bufferptr, Messptr, ThisBit); - Messptr += ThisBit; - MsgLen -= ThisBit; - - // QUEUE IT AND GET ANOTHER BUFFER - - Buffer = (struct DATAMESSAGE *)GetBuff(); - - if (Buffer == NULL) - - // No buffers, so just reuse the old one (better than crashing !!) - - Buffer = REPLYBUFFER; - else - SendCommandReply(Session, REPLYBUFFER, Paclen + (4 + sizeof(void *))); - - - REPLYBUFFER = Buffer; - Buffer->PID = 0xf0; - - Bufferptr = &Buffer->L2DATA[0]; - OldLen = 0; - } - - // Add last bit to buffer - - memcpy(Bufferptr, Messptr, MsgLen); - - return Bufferptr + MsgLen; -} - - -VOID SENDNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - SENDNODESMSG(); - - strcpy(Bufferptr, OKMSG); - Bufferptr += (int)strlen(OKMSG); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID SAVEMHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - SaveMH(); - - strcpy(Bufferptr, OKMSG); - Bufferptr += (int)strlen(OKMSG); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID SAVENODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - SaveNodes(); - - strcpy(Bufferptr, OKMSG); - Bufferptr += (int)strlen(OKMSG); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID DUMPCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - WriteMiniDump(); - - strcpy(Bufferptr, OKMSG); - Bufferptr += (int)strlen(OKMSG); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID RIGRECONFIG(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - if (!ProcessConfig()) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Configuration File check falled - will continue with old config"); - } - else - { - RigReconfigFlag = TRUE; - Bufferptr = Cmdprintf(Session, Bufferptr, "Rigcontrol Reconfig requested"); - } - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID REBOOT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - if (Reboot()) - { - strcpy(Bufferptr, REBOOTOK); - Bufferptr += (int)strlen(REBOOTOK); - } - else - { - strcpy(Bufferptr, REBOOTFAILED); - Bufferptr += (int)strlen(REBOOTFAILED); - } - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID RESTART(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - if (Restart()) - { - strcpy(Bufferptr, RESTARTOK); - Bufferptr += (int)strlen(RESTARTOK); - } - else - { - strcpy(Bufferptr, RESTARTFAILED); - Bufferptr += (int)strlen(RESTARTFAILED); - } - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID RESTARTTNC(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - char * ptr, *Context; - int portno; - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - { - portno = atoi (ptr); - - if (portno && portno < 33) - { - struct TNCINFO * TNC = TNCInfo[portno]; - - if (TNC == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r"); - } - else - { - if (TNC->ProgramPath) - { - if (RestartTNC(TNC)) - Bufferptr = Cmdprintf(Session, Bufferptr, "Restart %s Ok\r", TNC->ProgramPath); - else - Bufferptr = Cmdprintf(Session, Bufferptr, "Restart %s Failed\r", TNC->ProgramPath); - } - else - { - Bufferptr = Cmdprintf(Session, Bufferptr, "PATH not defined so can't restart TNC\r"); - } - } - } - else - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r"); - - } - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -UCHAR VALNODESFLAG = 0, EXTONLY = 0; - -VOID PORTVAL (TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); - -VOID VALNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - VALNODESFLAG = 1; - PORTVAL(Session, Bufferptr, CmdTail, CMD); -} - -VOID EXTPORTVAL(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - EXTONLY = 1; - PORTVAL(Session, Bufferptr, CmdTail, CMD); -} -VOID PORTVAL(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // PROCESS PORT VALUE COMMANDS - - char * ptr, *Context, * ptr1; - int portno; - UCHAR oldvalue, newvalue; - struct PORTCONTROL * PORT = PORTTABLE; - int n = NUMBEROFPORTS; - UCHAR * valueptr; - - // Get port number - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - { - portno = atoi (ptr); - - if (portno) - { - while (n--) - { - if (PORT->PORTNUMBER == portno) - { - if (VALNODESFLAG) - { - char * VNPtr = PORT->PERMITTEDCALLS; - char Normcall[10]; - - VALNODESFLAG = 0; - - if (VNPtr) - { - while (VNPtr[0]) - { - Normcall[ConvFromAX25(VNPtr, Normcall)] = 0; - Bufferptr = Cmdprintf(Session, Bufferptr, "%s ", Normcall); - VNPtr += 7; - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - } - else - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", NOVALCALLS); - } - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - - return; - - } - - if (EXTONLY) - { - // Make sure an Extenal Port - - EXTONLY = 0; - - if (PORT->PORTTYPE != 0x10) - { - strcpy(Bufferptr, NOTEXTPORT); - Bufferptr += (int)strlen(NOTEXTPORT); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - } - - valueptr = (UCHAR *)PORT + CMD->CMDFLAG; - oldvalue = *valueptr; - - // Display Param Namee - - ptr1 = &CMD->String[0]; - n = 12; - - while (*(ptr1) != ' ' && n--) - *(Bufferptr++) = *(ptr1++); - - // See if another param - if not, just display current value - - ptr = strtok_s(NULL, " ", &Context); - - if (ptr && ptr[0]) - { - // Get new value - - newvalue = atoi(ptr); - *valueptr = newvalue; - - Bufferptr = Cmdprintf(Session, Bufferptr, " was %d now %d\r", oldvalue, newvalue); - } - - else - Bufferptr = Cmdprintf(Session, Bufferptr, " %d\r", oldvalue); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - - } - PORT = PORT->PORTPOINTER; - } - } - } - - // Bad port - - strcpy(Bufferptr, BADPORT); - Bufferptr += (int)strlen(BADPORT); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - -} - -VOID SWITCHVAL (TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // Update switch 8 bit value - - char * ptr, *Context, * ptr1; - UCHAR oldvalue, newvalue; - int n; - UCHAR * valueptr; - - valueptr = (UCHAR *)CMD->CMDFLAG; - - oldvalue = *valueptr; - - // Display Param Name - - ptr1 = &CMD->String[0]; - n = 12; - - while (*(ptr1) != ' ' && n--) - *(Bufferptr++) = *(ptr1++); - - // See if a param - if not, just display current value - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr && ptr[0]) - { - // Get new value - - newvalue = atoi(ptr); - *valueptr = newvalue; - - Bufferptr = Cmdprintf(Session, Bufferptr, " was %d now %d\r", oldvalue, newvalue); - - if (memcmp(CMD->String, "NODESINT ", 8) == 0) - L3TIMER = L3INTERVAL; - } - else - Bufferptr = Cmdprintf(Session, Bufferptr, " %d\r", oldvalue); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - -} - -VOID SWITCHVALW (TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // Update switch 16 bit value - - char * ptr, *Context, * ptr1; - USHORT oldvalue, newvalue; - int n; - USHORT * valueptr; - - valueptr = (USHORT *)CMD->CMDFLAG; - - oldvalue = (USHORT)*valueptr; - - // Display Param Name - - ptr1 = &CMD->String[0]; - n = 12; - - while (*(ptr1) != ' ' && n--) - *(Bufferptr++) = *(ptr1++); - - // See if a param - if not, just display current value - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr && ptr[0]) - { - // Get new value - - newvalue = atoi(ptr); - *valueptr = newvalue; - - Bufferptr = Cmdprintf(Session, Bufferptr, " was %d now %d\r", oldvalue, newvalue); - } - else - Bufferptr = Cmdprintf(Session, Bufferptr, " %d\r", oldvalue); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - -} - -TRANSPORTENTRY * SetupSessionFromSession(TRANSPORTENTRY * Session, PBPQVECSTRUC HOSTSESS, UINT APPLMASK) -{ - // Create a Transport (L4) session linked to an incoming Session - - TRANSPORTENTRY * NewSess = L4TABLE; - int Index = 0; - - while (Index < MAXCIRCUITS) - { - if (NewSess->L4USER[0] == 0) - { - // Got One - - UCHAR * ourcall = &MYCALL[0]; - - Session->L4CROSSLINK = NewSess; - NewSess->L4CROSSLINK = Session; - - if (APPLMASK) - { - // Circuit for APPL - look for an APPLCALL - - APPLCALLS * APPL = APPLCALLTABLE; - - while ((APPLMASK & 1) == 0) - { - APPLMASK >>= 1; - APPL++; - } - if (APPL->APPLCALL[0] > 0x40) // We have an applcall - ourcall = &APPL->APPLCALL[0]; - } - - memcpy(NewSess->L4USER, ourcall, 7); - memcpy(NewSess->L4MYCALL, Session->L4MYCALL, 7); - - NewSess->CIRCUITINDEX = Index; //OUR INDEX - NewSess->CIRCUITID = NEXTID; - - NEXTID++; - if (NEXTID == 0) - NEXTID++; // kEEP nON-ZERO - - NewSess->SESSIONT1 = Session->SESSIONT1; - NewSess->L4WINDOW = (UCHAR)L4DEFAULTWINDOW; - NewSess->SESSPACLEN = PACLEN; // Default; - - NewSess->L4TARGET.HOST = HOSTSESS; - NewSess->L4STATE = 5; - return NewSess; - } - Index++; - NewSess++; - } - return NULL; -} - -extern int GETCONNECTIONINFO(); - - -BOOL cATTACHTOBBS(TRANSPORTENTRY * Session, UINT Mask, int Paclen, int * AnySessions) -{ - PBPQVECSTRUC HOSTSESS = BPQHOSTVECTOR; - TRANSPORTENTRY * NewSess; - int ApplNum; - int n = BPQHOSTSTREAMS; - int ConfigedPorts = 0; - - // LOOK FOR A FREE HOST SESSION - - while (n--) - { - if (HOSTSESS->HOSTAPPLMASK & Mask) - { - // Right appl - - ConfigedPorts++; - - if (HOSTSESS->HOSTSESSION == NULL && (HOSTSESS->HOSTFLAGS & 3) == 0) // Not attached and no report outstanding - { - // WEVE GOT A FREE BPQ HOST PORT - USE IT - - NewSess = SetupSessionFromSession(Session, HOSTSESS, Mask); - - if (NewSess == NULL) - return FALSE; // Appl not available - - HOSTSESS->HOSTSESSION = NewSess; - - // Convert APPLMASK to APPLNUM - - ApplNum = 1; - - while (APPLMASK && (APPLMASK & 1) == 0) - { - ApplNum++; - APPLMASK >>= 1; - } - - HOSTSESS->HOSTAPPLNUM = ApplNum; - - HOSTSESS->HOSTFLAGS |= 2; // Indicate State Change - - NewSess->L4CIRCUITTYPE = BPQHOST | DOWNLINK; - - PostStateChange(NewSess); - - NewSess->SESS_APPLFLAGS = HOSTSESS->HOSTAPPLFLAGS; - - NewSess->SESSPACLEN = Paclen; - - return TRUE; - } - } - HOSTSESS++; - } - - *AnySessions = ConfigedPorts; // to distinguish between none and all in use - return FALSE; -} - -VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - BOOL CONFAILED = 0; - UINT CONERROR ; - char APPName[13]; - char * ptr1, *ptr2; - int n = 12; - BOOL Stay = FALSE; - - // Copy Appl and Null Terminate - - ptr1 = &CMD->String[0]; - ptr2 = APPName; - - while (*(ptr1) != ' ' && n--) - *(ptr2++) = *(ptr1++); - - *(ptr2) = 0; - - if (Session->LISTEN) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Can't use %s while listening\r", APPName); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - - if (CmdTail[0] == 'S') - Stay = TRUE; - - Session->STAYFLAG = Stay; - - memcpy(Session->APPL, CMD->String, 12); - - // SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND - - if (ALIASPTR[0] > ' ') - { - // COPY ALIAS TO COMMAND BUFFER, THEN REENTER COMMAND HANDLER - - int SaveSecure = Session->Secure_Session; - - memcpy(COMMANDBUFFER, ALIASPTR, ALIASLEN); - _strupr(COMMANDBUFFER); - memcpy(OrigCmdBuffer, ALIASPTR, ALIASLEN); // In case original case version needed - - ALIASINVOKED = 1; // To prevent Alias Loops - - // Set secure session for application alias in case telnet outward connect - - Session->Secure_Session = 1; - DoTheCommand(Session); - Session->Secure_Session = SaveSecure; - - return; - } - - if (cATTACHTOBBS(Session, APPLMASK, CMDPACLEN, &CONERROR) == 0) - { - // No Streams - - if (CONERROR) - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, All %s Ports are in use - Please try later\r", APPName); - else - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, Application %s is not running - Please try later\r", APPName); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // IF CMD_TO_APPL SET IN APPLFLAGS, SEND INPUT MSG TO APPL - - if (Session->L4CROSSLINK->SESS_APPLFLAGS & CMD_TO_APPL) - { - struct DATAMESSAGE * Msg = (struct DATAMESSAGE *)GetBuff(); - TRANSPORTENTRY * XSession = Session->L4CROSSLINK; - - if (Msg) - { - COMMANDBUFFER[72] = 13; - memcpy(Msg->L2DATA, COMMANDBUFFER, 73); - Msg->LENGTH = 73 + 4 + sizeof(void *); - Msg->PID = 0xf0; - - C_Q_ADD(&XSession->L4TX_Q, (UINT *)Msg); - PostDataAvailable(XSession); - } - } - - if (Stay) - Session->L4CROSSLINK->L4TARGET.HOST->HOSTFLAGS |= 0x20; - - // IF MSG_TO_USER SET, SEND 'CONNECTED' MESSAGE TO USER - - Session->SESS_APPLFLAGS = Session->L4CROSSLINK->SESS_APPLFLAGS; - - if (Session->L4CROSSLINK->SESS_APPLFLAGS & MSG_TO_USER) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Connected to %s\r", APPName); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - - // DONT NEED BUFFER ANY MORE - - ReleaseBuffer((UINT *)REPLYBUFFER); - return; -} - - -VOID CMDI00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", INFOMSG); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID CMDV00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - if (sizeof(void *) == 4) - Bufferptr = Cmdprintf(Session, Bufferptr, "Version %s\r", VersionString); - else - Bufferptr = Cmdprintf(Session, Bufferptr, "Version %s (64 bit)\r", VersionString); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID BYECMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - CLOSECURRENTSESSION(Session); // Kills any crosslink, plus local link - ReleaseBuffer((UINT *)REPLYBUFFER); - return; -} - -VOID CMDPAC(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // SET PACLEN FOR THIS SESSION - - char * ptr, *Context; - int newvalue; - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr && ptr[0]) - { - // Get new value - - newvalue = atoi(ptr); - if (newvalue > 29 && newvalue < 256) - Session->SESSPACLEN = newvalue & 0xff; - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "PACLEN - %d\r", Session->SESSPACLEN); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID CMDIDLE(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // SET IDLETIME FOR THIS SESSION - - char * ptr, *Context; - int newvalue; - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr && ptr[0]) - { - // Get new value - - newvalue = atoi(ptr); - if (newvalue > 59 && newvalue < 901) - Session->L4LIMIT = newvalue; - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "IDLETIME - %d\r", Session->L4LIMIT); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - -} -VOID CMDT00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // SET L4 TIMEOUT FOR CONNECTS ON THIS SESSION - - char * ptr, *Context; - int newvalue; - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr && ptr[0]) - { - // Get new value - - newvalue = atoi(ptr); - if (newvalue > 20) - Session->SESSIONT1 = newvalue; - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "L4TIMEOUT - %d\r", Session->SESSIONT1); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -UCHAR PWLen; -char PWTEXT[80]; - -VOID PWDCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - char * ptr, *Context; - USHORT pwsum = 0; - int n = 5, p1, p2, p3, p4, p5; - - if (Session->Secure_Session) // HOST - SET AUTHORISED REGARDLESS - { - Session->PASSWORD = 0xFFFF; // SET AUTHORISED - Session->Secure_Session = 1; - strcpy(Bufferptr, OKMSG); - Bufferptr += (int)strlen(OKMSG); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr && ptr[0]) - { - // Check Password - - n = 5; - - while (n--) - pwsum += *(ptr++); - - if (Session->PASSWORD == pwsum) - { - Session->PASSWORD = 0xFFFF; // SET AUTHORISED - Session->Secure_Session = 1; - strcpy(Bufferptr, OKMSG); - Bufferptr += (int)strlen(OKMSG); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - ReleaseBuffer((UINT *)REPLYBUFFER); - return; - } - - // SEND PASSWORD PROMPT - - if (PWLen == 0) - PWLen = 1; - - p1 = rand() % PWLen; - pwsum += PWTEXT[p1++]; - - p2 = rand() % PWLen; - pwsum += PWTEXT[p2++]; - - p3 = rand() % PWLen; - pwsum += PWTEXT[p3++]; - - p4 = rand() % PWLen; - pwsum += PWTEXT[p4++]; - - p5 = rand() % PWLen; - pwsum += PWTEXT[p5++]; - - Session->PASSWORD = pwsum; - - Bufferptr = Cmdprintf(Session, Bufferptr, "%d %d %d %d %d\r", p1, p2, p3, p4, p5); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - -VOID CMDSTATS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - char * ptr, *Context; - int Port = 0, cols = NUMBEROFPORTS, i; - char * uptime; - struct PORTCONTROL * PORT = PORTTABLE; - struct PORTCONTROL * STARTPORT; - - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - // SEE IF ANY PARAM - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr && ptr[0]) - Port = atoi(ptr); - - // IF ASKING FOR PORT STATS, DONT DO SYSTEM ONES - - if (Port == 0) - { - uptime = FormatUptime(STATSTIME); - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", uptime); - - Bufferptr = Cmdprintf(Session, Bufferptr, "Semaphore Get-Rel/Clashes %9d%9d\r", - Semaphore.Gets - Semaphore.Rels, Semaphore.Clashes); - - Bufferptr = Cmdprintf(Session, Bufferptr, "Buffers:Max/Cur/Min/Out/Wait%9d%9d%9d%9d%9d\r", - MAXBUFFS, QCOUNT, MINBUFFCOUNT, NOBUFFCOUNT, BUFFERWAITS); - - Bufferptr = Cmdprintf(Session, Bufferptr, "Known Nodes/Max Nodes %9d%9d\r", - NUMBEROFNODES, MAXDESTS); - - Bufferptr = Cmdprintf(Session, Bufferptr, "L4 Connects Sent/Rxed %9d%9d\r", - L4CONNECTSOUT, L4CONNECTSIN); - - Bufferptr = Cmdprintf(Session, Bufferptr, "L4 Frames TX/RX/Resent/Reseq%9d%9d%9d%9d\r", - L4FRAMESTX, L4FRAMESRX, L4FRAMESRETRIED, OLDFRAMES); - - Bufferptr = Cmdprintf(Session, Bufferptr, "L3 Frames Relayed %9d\r", L3FRAMES); - - if (ptr && ptr[0] == 'S') - { - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - } - - // POSITION TO REQUESTED PORT - - if (Port) - { - while (PORT && PORT->PORTNUMBER != Port) - { - PORT = PORT->PORTPOINTER; - cols--; - } - } - - if (PORT == NULL) // REQUESTED PORT NOT FOUND - { - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - STARTPORT = PORT; - - if (cols > 7) - cols = 7; - - Bufferptr = Cmdprintf(Session, Bufferptr, " "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Port %02d ", PORT->PORTNUMBER); - PORT = PORT->PORTPOINTER; - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "L2 Frames Digied"); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2DIGIED); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "L2 Frames Heard "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2FRAMES); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "L2 Frames Rxed "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2FRAMESFORUS); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "L2 Frames Sent "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2FRAMESSENT); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "L2 Timeouts "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2TIMEOUTS); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "REJ Frames Rxed "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2REJCOUNT); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "RX out of Seq "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2OUTOFSEQ); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "L2 Resequenced "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2RESEQ); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "Undrun/Poll T/o "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2URUNC); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "RX Overruns "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2ORUNC); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "RX CRC Errors "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->RXERRORS); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "FRMRs Sent "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2FRMRTX); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "FRMRs Received "); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L2FRMRRX); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; - Bufferptr = Cmdprintf(Session, Bufferptr, "Frames abandoned"); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%9d", PORT->L1DISCARD); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - PORT = STARTPORT; -// Bufferptr = Cmdprintf(Session, Bufferptr, "Link Active %% "); - Bufferptr = Cmdprintf(Session, Bufferptr, "Active(TX/Busy) %%"); - - for (i = 0; i < cols; i++) - { - Bufferptr = Cmdprintf(Session, Bufferptr, " %2d %3d ", PORT->AVSENDING, PORT->AVACTIVE); - PORT = PORT->PORTPOINTER; - } - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID CMDL00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // PROCESS 'LINKS' MESSAGE - - struct _LINKTABLE * LINK = LINKS; - int n = MAXLINKS; - int len; - char Normcall[11] = ""; - - Bufferptr = Cmdprintf(Session, Bufferptr, "Links\r"); - - while (n--) - { - if (LINK->LINKCALL[0]) - { - len = ConvFromAX25(LINK->LINKCALL, Normcall); - - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", Normcall); - - len = ConvFromAX25(LINK->OURCALL, Normcall); - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", Normcall); - - if (LINK->Ver2point2) - Bufferptr = Cmdprintf(Session, Bufferptr, " S=%d P=%d T=%d V=2.2\r", - LINK->L2STATE, LINK->LINKPORT->PORTNUMBER, LINK->LINKTYPE); - else - Bufferptr = Cmdprintf(Session, Bufferptr, " S=%d P=%d T=%d V=%d\r", - LINK->L2STATE, LINK->LINKPORT->PORTNUMBER, LINK->LINKTYPE, 2 - LINK->VER1FLAG); - } - LINK++; - } - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - - -VOID CMDS00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // PROCESS 'USERS' - - int n = MAXCIRCUITS; - TRANSPORTENTRY * L4 = L4TABLE; - TRANSPORTENTRY * Partner; - int MaxLinks = MAXLINKS; - char State[12] = "", Type[12] = "Uplink"; - char LHS[50] = "", MID[10] = "", RHS[50] = ""; - char Line[100]; - - Bufferptr = Cmdprintf(Session, Bufferptr, "%s%d)\r", SESSIONHDDR, QCOUNT); - - while (n--) - { - if (L4->L4USER[0]) - { - RHS[0] = MID[0] = 0; - - if ((L4->L4CIRCUITTYPE & UPLINK) == 0) //SHORT CMDS10A ; YES - { - // IF DOWNLINK, ONLY DISPLAY IF NO CROSSLINK - - if (L4->L4CROSSLINK == 0) //jne CMDS60 ; WILL PROCESS FROM OTHER END - { - // ITS A DOWNLINK WITH NO PARTNER - MUST BE A CLOSING SESSION - // DISPLAY TO THE RIGHT FOR NOW - - strcpy(LHS, "(Closing) "); - DISPLAYCIRCUIT(L4, RHS); - goto CMDS50; - } - else - goto CMDS60; // WILL PROCESS FROM OTHER END - } - - if (L4->L4CROSSLINK == 0) - { - // Single Entry - - DISPLAYCIRCUIT(L4, LHS); - } - else - { - DISPLAYCIRCUIT(L4, LHS); - - Partner = L4->L4CROSSLINK; - - if (Partner->L4STATE == 5) - strcpy(MID, "<-->"); - else - strcpy(MID, "<~~>"); - - DISPLAYCIRCUIT(Partner, RHS); - } -CMDS50: - memset(Line, 32, 100); - memcpy(Line, LHS, (int)strlen(LHS)); - memcpy(&Line[35], MID, (int)strlen(MID)); - strcpy(&Line[40], RHS); - strcat(&Line[40], "\r"); - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", Line); - } -CMDS60: - L4++; - } - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -extern int MasterPort[MAXBPQPORTS+1]; // Pointer to first BPQ port for a specific MPSK or UZ7HO host - -VOID CMDP00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // Process PORTS Message - - // If extended show state of TNC (Open, Active, etc) - - struct PORTCONTROL * PORT = PORTTABLE; - char Extended = CmdTail[0]; - struct PORTCONTROL * SAVEPORT; - - Bufferptr = Cmdprintf(Session, Bufferptr, "Ports\r"); - - while (PORT) - { - char Status[32] = "???????"; - int Portno = PORT->PORTNUMBER; - - if (PORT->Hide) - { - PORT = PORT->PORTPOINTER; - continue; - } - - if (Extended != 'E') - { - Bufferptr = Cmdprintf(Session, Bufferptr, " %2d %s\r", PORT->PORTNUMBER, PORT->PORTDESCRIPTION); - - PORT = PORT->PORTPOINTER; - continue; - } - - // Try to get port status - may not be possible with some - - if (PORT->PortStopped) - { - strcpy(Status, "Stopped"); - Bufferptr = Cmdprintf(Session, Bufferptr, " %2d %-7s %s\r", PORT->PORTNUMBER, Status, PORT->PORTDESCRIPTION); - - PORT = PORT->PORTPOINTER; - continue; - } - - if (PORT->PORTTYPE == 0) - { - struct KISSINFO * KISS = (struct KISSINFO *)PORT; - NPASYINFO Port; - - SAVEPORT = PORT; - - if (KISS->FIRSTPORT && KISS->FIRSTPORT != KISS) - { - // Not first port on device - - PORT = (struct PORTCONTROL *)KISS->FIRSTPORT; - Port = KISSInfo[Portno]; - } - - Port = KISSInfo[PORT->PORTNUMBER]; - - if (Port) - { - // KISS like - see if connected - - if (PORT->PORTIPADDR.s_addr || PORT->KISSSLAVE) - { - // KISS over UDP or TCP - - if (PORT->KISSTCP) - { - if (Port->Connected) - strcpy(Status, "Open "); - else - if (PORT->KISSSLAVE) - strcpy(Status, "Listen"); - else - strcpy(Status, "Closed"); - } - else - strcpy(Status, "UDP"); - } - else - if (Port->idComDev) // Serial port Open - strcpy(Status, "Open "); - else - strcpy(Status, "Closed"); - - PORT = SAVEPORT; - } - } - else if (PORT->PORTTYPE == 14) // Loopback - strcpy(Status, "Open "); - - else if (PORT->PORTTYPE == 16) // External - { - if (PORT->PROTOCOL == 10) // 'HF' Port - { - struct TNCINFO * TNC = TNCInfo[Portno]; - - if (TNC == NULL) - { - PORT = PORT->PORTPOINTER; - continue; - } - - switch (TNC->Hardware) // Hardware Type - { - case H_SCS: - case H_KAM: - case H_AEA: - case H_HAL: - case H_TRK: - case H_SERIAL: - - // Serial - - if (TNC->hDevice) - strcpy(Status, "Open "); - else - strcpy(Status, "Closed"); - - break; - - case H_UZ7HO: - - if (TNCInfo[MasterPort[Portno]]->CONNECTED) - strcpy(Status, "Open "); - else - strcpy(Status, "Closed"); - - break; - - case H_WINMOR: - case H_V4: - - case H_MPSK: - case H_FLDIGI: - case H_UIARQ: - case H_ARDOP: - case H_VARA: - case H_KISSHF: - case H_WINRPR: - case H_FREEDATA: - - // TCP - - if (TNC->CONNECTED) - { - if (TNC->Streams[0].Attached) - strcpy(Status, "In Use"); - else - strcpy(Status, "Open "); - } - else - strcpy(Status, "Closed"); - - break; - - case H_TELNET: - - strcpy(Status, "Open "); - } - } - else - { - // External but not HF - AXIP, BPQETHER VKISS, ?? - - struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)PORT; - - strcpy(Status, "Open "); - } - } - - Bufferptr = Cmdprintf(Session, Bufferptr, " %2d %-7s %s\r", PORT->PORTNUMBER, Status, PORT->PORTDESCRIPTION); - - PORT = PORT->PORTPOINTER; - } - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -char * DisplayRoute(TRANSPORTENTRY * Session, char * Bufferptr, struct ROUTE * Routes, char Verbose) -{ - char Normcall[10]; - char locked[] = " ! "; - int NodeCount; - int Percent = 0; - char PercentString[20]; - int Iframes, Retries; - char Active[10]; - int Queued; - - int Port = 0; - - int len = ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall); - - Normcall[9]=0; - - if ((Routes->NEIGHBOUR_FLAG & 1) == 1) - strcpy(locked, "!"); - else - strcpy(locked, " "); - - NodeCount = COUNTNODES(Routes); - - if (Routes->NEIGHBOUR_LINK && Routes->NEIGHBOUR_LINK->L2STATE >= 5) - strcpy(Active, ">"); - else - strcpy(Active, " "); - - if (Verbose) - { - if (Routes->NEIGHBOUR_LINK) - Queued = COUNT_AT_L2(Routes->NEIGHBOUR_LINK); // SEE HOW MANY QUEUED - else - Queued = 0; - - Iframes = Routes->NBOUR_IFRAMES; - Retries = Routes->NBOUR_RETRIES; - - if (Iframes) - { - Percent = (Retries * 100) / Iframes; - sprintf(PercentString, "%3d%%", Percent); - } - else - strcpy(PercentString, " "); - - - Bufferptr = Cmdprintf(Session, Bufferptr, "%s%2d %s %3d %3d%s%4d %4d %s %d %d %02d:%02d %d %d", - Active, Routes->NEIGHBOUR_PORT, Normcall, - Routes->NEIGHBOUR_QUAL, NodeCount, locked, Iframes, Retries, PercentString, Routes->NBOUR_MAXFRAME, Routes->NBOUR_FRACK, - Routes->NEIGHBOUR_TIME >> 8, (Routes->NEIGHBOUR_TIME) & 0xff, Queued, Routes->OtherendsRouteQual); - - // IF INP3 DISPLAY SRTT - - if (Routes->INP3Node) // INP3 Enabled? - { - double srtt = Routes->SRTT/1000.0; - double nsrtt = Routes->NeighbourSRTT/1000.0; - - Bufferptr = Cmdprintf(Session, Bufferptr, " %4.2fs %4.2fs", srtt, nsrtt); - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - } - else - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%s %d %s %d %d%s\r", - Active, Routes->NEIGHBOUR_PORT, Normcall, Routes->NEIGHBOUR_QUAL, NodeCount, locked); - } - - return Bufferptr; -} - - -VOID CMDR00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - struct ROUTE * Routes = NEIGHBOURS; - int MaxRoutes = MAXNEIGHBOURS; - char locked[] = " ! "; - int Percent = 0; - char * ptr, * Context; - char Verbose = 0; - int Port = 0; - char AXCALL[7]; - BOOL Found; - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr && (int)strlen(ptr) > 1) - { - // Route Update - - goto ROUTEUPDATE; - } - - if (ptr) - { - Verbose = ptr[0]; - ptr = strtok_s(NULL, " ", &Context); - if (ptr) - Port = atoi(ptr); - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "Routes\r"); - - while (MaxRoutes--) - { - if (Routes->NEIGHBOUR_CALL[0] != 0) - if (Port == 0 || Port == Routes->NEIGHBOUR_PORT) - Bufferptr = DisplayRoute(Session, Bufferptr, Routes, Verbose); - - Routes++; - } - goto SendReply; - -ROUTEUPDATE: - - if (Session->PASSWORD != 0xFFFF) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", PASSWORDMSG); - goto SendReply; - } - - // Line is - - // ROUTES G8BPQ-2 2 100 - Set quality to 100 - // ROUTES G8BPQ-2 2 ! - Toggle 'Locked Route' flag - // ROUTES G8BPQ-2 2 100 ! - Set quality and toggle 'locked' flag - - - ConvToAX25(ptr, AXCALL); - - ptr = strtok_s(NULL, " ", &Context); - - if (ptr) - Port = atoi(ptr); - - if (Port == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Port Number Missing \r"); - goto SendReply; - } - - Found = FindNeighbour(AXCALL, Port, &Routes); - - if (Context && Context[0] > 32) - { - // More Params - - ptr = strtok_s(NULL, " ", &Context); - - if (ptr) - { - // Adding - - memcpy(Routes->NEIGHBOUR_CALL, AXCALL, 7); // In case Add - Routes->NEIGHBOUR_PORT = Port; - Found = TRUE; - } - - if (strcmp(ptr, "!") == 0) - { - // Toggle Lock - - Routes->NEIGHBOUR_FLAG ^= 1; // FLIP LOCKED BIT - goto Displayit; - } - - if (strcmp(ptr, "Z") == 0) - { - // Clear Counts - - Routes->NBOUR_IFRAMES = 0; - Routes->NBOUR_RETRIES = 0; - goto Displayit; - } - - Routes->NEIGHBOUR_QUAL = atoi(ptr); - - if (Context && Context[0] == '!') - { - // Toggle Lock - - Routes->NEIGHBOUR_FLAG ^= 1; // FLIP LOCKED BIT - goto Displayit; - } - } - -Displayit: - - // Just display - - if (Found) - Bufferptr = DisplayRoute(Session, Bufferptr, Routes, 1); - else - Bufferptr = Cmdprintf(Session, Bufferptr, "Not Found\r"); - - - -/* MOV ROUTEDISP,1 - - CMP BYTE PTR [ESI],20H - JE SHORT JUSTDISPLAY - - MOV ZAPFLAG,0 - - CMP BYTE PTR [ESI],'Z' - JNE SHORT NOTZAP - - MOV ZAPFLAG,1 - JMP SHORT JUSTDISPLAY - - PUBLIC NOTZAP -NOTZAP: - - MOV ROUTEDISP,2 ; LOCK UPDATE - - CMP BYTE PTR [ESI],'!' - JE SHORT JUSTDISPLAY -; -; LOOK FOR V FOR ADDING A DIGI -; - CMP WORD PTR [ESI],' V' ; V [SPACE] - JE ADDDIGI - - CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH - JC SHORT BADROUTECMD ; INVALID DIGITS - - MOV NEWROUTEVAL,AL - - MOV ROUTEDISP,0 - - CALL SCAN ; SEE IF ! - MOV AH,[ESI] - - - PUBLIC JUSTDISPLAY -JUSTDISPLAY: - - - MOV ESI,OFFSET32 AX25CALL - CALL _FINDNEIGHBOUR - JZ SHORT FOUNDROUTE ; IN LIST - OK - - CMP EBX,0 - JE SHORT BADROUTECMD ; TABLE FULL?? - - MOV ECX,7 - MOV EDI,EBX - REP MOVSB ; PUT IN CALL - - MOV AL,SAVEPORT - MOV NEIGHBOUR_PORT[EBX],AL - - JMP SHORT FOUNDROUTE - - - PUBLIC BADROUTECMD -BADROUTECMD: - - POP EDI - - JMP PBADVALUE - - PUBLIC FOUNDROUTE -FOUNDROUTE: - - CMP ZAPFLAG,1 - JNE SHORT NOTCLEARCOUNTS - - XOR AX,AX - MOV ES:WORD PTR NBOUR_IFRAMES[EDI],AX - MOV ES:WORD PTR NBOUR_IFRAMES+2[EDI],AX - MOV ES:WORD PTR NBOUR_RETRIES[EDI],AX - MOV ES:WORD PTR NBOUR_RETRIES+2[EDI],AX - - JMP SHORT NOUPDATE - - PUBLIC NOTCLEARCOUNTS -NOTCLEARCOUNTS: - - CMP ROUTEDISP,1 - JE SHORT NOUPDATE - - CMP ROUTEDISP,2 - JE SHORT LOCKUPDATE - - MOV AL,NEWROUTEVAL - MOV NEIGHBOUR_QUAL[EBX],AL - - CMP AH,'!' - JNE SHORT NOUPDATE - - PUBLIC LOCKUPDATE -LOCKUPDATE: - - XOR NEIGHBOUR_FLAG[EBX],1 ; FLIP LOCKED BIT - - PUBLIC NOUPDATE -NOUPDATE: - - MOV ESI,EBX - POP EDI - - POP EBX - CALL DISPLAYROUTE - - JMP SENDCOMMANDREPLY - - PUBLIC ADDDIGI -ADDDIGI: - - ADD ESI,2 - PUSH ESI ; SAVE INPUT BUFFER - - MOV ESI,OFFSET32 AX25CALL - CALL _FINDNEIGHBOUR - - POP ESI - - JZ SHORT ADD_FOUND ; IN LIST - OK - - JMP BADROUTECMD - - PUBLIC ADD_FOUND -ADD_FOUND: - - CALL CONVTOAX25 ; GET DIGI CALLSIGN - - PUSH ESI - - MOV ESI,OFFSET32 AX25CALL - LEA EDI,NEIGHBOUR_DIGI[EBX] - MOV ECX,7 - REP MOVSB - - POP ESI ; MSG BUFFER -; -; SEE IF ANOTHER DIGI -; - CMP BYTE PTR [ESI],20H - JE SHORT NOMORE - - CALL CONVTOAX25 ; GET DIGI CALLSIGN - MOV ESI,OFFSET32 AX25CALL - LEA EDI,NEIGHBOUR_DIGI+7[EBX] - MOV ECX,7 - REP MOVSB - - PUBLIC NOMORE -NOMORE: - - JMP NOUPDATE - - - -*/ - -SendReply: - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - - -VOID LISTENCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // PROCESS LISTEN COMMAND - - // for monitoring a remote ax.25 port - - int Port = 0, index =0; - uint64_t ListenMask = 0; - char * ptr, *Context; - struct PORTCONTROL * PORT = NULL; - char ListenPortList[128] = ""; - - ptr = strtok_s(CmdTail, " ,", &Context); - - // Now accepts a list of ports - - if (ptr == 0 || memcmp(ptr, "OFF", 3) == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Listening disabled\r"); - Session->LISTEN = 0; - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - while (ptr) - { - Port = atoi(ptr); - - if (Port == 0 && NUMBEROFPORTS == 1) - Port = 1; - - ptr = strtok_s(NULL, ", ", &Context); // Get port String - - if (Port) - PORT = GetPortTableEntryFromPortNum(Port); - - if (PORT == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port %d\r", Port); - continue; - } - - if (PORT->PROTOCOL == 10 && PORT->UICAPABLE == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, port %d is not an ax.25 port\r", Port); - continue; - } - - if (PORT->PORTL3FLAG) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, port %d is for internode traffic only\r", Port); - continue; - } - - if (Session->L4CIRCUITTYPE == L2LINK + UPLINK) - { - if (Session->L4TARGET.LINK->LINKPORT->PORTNUMBER == Port) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "You can't Listen to the port you are connected on\r"); - continue; - } - } - - sprintf(ListenPortList, "%s %d", ListenPortList, Port); - - ListenMask |= ((uint64_t)1 << (Port - 1)); - } - - Session->LISTEN = ListenMask; - - if (ListenMask) - { - if (CountBits64(ListenMask) == 1) - Bufferptr = Cmdprintf(Session, Bufferptr, "Listening on port%s. Use CQ to send a beacon, LIS to disable\r", ListenPortList); - else - Bufferptr = Cmdprintf(Session, Bufferptr, "Listening on ports%s. Use LIS to disable\r", ListenPortList); - } - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - - -VOID UNPROTOCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // PROCESS UNPROTO COMMAND - - int Port = 0, index =0; - char * ptr, *Context; - struct PORTCONTROL * PORT = NULL; - UCHAR axcalls[64]; - BOOL Stay, Spy; - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - Port = atoi(ptr); - - if (Port == 0 && NUMBEROFPORTS == 1) - Port = 1; - else - ptr = strtok_s(NULL, " ", &Context); // Get Unproto String - - if (Port) - PORT = GetPortTableEntryFromPortNum(Port); - - if (PORT == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (ptr == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Destination missing\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - ptr[strlen(ptr)] = ' '; // Put param back together - - if (DecodeCallString(ptr, &Stay, &Spy, &axcalls[0]) == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Call\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (PORT->PROTOCOL == 10 && PORT->UICAPABLE == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, port is not an ax.25 port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (PORT->PORTL3FLAG) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, port is for internode traffic only\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // Copy Address Info to Session Record - - Session->UNPROTO = Port; - Session->UAddrLen = (int)strlen(axcalls); - memcpy(Session->UADDRESS, axcalls, 63); - - Bufferptr = Cmdprintf(Session, Bufferptr, "Unproto Mode - enter ctrl/z or /ex to exit\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - -VOID CALCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // PROCESS CAL COMMAND - - int Port = 0, index = 0, Count = 0; - char * ptr, *Context; - struct PORTCONTROL * PORT = NULL; - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - Port = atoi(ptr); - - if (Port == 0 && NUMBEROFPORTS == 1) - Port = 1; - else - ptr = strtok_s(NULL, " ", &Context); // Get Unproto String - - if (Port) - PORT = GetPortTableEntryFromPortNum(Port); - - if (PORT == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (PORT->PROTOCOL == 10 && PORT->UICAPABLE == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, port is not an ax.25 port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (ptr == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Count Missing\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - Count = atoi(ptr); - - ptr = strtok_s(NULL, " ", &Context); // Get Unproto String - - Bufferptr = Cmdprintf(Session, Bufferptr, "Ok\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - - - -VOID CQCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // Send a CQ Beacon on a radio port. Must be in LISTEN state - - DIGIMESSAGE Msg; - int Port = 0; - int OneBits = 0; - uint64_t MaskCopy = Session->LISTEN; - int Len; - UCHAR CQCALL[7]; - char Empty[] = ""; - char * ptr1 = &OrigCmdBuffer[3]; - UCHAR * axptr = &Msg.DIGIS[0][0]; - char * ptr2, *Context; - - while (MaskCopy) - { - if (MaskCopy & 1) - OneBits++; - - Port++; - MaskCopy = MaskCopy >> 1; - } - - if (OneBits == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "You must enter LISTEN before calling CQ\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (OneBits > 1) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "You can't call CQ if LISTENing on more than one port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - - Len = (int)strlen(OrigCmdBuffer) - 3; - - if (Len < 0) - Len = 0; - - memset(&Msg, 0, sizeof(Msg)); - - Msg.PORT = Port; - Msg.CTL = 3; // UI - - // see if a Via specified - - if (_memicmp(ptr1, "via ", 4) == 0) - { - ptr2 = strtok_s(ptr1 + 4, ",", &Context); - - while (ptr2) - { - if (ConvToAX25(ptr2, axptr) == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid via string\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - axptr += 7; - - if (axptr == &Msg.DIGIS[7][0]) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Too many digis\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - ptr1 = ptr2; - ptr2 = strtok_s(NULL, ",", &Context); - } - - // ptr1 is start of last digi call. We need to position to data - - ptr1 = strchr(ptr1, ' '); - - if (ptr1 == NULL) - ptr1 = Empty; - else - ptr1++ ; // to message - - Len = (int)strlen(ptr1); - - } - - ConvToAX25("CQ", CQCALL); - memcpy(Msg.DEST, CQCALL, 7); - Msg.DEST[6] |= 0x80; // set Command Bit - memcpy(Msg.ORIGIN, Session->L4USER, 7); - Msg.ORIGIN[6] ^= 0x1e; // Flip SSID - Msg.PID = 0xf0; // Data PID - memcpy(&Msg.L2DATA, ptr1, Len); - - Send_AX_Datagram(&Msg, Len + 2, Port); // Len is Payload ie CTL, PID and Data - - Bufferptr = Cmdprintf(Session, Bufferptr, "CQ sent\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - -} - - -TRANSPORTENTRY * SetupNewSession(TRANSPORTENTRY * Session, char * Bufferptr) -{ - TRANSPORTENTRY * NewSess = L4TABLE; - int Index = 0; - - while (Index < MAXCIRCUITS) - { - if (NewSess->L4USER[0] == 0) - { - // Got One - - Session->L4CROSSLINK = NewSess; - NewSess->L4CROSSLINK = Session; - - memcpy(NewSess->L4USER, Session->L4USER, 7); - memcpy(NewSess->L4MYCALL, Session->L4MYCALL, 7); - - - NewSess->CIRCUITINDEX = Index; //OUR INDEX - NewSess->CIRCUITID = NEXTID; - - NEXTID++; - if (NEXTID == 0) - NEXTID++; // kEEP nON-ZERO - - NewSess->SESSIONT1 = Session->SESSIONT1; - NewSess->L4WINDOW = (UCHAR)L4DEFAULTWINDOW; - - return NewSess; - } - Index++; - NewSess++; - } - - if (Bufferptr) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry - System Tables Full\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - } - - return NULL; -} - - -VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST * Dest, BOOL Spy) -{ - TRANSPORTENTRY * NewSess; - - NewSess = SetupNewSession(Session, Bufferptr); - - if (NewSess == NULL) - return; // Tables Full - - NewSess->L4CIRCUITTYPE = SESSION + DOWNLINK; - - NewSess->L4TARGET.DEST = Dest; - NewSess->L4STATE = 2; // CONNECTING - - NewSess->SPYFLAG = Spy; - - ReleaseBuffer((UINT *)REPLYBUFFER); - - SENDL4CONNECT(NewSess); - - L4CONNECTSOUT++; - - return; -} - -BOOL FindLink(UCHAR * LinkCall, UCHAR * OurCall, int Port, struct _LINKTABLE ** REQLINK) -{ - struct _LINKTABLE * LINK = LINKS; - struct _LINKTABLE * FIRSTSPARE = NULL; - int n = MAXLINKS; - - while (n--) - { - if (LINK->LINKCALL[0] == 0) // Spare - { - if (FIRSTSPARE == NULL) - FIRSTSPARE = LINK; - - LINK++; - continue; - } - - if ((LINK->LINKPORT->PORTNUMBER == Port) && CompareCalls(LINK->LINKCALL, LinkCall) && CompareCalls(LINK->OURCALL, OurCall)) - { - *REQLINK = LINK; - return TRUE; - } - - LINK++; - } - // ENTRY NOT FOUND - FIRSTSPARE HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL - - *REQLINK = FIRSTSPARE; - return FALSE; -} - -VOID ATTACHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * UserCMD); - -VOID CMDC00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // PROCESS CONNECT COMMAND - - TRANSPORTENTRY * NewSess; - - int CONNECTPORT, Port; - BOOL CallEvenIfInNodes = FALSE; - char * ptr, *Context; - UCHAR axcalls[64]; - UCHAR ourcall[7]; // Call we are using (may have SSID bits inverted - int ret; - struct PORTCONTROL * PORT = PORTTABLE; - struct _LINKTABLE * LINK; - int CQFLAG = 0; // NOT CQ CALL - BOOL Stay, Spy; - int n; - char TextCall[10]; - int TextCallLen; - char PortString[10]; - char cmdCopy[256]; - struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)PORT; - char toCall[12], fromCall[12]; - -#ifdef EXCLUDEBITS - - if (CheckExcludeList(Session->L4USER) == FALSE) - { - // CONNECTS FROM THIS STATION ARE NOT ALLOWED - - ReleaseBuffer((UINT *)REPLYBUFFER); - return; - } - -#endif - - if (Session->LISTEN) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Can't connect while listening\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - CONNECTPORT = 0; // NO PORT SPECIFIED - - ptr = strtok_s(CmdTail, " ", &Context); - - strcpy(cmdCopy, Context); // Save in case Telnet Connect - - if (ptr == 0) - { - // No param - - if (CFLAG) // C Command Disabled ? - { - // Convert to HOST (appl 32) command - - //MOV _CMDPTR,OFFSET32 _HOSTCMD - //MOV _ALIASPTR,OFFSET32 _HOSTCMD + 32 * 31 - - //MOV _APPLMASK, 80000000H ; Internal Term - - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Call\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - Port = atoi(ptr); - - if (Port) - { - // IF THERE IS NOTHING FOLLOWING THE NUMBER, ASSUME IT IS A - // NUMERIC ALIAS INSTEAD OF A PORT - - sprintf(PortString, "%d", Port); - - if (strlen(PortString) < (int)strlen(ptr)) - goto NoPort; - - PORT = GetPortTableEntryFromPortNum(Port); - - if (PORT == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - EXTPORT = (struct _EXTPORTDATA *)PORT; - - ptr = strtok_s(NULL, " ", &Context); - - if (ptr == 0) - { - // No param - - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Call\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - CONNECTPORT = Port; - - if (strcmp(ptr, "CMS") == 0 || strcmp(ptr, "HOST") == 0) // In case someeone has CMS or HOST as an alias - goto Downlink; - - } - -NoPort: - - ptr[strlen(ptr)] = ' '; // Put param back together - - if (ptr[0] == '!') - { - CallEvenIfInNodes = TRUE; - ptr++; - } - - if (memcmp(ptr, "RELAY ", 5) == 0 || memcmp(ptr, "SYNC ", 5) == 0) - { - // c p relay with extra parms - - goto Downlink; - } - - // Skip call validation if using a ptc to allow 1:call, 2:call format - - if (Port && PORT->PROTOCOL == 10 && memcmp(EXTPORT->PORT_DLL_NAME, "SCSPACTOR", 9) == 0) - { - char * p; - - if (p = strstr(cmdCopy, " S ")) - { - Stay = TRUE; - p++; - *p = ' '; - } - - if (p = strstr(cmdCopy, " Z ")) - { - Spy = TRUE; - p++; - *p = ' '; - } - - goto Downlink; - } - else - { - if (DecodeCallString(ptr, &Stay, &Spy, &axcalls[0]) == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Call\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - } - - Session->STAYFLAG = Stay; - - TextCallLen = ConvFromAX25(axcalls, TextCall); - - if (CallEvenIfInNodes) - goto Downlink; - - // SEE IF CALL TO ANY OF OUR HOST SESSIONS - UNLESS DIGIS SPECIFIED - - if (axcalls[7] == 0) - { - // If this connect is as a result of a command alias, don't check appls or we will loop - - if (ALIASINVOKED == 0) - { - APPLCALLS * APPL = APPLCALLTABLE; - int n = NumberofAppls; - APPLMASK = 1; - - while (n--) - { - if (memcmp(axcalls, APPL->APPLALIAS, 6) == 0 || CompareCalls(axcalls, APPL->APPLCALL)) - { - // Call to an appl - - // Convert to an APPL command, so any alias is actioned - - // SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND - - if (APPL->APPLHASALIAS && APPL->APPLALIASVAL[0] != 0x20) - { - // COPY ALIAS TO COMMAND _BUFFER, THEN REENTER COMMAND HANDLER - - memcpy(COMMANDBUFFER, APPL->APPLALIASVAL, ALIASLEN); - COMMANDBUFFER[80] = 0; - _strupr(COMMANDBUFFER); - memcpy(OrigCmdBuffer, APPL->APPLALIASVAL, ALIASLEN); // In case original case version needed - - ALIASINVOKED = TRUE; // To prevent Alias Loops - } - else - { - - // Copy Appl Command to Command Buffer. Ensure doesn't contain old command - - memset(COMMANDBUFFER, ' ', 72); - memcpy(COMMANDBUFFER, APPL->APPLCMD, 12); - } - DoTheCommand(Session); - return; - } - APPL++; - APPLMASK <<= 1; - } - } - } - - if (axcalls[7] == 0) - { - // SEE IF CALL TO ANOTHER NODE - - struct DEST_LIST * Dest = DESTS; - int n = MAXDESTS; - - if (axcalls[6] == 0x60) // if SSID, dont check aliases - { - while (n--) - { - if (memcmp(Dest->DEST_ALIAS, TextCall, 6) == 0) - { - DoNetromConnect(Session, Bufferptr, Dest, Spy); - return; - } - Dest++; - } - } - - Dest = DESTS; - n = MAXDESTS; - - while (n--) - { - if (CompareCalls(Dest->DEST_CALL, axcalls)) - { - DoNetromConnect(Session, Bufferptr, Dest, Spy); - return; - } - Dest++; - } - } - - // Must be Downlink Connect - -Downlink: - - if (CONNECTPORT == 0 && NUMBEROFPORTS > 1) - { - // L2 NEEDS PORT NUMBER - - Bufferptr = Cmdprintf(Session, Bufferptr, "Downlink connect needs port number - C P CALLSIGN\r"); - - // Send Port List - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // ENSURE PORT IS AVAILABLE FOR L2 USE - - if (PORT->PROTOCOL >= 10) // Pactor=-style port? - { - int count; - - // if Via PACTOR ARDOP WINMOR or VARA, convert to attach and call = Digi's are in AX25STRING (+7) - - if (memcmp(&axcalls[7], &WINMOR[0], 6) == 0 || - memcmp(&axcalls[7], &ARDOP[0], 6) == 0 || - memcmp(&axcalls[7], &VARA[0], 6) == 0 || - memcmp(&axcalls[7], &PACTORCALL[0], 6) == 0) - { - char newcmd[80]; - - TextCall[TextCallLen] = 0; - sprintf(newcmd, "%s %s", CmdTail, TextCall); - - ATTACHCMD(Session, Bufferptr, newcmd, NULL); - return; - } - - // If on a KAM or SCS with ax.25 on port 2, do an Attach command, then pass on connect - - if (EXTPORT->MAXHOSTMODESESSIONS <= 1) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, port is not an ax.25 port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // Only Allow Attach VHF from Secure Applications or if PERMITGATEWAY is set - - if (EXTPORT->PERMITGATEWAY == 0 && Session->Secure_Session == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, you are not allowed to use this port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - count = EXTPORT->MAXHOSTMODESESSIONS; - count--; // First is Pactor Stream, count is now last ax.25 session - - while (count) - { - if (EXTPORT->ATTACHEDSESSIONS[count] == 0) - { - int Paclen, PortPaclen; - struct DATAMESSAGE * Buffer; - struct DATAMESSAGE Message = {0}; - char Callstring[80]; - int len; - - // Found a free one - use it - - // See if TNC is OK - - Message.PORT = count; - - ret = PORT->PORTTXCHECKCODE(PORT, Message.PORT); - - if ((ret & 0xff00) == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Error - TNC Not Ready\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // GET CIRCUIT TABLE ENTRY FOR OTHER END OF LINK - - NewSess = SetupNewSession(Session, Bufferptr); - if (NewSess == NULL) - return; - - // if a UZ7HO port, and the uplink is L2 or Uz7HO invert SSID bits - - // We only get here if multisession - - if (memcmp(EXTPORT->PORT_DLL_NAME, "UZ7HO", 5) != 0) - goto noFlip; - - if ((Session->L4CIRCUITTYPE & BPQHOST))// host - goto noFlip; - - if ((Session->L4CIRCUITTYPE & PACTOR)) - { - // incoming is Pactorlike - see if UZ7HO - - if (memcmp(Session->L4TARGET.EXTPORT->PORT_DLL_NAME, "UZ7HO", 5) != 0) - goto noFlip; - else - NewSess->L4USER[6] ^= 0x1e; // UZ7HO Uplink - flip - } - else - - // Must be L2 uplink - flip - - NewSess->L4USER[6] ^= 0x1e; // Flip SSID -noFlip: - EXTPORT->ATTACHEDSESSIONS[count] = NewSess; - - NewSess->KAMSESSION = count; - - // Set paclen to lower of incoming and outgoing - - Paclen = Session->SESSPACLEN; // Incoming PACLEN - - if (Paclen == 0) - Paclen = 256; // 0 = 256 - - PortPaclen = PORT->PORTPACLEN; - - if (PortPaclen == 0) - PortPaclen = 256; // 0 = 256 - - if (PortPaclen < Paclen) - Paclen = PortPaclen; - - NewSess->SESSPACLEN = Paclen; - Session->SESSPACLEN = Paclen; - - NewSess->L4STATE = 5; - NewSess->L4CIRCUITTYPE = DOWNLINK + PACTOR; - NewSess->L4TARGET.PORT = PORT; - - // Send the connect command to the TNC - - Buffer = REPLYBUFFER; - - Buffer->PORT = count; - Buffer->PID = 0xf0; - - // if on Telnet Port convert use original cmd tail - - // Why just on telnet - what not all ports?? - - if (memcmp(EXTPORT->PORT_DLL_NAME, "TELNET", 6) == 0 || memcmp(EXTPORT->PORT_DLL_NAME, "SCSPACTOR", 9) == 0) - { - NewSess->Secure_Session = Session->Secure_Session; - len = sprintf(Callstring,"C %s", cmdCopy); - } - else - { - TextCall[TextCallLen] = 0; - - len = sprintf(Callstring,"C %s", TextCall); - - if (axcalls[7]) - { - int digi = 7; - - // we have digis - - len += sprintf(&Callstring[len], " via"); - - while (axcalls[digi]) - { - TextCall[ConvFromAX25(&axcalls[digi], TextCall)] = 0; - len += sprintf(&Callstring[len], " %s", TextCall); - digi += 7; - } - } - } - Callstring[len++] = 13; - Callstring[len] = 0; - - Buffer->LENGTH = len + MSGHDDRLEN + 1; - memcpy(Buffer->L2DATA, Callstring, len); - C_Q_ADD(&PORT->PORTTX_Q, (UINT *)Buffer); - - return; - } - count--; - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "Error - No free streams on this port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if ((Session->L4CIRCUITTYPE & BPQHOST) == 0 && PORT->PORTL3FLAG) - { - //Port only for L3 - - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, port is for internode traffic only\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (PORT->PortUIONLY) - { - //Port only for UI - - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, port is for UI traffic only\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - ret = CheckKissInterlock(PORT, TRUE); - - if (ret) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, Interlocked port %d is in use\r", ret); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - - if (Session->L4USER[6] == 0x42 || Session->L4USER[6] == 0x44) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry - Can't make ax.25 calls with SSID of T or R\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // Get Session Entry for Downlink - - NewSess = SetupNewSession(Session, Bufferptr); - if (NewSess == NULL) - return; - - NewSess->L4CIRCUITTYPE = L2LINK + DOWNLINK; - - // FORMAT LINK TABLE ENTRY FOR THIS CONNECTION - - memcpy(ourcall, NewSess->L4USER, 7); - - // SSID SWAP TEST - LEAVE ALONE FOR HOST or Pactor like (unless UZ7HO) - - if ((Session->L4CIRCUITTYPE & BPQHOST))// host - goto noFlip3; - - if ((Session->L4CIRCUITTYPE & PACTOR)) - { - // incoming is Pactorlike - see if UZ7HO - - if (memcmp(Session->L4TARGET.EXTPORT->PORT_DLL_NAME, "UZ7HO", 5) != 0) - goto noFlip3; - - if (Session->L4TARGET.EXTPORT->MAXHOSTMODESESSIONS < 2) // Not multisession - goto noFlip3; - - ourcall[6] ^= 0x1e; // UZ7HO Uplink - flip - } - else - - // Must be L2 uplink - flip - - ourcall[6] ^= 0x1e; // Flip SSID - -noFlip3: - - // SET UP NEW SESSION (OR RESET EXISTING ONE) - - FindLink(axcalls, ourcall, Port, &LINK); - - if (LINK == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry - System Tables Full\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - - // Should release NewSess - - return; - } - - memcpy(LINK->LINKCALL, axcalls, 7); - memcpy(LINK->OURCALL, ourcall, 7); - - LINK->LINKPORT = PORT; - - LINK->L2TIME = PORT->PORTT1; - - // Copy Digis - - n = 7; - ptr = &LINK->DIGIS[0]; - - while (axcalls[n]) - { - memcpy(ptr, &axcalls[n], 7); - n += 7; - ptr += 7; - - LINK->L2TIME += 2 * PORT->PORTT1; // ADJUST TIMER VALUE FOR 1 DIGI - } - - LINK->LINKTYPE = 2; // DOWNLINK - LINK->LINKWINDOW = PORT->PORTWINDOW; - - RESET2(LINK); // RESET ALL FLAGS - - if (CMD->String[0] == 'N' && SUPPORT2point2) - LINK->L2STATE = 1; // New (2.2) send XID - else - LINK->L2STATE = 2; // Send SABM - - LINK->CIRCUITPOINTER = NewSess; - - NewSess->L4TARGET.LINK = LINK; - - if (PORT->PORTPACLEN) - NewSess->SESSPACLEN = Session->SESSPACLEN = PORT->PORTPACLEN; - - if (CQFLAG == 0) // if a CQ CALL DONT SEND SABM - { - seeifInterlockneeded(PORT); - - if (LINK->L2STATE == 1) - L2SENDXID(LINK); - else - SENDSABM(LINK); - } - ReleaseBuffer((UINT *)REPLYBUFFER); - return; -} - -BOOL DecodeCallString(char * Calls, BOOL * Stay, BOOL * Spy, UCHAR * AXCalls) -{ - // CONVERT CALL + OPTIONAL DIGI STRING TO AX25, RETURN - // CONVERTED STRING IN AXCALLS. Return FALSE if invalied - - char * axptr = AXCalls; - char * ptr, *Context; - int CQFLAG = 0; // NOT CQ CALL - int n = 8; // Max digis - - *Stay = 0; - *Spy = 0; - - memset(AXCalls, 0, 64); - - ptr = strtok_s(Calls, " ,", &Context); - - if (ptr == NULL) - return FALSE; - - // First field is Call - - if (ConvToAX25(ptr, axptr) == 0) - return FALSE; - - axptr += 7; - - ptr = strtok_s(NULL, " ,", &Context); - - while (ptr && n--) - { - // NEXT FIELD = COULD BE CALLSIGN, VIA, OR S (FOR STAY) - - if (strcmp(ptr, "S") == 0) - *Stay = TRUE; - else if (strcmp(ptr, "Z") == 0) - *Spy = TRUE; - else if (memcmp(ptr, "VIA", (int)strlen(ptr)) == 0) - { - } //skip via - else - { - // Convert next digi - - if (ConvToAX25(ptr, axptr) == 0) - return FALSE; - - axptr += 7; - } - - ptr = strtok_s(NULL, " ,", &Context); - } - - return TRUE; -} - - -VOID LINKCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // PROCESS *** LINKED to CALLSIGN - - char * ptr, *Context; - UCHAR axcall[7]; - int ret; - - if (LINKEDFLAG == 'Y' || // UNCONDITIONAL? - (LINKEDFLAG == 'A' && - ((Session->L4CIRCUITTYPE & BPQHOST) || Session->Secure_Session || Session->PASSWORD == 0xffff))) - { - ptr = strtok_s(CmdTail, " ", &Context); - if (ptr) - ptr = strtok_s(NULL, " ", &Context); - - if (ptr) - { - ret = ConvToAX25Ex(ptr, axcall); - - if (ret) - { - memcpy(Session->L4USER, axcall, 7); - strcpy(Bufferptr, OKMSG); - Bufferptr += (int)strlen(OKMSG); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - } - - strcpy(Bufferptr, BADMSG); - Bufferptr += (int)strlen(BADMSG); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - memcpy(Bufferptr, PASSWORDMSG, LPASSMSG); - Bufferptr += LPASSMSG; - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -int CompareNode(const void *a, const void *b); -int CompareAlias(const void *a, const void *b); - -char * DoOneNode(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST * Dest) -{ - char Normcall[10]; - char Alias[10]; - struct NR_DEST_ROUTE_ENTRY * NRRoute; - struct DEST_ROUTE_ENTRY * Route; - struct ROUTE * Neighbour; - int i, Active, len; - - Alias[6] = 0; - - memcpy(Alias, Dest->DEST_ALIAS, 6); - strlop(Alias, ' '); - - Normcall[ConvFromAX25(Dest->DEST_CALL, Normcall)] = 0; - - Bufferptr = Cmdprintf(Session, Bufferptr, "Routes to: %s:%s", Alias, Normcall); - - if (Dest->DEST_COUNT) - Bufferptr = Cmdprintf(Session, Bufferptr, " RTT=%4.2f FR=%d %c %.1d\r", - Dest->DEST_RTT /1000.0, Dest->DEST_COUNT, - (Dest->DEST_STATE & 0x40)? 'B':' ', (Dest->DEST_STATE & 63)); - else - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - NRRoute = &Dest->NRROUTE[0]; - - Active = Dest->DEST_ROUTE; - - for (i = 1; i < 4; i++) - { - Neighbour = NRRoute->ROUT_NEIGHBOUR; - - if (Neighbour) - { - len = ConvFromAX25(Neighbour->NEIGHBOUR_CALL, Normcall); - Normcall[len] = 0; - - Bufferptr = Cmdprintf(Session, Bufferptr, "%c %d %d %d %s\r", - (Active == i)?'>':' ',NRRoute->ROUT_QUALITY, NRRoute->ROUT_OBSCOUNT, Neighbour->NEIGHBOUR_PORT, Normcall); - } - NRRoute++; - } - - // DISPLAY INP3 ROUTES - - Route = &Dest->ROUTE[0]; - - Active = Dest->DEST_ROUTE; - - for (i = 1; i < 4; i++) - { - Neighbour = Route->ROUT_NEIGHBOUR; - - if (Neighbour) - { - double srtt = Route->SRTT/1000.0; - - len = ConvFromAX25(Neighbour->NEIGHBOUR_CALL, Normcall); - Normcall[len] = 0; - - Bufferptr = Cmdprintf(Session, Bufferptr, "%c %d %4.2fs %d %s\r", - (Active == i + 3)?'>':' ',Route->Hops, srtt, Neighbour->NEIGHBOUR_PORT, Normcall); - } - Route++; - } - - return Bufferptr; -} - - -int DoViaEntry(struct DEST_LIST * Dest, int n, char * line, int cursor) -{ - char Portcall[10]; - int len; - - if (Dest->NRROUTE[n].ROUT_NEIGHBOUR != 0 && Dest->NRROUTE[n].ROUT_NEIGHBOUR->INP3Node == 0) - { - len=ConvFromAX25(Dest->NRROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Portcall); - Portcall[len]=0; - - len=sprintf(&line[cursor],"%s %d %d ", - Portcall, - Dest->NRROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_PORT, - Dest->NRROUTE[n].ROUT_QUALITY); - - cursor+=len; - - if (Dest->NRROUTE[n].ROUT_OBSCOUNT > 127) - { - len=sprintf(&line[cursor],"! "); - cursor+=len; - } - } - return cursor; -} - -int DoINP3ViaEntry(struct DEST_LIST * Dest, int n, char * line, int cursor) -{ - char Portcall[10]; - int len; - double srtt; - - if (Dest->ROUTE[n].ROUT_NEIGHBOUR != 0) - { - srtt = Dest->ROUTE[n].SRTT/1000.0; - - len=ConvFromAX25(Dest->ROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Portcall); - Portcall[len]=0; - - len=sprintf(&line[cursor],"%s %d %d %4.2fs ", - Portcall, - Dest->ROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_PORT, - Dest->ROUTE[n].Hops, srtt); - - cursor+=len; - - if (Dest->NRROUTE[n].ROUT_OBSCOUNT > 127) - { - len=sprintf(&line[cursor],"! "); - cursor+=len; - } - } - return cursor; -} - -int WildCmp(char * pattern, char * string) -{ - // Check if string is at end or not. - - if (*pattern == '\0') - return *string == '\0'; - - // Check for single character missing or match - - if (*pattern == '?' || *pattern == *string) - return *string != '\0' && WildCmp(pattern + 1, string + 1); - - if (*pattern == '*') - { - // Check for multiple character missing - - return WildCmp(pattern + 1, string) || (*string != '\0' && WildCmp(pattern, string + 1)); - } - - return 0; -} - -VOID CMDN00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - struct DEST_LIST * Dest = DESTS; - int count = MAXDESTS, i; - char Normcall[10]; - char Alias[10]; - int Width = 4; - int x = 0, n = 0; - struct DEST_LIST * List[1000]; - char Param = 0; - char * ptr, * param2,* Context; - char Nodeline[21]; - char AXCALL[7]; - char * Call; - char * Qualptr; - int Qual; - char line[160]; - int cursor, len; - UCHAR axcall[7]; - int SavedOBSINIT = OBSINIT; - struct ROUTE * ROUTE = NULL; - char Pattern[80] = ""; - char * firststar; - int minqual = 0; - - ptr = strtok_s(CmdTail, " ", &Context); - param2 = strtok_s(NULL, " ", &Context); - - if (ptr) - { - if (strcmp(ptr, "ADD") == 0) - goto NODE_ADD; - - if (strcmp(ptr, "DEL") == 0) - goto NODE_DEL; - - if (strcmp(ptr, "VIA") == 0) - goto NODE_VIA; - } - - if (ptr) - { - // Could be C or a pattern. Accept C pattern or pattern C - - if ((int)strlen(ptr) > 1) - { - strcpy(Pattern, ptr); - if (param2 && param2[0] == 'C') - Param = 'C'; - } - else - { - Param = ptr[0]; - if (param2) - strcpy(Pattern, param2); - } - } - - // Pattern >nnn selects nodes with at least that quality - - if (Pattern[0] == '>') - { - minqual = atoi(&Pattern[1]); - Pattern[0] = 0; - } - - // We need to pick out CALL or CALL* from other patterns (as call use detail display) - - firststar = strchr(Pattern, '*'); - - if ((firststar && *(firststar + 1) != 0)|| strchr(Pattern, '?')) //(* not on end) - - // definitely pattern - - goto DoNodePattern; - - // If it works as CALL*, process, else drop through - - if (Pattern[0]) - { - UCHAR AXCall[8]; - int count; - int paramlen = (int)strlen(ptr); - char parampadded[20]; - int n = 0; - - Alias[8] = 0; - strcpy(parampadded, Pattern); - strcat(parampadded, " "); - - ConvToAX25(Pattern, AXCall); - - // if * on end, list all ssids - - if (firststar) - { - AXCall[6] = 0; - - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - while (AXCall[6] < 32) - { - Dest = DESTS; - - for (count = 0; count < MAXDESTS; count++) - { - if (memcmp(Dest->DEST_ALIAS, parampadded, 6) == 0 || CompareCalls(Dest->DEST_CALL, AXCall)) - { - break; - } - Dest++; - } - - if (count < MAXDESTS) - { - Bufferptr = DoOneNode(Session, Bufferptr, Dest); - n++; - } - - AXCall[6] += 2; - } - - if (n) // Found Some - { - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - Dest = DESTS; // Reset - - // Drop through to try as pattern - } - else - { - // process as just call - - for (count = 0; count < MAXDESTS; count++) - { - if (memcmp(Dest->DEST_ALIAS, parampadded, 6) == 0 || CompareCalls(Dest->DEST_CALL, AXCall)) - { - break; - } - Dest++; - } - - if (count == MAXDESTS) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not found\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - Bufferptr = DoOneNode(Session, Bufferptr, Dest); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - } - -DoNodePattern: - - Bufferptr = Cmdprintf(Session, Bufferptr, "Nodes\r"); - - while (count--) - { - if (Dest->DEST_CALL[0] != 0) - { - if (Dest->NRROUTE->ROUT_QUALITY >= minqual) - if (Param != 'T' || Dest->DEST_COUNT) - List[n++] = Dest; - - if (n > 999) - break; - } - Dest++; - } - - if (Param == 'C') - qsort(List, n, sizeof(void *), CompareNode); - else - qsort(List, n, sizeof(void *), CompareAlias); - - - for (i = 0; i < n; i++) - { - int len = ConvFromAX25(List[i]->DEST_CALL, Normcall); - Normcall[len]=0; - - memcpy(Alias, List[i]->DEST_ALIAS, 6); - Alias[6] = 0; - strlop(Alias, ' '); - - if (strlen(Alias)) - strcat(Alias, ":"); - - if (Alias[0] == '#' && HIDENODES == 1 && Param != '*') // Hidden Node and not N * command - continue; - - if (Pattern[0]) - if (!WildCmp(Pattern, Normcall) && !WildCmp(Pattern, Alias)) - continue; - - if (Param == 'T') - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%s%s RTT=%4.2f Frames = %d %c %.1d\r", - Alias, Normcall, List[i]->DEST_RTT /1000.0, List[i]->DEST_COUNT, - (List[i]->DEST_STATE & 0x40)? 'B':' ', (List[i]->DEST_STATE & 63)); - } - else - { - len = sprintf(Nodeline, "%s%s", Alias, Normcall); - memset(&Nodeline[len], ' ', 20 - len); - Nodeline[20] = 0; - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", Nodeline); - - if (++x == Width) - { - x = 0; - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - } - } - } - - if (x) - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - goto SendReply; - - -NODE_VIA: - - // List Nodes reachable via a neighbour - - ptr = param2; - - if (ptr == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Missing Call\r"); - goto SendReply; - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - ConvToAX25(ptr, AXCALL); - - Dest = DESTS; - - Dest-=1; - - for (count=0; countNRROUTE[0].ROUT_NEIGHBOUR == 0 && Dest->ROUTE[0].ROUT_NEIGHBOUR == 0) - continue; - - - if ((Dest->NRROUTE[0].ROUT_NEIGHBOUR && CompareCalls(Dest->NRROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, AXCALL)) - || (Dest->NRROUTE[1].ROUT_NEIGHBOUR && CompareCalls(Dest->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, AXCALL)) - || (Dest->NRROUTE[2].ROUT_NEIGHBOUR && CompareCalls(Dest->NRROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, AXCALL)) - - || (Dest->ROUTE[0].ROUT_NEIGHBOUR && CompareCalls(Dest->ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, AXCALL)) - || (Dest->ROUTE[1].ROUT_NEIGHBOUR && CompareCalls(Dest->ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, AXCALL)) - || (Dest->ROUTE[2].ROUT_NEIGHBOUR && CompareCalls(Dest->ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, AXCALL))) - { - len=ConvFromAX25(Dest->DEST_CALL,Normcall); - - Normcall[len]=0; - - memcpy(Alias,Dest->DEST_ALIAS,6); - - Alias[6]=0; - - for (i=0;i<6;i++) - { - if (Alias[i] == ' ') - Alias[i] = 0; - } - - cursor=sprintf(line,"%s:%s ", Alias,Normcall); - - cursor = DoViaEntry(Dest, 0, line, cursor); - cursor = DoViaEntry(Dest, 1, line, cursor); - cursor = DoViaEntry(Dest, 2, line, cursor); - cursor = DoINP3ViaEntry(Dest, 0, line, cursor); - cursor = DoINP3ViaEntry(Dest, 1, line, cursor); - cursor = DoINP3ViaEntry(Dest, 2, line, cursor); - - line[cursor++]='\r'; - line[cursor++]=0; - - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", line); - } - } - - - goto SendReply; - -NODE_ADD: - - // FORMAT IS NODE ADD ALIAS:CALL QUAL ROUTE PORT - - - if (Session->PASSWORD != 0xFFFF) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", PASSWORDMSG); - goto SendReply; - } - - ptr = param2; - - if (ptr == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Missing Alias:Call\r"); - goto SendReply; - } - - Call = strlop(ptr, ':'); - - if (Call == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Missing Alias:Call\r"); - goto SendReply; - } - - - ConvToAX25(Call, AXCALL); - - Qualptr = strtok_s(NULL, " ", &Context); - - if (Qualptr == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Quality missing\r"); - goto SendReply; - } - - Qual = atoi(Qualptr); - - if (Qual < MINQUAL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Quality is below MINQUAL\r"); - goto SendReply; - } - - if (FindDestination(AXCALL, &Dest)) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Node already in Table\r"); - goto SendReply; - } - - if (Dest == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Node Table Full\r"); - goto SendReply; - } - - memcpy(Dest->DEST_CALL, AXCALL, 7); - memcpy(Dest->DEST_ALIAS, ptr, 6); - - NUMBEROFNODES++; - - ptr = strtok_s(NULL, " ", &Context); - - if (ptr == NULL || ptr[0] == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Neighbour missing\r"); - goto SendReply; - } - - if (ConvToAX25(ptr, axcall) == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Neighbour\r"); - goto SendReply; - } - else - { - int Port; - - ptr = strtok_s(NULL, " ", &Context); - if (ptr == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Port missing\r"); - goto SendReply; - } - - Port = atoi(ptr); - - if (Context[0] == '!') - { - OBSINIT = 255; //; SPECIAL FOR LOCKED - } - - if (FindNeighbour(axcall, Port, &ROUTE)) - { - PROCROUTES(Dest, ROUTE, Qual); - } - - OBSINIT = SavedOBSINIT; - - Bufferptr = Cmdprintf(Session, Bufferptr, "Node Added\r"); - goto SendReply; - } - - - - -/* -PNODE48: - - -; GET NEIGHBOURS FOR THIS DESTINATION -; - CALL CONVTOAX25 - JNZ SHORT BADROUTE -; - CALL GETVALUE - MOV SAVEPORT,AL ; SET PORT FOR _FINDNEIGHBOUR - - CALL GETVALUE - MOV ROUTEQUAL,AL -; - MOV ESI,OFFSET32 AX25CALL - - PUSH EBX ; SAVE DEST - CALL _FINDNEIGHBOUR - MOV EAX,EBX ; ROUTE TO AX - POP EBX - - JZ SHORT NOTBADROUTE - - JMP SHORT BADROUTE - -NOTBADROUTE: -; -; UPDATE ROUTE LIST FOR THIS DEST -; - MOV ROUT1_NEIGHBOUR[EBX],EAX - MOV AL,ROUTEQUAL - MOV ROUT1_QUALITY[EBX],AL - MOV ROUT1_OBSCOUNT[EBX],255 ; LOCKED -; - POP EDI - POP EBX - - INC _NUMBEROFNODES - - JMP SENDOK - -BADROUTE: -; -; KILL IT -; - MOV ECX,TYPE DEST_LIST - MOV EDI,EBX - MOV AL,0 - REP STOSB - - JMP BADROUTECMD - -*/ - - goto SendReply; - - -NODE_DEL: - - if (Session->PASSWORD != 0xFFFF) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", PASSWORDMSG); - goto SendReply; - } - - ptr = param2; - - if (ptr == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Missing Call\r"); - goto SendReply; - } - - if (strcmp(ptr, "ALL") == 0) - { - struct DEST_LIST * DEST = DESTS; - int n = MAXDESTS; - - while (n--) - { - if (DEST->DEST_CALL[0] && ((DEST->DEST_STATE & 0x80) == 0)) // Don't delete appl node - REMOVENODE(DEST); - - DEST++; - } - - ClearNodes(); - - Bufferptr = Cmdprintf(Session, Bufferptr, "All Nodes Deleted\r"); - goto SendReply; - } - - ConvToAX25(ptr, AXCALL); - - if (FindDestination(AXCALL, &Dest) == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not Found\r"); - goto SendReply; - } - - if (Dest->DEST_STATE & 0x80) - Bufferptr = Cmdprintf(Session, Bufferptr, "APPL Node - Can't delete\r"); - else - { - REMOVENODE(Dest); - Bufferptr = Cmdprintf(Session, Bufferptr, "Node Deleted\r"); - } - Bufferptr = Cmdprintf(Session, Bufferptr, "Node Deleted\r"); - -SendReply: - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID CMDQUERY(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * UserCMD) -{ - // DISPLAY AVAILABLE COMMANDS - - int n; - char * ptr; - char ApplList[2048]; - char * out = ApplList; - - CMDX * CMD = &COMMANDS[APPL1]; - - for (n = 0; n < NumberofAppls; n++) - { - ptr = &CMD->String[0]; - if (*(ptr) != '*') - { - while (*ptr != ' ') - { - *(out++) = *(ptr++); - } - *(out++) = ' '; - } - CMD++; - } - - *(out) = 0; - - n = CMDLISTLEN; - - if (NEEDMH == 0) - n -= 7; // Dont show MH - - Bufferptr = Cmdprintf(Session, Bufferptr, "%s%s\r", ApplList, CMDLIST); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -char * FormatMH(MHSTRUC * MH, char Format); - -VOID MHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // DISPLAY HEARD LIST - - int Port = 0, sess = 0; - char * ptr, *Context, *pattern; - struct PORTCONTROL * PORT = NULL; - MHSTRUC * MH; - int count = MHENTRIES; - int n; - char Normcall[20]; - char From[10]; - char DigiList[100]; - char * Output; - int len; - char Digi = 0; - - - // Note that the MHDIGIS field may contain rubbish. You have to check End of Address bit to find - // how many digis there are - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr == NULL || ptr[0] == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Port Number needed eg MH 1\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (ptr) - Port = atoi(ptr); - - if (Port) - PORT = GetPortTableEntryFromPortNum(Port); - - if (PORT == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - pattern = strtok_s(NULL, " ", &Context); - - if (pattern) - _strupr(pattern); // Optional filter - - MH = PORT->PORTMHEARD; - - if (MH == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "MHEARD not enabled on that port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (pattern && strstr(pattern, "CLEAR")) - { - if (Session->Secure_Session) - { - memset(MH, 0, MHENTRIES * sizeof(MHSTRUC)); - SaveMH(); - Bufferptr = Cmdprintf(Session, Bufferptr, "Heard List for Port %d Cleared\r", Port); - } - else - { - Bufferptr = Cmdprintf(Session, Bufferptr, "MH Clear needs SYSOP status\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - } - else - { - if (CMD->String[2] == 'V') // MHV - { - Bufferptr = Cmdprintf(Session, Bufferptr, "MHeard List %s for Port %d\r", MYNODECALL, Port); - Bufferptr = Cmdprintf(Session, Bufferptr, "Callsign Last heard Pkts RX via Digi ;) \r"); - Bufferptr = Cmdprintf(Session, Bufferptr, "--------- ----------- ------- ------------------------------------------\r"); - } - else - if (pattern) - Bufferptr = Cmdprintf(Session, Bufferptr, "Heard List for Port %d filtered by %s\r", Port, pattern); - else - Bufferptr = Cmdprintf(Session, Bufferptr, "Heard List for Port %d\r", Port); - } - while (count--) - { - if (MH->MHCALL[0] == 0) - break; - - Digi = 0; - - len = ConvFromAX25(MH->MHCALL, Normcall); - - Normcall[len++] = MH->MHDIGI; - Normcall[len++] = 0; - - if (pattern && strstr(Normcall, pattern) == 0) - { - MH++; - continue; - } - - n = 8; // Max number of digi-peaters - - ptr = &MH->MHCALL[6]; // End of Address bit - - Output = &DigiList[0]; - - if ((*ptr & 1) == 0) - { - // at least one digi - - strcpy(Output, "via "); - Output += 4; - - while ((*ptr & 1) == 0) - { - // MORE TO COME - - From[ConvFromAX25(ptr + 1, From)] = 0; - Output += sprintf((char *)Output, "%s", From); - - ptr += 7; - n--; - - if (n == 0) - break; - - // See if digi actioned - put a * on last actioned - - if (*ptr & 0x80) - { - if (*ptr & 1) // if last address, must need * - { - *(Output++) = '*'; - Digi = '*'; - } - - else - if ((ptr[7] & 0x80) == 0) // Repeased by next? - { - *(Output++) = '*'; // No, so need * - Digi = '*'; - } - -} - *(Output++) = ','; - } - *(--Output) = 0; // remove last comma - } - else - *(Output) = 0; - - // if we used a digi set * on call and display via string - - - if (Digi) - Normcall[len++] = Digi; - else - DigiList[0] = 0; // Dont show list if not used - - Normcall[len++] = 0; - - - ptr = FormatMH(MH, CMD->String[2]); - - if (CMD->String[2] == 'V') // MHV - Bufferptr = Cmdprintf(Session, Bufferptr, "%-10s %-10s %-10d %-30s\r", - Normcall, ptr, MH->MHCOUNT, DigiList); - else - Bufferptr = Cmdprintf(Session, Bufferptr, "%-10s %s %s\r", Normcall, ptr, DigiList); - - MH++; - } - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -int Rig_Command(TRANSPORTENTRY * Session, char * Command); - -VOID RADIOCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * UserCMD) -{ - char * ptr; - - if (Rig_Command(Session, CmdTail)) - { - ReleaseBuffer((UINT *)REPLYBUFFER); - return; - } - - // Error Message is in buffer - - ptr = strchr(CmdTail, 13); - - if (ptr) - { - int len = (int)(++ptr - CmdTail); - - memcpy(Bufferptr, CmdTail, len); - Bufferptr += len; - } - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - - -VOID SendNRRecordRoute(struct DEST_LIST * DEST, TRANSPORTENTRY * Session); - - -VOID NRRCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * UserCMD) -{ - // PROCESS 'NRR - Netrom Record Route' COMMAND - - char * ptr, *Context; - struct DEST_LIST * Dest = DESTS; - int count = MAXDESTS; - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - { - UCHAR AXCall[8]; - int count; - - ConvToAX25(ptr, AXCall); - strcat(ptr, " "); - - for (count = 0; count < MAXDESTS; count++) - { - if (memcmp(Dest->DEST_ALIAS, ptr, 6) == 0 || CompareCalls(Dest->DEST_CALL, AXCall)) - { - SendNRRecordRoute(Dest, Session); - memcpy(Bufferptr, OKMSG, 3); - Bufferptr += 3; - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - - return; - } - Dest++; - } - } - Bufferptr = Cmdprintf(Session, Bufferptr, "Not found\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - -int CHECKINTERLOCK(struct PORTCONTROL * OURPORT) -{ - // See if any Interlocked ports are Busy - - struct PORTCONTROL * PORT = PORTTABLE; - struct _EXTPORTDATA * EXTPORT; - - int n = NUMBEROFPORTS; - int ourgroup = OURPORT->PORTINTERLOCK; - - while (PORT) - { - if (PORT != OURPORT) - { - if (PORT->PORTINTERLOCK == ourgroup) - { - // Same Group - is it busy - - int i = 0; - - EXTPORT = (struct _EXTPORTDATA *)PORT; - - while (i < 27) - if (EXTPORT->ATTACHEDSESSIONS[i++]) - return PORT->PORTNUMBER; - } - } - PORT = PORT->PORTPOINTER; - } - - return 0; -} - -VOID ATTACHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * UserCMD) -{ - // ATTACH to a PACTOR or similar port - - TRANSPORTENTRY * NewSess; - struct _EXTPORTDATA * EXTPORT; - struct TNCINFO * TNC = 0; - - int Port = 0, sess = 0; - char * ptr, *Context; - int ret; - struct PORTCONTROL * PORT = NULL; - struct DATAMESSAGE Message = {0}; - int Paclen, PortPaclen; - struct DATAMESSAGE * Buffer; - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - Port = atoi(ptr); - - if (Port) - PORT = GetPortTableEntryFromPortNum(Port); - - if (PORT == NULL || PORT->PROTOCOL < 10) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // If attach on telnet port, find a free stream - - EXTPORT = (struct _EXTPORTDATA *)PORT; - - if (strstr(EXTPORT->PORT_DLL_NAME, "TELNET")) - { - int count = EXTPORT->MAXHOSTMODESESSIONS; - count--; // First is Pactor Stream, count is now last ax.25 session - - while (count) - { - if (EXTPORT->ATTACHEDSESSIONS[count] == 0) - { - int Paclen, PortPaclen; - struct DATAMESSAGE Message = {0}; - - // Found a free one - use it - - // See if TNC is OK - - Message.PORT = count; - - ret = PORT->PORTTXCHECKCODE(PORT, Message.PORT); - - if ((ret & 0xff00) == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Error - TNC Not Ready\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // GET CIRCUIT TABLE ENTRY FOR OTHER END OF LINK - - NewSess = SetupNewSession(Session, Bufferptr); - - if (NewSess == NULL) - return; - - EXTPORT->ATTACHEDSESSIONS[count] = NewSess; - - NewSess->Secure_Session = Session->Secure_Session; - - NewSess->KAMSESSION = count; - - // Set paclen to lower of incoming and outgoing - - Paclen = Session->SESSPACLEN; // Incoming PACLEN - - if (Paclen == 0) - Paclen = 256; // 0 = 256 - - PortPaclen = PORT->PORTPACLEN; - - if (PortPaclen == 0) - PortPaclen = 256; // 0 = 256 - - if (PortPaclen < Paclen) - Paclen = PortPaclen; - - NewSess->SESSPACLEN = Paclen; - Session->SESSPACLEN = Paclen; - - NewSess->L4STATE = 5; - NewSess->L4CIRCUITTYPE = DOWNLINK + PACTOR; - NewSess->L4TARGET.PORT = PORT; - - ptr = strtok_s(NULL, " ", &Context); - sess = count; - - // Replace command tail with original (before conversion to upper case - - Context = Context + (OrigCmdBuffer - COMMANDBUFFER); - - goto checkattachandcall; - - - memcpy(Bufferptr, OKMSG, 3); - Bufferptr += 3; - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - - return; - } - count--; - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "Error - No free streams on this port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - Message.PORT = 0; - - ret = PORT->PORTTXCHECKCODE(PORT, Message.PORT); - - if ((ret & 0xff00) == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Error - TNC Not Ready\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // See if "Attach and Call" (for VHF ports) - - ptr = strtok_s(NULL, " ", &Context); - - if (ptr && strcmp(ptr, "S") == 0) - { - Session->STAYFLAG = TRUE; - ptr = strtok_s(NULL, " ", &Context); - } - - if (ptr) - { - // we have another param - - // if it is a single char it is a channel number for vhf attach - - if (strlen(ptr) == 1) - { - // Only Allow Attach VHF from Secure Applications or if PERMITGATEWAY is set - - if (EXTPORT->PERMITGATEWAY == 0 && Session->Secure_Session == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, you are not allowed to use this port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - sess = ptr[0] - '@'; - - if (sess < 1 || sess > EXTPORT->MAXHOSTMODESESSIONS) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Invalid Channel\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - ptr = strtok_s(NULL, " ", &Context); - - if (ptr && strcmp(ptr, "S") == 0) - { - Session->STAYFLAG = TRUE; - ptr = strtok_s(NULL, " ", &Context); - } - } - } - - if (ret & 0x8000) // Disconnecting - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port in use\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // Check Interlock. Only ports with a TNC record can be interlocked - - TNC = PORT->TNC; - - if (TNC) - { - // See if any interlocked ports are in use - - struct TNCINFO * OtherTNC; - int i; - int rxInterlock = TNC->RXRadio; - int txInterlock = TNC->TXRadio; - - if (rxInterlock || txInterlock) - { - for (i=1; i <= MAXBPQPORTS; i++) - { - OtherTNC = TNCInfo[i]; - - if (OtherTNC == NULL) - continue; - - if (OtherTNC == TNC) - continue; - - if (rxInterlock && rxInterlock == OtherTNC->RXRadio || txInterlock && txInterlock == OtherTNC->TXRadio) // Same Group - { - int n; - - for (n = 0; n <= 26; n++) - { - if (OtherTNC->PortRecord->ATTACHEDSESSIONS[n]) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, interlocked port %d is in use\r", i); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - } - } - } - } - } - - - - - if (EXTPORT->ATTACHEDSESSIONS[sess] || PORT->PortSuspended) - { - // In use - - Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port in use\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - // GET CIRCUIT TABLE ENTRY FOR OTHER END OF LINK - - NewSess = SetupNewSession(Session, Bufferptr); - - if (NewSess == NULL) - return; - - // if a UZ7HO port, and the uplink is L2 or Uz7HO and multisession, - // invert SSID bits - - if (memcmp(EXTPORT->PORT_DLL_NAME, "UZ7HO", 5) != 0) - goto noFlip1; - - if (EXTPORT->MAXHOSTMODESESSIONS < 2) // Not multisession - goto noFlip1; - - if ((Session->L4CIRCUITTYPE & BPQHOST)) // host - goto noFlip1; - - if ((Session->L4CIRCUITTYPE & PACTOR)) - { - // incoming is Pactorlike - see if UZ7HO - - if (memcmp(Session->L4TARGET.EXTPORT->PORT_DLL_NAME, "UZ7HO", 5) != 0) - goto noFlip1; - else - NewSess->L4USER[6] ^= 0x1e; // UZ7HO Uplink - flip - } - else - - // Must be L2 uplink - flip - - NewSess->L4USER[6] ^= 0x1e; // Flip SSID -noFlip1: - - EXTPORT->ATTACHEDSESSIONS[sess] = NewSess; - - NewSess->KAMSESSION = sess; - - // Set paclen to lower of incoming and outgoing - - Paclen = Session->SESSPACLEN; // Incoming PACLEN - - if (Paclen == 0) - Paclen = 256; // 0 = 256 - - PortPaclen = PORT->PORTPACLEN; - - if (PortPaclen == 0) - PortPaclen = 256; // 0 = 256 - - if (PortPaclen < Paclen) - Paclen = PortPaclen; - - NewSess->SESSPACLEN = Paclen; - Session->SESSPACLEN = Paclen; - NewSess->L4STATE = 5; - NewSess->L4CIRCUITTYPE = DOWNLINK + PACTOR; - NewSess->L4TARGET.PORT = PORT; - -checkattachandcall: - - // If set freq on attach is defined, do it - - if (TNC && TNC->ActiveRXFreq && TNC->RXRadio) - { - char Msg[128]; - - sprintf(Msg, "R%d %f", TNC->RXRadio, TNC->ActiveRXFreq); - Rig_Command( (TRANSPORTENTRY *) -1, Msg); - } - - if (TNC && TNC->ActiveTXFreq && TNC->TXRadio && TNC->TXRadio != TNC->RXRadio) - { - char Msg[128]; - - sprintf(Msg, "R%d %f", TNC->TXRadio, TNC->ActiveTXFreq); - Rig_Command( (TRANSPORTENTRY *) -1, Msg); - } - - if (ptr) - { - // we have a call to connect to - - char Callstring[80]; - int len; - - Buffer = REPLYBUFFER; - Buffer->PORT = sess; - Buffer->PID = 0xf0; - - len = sprintf(Callstring,"C %s", ptr); - - ptr = strtok_s(NULL, " ", &Context); - - while (ptr) // if any other params (such as digis) copy them - { - if (strcmp(ptr, "S") == 0) - { - Session->STAYFLAG = TRUE; - } - else - len += sprintf(&Callstring[len], " %s", ptr); - - ptr = strtok_s(NULL, " ", &Context); - } - - Callstring[len++] = 13; - Callstring[len] = 0; - - Buffer->LENGTH = len + MSGHDDRLEN + 1; - memcpy(Buffer->L2DATA, Callstring, len); - C_Q_ADD(&PORT->PORTTX_Q, (UINT *)Buffer); - - return; - } - - memcpy(Bufferptr, OKMSG, 3); - Bufferptr += 3; - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - - return; -} - -// SYSOP COMMANDS - -CMDX COMMANDS[] = -{ - "SAVENODES ",8, SAVENODES, 0, - "TELRECONFIG ",4, RECONFIGTELNET, 0, - "SAVEMH ",6, SAVEMHCMD, 0, - "REBOOT ",6, REBOOT, 0, - "RIGRECONFIG ",8 , RIGRECONFIG, 0, - "RESTART ",7,RESTART,0, - "RESTARTTNC ",10,RESTARTTNC,0, - "SENDNODES ",8,SENDNODES,0, - "EXTRESTART ",10, EXTPORTVAL, offsetof(EXTPORTDATA, EXTRESTART), - "TXDELAY ",3, PORTVAL, offsetof(PORTCONTROLX, PORTTXDELAY), - "MAXFRAME ",3, PORTVAL, offsetof(PORTCONTROLX, PORTWINDOW), - "RETRIES ",3, PORTVAL, offsetof(PORTCONTROLX, PORTN2), - "FRACK ",3,PORTVAL, offsetof(PORTCONTROLX, PORTT1), - "RESPTIME ",3,PORTVAL, offsetof(PORTCONTROLX, PORTT2), - "PPACLEN ",3,PORTVAL, offsetof(PORTCONTROLX, PORTPACLEN), - "QUALITY ",3,PORTVAL, offsetof(PORTCONTROLX, PORTQUALITY), - "PERSIST ",2,PORTVAL, offsetof(PORTCONTROLX, PORTPERSISTANCE), - "TXTAIL ",3,PORTVAL, offsetof(PORTCONTROLX, PORTTAILTIME), - "XMITOFF ",7,PORTVAL, offsetof(PORTCONTROLX, PORTDISABLED), - "DIGIFLAG ",5,PORTVAL, offsetof(PORTCONTROLX, DIGIFLAG), - "DIGIPORT ",5,PORTVAL, offsetof(PORTCONTROLX, DIGIPORT), - "MAXUSERS ",4,PORTVAL, offsetof(PORTCONTROLX, USERS), - "L3ONLY ",6,PORTVAL, offsetof(PORTCONTROLX, PORTL3FLAG), - "BBSALIAS ",4,PORTVAL, offsetof(PORTCONTROLX, PORTBBSFLAG), - "VALIDCALLS ",5,VALNODES,0, - "WL2KSYSOP ",5,WL2KSYSOP,0, - "STOPPORT ",4,STOPPORT,0, - "STARTPORT ",5,STARTPORT,0, - "STOPCMS ",7,STOPCMS,0, - "STARTCMS ",8,STARTCMS,0, - - "FINDBUFFS ",4,FINDBUFFS,0, - "KISS ",4,KISSCMD,0, - "GETPORTCTEXT",9,GetPortCTEXT, 0, - -#ifdef EXCLUDEBITS - - "EXCLUDE ",4,ListExcludedCalls,0, - -#endif - - "FULLDUP ",4,PORTVAL, offsetof(PORTCONTROLX, FULLDUPLEX), - "SOFTDCD ",4,PORTVAL, offsetof(PORTCONTROLX, SOFTDCDFLAG), - "OBSINIT ",7,SWITCHVAL,(size_t)&OBSINIT, - "OBSMIN ",6,SWITCHVAL,(size_t)&OBSMIN, - "NODESINT ",8,SWITCHVAL,(size_t)&L3INTERVAL, - "L3TTL ",5,SWITCHVAL,(size_t)&L3LIVES, - "L4RETRIES ",5,SWITCHVAL,(size_t)&L4N2, - "L4TIMEOUT ",5,SWITCHVALW,(size_t)&L4T1, - "T3 ",2,SWITCHVALW,(size_t)&T3, - "NODEIDLETIME",8,SWITCHVALW,(size_t)&L4LIMIT, - "LINKEDFLAG ",10,SWITCHVAL,(size_t)&LINKEDFLAG, - "IDINTERVAL ",5,SWITCHVAL,(size_t)&IDINTERVAL, - "MINQUAL ",7,SWITCHVAL,(size_t)&MINQUAL, - "FULLCTEXT ",6,SWITCHVAL,(size_t)&FULL_CTEXT, - "HIDENODES ",8,SWITCHVAL,(size_t)&HIDENODES, - "L4DELAY ",7,SWITCHVAL,(size_t)&L4DELAY, - "L4WINDOW ",6,SWITCHVAL,(size_t)&L4DEFAULTWINDOW, - "BTINTERVAL ",5,SWITCHVAL,(size_t)&BTINTERVAL, - "PASSWORD ", 8, PWDCMD, 0, - - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, - "************", 12, APPLCMD, 0, // Apppl 32 is internal Terminal - "*** LINKED ",10,LINKCMD,0, - "CQ ",2,CQCMD,0, - "CONNECT ",1,CMDC00,0, - "NC ",2,CMDC00,0, - "BYE ",1,BYECMD,0, - "QUIT ",1,BYECMD,0, - "INFO ",1,CMDI00,0, - "HELP ",1,HELPCMD,0, - "VERSION ",1,CMDV00,0, - "NODES ",1,CMDN00,0, - "LINKS ",1,CMDL00,0, - "LISTEN ",3,LISTENCMD,0, - "L4T1 ",2,CMDT00,0, - "PORTS ",1,CMDP00,0, - "PACLEN ",3,CMDPAC,0, - "IDLETIME ",4,CMDIDLE,0, - "ROUTES ",1,CMDR00,0, - "STATS ",1,CMDSTATS,0, - "USERS ",1,CMDS00,0, - "UNPROTO ",2,UNPROTOCMD,0, - "? ",1,CMDQUERY,0, - "DUMP ",4,DUMPCMD,0, - "MHU ",3,MHCMD,0, // UTC Times - "MHL ",3,MHCMD,0, // Local Times - "MHV ",3,MHCMD,0, - "MHEARD ",1,MHCMD,0, - "APRS ",2,APRSCMD,0, - "ATTACH ",1,ATTACHCMD,0, - "RADIO ",3,RADIOCMD,0, - "AXRESOLVER ",3,AXRESOLVER,0, - "AXMHEARD ",3,AXMHEARD,0, - "TELSTATUS ",3,SHOWTELNET,0, - "NRR ",1,NRRCMD,0, - "PING ",2,PING,0, - "AGWSTATUS ",3,SHOWAGW,0, - "ARP ",3,SHOWARP,0, - "NAT ",3,SHOWNAT,0, - "IPROUTE ",3,SHOWIPROUTE,0, - "UZ7HO ",5,UZ7HOCMD,0, - "QTSM ",4,QTSMCMD,0, - - "..FLMSG ",7,FLMSG,0 -}; - -CMDX * CMD = NULL; - -int NUMBEROFCOMMANDS = sizeof(COMMANDS)/sizeof(CMDX); - -char * ReplyPointer; // Pointer into reply buffer - -int DecodeNodeName(char * NodeName, char * ptr) -{ - // NodeName is TABLE ENTRY WITH AX25 CALL AND ALIAS - - // Copyies 20 byte 20 DECODED NAME IN FORM ALIAS:CALL to ptr - // Returns significant length of string - - int len; - char Normcall[10]; - char * alias = &NodeName[7]; - int n = 6; - char * start = ptr; - - memset(ptr, ' ', 20); - - len = ConvFromAX25(NodeName, Normcall); - - if (*(alias) > ' ') // Does alias start with a null or a space ? - { - while (*(alias) > ' ' && n--) - { - *ptr++ = *alias++; - } - *ptr++ = ':'; - } - - memcpy(ptr, Normcall, len); - ptr += len; - - return (int)(ptr - start); -} - -char * SetupNodeHeader(struct DATAMESSAGE * Buffer) -{ - char Header[20]; - int len; - - char * ptr = &Buffer->L2DATA[0]; - - len = DecodeNodeName(MYCALLWITHALIAS, Header); - - memcpy (ptr, Header, len); - ptr += len; - - (*ptr++) = HEADERCHAR; - (*ptr++) = ' '; - - return ptr; -} - -VOID SendCommandReply(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer, int Len) -{ - if (Len == (4 + sizeof(void *))) // Null Packet - { - ReleaseBuffer((UINT *)Buffer); - return; - } - - Buffer->LENGTH = Len; - - C_Q_ADD(&Session->L4TX_Q, (UINT *)Buffer); - - PostDataAvailable(Session); -} - - -VOID CommandHandler(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer) -{ - // ignore frames with single NULL (Keepalive) - - if (Buffer->LENGTH == sizeof(void *) + 5 && Buffer->L2DATA[0] == 0) - { - ReleaseBuffer(Buffer); - return; - } - - if (Buffer->LENGTH > 100) - { -// Debugprintf("BPQ32 command too long %s", Buffer->L2DATA); - ReleaseBuffer(Buffer); - return; - } - -InnerLoop: - - InnerCommandHandler(Session, Buffer); - -// See if any more commands in buffer - - if (Session->PARTCMDBUFFER) - { - char * ptr1, * ptr2; - int len; - - Buffer = Session->PARTCMDBUFFER; - - // Check that message has a CR, if not save buffer and exit - - len = Buffer->LENGTH - (4 + sizeof(void *)); - ptr1 = &Buffer->L2DATA[0]; - - ptr2 = memchr(ptr1, 13, len); - - if (ptr2 == NULL) - return; - - Session->PARTCMDBUFFER = NULL; - - goto InnerLoop; - } -} - - -VOID InnerCommandHandler(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer) -{ - char * ptr1, * ptr2, *ptr3; - int len, oldlen, newlen, rest, n; - struct DATAMESSAGE * OldBuffer; - struct DATAMESSAGE * SaveBuffer; - char c; - - // If a partial command is stored, append this data to it. - - if (Session->PARTCMDBUFFER) - { - len = Buffer->LENGTH - (sizeof(void *) + 4); - ptr1 = &Buffer->L2DATA[0]; - - OldBuffer = Session->PARTCMDBUFFER; // Old Data - - if (OldBuffer == Buffer) - { - // something has gone horribly wrong - - Session->PARTCMDBUFFER = NULL; - return; - } - - oldlen = OldBuffer->LENGTH; - - newlen = len + oldlen; - - if (newlen > 200) - { - // Command far too long - ignore previous - - OldBuffer->LENGTH = oldlen = sizeof(void *) + 4; - } - - OldBuffer->LENGTH += len; - memcpy(&OldBuffer->L2DATA[oldlen - (sizeof(void *) + 4)], Buffer->L2DATA, len); - - ReleaseBuffer((UINT *)Buffer); - - Buffer = OldBuffer; - - Session->PARTCMDBUFFER = NULL; - } - - // Check that message has a CR, if not save buffer and exit - - len = Buffer->LENGTH - (sizeof(void *) + 4); - ptr1 = &Buffer->L2DATA[0]; - - // Check for sending YAPP to Node - - if (len == 2 && ptr1[0] == 5 && ptr1[1] == 1) - { - ptr1[0] = 0x15; // NAK - - ptr1[1] = sprintf(&ptr1[2], "Node doesn't support YAPP Transfers"); - - Buffer->LENGTH += ptr1[1]; - - C_Q_ADD(&Session->L4TX_Q, (UINT *)Buffer); - PostDataAvailable(Session); - return; - } - - - ptr2 = memchr(ptr1, ';', len); - - if (ptr2 == 0) - { - ptr2 = memchr(ptr1, 13, len); - - if (ptr2 == 0) - { - // No newline - - Session->PARTCMDBUFFER = Buffer; - return; - } - } - - ptr2++; - - rest = len - (int)(ptr2 - ptr1); - - if (rest) - { - // there are chars beyond the cr in the buffer - - // see if LF after CR - - if ((*ptr2) == 10) // LF - { - ptr2++; - rest--; - } - - if (rest) // May only have had LF - { - // Get a new buffer, and copy extra data to it. - - SaveBuffer = (struct DATAMESSAGE *)GetBuff(); - - if (SaveBuffer) //`Just ignore if no buffers - { - SaveBuffer->LENGTH = rest + MSGHDDRLEN + 1; - SaveBuffer->PID = 0xf0; - memcpy(&SaveBuffer->L2DATA[0], ptr2, rest); - Session->PARTCMDBUFFER = SaveBuffer; - } - } - } - - // GET PACLEN FOR THIS CONNECTION - - CMDPACLEN = Session->SESSPACLEN; - - if (CMDPACLEN == 0) - CMDPACLEN = PACLEN; // Use default if no Session PACLEN - - // If sesion is in UNPROTO Mode, send message as a UI message - - if (Session->UNPROTO) - { -// char LongMsg[512] = -// "VeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessage" -// "VeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessageVeryLongMessage"; - - DIGIMESSAGE Msg; - int Port = Session->UNPROTO; - int Len = Buffer->LENGTH - (MSGHDDRLEN -1); // Need PID - - // First check for UNPROTO exit - ctrl/z or /ex - - if (Buffer->L2DATA[0] == 26 || (Len == 6 && _memicmp(&Buffer->L2DATA[0], "/ex", 3) == 0)) // CTRL/Z or /ex - { - REPLYBUFFER = Buffer; - - Session->UNPROTO = 0; - memset(Session->UADDRESS, 0, 64); - - // SET UP HEADER - - Buffer->PID = 0xf0; - ptr1 = SetupNodeHeader(Buffer); - memcpy(ptr1, OKMSG, 3); - ptr1 += 3; - SendCommandReply(Session, Buffer, (int)(ptr1 - (char *)Buffer)); - - return; - } - - memset(&Msg, 0, sizeof(Msg)); - - Msg.PORT = Port; - Msg.CTL = 3; // UI - memcpy(Msg.DEST, Session->UADDRESS, 7); - Msg.DEST[6] |= 0x80; // set Command Bit - memcpy(Msg.ORIGIN, Session->L4USER, 7); - memcpy(Msg.DIGIS, &Session->UADDRESS[7], Session->UAddrLen - 7); - memcpy(&Msg.PID, &Buffer->PID, Len); - Send_AX_Datagram(&Msg, Len, Port); // Len is Payload - CTL, PID and Data - -// memcpy(&Msg.PID + 1, LongMsg, 260); -// Send_AX_Datagram(&Msg, 241, Port); // Len is Payload - CTL, PID and Data - - -// SendUIModeFrame(Session, (PMESSAGE)Buffer, Session->UNPROTO); - - ReleaseBuffer((UINT *)Buffer); // Not using buffer for reply - - // Assume we don't allow multiple lines in buffer with UI - - if (Session->PARTCMDBUFFER) - { - Buffer = Session->PARTCMDBUFFER; - ReleaseBuffer((UINT *)Buffer); // Not using buffer for reply - Session->PARTCMDBUFFER = NULL; - } - return; - } - - memset(COMMANDBUFFER, 32, 80); // Clear to spaces - - ptr1 = &Buffer->L2DATA[0]; - ptr2 = &COMMANDBUFFER[0]; - ptr3 = &OrigCmdBuffer[0]; - - memset(OrigCmdBuffer, 0, 80); - n = 80; - - while (n--) - { - c = *(ptr1++) & 0x7f; // Mask paritu - - if (c == 13 || c == ';') - break; // CR - - *(ptr3++) = c; // Original Case - - c = toupper(c); - *(ptr2++) = c; - } - - - // USE INPUT MESSAGE _BUFFER FOR REPLY - - REPLYBUFFER = Buffer; - - // SET UP HEADER - - Buffer->PID = 0xf0; - ptr1 = SetupNodeHeader(Buffer); - - ReplyPointer = ptr1; - - ALIASINVOKED = 0; // Clear "Invoked by APPL ALIAS flag" - - DoTheCommand(Session); // We also call DotheCommand when we need to reprocess - eg for alias handling -} - -VOID DoTheCommand(TRANSPORTENTRY * Session) -{ - struct DATAMESSAGE * Buffer = REPLYBUFFER; - char * ptr1, * ptr2; - int n; - - ptr1 = &COMMANDBUFFER[0]; // - - n = 10; - - while ((*ptr1 == ' ' || *ptr1 == 0) && n--) - ptr1++; // STRIP LEADING SPACES and nulls (from keepalive) - - if (n == -1) - { - // Null command - - ReleaseBuffer((UINT *)Buffer); - return; - } - - ptr2 = ptr1; // Save - - - CMD = &COMMANDS[0]; - n = 0; - - for (n = 0; n < NUMBEROFCOMMANDS; n++) - { - int CL = CMD->CMDLEN; - - ptr1 = ptr2; - - CMDPTR = CMD; - - if (n == APPL1) // First APPL command - { - APPLMASK = 1; // FOR APPLICATION ATTACH REQUESTS - ALIASPTR = &CMDALIAS[0][0]; - } - - // ptr1 is input command - - if (memcmp(CMD->String, ptr1, CL) == 0) - { - // Found match so far - check rest - - char * ptr2 = &CMD->String[CL]; - - ptr1 += CL; - - if (*(ptr1) != ' ') - { - while(*(ptr1) == *ptr2 && *(ptr1) != ' ') - { - ptr1++; - ptr2++; - } - } - - if (*(ptr1) == ' ') - { - Session->BADCOMMANDS = 0; // RESET ERROR COUNT - - // SEE IF SYSOP COMMAND, AND IF SO IF PASSWORD HAS BEEN ENTERED - - if (n < PASSCMD) - { - //NEEDS PASSWORD FOR SYSOP COMMANDS - - if (Session->PASSWORD != 0xFFFF) - { - ptr1 = ReplyPointer; - - memcpy(ptr1, PASSWORDMSG, LPASSMSG); - ptr1 += LPASSMSG; - - SendCommandReply(Session, Buffer, (int)(ptr1 - (char *)Buffer)); - return; - } - } -// VALNODESFLAG = 0; // NOT VALID NODES COMMAND - - ptr1++; // Skip space - - CMD->CMDPROC(Session, ReplyPointer, ptr1, CMD); - return; - } - } - - APPLMASK <<= 1; - ALIASPTR += ALIASLEN; - - CMD++; - - } - Session->BADCOMMANDS++; - - if (Session->BADCOMMANDS > 6) // TOO MANY ERRORS - { - ReleaseBuffer((UINT *)Buffer); - Session->STAYFLAG = 0; - CLOSECURRENTSESSION(Session); - return; - } - - ptr1 = ReplyPointer; - - memcpy(ptr1, CMDERRMSG, CMDERRLEN); - ptr1 += CMDERRLEN; - - SendCommandReply(Session, Buffer, (int)(ptr1 - (char *)Buffer)); -} - - -VOID StatsTimer() -{ - struct PORTCONTROL * PORT = PORTTABLE; - uint64_t sum, sum2; - - // Interval is 60 secs - - while(PORT) - { - int index = PORT->StatsPointer++; - - if (index == 1439) - PORT->StatsPointer = 0; // Cyclic through 24 hours (1440 Mins) - - if (PORT->TNC) - { - struct TNCINFO * TNC = PORT->TNC; - if (TNC->Hardware == H_ARDOP || TNC->Hardware == H_VARA) - { - sum = TNC->PTTActivemS / 600; // ms but want % - PORT->AVSENDING = (UCHAR)sum; - TNC->PTTActivemS = 0; - - sum2 = TNC->BusyActivemS / 600; // ms but want % - PORT->AVACTIVE = (UCHAR)(sum + sum2); - TNC->BusyActivemS = 0; - } - } - else - { - // if KISS port using QtSM Average is already updated - - struct KISSINFO * KISS = (struct KISSINFO *)PORT; - - if (PORT->PORTNUMBER == 17) - { - int x = 17; - } - - if (PORT->PORTTXROUTINE == KISSTX && (KISS->QtSMStats || KISS->FIRSTPORT->PORT.QtSMPort)) // KISS Port QtSM Stats - { - } - else - { - sum = PORT->SENDING / 11; - PORT->AVSENDING = (UCHAR)sum; - - sum = (PORT->SENDING + PORT->ACTIVE) /11; - PORT->AVACTIVE = (UCHAR)sum; - } - } - - if (PORT->TX == NULL && PORT->AVACTIVE) - { - PORT->TX = zalloc(1440); // Keep 1 day history - PORT->BUSY = zalloc(1440); - } - if (PORT->TX) - { - PORT->TX[index] = PORT->AVSENDING; - PORT->BUSY[index] = PORT->AVACTIVE; - } - - PORT->SENDING = 0; - PORT->ACTIVE = 0; - - PORT = PORT->PORTPOINTER; - } -} - - - -extern struct AXIPPORTINFO * Portlist[]; - -#define TCPConnected 4 - - -VOID AXRESOLVER(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // DISPLAY AXIP Resolver info - - int Port = 0, index =0; - char * ptr, *Context; - struct PORTCONTROL * PORT = NULL; - struct AXIPPORTINFO * AXPORT; - char Normcall[11]; - char Flags[10]; - struct arp_table_entry * arp; - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - Port = atoi(ptr); - - if (Port) - PORT = GetPortTableEntryFromPortNum(Port); - - if (PORT == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - AXPORT = Portlist[Port]; - - if (AXPORT == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not an AXIP port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "AXIP Resolver info for Port %d\r", Port); - - while (index < AXPORT->arp_table_len) - { - arp = &AXPORT->arp_table[index]; - - if (arp->ResolveFlag && arp->error != 0) - { - // resolver error - Display Error Code - sprintf(AXPORT->hostaddr, "Error %d", arp->error); - } - else - { - if (arp->IPv6) - Format_Addr((unsigned char *)&arp->destaddr6.sin6_addr, AXPORT->hostaddr, TRUE); - else - Format_Addr((unsigned char *)&arp->destaddr.sin_addr, AXPORT->hostaddr, FALSE); - } - - ConvFromAX25(arp->callsign, Normcall); - - Flags[0] = 0; - - if (arp->BCFlag) - strcat(Flags, "B "); - - if (arp->TCPState == TCPConnected) - strcat(Flags, "C "); - - if (arp->AutoAdded) - strcat(Flags, "A"); - - if (arp->port == arp->SourcePort) - Bufferptr = Cmdprintf(Session, Bufferptr,"%.10s = %.64s %d = %-.42s %s\r", - Normcall, - arp->hostname, - arp->port, - AXPORT->hostaddr, - Flags); - - else - Bufferptr = Cmdprintf(Session, Bufferptr,"%.10s = %.64s %d<%d = %-.42s %s\r", - Normcall, - arp->hostname, - arp->port, - arp->SourcePort, - AXPORT->hostaddr, - Flags); - - index++; - } - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID AXMHEARD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - // DISPLAY AXIP Mheard info - - int Port = 0, index = 0; - char * ptr, *Context; - struct PORTCONTROL * PORT = NULL; - struct AXIPPORTINFO * AXPORT; - int n = MHENTRIES; - char Normcall[11]; - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - Port = atoi(ptr); - - if (Port) - PORT = GetPortTableEntryFromPortNum(Port); - - if (PORT == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - AXPORT = Portlist[Port]; - - if (AXPORT == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not an AXIP port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "AXIP Mheard for Port %d\r", Port); - - while (index < MaxMHEntries) - { - if (AXPORT->MHTable[index].proto != 0) - { - char Addr[80]; - - Format_Addr((unsigned char *)&AXPORT->MHTable[index].ipaddr6, Addr, AXPORT->MHTable[index].IPv6); - - Normcall[ConvFromAX25(AXPORT->MHTable[index].callsign, Normcall)] = 0; - - Bufferptr = Cmdprintf(Session, Bufferptr, "%-10s%-15s %c %-6d %-25s%c\r", Normcall, - Addr, - AXPORT->MHTable[index].proto, - AXPORT->MHTable[index].port, - asctime(gmtime( &AXPORT->MHTable[index].LastHeard )), - (AXPORT->MHTable[index].Keepalive == 0) ? ' ' : 'K'); - - Bufferptr[-3] = ' '; // Clear CR returned by asctime - } - - index++; - } - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -#pragma pack() - -extern char WL2KCall[10]; -extern char WL2KLoc[7]; - -BOOL GetWL2KSYSOPInfo(char * Call, char * _REPLYBUFFER); -BOOL UpdateWL2KSYSOPInfo(char * Call, char * SQL); - -VOID WL2KSYSOP(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - char _REPLYBUFFER[1000] = ""; - - char LastUpdated[100]; - char Name[100] = ""; - char Addr1[100] = ""; - char Addr2[100] = ""; - char City[100] = ""; - char State[100] = ""; - char Country[100] = ""; - char PostCode[100] = ""; - char Email[100] = ""; - char Website[100] = ""; - char Phone[100] = ""; - char Data[100] = ""; - char LOC[100] = ""; - BOOL Exists = TRUE; - time_t LastUpdateSecs = 0; - char * ptr1, * ptr2; - - SOCKET sock; - - int Len; - char Message[2048]; - - if (WL2KCall[0] < 33) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Winlink reporting is not configured\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - - if (GetWL2KSYSOPInfo(WL2KCall, _REPLYBUFFER) == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Failed to connect to WL2K Database\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (strstr(_REPLYBUFFER, "\"ErrorMessage\":")) - Exists = FALSE; - - GetJSONValue(_REPLYBUFFER, "\"SysopName\":", Name); - GetJSONValue(_REPLYBUFFER, "\"StreetAddress1\":", Addr1); - GetJSONValue(_REPLYBUFFER, "\"StreetAddress2\":", Addr2); - GetJSONValue(_REPLYBUFFER, "\"City\":", City); - GetJSONValue(_REPLYBUFFER, "\"State\":", State); - GetJSONValue(_REPLYBUFFER, "\"Country\":", Country); - GetJSONValue(_REPLYBUFFER, "\"PostalCode\":", PostCode); - GetJSONValue(_REPLYBUFFER, "\"Email\":", Email); - GetJSONValue(_REPLYBUFFER, "\"Website\":", Website); - GetJSONValue(_REPLYBUFFER, "\"Phones\":", Phone); - GetJSONValue(_REPLYBUFFER, "\"Comments\":", Data); - GetJSONValue(_REPLYBUFFER, "\"GridSquare\":", LOC); - GetJSONValue(_REPLYBUFFER, "\"Timestamp\":", LastUpdated); - - ptr1 = strchr(LastUpdated, '('); - - if (ptr1) - { - ptr2 = strchr(++ptr1, ')'); - - if (ptr2) - { - *(ptr2 - 3) = 0; // remove millisecs - LastUpdateSecs = atoi(ptr1); - - FormatTime3(LastUpdated, LastUpdateSecs); - } - } - - if (_memicmp(CmdTail, "SET ", 4) == 0) - { - if (Exists) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Record already exists in WL2K Database\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // Set New Values. Any other params are values to set, separated by | - -// ptr1 = strtok_s(&CmdTail[4], ",", &Context); - -// if (ptr1 == NULL) -// goto DoReplace; - -// strcpy(Name, ptr1); - -//DoReplace: - - Len = sprintf(Message, - "\"Callsign\":\"%s\"," - "\"GridSquare\":\"%s\"," - "\"SysopName\":\"%s\"," - "\"StreetAddress1\":\"%s\"," - "\"StreetAddress2\":\"%s\"," - "\"City\":\"%s\"," - "\"State\":\"%s\"," - "\"Country\":\"%s\"," - "\"PostalCode\":\"%s\"," - "\"Email\":\"%s\"," - "\"Phones\":\"%s\"," - "\"Website\":\"%s\"," - "\"Comments\":\"%s\",", - - WL2KCall, WL2KLoc, Name, Addr1, Addr2, City, State, Country, PostCode, Email, Phone, Website, Data); - - Debugprintf("Sending %s", Message); - - sock = OpenWL2KHTTPSock(); - - if (sock) - SendHTTPRequest(sock, "api.winlink.org", 80, - "/sysop/add", Message, Len, NULL); - - closesocket(sock); - - Bufferptr = Cmdprintf(Session, Bufferptr, "Database Updated\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (Exists) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "\rWL2K SYSOP Info for %s\r", WL2KCall); - Bufferptr = Cmdprintf(Session, Bufferptr, "Grid Square: %s\r", LOC); - Bufferptr = Cmdprintf(Session, Bufferptr, "Name: %s\r", Name); - Bufferptr = Cmdprintf(Session, Bufferptr, "Addr Line 1: %s\r", Addr1); - Bufferptr = Cmdprintf(Session, Bufferptr, "Addr Line 2: %s\r", Addr2); - Bufferptr = Cmdprintf(Session, Bufferptr, "City: %s\r", City); - Bufferptr = Cmdprintf(Session, Bufferptr, "State: %s\r", State); - Bufferptr = Cmdprintf(Session, Bufferptr, "Country: %s\r", Country); - Bufferptr = Cmdprintf(Session, Bufferptr, "PostCode: %s\r", PostCode); - Bufferptr = Cmdprintf(Session, Bufferptr, "Email Address: %s\r", Email); - Bufferptr = Cmdprintf(Session, Bufferptr, "Website: %s\r", Website); - Bufferptr = Cmdprintf(Session, Bufferptr, "Phone: %s\r", Phone); - Bufferptr = Cmdprintf(Session, Bufferptr, "Additional Data: %s\r", Data); - Bufferptr = Cmdprintf(Session, Bufferptr, "Last Updated: %s\r", LastUpdated); - } - else - Bufferptr = Cmdprintf(Session, Bufferptr, "No SYSOP record for %s\r", WL2KCall); - - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - -VOID CloseKISSPort(struct PORTCONTROL * PortVector); - -VOID STOPCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - char _REPLYBUFFER[1000] = ""; - char * ptr, * Context; - - int portno; - - struct TNCINFO * TNC; - struct TCPINFO * TCP; - struct PORTCONTROL * PORT = PORTTABLE; - int n = NUMBEROFPORTS; - - // Get port number - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - { - portno = atoi (ptr); - - if (portno) - { - while (n--) - { - if (PORT->PORTNUMBER == portno) - { - TNC = TNCInfo[portno]; - - if (!TNC || !TNC->TCPInfo) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not a Telnet Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - TCP = TNC->TCPInfo; - - TCP->CMS = 0; - TCP->CMSOK = FALSE; -#ifndef LINBPQ - CheckMenuItem(TCP->hActionMenu, 3, MF_BYPOSITION | TCP->CMS<<3); - SetWindowText(TCP->hCMSWnd, "CMS Off"); -#endif - Bufferptr = Cmdprintf(Session, Bufferptr, "CMS Server Disabled\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - PORT = PORT->PORTPOINTER; - } - } - } - - // Bad port - - strcpy(Bufferptr, BADPORT); - Bufferptr += (int)strlen(BADPORT); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - - -VOID STARTCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - char _REPLYBUFFER[1000] = ""; - char * ptr, * Context; - - int portno; - - struct TNCINFO * TNC; - struct TCPINFO * TCP; - struct PORTCONTROL * PORT = PORTTABLE; - int n = NUMBEROFPORTS; - - // Get port number - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - { - portno = atoi (ptr); - - if (portno) - { - while (n--) - { - if (PORT->PORTNUMBER == portno) - { - TNC = TNCInfo[portno]; - - if (!TNC || !TNC->TCPInfo) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not a Telnet Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - TCP = TNC->TCPInfo; - TCP->CMS = 1; -#ifndef LINBPQ - CheckMenuItem(TCP->hActionMenu, 3, MF_BYPOSITION | TCP->CMS<<3); -#endif - CheckCMS(TNC); - - Bufferptr = Cmdprintf(Session, Bufferptr, "CMS Server Enabled\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - PORT = PORT->PORTPOINTER; - } - } - } - - // Bad port - - strcpy(Bufferptr, BADPORT); - Bufferptr += (int)strlen(BADPORT); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - - -VOID STOPPORT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - char _REPLYBUFFER[1000] = ""; - char * ptr, * Context; - - int portno; - struct PORTCONTROL * PORT = PORTTABLE; - int n = NUMBEROFPORTS; - - // Get port number - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - { - portno = atoi (ptr); - - if (portno) - { - while (n--) - { - if (PORT->PORTNUMBER == portno) - { - struct KISSINFO * KISS; - - if (PORT->PORTSTOPCODE) - { - // Port has Close Routine - - PORT->PortStopped = TRUE; - - if (PORT->PORTSTOPCODE(PORT)) - Bufferptr = Cmdprintf(Session, Bufferptr, "Port Closed\r"); - else - Bufferptr = Cmdprintf(Session, Bufferptr, "Port Close Failed\r"); - - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - if (PORT->PORTTYPE != 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not a KISS Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (PORT->PORTIPADDR.s_addr || PORT->KISSSLAVE) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not a serial port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - KISS = (struct KISSINFO *) PORT; - - if (KISS->FIRSTPORT != KISS) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not first port of a Multidrop Set\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - CloseKISSPort(PORT); - PORT->PortStopped = TRUE; - Bufferptr = Cmdprintf(Session, Bufferptr, "Port Closed\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - - return; - } - PORT = PORT->PORTPOINTER; - } - } - } - - // Bad port - - strcpy(Bufferptr, BADPORT); - Bufferptr += (int)strlen(BADPORT); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - - -VOID STARTPORT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - char _REPLYBUFFER[1000] = ""; - char * ptr, * Context; - - int portno; - struct PORTCONTROL * PORT = PORTTABLE; - int n = NUMBEROFPORTS; - - // Get port number - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - { - portno = atoi (ptr); - - if (portno) - { - while (n--) - { - if (PORT->PORTNUMBER == portno) - { - struct KISSINFO * KISS; - - if (PORT->PORTSTARTCODE) - { - // Port has Open Routine - - PORT->PortStopped = FALSE; - - if (PORT->PORTSTARTCODE(PORT)) - Bufferptr = Cmdprintf(Session, Bufferptr, "Port Opened\r"); - else - Bufferptr = Cmdprintf(Session, Bufferptr, "Port Open Failed\r"); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - - if (PORT->PORTTYPE != 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not a KISS Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (PORT->PORTIPADDR.s_addr || PORT->KISSSLAVE) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not a serial port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - KISS = (struct KISSINFO *) PORT; - - if (KISS->FIRSTPORT != KISS) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not first port of a Multidrop Set\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (OpenConnection(PORT)) - Bufferptr = Cmdprintf(Session, Bufferptr, "Port Opened\r"); - else - Bufferptr = Cmdprintf(Session, Bufferptr, "Port Open Failed\r"); - - PORT->PortStopped = FALSE; - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - PORT = PORT->PORTPOINTER; - } - } - } - - // Bad port - - strcpy(Bufferptr, BADPORT); - Bufferptr += (int)strlen(BADPORT); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - - - -int ASYSEND(struct PORTCONTROL * PortVector, char * buffer, int count); -int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len); - -VOID KISSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - char _REPLYBUFFER[1000] = ""; - char * ptr, * Context; - - int portno = 0; - struct PORTCONTROL * PORT = PORTTABLE; - int n = NUMBEROFPORTS; - UCHAR KissString[128]; - UCHAR ENCBUFF[256]; - int KissLen = 0; - unsigned char * Kissptr = KissString; - - // Send KISS Command to TNC - - // Get port number - - ptr = strtok_s(CmdTail, " ", &Context); - - if (ptr) - { - portno = atoi (ptr); - ptr = strtok_s(NULL, " ", &Context); - - while (ptr && ptr[0] && KissLen < 120) - { - *(Kissptr++) = atoi (ptr); - KissLen++; - ptr = strtok_s(NULL, " ", &Context); - - } - } - - if (portno == 0 || KissLen == 0) - { - strcpy(Bufferptr, BADMSG); - Bufferptr += (int)strlen(BADMSG); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - while (n--) - { - if (PORT->PORTNUMBER == portno) - { - struct KISSINFO * KISS; - - if (PORT->PORTTYPE != 0 && PORT->PORTTYPE != 22) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not a KISS Port\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - KISS = (struct KISSINFO *) PORT; - - if (KISS->FIRSTPORT != KISS) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Not first port of a Multidrop Set\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - // Send Command - - KissLen = KissEncode(KissString, ENCBUFF, KissLen); - - PORT = (struct PORTCONTROL *)KISS->FIRSTPORT; // ALL FRAMES GO ON SAME Q - - PORT->Session = Session; - PORT->LastKISSCmdTime = time(NULL); - - ASYSEND(PORT, ENCBUFF, KissLen); - - Bufferptr = Cmdprintf(Session, Bufferptr, "Command Sent\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - PORT = PORT->PORTPOINTER; - } - - - // Bad port - - strcpy(Bufferptr, BADPORT); - Bufferptr += (int)strlen(BADPORT); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - - -VOID FINDBUFFS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - FindLostBuffers(); - -#ifdef WIN32 - Bufferptr = Cmdprintf(Session, Bufferptr, "Lost buffer info dumped to Debugview\r"); -#else - Bufferptr = Cmdprintf(Session, Bufferptr, "Lost buffer info dumped to syslog\r"); -#endif - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -VOID FLMSG(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * UserCMD) -{ - // Telnet Connection from FLMSG - CLOSECURRENTSESSION(Session); // Kills any crosslink, plus local link - ReleaseBuffer((UINT *)REPLYBUFFER); -} - -BOOL CheckExcludeList(UCHAR * Call) -{ - UCHAR * ptr1 = ExcludeList; - - while (*ptr1) - { - if (memcmp(Call, ptr1, 6) == 0) - return FALSE; - - ptr1 += 7; - } - - return TRUE; -} - - -void ListExcludedCalls(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - - UCHAR * ptr = ExcludeList; - char Normcall[10] = ""; - UCHAR AXCall[8] = ""; - - if (*CmdTail == ' ') - goto DISPLIST; - - if (*CmdTail == 'Z') - { - // CLEAR LIST - - memset(ExcludeList, 0, 70); - goto DISPLIST; - } - - ConvToAX25(CmdTail, AXCall); - - if (strlen(ExcludeList) < 70) - strcat(ExcludeList, AXCall); - -DISPLIST: - - while (*ptr) - { - Normcall[ConvFromAX25(ptr, Normcall)] = 0; - Bufferptr = Cmdprintf(Session, Bufferptr, "%s ", Normcall); - ptr += 7; - } - - *(Bufferptr++) = '\r'; - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -BOOL isSYSOP(TRANSPORTENTRY * Session, char * Bufferptr) -{ - if (Session->PASSWORD != 0xFFFF) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "%s", PASSWORDMSG); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - - return FALSE; - } - - return TRUE; -} - -VOID HELPCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - int FileSize; - char MsgFile[MAX_PATH]; - FILE * hFile; - char * MsgBytes; - struct stat STAT; - char * ptr1, * ptr, * ptr2; - - sprintf_s(MsgFile, sizeof(MsgFile), "%s/%s", BPQDirectory, "NodeHelp.txt"); - - if (stat(MsgFile, &STAT) == -1) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Help file not found\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - FileSize = STAT.st_size; - - hFile = fopen(MsgFile, "rb"); - - if (hFile == NULL) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Help file not found\r"); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - MsgBytes = malloc(FileSize+1); - - fread(MsgBytes, 1, FileSize, hFile); - - fclose(hFile); - - MsgBytes[FileSize] = 0; - - ptr1 = MsgBytes; - - // Replace LF or CRLF with CR - - // First remove cr from crlf - - while(ptr2 = strstr(ptr1, "\r\n")) - { - memmove(ptr2, ptr2 + 1, strlen(ptr2)); - } - - // Now replace lf with cr - - ptr1 = MsgBytes; - - while (*ptr1) - { - if (*ptr1 == '\n') - *(ptr1) = '\r'; - - ptr1++; - } - - ptr = ptr1 = MsgBytes; - - Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); - - // Read and send a line at a time, converting any line endings into CR - - while (*ptr1) - { - if (*ptr1 == '\r') - { - *(ptr1++) = 0; - - Bufferptr = Cmdprintf(Session, Bufferptr, "%s\r", ptr); - - ptr = ptr1; - } - else - ptr1++; - } - - free(MsgBytes); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); -} - -int UZ7HOSetFreq(int port, struct TNCINFO * TNC, struct AGWINFO * AGW, PDATAMESSAGE buff, PMSGWITHLEN buffptr); -int UZ7HOSetModem(int port, struct TNCINFO * TNC, struct AGWINFO * AGW, PDATAMESSAGE buff, PMSGWITHLEN buffptr); -int UZ7HOSetFlags(int port, struct TNCINFO * TNC, struct AGWINFO * AGW, PDATAMESSAGE buff, PMSGWITHLEN buffptr); - - -VOID UZ7HOCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - char * Cmd; - int port; - struct TNCINFO * TNC; - struct AGWINFO * AGW = 0; - PDATAMESSAGE buff; - PMSGWITHLEN buffptr; - - CmdTail = CmdTail + (OrigCmdBuffer - COMMANDBUFFER); // Replace with original case version - - Cmd = strlop(CmdTail, ' '); - port = atoi(CmdTail); - - // remove trailing spaces - - while(strlen(Cmd) && Cmd[strlen(Cmd) - 1] == ' ') - Cmd[strlen(Cmd) - 1] = 0; - - TNC = TNCInfo[port]; - - if (TNC) - AGW = TNC->AGWInfo; - - if (TNC == 0 || AGW == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Error - %d is not UZ7HO port\r", port); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - if (_memicmp(Cmd, "FREQ", 4) == 0 || _memicmp(Cmd, "MODEM", 5) == 0 || _memicmp(Cmd, "FLAGS", 5) == 0) - { - // Pass to procesing code in UZ7HO driver. This expects command in a PDATAMESSAGE amd places response in a PMSGWITHLEN buffer - - buff = (PDATAMESSAGE)GetBuff(); - buffptr = (PMSGWITHLEN)GetBuff(); - - if (buffptr == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "UZ7HO Command Failed - no buffers\r"); - if (buff) - ReleaseBuffer(buff); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - - - buff->LENGTH = sprintf(buff->L2DATA, "%s\r", Cmd) + MSGHDDRLEN + 1; - - if (_memicmp(Cmd, "FREQ", 4) == 0) - UZ7HOSetFreq(port, TNC, AGW, buff, buffptr); - else if (_memicmp(Cmd, "FLAGS", 5) == 0) - UZ7HOSetFlags(port, TNC, AGW, buff, buffptr); - else - UZ7HOSetModem(port, TNC, AGW, buff, buffptr); - - - Bufferptr = Cmdprintf(Session, Bufferptr, buffptr->Data); - - ReleaseBuffer(buff); - ReleaseBuffer(buffptr); - } - else - Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid UZ7HO Command (not Freq Modem or FLAGS)\r"); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - -VOID QTSMCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD) -{ - int port; - struct PORTCONTROL * PORT; - struct KISSINFO * KISS; - - CmdTail = CmdTail + (OrigCmdBuffer - COMMANDBUFFER); // Replace with original case version - - port = atoi(CmdTail); - - PORT = GetPortTableEntryFromPortNum(port); - - if (PORT == NULL || PORT->PORTTXROUTINE != KISSTX) // Must be a kiss like port - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port %d is not a KISS port\r", port); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - KISS = (struct KISSINFO *)PORT; - - if (KISS->QtSMModem == 0) - { - Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port %d has no QtSM information\r", port); - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; - } - - Bufferptr = Cmdprintf(Session, Bufferptr, "Modem %s Centre frequency %d\r", - (KISS->QtSMModem) ? KISS->QtSMModem : "Not Available", KISS->QtSMFreq); - - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); - return; -} - - - - - - - - - - - - - diff --git a/MailDataDefs.c b/MailDataDefs.c index 4c177d9..883963a 100644 --- a/MailDataDefs.c +++ b/MailDataDefs.c @@ -43,6 +43,7 @@ struct SEM AllocSemaphore = {0, 0}; struct SEM ConSemaphore = {0, 0}; struct SEM Semaphore = {0, 0}; struct SEM OutputSEM = {0, 0}; +struct SEM ConfigSEM = {0, 0}; struct UserInfo ** UserRecPtr=NULL; int NumberofUsers=0; diff --git a/Versions.h b/Versions.h index 5f51e71..efe04b6 100644 --- a/Versions.h +++ b/Versions.h @@ -10,8 +10,8 @@ #endif -#define KVers 6,0,24,48 -#define KVerstring "6.0.24.48\0" +#define KVers 6,0,24,49 +#define KVerstring "6.0.24.49\0" #ifdef CKernel