master 25.30
g8bpq 3 weeks ago
parent 225fbb1789
commit d84bcdac5c

@ -1393,7 +1393,13 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr)
if (sockptr->AGWRXHeader.DataKind == 'V') // Unproto with VIA string
{
Digis = sockptr->MsgData[0]; // Number of digis
if (Digis > 7)
{
AGWDataSocket_Disconnect(sockptr);
return 0;
}
for (j = 1; j<= Digis; j++)
{
ConvToAX25(&sockptr->MsgData[(j - 1) * 10 + 1],&TXMessage[7+(j*7)]); // No "last" bit

@ -439,9 +439,6 @@ void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method,
if (URL[0] == 0 || Method == NULL)
return;
if (strstr(input, "Host: 127.0.0.1"))
LOCAL = TRUE;
if (Session->TNC == (void *)1) // Re-using an address as a flag
LOCAL = TRUE;
@ -2032,6 +2029,15 @@ VOID SaveFwdDetails(struct HTTPConnectionInfo * Session, char * MsgPtr, char * R
ptr1 = GetNextParam(&ptr2); // Connect Timeout
FWDInfo->ConTimeout = atoi(ptr1);
// Don't allow blocked uncompressed
if (FWDInfo->AllowBlocked)
FWDInfo->AllowCompressed = 1;
if (FWDInfo->AllowCompressed)
FWDInfo->AllowBlocked = 1;
SaveConfig(ConfigName);
GetConfig(ConfigName);

@ -7368,6 +7368,14 @@ VOID SetupForwardingStruct(struct UserInfo * user)
ForwardingInfo->AllowB2 = GetIntValue(group, "UseB2Protocol");
ForwardingInfo->SendCTRLZ = GetIntValue(group, "SendCTRLZ");
// Don't allow blocked uncompressed
if (ForwardingInfo->AllowBlocked)
ForwardingInfo->AllowCompressed = 1;
if (ForwardingInfo->AllowCompressed)
ForwardingInfo->AllowBlocked = 1;
if (ForwardingInfo->AllowB1 || ForwardingInfo->AllowB2)
ForwardingInfo->AllowCompressed = TRUE;
@ -9346,14 +9354,18 @@ VOID Parse_SID(CIRCUIT * conn, char * SID, int len)
}
}
// Only allow blocked non-binary to other BPQ Nodes
// No longer Only blocked non-binary to other BPQ Nodes
if ((conn->BBSFlags & FBBForwarding) && ((conn->BBSFlags & FBBCompressed) == 0) && (conn->BPQBBS == 0))
{
// Switch back to MBL
// Disconnect user
Logprintf(LOG_BBS, conn, '?', "Uncompressed Blocked Forwarding is no longer supported - reconfgure BBS for MBL forwarding");
conn->BBSFlags &= ~RunningConnectScript; // so it doesn't get reentered
Disconnect(conn->BPQStream);
return ;
conn->BBSFlags |= MBLFORWARDING;
conn->BBSFlags &= ~FBBForwarding; // Turn off FBB Blocked
}
return;
@ -12048,6 +12060,7 @@ void run_pg(CIRCUIT * conn, struct UserInfo * user)
FILE *iop;
int argc, pdes[2];
pid_t pid;
int i;
pgret = 9999;
@ -12057,6 +12070,20 @@ void run_pg(CIRCUIT * conn, struct UserInfo * user)
conn->InputBuffer[conn->InputLen] = 0;
strlop(conn->InputBuffer, 13);
// validate command is alphanumberic
for (i = 0; i < conn->InputLen; i++)
{
if (isalnum(conn->InputBuffer[i]) == 0 && conn->InputBuffer[i] != ' ')
{
BBSputs(conn, "PG commnand string invalid\r");
conn->InputMode=0;
SendPrompt(conn, user);
return;
}
}
conn->InputLen = 0;
if (!user->Temp->RUNPGPARAMS)
@ -12088,7 +12115,7 @@ void run_pg(CIRCUIT * conn, struct UserInfo * user)
char pg_dir[MAX_PATH];
char log_file[50] = "pg.log";
char call[10];
char data[80];
char data[256];
char line[80];
size_t bufsize = 80;
@ -12307,6 +12334,7 @@ void run_pg( CIRCUIT * conn, struct UserInfo * user )
CHAR chBuf[BUFSIZE];
int index = 0;
int ret = 0;
int i;
// if first entry allocate RUNPGPARAMS
if (!user->Temp->RUNPGPARAMS)
@ -12322,6 +12350,20 @@ void run_pg( CIRCUIT * conn, struct UserInfo * user )
conn->InputBuffer[conn->InputLen] = 0;
strlop(conn->InputBuffer, 13);
// validate command is alphanumberic
for (i = 0; i < strlen(conn->InputBuffer); i++)
{
if (isalnum(conn->InputBuffer[i]) == 0 && conn->InputBuffer[i] != ' ')
{
BBSputs(conn, "PG commnand string invalid\r");
conn->InputMode=0;
SendPrompt(conn, user);
return;
}
}
conn->InputLen = 0;
// Build command line. Parmas are:

@ -400,6 +400,9 @@ VOID ProcessINP3RIF(struct ROUTE * Route, UCHAR * ptr1, int msglen, int Port)
UINT Stamp, HH, MM;
char Normcall[10];
if (Route == 0 || Route->NEIGHBOUR_LINK == 0 || Route->NEIGHBOUR_LINK->LINKCALL == 0)
return;
Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0;
if (DEBUGINP3) Debugprintf("Processing RIF from %s INP3Node %d Route SRTT %d", Normcall, Route->INP3Node, Route->SRTT);
@ -1711,7 +1714,7 @@ VOID SendNewInfo()
if (Dest->INP3FLAGS & NewNode)
{
char call[10];
ConvFromAX25(Dest->DEST_CALL, call);
call[ConvFromAX25(Dest->DEST_CALL, call)] = 0;
if (DEBUGINP3) Debugprintf("INP3 Sending New Node %s", call);
Dest->INP3FLAGS &= ~NewNode;

Binary file not shown.

@ -1160,6 +1160,10 @@
// 6.0.26.x
// Fix forwarding to/from AEA TNC mailbox (22)
// Fix possible crash in SendBBSDataToPktMap
// Remove Uncompressed Blocked forwarding (27)
// Fix mail api returning garbage when deflate isn't requested (27)
#include "bpqmail.h"
#include "winstdint.h"

File diff suppressed because it is too large Load Diff

@ -1917,6 +1917,15 @@ VOID SaveFWDConfig(HWND hDlg)
ForwardingInfo->MaxFBBBlockSize = GetDlgItemInt(hDlg, IDC_MAXBLOCK, &OK, FALSE);
ForwardingInfo->ConTimeout = GetDlgItemInt(hDlg, IDC_CONTIMEOUT,&OK , FALSE);
// Don't allow blocked uncompressed
if (ForwardingInfo->AllowBlocked)
ForwardingInfo->AllowCompressed = 1;
if (ForwardingInfo->AllowCompressed)
ForwardingInfo->AllowBlocked = 1;
GetDlgItemText(hDlg, IDC_BBSHA, BBSHA, 50);
if (ForwardingInfo->BBSHA)
free(ForwardingInfo->BBSHA);

@ -1314,7 +1314,11 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Fix handling of disconnects when using RHP (17)
// Fix propagating unreachable in INP3 (18)
// Add STOPROUTE and STARTROUTE commands (21)
// Fix resolver loop if no Internet (24)
// Support SSID -L for Winlink local messages (25)
// Fix crash when APRS pages requested when APRS isn't configured (26)
// Add setting modem params to QTSM command (28)
// Security fixes (28)
#define CKernel

308
Cmd.c

@ -161,6 +161,9 @@ extern int RigReconfigFlag;
extern int DEBUGINP3;
extern int PREFERINP3ROUTES;
extern char FX25Modes[8][8];
extern char IL2PModes[8][10];
struct CMDX COMMANDS[];
@ -168,6 +171,7 @@ int CMDXLEN = sizeof (struct CMDX);
VOID SENDNODESMSG(int Portnum);
VOID KISSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);
VOID LORACMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);
VOID STOPCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);
VOID STARTCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);
VOID STOPPORT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);
@ -2581,7 +2585,6 @@ VOID CMDC00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct C
int haveService = 0;
int i = 0;
#ifdef EXCLUDEBITS
if (CheckExcludeList(Session->L4USER) == FALSE)
@ -4700,6 +4703,7 @@ struct CMDX COMMANDS[] =
"FINDBUFFS ",4,FINDBUFFS,0,
"KISS ",4,KISSCMD,0,
"LORA ",4,LORACMD,0,
"GETPORTCTEXT",9,GetPortCTEXT, 0,
@ -6186,14 +6190,17 @@ VOID KISSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
KISS = (struct KISSINFO *) PORT;
// Send Command
// Set Channel bits
KissLen = KissEncode(KissString, ENCBUFF, KissLen);
KissString[0] |= KISS->OURCTRL;
// Send Command
PORT->Session = Session;
PORT->LastKISSCmdTime = time(NULL);
PORT = (struct PORTCONTROL *)KISS->FIRSTPORT; // ALL FRAMES GO ON SAME Q
KissLen = KissEncode(KissString, ENCBUFF, KissLen);
ASYSEND(PORT, ENCBUFF, KissLen);
Bufferptr = Cmdprintf(Session, Bufferptr, "Command Sent\r");
@ -6212,6 +6219,79 @@ VOID KISSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
return;
}
VOID LORACMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct 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;
int Param[4];
int i = 0;
// Send CONFIG Command to LORA 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)
{
Param[i++] = atoi(ptr);
ptr = strtok_s(NULL, " ", &Context);
}
}
if (portno == 0 || i != 4)
{
char ErrMsg[] = "Invalid params - format is LORA port freq bandwidth spreading factor coding rate";
strcpy(Bufferptr, ErrMsg);
Bufferptr += (int)strlen(ErrMsg);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
while (n--)
{
if (PORT->PORTNUMBER == portno)
{
KissLen = sprintf(KissString, "%cLORA=%d, %d, %d, %d", 6, Param[0], Param[1], Param[2], Param[3]);
KissLen = KissEncode(KissString, ENCBUFF, KissLen);
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, struct CMDX * CMD)
{
@ -6400,6 +6480,13 @@ VOID UZ7HOCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
Cmd = strlop(CmdTail, ' ');
port = atoi(CmdTail);
if (Cmd == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Missing params - usage is UZ7HO port Command\r", port);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
// remove trailing spaces
while(strlen(Cmd) && Cmd[strlen(Cmd) - 1] == ' ')
@ -6457,15 +6544,45 @@ VOID UZ7HOCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
return;
}
#define QTSMKISSCMD 7
#define MODEMREPORT 1 // QTSM Modem Info subcommand
#define SETMODEMPARAMS 2 // QtSM Moden change settings
VOID QTSMCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{
int port;
struct PORTCONTROL * PORT;
struct KISSINFO * KISS;
NPASYINFO Port;
char * ptr, * context;
UCHAR KissString[128] = "";
UCHAR ENCBUFF[256];
int KissLen = 0;
unsigned char * Data = KissString;
int fx25_mode = 0;
int il2p_mode = 0;
int il2p_crc = 0;
int i;
CmdTail = CmdTail + (OrigCmdBuffer - COMMANDBUFFER); // Replace with original case version
port = atoi(CmdTail);
ptr = strtok_s(CmdTail, " ,\r", &context);
if (_stricmp(ptr, "HELP") == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "QTSM portno displays QTSM configuration info (if avaliable)\r", ptr);
Bufferptr = Cmdprintf(Session, Bufferptr, "Modem, Centre Freq, fx25 flags and il2p flags can be changed if you have sysop access. All prameters are optional.\r", ptr);
Bufferptr = Cmdprintf(Session, Bufferptr, "The Modem name (if used) must come first. Others can be entered in any order. Values should be comma separated.\r", ptr);
Bufferptr = Cmdprintf(Session, Bufferptr, "For example QTSM 1 AFSK AX.25 1200bd, 1700, fx25 none, il2p only\r", ptr);
Bufferptr = Cmdprintf(Session, Bufferptr, " QTSM 1 il2p rx+tx\r", ptr);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
port = atoi(ptr);
PORT = GetPortTableEntryFromPortNum(port);
@ -6475,23 +6592,194 @@ VOID QTSMCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
KISS = (struct KISSINFO *)PORT;
if (KISS->QtSMModem == 0)
Port = KISSInfo[PORT->PORTNUMBER];
if (Port)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port %d has no QtSM information\r", port);
// Check if connected
if (PORT->KISSTCP)
{
if (Port->Connected == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - QTSM not connected\r", port);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
}
}
if (context == 0 || context[0] == 0)
{
// Display
if (PORT->QtSMFreq)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Modem %s Centre frequency %d fx25 %s il2p %s %s\r",
(PORT->QtSMModem[0]) ? PORT->QtSMModem : "Not Available", PORT->QtSMFreq,
FX25Modes[PORT->fx25Flags], IL2PModes[PORT->il2pFlags], PORT->il2pcrc?"CRC":"");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
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;
}
Bufferptr = Cmdprintf(Session, Bufferptr, "Modem %s Centre frequency %d\r",
(KISS->QtSMModem) ? KISS->QtSMModem : "Not Available", KISS->QtSMFreq);
// Set params. Layout is
/*
0 QTSMKISSCMD
1 SETMODEMPARAMS
2 Freq
4 Modem
24 Reserved
29 set flags indicator (2)
30 fx25
31 il2p
32 crc
*/
if (Session->PASSWORD != 0xFFFF)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Update requires SYSOP status - enter password\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
if (_memicmp(context, "fx25", 4) == 0 || _memicmp(context, "il2p", 4) == 0) // These have space separated params
ptr = strtok_s(NULL, " ,\r", &context);
else
ptr = strtok_s(NULL, ",\r", &context);
Data[0] = QTSMKISSCMD;
Data[1] = SETMODEMPARAMS;
while (ptr && ptr[0])
{
uint16_t freq = atoi(ptr);
if (freq)
memcpy(&Data[2], &freq, 2);
else if (strlen(ptr) > 8)
strcpy(&Data[4], ptr);
else if (_stricmp(ptr, "fx25") == 0)
{
ptr = strtok_s(NULL, " ,\r", &context);
i = 4;
if (ptr && ptr[0])
{
for (i = 0; i < 4; i++)
{
if (_stricmp(FX25Modes[i], ptr) == 0)
{
fx25_mode = i;
Data[29] = 2;
break;
}
}
}
if (i == 4)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "QTSM} Failed - fx25 flags invalid\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
}
else if (_stricmp(ptr, "il2p") == 0)
{
ptr = strtok_s(NULL, " ,\r", &context);
i = 4;
if (ptr && ptr[0])
{
for (i = 0; i < 4; i++)
{
if (_stricmp(IL2PModes[i], ptr) == 0)
{
il2p_mode = i;
Data[29] = 2;
break;
}
}
}
if (i == 4)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "QTSM} Failed - il2p flags invalid\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
}
else if (_stricmp(ptr, "crc") == 0)
{
il2p_crc = 1;
Data[29] = 2;
}
else if (_stricmp(ptr, "nocrc") == 0)
{
il2p_crc = 0;
Data[29] = 2;
}
else
{
Bufferptr = Cmdprintf(Session, Bufferptr, "QTSM} Failed - invalid param %s. Enter QTSM HELP for more info\r", ptr);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
ptr = strtok_s(NULL, " ,\r", &context);
}
Data[30] = fx25_mode;
Data[31] = il2p_mode;
Data[32] = il2p_crc;
KissLen = 33;
// Send Command
PORT->Session = Session;
PORT->LastKISSCmdTime = time(NULL);
KissString[0] |= KISS->OURCTRL;
PORT = (struct PORTCONTROL *)KISS->FIRSTPORT; // ALL FRAMES GO ON SAME Q
KissLen = KissEncode(KissString, ENCBUFF, KissLen);
ASYSEND(PORT, ENCBUFF, KissLen);
// Bufferptr = Cmdprintf(Session, Bufferptr, "Command Sent\r");
// SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
Bufferptr = Cmdprintf(Session, Bufferptr, "OK\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
DllExport int APIENTRY Get_APPLMASK(int Stream);
DllExport int APIENTRY GetStreamPID(int Stream);
DllExport int APIENTRY GetApplFlags(int Stream);

@ -3244,6 +3244,13 @@ DllExport BOOL ConvToAX25Ex(unsigned char * callsign, unsigned char * ax25call)
ax25call[6]=0x44;
return TRUE;
}
if (callsign[i+1] == 'L')
{
ax25call[6]=0x46;
return TRUE;
}
i = atoi(&callsign[i+1]);
if (i < 16)
@ -3348,6 +3355,13 @@ DllExport int ConvFromAX25(unsigned char * incall,unsigned char * outcall)
return out;
}
if (chr == 0x46)
{
outcall[out++]='-';
outcall[out++]='L';
return out;
}
chr >>= 1;
chr &= 15;
@ -3798,6 +3812,10 @@ VOID ResolveUpdateThread(void * Unused)
Sleep(1000 * 60 * 15);
continue;
}
// Resolve failed - try again in 5 mins
Sleep(1000 * 60 * 5);
}
}
@ -4968,11 +4986,16 @@ void GetPortCTEXT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, st
//
// For now at least will report dial freq if using RIGCONTROL
extern struct RIGPORTINFO * PORTInfo[MAXBPQPORTS + 2]; // Records are Malloc'd
extern int NumberofPorts;
DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqString)
{
struct PORTCONTROL * PORT = GetPortTableEntryFromPortNum(PortNo);
double freq = 0.0;
uint64_t freqint = 0;
struct RIGPORTINFO * RIGPORT;
int i, p;
char * ptr;
int n = 3;
@ -4991,7 +5014,6 @@ DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqString)
{
// Try rigcontrol
struct TNCINFO * TNC;
struct RIGINFO * RIG = 0;
@ -5000,9 +5022,43 @@ DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqString)
else
TNC = TNCInfo[PortNo];
if (TNC)
RIG = TNC->RIG;
if (TNC == 0)
{
// No associated TNC but could have an interlock group from which we can get RIG record
if (PORT->PORTINTERLOCK == 0)
return 0;
for (p = 0; p < NumberofPorts; p++)
{
RIGPORT = PORTInfo[p];
for (i=0; i< RIGPORT->ConfiguredRigs; i++)
{
RIG = &RIGPORT->Rigs[i];
if (RIG->Interlock == PORT->PORTINTERLOCK)
{
if (RIG->Valchar[0] == 0)
return 0;
freq = atof(RIG->Valchar);
// if port has QtSM modem centre add that
if (PORT->QtSMFreq)
freq += (PORT->QtSMFreq * 1.0) / 1000000.0;
freqint = (int64_t)(freq * 1000000.0);
goto returnFreq;
}
}
}
return 0;
}
RIG = TNC->RIG;
if (RIG == 0)
return 0;
@ -5011,10 +5067,18 @@ DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqString)
if (RIG->Valchar[0] == 0)
return 0;
freq = atof(TNC->RIG->Valchar);
freq = atof(RIG->Valchar);
// if port has QtSM modem centre add that
if (PORT->QtSMFreq)
freq += (PORT->QtSMFreq * 1.0) / 1000000.0;
freqint = (int64_t)(freq * 1000000.0);
}
returnFreq:
sprintf(FreqString, "%.6f", freq);
// Return 3 digits after . (KHz) unless more are significant

Binary file not shown.

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50608.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>

@ -0,0 +1,8 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC80.DebugCRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
</assembly>

Binary file not shown.

@ -0,0 +1 @@
Manifest resource last updated at 18:43:52.23 on 29/04/2026

Binary file not shown.

Binary file not shown.

@ -971,7 +971,7 @@ void APIL2Trace(struct _MESSAGE * Message, char * Dirn)
UDPMsg[udplen++] = '}';
UDPMsg[udplen] = 0;
Debugprintf(UDPMsg);
// Debugprintf(UDPMsg);
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
}

@ -1623,7 +1623,6 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
char * encPtr = 0;
int allowDeflate = 0;
char * Compressed = 0;
char * HostPtr = 0;
char * Context, * Method, * NodeURL = 0, * Key;
char _REPLYBUFFER[250000];
@ -1633,7 +1632,7 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
char Header[256];
int HeaderLen;
char TimeString[64];
BOOL LOCAL = FALSE;
BOOL LOCAL = conn->LOCALAuth;
BOOL COOKIE = FALSE;
int Len;
char * WebSock = 0;
@ -1677,41 +1676,8 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
strcpy(URL, MsgPtr);
HostPtr = strstr(MsgPtr, "Host: ");
WebSock = strstr(MsgPtr, "Upgrade: websocket");
if (HostPtr)
{
uint32_t Host;
char Hostname[32]= "";
struct LOCALNET * LocalNet = conn->TNC->TCPInfo->LocalNets;
HostPtr += 6;
memcpy(Hostname, HostPtr, 31);
strlop(Hostname, ':');
Host = inet_addr(Hostname);
if (strcmp(Hostname, "127.0.0.1") == 0)
LOCAL = TRUE;
else
{
if (conn->sin.sin_family != AF_INET6)
{
while(LocalNet)
{
uint32_t MaskedHost = conn->sin.sin_addr.s_addr & LocalNet->Mask;
if (MaskedHost == LocalNet->Network)
{
LOCAL = 1;
break;
}
LocalNet = LocalNet->Next;
}
}
}
}
encPtr = stristr(MsgPtr, "Accept-Encoding:");
if (encPtr && stristr(encPtr, "deflate"))
@ -1900,16 +1866,22 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
}
}
// APRS process internally
if (_memicmp(Context, "/APRS/", 6) == 0 || _stricmp(Context, "/APRS") == 0)
{
APRSProcessHTTPMessage(sock, MsgPtr, LOCAL, COOKIE);
if (APRSActive)
{
APRSProcessHTTPMessage(sock, MsgPtr, LOCAL, COOKIE);
return 0;
}
Len = sprintf(Header, "HTTP/1.1 404 Not Found\r\nContent-Length: 16\r\n\r\nPage not found\r\n");
send(sock, Header, Len, 0);
return 0;
}
if (_stricmp(Context, "/Node/Signon?Node") == 0)
{
char * IContext;
@ -2019,40 +1991,7 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
char * input;
char * IContext;
HostPtr = strstr(MsgPtr, "Host: ");
if (HostPtr)
{
uint32_t Host;
char Hostname[32]= "";
struct LOCALNET * LocalNet = conn->TNC->TCPInfo->LocalNets;
HostPtr += 6;
memcpy(Hostname, HostPtr, 31);
strlop(Hostname, ':');
Host = inet_addr(Hostname);
if (strcmp(Hostname, "127.0.0.1") == 0)
LOCAL = TRUE;
else while(LocalNet)
{
uint32_t MaskedHost = Host & LocalNet->Mask;
if (MaskedHost == LocalNet->Network)
{
char * rest;
LOCAL = 1;
rest = strchr(HostPtr, 13);
if (rest)
{
memmove(HostPtr + 9, rest, strlen(rest) + 1);
memcpy(HostPtr, "127.0.0.1", 9);
break;
}
}
LocalNet = LocalNet->Next;
}
}
// LOCAL is already set
NodeURL = strtok_s(Context, "?", &IContext);
Key = strtok_s(NULL, "?", &IContext);
@ -2310,7 +2249,7 @@ doHeader:
if (allowDeflate)
Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen);
else
Compressed = Reply;
Compressed = _REPLYBUFFER;
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n%s\r\n", ReplyLen, Encoding);
sendandcheck(sock, Header, HeaderLen);
@ -2500,6 +2439,9 @@ doHeader:
if (input == 0)
return 1;
if (LOCAL == FALSE && COOKIE == FALSE)
return 1;
input += 4;
if (port > 0 && port <= MaxBPQPortNo)
@ -2701,7 +2643,20 @@ doHeader:
{
// Save Config File
SaveConfigFile(sock, MsgPtr, Key, LOCAL);
if (conn->LOCALAuth)
SaveConfigFile(sock, MsgPtr, Key, LOCAL);
else
{
char _REPLYBUFFER[4096];
ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL);
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "<br><B>Not authorizedxx - please sign in</B>");
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail));
send(sock, Header, HeaderLen, 0);
send(sock, _REPLYBUFFER, ReplyLen, 0);
send(sock, Tail, (int)strlen(Tail), 0);
return 1;
}
return 0;
}
@ -2965,6 +2920,12 @@ doHeader:
{
struct TNCINFO * TNC = TNCInfo[port];
if (TNC == 0)
return 1;
if (LOCAL == FALSE && COOKIE == FALSE)
return 1;
KillTNC(TNC);
TNC->DontRestart = FALSE;
RestartTNC(TNC);

@ -4726,10 +4726,16 @@ int seeifInterlockneeded(struct PORTCONTROL * PORT)
int i;
int Interlock = PORT->PORTINTERLOCK;
struct TNCINFO * TNC;
char Cmd[64];
if (Interlock == 0)
return 0; // No locking
// I think we need to stop scanning here
sprintf(Cmd, "%d SCANSTOP", PORT->PORTNUMBER);
Rig_Command( (TRANSPORTENTRY *) -1, Cmd);
for (i = 1; i <= MAXBPQPORTS; i++)
{
TNC = TNCInfo[i];
@ -4753,6 +4759,7 @@ int seeifUnlockneeded(struct _LINKTABLE * LINK)
int Interlock;
struct TNCINFO * TNC;
struct PORTCONTROL * PORT = LINK->LINKPORT;
char Cmd[64];
if (PORT == NULL)
return 0;
@ -4795,6 +4802,14 @@ int seeifUnlockneeded(struct _LINKTABLE * LINK)
TNC->ReleasePortProc(TNC);
}
if (Interlock == 0)
return 0; // No locking
// I think we need to start scanning here
sprintf(Cmd, "%d SCANSTART 15", LINK->LINKPORT->PORTNUMBER);
Rig_Command((TRANSPORTENTRY *)-1, Cmd);
return 0;
}

@ -12,7 +12,7 @@ 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. See the
GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License
along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/

@ -864,6 +864,8 @@ int main(int argc, char * argv[])
printf("G8BPQ AX25 Packet Switch System Version %s %s\n", TextVerstring, Datestring);
printf("%s\n", VerCopyright);
printf("%d", sizeof(struct DEST_LIST));
srand(time(NULL));
// look for optarg format parameters

@ -1,4 +1,9 @@
// Apr 26
// Fix for 64 ports
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
@ -113,7 +118,7 @@ struct ModeItem
struct ModeEntries
{
struct ModeItem * Mode[32]; // One per port
struct ModeItem * Mode[64]; // One per port
};
struct FreqItem
@ -125,7 +130,7 @@ struct FreqItem
struct FreqEntries
{
struct FreqItem * Freq[32]; // One per interlock group
struct FreqItem * Freq[64]; // One per interlock group
};
struct ChatNodeData ** ChatNodes = NULL;
@ -620,6 +625,10 @@ int main(int argc, char * argv[])
pFlags = strlop(pFreq, ',');
pHeardTime = strlop(pFlags, ',');
if (pHeardTime == 0)
break;
if (pFlags && strlen(pFlags) > 14)
break;
@ -749,7 +758,7 @@ int main(int argc, char * argv[])
{
int Port = atoi(pPort);
if (Port < 32)
if (Port < 64)
{
Modes = Node->Modes;
@ -986,7 +995,7 @@ int main(int argc, char * argv[])
{
int ret = 0;
if (time(NULL) > restartTime)
if (restartTime && time(NULL) > restartTime)
return 0;
FD_ZERO(&readfd);
@ -1033,7 +1042,7 @@ int main(int argc, char * argv[])
if (nLength == 0)
continue;
// ret = sendto(sock, RXBUFFER, nLength, 0, (struct sockaddr *)&txaddr2, sizeof(txaddr));
ret = sendto(sock, RXBUFFER, nLength, 0, (struct sockaddr *)&txaddr, sizeof(txaddr));
if (ret == -1)
perror("sendto 1");
@ -1048,15 +1057,15 @@ int main(int argc, char * argv[])
*ptr = '/';
}
if (memcmp(&RXBUFFER[16], "LINK ", 5) != 0)
{
if (HostEnt1)
{
ret = sendto(sock, RXBUFFER, nLength, 0, (struct sockaddr *)&txaddr, sizeof(txaddr));
if (ret == -1)
perror("sendto 1");
}
}
// if (memcmp(&RXBUFFER[16], "LINK ", 5) != 0)
// {
// if (HostEnt1)
// {
// ret = sendto(sock, RXBUFFER, nLength, 0, (struct sockaddr *)&txaddr, sizeof(txaddr));
// if (ret == -1)
// perror("sendto 1");
// }
// }
#ifdef WIN32
Sleep(10);
@ -1252,10 +1261,10 @@ void ProcessNodeUpdate(char * From, char * Msg)
if (Port == 0)
return;
if (pFreq)
printf("%s %d %s %d %s\n", From, Port, ModeNames[Type], Interlock, pFreq);
else
printf("%s %d %s %d\n", From, Port, ModeNames[Type], Interlock);
// if (pFreq)
// printf("%s %d %s %d %s\n", From, Port, ModeNames[Type], Interlock, pFreq);
// else
// printf("%s %d %s %d\n", From, Port, ModeNames[Type], Interlock);
Port--; // Index from zero
@ -1295,7 +1304,7 @@ void ProcessNodeUpdate(char * From, char * Msg)
int lineLen = 0;
char freqString[256];
printf("%s %s\r\n", From, Msg);
// printf("%s %s\r\n", From, Msg);
if (strcmp("GM8BPQ-2", From) == 0)
n = 0;
@ -1343,7 +1352,7 @@ void ProcessNodeUpdate(char * From, char * Msg)
// Do we have a record for this group?
for (n = 0; n < 32; n++)
for (n = 0; n < 64; n++)
{
FreqItem = Node->Freqs->Freq[n];
@ -1771,7 +1780,7 @@ void GenerateOutputFiles(time_t Now)
{
struct ModeEntries * Modes = Node->Modes;
for (j = 0; j < 32; j++)
for (j = 0; j < 64; j++)
{
if (Modes->Mode[j])
{
@ -1803,7 +1812,7 @@ void GenerateOutputFiles(time_t Now)
FreqsString[0] = 0;
FreqsLen = 0;
for (j = 0; j < 32; j++)
for (j = 0; j < 64; j++)
{
if (Node->Freqs)
{
@ -2094,7 +2103,7 @@ void GenerateOutputFiles(time_t Now)
// Do Modes
for (j = 0; j < 32; j++)
for (j = 0; j < 64; j++)
{
if (Node->Modes)
{
@ -2123,7 +2132,7 @@ void GenerateOutputFiles(time_t Now)
{
struct FreqEntries * Freqs = Node->Freqs;
for (j = 0; j < 32; j++)
for (j = 0; j < 64; j++)
{
struct FreqItem * Freq = Freqs->Freq[j];

@ -5624,6 +5624,7 @@ struct RIGINFO * RigConfig(struct TNCINFO * TNC, char * buf, int Port)
RIG = &PORT->Rigs[0];
RIG->RIGOK = TRUE;
RIG->PORT = PORT;
RIG->RIG_DEBUG = RIG_DEBUG;
strcpy(PORT->IOBASE, ptr);
strcpy(RIG->RigName, "FLRIG");
@ -5657,6 +5658,7 @@ struct RIGINFO * RigConfig(struct TNCINFO * TNC, char * buf, int Port)
RIG = &PORT->Rigs[0];
RIG->RIGOK = TRUE;
RIG->PORT = PORT;
RIG->RIG_DEBUG = RIG_DEBUG;
strcpy(PORT->IOBASE, ptr);
strcpy(RIG->RigName, "HAMLIB");
@ -5690,6 +5692,7 @@ struct RIGINFO * RigConfig(struct TNCINFO * TNC, char * buf, int Port)
RIG = &PORT->Rigs[0];
RIG->RIGOK = TRUE;
RIG->PORT = PORT;
RIG->RIG_DEBUG = RIG_DEBUG;
strcpy(PORT->IOBASE, ptr);
strcpy(RIG->RigName, "RTLUDP");
@ -5765,7 +5768,7 @@ AngelRigFound:
RIG = &PORT->Rigs[PORT->ConfiguredRigs++];
RIG->RIGOK = TRUE;
RIG->PORT = PORT;
RIG->RigAddr = device;
RIG->RIG_DEBUG = RIG_DEBUG;
RIG->Channel = channel;
strcpy(RIG->RigName, Name);

@ -3285,6 +3285,7 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
struct TCPINFO * TCP = TNC->TCPInfo;
HMENU hDisMenu = TCP->hDisMenu;
u_long param=1;
int LOCAL = 0;
// if for TriModeData Session, use the TriMode Control connection entry
@ -3356,12 +3357,37 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
WriteLog (logmsg);
}
// Debugprintf("BPQ32 Telnet accept() Sock %d", sock);
ioctl(sock, FIONBIO, &param);
// See if localhost or a secure subnet
if (sockptr->sin.sin_family != AF_INET6)
{
if (sockptr->sin.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) // 127.0.0.1?
LOCAL = TRUE;
else
{
char Hostname[32]= "";
struct LOCALNET * LocalNet = TNC->TCPInfo->LocalNets;
while(LocalNet)
{
uint32_t MaskedHost = sockptr->sin.sin_addr.s_addr & LocalNet->Mask;
if (MaskedHost == LocalNet->Network)
{
LOCAL = TRUE;
break;
}
LocalNet = LocalNet->Next;
}
}
}
sockptr->LOCALAuth = LOCAL;
sockptr->socket = sock;
sockptr->SocketActive = TRUE;
sockptr->InputLen = 0;
@ -3993,7 +4019,7 @@ MsgLoop:
if (USER == NULL)
continue;
if (_stricmp(USER->UserName, "ANON") == 0)
if (_stricmp(USER->UserName, "ANON") == 0 && strlen(MsgPtr) < 10)
{
// Anon Login - Callsign is supplied as user
@ -5155,6 +5181,18 @@ int DataSocket_ReadHTTP(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S
Mask = MsgPtr[1] >> 7;
Len = MsgPtr[1] & 127;
// We don't support 64 bit payload length, so if Len = 127 disconnect session
if (Len == 127)
{
Debugprintf("WebSock 64 bit length not supported");
closesocket(sockptr->socket);
sockptr->SocketActive = FALSE;
ShowConnections(TNC);
sockptr->InputLen = 0;
return 0;
}
if (Len == 126) // Two Byte Len
{
Len = (MsgPtr[2] << 8) + MsgPtr[3];
@ -5187,10 +5225,13 @@ int DataSocket_ReadHTTP(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S
{
// PTT Message
char RigCMD[64];
if (strlen(Payload) < 6 && sockptr->WebSecure) // check for user generated input
{
char RigCMD[64];
sprintf(RigCMD, "%s PTT", Payload);
Rig_Command( (TRANSPORTENTRY *) -1, RigCMD);
sprintf(RigCMD, "%s PTT", Payload);
Rig_Command( (TRANSPORTENTRY *) -1, RigCMD);
}
}
else if (memcmp(sockptr->WebURL, "WMRefresh", 9) == 0)
{
@ -5262,8 +5303,7 @@ int DataSocket_ReadHTTP(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S
if(strstr(MsgPtr, "Upgrade: websocket"))
{
int LOCAL = 0, COOKIE = 0;
char * HostPtr;
int LOCAL = sockptr->LOCALAuth, COOKIE = 0;
char * ptr;
sockptr->WebSocks = 1;
@ -5274,44 +5314,12 @@ int DataSocket_ReadHTTP(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S
if (RigWebPage)
RigWebPage[0] = 0;
HostPtr = strstr(MsgPtr, "Host: ");
if (HostPtr)
{
uint32_t Host;
char Hostname[32]= "";
struct LOCALNET * LocalNet = sockptr->TNC->TCPInfo->LocalNets;
HostPtr += 6;
memcpy(Hostname, HostPtr, 31);
strlop(Hostname, ':');
Host = inet_addr(Hostname);
if (strcmp(Hostname, "127.0.0.1") == 0)
LOCAL = TRUE;
else
{
if (sockptr->sin.sin_family != AF_INET6)
{
while(LocalNet)
{
uint32_t MaskedHost = sockptr->sin.sin_addr.s_addr & LocalNet->Mask;
if (MaskedHost == LocalNet->Network)
{
LOCAL = 1;
break;
}
LocalNet = LocalNet->Next;
}
}
ptr = strstr(MsgPtr, "BPQSessionCookie=N");
ptr = strstr(MsgPtr, "BPQSessionCookie=N");
if (ptr)
COOKIE = TRUE;
if (ptr)
COOKIE = TRUE;
}
sockptr->WebSecure = LOCAL | COOKIE;
}
sockptr->WebSecure = LOCAL | COOKIE;
}

@ -92,7 +92,7 @@ static char WindowTitle[] = "UZ7HO";
static int RigControlRow = 165;
char FX25Modes[8][8] = {"None", "RxOnly", "RX+TX"};
char IL2PModes[8][10] = {"None", "RxOnly", "RX+TX", "il2pOnly"};
char IL2PModes[8][10] = {"None", "RxOnly", "RX+TX", "Only"};
//LOGFONT LFTTYFONT ;

@ -10,15 +10,15 @@
#endif
#define KVers 6,0,25,23
#define KVerstring "6.0.25.23\0"
#define KVers 6,0,25,28
#define KVerstring "6.0.25.28\0"
#ifdef CKernel
#define Vers KVers
#define Verstring KVerstring
#define Datestring "February 2026"
#define Datestring "April 2026"
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
#define VerCopyright "Copyright © 2001-2026 John Wiseman G8BPQ\0"
#define VerDesc "BPQ32 Switch\0"

@ -27,6 +27,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#ifdef WIN32
//#include "C:\Program Files (x86)\GnuWin32\include\iconv.h"
#define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
#else
#include <iconv.h>
#include <dirent.h>
@ -1467,6 +1468,15 @@ void ProcessWebMailMessage(struct HTTPConnectionInfo * Session, char * Key, BOOL
char Type[64] = "Content-Type: text/html\r\n";
UndoTransparency(FN);
// protect against malicious access
if (strstr(FN, ".."))
{
*RLen = sprintf(Reply, "HTTP/1.1 404 Not Found\r\nContent-Length: 16\r\n\r\nPage not found\r\n");
return;
}
ext = strchr(FN, '.');
sprintf(MsgFile, "%s/%s", BPQDirectory, FN);
@ -1480,6 +1490,14 @@ void ProcessWebMailMessage(struct HTTPConnectionInfo * Session, char * Key, BOOL
return;
}
FileSize = STAT.st_size;
if (FileSize > 200000)
{
*RLen = sprintf(Reply, "HTTP/1.1 400 File too long\r\nContent-Length: 15\r\n\r\nFile too long\r\n");
return;
}
hFile = fopen(MsgFile, "rb");
if (hFile == 0)
@ -1488,7 +1506,7 @@ void ProcessWebMailMessage(struct HTTPConnectionInfo * Session, char * Key, BOOL
return;
}
FileSize = STAT.st_size;
MsgBytes = malloc(FileSize + 1);
ReadLen = fread(MsgBytes, 1, FileSize, hFile);
@ -1543,8 +1561,24 @@ void ProcessWebMailMessage(struct HTTPConnectionInfo * Session, char * Key, BOOL
char * ext;
char Type[64] = "Content-Type: text/html\r\n";
UndoTransparency(FN);
// protect against malicious access
if (strstr(FN, ".."))
{
*RLen = sprintf(Reply, "HTTP/1.1 404 Not Found\r\nContent-Length: 16\r\n\r\nPage not found\r\n");
return;
}
// I'm pretty sure this should only be used for form sets, so name should start Standard or Local
if (_memicmp(FN, "Local", 5) != 0 && (_memicmp(FN, "Standard", 9) != 0))
{
*RLen = sprintf(Reply, "HTTP/1.1 404 Not Found\r\nContent-Length: 16\r\n\r\nPage not found\r\n");
return;
}
ext = strchr(FN, '.');
sprintf(MsgFile, "%s/%s", BPQDirectory, FN);
@ -1558,6 +1592,14 @@ void ProcessWebMailMessage(struct HTTPConnectionInfo * Session, char * Key, BOOL
return;
}
FileSize = STAT.st_size;
if (FileSize > 200000)
{
*RLen = sprintf(Reply, "HTTP/1.1 400 File too big\r\nContent-Length: 15\r\n\r\nFile too long\r\n");
return;
}
hFile = fopen(MsgFile, "rb");
if (hFile == 0)
@ -1566,7 +1608,6 @@ void ProcessWebMailMessage(struct HTTPConnectionInfo * Session, char * Key, BOOL
return;
}
FileSize = STAT.st_size;
MsgBytes = malloc(FileSize + 1);
ReadLen = fread(MsgBytes, 1, FileSize, hFile);
@ -3534,8 +3575,6 @@ int DisplayWebForm(struct HTTPConnectionInfo * Session, struct MsgInfo * Msg, ch
sprintf(FormDir, "WMFile/%s/%s/", Dir->FormSet, Dir->DirName);
if (Form == NULL)
{
// Not found - just display as normal message

@ -640,10 +640,10 @@ typedef struct PORTCONTROL
UCHAR AVSENDING; // LAST MINUTE
UCHAR AVACTIVE;
char PktFlags[64]; // Decode stts rom QtSM
char PktFlags[64]; // Decode stats from QtSM
char PORTTYPE; // H/W TYPE
// 0 = ASYNC, 2 = PC120, 4 = DRSI
// 0 = ASYNC, 2 = LORA, 4 = DRSI
// 6 = TOSH, 8 = QUAD, 10 = RLC100
// 12 = RLC400 14 = INTERNAL 16 = EXTERNAL
@ -740,12 +740,24 @@ typedef struct PORTCONTROL
int QtSMPort;
BOOL QtSMConnected;
int QtSMFreq; // From KISS reporting of QtSM info
char QtSMModem[21];
unsigned char Version[4];
unsigned char fx25Flags;
unsigned char il2pFlags;
unsigned char il2pcrc;
int StatsPointer;
UCHAR * TX; // % Sending
UCHAR * BUSY; // % Active (Normally DCD active or TX)
int Hardware; // TNC H_TYPE. Copied here for access from application context
int isRF; // For API reporting. -1 is unspecified
int FREQ; // Lora config
int BW;
int SF;
int CR;
int SENDRIFTIMER;
time_t LastRIFTime;

@ -626,7 +626,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
// if digis are present, scan down list for first non-used call
if (buff->ORIGIN[6] == 0)
if ((buff->ORIGIN[6] & 0x01) == 0)
{
// end of addr bit not set, so scan digis

@ -301,9 +301,11 @@ char BridgeMap[MaxBPQPortNo + 1][MaxBPQPortNo + 1] = {0};
// Keep Buffers at end
#define DATABYTES 600000 // WAS 320000
#define DATABYTES 800000 // WAS 320000
UCHAR DATAAREA[DATABYTES] = "";
UCHAR XXXXXXXX[DATABYTES] = "";
UCHAR * DATAAREA = &XXXXXXXX[0];
void ** Bufferlist[1000] = {0};
@ -1032,6 +1034,10 @@ BOOL Start()
PORT->ALLOWINP3 = PortRec->AllowINP3;
PORT->ENABLEINP3 = PortRec->EnableINP3;
PORT->isRF = PortRec->isRF;
PORT->FREQ = PortRec->FREQ;
PORT->BW = PortRec->BW;
PORT->SF = PortRec->SF;
PORT->CR = PortRec->CR;
PORT->PORTWINDOW = (UCHAR)PortRec->MAXFRAME;
@ -2996,6 +3002,10 @@ VOID FindLostBuffers()
break;
}
}
if (Buff == *Buff)
break;
Buff = *Buff;
}
n = NUMBEROFBUFFERS;

@ -256,6 +256,7 @@ int do_kiss(char *value,char *rec);
int decode_ded_rec(char *rec);
int simple(int i);
int64_t int64_value(int64_t * val, char value[], char rec[]);
int32_t int32_value(int32_t * val, char value[], char rec[]);
int C_Q_ADD_NP(VOID *PQ, VOID *PBUFF);
@ -384,7 +385,7 @@ static char *pkeywords[] =
"UDPPORT", "IPADDR", "I2CBUS", "I2CDEVICE", "UDPTXPORT", "UDPRXPORT", "NONORMALIZE",
"IGNOREUNLOCKEDROUTES", "INP3ONLY", "TCPPORT", "RIGPORT", "PERMITTEDAPPLS", "HIDE",
"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort",
"ALLOWINP3", "ENABLEINP3", "isRF"}; /* parameter keywords */
"ALLOWINP3", "ENABLEINP3", "isRF", "FREQ", "BW", "SF", "CR"}; /* parameter keywords */
static void * poffset[] =
{
@ -399,7 +400,7 @@ static void * poffset[] =
&xxp.IOADDR, &xxp.IPADDR, &xxp.INTLEVEL, &xxp.IOADDR, &xxp.IOADDR, &xxp.ListenPort, &xxp.NoNormalize,
&xxp.IGNOREUNLOCKED, &xxp.INP3ONLY, &xxp.TCPPORT, &xxp.RIGPORT, &xxp.PERMITTEDAPPLS, &xxp.Hide,
&xxp.SmartID, &xxp.KissParams, &xxp.SendtoM0LTEMap, &xxp.PortFreq, &xxp.M0LTEMapInfo, &xxp.QtSMPort,
&xxp.AllowINP3, &xxp.EnableINP3, &xxp.isRF}; /* offset for corresponding data in config file */
&xxp.AllowINP3, &xxp.EnableINP3, &xxp.isRF, &xxp.FREQ, &xxp.BW, &xxp.SF, &xxp.CR}; /* offset for corresponding data in config file */
static int proutine[] =
{
@ -414,7 +415,7 @@ static int proutine[] =
1, 17, 1, 1, 1, 1, 2,
2, 2, 1, 1, 19, 2,
1, 20, 1, 21, 22, 1,
1, 1, 1}; /* routine to process parameter */
1, 1, 1, 23, 23, 23, 23}; /* routine to process parameter */
int PPARAMLIM = sizeof(proutine)/sizeof(int);
@ -433,7 +434,7 @@ static int routeindex = 0;
/* Global variables */
/************************************************************************/
int paramok[100] = {0}; /* PARAMETER OK FLAG */
int paramok[120] = {0}; /* PARAMETER OK FLAG */
FILE *fp1; /* TEXT INPUT FILE */
@ -642,6 +643,10 @@ BOOL ProcessConfig()
paramok[96]=1; // EnableOARCAPI
paramok[97]=1; // MONTOFILE
paramok[98]=1; // RIFInterval
paramok[99]=1; // Freq
paramok[100]=1; // BW
paramok[101]=1; // SF
paramok[102]=1; // CR
for (i=0; i < PARAMLIM; i++)
@ -1394,6 +1399,23 @@ int int_value(short * val, char value[], char rec[])
return(1);
}
int int32_value(int32_t * val, char value[], char rec[])
{
int j,k;
k = sscanf(value," %d",&j);
if (k != 1)
{
Consoleprintf("Invalid numerical value ");
Consoleprintf("%s\r\n",rec);
return(0);
}
val[0] = j;
return(1);
}
int64_t int64_value(int64_t * val, char value[], char rec[])
{
*val = strtoll(value, NULL, 10);
@ -2424,7 +2446,7 @@ int decode_port_rec(char * rec)
break;
case 20:
cn = doKissCommand(i, value, rec); // Permitted Apps
cn = doKissCommand(i, value, rec);
break;
case 21:
@ -2436,6 +2458,10 @@ int decode_port_rec(char * rec)
cn = 1;
break;
case 23:
cn = int32_value(poffset[i], value, rec); /* INTEGER VALUES */
break;
case 9:
cn = 1;

@ -84,6 +84,11 @@ struct PORTCONFIG
int AllowINP3;
int EnableINP3;
short isRF;
int FREQ;
int BW;
int SF;
int CR;
};
struct ROUTECONFIG

100
kiss.c

@ -88,6 +88,8 @@ int i2cPoll(struct PORTCONTROL * PORT, NPASYINFO npKISSINFO);
#define TFEND 0xDC
#define TFESC 0xDD
#define QTSMKISSCMD 7
#define MODEMREPORT 1 // QTSM Modem Info subcommand
#define SETPARAMS 2 // QtSM Moden change settings
#define STX 2 // NETROM CONTROL CODES
#define ETX 3
@ -118,11 +120,15 @@ VOID CloseKISSPort(struct PORTCONTROL * PortVector);
int ReadCOMBlockEx(HANDLE fd, char * Block, int MaxLength, BOOL * Error);
void processDRATSFrame(unsigned char * Message, int Len, void * sockptr);
VOID ConnecttoQtSM(struct PORTCONTROL * PORT);
int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len);
extern struct PORTCONTROL * PORTTABLE;
extern int NUMBEROFPORTS;
extern void * TRACE_Q;
extern char FX25Modes[8][8];
extern char IL2PModes[8][10];
#define TICKS 10 // Ticks per sec
// temp for testing
@ -500,6 +506,18 @@ HANDLE OpenConnection(struct PORTCONTROL * PortVector)
if (KISS && KISS->KISSCMD && KISS->KISSCMDLEN)
ASYSEND(PortVector, KISS->KISSCMD, KISS->KISSCMDLEN);
if (PortVector->FREQ) // Lora params
{
UCHAR KissString[128];
UCHAR ENCBUFF[256];
int KissLen = 0;
unsigned char * Kissptr = KissString;
KissLen = sprintf(KissString, "%cLORA=%d, %d, %d, %d", 6, PortVector->FREQ, PortVector->BW, PortVector->SF, PortVector->CR);
KissLen = KissEncode(KissString, ENCBUFF, KissLen);
ASYSEND(PortVector, ENCBUFF, KissLen);
}
return ComDev;
}
@ -1560,15 +1578,60 @@ SeeifMore:
// ok, KISS now points to our port
// Debugprintf("%d %x %s", PORT->PORTNUMBER, Port->RXMSG[0], Msg);
if (memcmp(Msg, "STATS ", 6) == 0)
if (Msg[0] == MODEMREPORT)
{
int Freq = Msg[1] | (Msg[2] <<8);
KISS->PORT.QtSMFreq = Freq;
strcpy(KISS->PORT.QtSMModem, &Msg[3]);
if (len >= 32)
{
PORT->fx25Flags = Msg[29];
PORT->il2pFlags = Msg[30];
PORT->il2pcrc = Msg[31];
}
// If a response to a qtsm command display it
if (PORT->Session && (time(NULL) - PORT->LastKISSCmdTime < 10))
{
PDATAMESSAGE Buffer;
BPQVECSTRUC * VEC;
unsigned char * Msg = &Port->RXMSG[1];
len--;
Msg[len] = 0;
Buffer = GetBuff();
if (Buffer)
{
Buffer->PID = 0xf0;
Buffer->LENGTH = MSGHDDRLEN + 1; // Includes PID
Buffer->LENGTH += sprintf(Buffer->L2DATA, "Modem %s Centre frequency %d fx25 %s il2p %s %s\r",
(PORT->QtSMModem[0]) ? PORT->QtSMModem : "Not Available", PORT->QtSMFreq,
FX25Modes[PORT->fx25Flags], IL2PModes[PORT->il2pFlags], PORT->il2pcrc?"CRC":"");
VEC = PORT->Session->L4TARGET.HOST;
C_Q_ADD(&PORT->Session->L4TX_Q, (UINT *)Buffer);
#ifdef BPQ32
if (VEC)
PostMessage(VEC->HOSTHANDLE, BPQMsg, VEC->HOSTSTREAM, 2);
#endif
}
PORT->Session = 0;
}
}
else if (memcmp(Msg, "STATS ", 6) == 0)
{
// Save busy
int TX, DCD;
char * Msg1 = strlop(&Msg[6], ' ');
TX = atoi(&Msg[6]);
if (Msg1)
{
@ -1926,6 +1989,7 @@ VOID ConnecttoTCPThread(void * Param)
SOCKADDR_IN sinx;
int addrlen=sizeof(sinx);
struct KISSINFO * KISS = (struct KISSINFO *) ASY->Portvector;
struct KISSINFO * NEXT;
sinx.sin_family = AF_INET;
sinx.sin_addr.s_addr = INADDR_ANY;
@ -1984,8 +2048,32 @@ VOID ConnecttoTCPThread(void * Param)
ioctlsocket (sock, FIONBIO, &param);
if (KISS && KISS->KISSCMD && KISS->KISSCMDLEN)
send(sock, KISS->KISSCMD, KISS->KISSCMDLEN, 0);
// Send KISSCMD to all channels on this port
NEXT = KISS;
while (NEXT)
{
if (NEXT && NEXT->KISSCMD && NEXT->KISSCMDLEN)
{
NEXT->KISSCMD[1] |= NEXT->OURCTRL;
send(sock, NEXT->KISSCMD, NEXT->KISSCMDLEN, 0);
}
NEXT = NEXT->SUBCHAIN;
}
if (KISS->PORT.FREQ) // Lora params
{
UCHAR KissString[128];
UCHAR ENCBUFF[256];
int KissLen = 0;
unsigned char * Kissptr = KissString;
KissLen = sprintf(KissString, "%cLORA=%d, %d, %d, %d", 6, KISS->PORT.FREQ, KISS->PORT.BW, KISS->PORT.SF, KISS->PORT.CR);
KissLen = KissEncode(KissString, ENCBUFF, KissLen);
send(sock, ENCBUFF, KissLen, 0);
}
// Try to open Mgmt Port

@ -16,6 +16,7 @@ struct MsgInfo * GetMsgFromNumber(int msgno);
BOOL CheckUserMsg(struct MsgInfo * Msg, char * Call, BOOL SYSOP);
char * doXMLTransparency(char * string);
extern BOOL M0LTEMap;
// Constants
#define TOKEN_SIZE 32 // Length of the authentication token
@ -856,6 +857,10 @@ void SendBBSDataToPktMapThread(void * Param);
void SendBBSDataToPktMap()
{
#ifdef LINBPQ
if (M0LTEMap == 0)
return;
#endif
_beginthread(SendBBSDataToPktMapThread, 0, 0);
}
@ -994,6 +999,10 @@ void SendBBSDataToPktMapThread(void * Param)
// Have R Lines
Rlineend = strstr(Rlineptr, "\r\n");
if (Rlineend == 0)
break;
Rlineend[0] = 0;
ptr2 += sprintf(ptr2, "\"%s\",", Rlineptr);

@ -42,7 +42,7 @@ struct ConnectionInfo
BOOL TriMode; // Trimode emulation
BOOL TriModeConnected; // Set when remote session is connected - now send data to DataSock
SOCKET TriModeDataSock; // Data Socket
BOOL Auth; // Set if User is flagged as a Secure User
BOOL LOCALAuth; // Set if connection from localhost or a secure subnet
BOOL BPQTermMode; // Set if connected to BPQTermTCP
BOOL ClientSession; // Set if acting as a client (ie Linux HOST Mode)
BOOL MonitorNODES; // Monitor Control Flags

Loading…
Cancel
Save

Powered by TurnKey Linux.