New upstream version 6.0.25.9+repack

This commit is contained in:
Hibby 2025-11-09 22:34:20 +00:00
parent 7c796758d1
commit 367ab8fb01
48 changed files with 4189 additions and 1009 deletions

View file

@ -509,6 +509,14 @@ UCHAR * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen, int DoNo
return Output;
}
if (ADJBUFFER->L2DATA[0] == 0xfe) // Paula's Nodes Poll
{
memcpy(Alias, ++ptr, 6);
Output += sprintf((char *)Output, " NODES POLL from %s\r", Alias);
return Output;
}
// Display normal NET/ROM transmissions
Output += sprintf((char *)Output, " NET/ROM\r ");

20
ARDOP.c
View file

@ -62,6 +62,12 @@ int (WINAPI FAR *EnumProcessesPtr)();
#include "tncinfo.h"
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
#define WSA_ACCEPT WM_USER + 1
#define WSA_DATA WM_USER + 2
#define WSA_CONNECT WM_USER + 3
@ -567,7 +573,7 @@ static int ProcessLine(char * buf, int Port)
}
void ARDOPThread(struct TNCINFO * TNC);
void ARDOPThread(VOID * Param);
VOID ARDOPProcessDataSocketData(int port);
int ConnecttoARDOP(struct TNCINFO * TNC);
static VOID ARDOPProcessReceivedData(struct TNCINFO * TNC);
@ -1035,10 +1041,12 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{
TNC->Busy--;
if (TNC->Busy == 0)
{
MySetWindowText(TNC->xIDC_CHANSTATE, "Clear");
strcpy(TNC->WEB_CHANSTATE, "Clear");
}
}
}
if (TNC->BusyDelay)
{
@ -2312,12 +2320,13 @@ int ConnecttoARDOP(struct TNCINFO * TNC)
return 0;
}
VOID ARDOPThread(struct TNCINFO * TNC)
VOID ARDOPThread(VOID * Param)
{
// Opens sockets and looks for data on control and data sockets.
// Socket may be TCP/IP or Serial
struct TNCINFO * TNC = (struct TNCINFO *) Param;
char Msg[255];
int err, i, ret;
u_long param=1;
@ -5758,8 +5767,7 @@ VOID ARDOPSCSPoll(struct TNCINFO * TNC)
// Probably only for Teensy with ESP01. Runs SCS Emulator over a TCP Link
VOID SerialConnecttoTCPThread(struct TNCINFO * TNC);
VOID SerialConnecttoTCPThread(VOID * Param);
int SerialConnecttoTCP(struct TNCINFO * TNC)
{
@ -5767,9 +5775,9 @@ int SerialConnecttoTCP(struct TNCINFO * TNC)
return 0;
}
VOID SerialConnecttoTCPThread(struct TNCINFO * TNC)
VOID SerialConnecttoTCPThread(VOID * Param)
{
struct TNCINFO * TNC = (struct TNCINFO *) Param;
char Msg[255];
int i;
u_long param = 1;

View file

@ -3701,7 +3701,7 @@ void DoKillCommand(CIRCUIT * conn, struct UserInfo * user, char * Cmd, char * Ar
if (conn->sysop)
{
if (Arg1)
if (KillMessagesFrom(conn, user, Arg1) == 0);
if (KillMessagesFrom(conn, user, Arg1) == 0)
BBSputs(conn, "No Messages found\r");
return;
@ -6556,7 +6556,7 @@ nextline:
{
char APRS[128];
char Call[16];
int SSID = user->flags >> 28;
int SSID = (user->flags >> 28) & 15; // on some platforms this is treated as signed ??
if (SSID)
sprintf(Call, "%s-%d", Msg->to, SSID);
@ -13395,7 +13395,7 @@ int DeleteRedundantMessages()
{
while(n--)
{
if (stat(namelist[n]->d_name, &STAT) == 0);
if (stat(namelist[n]->d_name, &STAT) == 0)
{
Msgno = atoi(&namelist[n]->d_name[2]);

303
BPQINP3.c
View file

@ -35,16 +35,26 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#include <fcntl.h>
//#include "vmm.h"
uint64_t timeLoadedMS = 0;
uint64_t INP3timeLoadedMS = 0;
extern int DEBUGINP3;
VOID SendNegativeInfo();
VOID SortRoutes(struct DEST_LIST * Dest);
VOID SendRTTMsg(struct ROUTE * Route);
VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame);
static VOID SendNetFrame(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame)
{
// INP3 should only ever send over an active link, so just queue the message
if (Route->TCPPort) // NETROM over TCP
{
TCPNETROMSend(Route, Frame);
ReleaseBuffer(Frame);
return;
}
if (Route->NEIGHBOUR_LINK)
C_Q_ADD(&Route->NEIGHBOUR_LINK->TX_Q, Frame);
else
@ -62,8 +72,8 @@ typedef struct _RTTMSG
UCHAR ALIAS[7];
UCHAR VERSION[12];
UCHAR SWVERSION[9];
UCHAR FLAGS[10];
UCHAR PADDING[147];
UCHAR FLAGS[20];
UCHAR PADDING[137];
} RTTMSG;
@ -102,14 +112,14 @@ int RTTTimeout = 6; // 1 Min (Horizon is 1 min)
VOID InitialiseRTT()
{
UCHAR temp[sizeof(RTTMsg.FLAGS) + 4];
UCHAR temp[256] = "";
memset(&RTTMsg, ' ', sizeof(struct _RTTMSG));
memcpy(RTTMsg.ID, "L3RTT: ", 7);
memcpy(RTTMsg.VERSION, "LEVEL3_V2.1 ", 12);
memcpy(RTTMsg.SWVERSION, "BPQ32001 ", 9);
_snprintf(temp, sizeof(temp), "$M%d $N ", MAXRTT); // trailing spaces extend to ensure padding if the length of characters for MAXRTT changes.
memcpy(RTTMsg.FLAGS, temp, 10); // But still limit the actual characters copied.
memcpy(RTTMsg.SWVERSION, "BPQ32002 ", 9);
_snprintf(temp, sizeof(temp), "$M%d $N $H%d ", MAXRTT, MaxHops); // trailing spaces extend to ensure padding if the length of characters for MAXRTT changes.
memcpy(RTTMsg.FLAGS, temp, 20); // But still limit the actual characters copied.
memcpy(RTTMsg.ALIAS, &MYALIASTEXT, 6);
RTTMsg.ALIAS[6] = ' ';
}
@ -125,10 +135,11 @@ VOID TellINP3LinkGone(struct ROUTE * Route)
if (Route->NEIGHBOUR_LINK)
Debugprintf("BPQ32 Neighbour_Link not cleared");
// Link can have both NETROM and INP3 links
if (Route->INP3Node == 0)
// if (Route->INP3Node == 0)
DecayNETROMRoutes(Route);
else
// else
DeleteINP3Routes(Route);
}
@ -141,7 +152,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route)
Call1[ConvFromAX25(Route->NEIGHBOUR_CALL, Call1)] = 0;
Debugprintf("Deleting INP3 routes via %s", Call1);
if (DEBUGINP3) Debugprintf("Deleting INP3 routes via %s", Call1);
// Delete any INP3 Dest entries via this Route
@ -177,7 +188,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route)
// If we are cleaning up after a sabm on an existing link (frmr or other end reloaded) then we don't need to tell anyone - the routes should be reestablished very quickly
Debugprintf("Deleting First INP3 Route to %s", Call2);
if (DEBUGINP3) Debugprintf("Deleting First INP3 Route to %s", Call2);
if (Dest->INP3ROUTE[1].ROUT_NEIGHBOUR == 0)
{
@ -186,7 +197,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route)
Dest->INP3ROUTE[0].SRTT = 60000;
Dest->INP3ROUTE[0].Hops = 255;
Debugprintf("Was the only INP3 route");
if (DEBUGINP3) Debugprintf("Was the only INP3 route");
if (Dest->DEST_ROUTE == 4) // we were using it
Dest->DEST_ROUTE = 0;
@ -206,7 +217,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route)
if (Dest->INP3ROUTE[1].ROUT_NEIGHBOUR == Route)
{
Debugprintf("Deleting 2nd INP3 Route to %s", Call2);
if (DEBUGINP3) Debugprintf("Deleting 2nd INP3 Route to %s", Call2);
memcpy(&Dest->INP3ROUTE[1], &Dest->INP3ROUTE[2], sizeof(struct INP3_DEST_ROUTE_ENTRY));
memset(&Dest->INP3ROUTE[2], 0, sizeof(struct INP3_DEST_ROUTE_ENTRY));
@ -215,7 +226,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route)
if (Dest->INP3ROUTE[2].ROUT_NEIGHBOUR == Route)
{
Debugprintf("Deleting 3rd INP3 Route to %s", Call2);
if (DEBUGINP3) Debugprintf("Deleting 3rd INP3 Route to %s", Call2);
memset(&Dest->INP3ROUTE[2], 0, sizeof(struct INP3_DEST_ROUTE_ENTRY));
continue;
}
@ -339,10 +350,10 @@ VOID ProcessRTTReply(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff)
Route->Timeout = 0; // Got Response
sscanf(&Buff->L4DATA[6], "%d", &OrigTime);
RTT = (GetTickCount() - timeLoadedMS) - OrigTime;
RTT = (int)((GetTickCount() - INP3timeLoadedMS) / 10 - (OrigTime)); // We work internally in mS
if (RTT > 60000)
return; // Ignore if more than 60 secs
return; // Ignore if more than 60 secs (why ??)
Route->RTT = RTT;
@ -351,11 +362,13 @@ VOID ProcessRTTReply(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff)
else
Route->SRTT = ((Route->SRTT * 80)/100) + ((RTT * 20)/100);
Route->RTTIncrement = Route->SRTT / 2; // Half for one way time.
if ((Route->Status & GotRTTResponse) == 0)
{
// Link is just starting
Debugprintf("INP3 got first RTT reply from %s - Link is (Re)staring", Normcall);
if (DEBUGINP3) Debugprintf("INP3 got first RTT reply from %s - Link is (Re)staring", Normcall);
Route->Status |= GotRTTResponse;
}
@ -374,10 +387,10 @@ VOID ProcessINP3RIF(struct ROUTE * Route, UCHAR * ptr1, int msglen, int Port)
char Normcall[10];
Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0;
Debugprintf("Processing RIF from %s INP3Node %d Route SRTT %d", Normcall, Route->INP3Node, Route->SRTT);
if (DEBUGINP3) Debugprintf("Processing RIF from %s INP3Node %d Route SRTT %d", Normcall, Route->INP3Node, Route->SRTT);
if (Route->SRTT == 0)
Debugprintf("INP3 Zero SRTT");
if (DEBUGINP3) Debugprintf("INP3 Zero SRTT");
#ifdef NOINP3
@ -403,7 +416,7 @@ VOID ProcessINP3RIF(struct ROUTE * Route, UCHAR * ptr1, int msglen, int Port)
{
if (msglen < 10)
{
Debugprintf("Corrupt INP3 Message");
if (DEBUGINP3) Debugprintf("Corrupt INP3 Message");
return;
}
@ -421,7 +434,12 @@ VOID ProcessINP3RIF(struct ROUTE * Route, UCHAR * ptr1, int msglen, int Port)
// rtt is value from remote node. Add our RTT to that node
rtt += Route->SRTT;
// if other end is old bpq then value is mS otherwise 10 mS unita
if (Route->OldBPQ)
rtt /= 10;
// rtt += Route->SRTT; // Don't do this - other end has added linkrtt
msglen -= 10;
@ -439,7 +457,7 @@ VOID ProcessINP3RIF(struct ROUTE * Route, UCHAR * ptr1, int msglen, int Port)
memcpy(alias, ptr1+2, len-2);
else
{
Debugprintf("Corrupt INP3 Message");
if (DEBUGINP3) Debugprintf("Corrupt INP3 Message");
return;
}
}
@ -477,13 +495,13 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops,
if (CompareCalls(axcall, NETROMCALL))
{
Debugprintf("INP3 for our Nodecall - discarding");
if (DEBUGINP3) Debugprintf("INP3 for our Nodecall - discarding");
return;
}
if (CheckExcludeList(axcall) == 0)
{
Debugprintf("INP3 excluded - discarding");
if (DEBUGINP3) Debugprintf("INP3 excluded - discarding");
return;
}
@ -493,7 +511,7 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops,
if (CompareCalls(axcall, APPL->APPLCALL))
{
Debugprintf("INP3 for an APPLCALL - discarding");
if (DEBUGINP3) Debugprintf("INP3 for an APPLCALL - discarding");
return;
}
}
@ -502,20 +520,20 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops,
if (hops > MaxHops && hops < 255)
{
ConvFromAX25(axcall, call);
Debugprintf("INP3 Node %s Hops %d RTT %d Ignored - Hop Count too high", call, hops, rtt);
if (DEBUGINP3) Debugprintf("INP3 Node %s Hops %d RTT %d Ignored - Hop Count too high", call, hops, rtt);
return;
}
if (rtt > MAXRTT && rtt < 60000)
{
ConvFromAX25(axcall, call);
Debugprintf("INP3 Node %s Hops %d RTT %d Ignored - rtt too high", call, hops, rtt);
if (DEBUGINP3) Debugprintf("INP3 Node %s Hops %d RTT %d Ignored - rtt too high", call, hops, rtt);
return;
}
if (rtt >= 60000)
{
Debugprintf("INP3 RTT > 60000 - discarding");
if (DEBUGINP3) Debugprintf("INP3 RTT > 60000 - discarding");
return;
}
@ -524,7 +542,7 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops,
if (Dest == NULL)
{
Debugprintf("INP3 Table Full - discarding");
if (DEBUGINP3) Debugprintf("INP3 Table Full - discarding");
return; // Table Full
}
@ -548,7 +566,7 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops,
NUMBEROFNODES++;
ConvFromAX25(Dest->DEST_CALL, call);
Debugprintf("INP3 Adding New Node %s Hops %d RTT %d", call, hops, rtt);
if (DEBUGINP3) Debugprintf("INP3 Adding New Node %s Hops %d RTT %d", call, hops, rtt);
return;
@ -556,14 +574,14 @@ Found:
if (Dest->DEST_STATE & 0x80) // Application Entry
{
Debugprintf("INP3 Application Entry - discarding");
if (DEBUGINP3) Debugprintf("INP3 Application Entry - discarding");
return;
}
// Update ALIAS
ConvFromAX25(Dest->DEST_CALL, call);
Debugprintf("INP3 Updating Node %s Hops %d RTT %d", call, hops, rtt);
if (DEBUGINP3) Debugprintf("INP3 Updating Node %s Hops %d RTT %d", call, hops, rtt);
if (alias[0] > ' ')
memcpy(Dest->DEST_ALIAS, alias, 6);
@ -574,7 +592,7 @@ Found:
if (ROUTEPTR->ROUT_NEIGHBOUR == Route)
{
Debugprintf("INP3 Already have as route[0] - updating");
if (DEBUGINP3) Debugprintf("INP3 Already have as route[0] - updating");
UpdateRoute(Dest, ROUTEPTR, hops, rtt);
return;
}
@ -583,7 +601,7 @@ Found:
if (ROUTEPTR->ROUT_NEIGHBOUR == Route)
{
Debugprintf("INP3 Already have as route[1] - updating");
if (DEBUGINP3) Debugprintf("INP3 Already have as route[1] - updating");
UpdateRoute(Dest, ROUTEPTR, hops, rtt);
return;
}
@ -592,7 +610,7 @@ Found:
if (ROUTEPTR->ROUT_NEIGHBOUR == Route)
{
Debugprintf("INP3 Already have as route[2] - updating");
if (DEBUGINP3) Debugprintf("INP3 Already have as route[2] - updating");
UpdateRoute(Dest, ROUTEPTR, hops, rtt);
return;
}
@ -608,7 +626,7 @@ Found:
{
// Add here
Debugprintf("INP3 adding as route[%d]", i);
if (DEBUGINP3) Debugprintf("INP3 adding as route[%d]", i);
AddHere(ROUTEPTR, Route, hops, rtt);
SortRoutes(Dest);
return;
@ -616,7 +634,7 @@ Found:
ROUTEPTR++;
}
Debugprintf("INP3 All entries in use - see if this is better than existing");
if (DEBUGINP3) Debugprintf("INP3 All entries in use - see if this is better than existing");
// Full, see if this is better
@ -626,7 +644,7 @@ Found:
{
// We are better. Move others down and add on front
Debugprintf("INP3 Replacing route 0");
if (DEBUGINP3) Debugprintf("INP3 Replacing route 0");
memcpy(&Dest->INP3ROUTE[2], &Dest->INP3ROUTE[1], sizeof(struct INP3_DEST_ROUTE_ENTRY));
memcpy(&Dest->INP3ROUTE[1], &Dest->INP3ROUTE[0], sizeof(struct INP3_DEST_ROUTE_ENTRY));
@ -638,7 +656,7 @@ Found:
{
// We are better. Move 2nd down and add
Debugprintf("INP3 Replacing route 1");
if (DEBUGINP3) Debugprintf("INP3 Replacing route 1");
memcpy(&Dest->INP3ROUTE[2], &Dest->INP3ROUTE[1], sizeof(struct INP3_DEST_ROUTE_ENTRY));
AddHere(&Dest->INP3ROUTE[1], Route, hops, rtt);
return;
@ -648,13 +666,13 @@ Found:
{
// We are better. Add here
Debugprintf("INP3 Replacing route 2");
if (DEBUGINP3) Debugprintf("INP3 Replacing route 2");
AddHere(&Dest->INP3ROUTE[2], Route, hops, rtt);
return;
}
Debugprintf("INP3 Worse that any existing route");
if (DEBUGINP3) Debugprintf("INP3 Worse that any existing route");
// Worse than any - ignore
@ -729,13 +747,16 @@ VOID SortRoutes(struct DEST_LIST * Dest)
{
char Call1[10], Call2[10], Call3[10];
// force route re-evaluation
Dest->DEST_ROUTE = 0;
// May now be out of order
if (Dest->INP3ROUTE[1].ROUT_NEIGHBOUR == 0)
{
Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0;
Debugprintf("INP3 1 route %d %s", Dest->INP3ROUTE[0].SRTT, Call1);
if (DEBUGINP3) Debugprintf("INP3 1 route %d %s", Dest->INP3ROUTE[0].SRTT, Call1);
return; // Only One, so cant be out of order
}
if (Dest->INP3ROUTE[2].ROUT_NEIGHBOUR == 0)
@ -745,7 +766,7 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0;
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2);
if (DEBUGINP3) Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2);
if (Dest->INP3ROUTE[0].SRTT <= Dest->INP3ROUTE[1].SRTT)
return;
@ -759,7 +780,7 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0;
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2);
if (DEBUGINP3) Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2);
return;
}
@ -770,7 +791,7 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0;
Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
// In order?
@ -791,7 +812,7 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0;
Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
// if 3 is better than 2 swap them. As two is worse than one. three will then be worst
@ -807,7 +828,7 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0;
Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
// 3 is now slowest. 2 could still be better than 1
@ -824,14 +845,14 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0;
Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
if (Dest->INP3ROUTE[0].SRTT <= Dest->INP3ROUTE[1].SRTT && Dest->INP3ROUTE[1].SRTT <= Dest->INP3ROUTE[2].SRTT)// In order?
return;
// Something went wrong
Debugprintf("INP3 Sort Failed");
if (DEBUGINP3) Debugprintf("INP3 Sort Failed");
}
@ -871,9 +892,13 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len
{
int OtherRTT;
int Dummy;
char * ptr;
struct _RTTMSG * RTTMsg = (struct _RTTMSG *)&Buff->L4DATA[0];
char Normcall[10];
if (Route->NEIGHBOUR_LINK == 0)
return;
Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0;
// See if a reply to our message, or a new request
@ -885,20 +910,40 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len
return;
}
if (Route->NEIGHBOUR_LINK->LINKPORT->ALLOWINP3)
if (Route->NEIGHBOUR_LINK->LINKPORT && (Route->NEIGHBOUR_LINK->LINKPORT->ALLOWINP3 || Route->NEIGHBOUR_LINK->LINKPORT->ENABLEINP3))
Route->INP3Node = 1;
if (Route->INP3Node == 0)
{
Debugprintf("Ignoring RTT Msg from %s - not using INP3", Normcall);
if (DEBUGINP3) Debugprintf("Ignoring RTT Msg from %s - not using INP3", Normcall);
ReleaseBuffer(Buff);
return; // We don't want to use INP3
}
// Extract other end's SRTT
// Get SWVERSION to see if other end is old (Buggy) BPQ
if (memcmp(RTTMsg->SWVERSION, "BPQ32001 ", 9) == 0)
Route->OldBPQ = 1;
else
Route->OldBPQ = 0;
sscanf(&Buff->L4DATA[6], "%d %d", &Dummy, &OtherRTT);
Route->NeighbourSRTT = OtherRTT * 10; // We store in mS
Route->NeighbourSRTT = OtherRTT;
// Look for $M and $H (MAXRTT MAXHOPS)
ptr = strstr(RTTMsg->FLAGS, "$M");
if (ptr)
Route->RemoteMAXRTT = atoi(ptr + 2);
ptr = strstr(RTTMsg->FLAGS, "$H");
if (ptr)
Route->RemoteMAXHOPS = atoi(ptr + 2);
// Echo Back to sender
@ -908,20 +953,8 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len
{
// Link is just starting
Debugprintf("INP3 Processing first RTT frame from %s - link is (re)starting", Normcall);
if (DEBUGINP3) Debugprintf("INP3 Processing first RTT frame from %s - link is (re)starting", Normcall);
Route->Status |= GotRTTRequest;
// I don't think we should send RIF until we get an RTT response.
if ((Route->Status & SentRTTRequest) == 0) // Not sent one yet so send it
SendRTTMsg(Route);
// No, it's the other end that must have an rrt response and we've just sent it
Route->Status |= SentOurRIF;
SendOurRIF(Route);
SendRIPToNeighbour(Route);
}
}
@ -931,6 +964,8 @@ VOID SendRTTMsg(struct ROUTE * Route)
struct _L3MESSAGEBUFFER * Msg;
char Stamp[50];
char Normcall[10];
unsigned char temp[256];
uint64_t sendTime;
Normcall[ConvFromAX25(Route->NEIGHBOUR_CALL, Normcall)] = 0;
@ -950,13 +985,25 @@ VOID SendRTTMsg(struct ROUTE * Route)
Msg->L4TXNO = 0;
Msg->L4FLAGS = L4INFO;
// The timestamp can possibly exceed 10 digits. INP3 only works on differece between send and received, so base can be reset safely.
sendTime = ((uint64_t)GetTickCount() - INP3timeLoadedMS) / 10; // 10mS units
if (sendTime > 9999999999)
sendTime = INP3timeLoadedMS = 0;
sprintf(Stamp, "%10llu %10d %10d %10d ", sendTime, Route->SRTT, Route->RTT, 0);
sprintf(Stamp, "%10llu %10d %10d %10d ", (GetTickCount() - timeLoadedMS), Route->SRTT/10, Route->RTT/10, 0);
memcpy(RTTMsg.TXTIME, Stamp, 44);
// We now allow MAXRTT and MAXHOPS to be reconfigured so should update header each time
sprintf(temp, "$M%d $N $H%d ", MAXRTT, MaxHops); // trailing spaces extend to ensure padding if the length of characters for MAXRTT changes.
memcpy(RTTMsg.FLAGS, temp, 20); // But still limit the actual characters copied.
memcpy(Msg->L4DATA, &RTTMsg, 236);
Msg->LENGTH = 256 + 1 + 7;
Msg->LENGTH = 256 + 1 + MSGHDDRLEN;
Route->Timeout = RTTTimeout;
@ -967,7 +1014,7 @@ VOID SendRTTMsg(struct ROUTE * Route)
Route->Status |= SentRTTRequest;
Debugprintf("INP3 Sending first RTT Msg to %s", Normcall);
if (DEBUGINP3) Debugprintf("INP3 Sending first RTT Msg to %s", Normcall);
}
@ -1031,12 +1078,13 @@ int BuildRIF(UCHAR * RIF, UCHAR * Call, UCHAR * Alias, int Hops, int RTT)
RIF[12+AliasLen] = 0;
RIFLen = 13 + AliasLen;
Debugprintf("INP3 sending RIF Entry %s:%s %d %d", AliasCopy, Normcall, Hops, RTT);
if (DEBUGINP3) Debugprintf("INP3 sending RIF Entry %s:%s %d %d", AliasCopy, Normcall, Hops, RTT);
return RIFLen;
}
RIF[10] = 0;
Debugprintf("INP3 sending RIF Entry %s %d %d", Normcall, Hops, RTT);
if (DEBUGINP3) Debugprintf("INP3 sending RIF Entry %s %d %d", Normcall, Hops, RTT);
return (11);
}
@ -1057,14 +1105,18 @@ VOID SendOurRIF(struct ROUTE * Route)
Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0;
Debugprintf("INP3 Sending Initial RIF to %s ", Normcall);
if (DEBUGINP3) Debugprintf("INP3 Sending Initial RIF to %s ", Normcall);
Msg->L3SRCE[0] = 0xff;
// send a RIF for our Node and all our APPLCalls
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], MYCALL, MYALIASTEXT, 1, 0);
if (Route->OldBPQ)
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], MYCALL, MYALIASTEXT, 1, Route->RTTIncrement * 10);
else
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], MYCALL, MYALIASTEXT, 1, Route->RTTIncrement);
totLen += RIFLen;
for (App = 0; App < NumberofAppls; App++)
@ -1073,7 +1125,11 @@ VOID SendOurRIF(struct ROUTE * Route)
if (APPL->APPLQUAL > 0)
{
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], APPL->APPLCALL, APPL->APPLALIAS_TEXT, 1, 0);
if (Route->OldBPQ)
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], APPL->APPLCALL, APPL->APPLALIAS_TEXT, 1, Route->RTTIncrement * 10);
else
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], APPL->APPLCALL, APPL->APPLALIAS_TEXT, 1, Route->RTTIncrement);
totLen += RIFLen;
}
}
@ -1126,24 +1182,30 @@ int SendRIPTimer()
// Delay more if Locked - they could be retrying for a long time
if ((Route->NEIGHBOUR_FLAG)) // LOCKED ROUTE
INP3Delay = 1200;
if (Route->ConnectionAttempts < 5)
INP3Delay = 30;
else
INP3Delay = 600;
{
if ((Route->NEIGHBOUR_FLAG)) // LOCKED ROUTE
INP3Delay = 300;
else
INP3Delay = 120;
}
if (Route->LastConnectAttempt &&
(REALTIMETICKS - Route->LastConnectAttempt) < INP3Delay)
if (Route->LastConnectAttempt && (REALTIMETICKS - Route->LastConnectAttempt) < INP3Delay)
{
Route++;
continue; // No room for link
continue; // Not yet
}
// Try to activate link
Route->ConnectionAttempts++;
if (Route->INP3Node)
{
Normcall[ConvFromAX25(Route->NEIGHBOUR_CALL, Normcall)] = 0;
Debugprintf("INP3 Activating link to %s", Normcall);
if (DEBUGINP3) Debugprintf("INP3 Activating link to %s", Normcall);
}
L2SETUPCROSSLINKEX(Route, 2); // Only try SABM twice
@ -1207,7 +1269,7 @@ int SendRIPTimer()
char Call [11] = "";
ConvFromAX25(Route->NEIGHBOUR_CALL, Call);
Debugprintf("BPQ32 INP3 Neighbour %s Lost", Call);
if (DEBUGINP3) Debugprintf("BPQ32 INP3 Neighbour %s Lost", Call);
Route->Status = 0; // Down
}
@ -1222,7 +1284,7 @@ int SendRIPTimer()
}
else
{
Route->BCTimer = RTTInterval;
Route->BCTimer = RTTInterval + rand() % 4;
Route->Retries = RTTRetries;
SendRTTMsg(Route);
}
@ -1261,7 +1323,7 @@ VOID SendRIF(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Msg)
Msg->LENGTH += MSGHDDRLEN + 1; // PID
Debugprintf("Sending INP3 RIF length %d to %s", Msg->LENGTH, Normcall);
if (DEBUGINP3) Debugprintf("Sending INP3 RIF length %d to %s", Msg->LENGTH, Normcall);
SendNetFrame(Route, Msg);
}
@ -1271,10 +1333,11 @@ VOID SendRIPToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_RO
struct _L3MESSAGEBUFFER * Msg;
int count, MaxRoutes = MAXNEIGHBOURS;
char Normcall[10];
int sendHops, sendTT;
Normcall[ConvFromAX25(axcall, Normcall)] = 0;
Debugprintf("INP3 SendRIPToOtherNeighbours for %s", Normcall);
if (DEBUGINP3) Debugprintf("INP3 SendRIPToOtherNeighbours for %s", Normcall);
for (count=0; count<MaxRoutes; count++)
{
@ -1282,20 +1345,32 @@ VOID SendRIPToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_RO
(Routes->Status) &&
(Routes != Entry->ROUT_NEIGHBOUR)) // Dont send to originator of route
{
sendHops = Entry->Hops + 1;
sendTT = Entry->SRTT + Entry->ROUT_NEIGHBOUR->RTTIncrement;
// send, but only if within their constraints
if ((Routes->RemoteMAXHOPS == 0 || Routes->RemoteMAXHOPS >= Entry->Hops) &&
(Routes->RemoteMAXRTT == 0 || Routes->RemoteMAXRTT >= Entry->SRTT || Entry->SRTT == 60000))
{
Msg = Routes->Msg;
if (Msg == NULL)
{
Normcall[ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall)] = 0;
Debugprintf("INP3 Building RIF to send to %s", Normcall);
if (DEBUGINP3) Debugprintf("INP3 Building RIF to send to %s", Normcall);
Msg = Routes->Msg = CreateRIFHeader(Routes);
}
if (Msg)
{
if (Routes->OldBPQ)
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH],
axcall, alias, Entry->Hops + 1, Entry->SRTT + Entry->ROUT_NEIGHBOUR->SRTT/10);
axcall, alias, sendHops, sendTT + 10);
else
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH],
axcall, alias, sendHops, sendTT);
if (Msg->LENGTH > 250 - 15)
// if (Msg->LENGTH > Routes->NBOUR_PACLEN - 11)
@ -1305,6 +1380,7 @@ VOID SendRIPToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_RO
}
}
}
}
Routes+=1;
}
}
@ -1315,11 +1391,12 @@ VOID SendRIPToNeighbour(struct ROUTE * Route)
struct DEST_LIST * Dest = DESTS;
struct INP3_DEST_ROUTE_ENTRY * Entry;
struct _L3MESSAGEBUFFER * Msg;
int sendHops, sendTT;
char Normcall[10];
Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0;
Debugprintf("INP3 Sending Our Table to %s ", Normcall);
if (DEBUGINP3) Debugprintf("INP3 Sending Our Table to %s ", Normcall);
Dest--;
@ -1331,10 +1408,17 @@ VOID SendRIPToNeighbour(struct ROUTE * Route)
Entry = &Dest->INP3ROUTE[0];
if (Entry->ROUT_NEIGHBOUR && Entry->Hops && Route != Entry->ROUT_NEIGHBOUR)
{
// Best Route not via this neighbour - send
// Best Route not via this neighbour - send, but only if within their constraints
sendHops = Entry->Hops + 1;
sendTT = Entry->SRTT + Entry->ROUT_NEIGHBOUR->RTTIncrement;
if ((Route->RemoteMAXHOPS == 0 || Route->RemoteMAXHOPS >= Entry->Hops) &&
(Route->RemoteMAXRTT == 0 || Route->RemoteMAXRTT >= Entry->SRTT || Entry->SRTT == 60000))
{
Msg = Route->Msg;
if (Msg == NULL)
@ -1343,9 +1427,10 @@ VOID SendRIPToNeighbour(struct ROUTE * Route)
if (Msg == NULL)
return;
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH],
Dest->DEST_CALL, Dest->DEST_ALIAS,
Entry->Hops + 1, Entry->SRTT + Entry->ROUT_NEIGHBOUR->SRTT/10);
if (Route->OldBPQ)
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], Dest->DEST_CALL, Dest->DEST_ALIAS, sendHops, sendTT * 10); // old bpq bug - send mS not 10 mS units
else
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], Dest->DEST_CALL, Dest->DEST_ALIAS, sendHops, sendTT);
if (Msg->LENGTH > 250 - 15)
{
@ -1354,6 +1439,7 @@ VOID SendRIPToNeighbour(struct ROUTE * Route)
}
}
}
}
if (Route->Msg)
{
SendRIF(Route, Route->Msg);
@ -1368,6 +1454,15 @@ VOID FlushRIFs()
for (count=0; count<MaxRoutes; count++)
{
// Make sure we've sent our local calls
if ((Routes->Status & GotRTTRequest) && (Routes->Status & GotRTTResponse) && ((Routes->Status & SentOurRIF) == 0))
{
Routes->Status |= SentOurRIF;
SendOurRIF(Routes);
SendRIPToNeighbour(Routes);
}
if (Routes->Msg)
{
char Normcall[10];
@ -1375,7 +1470,7 @@ VOID FlushRIFs()
Normcall[ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall)] = 0;
SendRIF(Routes, Routes->Msg);
Routes->Msg = NULL;
Debugprintf("INP3 Flushing RIF to %s", Normcall);
if (DEBUGINP3) Debugprintf("INP3 Flushing RIF to %s", Normcall);
}
Routes+=1;
}
@ -1426,7 +1521,7 @@ VOID SendNegativeInfo()
{
char call[11]="";
ConvFromAX25(Dest->DEST_CALL, call);
Debugprintf("INP3 Deleting Node %s", call);
if (DEBUGINP3) Debugprintf("INP3 Deleting Node %s", call);
REMOVENODE(Dest); // Clear buffers, Remove from Sorted Nodes chain, and zap entry
}
else
@ -1544,7 +1639,7 @@ VOID INP3TIMER()
}
UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, unsigned int msglen)
UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, int msglen)
{
char call[10];
int calllen;
@ -1585,7 +1680,9 @@ UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, unsigned int msglen)
msglen -= 10;
while (*ptr1 && msglen > 0)
// Process optional fields
while (*ptr1 && msglen > 0) // Have an option
{
len = *ptr1;
opcode = *(ptr1+1);
@ -1599,18 +1696,20 @@ UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, unsigned int msglen)
{
memcpy(&alias[6 - (len - 2)], ptr1+2, len-2); // Right Justiify
}
else
if (opcode == 1 && len < 8)
else if (opcode == 1 && len < 8)
{
memcpy(IP, ptr1+2, len-2);
}
ptr1 += len;
msglen -= len;
}
ptr2+=sprintf(ptr2, " %s:%s %d %4.2d\r", alias, call, hops, rtt);
ptr1++;
msglen--; // EOP
}
msglen--; // Over EOP
return ptr2;
}
return ptr2;
}

Binary file not shown.

View file

@ -45,6 +45,8 @@ extern VOID Q_ADD();
VOID __cdecl Debugprintf(const char * format, ...);
TRANSPORTENTRY * NRRSession;
int NRRID = 1; // Id to correlate requests and responses
/*
datagrams (and other things) to be transported in Netrom L3 frames.
@ -75,7 +77,9 @@ VOID NRRecordRoute(UCHAR * Buff, int Len)
{
UCHAR * BUFFER = GetBuff();
UCHAR * ptr1;
struct _MESSAGE * Msg;
struct _MESSAGE * Msg1;
time_t Now = time(NULL);
int ID = (Msg->L4TXNO << 8) | Msg->L4RXNO;
if (BUFFER == NULL)
return;
@ -84,7 +88,18 @@ VOID NRRecordRoute(UCHAR * Buff, int Len)
*ptr1++ = 0xf0; // PID
ptr1 += sprintf(ptr1, "NRR Response:");
if (BUFFER == NULL)
return;
ptr1 = &BUFFER[MSGHDDRLEN];
*ptr1++ = 0xf0; // PID
if (ID == NRRSession->NRRID)
ptr1 += sprintf(ptr1, "NRR Response in %d Secs:", (int)(Now - NRRSession->NRRTime));
else
ptr1 += sprintf(ptr1, "NRR Response:", (int)(Now - NRRSession->NRRTime));
Buff += 21 + MSGHDDRLEN;
Len -= (21 + MSGHDDRLEN);
@ -111,11 +126,11 @@ VOID NRRecordRoute(UCHAR * Buff, int Len)
Len = (int)(ptr1 - BUFFER);
Msg = (struct _MESSAGE *)BUFFER;
Msg1 = (struct _MESSAGE *)BUFFER;
Msg->LENGTH = Len;
Msg1->LENGTH = Len;
Msg->CHAIN = NULL;
Msg1->CHAIN = NULL;
C_Q_ADD(&NRRSession->L4TX_Q, (UINT *)BUFFER);
@ -183,11 +198,16 @@ VOID SendNRRecordRoute(struct DEST_LIST * DEST, TRANSPORTENTRY * Session)
Msg->L4ID = 1;
Msg->L4INDEX = 0;
Msg->L4FLAGS = 0;
Msg->L4TXNO = NRRID << 8;
Msg->L4RXNO = NRRID & 0xff;
memcpy(Msg->L4DATA, MYCALL, 7);
Msg->L4DATA[7] = Stream + 28;
Msg->LENGTH = 8 + 21 + MSGHDDRLEN;
Session->NRRTime = time(NULL);
Session->NRRID = NRRID++;
C_Q_ADD(&DEST->DEST_Q, Msg);
}

186
Bpq32.c
View file

@ -1180,7 +1180,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Fix processing of the Winlink API /account/exists response (82)
// Fix sending CTEXT to L4 connects to Node when FULL_CTEXT is not set
// Version 6.0.25.?
// Version 6.0.25.1 Sept 2025
// Fix 64 bit compatibility problems in SCSTracker and UZ7HO drivers
// Add Chat PACLEN config (5)
@ -1284,6 +1284,22 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Fix Webmail autorefresh extra threads problem (websock connection lost handling) (82)
// Fix overwriting application alias (83)
// Version 6.0.26.?
// Fix for compiling with gcc15 (2)
// Fix possble stuck L2 session caused by window being set to zero (3)
// Improvments to INP3 (4, 5)
// Add Node API /api/tcpqueues (5)
// Add sending link events to OARC API (disabled by default) (6)
// Fix possible program error in Telnet_Connected (7)
// Close links when program is closed down (7)
// Fix possible problem with deleting routes when using both NODES and INP3 routing on same link (7)
// Add Paula's Netromx (allows connects to different applications using Node call) (8)
// Add Netrom over TCP (8)
// Fix FRMR caused by sending SREJ when no frames outstanding (8)
#define CKernel
#include "Versions.h"
@ -1377,6 +1393,8 @@ void * HSMODEMExtInit(EXTPORTDATA * PortEntry);
void * FreeDataExtInit(EXTPORTDATA * PortEntry);
void * SIXPACKExtInit(EXTPORTDATA * PortEntry);
VOID RealCloseAllPrograms();
extern char * ConfigBuffer; // Config Area
VOID REMOVENODE(dest_list * DEST);
DllExport int ConvFromAX25(unsigned char * incall,unsigned char * outcall);
@ -1386,6 +1404,9 @@ VOID ADIFWriteFreqList();
void SaveAIS();
void initAIS();
void initADSB();
int CloseAllSessions();
int CloseAllLinks();
void NETROMTCPResolve();
extern BOOL ADIFLogEnabled;
@ -1393,6 +1414,8 @@ int CloseOnError = 0;
char UIClassName[]="UIMAINWINDOW"; // the main window class name
char ClosingClassName[]="CLOSING"; // the main window class name
HWND UIhWnd;
extern char AUTOSAVE;
@ -1445,6 +1468,7 @@ extern HWND hIPResWnd;
extern BOOL IPMinimized;
extern int NODESINPROGRESS;
extern int NODESToOnePort;
extern VOID * CURRENTNODE;
@ -1514,7 +1538,7 @@ extern char ReportDest[7];
extern UCHAR ConfigDirectory[260];
extern uint64_t timeLoadedMS;
extern uint64_t INP3timeLoadedMS;
VOID __cdecl Debugprintf(const char * format, ...);
VOID __cdecl Consoleprintf(const char * format, ...);
@ -1632,6 +1656,8 @@ BOOL IGateEnabled = TRUE;
extern int ISDelayTimer; // Time before trying to reopen APRS-IS link
extern int ISPort;
int CLOSING = 0;
UINT * WINMORTraceQ = NULL;
UINT * SetWindowTextQ = NULL;
@ -1687,6 +1713,8 @@ BOOL ReconfigFlag = FALSE;
BOOL RigReconfigFlag = FALSE;
BOOL APRSReconfigFlag = FALSE;
BOOL CloseAllNeeded = FALSE;
int CloseAllTimer = 0;
BOOL NeedWebMailRefresh = FALSE;
int AttachedPIDList[100] = {0};
@ -2191,6 +2219,8 @@ VOID TimerProcX()
Start();
NETROMTCPResolve();
INITIALISEPORTS(); // Restart Ports
SetApplPorts();
@ -2368,6 +2398,52 @@ VOID TimerProcX()
CheckGuardZone();
if (CloseAllTimer == 50) // First entry
{
if (CloseAllSessions() == 0)
{
if (CloseAllLinks() == 0) // No sessions closed so close links now
CloseAllTimer = 1; // No Links so close now
else
CloseAllTimer = 39; // ~4 secs for links to close
}
}
if (CloseAllTimer == 40) // First entry
CloseAllLinks(); // No sessions closed so close links now
if (CloseAllTimer)
{
// See if any links left
struct _LINKTABLE * LINK = LINKS;
int i = MAXLINKS;
if (CloseAllTimer == 0)
RealCloseAllPrograms();
while (i--)
{
if (LINK->LINKCALL[0])
{
break;
}
if (i == 0)
{
CloseAllTimer = 0;
RealCloseAllPrograms();
return;
}
LINK++;
continue;
}
CloseAllTimer--;
if(CloseAllTimer == 0)
RealCloseAllPrograms();
}
return;
}
@ -2403,7 +2479,7 @@ FirstInit()
EnumProcessesPtr = (FARPROCX)GetProcAddress(ExtDriver,"EnumProcesses");
}
timeLoadedMS = GetTickCount();
INP3timeLoadedMS = GetTickCount();
srand(time(NULL));
@ -2561,6 +2637,7 @@ Check_Timer()
WSAStartup(MAKEWORD(2, 0), &WsaData);
// Load Psapi.dll if possible
ExtDriver = LoadLibrary("Psapi.dll");
@ -2575,6 +2652,8 @@ Check_Timer()
Start();
NETROMTCPResolve();
INITIALISEPORTS();
OpenReportingSockets();
@ -2898,6 +2977,8 @@ BOOL APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReser
}
else
{
NETROMTCPResolve();
SetApplPorts();
GetUIConfig();
@ -5894,13 +5975,106 @@ DllExport VOID APIENTRY CreateNewTrayIcon()
trayMenu = NULL;
}
void hookNodeClosing(char * Reason);
BOOL CALLBACK ClosaAllProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_CTLCOLORDLG:
return (LONG)bgBrush;
case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC)wParam;
SetTextColor(hdcStatic, RGB(0, 0, 0));
SetBkMode(hdcStatic, TRANSPARENT);
return (LONG)bgBrush;
}
case WM_COMMAND:
return 0;
case WM_SYSCOMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId)
{
case SC_RESTORE:
return (DefWindowProc(hWnd, message, wParam, lParam));
case SC_MINIMIZE:
if (MinimizetoTray)
return ShowWindow(hWnd, SW_HIDE);
else
return (DefWindowProc(hWnd, message, wParam, lParam));
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_CLOSE:
return(DestroyWindow(hWnd));
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
HWND hwndClosing = NULL; // Window handle of dialog box
DllExport VOID APIENTRY CloseAllPrograms()
{
// HANDLE hProc;
WNDCLASS wc;
CLOSING = TRUE;
// Close all attached BPQ32 programs
// Tell BG to shut when all links are gone or after 5 secs
Closing = TRUE;
CloseAllTimer = 50;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = ClosaAllProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(BPQICON) );
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = bgBrush;
wc.lpszMenuName = NULL;
wc.lpszClassName = ClosingClassName;
RegisterClass(&wc);
hwndClosing = CreateDialog(hInstance, ClosingClassName, NULL, (DLGPROC)ClosaAllProc);
ShowWindow(hwndClosing, SW_SHOW);
}
VOID RealCloseAllPrograms()
{
hookNodeClosing("Shutdown");
Sleep(500);
Closing = 1;
ShowWindow(FrameWnd, SW_RESTORE);

413
Cmd.c
View file

@ -17,9 +17,7 @@ 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
@ -44,8 +42,6 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#include "tncinfo.h"
#include "telnetserver.h"
//#include "GetVersion.h"
//#define DllImport __declspec( dllimport )
@ -73,7 +69,8 @@ int seeifInterlockneeded(struct PORTCONTROL * PORT);
int CompareNode(const void *a, const void *b);
int CompareAlias(const void *a, const void *b);
int CompareRoutes(const void * a, const void * b);
void SendVARANetromNodes(struct TNCINFO * TNC, MESSAGE *Buffer);
VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST * Dest, BOOL Spy, int Service);
extern VOID KISSTX(struct KISSINFO * KISS, PMESSAGE Buffer);
@ -86,6 +83,7 @@ UCHAR SAVEDAPPLFLAGS = 0;
UCHAR ALIASINVOKED = 0;
extern int MONTOFILEFLAG;
VOID * CMDPTR = 0;
@ -132,6 +130,8 @@ int NOBUFFCOUNT = 0;
int BUFFERWAITS = 0;
int MAXDESTS = 0;
int NUMBEROFNODES = 0;
int L2CONNECTSOUT = 0;
int L2CONNECTSIN = 0;
int L4CONNECTSOUT = 0;
int L4CONNECTSIN = 0;
int L4FRAMESTX = 0;
@ -155,13 +155,15 @@ char * ALIASPTR = &CMDALIAS[0][0];
extern int RigReconfigFlag;
extern int DEBUGINP3;
extern int PREFERINP3ROUTES;
struct CMDX COMMANDS[];
int CMDXLEN = sizeof (struct CMDX);
VOID SENDNODESMSG();
VOID SENDNODESMSG(int Portnum);
VOID KISSCMD(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);
@ -187,6 +189,54 @@ VOID QTSMCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
/* Paula's NetROMX includes a service number in a CREQX message which allows a node to host lots of applications without
filling the Nodes table with SSID's
I could make these (or some of them) BPQ Commands but some will clash (eg INFO) or match an existing APPL (eg BBS)
I could use C APPL@CALL for an extended call to a node
Maybe I can detect APPL NODE so Paula's syntax will work
or both??
Standard Services are:
*/
struct NETROMX SERVICES[] = {
{0, "CMD"}, // Normal connection to Node's command line
{1, "INFO"}, // Standard Information server
{2, "PMS"}, // Personal Message System
{3, "BBS"}, // (reserved for Bulletin Board System)
{4, "DX"}, // (reserved for DX cluster/dx-spot feed)
{5, "TPP"}, // (reserved for "Tampa Ping-Pong" chat)
{7, "ECHO"}, // Echoes data back to sender
{8, "XRCHAT"}, // XRChat server
{9, "DISCARD"}, // Data sink
{10, "RMS"}, // (reserved for winlink RMS}
{11, "CHAT"}, // (reserved for BPQ chat server)
{13, "DAYTIME"}, // Local date/time (similar to RFC867)
{14, "APRS"}, // APRS Server
{15, "CUSTINF"},// (reserved for custom information file server)
{16, "WX"}, // Local weather information
{17, "TELEM"}, // (reserved for Telemetry server)
{18, "SMS"}, // Short Message System server
{19, "CHARGEN"},// Generates a test pattern
{20, "NDATA"}, // (reserved for NFTP extension)
{21, "NFTP"}, // Netrom File Transfer Protocol
{22, "NSSH"}, // (reserved for secure login - if legal?)
{23, "TELNET"}, // Normal L4 login (same as 0)
{25, "SMTP"}, // (reserved for Simple Mail Transfer Protocol)
{26, "MHEARD"}, // MHEARD server (shows MH lists)
{27, "DXLIST"}, // DX List server (shows DX lists)
{79, "FINGER"}, // Finger server
{80, "HTTP"}, // NetromWeb (HTTP over Netrom) server
{87, "NTTY"}, // Netrom TTY - Keyboard to keyboard chat
{1883, "MQTT"} // MQTT server
};
int NUMBEROFSSERVICES = sizeof(SERVICES)/sizeof(struct NETROMX);
char * __cdecl Cmdprintf(TRANSPORTENTRY * Session, char * Bufferptr, const char * format, ...)
{
@ -249,10 +299,81 @@ char * __cdecl Cmdprintf(TRANSPORTENTRY * Session, char * Bufferptr, const char
return Bufferptr + MsgLen;
}
VOID POLLNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{
int Portnum = atoi(CmdTail);
struct PORTCONTROL * PORT = 0;
MESSAGE * Buffer;
UCHAR * ptr1;
if (Portnum)
PORT = GetPortTableEntryFromPortNum(Portnum);
if (Portnum == 0 || PORT == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
if (PORT->PORTQUALITY == 0 || PORT->INP3ONLY)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Quality = 0 or INP3 Port\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
Buffer = GetBuff();
if (Buffer == 0)
return;
Buffer->PORT = Portnum;
memcpy(Buffer->ORIGIN, NETROMCALL, 7);
memcpy(Buffer->DEST, NODECALL, 7);
Buffer->ORIGIN[6] |= 0x61; // SET CMD END AND RESERVED BITS
Buffer->CTL = UI;
Buffer->PID = 0xCF; // Netrom
ptr1 = &Buffer->L2DATA[0];
*(ptr1++) = 0xfe; // Nodes Poll Flag
memcpy(ptr1, MYALIASTEXT, 6);
ptr1+= 6;
Buffer->LENGTH = (int)(ptr1 - (UCHAR *)Buffer);
if (PORT->TNC && PORT->TNC->Hardware == H_VARA)
SendVARANetromNodes(PORT->TNC, Buffer);
else
PUT_ON_PORT_Q(PORT, Buffer);
strcpy(Bufferptr, OKMSG);
Bufferptr += (int)strlen(OKMSG);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
}
VOID SENDNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{
SENDNODESMSG();
int Portnum = atoi(CmdTail);
struct PORTCONTROL * PORT;
if (Portnum)
{
PORT = GetPortTableEntryFromPortNum(Portnum);
if (PORT == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
}
SENDNODESMSG(Portnum);
strcpy(Bufferptr, OKMSG);
Bufferptr += (int)strlen(OKMSG);
@ -717,6 +838,108 @@ BOOL cATTACHTOBBS(TRANSPORTENTRY * Session, UINT Mask, int Paclen, int * AnySess
return FALSE;
}
void ConnecttoService(TRANSPORTENTRY * Session, char * Bufferptr, int ServiceIndex, char * Node, int Stay)
{
struct DEST_LIST * Dest = DESTS;
int n = MAXDESTS;
int gotDest = 0;
unsigned char axcall[7];
int Service = -1;
// Make Sure Node is Known
strcat(Node, " "); // Node table has 6 byte Aliases
while (n--)
{
if (memcmp(Dest->DEST_ALIAS, Node, 6) == 0)
{
gotDest = 1;
break;
}
Dest++;
}
if (gotDest == 0)
{
Dest = DESTS;
n = MAXDESTS;
ConvToAX25(Node, axcall);
while (n--)
{
if (CompareCalls(Dest->DEST_CALL, axcall))
{
gotDest = 1;
break;
}
Dest++;
}
}
strlop(Node, ' ');
if (gotDest == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Node %s not found\r", Node);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
Session->STAYFLAG = Stay;
Service = SERVICES[ServiceIndex].ServiceNo;
Bufferptr = Cmdprintf(Session, Bufferptr, "Connecting to Service %s on Node %s \r", SERVICES[ServiceIndex].ServiceName, Node);
DoNetromConnect(Session, Bufferptr, Dest, 0, Service);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
}
int checkifService(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{
char APPName[13];
int n = 12;
BOOL Stay = FALSE;
char * ptr, *Context;
int i;
char TailCopy[256];
strcpy(TailCopy, CmdTail);
ptr = strtok_s(TailCopy, " ", &Context);
// see if any param. if longer than two chars treat as remote node
if (ptr == 0 || strlen(ptr) < 3)
return 0;
memcpy(APPName, CMD->String, 13);
strlop(APPName, ' ');
if (Context && Context[0] == 'S')
Session->STAYFLAG = Stay;
// See if APPL is one of Paula's service
for (i = 0; i < NUMBEROFSSERVICES; i++)
{
if (strcmp(APPName, SERVICES[i].ServiceName) == 0)
{
ConnecttoService(Session, Bufferptr, i, ptr, Stay);
return 1;
}
}
return 0;
}
VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{
BOOL CONFAILED = 0;
@ -725,6 +948,7 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
char * ptr1, *ptr2;
int n = 12;
BOOL Stay = FALSE;
char * ptr, *Context;
// Copy Appl and Null Terminate
@ -743,12 +967,43 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
return;
}
ptr = strtok_s(CmdTail, " ", &Context);
if (CmdTail[0] == 'S')
Stay = TRUE;
// ptr is first param. Context is rest of string;
if (ptr)
{
// could be Node for NETROMX connect or S flag
int i;
if (strlen(ptr) > 1)
{
if (Context && Context[0] == 'S')
Session->STAYFLAG = Stay;
// See if APPL is one of Paula's service
for (i = 0; i < NUMBEROFSSERVICES; i++)
{
if (strcmp(APPName, SERVICES[i].ServiceName) == 0)
{
ConnecttoService(Session, Bufferptr, i, ptr, Stay);
return;
}
}
// Not a service that can be accessed remotely
Bufferptr = Cmdprintf(Session, Bufferptr, "Connection to %s on a remote node is not possible\r", APPName);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
else if (ptr[0] == 'S')
Session->STAYFLAG = Stay;
}
memcpy(Session->APPL, CMD->String, 12);
// SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND
@ -830,6 +1085,9 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
VOID CMDI00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{
if (checkifService(Session, Bufferptr, CmdTail, CMD)) // See can be used remotely
return;
Bufferptr = Cmdprintf(Session, Bufferptr, "%s", INFOMSG);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
}
@ -1300,6 +1558,17 @@ VOID CMDL00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct C
else
Bufferptr = Cmdprintf(Session, Bufferptr, " S=%d P=%d T=%d V=%d Q=%d\r",
LINK->L2STATE, LINK->LINKPORT->PORTNUMBER, LINK->LINKTYPE, 2 - LINK->VER1FLAG, Count);
if (Count > 16 || LINK->LINKWINDOW == 0)
{
// Dump Link State
int secs = time(NULL) - LINK->LASTFRAMESENT;
Bufferptr = Cmdprintf(Session, Bufferptr, " Debug Info: LINK->LINKNS %d LINK->LINKOWS %d SDTSLOT %d LINKWINDOW %d L2FLAGS %d\r", LINK->LINKNS, LINK->LINKOWS, LINK->SDTSLOT, LINK->LINKWINDOW, LINK->L2FLAGS);
Bufferptr = Cmdprintf(Session, Bufferptr, " Debug Info: Slots %x %x %x %x %x %x %x %x\r", LINK->FRAMES[0], LINK->FRAMES[1], LINK->FRAMES[2], LINK->FRAMES[3],
LINK->FRAMES[4], LINK->FRAMES[5], LINK->FRAMES[6], LINK->FRAMES[7]);
}
}
LINK++;
}
@ -1622,8 +1891,8 @@ char * DisplayRoute(TRANSPORTENTRY * Session, char * Bufferptr, struct ROUTE *
if (Routes->INP3Node) // INP3 Enabled?
{
double srtt = Routes->SRTT/1000.0;
double nsrtt = Routes->NeighbourSRTT/1000.0;
double srtt = Routes->SRTT/100.0;
double nsrtt = Routes->NeighbourSRTT/100.0;
Bufferptr = Cmdprintf(Session, Bufferptr, " %4.2fs %4.2fs", srtt, nsrtt);
}
@ -2144,7 +2413,7 @@ TRANSPORTENTRY * SetupNewSession(TRANSPORTENTRY * Session, char * Bufferptr)
}
VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST * Dest, BOOL Spy)
VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST * Dest, BOOL Spy, int Service)
{
TRANSPORTENTRY * NewSess;
@ -2153,6 +2422,8 @@ VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIS
if (NewSess == NULL)
return; // Tables Full
NewSess->Service = Service;
NewSess->L4CIRCUITTYPE = SESSION + DOWNLINK;
NewSess->L4TARGET.DEST = Dest;
@ -2160,15 +2431,41 @@ VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIS
NewSess->SPYFLAG = Spy;
if (Service == -1)
ReleaseBuffer((UINT *)REPLYBUFFER);
SENDL4CONNECT(NewSess);
SENDL4CONNECT(NewSess, Service);
L4CONNECTSOUT++;
return;
}
BOOL CheckLink(UCHAR * LinkCall, UCHAR * OurCall, int Port)
{
// Check if a link exists betwwn a pair of calls on a port. Return TRUE if found
struct _LINKTABLE * LINK = LINKS;
int n = MAXLINKS;
while (n--)
{
if (LINK->LINKCALL[0] == 0) // Spare
{
LINK++;
continue;
}
if ((LINK->LINKPORT->PORTNUMBER == Port) && CompareCalls(LINK->LINKCALL, LinkCall) && CompareCalls(LINK->OURCALL, OurCall))
return TRUE;
LINK++;
}
// ENTRY NOT FOUND
return FALSE;
}
BOOL FindLink(UCHAR * LinkCall, UCHAR * OurCall, int Port, struct _LINKTABLE ** REQLINK)
{
struct _LINKTABLE * LINK = LINKS;
@ -2194,6 +2491,7 @@ BOOL FindLink(UCHAR * LinkCall, UCHAR * OurCall, int Port, struct _LINKTABLE **
LINK++;
}
// ENTRY NOT FOUND - FIRSTSPARE HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL
*REQLINK = FIRSTSPARE;
@ -2224,6 +2522,9 @@ VOID CMDC00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct C
char PortString[10];
char cmdCopy[256];
struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)PORT;
int Service = -1;
int haveService = 0;
int i = 0;
#ifdef EXCLUDEBITS
@ -2370,6 +2671,7 @@ NoPort:
// SEE IF CALL TO ANY OF OUR HOST SESSIONS - UNLESS DIGIS SPECIFIED
// if (axcalls[7] == 0 && axcalls[9])
if (axcalls[7] == 0)
{
// If this connect is as a result of a command alias, don't check appls or we will loop
@ -2388,6 +2690,9 @@ NoPort:
// Convert to an APPL command, so any alias is actioned
memcpy(Session->APPL,APPL->APPLCMD, 12);
// SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND
if (APPL->APPLHASALIAS && APPL->APPLALIASVAL[0] != 0x20)
@ -2418,7 +2723,33 @@ NoPort:
}
}
if (axcalls[7] == 0)
// if no digis see if connect to known node.
// But now could have a single numeric param as a service number (Paula's Netromx)
// cmdCopy is command tail (after call)
// Make sure field is numeric
if (cmdCopy[0] != ' ')
{
i = 0;
while (cmdCopy[i] >= '0' && cmdCopy[i]<= '9')
i++;
if (cmdCopy[i] != ' ')
goto Downlink;
else
{
if (i > 0) // Some digits
{
haveService = 1;
Service = atoi(cmdCopy);
}
}
}
if (axcalls[7] == 0 || haveService)
{
// SEE IF CALL TO ANOTHER NODE
@ -2431,7 +2762,7 @@ NoPort:
{
if (memcmp(Dest->DEST_ALIAS, TextCall, 6) == 0)
{
DoNetromConnect(Session, Bufferptr, Dest, Spy);
DoNetromConnect(Session, Bufferptr, Dest, Spy, Service);
return;
}
Dest++;
@ -2445,7 +2776,7 @@ NoPort:
{
if (CompareCalls(Dest->DEST_CALL, axcalls))
{
DoNetromConnect(Session, Bufferptr, Dest, Spy);
DoNetromConnect(Session, Bufferptr, Dest, Spy, Service);
return;
}
Dest++;
@ -2939,7 +3270,7 @@ char * DoOneNode(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST *
if (Neighbour)
{
double srtt = Route->SRTT/1000.0;
double srtt = Route->SRTT/100.0;
len = ConvFromAX25(Neighbour->NEIGHBOUR_CALL, Normcall);
Normcall[len] = 0;
@ -2988,7 +3319,7 @@ int DoINP3ViaEntry(struct DEST_LIST * Dest, int n, char * line, int cursor)
if (Dest->INP3ROUTE[n].ROUT_NEIGHBOUR != 0)
{
srtt = Dest->INP3ROUTE[n].SRTT/1000.0;
srtt = Dest->INP3ROUTE[n].SRTT/100.0;
len=ConvFromAX25(Dest->INP3ROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Portcall);
Portcall[len]=0;
@ -3608,6 +3939,8 @@ VOID MHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CM
int len;
char Digi = 0;
if (checkifService(Session, Bufferptr, CmdTail, CMD)) // See can be used remotely
return;
// Note that the MHDIGIS field may contain rubbish. You have to check End of Address bit to find
// how many digis there are
@ -4258,6 +4591,7 @@ struct CMDX COMMANDS[] =
"RIGRECONFIG ",8, &RIGRECONFIG, 0,
"RESTART ",7, &RESTART,0,
"RESTARTTNC ",10,&RESTARTTNC,0,
"POLLNODES ",8, &POLLNODES,0,
"SENDNODES ",8, &SENDNODES,0,
"EXTRESTART ",10, EXTPORTVAL, offsetof(EXTPORTDATA, EXTRESTART),
"TXDELAY ",3, PORTVAL, offsetof(PORTCONTROLX, PORTTXDELAY),
@ -4275,6 +4609,10 @@ struct CMDX COMMANDS[] =
"MAXUSERS ",4,PORTVAL, offsetof(PORTCONTROLX, USERS),
"L3ONLY ",6,PORTVAL, offsetof(PORTCONTROLX, PORTL3FLAG),
"BBSALIAS ",4,PORTVAL, offsetof(PORTCONTROLX, PORTBBSFLAG),
"INP3ONLY ",8,PORTVAL, offsetof(PORTCONTROLX, INP3ONLY),
"ALLOWINP3 ",9,PORTVAL, offsetof(PORTCONTROLX, ALLOWINP3),
"ENABLEINP3 ",10,PORTVAL, offsetof(PORTCONTROLX, ENABLEINP3),
"MONTOFILE ",9,SWITCHVAL,(size_t)&MONTOFILEFLAG,
"VALIDCALLS ",5,VALNODES,0,
"WL2KSYSOP ",5,WL2KSYSOP,0,
"STOPPORT ",4,STOPPORT,0,
@ -4286,6 +4624,7 @@ struct CMDX COMMANDS[] =
"KISS ",4,KISSCMD,0,
"GETPORTCTEXT",9,GetPortCTEXT, 0,
#ifdef EXCLUDEBITS
"EXCLUDE ",4,ListExcludedCalls,0,
@ -4310,6 +4649,11 @@ struct CMDX COMMANDS[] =
"L4DELAY ",7,SWITCHVAL,(size_t)&L4DELAY,
"L4WINDOW ",6,SWITCHVAL,(size_t)&L4DEFAULTWINDOW,
"BTINTERVAL ",5,SWITCHVAL,(size_t)&BTINTERVAL,
"DEBUGINP3 ",8,SWITCHVAL,(size_t)&DEBUGINP3,
"MAXHOPS ",7,SWITCHVAL,(size_t)&MaxHops,
"PREFERINP3 ",10,SWITCHVAL,(size_t)&PREFERINP3ROUTES,
"MAXRTT ",6,SWITCHVALW,(size_t)&MAXRTT,
"MAXTT ",6,SWITCHVALW,(size_t)&MAXRTT,
"PASSWORD ", 8, PWDCMD, 0,
"************", 12, APPLCMD, 0,
@ -4343,7 +4687,7 @@ struct CMDX COMMANDS[] =
"************", 12, APPLCMD, 0,
"************", 12, APPLCMD, 0,
"************", 12, APPLCMD, 0,
"************", 12, APPLCMD, 0, // Apppl 32 is internal Terminal
"************", 12, APPLCMD, 0, // Apppl 32 is internal Terminal on Windows
"*** LINKED ",10,LINKCMD,0,
"CQ ",2,CQCMD,0,
"CONNECT ",1,CMDC00,0,
@ -4736,6 +5080,8 @@ VOID DoTheCommand(TRANSPORTENTRY * Session)
struct DATAMESSAGE * Buffer = REPLYBUFFER;
char * ptr1, * ptr2;
int n;
int i, Service = -1;
char * Cmd, *Node, *Context;
ptr1 = &COMMANDBUFFER[0]; //
@ -4827,6 +5173,31 @@ VOID DoTheCommand(TRANSPORTENTRY * Session)
CMD++;
}
// See if a NETROMX Service
Cmd = strtok_s(ptr1, " ", &Context);
Node = strtok_s(NULL, " ", &Context);
for (i = 0; i < NUMBEROFSSERVICES; i++)
{
if (strcmp(Cmd, SERVICES[i].ServiceName) == 0)
{
int Stay = 0;
if (Context && Context[0] == 'S')
Session->STAYFLAG = Stay;
if (Node)
{
ConnecttoService(Session, ReplyPointer, i, Node, Stay);
return;
}
// Connecting to service on local node - msy be possible sometime
}
}
Session->BADCOMMANDS++;
if (Session->BADCOMMANDS > 6) // TOO MANY ERRORS

View file

@ -49,6 +49,12 @@ extern struct CONFIGTABLE xxcfg;
#endif
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
struct TNCINFO * TNCInfo[71]; // Records are Malloc'd
extern int ReportTimer;
@ -69,6 +75,7 @@ void printStack(void);
char * FormatMH(PMHSTRUC MH, char Format);
void WriteConnectLog(char * fromCall, char * toCall, UCHAR * Mode);
void SendDataToPktMap();
void NETROMTCPResolve();
extern BOOL LogAllConnects;
extern BOOL M0LTEMap;
@ -79,6 +86,7 @@ extern VOID * ENDBUFFERPOOL;
extern int PoolBuilt;
extern int EnableOARCAPI;
// Read/Write length field in a buffer header
@ -3313,8 +3321,12 @@ SOCKADDR_IN reportdest = {0};
SOCKET ReportSocket = 0;
SOCKET NodeAPISocket = 0 ;
SOCKADDR_IN Chatreportdest = {0};
SOCKADDR_IN UDPreportdest = {0};
extern char LOCATOR[]; // Locator for Reporting - may be Maidenhead or LAT:LON
extern char MAPCOMMENT[]; // Locator for Reporting - may be Maidenhead or LAT:LON
extern char LOC[7]; // Maidenhead Locator for Reporting
@ -3670,11 +3682,22 @@ pthread_t ResolveUpdateThreadId = 0;
char NodeMapServer[80] = "update.g8bpq.net";
char ChatMapServer[80] = "chatupdate.g8bpq.net";
char NodeAPIServer[80] = "node-api.packet.oarc.uk";
int NodeAPIPort = 13579;
int nodeStartedSent = 0;
extern time_t LastNodeStatus;
void hookNodeStarted();
VOID ResolveUpdateThread(void * Unused)
{
struct hostent * HostEnt1;
struct hostent * HostEnt2;
struct hostent * HostEnt3;
ResolveUpdateThreadId = GetCurrentThreadId();
@ -3702,14 +3725,29 @@ VOID ResolveUpdateThread(void * Unused)
if (HostEnt2)
memcpy(&Chatreportdest.sin_addr.s_addr,HostEnt2->h_addr,4);
if (HostEnt1 && HostEnt2)
Debugprintf("Resolving %s", NodeAPIServer);
HostEnt3 = gethostbyname(NodeAPIServer);
if (HostEnt3)
{
Sleep(1000 * 60 * 30);
continue;
memcpy(&UDPreportdest.sin_addr.s_addr,HostEnt3->h_addr,4);
if (nodeStartedSent == 0)
{
hookNodeStarted();
nodeStartedSent = 1;
LastNodeStatus = time(NULL);
}
}
Debugprintf("Resolve Failed for update.g8bpq.net or chatmap.g8bpq.net");
Sleep(1000 * 60 * 5);
NETROMTCPResolve();
if (HostEnt1 && HostEnt2)
{
Sleep(1000 * 60 * 15);
continue;
}
}
}
@ -5194,14 +5232,14 @@ skipit:
}
}
void SendDataToPktMapThread();
void SendDataToPktMapThread(void * Param);
void SendDataToPktMap()
{
_beginthread(SendDataToPktMapThread,2048000,0);
}
void SendDataToPktMapThread()
void SendDataToPktMapThread(void * Param)
{
char Return[256] = "";
char Request[64];

View file

@ -578,6 +578,7 @@ int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;

1029
Events.c

File diff suppressed because it is too large Load diff

View file

@ -36,6 +36,12 @@ extern int (WINAPI FAR *EnumProcessesPtr)();
#include "bpq32.h"
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
@ -819,7 +825,7 @@ pollloop:
char outbuff[1000];
int newlen;
buff->L2DATA[-1] = 6; // KISS Control
buff->PID = 6; // KISS Control (PID is just before Data)
newlen = KissEncode(&buff->L2DATA[-1], outbuff, txlen);
sendto(TNC->TCPDataSock, outbuff, newlen, 0, (struct sockaddr *)&TNC->Datadestaddr, sizeof(struct sockaddr));

View file

@ -43,6 +43,11 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
int KillTNC(struct TNCINFO * TNC);
static int RestartTNC(struct TNCINFO * TNC);
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
extern int (WINAPI FAR *GetModuleFileNameExPtr)();
extern int (WINAPI FAR *EnumProcessesPtr)();
static int Socket_Data(int sock, int error, int eventcode);

View file

@ -426,7 +426,7 @@ VOID ChatExpandAndSendMessage(ChatCIRCUIT * conn, char * Msg, int LOG)
len = RemoveLF(NewMessage, (int)strlen(NewMessage));
ChatWriteLogLine(conn, '>', NewMessage, len, LOG);
ChatWriteLogLine(conn, '>', NewMessage, len, LOG_CHAT);
ChatQueueMsg(conn, NewMessage, len);
}

View file

@ -50,6 +50,19 @@ BEGIN
LTEXT "Enable IGate",IDC_STATIC,5,2,49,10
END
CLOSING DIALOG DISCARDABLE 300, 300, 200, 50
STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU |
WS_THICKFRAME
CAPTION "BPQ32 Close All"
CLASS "CLOSING"
FONT 8, "Fixedsys"
BEGIN
LTEXT "Closing Links - Please wait....",IDC_BACKGROUND,22,20,337,273
END
CONFIG DIALOGEX 249, 200, 160, 118
STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION
EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE

260
L2Code.c
View file

@ -64,7 +64,7 @@ VOID L2SENDRESPONSE(struct _LINKTABLE * LINK, int CMD);
VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD);
VOID ACKMSG(struct _LINKTABLE * LINK);
VOID InformPartner(struct _LINKTABLE * LINK, int Reason);
UINT RR_OR_RNR(struct _LINKTABLE * LINK);
UINT RR_OR_RNR(struct _LINKTABLE * LINK, int CMD);
VOID L2TIMEOUT(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT);
VOID CLEAROUTLINK(struct _LINKTABLE * LINK);
VOID SENDFRMR(struct _LINKTABLE * LINK);
@ -99,6 +99,7 @@ VOID L2SENDXID(struct _LINKTABLE * LINK);
VOID __cdecl Debugprintf(const char * format, ...);
VOID Q_IP_MSG(MESSAGE * Buffer);
VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT);
VOID PROCESSNODESPOLL(struct PORTCONTROL * PORT);
VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG);
BOOL CompareAliases(UCHAR * c1, UCHAR * c2);
VOID L2FORUS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG);
@ -120,11 +121,18 @@ int CheckKissInterlock(struct PORTCONTROL * MYPORT, int Exclusive);
void hookL2SessionAccepted(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
void hookL2SessionDeleted(struct _LINKTABLE * LINK);
void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
void hookL2SessionConnected(struct _LINKTABLE * LINK);
int L2Compressit(unsigned char * Out, int OutSize, unsigned char * In, int Len);
VOID DeleteINP3Routes(struct ROUTE * Route);
VOID SendRTTMsg(struct ROUTE * Route);
void hookL2SessionStatus(struct _LINKTABLE * LINK);
void hookL2SessionClosed(struct _LINKTABLE * LINK, char * Reason, char * Direction);
int NETROMOpenConnection(struct ROUTE * Route);
extern int REALTIMETICKS;
int linkStatusInterval = 300; // 5 mins
// MSGFLAG contains CMD/RESPONSE BITS
#define CMDBIT 4 // CURRENT MESSAGE IS A COMMAND
@ -139,6 +147,7 @@ extern int REALTIMETICKS;
extern int L2Compress;
extern int L2CompMaxframe;
extern int L2CompPaclen;
extern BOOL CLOSING;
UCHAR NO_CTEXT = 0;
UCHAR ALIASMSG = 0;
@ -446,6 +455,8 @@ TRYBBS:
{
ALIASMSG = 0;
strcpy(LINK->ApplName, APPL->APPLCMD);
if (CompareCalls(Buffer->DEST, APPL->APPLCALL))
goto FORUS;
@ -479,9 +490,9 @@ NOWTRY_NODES:
if (CompareCalls(Buffer->DEST, NODECALL))
{
if (Buffer->L2DATA[0] == 0xff) // Valid NODES Broadcast
{
PROCESSNODEMESSAGE(Buffer, PORT);
}
else if (Buffer->L2DATA[0] == 0xfe) // Paula's NODES Poll (request Nodes broadcast on port)
PROCESSNODESPOLL(PORT);
}
ReleaseBuffer(Buffer);
@ -808,7 +819,15 @@ VOID L2FORUS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buff
if (CTLlessPF == XID)
{
// We could possibly get an XID response if packet is badly delayed and we had timed out
if ((MSGFLAG & CMDBIT)) // Command
ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG);
else
{
Debugprintf("Unexpected XID response with no session");
ReleaseBuffer(Buffer); // Ignore if not
}
return;
}
@ -929,6 +948,7 @@ VOID ProcessXIDCommand(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESS
LINK->L2STATE = 1; // XID received
LINK->Ver2point2 = TRUE; // Must support 2.2 if sent XID
LINK->L2TIME = PORT->PORTT1;
LINK->LINKWINDOW = PORT->PORTWINDOW; // Just in case!
LINK->LINKPORT = PORT;
@ -1067,6 +1087,7 @@ VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE *
if (CTLlessPF == DISC)
{
InformPartner(LINK, NORMALCLOSE); // SEND DISC TO OTHER END
hookL2SessionClosed(LINK, "Normal", "In");
CLEAROUTLINK(LINK);
L2SENDUA(PORT, Buffer, ADJBUFFER);
@ -1076,25 +1097,47 @@ VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE *
return;
}
if (CTLlessPF == XID)
{
// XID command or response on active session.
// if Command and state = 2 then other end missed XID Response. Process command again
if ((MSGFLAG & CMDBIT))
{
if (LINK->L2STATE == 2)
{
// I think we can just process as normal.
ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG);
return;
}
if (LINK->L2STATE == 1) // We've just sent XID so is probably XID Collision
{
// I think we can just process as normal. If we don't send a response the other end may not switch to 2.2
ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG);
return;
}
// XID Command on active session. Other end may be restarting. Reset session
InformPartner(LINK, NORMALCLOSE); // SEND DISC TO OTHER END
LINK->CIRCUITPOINTER = 0;
// I think it is safer to ignore it. The retry will be processed normally as XID command with no session
ReleaseBuffer(Buffer);
return;
}
// XID Response
// if Link State = 1 this is a normal response. Check it then send SABM
if (LINK->L2STATE == 1)
{
// XID State. Should be XID response if 2.2 ok or DM/FRMR if not
if (MSGFLAG & RESP)
{
if (CTLlessPF == DM || CTLlessPF == FRMR)
{
// Doesn't support XID - Send SABM
LINK->L2STATE = 2;
LINK->Ver2point2 = FALSE;
LINK->L2TIMER = 1; // Use retry to send SABM
}
else if (CTLlessPF == XID)
{
// Process response to make sure ok, Send SABM or DISC
LINK->L2STATE = 2;
LINK->Ver2point2 = TRUE;// Must support 2.2 if responded to XID
@ -1139,25 +1182,44 @@ VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE *
}
LINK->LINKWINDOW = PORT->PORTWINDOW; // Just in case!
LINK->L2TIMER = 1; // Use retry to send SABM
}
ReleaseBuffer(Buffer);
return;
}
// Command on existing session. Could be due to other end missing
// the XID response, so if XID just resend response
// XID response, not in state 1.
// This "shouldn't happen"
Debugprintf("Unexpected XID response, State = %d", LINK->L2STATE);
// Discard
ReleaseBuffer(Buffer);
return;
}
if (CTLlessPF == XID && (MSGFLAG & CMDBIT))
{
// XID Command on active session. Other end may be restarting. Send Response
ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG);
// Not XID
// if state = 1 then unexpected response to XID
if (LINK->L2STATE == 1)
{
if (CTLlessPF == DM || CTLlessPF == FRMR)
{
// Doesn't support XID - Send SABM
LINK->L2STATE = 2;
LINK->Ver2point2 = FALSE;
LINK->L2TIMER = 1; // Use retry to send SABM
ReleaseBuffer(Buffer);
return;
}
}
if (CTLlessPF == SABM)
@ -1221,9 +1283,13 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
int CONERROR;
struct ROUTE * ROUTE = NULL;
char toCall[12], fromCall[12];
if (CLOSING)
{
L2SENDDM(PORT, Buffer, ADJBUFFER);
return;
}
if (LINK == 0) // NO LINK ENTRIES - SEND DM RESPONSE
{
@ -1288,6 +1354,16 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
Debugprintf("INP3 Incoming connect from %s", fromCall);
DeleteINP3Routes(ROUTE);
}
else
{
if (PORT->ENABLEINP3)
{
// We will offer INP3 by sending an RTT probe.
SendRTTMsg(ROUTE);
}
}
}
if (NO_CTEXT == 1)
@ -1388,6 +1464,8 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
return;
}
strcpy(Session->APPL, LINK->ApplName);
// NOW TRY A BBS CONNECT
// IF APPL CONNECT, SEE IF APPL HAS AN ALIAS
@ -1772,6 +1850,16 @@ BOOL InternalL2SETUPCROSSLINK(PROUTE ROUTE, int Retries)
struct PORTCONTROL * PORT;
int FRACK;
// If it is NETROM Over TCP then check for existing connection
if (ROUTE->TCPPort)
{
if (strcmp(ROUTE->TCPHost, "0.0.0.0") == 0) // listening connection so wait for other end to connect
return FALSE;
return NETROMOpenConnection(ROUTE);
}
if (FindLink(ROUTE->NEIGHBOUR_CALL, NETROMCALL, ROUTE->NEIGHBOUR_PORT, &LINK))
{
// SESSION ALREADY EXISTS
@ -1983,19 +2071,32 @@ VOID L2_PROCESS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * B
if (FindNeighbour(Buffer->ORIGIN, PORT->PORTNUMBER, &ROUTE))
{
ROUTE->ConnectionAttempts = 0; // Reset counter
if (ROUTE->INP3Node)
{
Debugprintf("INP3 Route to %s connected", fromCall);
}
else
{
if (PORT->ENABLEINP3)
{
// We will offer INP3 by sending an RTT probe.
SendRTTMsg(ROUTE);
}
}
}
hookL2SessionConnected(LINK);
SendL2ToMonMap(PORT, fromCall, '+', 'O');
LINK->L2STATE = 5;
LINK->L2TIMER = 0; // CANCEL TIMER
LINK->L2RETRIES = 0;
LINK->L2SLOTIM, T3; // SET FRAME SENT RECENTLY
LINK->L2SLOTIM = T3; // SET FRAME SENT RECENTLY
// IF VERSION 1 MSG, SET FLAG
@ -2015,6 +2116,8 @@ VOID L2_PROCESS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * B
if (LINK->L2STATE == 4) // DISCONNECTING?
{
InformPartner(LINK, NORMALCLOSE); // SEND DISC TO OTHER END
hookL2SessionClosed(LINK, "Normal", "Out");
CLEAROUTLINK(LINK);
if (PORT->TNC && PORT->TNC->Hardware == H_KISSHF)
@ -2177,6 +2280,13 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
MESSAGE * Msg;
MESSAGE * Buffer;
// it shouldn't be possible to get srej when all are acked (NS = Link->NS) but just in case...
if (NS == LINK->LINKNS)
{
Debugprintf ("SREJ for our NS");
goto treatasRR;
}
LINK->L2FLAGS &= ~POLLSENT; // CLEAR I(P) or RR(P) SET
Msg = LINK->FRAMES[NS]; // is frame available?
@ -2236,6 +2346,9 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
LINK->L2TIMER = ONEMINUTE; // (RE)SET TIMER
LINK->framesResent++;
PORT = LINK->LINKPORT;
if (PORT)
@ -2254,6 +2367,9 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
return;
}
treatasRR:
// VALID RR/RNR RECEIVED
LINK->L2FLAGS &= ~RNRSET; //CLEAR RNR
@ -2274,7 +2390,7 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
if (LINK->LAST_F_TIME + 15 > REALTIMETICKS)
return; // DISCARD
CTL = RR_OR_RNR(LINK);
CTL = RR_OR_RNR(LINK, FALSE); // Sending response
CTL |= LINK->LINKNR << 5; // SHIFT N(R) TO TOP 3 BITS
CTL |= PFBIT;
@ -2339,6 +2455,20 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
LINK->L2FLAGS &= ~POLLSENT; // CLEAR I(P) or RR(P) SET
// ?? is this the place to do RTT?
if (LINK->lastPSent)
{
int RTT = GetTickCount() - LINK->lastPSent;
if (LINK->RTT)
LINK->RTT = ((LINK->RTT * 90) / 100) + RTT /10; // Smooth - 90% of old + 10% of new
else
LINK->RTT = RTT;
LINK->lastPSent = 0;
}
if ((CTL & 0xf) == RNR)
{
// Dont Clear timer on receipt of RNR(F), spec says should poll for clearing of busy,
@ -2586,6 +2716,7 @@ VOID PROC_I_FRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE *
LINK->bytesRXed += Length;
LINK->Received += Length - 1; // Exclude PID
LINK->framesRXed++;
// Adjust for DIGIS
@ -2813,6 +2944,8 @@ VOID RESETNS(struct _LINKTABLE * LINK, UCHAR NS)
{
int Resent = (LINK->LINKNS - NS) & 7; // FRAMES TO RESEND
LINK->framesResent += Resent;
LINK->LINKNS = NS; // RESET N(S)
if (LINK->LINKTYPE == 3) // mode-Node
@ -2981,9 +3114,9 @@ VOID SDETX(struct _LINKTABLE * LINK)
// **** Debug code **** look for stuck links
if (LINK->LASTFRAMESENT && (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs
if (LINK->LINKWINDOW == 0 || LINK->LASTFRAMESENT == 0 || (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs
{
if (COUNT_AT_L2(LINK) > 16)
if (COUNT_AT_L2(LINK) > 16 || LINK->LINKWINDOW == 0)
{
// Dump Link State
@ -3036,6 +3169,11 @@ VOID SDETX(struct _LINKTABLE * LINK)
LINK->LASTFRAMESENT = time(NULL);
LINK->LASTSENTQCOUNT = COUNT_AT_L2(LINK);
if (LINK->LASTSENTQCOUNT > LINK->maxQueued)
LINK->maxQueued = LINK->LASTSENTQCOUNT;
if (LINK->LASTSENTQCOUNT > LINK->intervalMaxQueued)
LINK->intervalMaxQueued = LINK->LASTSENTQCOUNT;
if (LINK->AllowCompress && Msg->LENGTH > 20 && LINK->TX_Q && Msg->PID == 240) // if short and no more not worth trying compression
{
@ -3162,6 +3300,10 @@ VOID SDETX(struct _LINKTABLE * LINK)
LINK->SDTSLOT ++;
LINK->SDTSLOT &= 7;
LINK->framesTXed++;
LINK->bytesTXed += sendLen;
compdata += sendLen;
complen -= sendLen;
}
@ -3174,6 +3316,9 @@ VOID SDETX(struct _LINKTABLE * LINK)
LINK->FRAMES[LINK->SDTSLOT] = Msg;
LINK->SDTSLOT ++;
LINK->SDTSLOT &= 7;
LINK->framesTXed++;
LINK->bytesTXed += (Msg->LENGTH - (MSGHDDRLEN + 1));
}
}
@ -3231,6 +3376,7 @@ VOID SDETX(struct _LINKTABLE * LINK)
// FLAG BUFFER TO CAUSE TIMER TO BE RESET AFTER SEND (or ACK if ACKMODE)
Buffer->Linkptr = LINK;
LINK->lastPSent = GetTickCount();
}
}
@ -3272,6 +3418,7 @@ VOID L2TimerProc()
int i = MAXLINKS;
struct _LINKTABLE * LINK = LINKS;
struct PORTCONTROL * PORT = PORTTABLE;
time_t Now = time(NULL);
while (i--)
{
@ -3281,6 +3428,12 @@ VOID L2TimerProc()
continue;
}
// Check for Status report time
if (LINK->lastStatusSentTime && (Now - LINK->lastStatusSentTime) > linkStatusInterval)
hookL2SessionStatus(LINK);
// CHECK FOR TIMER EXPIRY OR BUSY CLEARED
PORT = LINK->LINKPORT;
@ -3316,7 +3469,7 @@ VOID L2TimerProc()
{
// Was busy
if (RR_OR_RNR(LINK) != RNR) // SEE IF STILL BUSY
if (RR_OR_RNR(LINK, 0) != RNR) // SEE IF STILL BUSY
{
// Not still busy - tell other end
@ -3432,7 +3585,7 @@ VOID SendSupervisCmd(struct _LINKTABLE * LINK)
LINK->L2ACKREQ = 0; // CLEAR ACK NEEDED
CTL = RR_OR_RNR(LINK);
CTL = RR_OR_RNR(LINK, TRUE);
// MOV L2STATE[EBX],5 ; CANCEL REJ - ACTUALLY GOING TO 'PENDING ACK'
@ -3450,7 +3603,7 @@ void SEND_RR_RESP(struct _LINKTABLE * LINK, UCHAR PF)
{
UCHAR CTL;
CTL = RR_OR_RNR(LINK);
CTL = RR_OR_RNR(LINK, FALSE);
// MOV L2STATE[EBX],5 ; CANCEL REJ - ACTUALLY GOING TO 'PENDING ACK'
@ -3643,6 +3796,8 @@ VOID L2TIMEOUT(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT)
{
// RETRIED N TIMES SEND A COUPLE OF DISCS AND THEN CLOSE
hookL2SessionClosed(LINK, "Retried Out", "Out");
InformPartner(LINK, RETRIEDOUT); // TELL OTHER END ITS GONE
LINK->L2RETRIES -= 1; // Just send one DISC
@ -3801,6 +3956,7 @@ VOID L2SENDXID(struct _LINKTABLE * LINK)
if (PORT)
{
LINK->LINKWINDOW = PORT->PORTWINDOW; // Just in case!
Buffer->PORT = PORT->PORTNUMBER;
PUT_ON_PORT_Q(PORT, Buffer);
}
@ -3944,7 +4100,7 @@ VOID InformPartner(struct _LINKTABLE * LINK, int Reason)
}
UINT RR_OR_RNR(struct _LINKTABLE * LINK)
UINT RR_OR_RNR(struct _LINKTABLE * LINK, int CMD)
{
UCHAR Temp;
TRANSPORTENTRY * Session;
@ -4021,12 +4177,14 @@ stayinREJ2:
goto CheckNSLoop2; // See if OK or we have another saved frame
}
if (LINK->L2STATE == 6)
{
// if we support SREJ send that instesd or REJ
// Dont send SREJ if clearing RNR - causes FRMR
if (SaveRNRSent)
// Latest Spec says shouldn't send SREJ as Command
if (SaveRNRSent || CMD == 1)
return REJ;
if (LINK->Ver2point2) // We only allow 2.2 with SREJ Multi
@ -4034,6 +4192,7 @@ stayinREJ2:
else
return REJ;
}
}
return RR;
SENDRNR:
@ -4627,5 +4786,32 @@ int L2Compressit(unsigned char * Out, int OutSize, unsigned char * In, int Len)
}
int CloseAllLinks()
{
struct _LINKTABLE * LINK = LINKS;
int i = MAXLINKS;
int Closed = 0;
while (i--)
{
if (LINK->LINKCALL[0] == 0 || LINK->L2STATE !=5 )
{
LINK++;
continue;
}
// Close Link
InformPartner(LINK, NORMALCLOSE); // TELL OTHER END ITS GONE
LINK->L2RETRIES -= 1; // Just send one DISC
LINK->L2STATE = 4; // CLOSING
L2SENDCOMMAND(LINK, DISC | PFBIT);
Closed++;
}
return Closed;
}

View file

@ -60,6 +60,12 @@ VOID L3TRYNEXTDEST(struct ROUTE * ROUTE);
VOID SendNETROMRoute(struct PORTCONTROL * PORT, unsigned char * axcall);
void SendVARANetromNodes(struct TNCINFO * TNC, MESSAGE *Buffer);
void SendVARANetromMsg(struct TNCINFO * TNC,L3MESSAGEBUFFER * Buffer);
VOID SENDNODESMSG(int Portnum);
VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame);
extern int NODESINPROGRESS;
extern int NODESToOnePort;
extern int CLOSING;
extern BOOL NODESINPROGRESS ;;
PPORTCONTROL L3CURRENTPORT;
@ -94,7 +100,15 @@ VOID L3BG()
{
ROUTE = DEST->NRROUTE[ActiveRoute - 1].ROUT_NEIGHBOUR;
// if NetROM over VARA pass direct to the driver
// if NetROM over VARA or NetROM over TCP pass direct to the driver
if (ROUTE && ROUTE->TCPPort)
{
PL3MESSAGEBUFFER Frame = (PL3MESSAGEBUFFER)Q_REM(&DEST->DEST_Q);
TCPNETROMSend(ROUTE, Frame);
ReleaseBuffer(Frame);
continue;
}
if (ROUTE)
{
@ -222,7 +236,7 @@ BOOL ACTIVATE_DEST(struct DEST_LIST * DEST)
return L2SETUPCROSSLINK(ROUTE);
}
// We umst be waiting for link to come up
// We must be waiting for link to come up
return TRUE;
@ -241,6 +255,13 @@ char Call1[10];
char Call2[10];
char Call3[10];
VOID PROCESSNODESPOLL(struct PORTCONTROL * PORT)
{
// Pauls G8BPT's request NODES Broadcast
SENDNODESMSG(PORT->PORTNUMBER);
return;
}
VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT)
{
// PROCESS A NET/ROM 'NODES' MESSAGE
@ -606,9 +627,6 @@ VOID PROCROUTES(struct DEST_LIST * DEST, struct ROUTE * ROUTE, int Qual)
if (Index == 0)
{
// THIS IS A REFRESH OF BEST - IF THIS ISNT ACTIVE ROUTE, MAKE IT ACTIVE
if (DEST->DEST_ROUTE > 1) // LEAVE IT IF NOT SELECTED OR ALREADY USING BEST
DEST->DEST_ROUTE = 1;
}
goto UpdatateThisEntry;
@ -707,6 +725,8 @@ SORTROUTES:
goto SORTROUTES; // 1 AND 2 MAY NOW BE WRONG!
}
DEST->DEST_ROUTE = 0; // OForce re-evaluation.
}
int COUNTNODES(struct ROUTE * ROUTE)
@ -744,12 +764,26 @@ VOID L3BG();
VOID SENDNEXTNODESFRAGMENT();
VOID SENDNODESMSG()
VOID SENDNODESMSG(int Portnum)
{
if (NODESINPROGRESS)
return;
NODESToOnePort = Portnum;
if (Portnum) // Nodes to one port only
{
L3CURRENTPORT = GetPortTableEntryFromPortNum(Portnum);
if (L3CURRENTPORT == 0)
{
NODESToOnePort = 0;
return;
}
}
else
L3CURRENTPORT = PORTTABLE;
SENDNEXTNODESFRAGMENT();
}
@ -785,15 +819,18 @@ VOID SENDNEXTNODESFRAGMENT()
// No NODES to this port, so go to next
PORT = PORT->PORTPOINTER;
if (PORT == NULL)
if (PORT == NULL || NODESToOnePort)
{
// Finished
NODESToOnePort = 0;
NODESINPROGRESS = 0;
return;
}
}
if (NODESToOnePort == 0) // CurrentPort already set if NODESToOnePort
L3CURRENTPORT = PORT;
DEST = CURRENTNODE = DESTS; // START OF LIST
@ -851,6 +888,16 @@ VOID SENDNEXTNODESFRAGMENT()
if (DEST >= ENDDESTLIST)
{
CURRENTNODE = 0; // Finished on this port
// if sending to only one port then stop
if (NODESToOnePort)
{
NODESToOnePort = 0;
NODESINPROGRESS = 0;
}
else
{
L3CURRENTPORT = PORT->PORTPOINTER;
if (L3CURRENTPORT == NULL)
{
@ -858,6 +905,7 @@ VOID SENDNEXTNODESFRAGMENT()
NODESINPROGRESS = 0;
}
}
goto Sendit;
}
@ -951,7 +999,9 @@ VOID CLEARACTIVEROUTE(struct ROUTE * ROUTE, int Reason)
dest_list * DEST;
int n;
if (Reason != NORMALCLOSE || ROUTE->INP3Node)
// If a link restarts and is no longer inp3 we must still clear any inp3 routes
// if (Reason != NORMALCLOSE || ROUTE->INP3Node)
TellINP3LinkGone(ROUTE);
DEST = DESTS;
@ -991,7 +1041,8 @@ VOID L3TimerProc()
LINK = LINKS;
i = MAXLINKS;
while (i--);
while (i--)
{
if (LINK->LINKTYPE == 3) // Only if Internode
{
@ -1044,7 +1095,7 @@ VOID L3TimerProc()
L3TIMER = L3INTERVAL;
UPDATEDESTLIST();
SENDNODESMSG();
SENDNODESMSG(0);
}
}
@ -1082,6 +1133,11 @@ VOID L3FastTimer()
MESSAGE * Msg;
struct PORTCONTROL * PORT = PORTTABLE;
// Not if Node is closing
if (CLOSING)
return;
INP3TIMER();
// Send Node faster if VARA
@ -1254,6 +1310,9 @@ VOID REMOVENODE(dest_list * DEST)
while (DEST->DEST_Q)
ReleaseBuffer(Q_REM(&DEST->DEST_Q));
if (DEST->DEST_STATE & 0x80) // LOCKED DESTINATION
return;
// MAY NEED TO CHECK FOR L4 CIRCUITS USING DEST, BUT PROBABLY NOT,
// AS THEY SHOULD HAVE TIMED OUT LONG AGO

435
L4Code.c
View file

@ -49,7 +49,7 @@ BOOL FINDCIRCUIT(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY ** REQL4, int * NewInde
int GETBUSYBIT(TRANSPORTENTRY * L4);
BOOL cATTACHTOBBS(TRANSPORTENTRY * Session, UINT Mask, int Paclen, int * AnySessions);
VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG,
TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE);
TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE, int Service);
extern char * ALIASPTR;
void SendConACK(struct _LINKTABLE * LINK, TRANSPORTENTRY * L4, L3MESSAGEBUFFER * L3MSG, BOOL BPQNODE, UINT Applmask, UCHAR * ApplCall);
void L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG);
@ -69,6 +69,11 @@ void WriteConnectLog(char * fromCall, char * toCall, UCHAR * Mode);
void SendVARANetromMsg(struct TNCINFO * TNC, PL3MESSAGEBUFFER MSG);
int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen);
int L2Compressit(unsigned char * Out, int OutSize, unsigned char * In, int Len);
void OutgoingL4ConnectionEvent(TRANSPORTENTRY * L4);
void IncomingL4ConnectionEvent(TRANSPORTENTRY * L4);
void L4DisconnectEvent(TRANSPORTENTRY * L4, char * Direction, char * Reason);
VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame);
static UINT APPLMASK;
extern BOOL LogL4Connects;
@ -131,6 +136,14 @@ VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
return;
}
// IS IT INP3 (L3RTT)
if (CompareCalls(L3MSG->L3DEST, L3RTT))
{
ProcessRTTMsg(LINK->NEIGHBOUR, L3MSG, L3MSG->LENGTH, L3MSG->Port);
return;
}
APPLMASK = 0; // NOT APPLICATION
if (NODE) // _NODE SUPPORT INCLUDED?
@ -167,14 +180,6 @@ VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
APPL++;
}
// IS IT INP3 (L3RTT)
if (CompareCalls(L3MSG->L3DEST, L3RTT))
{
ProcessRTTMsg(LINK->NEIGHBOUR, L3MSG, L3MSG->LENGTH, L3MSG->Port);
return;
}
L3MSG->L3TTL--;
if (L3MSG->L3TTL == 0)
@ -455,7 +460,7 @@ VOID Q_IP_MSG(MESSAGE * Buffer)
ReleaseBuffer(Buffer);
}
VOID SENDL4CONNECT(TRANSPORTENTRY * Session)
VOID SENDL4CONNECT(TRANSPORTENTRY * Session, int Service)
{
PL3MESSAGEBUFFER MSG = (PL3MESSAGEBUFFER)GetBuff();
struct DEST_LIST * DEST = Session->L4TARGET.DEST;
@ -479,9 +484,18 @@ VOID SENDL4CONNECT(TRANSPORTENTRY * Session)
MSG->L4INDEX = Session->CIRCUITINDEX;
MSG->L4ID = Session->CIRCUITID;
MSG->L4TXNO = 0;
if (Service == -1) // Normal CREQ
{
MSG->L4RXNO = 0;
MSG->L4FLAGS = L4CREQ;
}
else
{
MSG->L4RXNO = Service << 8; // Paula's extended connect
MSG->L4TXNO = (Service & 0xff);
MSG->L4FLAGS = L4CREQX;
}
MSG->L4DATA[0] = L4DEFAULTWINDOW; // PROPOSED WINDOW
@ -791,7 +805,7 @@ VOID L4BG()
complen = L2Compressit(Compressed, 8192, toCompress, toCompressLen);
Debugprintf("%d %d %d%%", toCompressLen, complen, ((toCompressLen - complen) * 100) / toCompressLen);
// Debugprintf("%d %d %d%%", toCompressLen, complen, ((toCompressLen - complen) * 100) / toCompressLen);
// Send compressed
@ -826,7 +840,7 @@ VOID L4BG()
Len = ChunkSize;
complen = L2Compressit(Compressed, 8192, CompressPtr, Len);
Debugprintf("Chunked %d %d %d%%", Len, complen, ((Len - complen) * 100) / Len);
// Debugprintf("Chunked %d %d %d%%", Len, complen, ((Len - complen) * 100) / Len);
sendChunk(L4, Compressed, complen, savePort);
@ -858,8 +872,6 @@ VOID L4BG()
Msglen = Msg->LENGTH - (MSGHDDRLEN + 1); //Dont include PID
LINK->bytesTXed += Msglen;
Paclen = L4->SESSPACLEN;
if (Paclen == 0)
@ -1223,7 +1235,7 @@ VOID L4TIMEOUT(TRANSPORTENTRY * L4)
Debugprintf("Retrying L4 Connect Request");
SENDL4CONNECT(L4); // Resend connect
SENDL4CONNECT(L4, L4->Service); // Resend connect
return;
}
@ -1258,10 +1270,13 @@ VOID L4TIMEOUT(TRANSPORTENTRY * L4)
// if compressed session display stats
L4DisconnectEvent(L4, "outgoing", "Retried Out");
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
return;
}
// RESEND ALL OUTSTANDING FRAMES
L4->FLAGS &= 0x7F; // CLEAR CHOKED
@ -1568,19 +1583,26 @@ void WriteL4LogLine(UCHAR * mycall, UCHAR * call, UCHAR * node)
fclose(L4LogHandle);
}
VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT ApplMask, UCHAR * ApplCall)
extern struct CMDX COMMANDS[];
extern int NUMBEROFCOMMANDS;
VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT ApplMask, UCHAR * ApplCall, int Service)
{
// CONNECT REQUEST - SEE IF EXISTING SESSION
// IF NOT, GET AND FORMAT SESSION TABLE ENTRY
// SEND CONNECT ACK
// EDI = _BUFFER, EBX = LINK
// Service is for Paula's CREQX - Connect to Service
TRANSPORTENTRY * L4;
int BPQNODE = 0; // NOT ONE OF MINE
char BPQPARAMS[10]; // Extended Connect Params from BPQ Node
int CONERROR;
int Index;
char APPLCMD[13] = "";
if (APPL)
memcpy(APPLCMD, APPL->APPLCMD, 13);
memcpy(BPQPARAMS, &L4T1, 2); // SET DEFAULT T1 IN CASE NOT FROM ANOTHER BPQ NODE
@ -1608,8 +1630,9 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl
}
L4->CIRCUITINDEX = Index;
L4->Service = Service;
SETUPNEWCIRCUIT(LINK, L3MSG, L4, BPQPARAMS, ApplMask, &BPQNODE);
SETUPNEWCIRCUIT(LINK, L3MSG, L4, BPQPARAMS, ApplMask, &BPQNODE, Service);
if (L4->L4TARGET.DEST == 0)
{
@ -1619,6 +1642,60 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl
SendConNAK(LINK, L3MSG);
return;
}
// Check for NetromX Service
if (Service > 0 && Service != 23) // 0 is CMD Hander 23 is TELNET which also connects to node
{
int i;
for (i = 0; i < NUMBEROFSSERVICES; i++)
{
if (SERVICES[i].ServiceNo == Service)
{
// Check if we have this application
struct CMDX * CMD = NULL;
int n;
char * APP = &SERVICES[i].ServiceName[0];
int APPlen = strlen(APP);
for (n = PASSCMD; n < NUMBEROFCOMMANDS; n++) // Don't allow SYSOP Commands
{
CMD = &COMMANDS[n];
if (n == APPL1) // First APPL command
{
ApplMask = 1; // FOR APPLICATION ATTACH REQUESTS
ALIASPTR = &CMDALIAS[0][0];
}
// ptr1 is input command
if (memcmp(CMD->String, APP, APPlen) == 0)
{
// At the moment I only handle connects to appls. May support other node commands later.
memcpy(APPLCMD, CMD->String, 13);
if (n < APPL1 + NumberofAppls)
goto doAPPLConnect;
}
ApplMask <<= 1;
ALIASPTR += ALIASLEN;
}
}
}
// Not one of our applications - refuse connect
memset(L4, 0, sizeof (TRANSPORTENTRY));
SendConNAK(LINK, L3MSG);
return;
}
//
// IF CONNECT TO APPL, ALLOCATE BBS PORT
if (ApplMask == 0 || BPQPARAMS[2] == 'Z') // Z is "Spy" Connect
@ -1630,6 +1707,7 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl
// IF APPL CONNECT, SEE IF APPL HAS AN ALIAS
doAPPLConnect:
if (ALIASPTR[0] > ' ')
{
@ -1644,7 +1722,7 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl
if (Msg)
{
Msg->PID = 0xf0;
memcpy(Msg->L2DATA, APPL->APPLCMD, 12);
memcpy(Msg->L2DATA, APPLCMD, 12);
Msg->L2DATA[12] = 13;
Msg->LENGTH = MSGHDDRLEN + 12 + 2; // 2 for PID and CR
@ -1747,10 +1825,17 @@ VOID SendConACK(struct _LINKTABLE * LINK, TRANSPORTENTRY * L4, L3MESSAGEBUFFER *
TNC = LINK->LINKPORT->TNC;
if (TNC && TNC->NetRomMode)
if (LINK->NEIGHBOUR && LINK->NEIGHBOUR->TCPPort)
{
TCPNETROMSend(LINK->NEIGHBOUR, L3MSG);
ReleaseBuffer(L3MSG);
}
else if (TNC && TNC->NetRomMode)
SendVARANetromMsg(TNC, L3MSG);
else
C_Q_ADD(&LINK->TX_Q, L3MSG);
IncomingL4ConnectionEvent(L4);
}
int FINDCIRCUIT(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY ** REQL4, int * NewIndex)
@ -1827,7 +1912,7 @@ void L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG)
memcpy(L3MSG->L3SRCE, L3MSG->L3DEST, 7);
memcpy(L3MSG->L3DEST, Temp, 7);
L3MSG->L3DEST[6] &= 0x1E; // Mack EOA and CMD
L3MSG->L3DEST[6] &= 0x1E; // Mask EOA and CMD
L3MSG->L3SRCE[6] &= 0x1E;
L3MSG->L3SRCE[6] |= 1; // Set Last Call
}
@ -1847,6 +1932,9 @@ VOID SendL4RESET(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
{
// Paula's extension
L3MSG->L4RXNO = L3MSG->L4ID;
L3MSG->L4TXNO = L3MSG->L4INDEX;
L3MSG->L4FLAGS = L4RESET;
L3SWAPADDRESSES(L3MSG);
@ -1863,7 +1951,7 @@ VOID SendL4RESET(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG,
TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE)
TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE, int Service)
{
struct DEST_LIST * DEST;
int Maxtries = 2; // Just in case
@ -1882,10 +1970,10 @@ VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG,
L4->SESSIONT1 = L4T1;
L4->L4WINDOW = (UCHAR)L4DEFAULTWINDOW;
L4->L4WINDOW = L3MSG->L4DATA[0];
if (L3MSG->L4DATA[0] > L4DEFAULTWINDOW)
L4->L4WINDOW = L3MSG->L4DATA[0];
L4->L4WINDOW = L4DEFAULTWINDOW;
memcpy(L4->L4USER, &L3MSG->L4DATA[1], 7); // Originator's call from Call Request
@ -1943,7 +2031,7 @@ TryAgain:
while (n--)
{
if (DEST->DEST_COUNT == 0 && DEST->DEST_RTT == 0) // Not used and not INP3
if (DEST->DEST_COUNT == 0 && DEST->DEST_RTT == 0 && (DEST->DEST_STATE & 0x80) == 0) // Not used and not INP3 and not Appl
{
if (DEST->NRROUTE[0].ROUT_QUALITY < WorstQual)
{
@ -2020,6 +2108,8 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
char Call[10];
struct TNCINFO * TNC;
int Service = -1; // Paula's connect to service
L4FRAMESRX++;
Opcode = L3MSG->L4FLAGS & 15;
@ -2048,9 +2138,13 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
ReleaseBuffer(L3MSG);
return;
case L4CREQX: // Paula's connect to service
Service = (L3MSG->L4RXNO << 8) | L3MSG->L4TXNO;
case L4CREQ:
CONNECTREQUEST(LINK, L3MSG, ApplMask, ApplCall);
CONNECTREQUEST(LINK, L3MSG, ApplMask, ApplCall, Service);
return;
}
@ -2067,7 +2161,8 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
while (n--)
{
if (L4->L4USER[0] && L4->FARID == L3MSG->L4ID && L4->FARINDEX == L3MSG->L4INDEX)
if ((L4->L4USER[0] && L4->FARID == L3MSG->L4RXNO && L4->FARINDEX == L3MSG->L4TXNO) || // Paula returns session in RX/TXNO, I sent in ID/INDEX
(L4->L4USER[0] && L4->FARID == L3MSG->L4ID && L4->FARINDEX == L3MSG->L4INDEX))
{
// Check L3 source call to be sure (should that be L4 source call??
@ -2075,10 +2170,9 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
if (memcmp(L3MSG->L3SRCE, L4->L4TARGET.DEST->DEST_CALL, 7) == 0)
{
L4DisconnectEvent(L4, "incoming", "RESET Received");
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
}
ReleaseBuffer(L3MSG);
return;
}
L4++;
}
@ -2156,6 +2250,9 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
L4->L4WINDOW = L3MSG->L4DATA[0];
strcpy(ReplyText, "Connected to");
OutgoingL4ConnectionEvent(L4);
}
if (Partner == 0)
@ -2194,16 +2291,25 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
TNC = LINK->LINKPORT->TNC;
if (TNC && TNC->NetRomMode)
if (LINK->NEIGHBOUR && LINK->NEIGHBOUR->TCPPort)
{
TCPNETROMSend(LINK->NEIGHBOUR, L3MSG);
ReleaseBuffer(L3MSG);
}
else if (TNC && TNC->NetRomMode)
SendVARANetromMsg(TNC, L3MSG);
else
C_Q_ADD(&LINK->TX_Q, L3MSG);
L4DisconnectEvent(L4, "incoming", "DREQ Received");
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
return;
case L4DACK:
L4DisconnectEvent(L4, "outgoing", "DACK Received");
CLEARSESSIONENTRY(L4);
ReleaseBuffer(L3MSG);
return;
@ -2640,241 +2746,32 @@ VOID SENDL4IACK(TRANSPORTENTRY * Session)
}
/*
PUBLIC KILLSESSION
KILLSESSION:
pushad
push ebx
CALL _CLEARSESSIONENTRY
pop ebx
popad
JMP L4CONN90 ; REJECT
PUBLIC CONNECTACK
CONNECTACK:
;
; EXTRACT EXTENDED PARAMS IF PRESENT
;
CMP BYTE PTR MSGLENGTH[EDI],L4DATA+1
JE SHORT NOTBPQ
MOV AL,L4DATA+1[EDI]
SUB AL,L3MONR[EDI]
ADD AL,41H ; HOPS TO DEST + 40H
MOV ESI,L4TARGET[EBX]
AND DEST_STATE[ESI],80H
OR DEST_STATE[ESI],AL ; SAVE
PUBLIC NOTBPQ
NOTBPQ:
;
; SEE IF SUCCESS OR FAIL
;
PUSH EDI
MOV ESI,L4TARGET[EBX] ; ADDR OF LINK/DEST ENTRY
LEA ESI,DEST_CALL[ESI]
CALL DECODENODENAME ; CONVERT TO ALIAS:CALL
MOV EDI,OFFSET32 CONACKCALL
MOV ECX,17
REP MOVSB
POP EDI
TEST L4FLAGS[EDI],L4BUSY
JNZ SHORT L4CONNFAILED
CMP L4STATE[EBX],5
JE SHORT CONNACK05 ; MUST BE REPEAT MSG - DISCARD
MOV AX,WORD PTR L4TXNO[EDI] ; HIS INDEX
MOV WORD PTR FARINDEX[EBX],AX
MOV L4STATE[EBX],5 ; ACTIVE
MOV L4TIMER[EBX],0 ; CANCEL TIMER
MOV L4RETRIES[EBX],0 ; CLEAR RETRY COUNT
MOV AL,L4DATA[EDI] ; WINDOW
MOV L4WINDOW[EBX],AL ; SET WINDOW
MOV EDX,L4CROSSLINK[EBX] ; POINT TO PARTNER
;
MOV ESI,OFFSET32 CONNECTEDMSG
MOV ECX,LCONNECTEDMSG
JMP SHORT L4CONNCOMM
PUBLIC L4CONNFAILED
L4CONNFAILED:
;
MOV EDX,L4CROSSLINK[EBX] ; SAVE PARTNER
pushad
push ebx
CALL _CLEARSESSIONENTRY
pop ebx
popad
PUSH EBX
MOV EBX,EDX
MOV L4CROSSLINK[EBX],0 ; CLEAR CROSSLINK
POP EBX
MOV ESI,OFFSET32 BUSYMSG ; ?? BUSY
MOV ECX,LBUSYMSG
PUBLIC L4CONNCOMM
L4CONNCOMM:
OR EDX,EDX
JNZ SHORT L4CONNOK10
;
; CROSSLINK HAS GONE?? - JUST CHUCK MESSAGE
;
PUBLIC CONNACK05
CONNACK05:
JMP L4DISCARD
PUBLIC L4CONNOK10
L4CONNOK10:
PUSH EBX
PUSH ESI
PUSH ECX
MOV EDI,_BUFFER
ADD EDI,7
MOV AL,0F0H
STOSB ; PID
CALL _SETUPNODEHEADER ; PUT IN _NODE ID
POP ECX
POP ESI
REP MOVSB
MOV ESI,OFFSET32 CONACKCALL
MOV ECX,17 ; MAX LENGTH ALIAS:CALL
REP MOVSB
MOV AL,0DH
STOSB
MOV ECX,EDI
MOV EDI,_BUFFER
SUB ECX,EDI
MOV MSGLENGTH[EDI],CX
MOV EBX,EDX ; CALLER'S SESSION
LEA ESI,L4TX_Q[EBX]
CALL _Q_ADD ; SEND MESSAGE TO CALLER
CALL _POSTDATAAVAIL
POP EBX ; ORIGINAL CIRCUIT TABLE
RET
PUBLIC SENDCONNECTREPLY
SENDCONNECTREPLY:
;
; LINK SETUP COMPLETE - EBX = LINK, EDI = _BUFFER
;
CMP LINKTYPE[EBX],3
JNE SHORT CONNECTED00
;
; _NODE - _NODE SESSION SET UP - DONT NEED TO DO ANYTHING (I THINK!)
;
CALL RELBUFF
RET
;
; UP/DOWN LINK
;
PUBLIC CONNECTED00
CONNECTED00:
CMP CIRCUITPOINTER[EBX],0
JNE SHORT CONNECTED01
CALL RELBUFF ; UP/DOWN WITH NO SESSION - NOONE TO TELL
RET ; NO CROSS LINK
PUBLIC CONNECTED01
CONNECTED01:
MOV _BUFFER,EDI
PUSH EBX
PUSH ESI
PUSH ECX
ADD EDI,7
MOV AL,0F0H
STOSB ; PID
CALL _SETUPNODEHEADER ; PUT IN _NODE ID
LEA ESI,LINKCALL[EBX]
PUSH EDI
CALL CONVFROMAX25 ; ADDR OF CALLED STATION
POP EDI
MOV EBX,CIRCUITPOINTER[EBX]
MOV L4STATE[EBX],5 ; SET LINK UP
MOV EBX,L4CROSSLINK[EBX] ; TO INCOMING LINK
cmp ebx,0
jne xxx
;
; NO LINK ???
;
MOV EDI,_BUFFER
CALL RELBUFF
POP ECX
POP ESI
POP EBX
RET
PUBLIC xxx
xxx:
POP ECX
POP ESI
REP MOVSB
MOV ESI,OFFSET32 _NORMCALL
MOVZX ECX,_NORMLEN
REP MOVSB
MOV AL,0DH
STOSB
MOV ECX,EDI
MOV EDI,_BUFFER
SUB ECX,EDI
MOV MSGLENGTH[EDI],CX
LEA ESI,L4TX_Q[EBX]
CALL _Q_ADD ; SEND MESSAGE TO CALLER
CALL _POSTDATAAVAIL
POP EBX
RET
*/
int CloseAllSessions()
{
int n = MAXCIRCUITS;
TRANSPORTENTRY * L4 = L4TABLE;
TRANSPORTENTRY * Partner;
int MaxLinks = MAXLINKS;
int Closed = 0;
while (n--)
{
if (L4->L4USER[0] == 0)
{
L4++;
continue;
}
Closed++;
Partner = L4->L4CROSSLINK;
CLOSECURRENTSESSION(L4);
if (Partner)
CLOSECURRENTSESSION(Partner); // CLOSE THIS ONE
L4++;
}
return Closed;
}

View file

@ -83,8 +83,11 @@ void RHPPoll();
VOID GetPGConfig();
void SendBBSDataToPktMap();
void CloseAllLinks();
void hookNodeClosing(char * Reason);
void NETROMTCPResolve();
extern uint64_t timeLoadedMS;
extern uint64_t INP3timeLoadedMS;
BOOL IncludesMail = FALSE;
BOOL IncludesChat = FALSE;
@ -262,9 +265,9 @@ extern char MailDir[MAX_PATH];
extern time_t MaintClock; // Time to run housekeeping
#ifdef WIN32
BOOL KEEPGOING = 30; // 5 secs to shut down
int KEEPGOING = 30; // 5 secs to shut down
#else
BOOL KEEPGOING = 50; // 5 secs to shut down
int KEEPGOING = 50; // 5 secs to shut down
#endif
BOOL Restarting = FALSE;
BOOL CLOSING = FALSE;
@ -337,6 +340,7 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
// Handle the CTRL-C signal.
case CTRL_C_EVENT:
printf( "Ctrl-C event\n\n" );
CloseAllLinks();
CLOSING = TRUE;
Beep( 750, 300 );
return( TRUE );
@ -344,6 +348,7 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
// CTRL-CLOSE: confirm that the user wants to exit.
case CTRL_CLOSE_EVENT:
CloseAllLinks();
CLOSING = TRUE;
printf( "Ctrl-Close event\n\n" );
Sleep(20000);
@ -354,6 +359,7 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
case CTRL_BREAK_EVENT:
Beep( 900, 200 );
printf( "Ctrl-Break event\n\n" );
CloseAllLinks();
CLOSING = TRUE;
Beep( 750, 300 );
return FALSE;
@ -366,6 +372,7 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
case CTRL_SHUTDOWN_EVENT:
Beep( 750, 500 );
printf( "Ctrl-Shutdown event\n\n" );
CloseAllLinks();
CLOSING = TRUE;
Beep( 750, 300 );
return FALSE;
@ -399,6 +406,9 @@ static void segvhandler(int sig)
write(STDOUT_FILENO, msg, strlen(msg));
backtrace_symbols_fd(array, size, STDOUT_FILENO);
hookNodeClosing("sigsegv");
Sleep(500);
exit(1);
}
@ -419,6 +429,9 @@ static void abrthandler(int sig)
write(STDOUT_FILENO, msg, strlen(msg));
backtrace_symbols_fd(array, size, STDOUT_FILENO);
hookNodeClosing("sigabrt");
Sleep(500);
exit(1);
}
@ -427,12 +440,14 @@ static void sigterm_handler(int sig)
{
syslog(LOG_INFO, "terminating on SIGTERM\n");
CLOSING = TRUE;
CloseAllLinks();
}
static void sigint_handler(int sig)
{
printf("terminating on SIGINT\n");
CLOSING = TRUE;
CloseAllLinks();
}
@ -840,14 +855,13 @@ int main(int argc, char * argv[])
#endif
// Disable Console Terminal if stdout redirected
// printf("STDOUT %d\n",isatty(STDOUT_FILENO));
// printf("STDIN %d\n",isatty(STDIN_FILENO));
if (!isatty(STDOUT_FILENO) || !isatty(STDIN_FILENO))
Redirected = 1;
timeLoadedMS = GetTickCount();
INP3timeLoadedMS = GetTickCount();
#endif
@ -1002,6 +1016,8 @@ int main(int argc, char * argv[])
return (0);
}
NETROMTCPResolve();
for (i=0;PWTEXT[i] > 0x20;i++); //Scan for cr or null
PWLen=i;
@ -1534,6 +1550,8 @@ int main(int argc, char * argv[])
Start();
NETROMTCPResolve();
INITIALISEPORTS();
SetApplPorts();
@ -1683,6 +1701,9 @@ int main(int argc, char * argv[])
Slowtimer = 0;
}
hookNodeClosing("Shutdown");
Sleep(500);
printf("Closing Ports\n");
CloseTNCEmulator();

View file

@ -2105,7 +2105,6 @@ int CreateSMTPMessage(SocketConn * sockptr, int i, char * MsgTitle, time_t Date,
else
strcpy(B2To, Msg->to);
Msg->B2Flags = B2Msg | Attachments;
if (Msg->type == 'P')

108
Moncode.c
View file

@ -59,7 +59,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#define NODES_SIG 0xFF
UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, unsigned int msglen);
UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, int msglen);
char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen);
UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen);
@ -655,12 +655,13 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
char Node[10];
UCHAR TTL, Index, ID, TXNO, RXNO, OpCode, Flags, Window;
UCHAR * ptr = &ADJBUFFER->L2DATA[0];
int service = 0;
int netromx = 0; // Set if Paula's connect to service
if (ADJBUFFER->L2DATA[0] == NODES_SIG)
{
// Display NODES
// If an INP3 RIF (type <> UI) decode as such
if (ADJBUFFER->CTL != 3) // UI
@ -691,6 +692,14 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
return Output;
}
if (ADJBUFFER->L2DATA[0] == 0xfe) // Paula's Nodes Poll
{
memcpy(Alias, ++ptr, 6);
Output += sprintf((char *)Output, " NODES POLL from %s\r", Alias);
return Output;
}
// Display normal NET/ROM transmissions
Output += sprintf((char *)Output, " NET/ROM\r ");
@ -714,6 +723,12 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
switch (OpCode)
{
case L4CREQX: // Paula's connect to service
netromx = 1;
service = (RXNO << 8) | TXNO;
case L4CREQ:
Window = *(ptr++);
@ -722,6 +737,9 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
Node[ConvFromAX25(ptr, Node)] = 0;
ptr +=7;
if (netromx)
Output += sprintf((char *)Output, "<CON REQX> w=%d %d@%s at %s", Window, service, Dest, Node);
else
Output += sprintf((char *)Output, "<CON REQ> w=%d %s at %s", Window, Dest, Node);
if (MsgLen > 38) // BPQ Extended Params
@ -737,7 +755,7 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
if (Flags & L4BUSY) // BUSY RETURNED
return Output + sprintf((char *)Output, " <CON NAK> - BUSY");
return Output + sprintf((char *)Output, " <CON ACK> w=%d my cct=%02X%02X", ptr[1], TXNO, RXNO);
return Output + sprintf((char *)Output, " <CON ACK> w=%d my cct=%02X%02X", ptr[0], TXNO, RXNO);
case L4DREQ:
@ -985,3 +1003,87 @@ char * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output)
ptr[15], ptr[16], ptr[17], ptr[18], Dest, ptr[26], ptr[27], ptr[28], ptr[29]);
}
char Lastpacketlog[256];
int PacketLogDelay = 30000;
extern BPQVECSTRUC * FILEMONVECTOR;
extern UCHAR LogDirectory[260];
void WritePacketLogThread(void * param)
{
char FN[256];
time_t T;
struct tm * tm;
FILE * Handle;
int MsgLen;
MESSAGE * MSG;
MESSAGE * Q;
char buffer[512];
while(1)
{
BOOL SaveMTX = MTX;
BOOL SaveMCOM = MCOM;
BOOL SaveMUI = MUIONLY;
Sleep(PacketLogDelay);
// Get chain of queued packets under semaphore
GetSemaphore(&Semaphore, 101);
Q = FILEMONVECTOR->HOSTTRACEQ;
FILEMONVECTOR->HOSTTRACEQ = 0;
FreeSemaphore(&Semaphore);
if (Q == 0)
continue;
// Open log file and write decoded packets
T = time(NULL);
tm = gmtime(&T);
if (LogDirectory[0] == 0)
{
strcpy(FN, "logs/PacketLog");
}
else
{
strcpy(FN, LogDirectory);
strcat(FN, "/");
strcat(FN, "logs/PacketLog");
}
sprintf(&FN[strlen(FN)], "_%04d%02d%02d.log", tm->tm_year +1900, tm->tm_mon+1, tm->tm_mday);
Handle = fopen(FN, "ab");
if (Handle == NULL)
return;
while (Q)
{
MSG = Q;
Q = MSG->CHAIN; // get first
IntSetTraceOptionsEx(MMASK, 1, 1, 0);
MsgLen = IntDecodeFrame(MSG, buffer, MSG->Timestamp, 0xffffffffffffffff, FALSE, FALSE);
IntSetTraceOptionsEx(MMASK, SaveMTX, SaveMCOM, SaveMUI);
fwrite(buffer , 1, MsgLen, Handle);
GetSemaphore(&Semaphore, 101);
ReleaseBuffer(MSG);
FreeSemaphore(&Semaphore);
}
fclose(Handle);
}
return;
}

585
NETROMTCP.c Normal file
View file

@ -0,0 +1,585 @@
/*
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. See 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
*/
/*
Netrom over TCP Support
This is intended for operation over radio links with an IP interface, eg New Packet Radio or possibly microwave links
To simplify interface to the rest of the oode dummy LINK and PORT records are created
Packet Format is Length (2 byte little endian) Call (10 bytes ASCII) NETROM L3/4 Packet, starting 0xcf (to detect framing errors).
A TCP message can contain multiple packets and/or partial packets
It uses the Telnet Server, with port defined in NETROMPORT
ROUTE definitions have an extra field, the TCP Port Number
*/
//#pragma data_seg("_BPQDATA")
#define _CRT_SECURE_NO_DEPRECATE
#include "time.h"
#include "stdio.h"
#include <fcntl.h>
//#include "vmm.h"
#include "cheaders.h"
#include "asmstrucs.h"
#include "telnetserver.h"
#define NETROM_PID 0xCF
void NETROMConnectionLost(struct ConnectionInfo * sockptr);
int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info, int portNo);
int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr);
void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info);
VOID SendRTTMsg(struct ROUTE * Route);
BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE);
VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG);
int BPQTRACE(MESSAGE * Msg, BOOL TOAPRS);
VOID L3LINKCLOSED(struct _LINKTABLE * LINK, int Reason);
struct NRTCPMsg
{
short Length;
char Call[10];
unsigned char PID;
char Packet[1024];
};
struct NRTCPSTRUCT
{
struct ConnectionInfo * sockptr;
struct _LINKTABLE * LINK; // Dummy Link Record for this ROUTE
struct ROUTE * Route; // May need backlink
char Call[10];
};
struct NRTCPSTRUCT * NRTCPInfo[256] = {0};
// Do we want to use normal TCP server connections, which are limited, or our own. Let's try our own for now
struct ConnectionInfo * AllocateNRTCPRec()
{
struct ConnectionInfo * sockptr = 0;
struct NRTCPSTRUCT * Info;
int i;
for (i = 0; i < 255; i++)
{
if (NRTCPInfo[i] == 0)
{
// only allocate as many as needed
Info = NRTCPInfo[i] = (struct NRTCPSTRUCT *)zalloc(sizeof(struct NRTCPSTRUCT));
Info->sockptr = (struct ConnectionInfo *)zalloc(sizeof(struct ConnectionInfo));
Info->LINK = (struct _LINKTABLE *)zalloc(sizeof(struct _LINKTABLE));
Info->sockptr->Number = i;
}
else
Info = NRTCPInfo[i];
sockptr = Info->sockptr;
if (sockptr->SocketActive == FALSE)
{
sockptr->SocketActive = TRUE;
sockptr->ConnectTime = sockptr->LastSendTime = time(NULL);
Debugprintf("NRTCP Allocated %d", i);
return sockptr;
}
}
return 0;
}
void checkNRTCPSockets(int portNo)
{
SOCKET sock;
int Active = 0;
SOCKET maxsock;
int retval;
int i;
struct timeval timeout;
fd_set readfd, writefd, exceptfd;
struct ConnectionInfo * sockptr;
timeout.tv_sec = 0;
timeout.tv_usec = 0; // poll
maxsock = 0;
FD_ZERO(&readfd);
FD_ZERO(&writefd);
FD_ZERO(&exceptfd);
for (i = 0; i < 255; i++)
{
if (NRTCPInfo[i] == 0)
break; // only as many as have been used
sockptr = NRTCPInfo[i]->sockptr;
if (sockptr->SocketActive == 0)
continue;
if (sockptr->Connecting)
{
// look for complete or failed
FD_SET(sockptr->socket, &writefd);
FD_SET(sockptr->socket, &exceptfd);
}
else
{
FD_SET(sockptr->socket, &readfd);
FD_SET(sockptr->socket, &exceptfd);
}
Active++;
if (sockptr->socket > maxsock)
maxsock = sockptr->socket;
}
if (Active)
{
retval = select((int)maxsock + 1, &readfd, &writefd, &exceptfd, &timeout);
if (retval == -1)
{
perror("data select");
Debugprintf("NRTCP Select Error %d Active %d", WSAGetLastError(), Active);
}
else
{
if (retval)
{
// see who has data
for (i = 0; i < 255; i++)
{
if (NRTCPInfo[i] == 0)
break;
sockptr = NRTCPInfo[i]->sockptr;
if (sockptr->SocketActive == 0)
continue;
sock = sockptr->socket;
if (FD_ISSET(sock, &writefd))
NETROMConnected(sockptr, sock, NRTCPInfo[i]);
if (FD_ISSET(sock, &readfd))
DataSocket_ReadNETROM(sockptr, sock, NRTCPInfo[i], portNo);
if (FD_ISSET(sock, &exceptfd))
NETROMConnectionLost(sockptr);
}
}
}
}
}
int NETROMOpenConnection(struct ROUTE * Route)
{
struct NRTCPSTRUCT * Info;
struct ConnectionInfo * sockptr;
Debugprintf("Opening NRTCP Connection");
if (Route->TCPSession)
{
// SESSION ALREADY EXISTS
sockptr = Route->TCPSession->sockptr;
if (sockptr->Connected || sockptr->Connecting)
return TRUE;
// previous connect failed
}
else
{
sockptr = AllocateNRTCPRec();
if (sockptr == NULL)
return 0;
Info = Route->TCPSession = NRTCPInfo[sockptr->Number];
memcpy(Info->Call, MYNETROMCALL, 10);
Route->NEIGHBOUR_LINK = Info->LINK;
Info->Route = Route;
Info->LINK->NEIGHBOUR = Route;
Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT);
}
return NETROMTCPConnect(Route, sockptr);
}
void NETROMTCPResolve()
{
struct ROUTE * Route = NEIGHBOURS;
int n = MAXNEIGHBOURS;
struct addrinfo hints, *res = 0;
char PortString[20];
int err;
while (n--)
{
if (Route->TCPAddress)
{
// try to resolve host
sprintf(PortString, "%d", Route->TCPPort);
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_STREAM;
getaddrinfo(Route->TCPHost, PortString, &hints, &res);
err = WSAGetLastError();
if (res)
{
Route->TCPAddress->ai_family = res->ai_family;
Route->TCPAddress->ai_socktype = res->ai_socktype;
Route->TCPAddress->ai_protocol = res->ai_protocol;
Route->TCPAddress->ai_addrlen = res->ai_addrlen;
memcpy(Route->TCPAddress->ai_addr, res->ai_addr, sizeof(struct sockaddr));
freeaddrinfo(res);
}
}
Route++;
}
}
int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr)
{
int err;
u_long param=1;
BOOL bcopt=TRUE;
SOCKET sock;
struct sockaddr_in sinx;
int addrlen=sizeof(sinx);
char PortString[20];
struct addrinfo * res = Route->TCPAddress;
int Port = Route->TCPPort;
sprintf(PortString, "%d", Port);
// get host info, make socket, and connect it
if (res->ai_family == 0)
{
// err = WSAGetLastError();
// Debugprintf("Resolve HostName %s Failed - Error %d", Route->TCPHost, err);
return FALSE; // Resolve failed
}
sock = sockptr->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock == INVALID_SOCKET)
{
Debugprintf, ("Netrom over TCP Create Socket Failed");
return FALSE;
}
ioctl(sock, FIONBIO, &param);
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4);
if (connect(sock, res->ai_addr, (int)res->ai_addrlen) == 0)
{
//
// Connected successful
//
sockptr->Connected = TRUE;
return TRUE;
}
else
{
err=WSAGetLastError();
if (err == 10035 || err == 115 || err == 36) //EWOULDBLOCK
{
// Connect in Progress
sockptr->Connecting = TRUE;
return TRUE;
}
else
{
// Connect failed
closesocket(sockptr->socket);
return FALSE;
}
}
return FALSE;
}
void NETROMConnectionAccepted(struct ConnectionInfo * sockptr)
{
// Not sure we can do much here until first message arrives with callsign
sockptr->Connected = TRUE;
Debugprintf("NRTCP Connection Accepted");
}
void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info)
{
// Connection Complete
Debugprintf("NRTCP Connected");
sockptr->Connecting = FALSE;
sockptr->Connected = TRUE;
Info->LINK->L2STATE = 5;
if (Info->Route->INP3Node)
SendRTTMsg(Info->Route);
}
int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info, int portNo)
{
int len=0, maxlen;
struct NRTCPMsg * Msg;
struct _L3MESSAGEBUFFER * L3Msg;
struct ROUTE * Route;
UCHAR axCall[7];
PMESSAGE Buffer;
ioctl(sock,FIONREAD,&len);
maxlen = InputBufferLen - sockptr->InputLen;
if (len > maxlen) len = maxlen;
len = recv(sock, &sockptr->InputBuffer[sockptr->InputLen], len, 0);
if (len == SOCKET_ERROR || len == 0)
{
// Failed or closed - clear connection
NETROMConnectionLost(sockptr);
return 0;
}
sockptr->InputLen += len;
// Process data
checkLen:
// See if we have a whole packet
Msg = (struct NRTCPMsg *)&sockptr->InputBuffer[0];
if (Msg->Length > sockptr->InputLen) // if not got whole frame wait
return 0;
if (Info->Call[0] == 0)
{
// first packet - do we need to do anything?
// This must be an incoming connection as Call is set before calling so need to find route record and set things up.
Debugprintf("New NRTCP Connection from %s", Msg->Call);
memcpy(Info->Call, Msg->Call, 10);
ConvToAX25(Msg->Call, axCall);
if (FindNeighbour(axCall, portNo, &Route))
{
Info->Route = Route;
Route->NEIGHBOUR_LINK = Info->LINK;
Route->NEIGHBOUR_PORT = portNo;
Info->LINK->NEIGHBOUR = Route;
Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(portNo);
Route->TCPSession = Info;
Info->LINK->L2STATE = 5;
if (Info->Route->INP3Node)
SendRTTMsg(Info->Route);
}
else
{
Debugprintf("Neighbour %s port %d not found - closing connection", Msg->Call, portNo);
closesocket(sockptr->socket);
sockptr->SocketActive = FALSE;
memset(sockptr, 0, sizeof(struct ConnectionInfo));
Info->Call[0] = 0;
return 0;
}
}
if (memcmp(Info->Call, Msg->Call, 10) != 0)
{
// something wrong - maybe connection reused
}
// Format as if come from an ax.25 link
L3Msg = GetBuff();
if (L3Msg == 0)
goto seeifMore;
L3Msg->LENGTH = (Msg->Length - 12) + MSGHDDRLEN;
L3Msg->Next = 0;
L3Msg->Port = portNo;
L3Msg->L3PID = NETROM_PID;
memcpy(&L3Msg->L3SRCE, Msg->Packet, Msg->Length - 13);
// Create a dummy L2 message so we can trace it
Buffer = GetBuff();
if (Buffer)
{
Buffer->CHAIN = 0;
Buffer->CTL = 0;
Buffer->PORT = portNo;
ConvToAX25(Info->Call, Buffer->ORIGIN);
ConvToAX25(MYNETROMCALL, Buffer->DEST);
memcpy(Buffer->L2DATA, &L3Msg->L3SRCE[0], Msg->Length - 13);
Buffer->ORIGIN[6] |= 1; // Set end of calls
Buffer->PID = NETROM_PID;
Buffer->LENGTH = Msg->Length + 10;
time(&Buffer->Timestamp);
BPQTRACE(Buffer, FALSE);
ReleaseBuffer(Buffer);
}
NETROMMSG(Info->LINK, L3Msg);
seeifMore:
sockptr->InputLen -= Msg->Length;
if (sockptr->InputLen > 0)
{
memmove(sockptr->InputBuffer, &sockptr->InputBuffer[Msg->Length], sockptr->InputLen);
goto checkLen;
}
return 0;
}
VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame)
{
struct NRTCPMsg Msg;
unsigned char * Data = (unsigned char *)&Frame->L3SRCE[0];
int DataLen = Frame->LENGTH - (MSGHDDRLEN + 1); // Not including PID
int Ret;
PMESSAGE Buffer;
Msg.Length = DataLen + 13; // include PID
memcpy(Msg.Call, MYNETROMCALL, 10);
Msg.PID = NETROM_PID;
memcpy(Msg.Packet, Data, DataLen);
if (Route->TCPSession == 0)
return;
Ret = send(Route->TCPSession->sockptr->socket, (char *)&Msg, DataLen + 13, 0);
// Create a dummy L2 message so we can trace it
Buffer = GetBuff();
if (Buffer)
{
Buffer->CHAIN = 0;
Buffer->CTL = 0;
Buffer->PORT = Route->NEIGHBOUR_PORT | 128; // TX Flag
ConvToAX25(Route->TCPSession->Call, Buffer->DEST);
ConvToAX25(MYNETROMCALL, Buffer->ORIGIN);
memcpy(Buffer->L2DATA, &Frame->L3SRCE[0], DataLen);
Buffer->ORIGIN[6] |= 1; // Set end of calls
Buffer->PID = NETROM_PID;
Buffer->LENGTH = DataLen + 15 + MSGHDDRLEN;
time(&Buffer->Timestamp);
BPQTRACE(Buffer, FALSE);
ReleaseBuffer(Buffer);
}
}
void NETROMConnectionLost(struct ConnectionInfo * sockptr)
{
struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number];
struct ROUTE * Route;
closesocket(sockptr->socket);
// If there is an attached route (there should be) clear all connections
if (Info)
{
Route = Info->Route;
if (sockptr->Connected)
L3LINKCLOSED(Info->LINK, LINKLOST);
if (sockptr->Connecting)
L3LINKCLOSED(Info->LINK, SETUPFAILED);
if (Route)
Route->TCPSession = 0;
Info->Call[0] = 0;
}
sockptr->SocketActive = FALSE;
memset(sockptr, 0, sizeof(struct ConnectionInfo));
}

View file

@ -110,7 +110,7 @@ VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT);
int DecodeHAMLIBAddr(struct RIGPORTINFO * PORT, char * ptr);
void ProcessHAMLIBFrame(struct RIGPORTINFO * PORT, int Length);
VOID HAMLIBPoll(struct RIGPORTINFO * PORT);
void HAMLIBSlaveThread(struct RIGINFO * RIG);
void HAMLIBSlaveThread(VOID * Param);
void CheckAndProcessRTLUDP(struct RIGPORTINFO * PORT);
VOID RTLUDPPoll(struct RIGPORTINFO * PORT);
VOID ConnecttoRTLUDP(struct RIGPORTINFO * PORT);
@ -122,8 +122,8 @@ VOID ProcessSDRRadioFrame(struct RIGPORTINFO * PORT, int Length);
VOID SDRRadioPoll(struct RIGPORTINFO * PORT);
VOID SetupPortRIGPointers();
VOID PTTCATThread(struct RIGINFO *RIG);
VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT);
VOID PTTCATThread(void * Param);
// ----- G7TAJ ----
VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT);
@ -2217,7 +2217,7 @@ int BittoInt(UINT BitMask)
return i;
}
extern char * RadioConfigMsg[36];
extern char * RadioConfigMsg[70];
struct TNCINFO RIGTNC; // Dummy TNC Record for Rigcontrol without a corresponding TNC
@ -7484,8 +7484,9 @@ VOID SetupPortRIGPointers()
#ifdef WIN32
VOID PTTCATThread(struct RIGINFO *RIG)
VOID PTTCATThread(void * Param)
{
struct RIGINFO * RIG = (struct RIGINFO *)Param;
DWORD dwLength = 0;
int Length, ret, i;
UCHAR * ptr1;
@ -8471,7 +8472,7 @@ int DecodeHAMLIBAddr(struct RIGPORTINFO * PORT, char * ptr)
return 1;
}
VOID HAMLIBThread(struct RIGPORTINFO * PORT);
VOID HAMLIBThread(void * Param);
VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT)
{
@ -8481,10 +8482,11 @@ VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT)
return ;
}
VOID HAMLIBThread(struct RIGPORTINFO * PORT)
VOID HAMLIBThread(void * Param)
{
// Opens sockets and looks for data
struct RIGPORTINFO * PORT = (struct RIGPORTINFO * )Param;
char Msg[255];
int err, i, ret;
u_long param=1;
@ -8606,10 +8608,11 @@ Lost:
void HAMLIBSlaveThread(struct RIGINFO * RIG)
void HAMLIBSlaveThread(VOID * Param)
{
// Wait for connections and messages from HAMLIB Clients
struct RIGINFO * RIG = (struct RIGINFO *)Param;
fd_set readfs;
fd_set errorfs;
struct timeval timeout;
@ -8925,7 +8928,7 @@ VOID FLRIGSendCommand(struct RIGPORTINFO * PORT, char * Command, char * Value)
VOID FLRIGThread(struct RIGPORTINFO * PORT);
VOID FLRIGThread(VOID * Param);
VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT)
{
@ -8934,10 +8937,11 @@ VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT)
return ;
}
VOID FLRIGThread(struct RIGPORTINFO * PORT)
VOID FLRIGThread(VOID * Param)
{
// Opens sockets and looks for data
struct RIGPORTINFO * PORT = (struct RIGPORTINFO *)Param;
char Msg[255];
int err, i, ret;
u_long param=1;
@ -10177,7 +10181,7 @@ void ProcessSDRANGELFrame(struct RIGPORTINFO * PORT)
VOID SDRANGELThread(struct RIGPORTINFO * PORT);
VOID SDRANGELThread(VOID * Param);
VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT)
{
@ -10186,9 +10190,11 @@ VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT)
return ;
}
VOID SDRANGELThread(struct RIGPORTINFO * PORT)
VOID SDRANGELThread(VOID * Param)
{
// Opens sockets and looks for data
struct RIGPORTINFO * PORT = (struct RIGPORTINFO *)Param;
char Msg[512];
int err, i, ret;
u_long param=1;

View file

@ -90,7 +90,7 @@ void RHPThread(void * Params);
void ProcessRHPWebSockClosed(SOCKET socket);
int ProcessSNMPPayload(UCHAR * Msg, int Len, UCHAR * Reply, int * OffPtr);
int RHPProcessHTTPMessage(struct ConnectionInfo * conn, char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE);
void checkNRTCPSockets(int portNo);
#ifndef LINBPQ
extern HKEY REGTREE;
@ -172,12 +172,14 @@ VOID Tel_Format_Addr(struct ConnectionInfo * sockptr, char * dst);
VOID ProcessTrimodeCommand(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, char * MsgPtr);
VOID ProcessTrimodeResponse(struct TNCINFO * TNC, struct STREAMINFO * STREAM, unsigned char * MsgPtr, int Msglen);
VOID ProcessTriModeDataMessage(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, SOCKET sock, struct STREAMINFO * STREAM);
void processNETROMFrame(unsigned char * Message, int Len, struct ConnectionInfo * sockptr);
void NETROMConnectionLost(struct ConnectionInfo * sockptr);
void NETROMConnectionAccepted(struct ConnectionInfo * sockptr);
struct ConnectionInfo * AllocateNRTCPRec();
static int LogAge = 13;
#ifdef WIN32
int DeleteLogFile(char * Log);
@ -542,6 +544,9 @@ int ProcessLine(char * buf, int Port)
else if (_stricmp(param,"HTTPPORT") == 0)
HTTPPort = TCP->HTTPPort = atoi(value);
else if (_stricmp(param,"NETROMPORT") == 0)
TCP->NETROMPort = atoi(value);
else if (_stricmp(param,"APIPORT") == 0)
TCP->APIPort = atoi(value);
@ -1139,7 +1144,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
shutdown(TCP->FBBsock[n++], SD_BOTH);
shutdown(TCP->Relaysock, SD_BOTH);
shutdown(TCP->HTTPsock, SD_BOTH);
shutdown(TCP->HTTPSock, SD_BOTH);
shutdown(TCP->HTTPsock6, SD_BOTH);
@ -1163,7 +1168,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
closesocket(TCP->Relaysock);
closesocket(TCP->Relaysock6);
closesocket(TCP->HTTPsock);
closesocket(TCP->HTTPSock);
closesocket(TCP->HTTPsock6);
// Save info from old TNC record
@ -1248,7 +1253,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
shutdown(TCP->FBBsock[n++], SD_BOTH);
shutdown(TCP->Relaysock, SD_BOTH);
shutdown(TCP->HTTPsock, SD_BOTH);
shutdown(TCP->HTTPSock, SD_BOTH);
shutdown(TCP->HTTPsock6, SD_BOTH);
shutdown(TCP->sock6, SD_BOTH);
@ -1275,7 +1280,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
closesocket(TCP->FBBsock6[n++]);
closesocket(TCP->Relaysock6);
closesocket(TCP->HTTPsock);
closesocket(TCP->HTTPSock);
closesocket(TCP->HTTPsock6);
return (0);
@ -1713,11 +1718,14 @@ BOOL OpenSockets(struct TNCINFO * TNC)
}
if (TCP->HTTPPort)
TCP->HTTPsock = OpenSocket4(TNC, TCP->HTTPPort);
TCP->HTTPSock = OpenSocket4(TNC, TCP->HTTPPort);
if (TCP->APIPort)
TCP->APIsock = OpenSocket4(TNC, TCP->APIPort);
if (TCP->NETROMPort)
TCP->NETROMSock = OpenSocket4(TNC, TCP->NETROMPort);
if (TCP->SyncPort)
TCP->Syncsock = OpenSocket4(TNC, TCP->SyncPort);
@ -1836,6 +1844,9 @@ BOOL OpenSockets6(struct TNCINFO * TNC)
if (TCP->APIPort)
TCP->APIsock6 = OpenSocket6(TNC, TCP->APIPort);
if (TCP->NETROMPort)
TCP->NETROMSock6 = OpenSocket6(TNC, TCP->NETROMPort);
if (TCP->SyncPort)
TCP->Syncsock6 = OpenSocket6(TNC, TCP->SyncPort);
@ -1888,7 +1899,7 @@ static VOID SetupListenSet(struct TNCINFO * TNC)
maxsock = sock;
}
sock = TCP->HTTPsock;
sock = TCP->HTTPSock;
if (sock)
{
FD_SET(sock, readfd);
@ -1904,6 +1915,14 @@ static VOID SetupListenSet(struct TNCINFO * TNC)
maxsock = sock;
}
sock = TCP->NETROMSock;
if (sock)
{
FD_SET(sock, readfd);
if (sock > maxsock)
maxsock = sock;
}
sock = TCP->Syncsock;
if (sock)
{
@ -1979,6 +1998,14 @@ static VOID SetupListenSet(struct TNCINFO * TNC)
maxsock = sock;
}
sock = TCP->NETROMSock6;
if (sock)
{
FD_SET(sock, readfd);
if (sock > maxsock)
maxsock = sock;
}
sock = TCP->DRATSsock6;
if (sock)
@ -2066,13 +2093,20 @@ VOID TelnetPoll(int Port)
Socket_Accept(TNC, sock, TCP->RelayPort);
}
sock = TCP->HTTPsock;
sock = TCP->HTTPSock;
if (sock)
{
if (FD_ISSET(sock, &readfd))
Socket_Accept(TNC, sock, TCP->HTTPPort);
}
sock = TCP->NETROMSock;
if (sock)
{
if (FD_ISSET(sock, &readfd))
Socket_Accept(TNC, sock, TCP->NETROMPort);
}
sock = TCP->DRATSsock;
if (sock)
{
@ -2120,6 +2154,14 @@ VOID TelnetPoll(int Port)
Socket_Accept(TNC, sock, TCP->HTTPPort);
}
sock = TCP->NETROMSock6;
if (sock)
{
if (FD_ISSET(sock, &readfd))
Socket_Accept(TNC, sock, TCP->NETROMPort);
}
sock = TCP->DRATSsock6;
if (sock)
{
@ -2247,9 +2289,12 @@ VOID TelnetPoll(int Port)
}
}
nosocks:
// Poll TCPNR
checkNRTCPSockets(Port);
// Try SNMP
if (TCP->SNMPsock)
@ -3062,7 +3107,7 @@ LRESULT CALLBACK TelWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
shutdown(TCP->FBBsock[n++], SD_BOTH);
shutdown(TCP->Relaysock, SD_BOTH);
shutdown(TCP->HTTPsock, SD_BOTH);
shutdown(TCP->HTTPSock, SD_BOTH);
shutdown(TCP->HTTPsock6, SD_BOTH);
@ -3087,7 +3132,7 @@ LRESULT CALLBACK TelWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
closesocket(TCP->Relaysock);
closesocket(TCP->Relaysock6);
closesocket(TCP->HTTPsock);
closesocket(TCP->HTTPSock);
closesocket(TCP->HTTPsock6);
// Save info from old TNC record
@ -3256,6 +3301,35 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
return 0;
}
// Netrom Over TCP uses its own Connection Entries
if (SocketId == TCP->NETROMSock || SocketId == TCP->NETROMSock6)
{
sockptr = AllocateNRTCPRec();
if (sockptr == 0)
{
// No entries - accept and close
sock = accept(SocketId, (struct sockaddr *)&sin6, &addrlen);
send(sock,"No Free Sessions\r\n", 18,0);
Debugprintf("No Free Netrom Telnet Sessions");
Sleep (500);
closesocket(sock);
return 0;
}
sock = accept(SocketId, (struct sockaddr *)&sockptr->sin, &addrlen);
sockptr->socket = sock;
ioctl(sock, FIONBIO, &param);
sockptr->NETROMMode = TRUE;
NETROMConnectionAccepted(sockptr);
return 0;
}
// Find a free Session
for (n = 1; n <= TCP->MaxSessions; n++)
@ -3308,6 +3382,7 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
sockptr->HTTPMode = FALSE;
sockptr->APIMode = FALSE;
sockptr->NETROMMode = FALSE;
sockptr->SyncMode = FALSE;
sockptr->DRATSMode = FALSE;
sockptr->FBBMode = FALSE;
@ -3322,9 +3397,12 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
memset(sockptr->ADIF, 0, sizeof(struct ADIF));
if (SocketId == TCP->HTTPsock || SocketId == TCP->HTTPsock6)
if (SocketId == TCP->HTTPSock || SocketId == TCP->HTTPsock6)
sockptr->HTTPMode = TRUE;
if (SocketId == TCP->NETROMSock || SocketId == TCP->NETROMSock6)
sockptr->NETROMMode = TRUE;
if (SocketId == TCP->APIsock || SocketId == TCP->APIsock6)
{
sockptr->HTTPMode = TRUE; // API is a type of HTTP socket
@ -3796,11 +3874,13 @@ MsgLoop:
LFPtr=memchr(MsgPtr, 10, InputLen);
if (LFPtr == 0)
{
if (CRPtr)
{
LFPtr = ++CRPtr;
InputLen++;
}
}
if (LFPtr == 0)
{
// Check Paclen
@ -4493,6 +4573,7 @@ MsgLoop:
if (P8 == 1)
SendPortsForMonitor(sock, sockptr->UserPointer->Secure);
sockptr->InputLen = 0;
return 0;
}
@ -5271,6 +5352,7 @@ int DataSocket_ReadDRATS(struct TNCINFO * TNC, struct ConnectionInfo * sockptr,
}
int DataSocket_Disconnect(struct TNCINFO * TNC, struct ConnectionInfo * sockptr)
{
int n;
@ -5685,7 +5767,9 @@ int Telnet_Connected(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, SOCK
}
else
{
if (TNC->PortRecord->ATTACHEDSESSIONS[Stream]->L4CROSSLINK->APPL[0])
struct _TRANSPORTENTRY * CROSSLINK = TNC->PortRecord->ATTACHEDSESSIONS[Stream]->L4CROSSLINK;
if (CROSSLINK && CROSSLINK->APPL[0])
buffptr->Len = sprintf(&buffptr->Data[0], "*** Connected to %s\r",
TNC->PortRecord->ATTACHEDSESSIONS[Stream]->L4CROSSLINK->APPL);
else

View file

@ -80,6 +80,11 @@ int DoScanLine(struct TNCINFO * TNC, char * Buff, int Len);
VOID ProcessARQPacket(struct PORTCONTROL * PORT, MESSAGE * Buffer);
char * strlop(char * buf, char delim);
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
extern UCHAR BPQDirectory[];
extern char MYALIASLOPPED[10];

View file

@ -78,6 +78,11 @@ VOID ReleaseOtherPorts(struct TNCINFO * ThisTNC);
int DoScanLine(struct TNCINFO * TNC, char * Buff, int Len);
int standardParams(struct TNCINFO * TNC, char * buf);
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
extern UCHAR BPQDirectory[];
#define MAXUZ7HOPORTS 16

8
VARA.c
View file

@ -73,6 +73,11 @@ int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len);
VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT);
VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG);
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
#ifndef LINBPQ
BOOL CALLBACK EnumVARAWindowsProc(HWND hwnd, LPARAM lParam);
#endif
@ -418,10 +423,11 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{
TNC->Busy--;
if (TNC->Busy == 0)
SetWindowText(TNC->xIDC_CHANSTATE, "Clear");
{ SetWindowText(TNC->xIDC_CHANSTATE, "Clear");
strcpy(TNC->WEB_CHANSTATE, "Clear");
}
}
}
if (TNC->BusyDelay)
{

View file

@ -10,15 +10,15 @@
#endif
#define KVers 6,0,25,1
#define KVerstring "6.0.25.1\0"
#define KVers 6,0,25,9
#define KVerstring "6.0.25.9\0"
#ifdef CKernel
#define Vers KVers
#define Verstring KVerstring
#define Datestring "August 2025"
#define Datestring "October 2025"
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
#define VerCopyright "Copyright © 2001-2025 John Wiseman G8BPQ\0"
#define VerDesc "BPQ32 Switch\0"

View file

@ -105,6 +105,11 @@ int DoScanLine(struct TNCINFO * TNC, char * Buff, int Len);
BOOL KillOldTNC(char * Path);
int standardParams(struct TNCINFO * TNC, char * buf);
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
static char ClassName[]="WINMORSTATUS";
static char WindowTitle[] = "WINMOR";
static int RigControlRow = 165;
@ -613,10 +618,12 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{
TNC->Busy--;
if (TNC->Busy == 0)
{
SetWindowText(TNC->xIDC_CHANSTATE, "Clear");
strcpy(TNC->WEB_CHANSTATE, "Clear");
}
}
}
if (TNC->ConnectCmd && TNC->BusyDelay)
{

View file

@ -42,7 +42,7 @@ typedef int (FAR *FARPROCY)();
#define L4INFO 5 // INFORMATION
#define L4IACK 6 // INFORMATION ACK
#define L4RESET 7 // Paula's extension
#define L4CREQX 8 // Paula's extension
extern char MYCALL[]; // 7 chars, ax.25 format
extern char MYALIASTEXT[]; // 6 chars, not null terminated
@ -64,15 +64,6 @@ extern int ENDOFDATA;
extern int L3LIVES;
extern int NUMBEROFNODES;
struct CMDX
{
char String[12]; // COMMAND STRING
UCHAR CMDLEN; // SIGNIFICANT LENGTH
// VOID (*CMDPROC)(struct _TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);// COMMAND PROCESSOR
VOID (*CMDPROC)();// COMMAND PROCESSOR
size_t CMDFLAG; // FLAG/VALUE Offset
};
struct APPLCONFIG
{
@ -186,6 +177,14 @@ typedef struct _TRANSPORTENTRY
int Received;
int ReceivedAfterExpansion;
int segsSent;
int segsRcvd;
int segsResent;
int NRRID;
time_t NRRTime;
int Service; // For Paula's Connnect to Service
} TRANSPORTENTRY;
@ -229,13 +228,15 @@ typedef struct ROUTE
BOOL INP3Node;
BOOL NoKeepAlive; // Suppress Keepalive Processing
int LastConnectAttempt; // To stop us trying too often
int ConnectionAttempts;
int Status; //
int OldBPQ; // Set if other end is BPQ sending RIF in mS
int LastRTT; // Last Value Reported
int RTT; // Current
int SRTT; // Smoothed RTT
int NeighbourSRTT; // Other End SRTT
// int RTTIncrement; // Average of Ours and Neighbours SRTT in 10 ms
int RTTIncrement; // Average of Ours and Neighbours SRTT in 10 ms - smoothed neighbor transport time (SNTT) in spec
int BCTimer; // Time to next L3RTT Broadcast
int Timeout; // Lost Response Timer
int Retries; // Lost Response Count
@ -244,6 +245,13 @@ typedef struct ROUTE
int OtherendsRouteQual; // Route quality used by other end.
int OtherendLocked; // Route quality locked by ROUTES entry.
int FirstTimeFlag; // Set once quality has been set by direct receive
int RemoteMAXRTT; // For INP3
int RemoteMAXHOPS;
char * TCPHost; // For NETROM over TCP
int TCPPort;
struct NRTCPSTRUCT * TCPSession;
struct addrinfo * TCPAddress; // Resolved Address
} *PROUTE;
@ -701,7 +709,8 @@ typedef struct PORTCONTROL
BOOL NormalizeQuality; // Normalise Node Qualities
BOOL IgnoreUnlocked; // Ignore Unlocked routes
BOOL INP3ONLY; // Default to INP3 and disallow NODES
BOOL ALLOWINP3;
BOOL ALLOWINP3; // Accept INP3 if offered by other end
BOOL ENABLEINP3; // Send INP3 RTT probes to discovered neighbours
void (* UIHook)(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG); // Used for KISSARQ
struct PORTCONTROL * HookPort;
@ -966,6 +975,18 @@ typedef struct _LINKTABLE
time_t ConnectTime; // For session stats
int bytesRXed; // Info bytes only
int bytesTXed;
int framesRXed;
int framesTXed;
int framesResent;
time_t LastStatusTime;
int LastStatusbytesRXed;
int LastStatusbytesTXed;
int maxQueued;
int intervalMaxQueued;
uint64_t lastPSent; // Time last I frame with P bit sent in mS (for RTT Measurements)
int RTT;
// Now support compressing L2 Sessions.
// We collect as much data as possible before compressing and re-packetizing
@ -981,6 +1002,8 @@ typedef struct _LINKTABLE
int Received;
int ReceivedAfterExpansion;
char ApplName[16];
time_t lastStatusSentTime;
} LINKTABLE;
@ -1472,6 +1495,25 @@ struct AXIPPORTINFO
};
struct CMDX
{
char String[12]; // COMMAND STRING
UCHAR CMDLEN; // SIGNIFICANT LENGTH
VOID (*CMDPROC)(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);// COMMAND PROCESSOR
// VOID (*CMDPROC)();// COMMAND PROCESSOR
size_t CMDFLAG; // FLAG/VALUE Offset
};
struct NETROMX
{
int ServiceNo;
char ServiceName[10];
};
extern struct NETROMX SERVICES[];
extern int NUMBEROFSSERVICES;
#define Disconnect(stream) SessionControl(stream,2,0)
#define Connect(stream) SessionControl(stream,1,0)

View file

@ -192,8 +192,8 @@ extern UCHAR BPQDirectory[];
extern int OffsetH, OffsetW;
static void ResolveNames(struct AXIPPORTINFO * PORT);
void OpenSockets(struct AXIPPORTINFO * PORT);
static void ResolveNames(VOID * Param);
void OpenSockets(VOID * Param);
void CloseSockets(struct AXIPPORTINFO * PORT);
@ -221,7 +221,7 @@ int KissDecode(UCHAR * inbuff, int len);
int Socket_Accept(int SocketId);
int Socket_Connect(int SocketId, int Error);
int Socket_Data(int sock, int error, int eventcode);
VOID TCPConnectThread(struct arp_table_entry * arp);
VOID TCPConnectThread(VOID * Param);
VOID __cdecl Debugprintf(const char * format, ...);
VOID __cdecl Consoleprintf(const char * format, ...);
BOOL OpenListeningSocket(struct AXIPPORTINFO * PORT, struct arp_table_entry * arp);
@ -444,7 +444,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
From[ConvFromAX25(call, &From[1]) + 1] = 0;
if (strstr(CantReplyList, From) == 0)
{
if (strlen(CantReplyList) < 500);
if (strlen(CantReplyList) < 500)
strcat(CantReplyList, From);
Debugprintf("AXIP Packet from %s dropped - can't reply", &From[1]);
}
@ -557,7 +557,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
From[ConvFromAX25(call, &From[1]) + 1] = 0;
if (strstr(CantReplyList, From) == 0)
{
if (strlen(CantReplyList) < 500);
if (strlen(CantReplyList) < 500)
strcat(CantReplyList, From);
Debugprintf("AXIP Packet from %s dropped - can't reply", &From[1]);
}
@ -844,8 +844,9 @@ int InitAXIP(int Port)
return (TRUE);
}
void OpenSockets(struct AXIPPORTINFO * PORT)
void OpenSockets(void * Param)
{
struct AXIPPORTINFO * PORT = (struct AXIPPORTINFO *)Param;
char Msg[255];
int err;
u_long param=1;
@ -1528,8 +1529,9 @@ static void CreateResolverWindow(struct AXIPPORTINFO * PORT)
extern HWND hWndPopup;
static void ResolveNames(struct AXIPPORTINFO * PORT)
static void ResolveNames(VOID * Param)
{
struct AXIPPORTINFO * PORT = (struct AXIPPORTINFO *)Param;
int count = 0;
PORT->ResolveNamesThreadId = GetCurrentThreadId(); // Detect if another started
@ -2996,8 +2998,9 @@ int KissDecode(UCHAR * inbuff, int len)
return txptr;
}
VOID TCPConnectThread(struct arp_table_entry * arp)
VOID TCPConnectThread(void * Param)
{
struct arp_table_entry * arp = (struct arp_table_entry *)Param;
char Msg[255];
int err, i;
u_long param=1;

99
cMain.c
View file

@ -54,13 +54,26 @@ void MQTTTimer();
void SaveMH();
VOID InformPartner(struct _LINKTABLE * LINK, int Reason);
VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD);
void WritePacketLogThread(void * param);
void hookNodeStarted();
void hookNodeRunning();
void APIL2Trace(struct _MESSAGE * Message, char * Dirn);
#include "configstructs.h"
extern struct CONFIGTABLE xxcfg;
extern BOOL needAIS;
extern int needADSB;
extern int EnableOARCAPI;
extern SOCKET NodeAPISocket;
extern int nodeStartedSent;
extern SOCKADDR_IN UDPreportdest;
extern char NodeAPIServer[80];
extern int NodeAPIPort;
time_t LastNodeStatus = 0;
int nodeStatusTimer = 20 * 60; // 20 mins
struct PORTCONFIG * PortRec;
@ -181,6 +194,7 @@ extern VOID * ENDPOOL;
extern void * APPL_Q; // Queue of frames for APRS Appl
extern BOOL APRSActive;
extern int DEBUGINP3;
#define BPQHOSTSTREAMS 64
@ -194,9 +208,12 @@ BPQVECSTRUC * TELNETMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS];
BPQVECSTRUC * AGWMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 1];
BPQVECSTRUC * APRSMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 2];
BPQVECSTRUC * IPHOSTVECTORPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 3];
BPQVECSTRUC * FILEMONVECTOR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 4];
int BPQVECLENGTH = sizeof(BPQVECSTRUC);
int MONTOFILEFLAG = 0;
int NODEORDER = 0;
UCHAR LINKEDFLAG = 0;
@ -250,6 +267,8 @@ int CFLAG = 0; // C =HOST Command
VOID * IDMSG_Q = NULL; // ID/BEACONS WAITING TO BE SENT
int NODESINPROGRESS = 0;
int NODESToOnePort = 0; // Set to port num to send NODES to only one port.
VOID * CURRENTNODE = NULL; // NEXT _NODE TO SEND
VOID * DESTHEADER = NULL; // HEAD OF SORTED NODES CHAIN
@ -305,8 +324,8 @@ VOID LINKINIT(PEXTPORTDATA PORTVEC)
VOID LINKTX(PEXTPORTDATA PORTVEC, PMESSAGE Buffer)
{
// LOOP BACK TO SWITCH
struct _LINKTABLE * LINK;
struct _LINKTABLE * LINK;
LINK = Buffer->Linkptr;
if (LINK)
@ -862,6 +881,11 @@ BOOL Start()
PREFERINP3ROUTES = cfg->C_PREFERINP3ROUTES;
if (cfg->C_DEBUGINP3)
DEBUGINP3 = 0;
EnableOARCAPI = cfg->C_OARCAPI;
if (cfg->C_OnlyVer2point0)
SUPPORT2point2 = 0;
@ -992,6 +1016,7 @@ BOOL Start()
PORT->IgnoreUnlocked = PortRec->IGNOREUNLOCKED;
PORT->INP3ONLY = PortRec->INP3ONLY;
PORT->ALLOWINP3 = PortRec->AllowINP3;
PORT->ENABLEINP3 = PortRec->EnableINP3;
PORT->PORTWINDOW = (UCHAR)PortRec->MAXFRAME;
@ -1366,13 +1391,13 @@ BOOL Start()
PORT = GetPortTableEntryFromPortNum(ROUTE->NEIGHBOUR_PORT);
if (Rcfg->pwind & 0x40)
if (Rcfg->nokeepalives)
ROUTE->NoKeepAlive = 1;
else
if (PORT != NULL)
ROUTE->NoKeepAlive = PORT->PortNoKeepAlive;
if (Rcfg->pwind & 0x80 || (PORT && PORT->INP3ONLY))
if (Rcfg->inp3 || (PORT && PORT->INP3ONLY))
{
ROUTE->INP3Node = 1;
ROUTE->NoKeepAlive = 0; // Cant have INP3 and NOKEEPALIVES
@ -1387,6 +1412,15 @@ BOOL Start()
ROUTE->NEIGHBOUR_FLAG = LOCKEDBYCONFIG; // Locked
if (Rcfg->tcphost)
{
ROUTE->TCPHost = Rcfg->tcphost;
ROUTE->TCPPort = Rcfg->tcpport;
ROUTE->TCPAddress = (struct addrinfo *)zalloc(sizeof(struct addrinfo));
ROUTE->TCPAddress->ai_addr = (struct sockaddr *) zalloc(sizeof(struct sockaddr));
}
Rcfg++;
ROUTE++;
}
@ -1564,8 +1598,34 @@ BOOL Start()
upnpInit();
// Start Monitor to file thread
_beginthread(WritePacketLogThread, 0, NULL);
lastSaveSecs = CurrentSecs = lastSlowSecs = time(NULL);
// if EnableOARCAPI set try to resolve host here so we can send Node up event before anything else
if (EnableOARCAPI)
{
struct hostent * HostEnt3;
HostEnt3 = gethostbyname(NodeAPIServer);
NodeAPISocket = socket(AF_INET, SOCK_DGRAM, 0);
UDPreportdest.sin_family = AF_INET;
UDPreportdest.sin_port = htons(NodeAPIPort);
if (HostEnt3)
{
memcpy(&UDPreportdest.sin_addr.s_addr,HostEnt3->h_addr,4);
hookNodeStarted();
nodeStartedSent = 1;
LastNodeStatus = time(NULL);
}
}
return 0;
}
@ -1971,7 +2031,7 @@ VOID ReadNodes()
ptr = strtok_s(NULL, seps, &Context); // INP3
if (ptr == NULL) continue;
if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0); // Not LOCKED ROUTE
if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0) // Not LOCKED ROUTE
ROUTE->OtherendsRouteQual = atoi(ptr);
ptr = strtok_s(NULL, seps, &Context); // INP3
@ -2159,6 +2219,12 @@ VOID TIMERINTERRUPT()
if (MQTT)
MQTTTimer();
if (LastNodeStatus && (time(NULL) - LastNodeStatus) > nodeStatusTimer)
{
LastNodeStatus = time(NULL);
hookNodeRunning();
}
/*
if (QCOUNT < 200)
{
@ -2214,6 +2280,10 @@ VOID TIMERINTERRUPT()
}
Message = (struct _MESSAGE *)Buffer;
if(NodeAPISocket)
APIL2Trace(Message, "sent");
Message->PORT |= 0x80; // Set TX Bit
BPQTRACE(Message, FALSE); // Dont send TX'ed frames to APRS
@ -2326,6 +2396,9 @@ L2Packet:
if (MQTT && PORT->PROTOCOL == 0)
MQTTKISSRX(Buffer);
if(NodeAPISocket &&PORT->PROTOCOL == 0)
APIL2Trace(Message, "rcvd");
// Bridge if requested
for (toPort = 1; toPort <= MaxBPQPortNo; toPort++)
@ -2514,9 +2587,9 @@ ENDOFLIST:
{
// Stuck link debug check
if (LINK->LASTFRAMESENT && (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs
if (LINK->LINKWINDOW == 0 || LINK->LASTFRAMESENT == 0 || (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs
{
if (COUNT_AT_L2(LINK) > 16)
if (COUNT_AT_L2(LINK) > 16 || LINK->LINKWINDOW == 0)
{
// Dump Link State
@ -2675,6 +2748,18 @@ int BPQTRACE(MESSAGE * Msg, BOOL TOAPRS)
L4++;
}
// And to the Monitor to File system.
if (MONTOFILEFLAG) // Trace Enabled?
{
Buffer = GetBuff();
if (Buffer)
{
memcpy(&Buffer->PORT, &Msg->PORT, BUFFLEN - sizeof(void *)); // Dont copy chain word
C_Q_ADD(&FILEMONVECTOR->HOSTTRACEQ, Buffer);
}
}
return TRUE;
}
;

View file

@ -108,7 +108,7 @@ VOID SendCommandReply(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer, int
DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum);
int cCOUNT_AT_L2(struct _LINKTABLE * LINK);
VOID SENDL4CONNECT(TRANSPORTENTRY * Session);
VOID SENDL4CONNECT(TRANSPORTENTRY * Session, int Service);
VOID CloseSessionPartner(TRANSPORTENTRY * Session);
int COUNTNODES(struct ROUTE * ROUTE);
@ -445,7 +445,3 @@ DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqStringMhz);
void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _LINKTABLE * LINK);
void hookL2SessionDeleted(struct _LINKTABLE * LINK);
void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _LINKTABLE * LINK);
void hookL4SessionAttempt(void * STREAM, char * remotecall, char * ourcall);
void hookL4SessionAccepted(void * STREAM, char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);

View file

@ -49,7 +49,39 @@ Stuff to make compiling on WINDOWS and LINUX easier
int pthread_equal(pthread_t T1, pthread_t T2);
uintptr_t _beginthread(void(__cdecl *start_address)(void *), unsigned stack_size, void *arglist);
uintptr_t _beginthread(void(__cdecl start_address)(void *), unsigned stack_size, void *arglist);
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf c99_snprintf
#define vsnprintf c99_vsnprintf
__inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
{
int count = -1;
if (size != 0)
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
if (count == -1)
count = _vscprintf(format, ap);
return count;
}
__inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
{
int count;
va_list ap;
va_start(ap, format);
count = c99_vsnprintf(outBuf, size, format, ap);
va_end(ap);
return count;
}
#endif
#else
@ -152,9 +184,7 @@ int stricmp(const unsigned char * pStr1, const unsigned char *pStr2);
char * strupr(char* s);
char * strlwr(char* s);
pthread_t _beginthread(void(*start_address)(), unsigned stack_size, VOID * arglist);
pthread_t _beginthread(void(start_address)(void *), unsigned stack_size, VOID * arglist);
#define WSAGetLastError() errno
#define GetLastError() errno

164
config.c
View file

@ -305,11 +305,12 @@ static char *keywords[] =
"APPL5ALIAS", "APPL6ALIAS", "APPL7ALIAS", "APPL8ALIAS",
"APPL1QUAL", "APPL2QUAL", "APPL3QUAL", "APPL4QUAL",
"APPL5QUAL", "APPL6QUAL", "APPL7QUAL", "APPL8QUAL",
"BTEXT:", "NETROMCALL", "C_IS_CHAT", "MAXRTT", "MAXHOPS", // IPGATEWAY= no longer allowed
"BTEXT:", "NETROMCALL", "C_IS_CHAT", "MAXRTT", "MAXTT", "MAXHOPS", // IPGATEWAY= no longer allowed
"LogL4Connects", "LogAllConnects", "SAVEMH", "ENABLEADIFLOG", "ENABLEEVENTS", "SAVEAPRSMSGS",
"EnableM0LTEMap", "MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS",
"L4Compress", "L4CompMaxframe", "L4CompPaclen", "L2Compress", "L2CompMaxframe",
"L2CompPaclen", "PREFERINP3ROUTES", "OnlyVer2point0"
"L2CompPaclen", "PREFERINP3ROUTES", "OnlyVer2point0", "DEBUGINP3", "ENABLEOARCAPI"
}; /* parameter keywords */
static void * offset[] =
@ -328,11 +329,12 @@ static void * offset[] =
&xxcfg.C_APPL[4].ApplAlias, &xxcfg.C_APPL[5].ApplAlias, &xxcfg.C_APPL[6].ApplAlias, &xxcfg.C_APPL[7].ApplAlias,
&xxcfg.C_APPL[0].ApplQual, &xxcfg.C_APPL[1].ApplQual, &xxcfg.C_APPL[2].ApplQual, &xxcfg.C_APPL[3].ApplQual,
&xxcfg.C_APPL[4].ApplQual, &xxcfg.C_APPL[5].ApplQual, &xxcfg.C_APPL[6].ApplQual, &xxcfg.C_APPL[7].ApplQual,
&xxcfg.C_BTEXT, &xxcfg.C_NETROMCALL, &xxcfg.C_C, &xxcfg.C_MAXRTT, &xxcfg.C_MAXHOPS, // IPGATEWAY= no longer allowed
&xxcfg.C_BTEXT, &xxcfg.C_NETROMCALL, &xxcfg.C_C, &xxcfg.C_MAXRTT, &xxcfg.C_MAXRTT, &xxcfg.C_MAXHOPS, // IPGATEWAY= no longer allowed
&xxcfg.C_LogL4Connects, &xxcfg.C_LogAllConnects, &xxcfg.C_SaveMH, &xxcfg.C_ADIF, &xxcfg.C_EVENTS, &xxcfg.C_SaveAPRSMsgs,
&xxcfg.C_M0LTEMap, &xxcfg.C_MQTT, &xxcfg.C_MQTT_HOST, &xxcfg.C_MQTT_PORT, &xxcfg.C_MQTT_USER, &xxcfg.C_MQTT_PASS,
&xxcfg.C_L4Compress, &xxcfg.C_L4CompMaxframe, &xxcfg.C_L4CompPaclen, &xxcfg.C_L2Compress, &xxcfg.C_L2CompMaxframe,
&xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES, &xxcfg.C_OnlyVer2point0}; /* offset for corresponding data in config file */
&xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES, &xxcfg.C_OnlyVer2point0, &xxcfg.C_DEBUGINP3, &xxcfg.C_OARCAPI}; /* offset for corresponding data in config file */
static int routine[] =
{
@ -350,11 +352,12 @@ static int routine[] =
13, 13 ,13, 13,
14, 14, 14, 14,
14, 14 ,14, 14,
15, 0, 2, 9, 9,
15, 0, 2, 9, 9, 9,
2, 2, 1, 2, 2, 2,
2, 2, 0, 1, 20, 20,
1, 1, 1, 1, 1,
1, 1, 1} ; // Routine to process param
1, 1, 1, 1, 1}; // Routine to process param
int PARAMLIM = sizeof(routine)/sizeof(int);
//int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int);
@ -376,7 +379,7 @@ static char *pkeywords[] =
"BCALL", "DIGIMASK", "NOKEEPALIVES", "COMPORT", "DRIVER", "WL2KREPORT", "UIONLY",
"UDPPORT", "IPADDR", "I2CBUS", "I2CDEVICE", "UDPTXPORT", "UDPRXPORT", "NONORMALIZE",
"IGNOREUNLOCKEDROUTES", "INP3ONLY", "TCPPORT", "RIGPORT", "PERMITTEDAPPLS", "HIDE",
"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort", "ALLOWINP3"}; /* parameter keywords */
"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort", "ALLOWINP3", "ENABLEINP3"}; /* parameter keywords */
static void * poffset[] =
{
@ -390,7 +393,7 @@ static void * poffset[] =
&xxp.BCALL, &xxp.DIGIMASK, &xxp.DefaultNoKeepAlives, &xxp.IOADDR, &xxp.DLLNAME, &xxp.WL2K, &xxp.UIONLY,
&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}; /* offset for corresponding data in config file */
&xxp.SmartID, &xxp.KissParams, &xxp.SendtoM0LTEMap, &xxp.PortFreq, &xxp.M0LTEMapInfo, &xxp.QtSMPort, &xxp.AllowINP3, &xxp.EnableINP3}; /* offset for corresponding data in config file */
static int proutine[] =
{
@ -404,7 +407,7 @@ static int proutine[] =
0, 1, 2, 18, 15, 16, 2,
1, 17, 1, 1, 1, 1, 2,
2, 2, 1, 1, 19, 2,
1, 20, 1, 21, 22, 1, 1}; /* routine to process parameter */
1, 20, 1, 21, 22, 1, 1, 1}; /* routine to process parameter */
int PPARAMLIM = sizeof(proutine)/sizeof(int);
@ -601,7 +604,6 @@ BOOL ProcessConfig()
for (i=0;i<24;i++)
paramok[45+i]=1; /* or APPLCALLS, APPLALIASS APPLQUAL */
paramok[69]=1; // BText optional
@ -630,7 +632,11 @@ BOOL ProcessConfig()
paramok[90]=1; // L2Compress Maxframe
paramok[91]=1; // L2Compress Paclen
paramok[92]=1; // PREFERINP3ROUTES
paramok[93]=1; // C_ONLYVer2point0
paramok[93]=1; // ONLYVer2point0
paramok[94]=1; // DEBUGINP3
paramok[95]=1; // EnableOARCAPI
paramok[96]=1; // OARCAPI
for (i=0; i < PARAMLIM; i++)
{
@ -1583,6 +1589,127 @@ int routes(int i)
// strtok and sscanf can't handle successive commas, so split up usig strchr
// Now support keyword=value format
if (strchr(rec, '='))
{
// New format
// call quality port window frack paclen farquality inp3 nokeepalives tcp
char * ptr, *context;
char copy[512] = "";
if (strlen(rec) < 512)
strcpy(copy, rec);
_strupr(rec);
ptr = strtok_s(rec, " ,=", &context);
while (ptr)
{
if (strcmp(ptr, "CALL") == 0)
{
char * Call = strtok_s(NULL, ",=", &context);
if (strlen(Call) < 80)
strcpy(Route->call, Call);
}
else if (strcmp(ptr, "PORT") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->port = atoi(val);
}
else if (strcmp(ptr, "QUALITY") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->quality = atoi(val);
}
else if (strcmp(ptr, "FRACK") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->pfrack = atoi(val);
}
else if (strcmp(ptr, "PACLEN") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->pwind = atoi(val);
}
else if (strcmp(ptr, "WINDOW") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->pwind = atoi(val);
}
else if (strcmp(ptr, "FARQUALITY") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->farQual = atoi(val);
}
else if (strcmp(ptr, "INP3") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->inp3 = atoi(val);
}
else if (strcmp(ptr, "NOKEEPALIVES") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->farQual = atoi(val);
}
else if (strcmp(ptr, "TCP") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
{
char * port = strlop(val, ':');
Route->tcphost = _strdup(val);
if (port)
Route->tcpport = atoi(port);
else
Route->tcpport = 53119;
}
}
else
{
Consoleprintf("Bad Route %s\r\n",rec);
err_flag = 1;
break;
}
ptr = strtok_s(NULL, " ,=", &context);
}
}
else
{
memset(Param, 0, 2048);
strlop(rec, 13);
strlop(rec, ';');
@ -1610,6 +1737,13 @@ int routes(int i)
inp3 = atoi(Param[6]);
Route->farQual = atoi(Param[7]);
if (inp3 & 1)
Route->inp3 = 1;
if (inp3 & 2)
Route->nokeepalives = 1;
}
if (Route->farQual < 0 || Route->farQual > 255)
{
Consoleprintf("Remote Quality must be between 0 and 255");
@ -1633,14 +1767,6 @@ int routes(int i)
err_flag = 1;
}
// Use top bit of window as INP3 Flag, next as NoKeepAlive
if (inp3 & 1)
Route->pwind |= 0x80;
if (inp3 & 2)
Route->pwind |= 0x40;
if (err_flag == 1)
{
Consoleprintf("%s\r\n",rec);

View file

@ -82,6 +82,7 @@ struct PORTCONFIG
char * M0LTEMapInfo;
int QtSMPort;
int AllowINP3;
int EnableINP3;
};
struct ROUTECONFIG
@ -93,6 +94,10 @@ struct ROUTECONFIG
int pfrack;
int ppacl;
int farQual;
int inp3;
int nokeepalives;
char * tcphost;
int tcpport;
};
struct CONFIGTABLE
@ -179,6 +184,8 @@ struct CONFIGTABLE
int C_L2CompPaclen;
int C_PREFERINP3ROUTES;
int C_OnlyVer2point0;
int C_DEBUGINP3;
int C_OARCAPI;
//#define ApplOffset 80000 // Applications offset in config buffer

View file

@ -35,6 +35,9 @@ int RFOnly = 0;
int MAXRTT = 9000; // 90 secs
int MaxHops = 4;
int DEBUGINP3 = 0;
int EnableOARCAPI = 0;
int RTTInterval = 24; // 4 Minutes

View file

@ -78,6 +78,8 @@ typedef struct _ETHARP
UCHAR TARGETHWADDR[6];
uint32_t TARGETIPADDR;
char Padding[18]; // For min ether send of 60
} ETHARP, *PETHARP;
typedef struct _RIP2HDDR

10
kiss.c
View file

@ -1905,7 +1905,7 @@ int i2cPoll(struct PORTCONTROL * PORT, NPASYINFO npKISSINFO)
// KISS Over TCP Routines
VOID ConnecttoTCPThread(NPASYINFO ASY);
VOID ConnecttoTCPThread(void * Param);
int ConnecttoTCP(NPASYINFO ASY)
{
@ -1914,8 +1914,9 @@ int ConnecttoTCP(NPASYINFO ASY)
return 0;
}
VOID ConnecttoTCPThread(NPASYINFO ASY)
VOID ConnecttoTCPThread(void * Param)
{
NPASYINFO ASY = (NPASYINFO)Param;
char Msg[255];
int err,i;
u_long param=1;
@ -2131,7 +2132,7 @@ int KISSGetTCPMessage(NPASYINFO ASY)
// Interface to QtSM Managmemt Interface
VOID QtSMThread(struct PORTCONTROL * PORT);
VOID QtSMThread(void * Param);
VOID ConnecttoQtSM(struct PORTCONTROL * PORT)
{
@ -2141,11 +2142,12 @@ VOID ConnecttoQtSM(struct PORTCONTROL * PORT)
return ;
}
VOID QtSMThread(struct PORTCONTROL * PORT)
VOID QtSMThread(void * Param)
{
// This is the Managemt Interface in QtSM. It receives PTT ON/OFF msgs from QtSM and allows changing modem mode and freq.
// Also will collect link usage stats
struct PORTCONTROL * PORT = (struct PORTCONTROL *)Param;
char Msg[255];
int err, i, ret;
u_long param = 1;

View file

@ -852,14 +852,14 @@ double LatFromLOC = 0;
double LonFromLOC = 0;
#endif
void SendBBSDataToPktMapThread();
void SendBBSDataToPktMapThread(void * Param);
void SendBBSDataToPktMap()
{
_beginthread(SendBBSDataToPktMapThread, 0, 0);
}
void SendBBSDataToPktMapThread()
void SendBBSDataToPktMapThread(void * Param)
{
char Request[64];
char * Params;

View file

@ -13,7 +13,7 @@ OBJS = pngwtran.o pngrtran.o pngset.o pngrio.o pngwio.o pngtrans.o pngrutil.o pn
MailCommands.o MailDataDefs.o LinBPQ.o MailRouting.o MailTCP.o MBLRoutines.o md5.o Moncode.o \
NNTPRoutines.o RigControl.o TelnetV6.o WINMOR.o TNCCode.o UZ7HODrv.o WPRoutines.o \
SCSTrackeMulti.o SCSPactor.o SCSTracker.o HanksRT.o UIRoutines.o AGWAPI.o AGWMoncode.o \
DRATS.o FreeDATA.o base64.o Events.o nodeapi.o mailapi.o mqtt.o RHP.o
DRATS.o FreeDATA.o base64.o Events.o nodeapi.o mailapi.o mqtt.o RHP.o NETROMTCP.o
# Configuration:

158
nodeapi.c
View file

@ -9,6 +9,7 @@
#include <stdlib.h>
#include "tncinfo.h"
#include "asmstrucs.h"
#include "telnetserver.h"
#include "kiss.h"
// Constants
@ -56,6 +57,7 @@ int sendUserList(char * response, char * token, char * Rest, int Local);
int sendInfo(char * response, char * token, char * Rest, int Local);
int sendLinks(char * response, char * token, char * Rest, int Local);
int sendPortMHList(char * response, char * token, char * Rest, int Local);
int sendPortQState(char * response, char * token, char * Rest, int Local);
int sendWhatsPacState(char * response, char * token, char * param, int Local);
int sendWhatsPacConfig(char * response, char * token, char * param, int Local);
@ -74,6 +76,7 @@ struct API APIList[] =
"/api/links", 10, sendLinks, 0,
"/api/users", 10, sendUserList, 0,
"/api/mheard", 11, sendPortMHList, 0,
"/api/tcpqueues", 14, sendPortQState, 0,
"/api/v1/config", 14, sendWhatsPacConfig, AuthSysop,
"/api/v1/state", 13, sendWhatsPacState, AuthSysop
};
@ -827,9 +830,164 @@ int sendPortMHList(char * response, char * token, char * param, int Local)
strcat(response, "\r\n]}\r\n");
// printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response);
}
return strlen(response);
}
int sendPortQState(char * response, char * token, char * param, int Local)
{
struct TNCINFO * TNC;
struct TCPINFO * TCP;
struct ConnectionInfo * Conn;
struct STREAMINFO * STREAM;
int Stream;
int tcpqueue;
int Queued;
int n;
int port = 0;
char Type[10];
char Appl[20];
int radioport = 0;
if (param[0] = '?' || param[0] == '/')
port = atoi(&param[1]);
TNC = TNCInfo[port];
// At the moment only supports Telnet Ports
if (TNC == 0 || TNC->Hardware != H_TELNET)
return send_http_response(response, "401 Invalid API Call");
response[0] = 0;
TCP = TNC->TCPInfo;
if (TCP == 0)
return send_http_response(response, "401 Invalid API Call");
n = sprintf(response,"{\"QState\":[\r\n");
for (Stream = 0; Stream <= TCP->MaxSessions; Stream++)
{
char Call[10];
STREAM = &TNC->Streams[Stream];
Conn = TNC->Streams[Stream].ConnectionInfo;
// if connected to the node
if (Conn->SocketActive)
{
TRANSPORTENTRY * Sess1 = TNC->PortRecord->ATTACHEDSESSIONS[Stream];
TRANSPORTENTRY * Sess2 = NULL;
if (Sess1)
Sess2 = Sess1->L4CROSSLINK;
else
continue;
radioport = 0;
// Can't use TXCount - it is Semaphored=
Queued = C_Q_COUNT(&TNC->Streams[Stream].PACTORtoBPQ_Q);
Queued += C_Q_COUNT((UINT *)&TNC->PortRecord->PORTCONTROL.PORTRX_Q);
if (Sess2)
Queued += CountFramesQueuedOnSession(Sess2);
if (Sess1)
Queued += CountFramesQueuedOnSession(Sess1);
// CountFramesQueuedOnSession(TRANSPORTENTRY * Session)
tcpqueue = Conn->FromHostBuffPutptr - Conn->FromHostBuffGetptr;
if (Sess2)
Sess1 = Sess2;
Call[ConvFromAX25(Sess1->L4USER, Call)] = 0;
if (Sess1->L4CIRCUITTYPE & BPQHOST)
strcpy(Type, "Host");
else if (Sess1->L4CIRCUITTYPE & SESSION)
{
struct DEST_LIST * DEST = Sess1->L4TARGET.DEST;
strcpy(Type, "NETROM");
if (DEST)
{
int ActiveRoute = DEST->DEST_ROUTE;
if (ActiveRoute)
{
struct ROUTE * ROUTE = DEST->NRROUTE[ActiveRoute - 1].ROUT_NEIGHBOUR;
if (ROUTE)
{
struct _LINKTABLE * LINK = ROUTE->NEIGHBOUR_LINK;
if (LINK && LINK->LINKPORT)
radioport = LINK->LINKPORT->PORTNUMBER;
}
}
}
}
else if (Sess1->L4CIRCUITTYPE & PACTOR)
{
// PACTOR Type - Frames are queued on the Port Entry
struct PORTCONTROL * PORT = Sess1->L4TARGET.PORT;
strcpy(Type, "HFLINK");
if (PORT)
radioport = PORT->PORTNUMBER;
}
else
{
struct _LINKTABLE * LINK = Sess1->L4TARGET.LINK;
strcpy(Type, "L2 Link");
if (LINK && LINK->LINKPORT)
radioport = LINK->LINKPORT->PORTNUMBER;
}
memcpy(Appl, Sess1->APPL, 16);
strlop(Appl, ' ');
n += sprintf(&response[n], "{\"APPL\": \"%s\", \"callSign\": \"%s\", \"type\": \"%s\", \"tcpqueue\": %d, \"packets\": %d, \"port\": %d},\r\n" , Appl, Call, Type, tcpqueue, Queued, radioport);
}
}
if (n < 20) // No entries
{
response[strlen(response) - 2] = '\0'; // remove \r\n
strcat(response, "]}\r\n");
}
else
{
response[strlen(response)-3 ] = '\0'; // remove ,\r\n
strcat(response, "\r\n]}\r\n");
// printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response);
}
return strlen(response);
}
// WhatsPac configuration interface
// WhatsPac also uses Paula's Remote Host Protocol (RHP). This is in a separate module

View file

@ -354,6 +354,7 @@ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
comp->output_ptr=NULL;
/* write anything left in zbuf */
if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
png_write_chunk_data(png_ptr, png_ptr->zbuf,
png_ptr->zbuf_size - png_ptr->zstream.avail_out);

View file

@ -38,6 +38,7 @@ struct ConnectionInfo
BOOL SyncMode; // RMS Relay Sync
BOOL HTTPMode; // HTTP Server
BOOL APIMode; // REST API Server
BOOL NETROMMode;
BOOL TriMode; // Trimode emulation
BOOL TriModeConnected; // Set when remote session is connected - now send data to DataSock
SOCKET TriModeDataSock; // Data Socket
@ -73,6 +74,9 @@ struct ConnectionInfo
int WebSocks;
char WebURL[32]; // URL for WebSocket Connection
int WebSecure; // Set if secure session
int Connecting; // For outward connect
int Connected;
};

View file

@ -116,6 +116,7 @@ struct TCPINFO
int SNMPPort;
int DRATSPort;
int CMDPort[33];
int NETROMPort;
char RELAYHOST[64];
char CMSServer[64];
BOOL FallbacktoRelay; // Use Relsy if can't connect to CMS
@ -160,13 +161,14 @@ struct TCPINFO
SOCKET TCPSock;
SOCKET FBBsock[100];
SOCKET Relaysock;
SOCKET HTTPsock;
SOCKET HTTPSock;
SOCKET APIsock;
SOCKET TriModeSock;
SOCKET TriModeDataSock;
SOCKET Syncsock;
SOCKET DRATSsock;
SOCKET SNMPsock;
SOCKET NETROMSock;
struct ConnectionInfo * TriModeControlSession;
SOCKET sock6;
@ -176,6 +178,7 @@ struct TCPINFO
SOCKET APIsock6;
SOCKET Syncsock6;
SOCKET DRATSsock6;
SOCKET NETROMSock6;
fd_set ListenSet;
SOCKET maxsock;