New upstream version 6.0.25.8+repack
This commit is contained in:
parent
96ac3e4a36
commit
453f162d22
6
ARDOP.c
6
ARDOP.c
|
|
@ -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
|
||||
|
|
|
|||
38
BPQINP3.c
38
BPQINP3.c
|
|
@ -42,11 +42,19 @@ 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
|
||||
|
|
@ -127,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);
|
||||
}
|
||||
|
||||
|
|
@ -882,9 +891,11 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len
|
|||
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
|
||||
|
|
@ -896,7 +907,7 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len
|
|||
return;
|
||||
}
|
||||
|
||||
if (Route->NEIGHBOUR_LINK->LINKPORT->ALLOWINP3 || Route->NEIGHBOUR_LINK->LINKPORT->ENABLEINP3)
|
||||
if (Route->NEIGHBOUR_LINK->LINKPORT && (Route->NEIGHBOUR_LINK->LINKPORT->ALLOWINP3 || Route->NEIGHBOUR_LINK->LINKPORT->ENABLEINP3))
|
||||
Route->INP3Node = 1;
|
||||
|
||||
if (Route->INP3Node == 0)
|
||||
|
|
@ -1168,11 +1179,16 @@ 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)
|
||||
{
|
||||
Route++;
|
||||
|
|
@ -1181,6 +1197,8 @@ int SendRIPTimer()
|
|||
|
||||
// Try to activate link
|
||||
|
||||
Route->ConnectionAttempts++;
|
||||
|
||||
if (Route->INP3Node)
|
||||
{
|
||||
Normcall[ConvFromAX25(Route->NEIGHBOUR_CALL, Normcall)] = 0;
|
||||
|
|
@ -1618,7 +1636,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;
|
||||
|
|
|
|||
34
BPQNRR.c
34
BPQNRR.c
|
|
@ -45,7 +45,7 @@ extern VOID Q_ADD();
|
|||
VOID __cdecl Debugprintf(const char * format, ...);
|
||||
|
||||
TRANSPORTENTRY * NRRSession;
|
||||
time_t NRRTime;
|
||||
int NRRID = 1; // Id to correlate requests and responses
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -77,8 +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;
|
||||
|
|
@ -87,7 +88,18 @@ VOID NRRecordRoute(UCHAR * Buff, int Len)
|
|||
|
||||
*ptr1++ = 0xf0; // PID
|
||||
|
||||
ptr1 += sprintf(ptr1, "NRR Response in (probably) %d Secs :", (int)(Now - NRRTime));
|
||||
|
||||
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);
|
||||
|
|
@ -100,7 +112,7 @@ VOID NRRecordRoute(UCHAR * Buff, int Len)
|
|||
if ((Buff[7] & 0x80) == 0x80) // Check turnround bit
|
||||
*ptr1++ = '*';
|
||||
|
||||
Buff+=8;
|
||||
Buff += 8;
|
||||
Len -= 8;
|
||||
}
|
||||
|
||||
|
|
@ -114,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);
|
||||
|
||||
|
|
@ -175,7 +187,6 @@ VOID SendNRRecordRoute(struct DEST_LIST * DEST, TRANSPORTENTRY * Session)
|
|||
return;
|
||||
|
||||
NRRSession = Session; // Save Session Pointer for reply
|
||||
NRRTime = time(NULL);
|
||||
|
||||
Msg->Port = 0;
|
||||
Msg->L3PID = NRPID;
|
||||
|
|
@ -187,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);
|
||||
}
|
||||
|
|
|
|||
77
Bpq32.c
77
Bpq32.c
|
|
@ -1292,6 +1292,12 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
|
|||
// 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
|
||||
|
|
@ -1387,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);
|
||||
|
|
@ -1396,6 +1404,8 @@ VOID ADIFWriteFreqList();
|
|||
void SaveAIS();
|
||||
void initAIS();
|
||||
void initADSB();
|
||||
int CloseAllSessions();
|
||||
int CloseAllLinks();
|
||||
|
||||
extern BOOL ADIFLogEnabled;
|
||||
|
||||
|
|
@ -1643,6 +1653,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;
|
||||
|
||||
|
|
@ -1698,6 +1710,8 @@ BOOL ReconfigFlag = FALSE;
|
|||
BOOL RigReconfigFlag = FALSE;
|
||||
BOOL APRSReconfigFlag = FALSE;
|
||||
BOOL CloseAllNeeded = FALSE;
|
||||
int CloseAllTimer = 0;
|
||||
|
||||
BOOL NeedWebMailRefresh = FALSE;
|
||||
|
||||
int AttachedPIDList[100] = {0};
|
||||
|
|
@ -2379,6 +2393,52 @@ VOID TimerProcX()
|
|||
|
||||
CheckGuardZone();
|
||||
|
||||
if (CloseAllTimer == 50) // First entry
|
||||
{
|
||||
if (CloseAllSessions() == 0)
|
||||
{
|
||||
if (CloseAllLinks() == 0) // No sessions closed so close links now
|
||||
CloseAllTimer = 0; // 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;
|
||||
}
|
||||
|
||||
|
|
@ -5905,13 +5965,24 @@ DllExport VOID APIENTRY CreateNewTrayIcon()
|
|||
trayMenu = NULL;
|
||||
}
|
||||
|
||||
void hookNodeClosing(char * Reason);
|
||||
|
||||
|
||||
DllExport VOID APIENTRY CloseAllPrograms()
|
||||
{
|
||||
// HANDLE hProc;
|
||||
CLOSING = TRUE;
|
||||
|
||||
// Close all attached BPQ32 programs
|
||||
// Tell BG to shut when all links are gone or after 5 secs
|
||||
|
||||
Closing = TRUE;
|
||||
CloseAllTimer = 50;
|
||||
}
|
||||
|
||||
VOID RealCloseAllPrograms()
|
||||
{
|
||||
hookNodeClosing("Shutdown");
|
||||
Sleep(500);
|
||||
|
||||
Closing = 1;
|
||||
|
||||
ShowWindow(FrameWnd, SW_RESTORE);
|
||||
|
||||
|
|
|
|||
272
Cmd.c
272
Cmd.c
|
|
@ -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 )
|
||||
|
|
@ -74,6 +70,7 @@ 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);
|
||||
|
||||
|
|
@ -190,6 +187,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, ...)
|
||||
{
|
||||
|
|
@ -791,6 +836,104 @@ 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;
|
||||
|
||||
ptr = strtok_s(CmdTail, " ", &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;
|
||||
|
|
@ -799,6 +942,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
|
||||
|
||||
|
|
@ -817,12 +961,43 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
|
|||
return;
|
||||
}
|
||||
|
||||
ptr = strtok_s(CmdTail, " ", &Context);
|
||||
|
||||
if (CmdTail[0] == 'S')
|
||||
Stay = TRUE;
|
||||
|
||||
Session->STAYFLAG = Stay;
|
||||
// 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
|
||||
|
|
@ -904,6 +1079,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));
|
||||
}
|
||||
|
|
@ -2229,7 +2407,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;
|
||||
|
||||
|
|
@ -2238,6 +2416,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;
|
||||
|
|
@ -2245,12 +2425,12 @@ VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIS
|
|||
|
||||
NewSess->SPYFLAG = Spy;
|
||||
|
||||
ReleaseBuffer((UINT *)REPLYBUFFER);
|
||||
if (Service == -1)
|
||||
ReleaseBuffer((UINT *)REPLYBUFFER);
|
||||
|
||||
SENDL4CONNECT(NewSess);
|
||||
SENDL4CONNECT(NewSess, Service);
|
||||
|
||||
L4CONNECTSOUT++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2336,6 +2516,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
|
||||
|
|
@ -2482,7 +2665,7 @@ NoPort:
|
|||
|
||||
// SEE IF CALL TO ANY OF OUR HOST SESSIONS - UNLESS DIGIS SPECIFIED
|
||||
|
||||
if (axcalls[7] == 0)
|
||||
if (axcalls[7] == 0 && axcalls[9] )
|
||||
{
|
||||
// If this connect is as a result of a command alias, don't check appls or we will loop
|
||||
|
||||
|
|
@ -2533,9 +2716,30 @@ 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
|
||||
|
||||
i = 0;
|
||||
|
||||
while (cmdCopy[i] >= '0' && cmdCopy[i]<= '9')
|
||||
i++;
|
||||
|
||||
if (cmdCopy[i] != ' ')
|
||||
goto Downlink;
|
||||
else
|
||||
{
|
||||
// SEE IF CALL TO ANOTHER NODE
|
||||
if (i > 0) // Some digits
|
||||
{
|
||||
haveService = 1;
|
||||
Service = atoi(cmdCopy);
|
||||
}
|
||||
}
|
||||
|
||||
if (axcalls[7] == 0 || haveService)
|
||||
{
|
||||
// SEE IF CALL TO ANOTHER NODE
|
||||
|
||||
struct DEST_LIST * Dest = DESTS;
|
||||
int n = MAXDESTS;
|
||||
|
|
@ -2546,7 +2750,7 @@ NoPort:
|
|||
{
|
||||
if (memcmp(Dest->DEST_ALIAS, TextCall, 6) == 0)
|
||||
{
|
||||
DoNetromConnect(Session, Bufferptr, Dest, Spy);
|
||||
DoNetromConnect(Session, Bufferptr, Dest, Spy, Service);
|
||||
return;
|
||||
}
|
||||
Dest++;
|
||||
|
|
@ -2560,7 +2764,7 @@ NoPort:
|
|||
{
|
||||
if (CompareCalls(Dest->DEST_CALL, axcalls))
|
||||
{
|
||||
DoNetromConnect(Session, Bufferptr, Dest, Spy);
|
||||
DoNetromConnect(Session, Bufferptr, Dest, Spy, Service);
|
||||
return;
|
||||
}
|
||||
Dest++;
|
||||
|
|
@ -3723,6 +3927,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
|
||||
|
|
@ -4435,6 +4641,7 @@ struct CMDX COMMANDS[] =
|
|||
"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,
|
||||
|
|
@ -4468,7 +4675,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,
|
||||
|
|
@ -4861,6 +5068,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]; //
|
||||
|
||||
|
|
@ -4952,6 +5161,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
|
||||
|
|
|
|||
35
CommonCode.c
35
CommonCode.c
|
|
@ -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;
|
||||
|
|
@ -3679,6 +3685,12 @@ 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;
|
||||
|
|
@ -3717,15 +3729,23 @@ VOID ResolveUpdateThread(void * Unused)
|
|||
HostEnt3 = gethostbyname(NodeAPIServer);
|
||||
|
||||
if (HostEnt3)
|
||||
{
|
||||
memcpy(&UDPreportdest.sin_addr.s_addr,HostEnt3->h_addr,4);
|
||||
|
||||
|
||||
if (nodeStartedSent == 0)
|
||||
{
|
||||
hookNodeStarted();
|
||||
nodeStartedSent = 1;
|
||||
LastNodeStatus = time(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (HostEnt1 && HostEnt2)
|
||||
{
|
||||
Sleep(1000 * 60 * 30);
|
||||
{
|
||||
Sleep(1000 * 60 * 30);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Debugprintf("Resolve Failed for update.g8bpq.net or chatmap.g8bpq.net");
|
||||
Sleep(1000 * 60 * 5);
|
||||
}
|
||||
|
|
@ -3759,13 +3779,6 @@ VOID OpenReportingSockets()
|
|||
reportdest.sin_port = htons(81);
|
||||
ConvToAX25("DUMMY-1", ReportDest);
|
||||
}
|
||||
|
||||
UDPreportdest.sin_family = AF_INET;
|
||||
UDPreportdest.sin_port = htons(NodeAPIPort);
|
||||
|
||||
if (EnableOARCAPI)
|
||||
NodeAPISocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
|
||||
// Set up Chat Report even if no LOCATOR reportdest.sin_family = AF_INET;
|
||||
// Socket must be opened in MailChat Process
|
||||
|
|
|
|||
928
Events.c
928
Events.c
|
|
@ -25,6 +25,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
|
|||
#include <string.h>
|
||||
#include "asmstrucs.h"
|
||||
#include "tncinfo.h"
|
||||
#include "cheaders.h"
|
||||
|
||||
VOID __cdecl Debugprintf(const char * format, ...);
|
||||
|
||||
|
|
@ -41,9 +42,9 @@ VOID __cdecl Debugprintf(const char * format, ...);
|
|||
extern BOOL EventsEnabled;
|
||||
void MQTTReportSession(char * Msg);
|
||||
extern int MQTT;
|
||||
extern time_t TimeLoaded;
|
||||
|
||||
|
||||
int UDPSeq = 0;
|
||||
int UDPSeq = 1;
|
||||
|
||||
extern SOCKET NodeAPISocket;
|
||||
extern SOCKADDR_IN UDPreportdest;
|
||||
|
|
@ -51,9 +52,23 @@ extern SOCKADDR_IN UDPreportdest;
|
|||
extern char Modenames[19][10];
|
||||
|
||||
extern char NODECALLLOPPED[10];
|
||||
extern char MYALIASLOPPED[10];
|
||||
extern char LOC[7];
|
||||
extern char VersionString[50];
|
||||
extern double LatFromLOC;
|
||||
extern double LonFromLOC;
|
||||
|
||||
void hookL2SessionClosed(struct _LINKTABLE * LINK, char * Reason, char * Direction);
|
||||
int ConvFromAX25(unsigned char * incall, unsigned char * outcall);
|
||||
int COUNT_AT_L2(struct _LINKTABLE * LINK);
|
||||
int CountFramesQueuedOnSession(TRANSPORTENTRY * Session);
|
||||
int decodeNETROMUIMsg(unsigned char * Msg, int iLen, char * Buffer, int BufferLen);
|
||||
int decodeNETROMIFrame(unsigned char * Msg, int iLen, char * Buffer, int BufferLen);
|
||||
int decodeINP3RIF(unsigned char * Msg, int iLen, char * Buffer, int BufferLen);
|
||||
int decodeRecordRoute(L3MESSAGE * L3, int iLen, char * Buffer, int BufferLen);
|
||||
|
||||
// Runs use specified routine on certain event
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
void RunEventProgram(char * Program, char * Param)
|
||||
|
|
@ -130,9 +145,8 @@ void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _
|
|||
char UDPMsg[1024];
|
||||
int udplen;
|
||||
|
||||
|
||||
LINK->ConnectTime = time(NULL);
|
||||
LINK->bytesTXed = LINK->bytesRXed = 0;
|
||||
LINK->bytesTXed = LINK->bytesRXed = LINK->framesResent = LINK->framesRXed = LINK->framesTXed = 0;
|
||||
|
||||
strcpy(LINK->callingCall, remotecall);
|
||||
strcpy(LINK->receivingCall, ourcall);
|
||||
|
|
@ -140,12 +154,14 @@ void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _
|
|||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\"}",
|
||||
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall);
|
||||
|
||||
Debugprintf(UDPMsg);
|
||||
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
LINK->lastStatusSentTime = time(NULL);
|
||||
|
||||
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\"}",
|
||||
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall);
|
||||
|
||||
// Debugprintf(UDPMsg);
|
||||
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -170,8 +186,6 @@ void hookL2SessionDeleted(struct _LINKTABLE * LINK)
|
|||
double avBytesRXed = LINK->bytesRXed / (sessionTime / 60.0);
|
||||
time_t Now = time(NULL);
|
||||
struct tm * TM = localtime(&Now);
|
||||
char UDPMsg[1024];
|
||||
int udplen;
|
||||
|
||||
sprintf(timestamp, "%02d:%02d:%02d", TM->tm_hour, TM->tm_min, TM->tm_sec);
|
||||
|
||||
|
|
@ -190,36 +204,21 @@ void hookL2SessionDeleted(struct _LINKTABLE * LINK)
|
|||
if (MQTT)
|
||||
MQTTReportSession(Msg);
|
||||
|
||||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
if (strcmp(LINK->Direction, "Out") == 0)
|
||||
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkDownEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\"}",
|
||||
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->receivingCall, LINK->callingCall);
|
||||
else
|
||||
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkDownEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\"}",
|
||||
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall);
|
||||
|
||||
Debugprintf(UDPMsg);
|
||||
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
}
|
||||
LINK->ConnectTime = 0;
|
||||
}
|
||||
|
||||
LINK->ConnectTime = 0;
|
||||
}
|
||||
|
||||
if (LINK->Sent && LINK->Received && (LINK->SentAfterCompression || LINK->ReceivedAfterExpansion))
|
||||
Debugprintf("L2 Compression Stats %s %s TX %d %d %d%% RX %d %d %d%%", LINK->callingCall, LINK->receivingCall,
|
||||
if (LINK->Sent && LINK->Received && (LINK->SentAfterCompression || LINK->ReceivedAfterExpansion))
|
||||
Debugprintf("L2 Compression Stats %s %s TX %d %d %d%% RX %d %d %d%%", LINK->callingCall, LINK->receivingCall,
|
||||
LINK->Sent, LINK->SentAfterCompression, ((LINK->Sent - LINK->SentAfterCompression) * 100) / LINK->Sent,
|
||||
LINK->Received, LINK->ReceivedAfterExpansion, ((LINK->ReceivedAfterExpansion - LINK->Received) * 100) / LINK->Received);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _LINKTABLE * LINK)
|
||||
{
|
||||
LINK->ConnectTime = time(NULL);
|
||||
LINK->bytesTXed = LINK->bytesRXed = 0;
|
||||
LINK->bytesTXed = LINK->bytesRXed = LINK->framesResent = LINK->framesRXed = LINK->framesTXed = 0;
|
||||
|
||||
strcpy(LINK->callingCall, ourcall);
|
||||
strcpy(LINK->receivingCall, remotecall);
|
||||
|
|
@ -234,13 +233,72 @@ void hookL2SessionConnected(struct _LINKTABLE * LINK)
|
|||
int udplen;
|
||||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\"}",
|
||||
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall);
|
||||
|
||||
Debugprintf(UDPMsg);
|
||||
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
{
|
||||
LINK->lastStatusSentTime = time(NULL);
|
||||
|
||||
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\"}",
|
||||
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall);
|
||||
|
||||
// Debugprintf(UDPMsg);
|
||||
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
}
|
||||
}
|
||||
|
||||
void hookL2SessionClosed(struct _LINKTABLE * LINK, char * Reason, char * Direction)
|
||||
{
|
||||
// Link closed. Could be normal, ie disc send/received or restried out etc
|
||||
|
||||
char UDPMsg[1024];
|
||||
int udplen;
|
||||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
if (LINK->receivingCall[0] == 0 || LINK->callingCall[0] == 0)
|
||||
return;
|
||||
|
||||
if (strcmp(Direction, "Out") == 0)
|
||||
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkDownEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\","
|
||||
"\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d, \"reason\": \"%s\"}",
|
||||
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->receivingCall, LINK->callingCall,
|
||||
LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason);
|
||||
else
|
||||
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkDownEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\","
|
||||
"\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d, \"reason\": \"%s\"}",
|
||||
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall,
|
||||
LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason);
|
||||
|
||||
// Debugprintf(UDPMsg);
|
||||
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
}
|
||||
}
|
||||
|
||||
void hookL2SessionStatus(struct _LINKTABLE * LINK)
|
||||
{
|
||||
// Send at regular intervals on open links
|
||||
|
||||
char UDPMsg[1024];
|
||||
int udplen;
|
||||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
LINK->lastStatusSentTime = time(NULL);
|
||||
|
||||
if (strcmp(LINK->Direction, "Out") == 0)
|
||||
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkStatus\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\","
|
||||
"\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d}",
|
||||
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->receivingCall, LINK->callingCall,
|
||||
LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, 0, LINK->framesResent);
|
||||
else
|
||||
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkStatus\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\","
|
||||
"\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d}",
|
||||
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall,
|
||||
LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent);
|
||||
|
||||
// Debugprintf(UDPMsg);
|
||||
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -316,3 +374,795 @@ void hookL4SessionDeleted(struct TNCINFO * TNC, struct STREAMINFO * STREAM)
|
|||
}
|
||||
|
||||
|
||||
|
||||
void hookNodeStarted()
|
||||
{
|
||||
char UDPMsg[1024];
|
||||
int udplen;
|
||||
#ifdef LINBPQ
|
||||
char Software[80] = "LinBPQ";
|
||||
|
||||
if (sizeof(void *) == 4)
|
||||
strcat(Software, "(32 bit)");
|
||||
#else
|
||||
char Software[80] = "BPQ32";
|
||||
#endif
|
||||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
int ret;
|
||||
|
||||
udplen = sprintf(UDPMsg, "{\"@type\": \"NodeUpEvent\", \"nodeCall\": \"%s\", \"nodeAlias\": \"%s\", \"locator\": \"%s\","
|
||||
"\"latitude\": %f, \"longitude\": %f, \"software\": \"%s\", \"version\": \"%s\"}",
|
||||
NODECALLLOPPED, MYALIASLOPPED, LOC, LatFromLOC, LonFromLOC, Software, VersionString);
|
||||
|
||||
ret = sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
|
||||
if (ret != udplen)
|
||||
Debugprintf("%d %d %s", ret, WSAGetLastError(), UDPMsg);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hookNodeClosing(char * Reason)
|
||||
{
|
||||
char UDPMsg[1024];
|
||||
int udplen;
|
||||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
udplen = sprintf(UDPMsg, "{\"@type\": \"NodeDownEvent\", \"nodeCall\": \"%s\", \"nodeAlias\": \"%s\", \"reason\": \"%s\"}",
|
||||
NODECALLLOPPED, MYALIASLOPPED, Reason);
|
||||
|
||||
// Debugprintf(UDPMsg);
|
||||
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
}
|
||||
}
|
||||
|
||||
void hookNodeRunning()
|
||||
{
|
||||
char UDPMsg[1024];
|
||||
int udplen;
|
||||
#ifdef LINBPQ
|
||||
char Software[80] = "LinBPQ";
|
||||
|
||||
if (sizeof(void *) == 4)
|
||||
strcat(Software, "(32 bit)");
|
||||
#else
|
||||
char Software[80] = "BPQ32";
|
||||
#endif
|
||||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
|
||||
udplen = sprintf(UDPMsg, "{\"@type\": \"NodeStatus\", \"nodeCall\": \"%s\", \"nodeAlias\": \"%s\", \"locator\": \"%s\","
|
||||
"\"latitude\": %f, \"longitude\": %f, \"software\": \"%s\", \"version\": \"%s\", \"uptimeSecs\": %d}",
|
||||
NODECALLLOPPED, MYALIASLOPPED, LOC, LatFromLOC, LonFromLOC, Software, VersionString, time(NULL) - TimeLoaded);
|
||||
|
||||
|
||||
// Debugprintf(UDPMsg);
|
||||
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
}
|
||||
}
|
||||
|
||||
void IncomingL4ConnectionEvent(TRANSPORTENTRY * L4)
|
||||
{
|
||||
char UDPMsg[1024];
|
||||
int udplen;
|
||||
|
||||
char remotecall[64];
|
||||
char ourcall[64];
|
||||
char circuitinfo[32];
|
||||
|
||||
// CACK sent to CREQ
|
||||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
remotecall[ConvFromAX25(L4->L4TARGET.DEST->DEST_CALL, remotecall)] = 0;
|
||||
// remotecall[ConvFromAX25(L4->L4USER, remotecall)] = 0;
|
||||
ourcall[ConvFromAX25(L4->L4MYCALL, ourcall)] = 0;
|
||||
|
||||
sprintf(circuitinfo, ":%02x%02x", L4->FARINDEX, L4->FARID);
|
||||
strcat(remotecall, circuitinfo);
|
||||
|
||||
sprintf(circuitinfo, ":%02x%02x", L4->CIRCUITINDEX, L4->CIRCUITID);
|
||||
strcat(ourcall, circuitinfo);
|
||||
|
||||
udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\","
|
||||
"\"service\": %d, \"remote\": \"%s\", \"local\": \"%s\"}",
|
||||
NODECALLLOPPED, UDPSeq++, L4->Service, remotecall, ourcall);
|
||||
|
||||
// Debugprintf(UDPMsg);
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OutgoingL4ConnectionEvent(TRANSPORTENTRY * L4)
|
||||
{
|
||||
char UDPMsg[1024];
|
||||
int udplen;
|
||||
char remotecall[64];
|
||||
char ourcall[64];
|
||||
char circuitinfo[32];
|
||||
|
||||
// CACK received
|
||||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
remotecall[ConvFromAX25(L4->L4TARGET.DEST->DEST_CALL, remotecall)] = 0;
|
||||
// remotecall[ConvFromAX25(L4->L4USER, remotecall)] = 0;
|
||||
ourcall[ConvFromAX25(L4->L4MYCALL, ourcall)] = 0;
|
||||
|
||||
sprintf(circuitinfo, ":%02x%02x", L4->FARID, L4->FARINDEX);
|
||||
strcat(remotecall, circuitinfo);
|
||||
|
||||
sprintf(circuitinfo, ":%02x%02x", L4->CIRCUITID, L4->CIRCUITINDEX);
|
||||
strcat(ourcall, circuitinfo);
|
||||
|
||||
udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\","
|
||||
"\"service\": %d, \"remote\": \"%s\", \"local\": \"%s\"}",
|
||||
NODECALLLOPPED, UDPSeq++, L4->Service, remotecall, ourcall);
|
||||
|
||||
// Debugprintf(UDPMsg);
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"@type": "CircuitUpEvent",
|
||||
"node": "G8PZT"
|
||||
"id": 1,
|
||||
"direction": "incoming",
|
||||
"service": 0,
|
||||
"remote": "G8PZT@G8PZT:14c0",
|
||||
"local": "G8PZT-4:0001"
|
||||
}
|
||||
|
||||
|
||||
"segsSent": 5,
|
||||
"segsRcvd": 27,
|
||||
"segsResent": 0,
|
||||
"segsQueued": 0,
|
||||
"reason": "rcvd DREQ"
|
||||
|
||||
*/
|
||||
|
||||
void L4DisconnectEvent(TRANSPORTENTRY * L4, char * Direction, char * Reason)
|
||||
{
|
||||
char UDPMsg[1024];
|
||||
int udplen;
|
||||
char remotecall[64];
|
||||
char ourcall[64];
|
||||
char circuitinfo[32];
|
||||
int Count;
|
||||
|
||||
// CACK received
|
||||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
remotecall[ConvFromAX25(L4->L4TARGET.DEST->DEST_CALL, remotecall)] = 0;
|
||||
// remotecall[ConvFromAX25(L4->L4USER, remotecall)] = 0;
|
||||
ourcall[ConvFromAX25(L4->L4MYCALL, ourcall)] = 0;
|
||||
|
||||
sprintf(circuitinfo, ":%02x%02x", L4->FARINDEX, L4->FARID);
|
||||
strcat(remotecall, circuitinfo);
|
||||
|
||||
sprintf(circuitinfo, ":%02x%02x", L4->CIRCUITINDEX, L4->CIRCUITID);
|
||||
strcat(ourcall, circuitinfo);
|
||||
|
||||
|
||||
if (L4->L4CROSSLINK) // CONNECTED?
|
||||
Count = CountFramesQueuedOnSession(L4->L4CROSSLINK);
|
||||
else
|
||||
Count = CountFramesQueuedOnSession(L4);
|
||||
|
||||
udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitDownEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"%s\","
|
||||
"\"service\": %d, \"remote\": \"%s\", \"local\": \"%s\", \"segsSent\": %d, \"segsRcvd\": %d, \"segsResent\": %d, \"segsQueued\": %d, \"reason\": \"%s\"}",
|
||||
NODECALLLOPPED, UDPSeq++, Direction, 0, remotecall, ourcall,L4->segsSent, L4->segsRcvd, L4->segsResent, Count, Reason);
|
||||
|
||||
// Debugprintf(UDPMsg);
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
}
|
||||
}
|
||||
|
||||
void L4StatusSeport(TRANSPORTENTRY * L4)
|
||||
{
|
||||
char UDPMsg[1024];
|
||||
int udplen;
|
||||
char remotecall[64];
|
||||
char ourcall[64];
|
||||
char nodecall[16];
|
||||
char circuitinfo[32];
|
||||
int Count;
|
||||
|
||||
// CACK received
|
||||
|
||||
if (NodeAPISocket)
|
||||
{
|
||||
nodecall[ConvFromAX25(L4->L4TARGET.DEST->DEST_CALL, nodecall)] = 0;
|
||||
remotecall[ConvFromAX25(L4->L4USER, remotecall)] = 0;
|
||||
ourcall[ConvFromAX25(L4->L4MYCALL, ourcall)] = 0;
|
||||
|
||||
sprintf(circuitinfo, ":%02x%02x", L4->FARINDEX, L4->FARID);
|
||||
strcat(remotecall, circuitinfo);
|
||||
|
||||
sprintf(circuitinfo, ":%02x%02x", L4->CIRCUITINDEX, L4->CIRCUITID);
|
||||
strcat(ourcall, circuitinfo);
|
||||
|
||||
|
||||
if (L4->L4CROSSLINK) // CONNECTED?
|
||||
Count = CountFramesQueuedOnSession(L4->L4CROSSLINK);
|
||||
else
|
||||
Count = CountFramesQueuedOnSession(L4);
|
||||
|
||||
udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitStatus\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\","
|
||||
"\"service\": %d, \"remote\": %s, \"local\": \"%s\", \"segsSent\": %d, \"segsRcvd\": %d, \"segsResent\": %d, \"segsQueued\": %d}",
|
||||
NODECALLLOPPED, UDPSeq++, 0, remotecall, ourcall,L4->segsSent, L4->segsRcvd, L4->segsResent, Count);
|
||||
|
||||
// Debugprintf(UDPMsg);
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// L2/3/4 Tracing
|
||||
|
||||
#define PFBIT 0x10 // POLL/FINAL BIT IN CONTROL BYTE
|
||||
#define NETROM_PID 0xCF
|
||||
#define IP_PID 0xCC
|
||||
#define ARP_PID 0xCD
|
||||
|
||||
char * PIDtoText(int PID)
|
||||
{
|
||||
switch (PID)
|
||||
{
|
||||
case 240:
|
||||
return "DATA";
|
||||
case NETROM_PID:
|
||||
return "NET/ROM";
|
||||
case IP_PID:
|
||||
return "IP";
|
||||
case ARP_PID:
|
||||
return "ARP";
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
void APIL2Trace(struct _MESSAGE * Message, char Dirn)
|
||||
{
|
||||
char UDPMsg[2048];
|
||||
int udplen;
|
||||
char srcecall[64];
|
||||
char destcall[16];
|
||||
char CR[3] = "";
|
||||
char PF[2] = "";
|
||||
int iLen = 0;
|
||||
int CTL = Message->CTL;
|
||||
char Type[16] = "Unknown";
|
||||
int UIFlag = 0;
|
||||
int IFlag = 0;
|
||||
int UFlag = 0;
|
||||
int NS;
|
||||
int NR;
|
||||
|
||||
if ((Message->ORIGIN[6] & 1) == 0) // Digis
|
||||
return;
|
||||
|
||||
destcall[ConvFromAX25(Message->DEST, destcall)] = 0;
|
||||
srcecall[ConvFromAX25(Message->ORIGIN, srcecall)] = 0;
|
||||
|
||||
// See if any Digis
|
||||
|
||||
if ((Message->ORIGIN[6] & 1) == 0) // Digis - ignore for now
|
||||
return;
|
||||
|
||||
|
||||
if ((Message->DEST[6] & 0x80) == 0 && (Message->ORIGIN[6] & 0x80) == 0)
|
||||
strcpy(CR, "V1");
|
||||
else if ((Message->DEST[6] & 0x80))
|
||||
strcpy(CR, "C");
|
||||
else if (Message->ORIGIN[6] & 0x80)
|
||||
strcpy(CR, "R");
|
||||
else
|
||||
strcpy(CR, "V1");
|
||||
|
||||
if (CTL & PFBIT)
|
||||
{
|
||||
if (CR[0] == 'C')
|
||||
PF[0] = 'P';
|
||||
else if (CR[0] == 'R')
|
||||
PF[0] = 'F';
|
||||
}
|
||||
|
||||
CTL &= ~PFBIT;
|
||||
|
||||
if ((CTL & 1) == 0) // I frame
|
||||
{
|
||||
NS = (CTL >> 1) & 7; // ISOLATE RECEIVED N(S)
|
||||
NR = (CTL >> 5) & 7;
|
||||
|
||||
IFlag = 1;
|
||||
iLen = Message->LENGTH - (MSGHDDRLEN + 16); // Dest origin ctl pid
|
||||
|
||||
strcpy(Type, "I");
|
||||
}
|
||||
else if (CTL == 3)
|
||||
{
|
||||
// Un-numbered Information Frame
|
||||
|
||||
strcpy(Type, "UI");
|
||||
UIFlag = 1;
|
||||
iLen = Message->LENGTH - (MSGHDDRLEN + 16); // Dest origin ctl pid
|
||||
}
|
||||
|
||||
if (CTL & 2)
|
||||
{
|
||||
// UnNumbered
|
||||
|
||||
UFlag = 1;
|
||||
|
||||
switch (CTL)
|
||||
{
|
||||
case SABM:
|
||||
|
||||
strcpy(Type, "C");
|
||||
break;
|
||||
|
||||
case SABME:
|
||||
|
||||
strcpy(Type, "SABME");
|
||||
break;
|
||||
|
||||
case XID:
|
||||
|
||||
strcpy(Type, "XID");
|
||||
break;
|
||||
|
||||
case TEST:
|
||||
|
||||
strcpy(Type, "TEST");
|
||||
break;
|
||||
|
||||
case DISC:
|
||||
|
||||
strcpy(Type, "D");
|
||||
break;
|
||||
|
||||
case DM:
|
||||
|
||||
strcpy(Type, "DM");
|
||||
break;
|
||||
|
||||
case UA:
|
||||
|
||||
strcpy(Type, "UA");
|
||||
break;
|
||||
|
||||
|
||||
case FRMR:
|
||||
|
||||
strcpy(Type, "FRMR");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Super
|
||||
|
||||
NR = (CTL >> 5) & 7;
|
||||
NS = (CTL >> 1) & 7; // ISOLATE RECEIVED N(S)
|
||||
|
||||
switch (CTL & 0x0F)
|
||||
{
|
||||
case RR:
|
||||
|
||||
strcpy(Type, "RR");
|
||||
break;
|
||||
|
||||
case RNR:
|
||||
|
||||
strcpy(Type, "RNR");
|
||||
break;
|
||||
|
||||
case REJ:
|
||||
|
||||
strcpy(Type, "REJ");
|
||||
break;
|
||||
|
||||
case SREJ:
|
||||
|
||||
strcpy(Type, "SREJ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Common to all frame types
|
||||
|
||||
udplen = snprintf(UDPMsg, 2048,
|
||||
"{\"@type\": \"L2Trace\", \"reportFrom\": \"%s\", \"port\": \"%d\", \"srce\": \"%s\", \"dest\": \"%s\", \"ctrl\": %d,"
|
||||
"\"l2type\": \"%s\", \"modulo\": 8, \"cr\": \"%s\"",
|
||||
NODECALLLOPPED, Message->PORT, srcecall, destcall, Message->CTL, Type, CR);
|
||||
|
||||
if (UIFlag)
|
||||
{
|
||||
udplen += snprintf(&UDPMsg[udplen], 2048 - udplen,
|
||||
", \"ilen\": %d, \"pid\": %d, \"ptcl\": \"%s\"", iLen, Message->PID, PIDtoText(Message->PID));
|
||||
|
||||
if (Message->PID == NETROM_PID)
|
||||
{
|
||||
udplen += decodeNETROMUIMsg(Message->L2DATA, iLen, &UDPMsg[udplen], 2048 - udplen);
|
||||
}
|
||||
}
|
||||
else if (IFlag)
|
||||
{
|
||||
if (PF[0])
|
||||
udplen += snprintf(&UDPMsg[udplen], 2048 - udplen,
|
||||
", \"ilen\": %d, \"pid\": %d, \"ptcl\": \"%s\", \"pf\": \"%s\", \"rseq\": %d, \"tseq\": %d",
|
||||
iLen, Message->PID, PIDtoText(Message->PID), PF, NR, NS);
|
||||
else
|
||||
udplen += snprintf(&UDPMsg[udplen], 2048 - udplen,
|
||||
", \"ilen\": %d, \"pid\": %d, \"ptcl\": \"%s\", \"rseq\": %d, \"tseq\": %d",
|
||||
iLen, Message->PID, PIDtoText(Message->PID), NR, NS);
|
||||
|
||||
if (Message->PID == NETROM_PID)
|
||||
{
|
||||
int n = decodeNETROMIFrame(Message->L2DATA, iLen, &UDPMsg[udplen], 2048 - udplen);
|
||||
|
||||
if (n == 0)
|
||||
return; // Can't decode so don't trace anything;
|
||||
|
||||
udplen += n;
|
||||
}
|
||||
|
||||
}
|
||||
else if (UFlag)
|
||||
{
|
||||
if (PF[0])
|
||||
udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, ", \"pf\": \"%s\"", PF);
|
||||
}
|
||||
else
|
||||
{
|
||||
// supervisory
|
||||
|
||||
if (PF[0])
|
||||
udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, ", \"pf\": \"%s\", \"rseq\": %d, \"tseq\": %d", PF, NR, NS);
|
||||
else
|
||||
udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, ", \"rseq\": %d, \"tseq\": %d", NR, NS);
|
||||
}
|
||||
|
||||
|
||||
UDPMsg[udplen++] = '}';
|
||||
UDPMsg[udplen] = 0;
|
||||
// Debugprintf(UDPMsg);
|
||||
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
|
||||
|
||||
}
|
||||
|
||||
|
||||
int decodeNETROMUIMsg(unsigned char * Msg, int iLen, char * Buffer, int BufferLen)
|
||||
{
|
||||
int Len = 0;
|
||||
|
||||
// UI with NETROM PID are assumed to by NODES broadcast (INP3 routes are sent in I frames)
|
||||
|
||||
// But check first byte is 0xff to be sure, or 0xfe for Paula's char Alias[7]= "";
|
||||
|
||||
char Dest[10];
|
||||
char Node[10];
|
||||
char Alias[10] = "";
|
||||
|
||||
memcpy(Alias, &Msg[1], 6);
|
||||
strlop(Alias, ' ');
|
||||
|
||||
if (Msg[0] == 0xfe) // Paula's Nodes Poll
|
||||
{
|
||||
Len = snprintf(Buffer, BufferLen, ", \"l3Type\": \"Routing info\", \"type\": \"Routing poll\"");
|
||||
return Len;
|
||||
}
|
||||
|
||||
if (Msg[0] != 0xff)
|
||||
return 0;
|
||||
|
||||
Msg += 7; // to first field
|
||||
|
||||
Len = snprintf(Buffer, BufferLen, ", \"l3Type\": \"Routing info\", \"type\": \"NODES\", \"nodes\": [");
|
||||
|
||||
iLen -= 7; //Header, mnemonic and signature length
|
||||
|
||||
if (iLen < 21) // No Entries
|
||||
{
|
||||
Buffer[Len++] = ']';
|
||||
return Len;
|
||||
}
|
||||
|
||||
while(iLen > 20) // Entries are 21 bytes
|
||||
{
|
||||
Dest[ConvFromAX25(Msg, Dest)] = 0;
|
||||
Msg +=7;
|
||||
memcpy(Alias, Msg, 6);
|
||||
Msg +=6;
|
||||
strlop(Alias, ' ');
|
||||
Node[ConvFromAX25(Msg, Node)] = 0;
|
||||
Msg +=7;
|
||||
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, "{\"call\": \"%s\", \"alias\": \"%s\", \"via\": \"%s\", \"qual\": %d},", Dest, Alias, Node, Msg[0]);
|
||||
Msg++;
|
||||
iLen -= 21;
|
||||
}
|
||||
// Have to replace trailing , with ]
|
||||
|
||||
Buffer[Len - 1] = ']';
|
||||
return Len;
|
||||
}
|
||||
|
||||
int decodeNETROMIFrame(unsigned char * Msg, int iLen, char * Buffer, int BufferLen)
|
||||
{
|
||||
int Len = 0;
|
||||
L3MESSAGE * L3MSG = (L3MESSAGE *)Msg;
|
||||
char srcecall[64];
|
||||
char destcall[16];
|
||||
char srcUser[16];
|
||||
char srcNode[16];
|
||||
int Opcode;
|
||||
int netromx = 0;
|
||||
int service = 0;
|
||||
|
||||
|
||||
if (Msg[0] == 0xff) // RIF?
|
||||
return decodeINP3RIF(&Msg[1], iLen - 1, Buffer, BufferLen);
|
||||
|
||||
// Netrom L3 /4 frame. Do standard L3 header
|
||||
|
||||
destcall[ConvFromAX25(L3MSG->L3DEST, destcall)] = 0;
|
||||
srcecall[ConvFromAX25(L3MSG->L3SRCE, srcecall)] = 0;
|
||||
|
||||
if (strcmp(destcall, "KEEPLI") == 0)
|
||||
return 0;
|
||||
|
||||
Len = snprintf(Buffer, BufferLen, ", \"l3Type\": \"NetRom\", \"l3src\": \"%s\", \"l3dst\": \"%s\", \"ttl\": %d", srcecall, destcall, L3MSG->L3TTL);
|
||||
|
||||
// L4 Stuff
|
||||
|
||||
Opcode = L3MSG->L4FLAGS & 15;
|
||||
|
||||
switch (Opcode)
|
||||
{
|
||||
case 0:
|
||||
|
||||
// OPCODE 0 is used for a variety of functions, using L4INDEX and L4ID as qualifiers
|
||||
// 0c0c is used for IP. Ignore for now
|
||||
|
||||
// 00 01 Seesm to be Netrom Record Route
|
||||
|
||||
if (L3MSG->L4ID == 1 && L3MSG->L4INDEX == 0)
|
||||
{
|
||||
Len += decodeRecordRoute(L3MSG, iLen, &Buffer[Len], BufferLen - Len);
|
||||
return Len;
|
||||
}
|
||||
|
||||
case L4CREQX:
|
||||
|
||||
netromx = 1;
|
||||
service = (L3MSG->L4RXNO << 8) | L3MSG->L4TXNO;
|
||||
|
||||
case L4CREQ:
|
||||
|
||||
srcUser[ConvFromAX25(&L3MSG->L4DATA[1], srcUser)] = 0;
|
||||
srcNode[ConvFromAX25(&L3MSG->L4DATA[8], srcNode)] = 0;
|
||||
|
||||
if (netromx)
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"CONN REQX\", \"fromCct\": %d, \"srcUser\": \"%s\", \"srcNode\": \"%s\", \"window\": %d, \"service\": %d",
|
||||
(L3MSG->L4INDEX << 8) | L3MSG->L4ID, srcUser, srcNode, L3MSG->L4DATA[0], service);
|
||||
else
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"CONN REQ\", \"fromCct\": %d, \"srcUser\": \"%s\", \"srcNode\": \"%s\", \"window\": %d",
|
||||
(L3MSG->L4INDEX << 8) | L3MSG->L4ID, srcUser, srcNode, L3MSG->L4DATA[0]);
|
||||
|
||||
return Len;
|
||||
|
||||
case L4CACK:
|
||||
|
||||
// Can be ACK or NACK depending on Choke flag
|
||||
|
||||
if (L3MSG->L4FLAGS & L4BUSY)
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"CONN NACK\", \"toCct\": %d",
|
||||
(L3MSG->L4INDEX << 8) | L3MSG->L4ID);
|
||||
else
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"CONN ACK\", \"toCct\": %d, \"fromCct\": %d, \"accWin\": %d",
|
||||
(L3MSG->L4INDEX << 8) | L3MSG->L4ID, (L3MSG->L4TXNO << 8) | L3MSG->L4RXNO, L3MSG->L4DATA[0]);
|
||||
|
||||
return Len;
|
||||
|
||||
|
||||
case L4INFO:
|
||||
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"INFO\", \"toCct\": %d, \"txSeq\": %d, \"rxSeq\": %d, \"paylen\": %d",
|
||||
(L3MSG->L4INDEX << 8) | L3MSG->L4ID, L3MSG->L4TXNO, L3MSG->L4RXNO, iLen - 20);
|
||||
|
||||
return Len;
|
||||
|
||||
case L4IACK:
|
||||
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"INFO ACK\", \"toCct\": %d, \"rxSeq\": %d",
|
||||
(L3MSG->L4INDEX << 8) | L3MSG->L4ID, L3MSG->L4RXNO);
|
||||
|
||||
return Len;
|
||||
|
||||
|
||||
case L4DREQ:
|
||||
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"DISC REQ\", \"toCct\": %d", (L3MSG->L4INDEX << 8) | L3MSG->L4ID);
|
||||
return Len;
|
||||
|
||||
case L4DACK:
|
||||
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"DISC ACK\", \"toCct\": %d", (L3MSG->L4INDEX << 8) | L3MSG->L4ID);
|
||||
return Len;
|
||||
|
||||
case L4RESET:
|
||||
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"RSET\", \"fromCct\": %d", (L3MSG->L4INDEX << 8) | L3MSG->L4ID);
|
||||
return Len;
|
||||
|
||||
|
||||
/*
|
||||
"NRR Request" Netrom Record Route Request
|
||||
"NRR Reply" Netrom Record Route Reply
|
||||
"CONN REQ" Connect Request
|
||||
"CONN REQX" Extended Connect Request
|
||||
"CONN ACK" Connection Acknowledgement
|
||||
"CONN NAK" Connection Negative Ack (refusal)
|
||||
"DISC REQ" Disconnect request
|
||||
"DISC ACK" Disconnect Acknowledgement
|
||||
"INFO" Information-bearing frame
|
||||
"INFO ACK" Acknowledgement for an INFO frame.
|
||||
"RSET" Circuit Reset (kill)
|
||||
"PROT EXT" Protocol Extension (e.g. IP, NCMP etc)
|
||||
"unknown" Unrecognised type (shouldn't happen)
|
||||
|
||||
|
||||
|
||||
|
||||
"l4type": "CONN ACK",
|
||||
"fromCct": 10,
|
||||
"toCct": 23809,
|
||||
"accWin": 4,
|
||||
*/
|
||||
|
||||
}
|
||||
return Len;
|
||||
}
|
||||
|
||||
int decodeRecordRoute(L3MESSAGE * L3, int iLen, char * Buffer, int BufferLen)
|
||||
{
|
||||
int Len = 0;
|
||||
char callList[512];
|
||||
char * ptr1 = callList;
|
||||
unsigned char * ptr = L3->L4DATA;
|
||||
char call[16];
|
||||
int Response = 0;
|
||||
|
||||
iLen -= 20;
|
||||
|
||||
while (iLen > 0)
|
||||
{
|
||||
call[ConvFromAX25(ptr, call)] = 0;
|
||||
|
||||
ptr1 += sprintf(ptr1, " %s", call);
|
||||
|
||||
if ((ptr[7] & 0x80) == 0x80) // Check turnround bit
|
||||
{
|
||||
*ptr1++ = '*';
|
||||
Response = 1;
|
||||
}
|
||||
|
||||
ptr += 8;
|
||||
iLen -= 8;
|
||||
}
|
||||
|
||||
*ptr1 = 0;
|
||||
|
||||
if (Response)
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"NRR Reply\", \"nrrId\": %d, \"nrrRoute\": \"%s\"",
|
||||
(L3->L4TXNO << 8) | L3->L4RXNO, callList);
|
||||
else
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"NRR Request\", \"nrrId\": %d, \"nrrRoute\": \"%s\"",
|
||||
(L3->L4TXNO << 8) | L3->L4RXNO, callList);
|
||||
|
||||
Debugprintf(Buffer);
|
||||
|
||||
return Len;
|
||||
}
|
||||
|
||||
|
||||
int decodeINP3RIF(unsigned char * Msg, int iLen, char * Buffer, int BufferLen)
|
||||
{
|
||||
char call[10];
|
||||
int calllen;
|
||||
int hops;
|
||||
unsigned short rtt;
|
||||
unsigned int len;
|
||||
unsigned int opcode;
|
||||
char alias[10] = "";
|
||||
UCHAR IP[6];
|
||||
int i;
|
||||
int Len = 0;
|
||||
|
||||
Len = snprintf(Buffer, BufferLen, ", \"l3Type\": \"Routing info\", \"type\": \"INP3\", \"nodes\": [");
|
||||
|
||||
if (iLen < 10) // No Entries
|
||||
{
|
||||
Buffer[Len++] = ']';
|
||||
return Len;
|
||||
}
|
||||
|
||||
while (iLen > 1)
|
||||
{
|
||||
calllen = ConvFromAX25(Msg, call);
|
||||
call[calllen] = 0;
|
||||
|
||||
// Validate the call
|
||||
|
||||
for (i = 0; i < calllen; i++)
|
||||
{
|
||||
if (!isupper(call[i]) && !isdigit(call[i]) && call[i] != '-')
|
||||
return 0;
|
||||
}
|
||||
|
||||
Msg+=7;
|
||||
|
||||
hops = *Msg++;
|
||||
rtt = (*Msg++ << 8);
|
||||
rtt += *Msg++;
|
||||
|
||||
IP[0] = 0;
|
||||
strcpy(alias, " ");
|
||||
|
||||
iLen -= 10;
|
||||
|
||||
// Process optional fields
|
||||
|
||||
while (*Msg && iLen > 0) // Have an option
|
||||
{
|
||||
len = *Msg;
|
||||
opcode = *(Msg+1);
|
||||
|
||||
if (len < 2 || len > iLen)
|
||||
return 0;
|
||||
|
||||
if (opcode == 0 && len < 9)
|
||||
{
|
||||
memcpy(alias, Msg+2, len-2);
|
||||
}
|
||||
else if (opcode == 1 && len < 8)
|
||||
{
|
||||
memcpy(IP, Msg+2, len-2);
|
||||
}
|
||||
|
||||
Msg += len;
|
||||
iLen -= len;
|
||||
|
||||
}
|
||||
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, "{\"call\": \"%s\", \"hops\": %d, \"tt\": %d", call, hops, rtt);
|
||||
|
||||
if (alias[0] > ' ')
|
||||
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"alias\": \"%s\"", alias);
|
||||
|
||||
Buffer[Len++] = '}';
|
||||
Buffer[Len++] = ',';
|
||||
|
||||
Msg++;
|
||||
iLen--; // Over EOP
|
||||
|
||||
}
|
||||
// Have to replace trailing , with ]
|
||||
|
||||
Buffer[Len - 1] = ']';
|
||||
return Len;
|
||||
}
|
||||
|
||||
|
|
|
|||
8
FLDigi.c
8
FLDigi.c
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
104
L2Code.c
104
L2Code.c
|
|
@ -125,9 +125,14 @@ 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
|
||||
|
|
@ -142,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;
|
||||
|
|
@ -1081,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);
|
||||
|
||||
|
|
@ -1276,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
|
||||
{
|
||||
|
|
@ -1839,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
|
||||
|
|
@ -2050,6 +2071,8 @@ 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);
|
||||
|
|
@ -2093,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)
|
||||
|
|
@ -2255,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?
|
||||
|
|
@ -2332,6 +2364,9 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
|
|||
return;
|
||||
}
|
||||
|
||||
treatasRR:
|
||||
|
||||
|
||||
// VALID RR/RNR RECEIVED
|
||||
|
||||
LINK->L2FLAGS &= ~RNRSET; //CLEAR RNR
|
||||
|
|
@ -2664,6 +2699,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
|
||||
|
||||
|
|
@ -3239,6 +3275,10 @@ VOID SDETX(struct _LINKTABLE * LINK)
|
|||
LINK->FRAMES[LINK->SDTSLOT] = Msg;
|
||||
LINK->SDTSLOT ++;
|
||||
LINK->SDTSLOT &= 7;
|
||||
|
||||
LINK->framesTXed++;
|
||||
LINK->bytesTXed += sendLen;
|
||||
|
||||
|
||||
compdata += sendLen;
|
||||
complen -= sendLen;
|
||||
|
|
@ -3252,6 +3292,9 @@ VOID SDETX(struct _LINKTABLE * LINK)
|
|||
LINK->FRAMES[LINK->SDTSLOT] = Msg;
|
||||
LINK->SDTSLOT ++;
|
||||
LINK->SDTSLOT &= 7;
|
||||
|
||||
LINK->framesTXed++;
|
||||
LINK->bytesTXed += (Msg->LENGTH - (MSGHDDRLEN + 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3350,6 +3393,7 @@ VOID L2TimerProc()
|
|||
int i = MAXLINKS;
|
||||
struct _LINKTABLE * LINK = LINKS;
|
||||
struct PORTCONTROL * PORT = PORTTABLE;
|
||||
time_t Now = time(NULL);
|
||||
|
||||
while (i--)
|
||||
{
|
||||
|
|
@ -3357,8 +3401,14 @@ VOID L2TimerProc()
|
|||
{
|
||||
LINK++;
|
||||
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;
|
||||
|
|
@ -3721,6 +3771,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
|
||||
|
|
@ -4100,20 +4152,21 @@ 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
|
||||
|
||||
// if we support SREJ send that instesd or REJ
|
||||
// Dont send SREJ if clearing RNR - causes FRMR
|
||||
|
||||
// Dont send SREJ if clearing RNR - causes FRMR
|
||||
// Latest Spec says shouldn't send SREJ as Command
|
||||
|
||||
// Latest Spec says shouldn't send SREJ as Command
|
||||
if (SaveRNRSent || CMD == 1)
|
||||
return REJ;
|
||||
|
||||
if (SaveRNRSent || CMD == 1)
|
||||
return REJ;
|
||||
|
||||
if (LINK->Ver2point2) // We only allow 2.2 with SREJ Multi
|
||||
return SREJ;
|
||||
else
|
||||
return REJ;
|
||||
if (LINK->Ver2point2) // We only allow 2.2 with SREJ Multi
|
||||
return SREJ;
|
||||
else
|
||||
return REJ;
|
||||
}
|
||||
}
|
||||
return RR;
|
||||
|
||||
|
|
@ -4708,5 +4761,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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
21
L3Code.c
21
L3Code.c
|
|
@ -61,9 +61,11 @@ 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;
|
||||
|
|
@ -98,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)
|
||||
{
|
||||
|
|
@ -990,7 +1000,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;
|
||||
|
|
@ -1121,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
|
||||
|
|
|
|||
424
L4Code.c
424
L4Code.c
|
|
@ -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,12 +484,21 @@ VOID SENDL4CONNECT(TRANSPORTENTRY * Session)
|
|||
|
||||
MSG->L4INDEX = Session->CIRCUITINDEX;
|
||||
MSG->L4ID = Session->CIRCUITID;
|
||||
MSG->L4TXNO = 0;
|
||||
MSG->L4RXNO = 0;
|
||||
MSG->L4FLAGS = L4CREQ;
|
||||
|
||||
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
|
||||
|
||||
|
||||
memcpy(&MSG->L4DATA[1], Session->L4USER, 7); // ORIG CALL
|
||||
memcpy(&MSG->L4DATA[8], Session->L4MYCALL, 7);
|
||||
|
||||
|
|
@ -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,25 @@ 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] = "";
|
||||
|
||||
memcpy(APPLCMD, APPL->APPLCMD, 13);
|
||||
|
||||
memcpy(BPQPARAMS, &L4T1, 2); // SET DEFAULT T1 IN CASE NOT FROM ANOTHER BPQ NODE
|
||||
|
||||
|
|
@ -1608,8 +1629,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 +1641,58 @@ 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.
|
||||
|
||||
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 +1704,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 +1719,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 +1822,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 +1909,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 +1929,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 +1948,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 +1967,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
|
||||
|
||||
|
|
@ -2020,6 +2105,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 +2135,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 +2158,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 +2167,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 +2247,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 +2288,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 +2743,32 @@ VOID SENDL4IACK(TRANSPORTENTRY * Session)
|
|||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
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
|
||||
Closed++;
|
||||
|
||||
POP ECX
|
||||
POP ESI
|
||||
POP EBX
|
||||
|
||||
RET
|
||||
Partner = L4->L4CROSSLINK;
|
||||
|
||||
PUBLIC xxx
|
||||
xxx:
|
||||
|
||||
POP ECX
|
||||
POP ESI
|
||||
REP MOVSB
|
||||
CLOSECURRENTSESSION(L4);
|
||||
|
||||
if (Partner)
|
||||
CLOSECURRENTSESSION(Partner); // CLOSE THIS ONE
|
||||
|
||||
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
|
||||
*/
|
||||
L4++;
|
||||
}
|
||||
return Closed;
|
||||
}
|
||||
|
|
|
|||
27
LinBPQ.c
27
LinBPQ.c
|
|
@ -83,6 +83,8 @@ void RHPPoll();
|
|||
|
||||
VOID GetPGConfig();
|
||||
void SendBBSDataToPktMap();
|
||||
void CloseAllLinks();
|
||||
void hookNodeClosing(char * Reason);
|
||||
|
||||
extern uint64_t INP3timeLoadedMS;
|
||||
|
||||
|
|
@ -262,9 +264,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 +339,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,7 +347,8 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
|
|||
// CTRL-CLOSE: confirm that the user wants to exit.
|
||||
case CTRL_CLOSE_EVENT:
|
||||
|
||||
CLOSING = TRUE;
|
||||
CloseAllLinks();
|
||||
CLOSING = TRUE;
|
||||
printf( "Ctrl-Close event\n\n" );
|
||||
Sleep(20000);
|
||||
Beep( 750, 300 );
|
||||
|
|
@ -354,7 +358,8 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
|
|||
case CTRL_BREAK_EVENT:
|
||||
Beep( 900, 200 );
|
||||
printf( "Ctrl-Break event\n\n" );
|
||||
CLOSING = TRUE;
|
||||
CloseAllLinks();
|
||||
CLOSING = TRUE;
|
||||
Beep( 750, 300 );
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -366,7 +371,8 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
|
|||
case CTRL_SHUTDOWN_EVENT:
|
||||
Beep( 750, 500 );
|
||||
printf( "Ctrl-Shutdown event\n\n" );
|
||||
CLOSING = TRUE;
|
||||
CloseAllLinks();
|
||||
CLOSING = TRUE;
|
||||
Beep( 750, 300 );
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -399,6 +405,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 +428,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 +439,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();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1682,6 +1696,9 @@ int main(int argc, char * argv[])
|
|||
Slowtimer = 0;
|
||||
}
|
||||
|
||||
hookNodeClosing("Shutdown");
|
||||
Sleep(500);
|
||||
|
||||
printf("Closing Ports\n");
|
||||
|
||||
CloseTNCEmulator();
|
||||
|
|
|
|||
18
Moncode.c
18
Moncode.c
|
|
@ -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
|
||||
|
|
@ -722,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++);
|
||||
|
|
@ -730,7 +737,10 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
|
|||
Node[ConvFromAX25(ptr, Node)] = 0;
|
||||
ptr +=7;
|
||||
|
||||
Output += sprintf((char *)Output, "<CON REQ> w=%d %s at %s", Window, Dest, Node);
|
||||
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
|
||||
{
|
||||
|
|
@ -745,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:
|
||||
|
||||
|
|
|
|||
551
NETROMTCP.c
Normal file
551
NETROMTCP.c
Normal file
|
|
@ -0,0 +1,551 @@
|
|||
/*
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
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 hints, *res = 0, *saveres;
|
||||
int Port = Route->TCPPort;
|
||||
|
||||
sprintf(PortString, "%d", Port);
|
||||
|
||||
// get host info, make socket, and connect it
|
||||
|
||||
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);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
err = WSAGetLastError();
|
||||
Debugprintf("Resolve HostName %s Failed - Error %d", Route->TCPHost, err);
|
||||
return FALSE; // Resolve failed
|
||||
}
|
||||
|
||||
// Step thorough the list of hosts
|
||||
|
||||
saveres = res; // Save for free
|
||||
|
||||
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, ¶m);
|
||||
|
||||
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;
|
||||
freeaddrinfo(saveres);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
freeaddrinfo(saveres);
|
||||
|
||||
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.
|
||||
|
||||
memcpy(Info->Call, Msg->Call, 10);
|
||||
|
||||
ConvToAX25(Msg->Call, axCall);
|
||||
|
||||
if (FindNeighbour(axCall, portNo, &Route))
|
||||
{
|
||||
Info->Route = Route;
|
||||
Route->NEIGHBOUR_LINK = Info->LINK;
|
||||
Info->LINK->NEIGHBOUR = Route;
|
||||
Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT);
|
||||
Route->TCPSession = Info;
|
||||
Info->LINK->L2STATE = 5;
|
||||
|
||||
if (Info->Route->INP3Node)
|
||||
SendRTTMsg(Info->Route);
|
||||
}
|
||||
else
|
||||
goto seeifMore; // Should we kill connection?
|
||||
}
|
||||
|
||||
|
||||
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 = 0;
|
||||
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);
|
||||
|
||||
Route->TCPSession = 0;
|
||||
|
||||
Info->Call[0] = 0;
|
||||
}
|
||||
|
||||
sockptr->SocketActive = FALSE;
|
||||
|
||||
memset(sockptr, 0, sizeof(struct ConnectionInfo));
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
115
TelnetV6.c
115
TelnetV6.c
|
|
@ -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, ¶m);
|
||||
|
||||
sockptr->NETROMMode = TRUE;
|
||||
NETROMConnectionAccepted(sockptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find a free Session
|
||||
|
||||
for (n = 1; n <= TCP->MaxSessions; n++)
|
||||
|
|
@ -3307,7 +3381,8 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
|
|||
TNC->Streams[n].FramesQueued = 0;
|
||||
|
||||
sockptr->HTTPMode = FALSE;
|
||||
sockptr->APIMode = 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
|
||||
|
|
@ -3358,7 +3436,7 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
|
|||
|
||||
if (sockptr->HTTPMode)
|
||||
return 0;
|
||||
|
||||
|
||||
if (sockptr->DRATSMode)
|
||||
{
|
||||
send(sock, "100 Authentication not required\n", 33, 0);
|
||||
|
|
@ -5271,6 +5349,7 @@ int DataSocket_ReadDRATS(struct TNCINFO * TNC, struct ConnectionInfo * sockptr,
|
|||
}
|
||||
|
||||
|
||||
|
||||
int DataSocket_Disconnect(struct TNCINFO * TNC, struct ConnectionInfo * sockptr)
|
||||
{
|
||||
int n;
|
||||
|
|
@ -5685,7 +5764,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
|
||||
|
|
|
|||
5
UIARQ.c
5
UIARQ.c
|
|
@ -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];
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
5
VARA.c
5
VARA.c
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
#endif
|
||||
|
||||
#define KVers 6,0,25,6
|
||||
#define KVerstring "6.0.25.6\0"
|
||||
#define KVers 6,0,25,8
|
||||
#define KVerstring "6.0.25.8\0"
|
||||
|
||||
|
||||
#ifdef CKernel
|
||||
|
|
|
|||
5
WINMOR.c
5
WINMOR.c
|
|
@ -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;
|
||||
|
|
|
|||
29
asmstrucs.h
29
asmstrucs.h
|
|
@ -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
|
||||
|
|
@ -177,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;
|
||||
|
||||
|
|
@ -220,6 +228,7 @@ 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
|
||||
|
|
@ -239,6 +248,10 @@ typedef struct ROUTE
|
|||
int RemoteMAXRTT; // For INP3
|
||||
int RemoteMAXHOPS;
|
||||
|
||||
char * TCPHost; // For NETROM over TCP
|
||||
int TCPPort;
|
||||
struct NRTCPSTRUCT * TCPSession;
|
||||
|
||||
} *PROUTE;
|
||||
|
||||
// Status Equates
|
||||
|
|
@ -961,6 +974,9 @@ typedef struct _LINKTABLE
|
|||
time_t ConnectTime; // For session stats
|
||||
int bytesRXed; // Info bytes only
|
||||
int bytesTXed;
|
||||
int framesRXed;
|
||||
int framesTXed;
|
||||
int framesResent;
|
||||
|
||||
// Now support compressing L2 Sessions.
|
||||
// We collect as much data as possible before compressing and re-packetizing
|
||||
|
|
@ -977,7 +993,7 @@ typedef struct _LINKTABLE
|
|||
int ReceivedAfterExpansion;
|
||||
|
||||
char ApplName[16];
|
||||
|
||||
time_t lastStatusSentTime;
|
||||
|
||||
} LINKTABLE;
|
||||
|
||||
|
|
@ -1479,6 +1495,15 @@ struct CMDX
|
|||
|
||||
};
|
||||
|
||||
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)
|
||||
|
|
|
|||
61
cMain.c
61
cMain.c
|
|
@ -55,7 +55,9 @@ 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"
|
||||
|
||||
|
|
@ -63,6 +65,15 @@ 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;
|
||||
|
||||
|
|
@ -313,8 +324,8 @@ VOID LINKINIT(PEXTPORTDATA PORTVEC)
|
|||
VOID LINKTX(PEXTPORTDATA PORTVEC, PMESSAGE Buffer)
|
||||
{
|
||||
// LOOP BACK TO SWITCH
|
||||
|
||||
struct _LINKTABLE * LINK;
|
||||
|
||||
LINK = Buffer->Linkptr;
|
||||
|
||||
if (LINK)
|
||||
|
|
@ -1380,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
|
||||
|
|
@ -1400,6 +1411,12 @@ BOOL Start()
|
|||
ROUTE->OtherendsRouteQual = ROUTE->OtherendLocked = Rcfg->farQual;
|
||||
|
||||
ROUTE->NEIGHBOUR_FLAG = LOCKEDBYCONFIG; // Locked
|
||||
|
||||
if (Rcfg->tcphost)
|
||||
{
|
||||
ROUTE->TCPHost = Rcfg->tcphost;
|
||||
ROUTE->TCPPort = Rcfg->tcpport;
|
||||
}
|
||||
|
||||
Rcfg++;
|
||||
ROUTE++;
|
||||
|
|
@ -1584,6 +1601,28 @@ BOOL Start()
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -2177,6 +2216,12 @@ VOID TIMERINTERRUPT()
|
|||
if (MQTT)
|
||||
MQTTTimer();
|
||||
|
||||
if (LastNodeStatus && (time(NULL) - LastNodeStatus) > nodeStatusTimer)
|
||||
{
|
||||
LastNodeStatus = time(NULL);
|
||||
hookNodeRunning();
|
||||
}
|
||||
|
||||
/*
|
||||
if (QCOUNT < 200)
|
||||
{
|
||||
|
|
@ -2232,6 +2277,10 @@ VOID TIMERINTERRUPT()
|
|||
}
|
||||
|
||||
Message = (struct _MESSAGE *)Buffer;
|
||||
|
||||
if(NodeAPISocket)
|
||||
APIL2Trace(Message, 'T');
|
||||
|
||||
Message->PORT |= 0x80; // Set TX Bit
|
||||
|
||||
BPQTRACE(Message, FALSE); // Dont send TX'ed frames to APRS
|
||||
|
|
@ -2343,6 +2392,9 @@ L2Packet:
|
|||
|
||||
if (MQTT && PORT->PROTOCOL == 0)
|
||||
MQTTKISSRX(Buffer);
|
||||
|
||||
if(NodeAPISocket &&PORT->PROTOCOL == 0)
|
||||
APIL2Trace(Message, 'R');
|
||||
|
||||
// Bridge if requested
|
||||
|
||||
|
|
@ -2695,7 +2747,6 @@ int BPQTRACE(MESSAGE * Msg, BOOL TOAPRS)
|
|||
|
||||
// And to the Monitor to File system.
|
||||
|
||||
|
||||
if (MONTOFILEFLAG) // Trace Enabled?
|
||||
{
|
||||
Buffer = GetBuff();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
185
config.c
185
config.c
|
|
@ -305,7 +305,8 @@ 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",
|
||||
|
|
@ -328,7 +329,8 @@ 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,
|
||||
|
|
@ -350,7 +352,8 @@ 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,
|
||||
|
|
@ -1584,32 +1587,160 @@ int routes(int i)
|
|||
|
||||
// strtok and sscanf can't handle successive commas, so split up usig strchr
|
||||
|
||||
memset(Param, 0, 2048);
|
||||
strlop(rec, 13);
|
||||
strlop(rec, ';');
|
||||
// Now support keyword=value format
|
||||
|
||||
ptr1 = rec;
|
||||
|
||||
while (ptr1 && *ptr1 && n < 8)
|
||||
if (strchr(rec, '='))
|
||||
{
|
||||
ptr2 = strchr(ptr1, ',');
|
||||
if (ptr2) *ptr2++ = 0;
|
||||
// New format
|
||||
// call quality port window frack paclen farquality inp3 nokeepalives tcp
|
||||
|
||||
strcpy(&Param[n++][0], ptr1);
|
||||
ptr1 = ptr2;
|
||||
while(ptr1 && *ptr1 && *ptr1 == ' ')
|
||||
ptr1++;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(Route->call, &Param[0][0]);
|
||||
else
|
||||
{
|
||||
|
||||
Route->quality = atoi(Param[1]);
|
||||
Route->port = atoi(Param[2]);
|
||||
Route->pwind = atoi(Param[3]);
|
||||
Route->pfrack = atoi(Param[4]);
|
||||
Route->ppacl = atoi(Param[5]);
|
||||
inp3 = atoi(Param[6]);
|
||||
Route->farQual = atoi(Param[7]);
|
||||
memset(Param, 0, 2048);
|
||||
strlop(rec, 13);
|
||||
strlop(rec, ';');
|
||||
|
||||
ptr1 = rec;
|
||||
|
||||
while (ptr1 && *ptr1 && n < 8)
|
||||
{
|
||||
ptr2 = strchr(ptr1, ',');
|
||||
if (ptr2) *ptr2++ = 0;
|
||||
|
||||
strcpy(&Param[n++][0], ptr1);
|
||||
ptr1 = ptr2;
|
||||
while(ptr1 && *ptr1 && *ptr1 == ' ')
|
||||
ptr1++;
|
||||
}
|
||||
|
||||
strcpy(Route->call, &Param[0][0]);
|
||||
|
||||
Route->quality = atoi(Param[1]);
|
||||
Route->port = atoi(Param[2]);
|
||||
Route->pwind = atoi(Param[3]);
|
||||
Route->pfrack = atoi(Param[4]);
|
||||
Route->ppacl = atoi(Param[5]);
|
||||
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)
|
||||
{
|
||||
|
|
@ -1634,14 +1765,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);
|
||||
|
|
|
|||
|
|
@ -94,6 +94,10 @@ struct ROUTECONFIG
|
|||
int pfrack;
|
||||
int ppacl;
|
||||
int farQual;
|
||||
int inp3;
|
||||
int nokeepalives;
|
||||
char * tcphost;
|
||||
int tcpport;
|
||||
};
|
||||
|
||||
struct CONFIGTABLE
|
||||
|
|
|
|||
2
ipcode.h
2
ipcode.h
|
|
@ -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
|
||||
|
|
|
|||
2
makefile
2
makefile
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue