diff --git a/APRSCode.c b/APRSCode.c index 2ee3b5f..6e65001 100644 --- a/APRSCode.c +++ b/APRSCode.c @@ -7693,7 +7693,7 @@ VOID APRSProcessHTTPMessage(SOCKET sock, char * MsgPtr, BOOL LOCAL, BOOL COOKIE) while (ptr) { char ToLopped[11] = ""; - + if (ptr->Acked) strcpy(Retries, "A"); else if (ptr->Retries == 0) @@ -7701,26 +7701,26 @@ VOID APRSProcessHTTPMessage(SOCKET sock, char * MsgPtr, BOOL LOCAL, BOOL COOKIE) else sprintf(Retries, "%d", ptr->Retries); - memcpy(ToLopped, ptr->ToCall, 10); - strlop(ToLopped, ' '); + memcpy(ToLopped, ptr->ToCall, 10); + strlop(ToLopped, ' '); - OutputLen += sprintf(&OutBuffer[OutputLen], WebTXLine, - ptr->ToCall, ptr->Seq, ptr->Time, Retries, ptr->Text); - ptr = ptr->Next; + OutputLen += sprintf(&OutBuffer[OutputLen], WebTXLine, + ptr->ToCall, ptr->Seq, ptr->Time, Retries, ptr->Text); + ptr = ptr->Next; - if (OutputLen > 99000) - break; + if (OutputLen > 99000) + break; - } + } - OutputLen += sprintf(&OutBuffer[OutputLen], "%s", WebTrailer); + OutputLen += sprintf(&OutBuffer[OutputLen], "%s", WebTrailer); - HeaderLen = sprintf(Header, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", OutputLen); - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, OutBuffer, OutputLen); + HeaderLen = sprintf(Header, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", OutputLen); + sendandcheck(sock, Header, HeaderLen); + sendandcheck(sock, OutBuffer, OutputLen); + + return; - return; - } diff --git a/ARDOP.c b/ARDOP.c index 5832c44..ef92fad 100644 --- a/ARDOP.c +++ b/ARDOP.c @@ -466,107 +466,107 @@ static int ProcessLine(char * buf, int Port) else return FALSE; // Must start with ADDR - TNC->InitScript = malloc(1000); - TNC->InitScript[0] = 0; + TNC->InitScript = malloc(1000); + TNC->InitScript[0] = 0; - ptr = strtok(NULL, " \t\n\r"); + ptr = strtok(NULL, " \t\n\r"); - if (ptr) + if (ptr) + { + if (_stricmp(ptr, "PTT") == 0) { - if (_stricmp(ptr, "PTT") == 0) - { - ptr = strtok(NULL, " \t\n\r"); + ptr = strtok(NULL, " \t\n\r"); - if (ptr) - { - DecodePTTString(TNC, ptr); - ptr = strtok(NULL, " \t\n\r"); - } - } - } - - if (ptr) - { - if (_memicmp(ptr, "PATH", 4) == 0) - { - p_cmd = strtok(NULL, "\n\r"); - if (p_cmd) TNC->ProgramPath = _strdup(p_cmd); - } - } - - TNC->MaxConReq = 10; // Default - TNC->OldMode = FALSE; // Default - - // Read Initialisation lines - - while(TRUE) - { - if (GetLine(buf) == 0) - return TRUE; - - strcpy(errbuf, buf); - - if (memcmp(buf, "****", 4) == 0) - return TRUE; - - ptr = strchr(buf, ';'); if (ptr) { - *ptr++ = 13; - *ptr = 0; + DecodePTTString(TNC, ptr); + ptr = strtok(NULL, " \t\n\r"); } - - if ((_memicmp(buf, "CAPTURE", 7) == 0) || (_memicmp(buf, "PLAYBACK", 8) == 0)) - {} // Ignore - else -/* + } + } + + if (ptr) + { + if (_memicmp(ptr, "PATH", 4) == 0) + { + p_cmd = strtok(NULL, "\n\r"); + if (p_cmd) TNC->ProgramPath = _strdup(p_cmd); + } + } + + TNC->MaxConReq = 10; // Default + TNC->OldMode = FALSE; // Default + + // Read Initialisation lines + + while(TRUE) + { + if (GetLine(buf) == 0) + return TRUE; + + strcpy(errbuf, buf); + + if (memcmp(buf, "****", 4) == 0) + return TRUE; + + ptr = strchr(buf, ';'); + if (ptr) + { + *ptr++ = 13; + *ptr = 0; + } + + if ((_memicmp(buf, "CAPTURE", 7) == 0) || (_memicmp(buf, "PLAYBACK", 8) == 0)) + {} // Ignore + else + /* if (_memicmp(buf, "PATH", 4) == 0) { - char * Context; - p_cmd = strtok_s(&buf[5], "\n\r", &Context); - if (p_cmd) TNC->ProgramPath = _strdup(p_cmd); + char * Context; + p_cmd = strtok_s(&buf[5], "\n\r", &Context); + if (p_cmd) TNC->ProgramPath = _strdup(p_cmd); } else -*/ + */ if (_memicmp(buf, "PACKETCHANNELS", 14) == 0) // Packet Channels TNC->PacketChannels = atoi(&buf[14]); else - if (_memicmp(buf, "MAXCONREQ", 9) == 0) // Hold Time for Busy Detect - TNC->MaxConReq = atoi(&buf[9]); + if (_memicmp(buf, "MAXCONREQ", 9) == 0) // Hold Time for Busy Detect + TNC->MaxConReq = atoi(&buf[9]); - else - if (_memicmp(buf, "STARTINROBUST", 13) == 0) - TNC->StartInRobust = TRUE; - - else - if (_memicmp(buf, "ROBUST", 6) == 0) - { - if (_memicmp(&buf[7], "TRUE", 4) == 0) - TNC->Robust = TRUE; - - strcat (TNC->InitScript, buf); - } - else - if (_memicmp(buf, "LOGDIR ", 7) == 0) - TNC->LogPath = _strdup(&buf[7]); - else - if (_memicmp(buf, "ENABLEPACKET", 12) == 0) - { - if (TNC->PacketChannels == 0) - TNC->PacketChannels = 5; - // AddVirtualKISSPort(TNC, Port, buf); - } + else + if (_memicmp(buf, "STARTINROBUST", 13) == 0) + TNC->StartInRobust = TRUE; -// else if (_memicmp(buf, "PAC ", 4) == 0 && _memicmp(buf, "PAC MODE", 8) != 0) -// { - // PAC MODE goes to TNC, others are parsed locally -// -// ConfigVirtualKISSPort(TNC, buf); -// } - else if (standardParams(TNC, buf) == FALSE) - strcat(TNC->InitScript, buf); - } + else + if (_memicmp(buf, "ROBUST", 6) == 0) + { + if (_memicmp(&buf[7], "TRUE", 4) == 0) + TNC->Robust = TRUE; + + strcat (TNC->InitScript, buf); + } + else + if (_memicmp(buf, "LOGDIR ", 7) == 0) + TNC->LogPath = _strdup(&buf[7]); + else + if (_memicmp(buf, "ENABLEPACKET", 12) == 0) + { + if (TNC->PacketChannels == 0) + TNC->PacketChannels = 5; + // AddVirtualKISSPort(TNC, Port, buf); + } + + // else if (_memicmp(buf, "PAC ", 4) == 0 && _memicmp(buf, "PAC MODE", 8) != 0) + // { + // PAC MODE goes to TNC, others are parsed locally + // + // ConfigVirtualKISSPort(TNC, buf); + // } + else if (standardParams(TNC, buf) == FALSE) + strcat(TNC->InitScript, buf); + } return (TRUE); @@ -1041,8 +1041,10 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) { TNC->Busy--; if (TNC->Busy == 0) + { MySetWindowText(TNC->xIDC_CHANSTATE, "Clear"); strcpy(TNC->WEB_CHANSTATE, "Clear"); + } } } diff --git a/BBSUtilities.c b/BBSUtilities.c index e803500..e6f7ade 100644 --- a/BBSUtilities.c +++ b/BBSUtilities.c @@ -3701,10 +3701,10 @@ void DoKillCommand(CIRCUIT * conn, struct UserInfo * user, char * Cmd, char * Ar if (conn->sysop) { if (Arg1) - if (KillMessagesFrom(conn, user, Arg1) == 0); + if (KillMessagesFrom(conn, user, Arg1) == 0) BBSputs(conn, "No Messages found\r"); - return; + return; } } @@ -6556,7 +6556,7 @@ nextline: { char APRS[128]; char Call[16]; - int SSID = user->flags >> 28; + int SSID = (user->flags >> 28) & 15; // on some platforms this is treated as signed ?? if (SSID) sprintf(Call, "%s-%d", Msg->to, SSID); @@ -13395,7 +13395,7 @@ int DeleteRedundantMessages() { while(n--) { - if (stat(namelist[n]->d_name, &STAT) == 0); + if (stat(namelist[n]->d_name, &STAT) == 0) { Msgno = atoi(&namelist[n]->d_name[2]); diff --git a/BPQINP3.c b/BPQINP3.c index 872496b..d87aa69 100644 --- a/BPQINP3.c +++ b/BPQINP3.c @@ -35,8 +35,6 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses #include //#include "vmm.h" -uint64_t INP3timeLoadedMS = 0; - extern int DEBUGINP3; VOID SendNegativeInfo(); @@ -64,11 +62,16 @@ static VOID SendNetFrame(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame) typedef struct _RTTMSG { - UCHAR ID[7]; - UCHAR TXTIME[11]; - UCHAR SMOOTHEDRTT[11]; - UCHAR LASTRTT[11]; - UCHAR POINTER[11]; + UCHAR ID[6]; + UCHAR Space1; + UCHAR TXTIME[10]; + UCHAR Space2; + UCHAR SMOOTHEDRTT[10]; + UCHAR Space3; + UCHAR LASTRTT[10]; + UCHAR Space4; + UCHAR RTTID[10]; + UCHAR Space5; UCHAR ALIAS[7]; UCHAR VERSION[12]; UCHAR SWVERSION[9]; @@ -110,6 +113,8 @@ extern int RTTInterval; // 4 Minutes int RTTRetries = 2; int RTTTimeout = 6; // 1 Min (Horizon is 1 min) +uint32_t RTTID = 1; + VOID InitialiseRTT() { UCHAR temp[256] = ""; @@ -161,10 +166,11 @@ VOID DeleteINP3Routes(struct ROUTE * Route) Route->BCTimer = 0; Route->Status = 0; Route->Timeout = 0; + Route->NeighbourSRTT = 0; Dest--; - // Delete any Dest entries via this Route + // Delete any Dest entries via this Route for (i=0; i < MAXDESTS; i++) { @@ -340,8 +346,8 @@ VOID TellINP3LinkSetupFailed(struct ROUTE * Route) VOID ProcessRTTReply(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff) { - int RTT; - unsigned int OrigTime; + uint32_t RTT; + uint32_t OrigTime; char Normcall[10]; @@ -349,10 +355,10 @@ VOID ProcessRTTReply(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff) Route->Timeout = 0; // Got Response - sscanf(&Buff->L4DATA[6], "%d", &OrigTime); - RTT = (int)((GetTickCount() - INP3timeLoadedMS) / 10 - (OrigTime)); // We work internally in mS + sscanf(&Buff->L4DATA[6], "%u", &OrigTime); + RTT = GetTickCountINP3() - OrigTime; // We work internally in mS - if (RTT > 60000) + if (RTT > 60000 || RTT < 0) return; // Ignore if more than 60 secs (why ??) Route->RTT = RTT; @@ -747,6 +753,9 @@ VOID SortRoutes(struct DEST_LIST * Dest) { char Call1[10], Call2[10], Call3[10]; + // force route re-evaluation + + Dest->DEST_ROUTE = 0; // May now be out of order @@ -887,8 +896,8 @@ VOID UpdateRoute(struct DEST_LIST * Dest, struct INP3_DEST_ROUTE_ENTRY * ROUTEPT VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len, int Port) { - int OtherRTT; - int Dummy; + uint32_t OtherRTT; + uint32_t Dummy; char * ptr; struct _RTTMSG * RTTMsg = (struct _RTTMSG *)&Buff->L4DATA[0]; char Normcall[10]; @@ -917,18 +926,28 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len return; // We don't want to use INP3 } - // Extract other end's SRTT + // Basic Validation - look for spaces in the right place - // Get SWVERSION to see if other end is old (Buggy) BPQ - - if (memcmp(RTTMsg->SWVERSION, "BPQ32001 ", 9) == 0) - Route->OldBPQ = 1; + if ((RTTMsg->Space1 | RTTMsg->Space2 | RTTMsg->Space3 | RTTMsg->Space4 | RTTMsg->Space5) != ' ') + { + Debugprintf("Corrupt INP3 RTT Message %s", &Buff->L4DATA[0]); + } else - Route->OldBPQ = 0; + { + // Extract other end's SRTT - sscanf(&Buff->L4DATA[6], "%d %d", &Dummy, &OtherRTT); + // Get SWVERSION to see if other end is old (Buggy) BPQ - Route->NeighbourSRTT = OtherRTT; + if (memcmp(RTTMsg->SWVERSION, "BPQ32001 ", 9) == 0) + Route->OldBPQ = 1; + else + Route->OldBPQ = 0; + + sscanf(&Buff->L4DATA[6], "%u %u", &Dummy, &OtherRTT); + + if (OtherRTT < 60000) // Don't save suspect values + Route->NeighbourSRTT = OtherRTT; + } // Look for $M and $H (MAXRTT MAXHOPS) @@ -942,6 +961,8 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len if (ptr) Route->RemoteMAXHOPS = atoi(ptr + 2); + + // Echo Back to sender SendNetFrame(Route, Buff); @@ -962,7 +983,8 @@ VOID SendRTTMsg(struct ROUTE * Route) char Stamp[50]; char Normcall[10]; unsigned char temp[256]; - uint64_t sendTime; + uint32_t sendTime; + int n; Normcall[ConvFromAX25(Route->NEIGHBOUR_CALL, Normcall)] = 0; @@ -982,14 +1004,21 @@ VOID SendRTTMsg(struct ROUTE * Route) Msg->L4TXNO = 0; Msg->L4FLAGS = L4INFO; - // The timestamp can possibly exceed 10 digits. INP3 only works on differece between send and received, so base can be reset safely. + // Windows GetTickCount wraps every 54 days or so. INP3 doesn't care, so long as the edge + // case where timer wraps between sending msg and getting response is ignored + // For platform independence use GetTickCountINP3() and map as appropriate - sendTime = ((uint64_t)GetTickCount() - INP3timeLoadedMS) / 10; // 10mS units + sendTime = GetTickCountINP3(); // 10mS units - if (sendTime > 9999999999) - sendTime = INP3timeLoadedMS = 0; + sprintf(Stamp, "%10u %10d %10d %10d ", sendTime, Route->SRTT, Route->RTT, RTTID++); - sprintf(Stamp, "%10llu %10d %10d %10d ", sendTime, Route->SRTT, Route->RTT, 0); + n = strlen(Stamp); + + if (n != 44) + { + Debugprintf("Trying to send corrupt RTT message %s", Stamp); + return; + } memcpy(RTTMsg.TXTIME, Stamp, 44); @@ -1206,6 +1235,7 @@ int SendRIPTimer() } L2SETUPCROSSLINKEX(Route, 2); // Only try SABM twice + Route->NeighbourSRTT = 0; // just in case! Route->LastConnectAttempt = REALTIMETICKS; diff --git a/Bpq32.c b/Bpq32.c index 41d4e64..1f80282 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1298,6 +1298,10 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // 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) +// Fix some issues with NetromX connects and Route Selection when running INP3 and NODES routing (9) +// Fix connecting to a netrom node with c p node command (10) +// Add validation of INP3 RTT messages and various INP3 fixes (12) +// Change NetromX connect syntax to Service@Node to fix passing commands to local applications (12) #define CKernel @@ -1406,6 +1410,7 @@ void initAIS(); void initADSB(); int CloseAllSessions(); int CloseAllLinks(); +void NETROMTCPResolve(); extern BOOL ADIFLogEnabled; @@ -1413,6 +1418,8 @@ int CloseOnError = 0; char UIClassName[]="UIMAINWINDOW"; // the main window class name +char ClosingClassName[]="CLOSING"; // the main window class name + HWND UIhWnd; extern char AUTOSAVE; @@ -1535,7 +1542,6 @@ extern char ReportDest[7]; extern UCHAR ConfigDirectory[260]; -extern uint64_t INP3timeLoadedMS; VOID __cdecl Debugprintf(const char * format, ...); VOID __cdecl Consoleprintf(const char * format, ...); @@ -2216,6 +2222,8 @@ VOID TimerProcX() Start(); + NETROMTCPResolve(); + INITIALISEPORTS(); // Restart Ports SetApplPorts(); @@ -2398,7 +2406,7 @@ VOID TimerProcX() if (CloseAllSessions() == 0) { if (CloseAllLinks() == 0) // No sessions closed so close links now - CloseAllTimer = 0; // No Links so close now + CloseAllTimer = 1; // No Links so close now else CloseAllTimer = 39; // ~4 secs for links to close } @@ -2474,8 +2482,6 @@ FirstInit() EnumProcessesPtr = (FARPROCX)GetProcAddress(ExtDriver,"EnumProcesses"); } - INP3timeLoadedMS = GetTickCount(); - srand(time(NULL)); INITIALISEPORTS(); @@ -2632,6 +2638,7 @@ Check_Timer() WSAStartup(MAKEWORD(2, 0), &WsaData); + // Load Psapi.dll if possible ExtDriver = LoadLibrary("Psapi.dll"); @@ -2646,6 +2653,8 @@ Check_Timer() Start(); + NETROMTCPResolve(); + INITIALISEPORTS(); OpenReportingSockets(); @@ -2969,6 +2978,8 @@ BOOL APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReser } else { + NETROMTCPResolve(); + SetApplPorts(); GetUIConfig(); @@ -5967,14 +5978,96 @@ DllExport VOID APIENTRY CreateNewTrayIcon() void hookNodeClosing(char * Reason); +BOOL CALLBACK ClosaAllProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int wmId, wmEvent; + + switch (message) + { + case WM_INITDIALOG: + return (INT_PTR)TRUE; + + case WM_CTLCOLORDLG: + return (LONG)bgBrush; + + case WM_CTLCOLORSTATIC: + { + HDC hdcStatic = (HDC)wParam; + SetTextColor(hdcStatic, RGB(0, 0, 0)); + SetBkMode(hdcStatic, TRANSPARENT); + + return (LONG)bgBrush; + } + + case WM_COMMAND: + + return 0; + + case WM_SYSCOMMAND: + + wmId = LOWORD(wParam); // Remember, these are... + wmEvent = HIWORD(wParam); // ...different for Win32! + + switch (wmId) + { + case SC_RESTORE: + + return (DefWindowProc(hWnd, message, wParam, lParam)); + + case SC_MINIMIZE: + + if (MinimizetoTray) + return ShowWindow(hWnd, SW_HIDE); + else + return (DefWindowProc(hWnd, message, wParam, lParam)); + + break; + + default: + return (DefWindowProc(hWnd, message, wParam, lParam)); + } + + case WM_CLOSE: + return(DestroyWindow(hWnd)); + + default: + return (DefWindowProc(hWnd, message, wParam, lParam)); + + } + + return (0); +} + + +HWND hwndClosing = NULL; // Window handle of dialog box + DllExport VOID APIENTRY CloseAllPrograms() { + WNDCLASS wc; CLOSING = TRUE; // Tell BG to shut when all links are gone or after 5 secs CloseAllTimer = 50; + + + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = ClosaAllProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = DLGWINDOWEXTRA; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(BPQICON) ); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = bgBrush; + + wc.lpszMenuName = NULL; + wc.lpszClassName = ClosingClassName; + + RegisterClass(&wc); + + hwndClosing = CreateDialog(hInstance, ClosingClassName, NULL, (DLGPROC)ClosaAllProc); + ShowWindow(hwndClosing, SW_SHOW); } VOID RealCloseAllPrograms() diff --git a/Cmd.c b/Cmd.c index 605ccd1..3e6c0eb 100644 --- a/Cmd.c +++ b/Cmd.c @@ -130,6 +130,8 @@ int NOBUFFCOUNT = 0; int BUFFERWAITS = 0; int MAXDESTS = 0; int NUMBEROFNODES = 0; +int L2CONNECTSOUT = 0; +int L2CONNECTSIN = 0; int L4CONNECTSOUT = 0; int L4CONNECTSIN = 0; int L4FRAMESTX = 0; @@ -836,13 +838,14 @@ BOOL cATTACHTOBBS(TRANSPORTENTRY * Session, UINT Mask, int Paclen, int * AnySess return FALSE; } -void ConnecttoService(TRANSPORTENTRY * Session, char * Bufferptr, int ServiceIndex, char * Node, int Stay) +void ConnecttoService(TRANSPORTENTRY * Session, char * Bufferptr, int Service, char * Node, int Stay) { struct DEST_LIST * Dest = DESTS; int n = MAXDESTS; int gotDest = 0; unsigned char axcall[7]; - int Service = -1; + char cmdName[80]; + int i; // Make Sure Node is Known @@ -887,9 +890,20 @@ void ConnecttoService(TRANSPORTENTRY * Session, char * Bufferptr, int ServiceInd Session->STAYFLAG = Stay; - Service = SERVICES[ServiceIndex].ServiceNo; + // Get command name if a named command - Bufferptr = Cmdprintf(Session, Bufferptr, "Connecting to Service %s on Node %s \r", SERVICES[ServiceIndex].ServiceName, Node); + sprintf(cmdName, "%d", Service); // default to number + + for (i = 0; i < NUMBEROFSSERVICES; i++) + { + if (SERVICES[i].ServiceNo == Service) + { + strcpy(cmdName, SERVICES[i].ServiceName); + break; + } + } + + Bufferptr = Cmdprintf(Session, Bufferptr, "Connecting to Service %s on Node %s \r", cmdName, Node); DoNetromConnect(Session, Bufferptr, Dest, 0, Service); @@ -903,8 +917,12 @@ int checkifService(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, s BOOL Stay = FALSE; char * ptr, *Context; int i; + char TailCopy[256]; - ptr = strtok_s(CmdTail, " ", &Context); + strcpy(TailCopy, CmdTail); + + + ptr = strtok_s(TailCopy, " ", &Context); // see if any param. if longer than two chars treat as remote node @@ -924,7 +942,7 @@ int checkifService(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, s { if (strcmp(APPName, SERVICES[i].ServiceName) == 0) { - ConnecttoService(Session, Bufferptr, i, ptr, Stay); + ConnecttoService(Session, Bufferptr, SERVICES[i].ServiceNo, ptr, Stay); return 1; } } @@ -942,7 +960,6 @@ 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 @@ -961,14 +978,17 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct return; } - ptr = strtok_s(CmdTail, " ", &Context); - // ptr is first param. Context is rest of string; + if (CmdTail[0] == 'S') + Stay = TRUE; + // could be Node for NETROMX connect or S flag + + // We now use service@node, so can't get here + +/* if (ptr) { - // could be Node for NETROMX connect or S flag - int i; if (strlen(ptr) > 1) @@ -977,6 +997,8 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct Session->STAYFLAG = Stay; // See if APPL is one of Paula's service + + for (i = 0; i < NUMBEROFSSERVICES; i++) { @@ -997,7 +1019,7 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct else if (ptr[0] == 'S') Session->STAYFLAG = Stay; } - +*/ memcpy(Session->APPL, CMD->String, 12); // SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND @@ -2566,6 +2588,56 @@ VOID CMDC00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct C return; } + // See if NETROMX connect c service@node + + if (strchr(ptr, '@')) + { + // We now use service@node, unlike xr + + char * Context1; + + char * Cmd = strtok_s(ptr, "@", &Context1); + char * Node = strtok_s(NULL, " ", &Context1); + int i; + int Stay = 0; + + if (Context1 && Context1[0] == 'S') + Session->STAYFLAG = Stay; + + for (i = 0; i < NUMBEROFSSERVICES; i++) + { + if (strcmp(Cmd, SERVICES[i].ServiceName) == 0) + { + if (Node) + { + ConnecttoService(Session, Bufferptr, SERVICES[i].ServiceNo, Node, Stay); + return; + } + } + } + + // May be numeric service + + for (i = 0; i < strlen(Cmd); i++) + { + if (!isdigit(Cmd[i])) + break; + } + + if (i == strlen(Cmd)) + { + if (Node) + { + ConnecttoService(Session, Bufferptr, atoi(Cmd), Node, Stay); + return; + } + } + + Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid NetromX command\r"); + SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); + return; + } + Port = atoi(ptr); if (Port) @@ -2665,7 +2737,7 @@ NoPort: // SEE IF CALL TO ANY OF OUR HOST SESSIONS - UNLESS DIGIS SPECIFIED - if (axcalls[7] == 0 && axcalls[9] ) + if (axcalls[7] == 0) { // If this connect is as a result of a command alias, don't check appls or we will loop @@ -2716,28 +2788,7 @@ NoPort: } } - // 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 - { - if (i > 0) // Some digits - { - haveService = 1; - Service = atoi(cmdCopy); - } - } - - if (axcalls[7] == 0 || haveService) + if (axcalls[7] == 0) { // SEE IF CALL TO ANOTHER NODE @@ -2780,9 +2831,6 @@ Downlink: // L2 NEEDS PORT NUMBER Bufferptr = Cmdprintf(Session, Bufferptr, "Downlink connect needs port number - C P CALLSIGN\r"); - - // Send Port List - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); return; } @@ -5070,6 +5118,7 @@ VOID DoTheCommand(TRANSPORTENTRY * Session) int n; int i, Service = -1; char * Cmd, *Node, *Context; + int Stay = 0; ptr1 = &COMMANDBUFFER[0]; // @@ -5164,28 +5213,47 @@ VOID DoTheCommand(TRANSPORTENTRY * Session) // See if a NETROMX Service - Cmd = strtok_s(ptr1, " ", &Context); - Node = strtok_s(NULL, " ", &Context); - - for (i = 0; i < NUMBEROFSSERVICES; i++) + // We now use service@node, unlike xr + + if (strchr(ptr1, '@')) { - if (strcmp(Cmd, SERVICES[i].ServiceName) == 0) + Cmd = strtok_s(ptr1, "@", &Context); + Node = strtok_s(NULL, " ", &Context); + + if (Cmd && Node) { - int Stay = 0; - if (Context && Context[0] == 'S') Session->STAYFLAG = Stay; - if (Node) + for (i = 0; i < NUMBEROFSSERVICES; i++) { - ConnecttoService(Session, ReplyPointer, i, Node, Stay); + if (strcmp(Cmd, SERVICES[i].ServiceName) == 0) + { + ConnecttoService(Session, ReplyPointer, SERVICES[i].ServiceNo, Node, Stay); + return; + } + } + + // May be numeric service + + for (i = 0; i < strlen(Cmd); i++) + { + if (!isdigit(Cmd[i])) + break; + } + + if (i == strlen(Cmd)) + { + ConnecttoService(Session, ReplyPointer, atoi(Cmd), Node, Stay); return; } - - // Connecting to service on local node - msy be possible sometime } - } + ReplyPointer = Cmdprintf(Session, ReplyPointer, "Invalid NetromX command\r"); + SendCommandReply(Session, REPLYBUFFER, (int)(ReplyPointer - (char *)REPLYBUFFER)); + return; + + } Session->BADCOMMANDS++; if (Session->BADCOMMANDS > 6) // TOO MANY ERRORS @@ -5202,19 +5270,19 @@ VOID DoTheCommand(TRANSPORTENTRY * Session) ptr1 += CMDERRLEN; SendCommandReply(Session, Buffer, (int)(ptr1 - (char *)Buffer)); -} + } -VOID StatsTimer() -{ - struct PORTCONTROL * PORT = PORTTABLE; - uint64_t sum, sum2; - - // Interval is 60 secs - - while(PORT) + VOID StatsTimer() { - int index = PORT->StatsPointer++; + struct PORTCONTROL * PORT = PORTTABLE; + uint64_t sum, sum2; + + // Interval is 60 secs + + while(PORT) + { + int index = PORT->StatsPointer++; if (index == 1439) PORT->StatsPointer = 0; // Cyclic through 24 hours (1440 Mins) diff --git a/CommonCode.c b/CommonCode.c index cffbdb7..9e8b37a 100644 --- a/CommonCode.c +++ b/CommonCode.c @@ -75,6 +75,7 @@ void printStack(void); char * FormatMH(PMHSTRUC MH, char Format); void WriteConnectLog(char * fromCall, char * toCall, UCHAR * Mode); void SendDataToPktMap(); +void NETROMTCPResolve(); extern BOOL LogAllConnects; extern BOOL M0LTEMap; @@ -3739,15 +3740,14 @@ VOID ResolveUpdateThread(void * Unused) LastNodeStatus = time(NULL); } } + + NETROMTCPResolve(); if (HostEnt1 && HostEnt2) { - Sleep(1000 * 60 * 30); + Sleep(1000 * 60 * 15); continue; } - - Debugprintf("Resolve Failed for update.g8bpq.net or chatmap.g8bpq.net"); - Sleep(1000 * 60 * 5); } } diff --git a/DRATS.c b/DRATS.c index c7b6b83..7fd85cf 100644 --- a/DRATS.c +++ b/DRATS.c @@ -568,18 +568,19 @@ void DRATSConnectionLost(struct ConnectionInfo * sockptr) int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen) { - int ret; - z_stream strm; + int ret; + z_stream strm; - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.avail_in = 0; - strm.next_in = Z_NULL; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; - ret = inflateInit(&strm); - if (ret != Z_OK) - return ret; + ret = inflateInit(&strm); + + if (ret != Z_OK) + return ret; strm.avail_in = Len; strm.next_in = source; diff --git a/Events.c b/Events.c index 2030929..8e63cfe 100644 --- a/Events.c +++ b/Events.c @@ -26,6 +26,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses #include "asmstrucs.h" #include "tncinfo.h" #include "cheaders.h" +#include "kiss.h" VOID __cdecl Debugprintf(const char * format, ...); @@ -44,7 +45,9 @@ void MQTTReportSession(char * Msg); extern int MQTT; extern time_t TimeLoaded; -int UDPSeq = 1; +uint16_t UDPSeq = 1; +int linkSeq = 1; +int cctSeq = 1; extern SOCKET NodeAPISocket; extern SOCKADDR_IN UDPreportdest; @@ -57,6 +60,8 @@ extern char LOC[7]; extern char VersionString[50]; extern double LatFromLOC; extern double LonFromLOC; +extern int NUMBEROFNODES, MAXDESTS, L4CONNECTSOUT, L4CONNECTSIN, L4FRAMESTX, L4FRAMESRX, L4FRAMESRETRIED, OLDFRAMES; +extern int L2CONNECTSOUT, L2CONNECTSIN; void hookL2SessionClosed(struct _LINKTABLE * LINK, char * Reason, char * Direction); int ConvFromAX25(unsigned char * incall, unsigned char * outcall); @@ -66,6 +71,7 @@ int decodeNETROMUIMsg(unsigned char * Msg, int iLen, char * Buffer, int BufferLe 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); +char * byte_base64_encode(char *str, int len); // Runs use specified routine on certain event @@ -145,9 +151,12 @@ void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _ char UDPMsg[1024]; int udplen; - LINK->ConnectTime = time(NULL); - LINK->bytesTXed = LINK->bytesRXed = LINK->framesResent = LINK->framesRXed = LINK->framesTXed = 0; + L2CONNECTSIN++; + LINK->apiSeq = linkSeq++; + LINK->lastStatusSentTime = LINK->ConnectTime = time(NULL); + LINK->bytesTXed = LINK->bytesRXed = LINK->framesResent = LINK->framesRXed = LINK->framesTXed = 0; + LINK->LastStatusbytesTXed = LINK->LastStatusbytesRXed = 0; strcpy(LINK->callingCall, remotecall); strcpy(LINK->receivingCall, ourcall); strcpy(LINK->Direction, "In"); @@ -156,8 +165,8 @@ void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _ { 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); + udplen = sprintf(UDPMsg, "{\"@type\":\"LinkUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\", \"isRF\": %s}", + NODECALLLOPPED, LINK->apiSeq, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall, (LINK->LINKPORT->isRF)?"true":"false"); // Debugprintf(UDPMsg); @@ -217,9 +226,9 @@ void hookL2SessionDeleted(struct _LINKTABLE * LINK) void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _LINKTABLE * LINK) { - LINK->ConnectTime = time(NULL); + LINK->lastStatusSentTime = LINK->ConnectTime = time(NULL); LINK->bytesTXed = LINK->bytesRXed = LINK->framesResent = LINK->framesRXed = LINK->framesTXed = 0; - + LINK->LastStatusbytesTXed = LINK->LastStatusbytesRXed = 0; strcpy(LINK->callingCall, ourcall); strcpy(LINK->receivingCall, remotecall); strcpy(LINK->Direction, "Out"); @@ -232,12 +241,15 @@ void hookL2SessionConnected(struct _LINKTABLE * LINK) char UDPMsg[1024]; int udplen; + L2CONNECTSOUT++; + LINK->apiSeq = linkSeq++; + if (NodeAPISocket) { 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); + udplen = sprintf(UDPMsg, "{\"@type\":\"LinkUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\", \"isRF\": %s}", + NODECALLLOPPED, LINK->apiSeq, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall, (LINK->LINKPORT->isRF)?"true":"false"); // Debugprintf(UDPMsg); @@ -251,6 +263,7 @@ void hookL2SessionClosed(struct _LINKTABLE * LINK, char * Reason, char * Directi char UDPMsg[1024]; int udplen; + time_t Now = time(NULL); if (NodeAPISocket) { @@ -259,14 +272,18 @@ void hookL2SessionClosed(struct _LINKTABLE * LINK, char * Reason, char * Directi 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); + "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d, \"reason\": \"%s\"," + " \"time\": %d, \"upForSecs\": %d, \"frmsQdPeak\": %d, \"isRF\": %s}", + NODECALLLOPPED, LINK->apiSeq, LINK->LINKPORT->PORTNUMBER, LINK->receivingCall, LINK->callingCall, + LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason, + (int)Now, (int)Now - LINK->ConnectTime, LINK->maxQueued, (LINK->LINKPORT->isRF)?"true":"false"); 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); + "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d, \"reason\": \"%s\"," + " \"time\": %d, \"upForSecs\": %d, \"frmsQdPeak\": %d, \"isRF\": %s}", + NODECALLLOPPED, LINK->apiSeq, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall, + LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason, + (int)Now, (int)Now - LINK->ConnectTime, LINK->maxQueued, (LINK->LINKPORT->isRF)?"true":"false"); // Debugprintf(UDPMsg); @@ -280,24 +297,37 @@ void hookL2SessionStatus(struct _LINKTABLE * LINK) char UDPMsg[1024]; int udplen; + time_t Now = time(NULL); + int bpsTx, bpsRx, interval; if (NodeAPISocket) { - LINK->lastStatusSentTime = time(NULL); + interval = Now - (int)LINK->lastStatusSentTime; + bpsTx = (LINK->bytesTXed - LINK->LastStatusbytesTXed) / interval; + bpsRx = (LINK->bytesRXed - LINK->LastStatusbytesRXed) / interval; + + LINK->lastStatusSentTime = Now; + LINK->LastStatusbytesTXed = LINK->bytesTXed; + LINK->LastStatusbytesRXed = LINK->bytesRXed; 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); + "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d," + "\"upForSecs\": %d, \"frmsQdPeak\": %d, \"bpsTxMean\": %d, \"bpsRxMean\": %d, \"frmQMax\": %d, \"l2rttMs\": %d, \"isRF\": %s}", + NODECALLLOPPED, LINK->apiSeq, LINK->LINKPORT->PORTNUMBER, LINK->receivingCall, LINK->callingCall, + LINK->bytesTXed, LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, 0, LINK->framesResent, + (int)Now - LINK->ConnectTime, LINK->maxQueued, bpsTx, bpsRx, LINK->intervalMaxQueued, LINK->RTT, (LINK->LINKPORT->isRF)?"true":"false"); 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); + "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d," + "\"upForSecs\": %d, \"frmsQdPeak\": %d, \"bpsTxMean\": %d, \"bpsRxMean\": %d, \"frmQMax\": %d, \"l2rttMs\": %d, \"isRF\": %s}", + NODECALLLOPPED, LINK->apiSeq, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall, + LINK->bytesTXed, LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, 0, LINK->framesResent, + (int)Now - LINK->ConnectTime, LINK->maxQueued, bpsTx, bpsRx, LINK->intervalMaxQueued, LINK->RTT, (LINK->LINKPORT->isRF)?"true":"false"); + + LINK->intervalMaxQueued = 0; // Debugprintf(UDPMsg); - sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest)); } } @@ -412,8 +442,9 @@ void hookNodeClosing(char * Reason) if (NodeAPISocket) { - udplen = sprintf(UDPMsg, "{\"@type\": \"NodeDownEvent\", \"nodeCall\": \"%s\", \"nodeAlias\": \"%s\", \"reason\": \"%s\"}", - NODECALLLOPPED, MYALIASLOPPED, Reason); + udplen = sprintf(UDPMsg, "{\"@type\": \"NodeDownEvent\", \"nodeCall\": \"%s\", \"nodeAlias\": \"%s\", \"reason\": \"%s\", \"uptimeSecs\": %d," + "\"linksIn\": %d, \"linksOut\": %d, \"cctsIn\": %d, \"cctsOut\": %d, \"l3Relayed\": %d}", + NODECALLLOPPED, MYALIASLOPPED, Reason, time(NULL) - TimeLoaded, L2CONNECTSIN, L2CONNECTSOUT, L4CONNECTSIN, L4CONNECTSOUT, L3FRAMES); // Debugprintf(UDPMsg); @@ -438,9 +469,10 @@ void hookNodeRunning() { 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); - + "\"latitude\": %f, \"longitude\": %f, \"software\": \"%s\", \"version\": \"%s\", \"uptimeSecs\": %d," + "\"linksIn\": %d, \"linksOut\": %d, \"cctsIn\": %d, \"cctsOut\": %d, \"l3Relayed\": %d}", + NODECALLLOPPED, MYALIASLOPPED, LOC, LatFromLOC, LonFromLOC, Software, VersionString, time(NULL) - TimeLoaded, + L2CONNECTSIN, L2CONNECTSOUT, L4CONNECTSIN, L4CONNECTSOUT, L3FRAMES); // Debugprintf(UDPMsg); @@ -456,11 +488,17 @@ void IncomingL4ConnectionEvent(TRANSPORTENTRY * L4) char remotecall[64]; char ourcall[64]; char circuitinfo[32]; + int Service = L4->Service; // CACK sent to CREQ + L4->apiSeq = cctSeq++; + strcpy(L4->Direction, "incoming"); + if (NodeAPISocket) { + L4->lastStatusSentTime = time(NULL); + remotecall[ConvFromAX25(L4->L4TARGET.DEST->DEST_CALL, remotecall)] = 0; // remotecall[ConvFromAX25(L4->L4USER, remotecall)] = 0; ourcall[ConvFromAX25(L4->L4MYCALL, ourcall)] = 0; @@ -470,10 +508,16 @@ void IncomingL4ConnectionEvent(TRANSPORTENTRY * L4) sprintf(circuitinfo, ":%02x%02x", L4->CIRCUITINDEX, L4->CIRCUITID); strcat(ourcall, circuitinfo); - - udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\"," + + if (Service == -1) + udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", " + "\"remote\": \"%s\", \"local\": \"%s\"}", + NODECALLLOPPED, L4->apiSeq, remotecall, ourcall); + else + udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", " "\"service\": %d, \"remote\": \"%s\", \"local\": \"%s\"}", - NODECALLLOPPED, UDPSeq++, L4->Service, remotecall, ourcall); + NODECALLLOPPED, L4->apiSeq, Service, remotecall, ourcall); + // Debugprintf(UDPMsg); sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest)); @@ -488,11 +532,18 @@ void OutgoingL4ConnectionEvent(TRANSPORTENTRY * L4) char remotecall[64]; char ourcall[64]; char circuitinfo[32]; + int Service = L4->Service; // CACK received + strcpy(L4->Direction, "outgoing"); + + L4->apiSeq = cctSeq++; + if (NodeAPISocket) { + L4->lastStatusSentTime = time(NULL); + remotecall[ConvFromAX25(L4->L4TARGET.DEST->DEST_CALL, remotecall)] = 0; // remotecall[ConvFromAX25(L4->L4USER, remotecall)] = 0; ourcall[ConvFromAX25(L4->L4MYCALL, ourcall)] = 0; @@ -503,9 +554,14 @@ void OutgoingL4ConnectionEvent(TRANSPORTENTRY * L4) sprintf(circuitinfo, ":%02x%02x", L4->CIRCUITID, L4->CIRCUITINDEX); strcat(ourcall, circuitinfo); - udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\"," + if (Service == -1) + udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", " + "\"remote\": \"%s\", \"local\": \"%s\"}", + NODECALLLOPPED, L4->apiSeq, remotecall, ourcall); + else + udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", " "\"service\": %d, \"remote\": \"%s\", \"local\": \"%s\"}", - NODECALLLOPPED, UDPSeq++, L4->Service, remotecall, ourcall); + NODECALLLOPPED, L4->apiSeq, Service, remotecall, ourcall); // Debugprintf(UDPMsg); sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest)); @@ -563,7 +619,7 @@ void L4DisconnectEvent(TRANSPORTENTRY * L4, char * Direction, char * Reason) 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); + NODECALLLOPPED, L4->apiSeq, Direction, 0, remotecall, ourcall,L4->segsSent, L4->segsRcvd, L4->segsResent, Count, Reason); // Debugprintf(UDPMsg); sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest)); @@ -579,11 +635,16 @@ void L4StatusSeport(TRANSPORTENTRY * L4) char nodecall[16]; char circuitinfo[32]; int Count; + time_t Now = time(NULL); + int Service = L4->Service; - // CACK received + + + // Regular Status reports if (NodeAPISocket) { + L4->lastStatusSentTime = Now; nodecall[ConvFromAX25(L4->L4TARGET.DEST->DEST_CALL, nodecall)] = 0; remotecall[ConvFromAX25(L4->L4USER, remotecall)] = 0; ourcall[ConvFromAX25(L4->L4MYCALL, ourcall)] = 0; @@ -599,10 +660,15 @@ void L4StatusSeport(TRANSPORTENTRY * L4) 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); + + if (Service == -1) + udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitStatus\", \"node\": \"%s\", \"id\": %d, \"direction\": \"%s\"," + "\"upForSecs\": %d,\"remote\": \"%s\", \"local\": \"%s\", \"segsSent\": %d, \"segsRcvd\": %d, \"segsResent\": %d, \"segsQueued\": %d}", + NODECALLLOPPED, L4->apiSeq, L4->Direction, Now - L4->ConnectTime, remotecall, ourcall,L4->segsSent, L4->segsRcvd, L4->segsResent, Count); + else + udplen = sprintf(UDPMsg, "{\"@type\": \"CircuitStatus\", \"node\": \"%s\", \"id\": %d, \"direction\": \"%s\"," + "\"upForSecs\": %d, \"service\": %d, \"remote\": \"%s\", \"local\": \"%s\", \"segsSent\": %d, \"segsRcvd\": %d, \"segsResent\": %d, \"segsQueued\": %d}", + NODECALLLOPPED, L4->apiSeq, L4->Direction, Now - L4->ConnectTime, Service, remotecall, ourcall,L4->segsSent, L4->segsRcvd, L4->segsResent, Count); // Debugprintf(UDPMsg); sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest)); @@ -633,7 +699,42 @@ char * PIDtoText(int PID) return "?"; } -void APIL2Trace(struct _MESSAGE * Message, char Dirn) +void dumpDuffPacket(char * call, char * Buffer, int Len) +{ + // log to syslog in base64 + + char * Base64; + + Base64 = byte_base64_encode(Buffer, Len); + + Debugprintf("Trace Error %s %s", call, Base64); + free(Base64); +} + +int checkCall(char * call, unsigned char * Buffer, int Len) +{ + char c; + int i; + + // Validate source and dest calls - if duff, dump packet + + for (i = 0; i < strlen(call); i++) + { + c = call[i]; + + if (isalnum(c) || c == '-' || c == '@') + continue; + + dumpDuffPacket(call, Buffer, Len); + return 0; + } + + return 1; +} + + + +void APIL2Trace(struct _MESSAGE * Message, char * Dirn) { char UDPMsg[2048]; int udplen; @@ -649,6 +750,12 @@ void APIL2Trace(struct _MESSAGE * Message, char Dirn) int UFlag = 0; int NS; int NR; + struct PORTCONTROL * PORT = GetPortTableEntryFromPortNum(Message->PORT); + time_t Now = time(NULL); + + + if (PORT == 0) + return; if ((Message->ORIGIN[6] & 1) == 0) // Digis return; @@ -656,12 +763,19 @@ void APIL2Trace(struct _MESSAGE * Message, char Dirn) destcall[ConvFromAX25(Message->DEST, destcall)] = 0; srcecall[ConvFromAX25(Message->ORIGIN, srcecall)] = 0; - // See if any Digis + // Validate source and dest calls - if duff, dump packet + + if (!checkCall(destcall,(char *) Message, Message->LENGTH)) + return; + + if (!checkCall(srcecall, (char *) Message, Message->LENGTH)) + return; + + // 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)) @@ -784,9 +898,9 @@ void APIL2Trace(struct _MESSAGE * Message, char Dirn) // 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); + "{\"@type\": \"L2Trace\", \"serial\": %d, \"time\": %d, \"dirn\": \"%s\", \"isRF\": %s, \"reportFrom\": \"%s\", \"port\": \"%d\", \"srce\": \"%s\", \"dest\": \"%s\", \"ctrl\": %d," + "\"l2Type\": \"%s\", \"modulo\": 8, \"cr\": \"%s\"", + UDPSeq++, (int)Now, Dirn, (PORT->isRF)?"true":"false", NODECALLLOPPED, Message->PORT, srcecall, destcall, Message->CTL, Type, CR); if (UIFlag) { @@ -830,9 +944,9 @@ void APIL2Trace(struct _MESSAGE * Message, char Dirn) // supervisory if (PF[0]) - udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, ", \"pf\": \"%s\", \"rseq\": %d, \"tseq\": %d", PF, NR, NS); + udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, ", \"pf\": \"%s\", \"rseq\": %d", PF, NR); else - udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, ", \"rseq\": %d, \"tseq\": %d", NR, NS); + udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, ", \"rseq\": %d", NR); } @@ -844,6 +958,48 @@ void APIL2Trace(struct _MESSAGE * Message, char Dirn) } + //"@type" = @L3Trace, reportFrom, time, dirn, + +void NetromTCPTrace(struct _MESSAGE * Message, char * Dirn) +{ + char UDPMsg[2048]; + int udplen; + time_t Now = time(NULL); + int iLen = Message->LENGTH - (15 + MSGHDDRLEN); + int isRF = 0; + + + udplen = snprintf(UDPMsg, 2048, + "{\"@type\": \"L3Trace\", \"serial\": %d, \"time\": %d, \"dirn\": \"%s\", \"isRF\": %s, \"reportFrom\": \"%s\", \"port\": %d", + UDPSeq++, (int)Now, Dirn, (isRF)?"true":"false", NODECALLLOPPED, Message->PORT); + + + udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, + ", \"ilen\": %d, \"pid\": %d, \"ptcl\": \"%s\"", + iLen, Message->PID, PIDtoText(Message->PID)); + + 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; + } + + + + 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; @@ -870,7 +1026,7 @@ int decodeNETROMUIMsg(unsigned char * Msg, int iLen, char * Buffer, int BufferLe Msg += 7; // to first field - Len = snprintf(Buffer, BufferLen, ", \"l3Type\": \"Routing info\", \"type\": \"NODES\", \"nodes\": ["); + Len = snprintf(Buffer, BufferLen, ", \"l3Type\": \"Routing info\", \"type\": \"NODES\", \"fromAlias\": \"%s\", \"nodes\": [", Alias); iLen -= 7; //Header, mnemonic and signature length @@ -921,6 +1077,13 @@ int decodeNETROMIFrame(unsigned char * Msg, int iLen, char * Buffer, int BufferL destcall[ConvFromAX25(L3MSG->L3DEST, destcall)] = 0; srcecall[ConvFromAX25(L3MSG->L3SRCE, srcecall)] = 0; + if (!checkCall(destcall, Msg, iLen)) + return 0; + + if (!checkCall(srcecall, Msg, iLen)) + return 0; + + if (strcmp(destcall, "KEEPLI") == 0) return 0; @@ -955,6 +1118,14 @@ int decodeNETROMIFrame(unsigned char * Msg, int iLen, char * Buffer, int BufferL srcUser[ConvFromAX25(&L3MSG->L4DATA[1], srcUser)] = 0; srcNode[ConvFromAX25(&L3MSG->L4DATA[8], srcNode)] = 0; + if (!checkCall(srcUser, Msg, iLen)) + return 0; + + + if (!checkCall(srcNode, Msg, iLen)) + return 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); @@ -969,7 +1140,7 @@ int decodeNETROMIFrame(unsigned char * Msg, int iLen, char * Buffer, int BufferL // Can be ACK or NACK depending on Choke flag if (L3MSG->L4FLAGS & L4BUSY) - Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"CONN NACK\", \"toCct\": %d", + Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"CONN NAK\", \"toCct\": %d", (L3MSG->L4INDEX << 8) | L3MSG->L4ID); else Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"CONN ACK\", \"toCct\": %d, \"fromCct\": %d, \"accWin\": %d", @@ -1073,7 +1244,7 @@ int decodeRecordRoute(L3MESSAGE * L3, int iLen, char * Buffer, int BufferLen) Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"NRR Request\", \"nrrId\": %d, \"nrrRoute\": \"%s\"", (L3->L4TXNO << 8) | L3->L4RXNO, callList); - Debugprintf(Buffer); +// Debugprintf(Buffer); return Len; } diff --git a/KernelScript1.rc b/KernelScript1.rc index 4eef3b5..b230ace 100644 --- a/KernelScript1.rc +++ b/KernelScript1.rc @@ -50,6 +50,19 @@ BEGIN LTEXT "Enable IGate",IDC_STATIC,5,2,49,10 END +CLOSING DIALOG DISCARDABLE 300, 300, 200, 50 +STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | + WS_THICKFRAME +CAPTION "BPQ32 Close All" +CLASS "CLOSING" +FONT 8, "Fixedsys" +BEGIN + LTEXT "Closing Links - Please wait....",IDC_BACKGROUND,22,20,337,273 + +END + + + CONFIG DIALOGEX 249, 200, 160, 118 STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE diff --git a/L2Code.c b/L2Code.c index 8171d49..44015e1 100644 --- a/L2Code.c +++ b/L2Code.c @@ -2346,6 +2346,9 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA LINK->L2TIMER = ONEMINUTE; // (RE)SET TIMER + + LINK->framesResent++; + PORT = LINK->LINKPORT; if (PORT) @@ -2452,6 +2455,20 @@ treatasRR: LINK->L2FLAGS &= ~POLLSENT; // CLEAR I(P) or RR(P) SET + // ?? is this the place to do RTT? + + if (LINK->lastPSent) + { + int RTT = GetTickCount() - LINK->lastPSent; + + if (LINK->RTT) + LINK->RTT = ((LINK->RTT * 90) / 100) + RTT /10; // Smooth - 90% of old + 10% of new + else + LINK->RTT = RTT; + + LINK->lastPSent = 0; + } + if ((CTL & 0xf) == RNR) { // Dont Clear timer on receipt of RNR(F), spec says should poll for clearing of busy, @@ -2927,6 +2944,8 @@ VOID RESETNS(struct _LINKTABLE * LINK, UCHAR NS) { int Resent = (LINK->LINKNS - NS) & 7; // FRAMES TO RESEND + LINK->framesResent += Resent; + LINK->LINKNS = NS; // RESET N(S) if (LINK->LINKTYPE == 3) // mode-Node @@ -3150,6 +3169,11 @@ VOID SDETX(struct _LINKTABLE * LINK) LINK->LASTFRAMESENT = time(NULL); LINK->LASTSENTQCOUNT = COUNT_AT_L2(LINK); + if (LINK->LASTSENTQCOUNT > LINK->maxQueued) + LINK->maxQueued = LINK->LASTSENTQCOUNT; + + if (LINK->LASTSENTQCOUNT > LINK->intervalMaxQueued) + LINK->intervalMaxQueued = LINK->LASTSENTQCOUNT; if (LINK->AllowCompress && Msg->LENGTH > 20 && LINK->TX_Q && Msg->PID == 240) // if short and no more not worth trying compression { @@ -3352,6 +3376,7 @@ VOID SDETX(struct _LINKTABLE * LINK) // FLAG BUFFER TO CAUSE TIMER TO BE RESET AFTER SEND (or ACK if ACKMODE) Buffer->Linkptr = LINK; + LINK->lastPSent = GetTickCount(); } } diff --git a/L3Code.c b/L3Code.c index c25df5b..0aafe67 100644 --- a/L3Code.c +++ b/L3Code.c @@ -236,7 +236,7 @@ BOOL ACTIVATE_DEST(struct DEST_LIST * DEST) return L2SETUPCROSSLINK(ROUTE); } - // We umst be waiting for link to come up + // We must be waiting for link to come up return TRUE; @@ -627,9 +627,6 @@ VOID PROCROUTES(struct DEST_LIST * DEST, struct ROUTE * ROUTE, int Qual) if (Index == 0) { // THIS IS A REFRESH OF BEST - IF THIS ISNT ACTIVE ROUTE, MAKE IT ACTIVE - - if (DEST->DEST_ROUTE > 1) // LEAVE IT IF NOT SELECTED OR ALREADY USING BEST - DEST->DEST_ROUTE = 1; } goto UpdatateThisEntry; @@ -728,6 +725,8 @@ SORTROUTES: goto SORTROUTES; // 1 AND 2 MAY NOW BE WRONG! } + + DEST->DEST_ROUTE = 0; // OForce re-evaluation. } int COUNTNODES(struct ROUTE * ROUTE) @@ -1042,7 +1041,8 @@ VOID L3TimerProc() LINK = LINKS; i = MAXLINKS; - while (i--); + + while (i--) { if (LINK->LINKTYPE == 3) // Only if Internode { @@ -1310,6 +1310,9 @@ VOID REMOVENODE(dest_list * DEST) while (DEST->DEST_Q) ReleaseBuffer(Q_REM(&DEST->DEST_Q)); + if (DEST->DEST_STATE & 0x80) // LOCKED DESTINATION + return; + // MAY NEED TO CHECK FOR L4 CIRCUITS USING DEST, BUT PROBABLY NOT, // AS THEY SHOULD HAVE TIMED OUT LONG AGO diff --git a/L4Code.c b/L4Code.c index ecfd5f0..9a37668 100644 --- a/L4Code.c +++ b/L4Code.c @@ -73,6 +73,7 @@ void OutgoingL4ConnectionEvent(TRANSPORTENTRY * L4); void IncomingL4ConnectionEvent(TRANSPORTENTRY * L4); void L4DisconnectEvent(TRANSPORTENTRY * L4, char * Direction, char * Reason); VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame); +void L4StatusSeport(TRANSPORTENTRY * L4); static UINT APPLMASK; @@ -89,6 +90,8 @@ extern int L2Compress; extern int L2CompMaxframe; extern int L2CompPaclen; +int sessionStatusInterval = 300; // 5 mins + // L4 Flags Values #define DISCPENDING 8 // SEND DISC WHEN ALL DATA ACK'ED @@ -1128,6 +1131,7 @@ VOID L4TimerProc() TRANSPORTENTRY * L4 = L4TABLE; TRANSPORTENTRY * Partner; int MaxLinks = MAXLINKS; + time_t Now = time(NULL); while (n--) { @@ -1136,6 +1140,12 @@ VOID L4TimerProc() L4++; continue; } + + // Check for Status report time + + if (L4->lastStatusSentTime && (Now - L4->lastStatusSentTime) > sessionStatusInterval) + L4StatusSeport(L4); + // CHECK FOR L4BUSY SET AND NO LONGER BUSY @@ -1601,7 +1611,8 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl int Index; char APPLCMD[13] = ""; - memcpy(APPLCMD, APPL->APPLCMD, 13); + if (APPL) + memcpy(APPLCMD, APPL->APPLCMD, 13); memcpy(BPQPARAMS, &L4T1, 2); // SET DEFAULT T1 IN CASE NOT FROM ANOTHER BPQ NODE @@ -1674,6 +1685,8 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl { // At the moment I only handle connects to appls. May support other node commands later. + memcpy(APPLCMD, CMD->String, 13); + if (n < APPL1 + NumberofAppls) goto doAPPLConnect; } @@ -1916,19 +1929,34 @@ void L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG) void SendConNAK(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG) { + struct TNCINFO * TNC; + L3MSG->L4FLAGS = L4CACK | L4BUSY; // REJECT L3MSG->L4DATA[0] = 0; // WINDOW L3SWAPADDRESSES(L3MSG); L3MSG->L3TTL = L3LIVES; - C_Q_ADD(&LINK->TX_Q, L3MSG); + TNC = LINK->LINKPORT->TNC; + + 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); + } VOID SendL4RESET(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG) { // Paula's extension + struct TNCINFO * TNC; + L3MSG->L4RXNO = L3MSG->L4ID; L3MSG->L4TXNO = L3MSG->L4INDEX; @@ -1938,7 +1966,19 @@ VOID SendL4RESET(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG) L3MSG->L3TTL = L3LIVES; L3MSG->LENGTH = (int)(&L3MSG->L4DATA[0] - (UCHAR *)L3MSG); - C_Q_ADD(&LINK->TX_Q, L3MSG); + + TNC = LINK->LINKPORT->TNC; + + 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); + } @@ -2028,7 +2068,7 @@ TryAgain: while (n--) { - if (DEST->DEST_COUNT == 0 && DEST->DEST_RTT == 0) // Not used and not INP3 + if (DEST->DEST_COUNT == 0 && DEST->DEST_RTT == 0 && (DEST->DEST_STATE & 0x80) == 0) // Not used and not INP3 and not Appl { if (DEST->NRROUTE[0].ROUT_QUALITY < WorstQual) { @@ -2258,6 +2298,14 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask, return; } + // if connect to service don't send connected to node messsage as service will send own message + +// if (L4->Service) +// { +// ReleaseBuffer(L3MSG); +// return; +// } + Msg = (PDATAMESSAGE)L3MSG; // reuse input buffer Msg->PID = 0xf0; diff --git a/LinBPQ.c b/LinBPQ.c index 1c16ef4..dd9bdf6 100644 --- a/LinBPQ.c +++ b/LinBPQ.c @@ -85,8 +85,7 @@ VOID GetPGConfig(); void SendBBSDataToPktMap(); void CloseAllLinks(); void hookNodeClosing(char * Reason); - -extern uint64_t INP3timeLoadedMS; +void NETROMTCPResolve(); BOOL IncludesMail = FALSE; BOOL IncludesChat = FALSE; @@ -860,8 +859,6 @@ int main(int argc, char * argv[]) if (!isatty(STDOUT_FILENO) || !isatty(STDIN_FILENO)) Redirected = 1; - INP3timeLoadedMS = GetTickCount(); - #endif printf("G8BPQ AX25 Packet Switch System Version %s %s\n", TextVerstring, Datestring); @@ -1015,6 +1012,8 @@ int main(int argc, char * argv[]) return (0); } + NETROMTCPResolve(); + for (i=0;PWTEXT[i] > 0x20;i++); //Scan for cr or null PWLen=i; @@ -1546,6 +1545,8 @@ int main(int argc, char * argv[]) Consoleprintf(VerCopyright); Start(); + + NETROMTCPResolve(); INITIALISEPORTS(); diff --git a/MailTCP.c b/MailTCP.c index 289fb62..37c7cf9 100644 --- a/MailTCP.c +++ b/MailTCP.c @@ -2092,20 +2092,19 @@ int CreateSMTPMessage(SocketConn * sockptr, int i, char * MsgTitle, time_t Date, struct tm * tm; tm = gmtime(&Date); - + sprintf(DateString, "%04d/%02d/%02d %02d:%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min); if (strcmp(Msg->to, "RMS") == 0) // Address is in via - strcpy(B2To, Msg->via); - else - if (Msg->via[0]) - sprintf(B2To, "%s@%s", Msg->to, Msg->via); + strcpy(B2To, Msg->via); else - strcpy(B2To, Msg->to); + if (Msg->via[0]) + sprintf(B2To, "%s@%s", Msg->to, Msg->via); + else + strcpy(B2To, Msg->to); - Msg->B2Flags = B2Msg | Attachments; if (Msg->type == 'P') @@ -3934,12 +3933,12 @@ int CreatePOP3Message(char * From, char * To, char * MsgTitle, time_t Date, char if (strcmp(Msg->to, "RMS") == 0) // Address is in via - strcpy(B2To, Msg->via); - else - if (Msg->via[0]) - sprintf(B2To, "%s@%s", Msg->to, Msg->via); + strcpy(B2To, Msg->via); else - strcpy(B2To, Msg->to); + if (Msg->via[0]) + sprintf(B2To, "%s@%s", Msg->to, Msg->via); + else + strcpy(B2To, Msg->to); Msg->B2Flags = B2Msg | Attachments; diff --git a/NETROMTCP.c b/NETROMTCP.c index 79f186b..0710f73 100644 --- a/NETROMTCP.c +++ b/NETROMTCP.c @@ -1,551 +1,608 @@ -/* -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 -//#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)); -} - +/* +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 +//#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); +void NetromTCPTrace(struct _MESSAGE * Message, char * Dirn); + +extern SOCKET NodeAPISocket; + +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; + char farCall[10]; + + farCall[ConvFromAX25(Route->NEIGHBOUR_CALL, farCall)] = 0; + +// Debugprintf("Opening NRTCP Connection to %s", farCall); + + 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, farCall, 10); + Route->NEIGHBOUR_LINK = Info->LINK; + + Info->Route = Route; + Info->LINK->NEIGHBOUR = Route; + Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT); + } + + return NETROMTCPConnect(Route, sockptr); + +} + +void NETROMTCPResolve() +{ + struct ROUTE * Route = NEIGHBOURS; + int n = MAXNEIGHBOURS; + struct addrinfo hints, *res = 0; + char PortString[20]; + int err; + + while (n--) + { + if (Route->TCPAddress) + { + // try to resolve host + + sprintf(PortString, "%d", Route->TCPPort); + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + getaddrinfo(Route->TCPHost, PortString, &hints, &res); + + err = WSAGetLastError(); + + if (res) + { + Route->TCPAddress->ai_family = res->ai_family; + Route->TCPAddress->ai_socktype = res->ai_socktype; + Route->TCPAddress->ai_protocol = res->ai_protocol; + Route->TCPAddress->ai_addrlen = res->ai_addrlen; + memcpy(Route->TCPAddress->ai_addr, res->ai_addr, sizeof(struct sockaddr)); + freeaddrinfo(res); + } + } + + Route++; + } +} + +int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr) +{ + int err; + u_long param=1; + BOOL bcopt=TRUE; + SOCKET sock; + struct sockaddr_in sinx; + int addrlen=sizeof(sinx); + char PortString[20]; + struct addrinfo * res = Route->TCPAddress; + int Port = Route->TCPPort; + + sprintf(PortString, "%d", Port); + + // get host info, make socket, and connect it + + if (res->ai_family == 0) + { +// err = WSAGetLastError(); +// Debugprintf("Resolve HostName %s Failed - Error %d", Route->TCPHost, err); + return FALSE; // Resolve failed + } + + sock = sockptr->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + if (sock == INVALID_SOCKET) + { + Debugprintf, ("Netrom over TCP Create Socket Failed"); + return FALSE; + } + + ioctl(sock, FIONBIO, ¶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; + return TRUE; + } + else + { + err=WSAGetLastError(); + + if (err == 10035 || err == 115 || err == 36) //EWOULDBLOCK + { + // Connect in Progress + + sockptr->Connecting = TRUE; + return TRUE; + } + else + { + // Connect failed + + closesocket(sockptr->socket); + + return FALSE; + } + } + + return FALSE; +} + + + + +void NETROMConnectionAccepted(struct ConnectionInfo * sockptr) +{ + // Not sure we can do much here until first message arrives with callsign + + sockptr->Connected = TRUE; +// Debugprintf("NRTCP Connection Accepted"); +} + +void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info) +{ + // Connection Complete + +// Debugprintf("NRTCP Connected"); + + sockptr->Connecting = FALSE; + sockptr->Connected = TRUE; + + Info->LINK->L2STATE = 5; + + if (Info->Route->INP3Node) + SendRTTMsg(Info->Route); +} + +int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info, int portNo) +{ + int len=0, maxlen; + struct NRTCPMsg * Msg; + struct _L3MESSAGEBUFFER * L3Msg; + struct ROUTE * Route; + UCHAR axCall[7]; + PMESSAGE Buffer; + + ioctl(sock,FIONREAD,&len); + + maxlen = InputBufferLen - sockptr->InputLen; + + if (len > maxlen) len = maxlen; + + len = recv(sock, &sockptr->InputBuffer[sockptr->InputLen], len, 0); + + if (len == SOCKET_ERROR || len == 0) + { + // Failed or closed - clear connection + + NETROMConnectionLost(sockptr); + return 0; + } + + sockptr->InputLen += len; + + // Process data + +checkLen: + + // See if we have a whole packet + + Msg = (struct NRTCPMsg *)&sockptr->InputBuffer[0]; + + if (Msg->Length > sockptr->InputLen) // if not got whole frame wait + return 0; + + if (Info->Call[0] == 0) + { + // first packet - do we need to do anything? + + // This must be an incoming connection as Call is set before calling so need to find route record and set things up. + +// Debugprintf("New NRTCP Connection from %s", Msg->Call); + + memcpy(Info->Call, Msg->Call, 10); + + ConvToAX25(Msg->Call, axCall); + + if (FindNeighbour(axCall, portNo, &Route)) + { + Info->Route = Route; + Route->NEIGHBOUR_LINK = Info->LINK; + Route->NEIGHBOUR_PORT = portNo; + Info->LINK->NEIGHBOUR = Route; + Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(portNo); + Route->TCPSession = Info; + Info->LINK->L2STATE = 5; + + if (Info->Route->INP3Node) + SendRTTMsg(Info->Route); + } + else + { + Debugprintf("Neighbour %s port %d not found - closing connection", Msg->Call, portNo); + closesocket(sockptr->socket); + sockptr->SocketActive = FALSE; + memset(sockptr, 0, sizeof(struct ConnectionInfo)); + Info->Call[0] = 0; + return 0; + } + } + + + if (memcmp(Info->Call, Msg->Call, 10) != 0) + { + Debugprintf("NRTCP Mismatch - closing connection"); + + closesocket(sockptr->socket); + sockptr->SocketActive = FALSE; + memset(sockptr, 0, sizeof(struct ConnectionInfo)); + Info->Call[0] = 0; + return 0; + } + + // Format as if come from an ax.25 link + + L3Msg = GetBuff(); + + if (L3Msg == 0) + goto seeifMore; + + L3Msg->LENGTH = (Msg->Length - 12) + MSGHDDRLEN; + L3Msg->Next = 0; + L3Msg->Port = portNo; + L3Msg->L3PID = NETROM_PID; + memcpy(&L3Msg->L3SRCE, Msg->Packet, Msg->Length - 13); + + // Create a dummy L2 message so we can trace it + + Buffer = GetBuff(); + + if (Buffer) + { + Buffer->CHAIN = 0; + Buffer->CTL = 0; + Buffer->PORT = portNo; + + ConvToAX25(Info->Call, Buffer->ORIGIN); + ConvToAX25(MYNETROMCALL, Buffer->DEST); + + memcpy(Buffer->L2DATA, &L3Msg->L3SRCE[0], Msg->Length - 13); + Buffer->ORIGIN[6] |= 1; // Set end of calls + Buffer->PID = NETROM_PID; + Buffer->LENGTH = Msg->Length + 10; + time(&Buffer->Timestamp); + + BPQTRACE(Buffer, FALSE); + + if(NodeAPISocket) + NetromTCPTrace(Buffer, "rcvd"); + + 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; + + 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); + + if(NodeAPISocket) + NetromTCPTrace(Buffer, "sent"); + + Buffer->PORT = Route->NEIGHBOUR_PORT | 128; // TX Flag + BPQTRACE(Buffer, FALSE); + + + ReleaseBuffer(Buffer); + } + +} + + +void NETROMConnectionLost(struct ConnectionInfo * sockptr) +{ + struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number]; + struct ROUTE * Route; + + closesocket(sockptr->socket); + + // If there is an attached route (there should be) clear all connections + + if (Info) + { + Route = Info->Route; + + if (sockptr->Connected) + L3LINKCLOSED(Info->LINK, LINKLOST); + + if (sockptr->Connecting) + L3LINKCLOSED(Info->LINK, SETUPFAILED); + + if (Route) + Route->TCPSession = 0; + + Info->Call[0] = 0; + Info->LINK->L2STATE = 0; + } + + sockptr->SocketActive = FALSE; + + memset(sockptr, 0, sizeof(struct ConnectionInfo)); +} + diff --git a/TelnetV6.c b/TelnetV6.c index 0761363..590186c 100644 --- a/TelnetV6.c +++ b/TelnetV6.c @@ -3874,12 +3874,14 @@ MsgLoop: LFPtr=memchr(MsgPtr, 10, InputLen); if (LFPtr == 0) + { if (CRPtr) { LFPtr = ++CRPtr; InputLen++; } - if (LFPtr == 0) + } + if (LFPtr == 0) { // Check Paclen @@ -3895,7 +3897,7 @@ MsgLoop: } // Send to Node - + // Line could be up to 500 chars if coming from a program rather than an interative user // Limit send to node to 255 @@ -3907,16 +3909,16 @@ MsgLoop: memmove(MsgPtr,MsgPtr+255,InputLen); } - + SendtoNode(TNC, sockptr->Number, MsgPtr, InputLen); sockptr->InputLen = 0; - + } // PACLEN return 0; // No CR } - + // Got a LF // Process data up to the cr @@ -3929,7 +3931,7 @@ MsgLoop: case 2: // Normal Data State - + STREAM->bytesRXed += MsgLen; SendIndex = 0; @@ -3944,7 +3946,7 @@ MsgLoop: } SendtoNode(TNC, sockptr->Number, MsgPtr + SendIndex, MsgLen); - + MsgLen += SendIndex; // If anything left, copy down buffer, and go back @@ -3963,20 +3965,20 @@ MsgLoop: return 0; case 0: - - // Check Username - // + + // Check Username + // *(LFPtr-1)=0; // remove cr - - // send(sock, NLMsg, 2, 0); - if (LogEnabled) + // send(sock, NLMsg, 2, 0); + + if (LogEnabled) { char Addr[256]; - + Tel_Format_Addr(sockptr, Addr); - + if (strlen(MsgPtr) > 64) { MsgPtr[64] = 0; @@ -4571,7 +4573,8 @@ MsgLoop: if (P8 == 1) SendPortsForMonitor(sock, sockptr->UserPointer->Secure); - sockptr->InputLen = 0; + + sockptr->InputLen = 0; return 0; } } @@ -6386,10 +6389,10 @@ VOID SaveCMSHostInfo(int port, struct TCPINFO * TCP, int CMSNo) char ip[256]; int n; - if (sizeof(time_t) == 4) - n = sscanf(buf,"%s %d %s", addr, (int *)&t, ip); - else - n = sscanf(buf, "%s %lld %s", addr, &t, ip); + if (sizeof(time_t) == 4) + n = sscanf(buf,"%s %d %s", addr, (int *)&t, ip); + else + n = sscanf(buf, "%s %lld %s", addr, &t, ip); if (n == 3) { diff --git a/UZ7HODrv.c b/UZ7HODrv.c index e166b36..2adfe12 100644 --- a/UZ7HODrv.c +++ b/UZ7HODrv.c @@ -1586,81 +1586,81 @@ static int ProcessLine(char * buf, int Port) if (TNC->TCPPort == 0) TNC->TCPPort = 8000; - TNC->destaddr.sin_family = AF_INET; - TNC->destaddr.sin_port = htons(TNC->TCPPort); - TNC->HostName = malloc(strlen(p_ipad)+1); + TNC->destaddr.sin_family = AF_INET; + TNC->destaddr.sin_port = htons(TNC->TCPPort); + TNC->HostName = malloc(strlen(p_ipad)+1); - if (TNC->HostName == NULL) return TRUE; + if (TNC->HostName == NULL) return TRUE; - strcpy(TNC->HostName,p_ipad); + strcpy(TNC->HostName,p_ipad); - ptr = strtok(NULL, " \t\n\r"); + ptr = strtok(NULL, " \t\n\r"); - if (ptr) + if (ptr) + { + if (_stricmp(ptr, "PTT") == 0) { - if (_stricmp(ptr, "PTT") == 0) - { - ptr = strtok(NULL, " \t\n\r"); + ptr = strtok(NULL, " \t\n\r"); - if (ptr) - { - DecodePTTString(TNC, ptr); - ptr = strtok(NULL, " \t\n\r"); - } - } - - if (ptr &&_memicmp(ptr, "PATH", 4) == 0) + if (ptr) { - p_cmd = strtok(NULL, "\n\r"); - if (p_cmd) TNC->ProgramPath = _strdup(p_cmd); + DecodePTTString(TNC, ptr); + ptr = strtok(NULL, " \t\n\r"); } } - // Read Initialisation lines - - while(TRUE) + if (ptr &&_memicmp(ptr, "PATH", 4) == 0) { - if (GetLine(buf) == 0) - return TRUE; + p_cmd = strtok(NULL, "\n\r"); + if (p_cmd) TNC->ProgramPath = _strdup(p_cmd); + } + } - strcpy(errbuf, buf); + // Read Initialisation lines - if (memcmp(buf, "****", 4) == 0) - return TRUE; + while(TRUE) + { + if (GetLine(buf) == 0) + return TRUE; - ptr = strchr(buf, ';'); - if (ptr) - { - *ptr++ = 13; - *ptr = 0; - } - - if (_memicmp(buf, "MAXSESSIONS", 11) == 0) - { - AGW->MaxSessions = atoi(&buf[12]); - if (AGW->MaxSessions > 26 ) AGW->MaxSessions = 26; - } - if (_memicmp(buf, "CONTIMEOUT", 10) == 0) - AGW->ConnTimeOut = atoi(&buf[11]) * 10; - else + strcpy(errbuf, buf); + + if (memcmp(buf, "****", 4) == 0) + return TRUE; + + ptr = strchr(buf, ';'); + if (ptr) + { + *ptr++ = 13; + *ptr = 0; + } + + if (_memicmp(buf, "MAXSESSIONS", 11) == 0) + { + AGW->MaxSessions = atoi(&buf[12]); + if (AGW->MaxSessions > 26 ) AGW->MaxSessions = 26; + } + if (_memicmp(buf, "CONTIMEOUT", 10) == 0) + AGW->ConnTimeOut = atoi(&buf[11]) * 10; + else if (_memicmp(buf, "UPDATEMAP", 9) == 0) TNC->PktUpdateMap = TRUE; else - if (_memicmp(buf, "BEACONAFTERSESSION", 18) == 0) // Send Beacon after each session - TNC->RPBEACON = TRUE; - else - if (_memicmp(buf, "WINDOW", 6) == 0) - TNC->Window = atoi(&buf[7]); - else - if (_memicmp(buf, "DEFAULTMODEM", 12) == 0) - TNC->AGWInfo->Modem = atoi(&buf[13]); - else - if (_memicmp(buf, "MODEMCENTER", 11) == 0 || _memicmp(buf, "MODEMCENTRE", 11) == 0) - TNC->AGWInfo->CenterFreq = atoi(&buf[12]); - else - if (standardParams(TNC, buf) == FALSE) - strcat(TNC->InitScript, buf); - } + if (_memicmp(buf, "BEACONAFTERSESSION", 18) == 0) // Send Beacon after each session + TNC->RPBEACON = TRUE; + else + if (_memicmp(buf, "WINDOW", 6) == 0) + TNC->Window = atoi(&buf[7]); + else + if (_memicmp(buf, "DEFAULTMODEM", 12) == 0) + TNC->AGWInfo->Modem = atoi(&buf[13]); + else + if (_memicmp(buf, "MODEMCENTER", 11) == 0 || _memicmp(buf, "MODEMCENTRE", 11) == 0) + TNC->AGWInfo->CenterFreq = atoi(&buf[12]); + else + if (standardParams(TNC, buf) == FALSE) + strcat(TNC->InitScript, buf); + } return (TRUE); diff --git a/VARA.c b/VARA.c index 70f7461..f913fe8 100644 --- a/VARA.c +++ b/VARA.c @@ -423,8 +423,9 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) { TNC->Busy--; if (TNC->Busy == 0) - SetWindowText(TNC->xIDC_CHANSTATE, "Clear"); + { SetWindowText(TNC->xIDC_CHANSTATE, "Clear"); strcpy(TNC->WEB_CHANSTATE, "Clear"); + } } } diff --git a/Versions.h b/Versions.h index be8a65e..25ed90e 100644 --- a/Versions.h +++ b/Versions.h @@ -10,8 +10,8 @@ #endif -#define KVers 6,0,25,8 -#define KVerstring "6.0.25.8\0" +#define KVers 6,0,25,12 +#define KVerstring "6.0.25.12\0" #ifdef CKernel diff --git a/WINMOR.c b/WINMOR.c index 836a070..94630b3 100644 --- a/WINMOR.c +++ b/WINMOR.c @@ -618,8 +618,10 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) { TNC->Busy--; if (TNC->Busy == 0) + { SetWindowText(TNC->xIDC_CHANSTATE, "Clear"); strcpy(TNC->WEB_CHANSTATE, "Clear"); + } } } diff --git a/WebMail.c b/WebMail.c index 63bfd6e..a97b9bf 100644 --- a/WebMail.c +++ b/WebMail.c @@ -3311,7 +3311,7 @@ char * xxReadTemplate(char * FormSet, char * DirName, char *FileName) while ((entry = readdir(dir)) != NULL) { if (entry->d_type == DT_DIR) - continue; + continue; if (stristr(entry->d_name, FileName)) { @@ -5609,7 +5609,7 @@ char * CheckFile(struct HtmlFormDir * Dir, char * FN) while ((entry = readdir(dir)) != NULL) { if (entry->d_type == DT_DIR) - continue; + continue; if (stricmp(entry->d_name, FN) == 0) { diff --git a/asmstrucs.h b/asmstrucs.h index 3ac464b..439b6f9 100644 --- a/asmstrucs.h +++ b/asmstrucs.h @@ -184,7 +184,13 @@ typedef struct _TRANSPORTENTRY int NRRID; time_t NRRTime; + time_t ConnectTime; + char Direction[16]; // In or Out + int Service; // For Paula's Connnect to Service + int apiSeq; // for OARC event reporting + time_t lastStatusSentTime; + } TRANSPORTENTRY; @@ -250,7 +256,8 @@ typedef struct ROUTE char * TCPHost; // For NETROM over TCP int TCPPort; - struct NRTCPSTRUCT * TCPSession; + struct NRTCPSTRUCT * TCPSession; + struct addrinfo * TCPAddress; // Resolved Address } *PROUTE; @@ -736,6 +743,7 @@ typedef struct PORTCONTROL UCHAR * BUSY; // % Active (Normally DCD active or TX) int Hardware; // TNC H_TYPE. Copied here for access from application context + int isRF; // For API reporting. -1 is unspecified } PORTCONTROLX, *PPORTCONTROL; @@ -977,6 +985,15 @@ typedef struct _LINKTABLE int framesRXed; int framesTXed; int framesResent; + time_t LastStatusTime; + int LastStatusbytesRXed; + int LastStatusbytesTXed; + int maxQueued; + int intervalMaxQueued; + + uint64_t lastPSent; // Time last I frame with P bit sent in mS (for RTT Measurements) + int RTT; + // Now support compressing L2 Sessions. // We collect as much data as possible before compressing and re-packetizing @@ -994,6 +1011,7 @@ typedef struct _LINKTABLE char ApplName[16]; time_t lastStatusSentTime; + int apiSeq; // for OARC event reporting } LINKTABLE; diff --git a/bpqaxip.c b/bpqaxip.c index 3491bbd..71f0ce1 100644 --- a/bpqaxip.c +++ b/bpqaxip.c @@ -444,7 +444,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff) From[ConvFromAX25(call, &From[1]) + 1] = 0; if (strstr(CantReplyList, From) == 0) { - if (strlen(CantReplyList) < 500); + if (strlen(CantReplyList) < 500) strcat(CantReplyList, From); Debugprintf("AXIP Packet from %s dropped - can't reply", &From[1]); } @@ -557,7 +557,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff) From[ConvFromAX25(call, &From[1]) + 1] = 0; if (strstr(CantReplyList, From) == 0) { - if (strlen(CantReplyList) < 500); + if (strlen(CantReplyList) < 500) strcat(CantReplyList, From); Debugprintf("AXIP Packet from %s dropped - can't reply", &From[1]); } diff --git a/cMain.c b/cMain.c index 74b6bc6..d592ecb 100644 --- a/cMain.c +++ b/cMain.c @@ -38,6 +38,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses #include "cheaders.h" #include "tncinfo.h" #include "mqtt.h" +#include "kiss.h" VOID L2Routine(struct PORTCONTROL * PORT, PMESSAGE Buffer); VOID ProcessIframe(struct _LINKTABLE * LINK, PDATAMESSAGE Buffer); @@ -57,7 +58,7 @@ VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD); void WritePacketLogThread(void * param); void hookNodeStarted(); void hookNodeRunning(); -void APIL2Trace(struct _MESSAGE * Message, char Dirn); +void APIL2Trace(struct _MESSAGE * Message, char * Dirn); #include "configstructs.h" @@ -1017,6 +1018,7 @@ BOOL Start() PORT->INP3ONLY = PortRec->INP3ONLY; PORT->ALLOWINP3 = PortRec->AllowINP3; PORT->ENABLEINP3 = PortRec->EnableINP3; + PORT->isRF = PortRec->isRF; PORT->PORTWINDOW = (UCHAR)PortRec->MAXFRAME; @@ -1416,12 +1418,15 @@ BOOL Start() { ROUTE->TCPHost = Rcfg->tcphost; ROUTE->TCPPort = Rcfg->tcpport; + + ROUTE->TCPAddress = (struct addrinfo *)zalloc(sizeof(struct addrinfo)); + ROUTE->TCPAddress->ai_addr = (struct sockaddr *) zalloc(sizeof(struct sockaddr)); } Rcfg++; ROUTE++; } - + // SET UP INFO MESSAGE ptr2 = &cfg->C_INFOMSG[0]; @@ -2028,7 +2033,7 @@ VOID ReadNodes() ptr = strtok_s(NULL, seps, &Context); // INP3 if (ptr == NULL) continue; - if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0); // Not LOCKED ROUTE + if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0) // Not LOCKED ROUTE ROUTE->OtherendsRouteQual = atoi(ptr); ptr = strtok_s(NULL, seps, &Context); // INP3 @@ -2279,7 +2284,7 @@ VOID TIMERINTERRUPT() Message = (struct _MESSAGE *)Buffer; if(NodeAPISocket) - APIL2Trace(Message, 'T'); + APIL2Trace(Message, "sent"); Message->PORT |= 0x80; // Set TX Bit @@ -2394,7 +2399,7 @@ L2Packet: MQTTKISSRX(Buffer); if(NodeAPISocket &&PORT->PROTOCOL == 0) - APIL2Trace(Message, 'R'); + APIL2Trace(Message, "rcvd"); // Bridge if requested @@ -2765,6 +2770,7 @@ VOID INITIALISEPORTS() { char INITMSG[80]; struct PORTCONTROL * PORT = PORTTABLE; + struct PORTCONTROL * SAVEPORT; while (PORT) { @@ -2772,7 +2778,68 @@ VOID INITIALISEPORTS() WritetoConsoleLocal(INITMSG); PORT->PORTINITCODE(PORT); - PORT = PORT->PORTPOINTER; + SAVEPORT=PORT; + + // See if it is an RF port + + if (PORT->isRF == -1) // Not set + { + // Try to determine if RF + + if (PORT->PORTTYPE == 0) + { + struct KISSINFO * KISS = (struct KISSINFO *)PORT; + NPASYINFO Port; + + if (KISS->FIRSTPORT && KISS->FIRSTPORT != KISS) + { + // Not first port on device + + PORT = (struct PORTCONTROL *)KISS->FIRSTPORT; + } + + Port = KISSInfo[PORT->PORTNUMBER]; + + if (Port) + { + // KISS like + + if (PORT->PORTIPADDR.s_addr || PORT->KISSSLAVE) + { + // KISS over UDP or TCP + + if (PORT->KISSTCP) + PORT->isRF = 1; // Assume TCP is RF (software modem) + else + PORT->isRF = 0; // Assuem UDP is Internet + } + else + PORT->isRF = 1; // Serial port + } + } + else if (PORT->PORTTYPE == 14) // Loopback + PORT->isRF = 0; + + else if (PORT->PORTTYPE == 16) // External + { + if (PORT->PROTOCOL == 10) // 'HF' Port + { + struct TNCINFO * TNC = TNCInfo[PORT->PORTNUMBER]; + + if (TNC && TNC->Hardware == H_TELNET) + PORT->isRF = 0; + else + PORT->isRF = 1; // ARDOP etc + } + else + { + // External but not HF - AXIP, BPQETHER VKISS, ?? + + PORT->isRF = 0; + } + } + } + PORT = SAVEPORT->PORTPOINTER; } } diff --git a/compatbits.c b/compatbits.c index f93b2e5..a6ce8f5 100644 --- a/compatbits.c +++ b/compatbits.c @@ -25,6 +25,8 @@ Stuff to make compiling on WINDOWS and LINUX easier #ifdef WIN32 +#include + typedef unsigned int uint32_t; #define pthread_t uint32_t @@ -41,6 +43,7 @@ int pthread_equal(pthread_t T1, pthread_t T2) #include #include #include +#include #define BOOL int @@ -188,3 +191,27 @@ void closesocket(int sock) } #endif + +#ifdef WIN32 + +uint32_t GetTickCountINP3() +{ + // Returns system uptime in 10 mS, lower 20 bits only + + return (GetTickCount() / 10) & 0xfffff; +} +#else + +uint64_t GetTickCount(); + +uint32_t GetTickCountINP3() +{ + uint64_t Ticks = GetTickCount(); + + // Returns system uptime in 10 mS, lower 20 bits only + + return (Ticks / 10) & 0xfffff; +} + +#endif + diff --git a/compatbits.h b/compatbits.h index 9707771..1642af9 100644 --- a/compatbits.h +++ b/compatbits.h @@ -24,6 +24,7 @@ Stuff to make compiling on WINDOWS and LINUX easier #define strtoll _strtoi64 + #ifdef _WIN64 #include "stdint.h" #else @@ -219,7 +220,7 @@ typedef struct tagRECT #endif - +uint32_t GetTickCountINP3(); #ifdef LINBPQ diff --git a/config.c b/config.c index bb0b2f2..b41e0e8 100644 --- a/config.c +++ b/config.c @@ -379,7 +379,8 @@ static char *pkeywords[] = "BCALL", "DIGIMASK", "NOKEEPALIVES", "COMPORT", "DRIVER", "WL2KREPORT", "UIONLY", "UDPPORT", "IPADDR", "I2CBUS", "I2CDEVICE", "UDPTXPORT", "UDPRXPORT", "NONORMALIZE", "IGNOREUNLOCKEDROUTES", "INP3ONLY", "TCPPORT", "RIGPORT", "PERMITTEDAPPLS", "HIDE", -"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort", "ALLOWINP3", "ENABLEINP3"}; /* parameter keywords */ +"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort", +"ALLOWINP3", "ENABLEINP3", "isRF"}; /* parameter keywords */ static void * poffset[] = { @@ -393,7 +394,8 @@ static void * poffset[] = &xxp.BCALL, &xxp.DIGIMASK, &xxp.DefaultNoKeepAlives, &xxp.IOADDR, &xxp.DLLNAME, &xxp.WL2K, &xxp.UIONLY, &xxp.IOADDR, &xxp.IPADDR, &xxp.INTLEVEL, &xxp.IOADDR, &xxp.IOADDR, &xxp.ListenPort, &xxp.NoNormalize, &xxp.IGNOREUNLOCKED, &xxp.INP3ONLY, &xxp.TCPPORT, &xxp.RIGPORT, &xxp.PERMITTEDAPPLS, &xxp.Hide, -&xxp.SmartID, &xxp.KissParams, &xxp.SendtoM0LTEMap, &xxp.PortFreq, &xxp.M0LTEMapInfo, &xxp.QtSMPort, &xxp.AllowINP3, &xxp.EnableINP3}; /* offset for corresponding data in config file */ +&xxp.SmartID, &xxp.KissParams, &xxp.SendtoM0LTEMap, &xxp.PortFreq, &xxp.M0LTEMapInfo, &xxp.QtSMPort, +&xxp.AllowINP3, &xxp.EnableINP3, &xxp.isRF}; /* offset for corresponding data in config file */ static int proutine[] = { @@ -407,7 +409,8 @@ static int proutine[] = 0, 1, 2, 18, 15, 16, 2, 1, 17, 1, 1, 1, 1, 2, 2, 2, 1, 1, 19, 2, -1, 20, 1, 21, 22, 1, 1, 1}; /* routine to process parameter */ +1, 20, 1, 21, 22, 1, +1, 1, 1}; /* routine to process parameter */ int PPARAMLIM = sizeof(proutine)/sizeof(int); @@ -635,6 +638,8 @@ BOOL ProcessConfig() paramok[93]=1; // ONLYVer2point0 paramok[94]=1; // DEBUGINP3 paramok[95]=1; // EnableOARCAPI + paramok[96]=1; // OARCAPI + for (i=0; i < PARAMLIM; i++) { @@ -1818,6 +1823,7 @@ int ports(int i) } xxp.SendtoM0LTEMap = 1; // Default to enabled + xxp.isRF = -1; // Default to undefined while (endport == 0 && !feof(fp1)) { diff --git a/configstructs.h b/configstructs.h index 013d725..fae9d30 100644 --- a/configstructs.h +++ b/configstructs.h @@ -83,6 +83,7 @@ struct PORTCONFIG int QtSMPort; int AllowINP3; int EnableINP3; + short isRF; }; struct ROUTECONFIG diff --git a/lzhuf32.c b/lzhuf32.c index c1aea82..961c624 100644 --- a/lzhuf32.c +++ b/lzhuf32.c @@ -487,124 +487,124 @@ static void reconst(void) static void update(int c) { - int i, j, l; + int i, j, l; unsigned int k; - if (freq[R] == MAX_FREQ) { - reconst(); - } - c = prnt[c + T]; - do { - k = ++freq[c]; + if (freq[R] == MAX_FREQ) { + reconst(); + } + c = prnt[c + T]; + do { + k = ++freq[c]; - /* if the order is disturbed, exchange nodes */ + /* if the order is disturbed, exchange nodes */ + + l = c + 1; - l = c + 1; - if ((unsigned)k > freq[l]) { - while ((unsigned)k > freq[++l]); - l--; - freq[c] = freq[l]; - freq[l] = k; + while ((unsigned)k > freq[++l]); + l--; + freq[c] = freq[l]; + freq[l] = k; - i = son[c]; - prnt[i] = l; - if (i < T) prnt[i + 1] = l; + i = son[c]; + prnt[i] = l; + if (i < T) prnt[i + 1] = l; - j = son[l]; - son[l] = i; + j = son[l]; + son[l] = i; - prnt[j] = c; - if (j < T) prnt[j + 1] = c; - son[c] = j; + prnt[j] = c; + if (j < T) prnt[j + 1] = c; + son[c] = j; - c = l; - } - } while ((c = prnt[c]) != 0); /* repeat up to root */ + c = l; + } + } while ((c = prnt[c]) != 0); /* repeat up to root */ } unsigned code, len; static void EncodeChar(unsigned int c) { - unsigned int i; - int j, k; + unsigned int i; + int j, k; - i = 0; - j = 0; - k = prnt[c + T]; + i = 0; + j = 0; + k = prnt[c + T]; - /* travel from leaf to root */ - do { - i >>= 1; + /* travel from leaf to root */ + do { + i >>= 1; - /* if node's address is odd-numbered, choose bigger brother node */ - if (k & 1) i += 0x8000; + /* if node's address is odd-numbered, choose bigger brother node */ + if (k & 1) i += 0x8000; - j++; - } while ((k = prnt[k]) != R); - Putcode(j, i); - code = i; - len = j; - update(c); + j++; + } while ((k = prnt[k]) != R); + Putcode(j, i); + code = i; + len = j; + update(c); } static void EncodePosition(unsigned int c) { - unsigned int i; + unsigned int i; - /* output upper 6 bits by table lookup */ - i = c >> 6; - Putcode(p_len[i], (unsigned)p_code[i] << 8); + /* output upper 6 bits by table lookup */ + i = c >> 6; + Putcode(p_len[i], (unsigned)p_code[i] << 8); - /* output lower 6 bits verbatim */ - Putcode(6, (c & 0x3f) << 10); + /* output lower 6 bits verbatim */ + Putcode(6, (c & 0x3f) << 10); } static void EncodeEnd(void) { - if (putlen) { - if (crc_fputc(putbuf >> 8) == EOF) { - Error(wterr); - } - codesize++; - } + if (putlen) { + if (crc_fputc(putbuf >> 8) == EOF) { + Error(wterr); + } + codesize++; + } } int DecodeChar(void) { - unsigned int c; + unsigned int c; - c = son[R]; + c = son[R]; - /* travel from root to leaf, */ - /* choosing the smaller child node (son[]) if the read bit is 0, */ - /* the bigger (son[]+1} if 1 */ - while (c < T) { - c += GetBit(); - c = son[c]; - } - c -= T; - update(c); - return (int)c; + /* travel from root to leaf, */ + /* choosing the smaller child node (son[]) if the read bit is 0, */ + /* the bigger (son[]+1} if 1 */ + while (c < T) { + c += GetBit(); + c = son[c]; + } + c -= T; + update(c); + return (int)c; } int DecodePosition(void) { - unsigned int i, j, c; + unsigned int i, j, c; - /* recover upper 6 bits from table */ - i = GetByte(); - c = (unsigned)d_code[i] << 6; - j = d_len[i]; + /* recover upper 6 bits from table */ + i = GetByte(); + c = (unsigned)d_code[i] << 6; + j = d_len[i]; - /* read lower 6 bits verbatim */ - j -= 2; - while (j--) { - i = (i << 1) + GetBit(); - } - return (int)(c | (i & 0x3f)); + /* read lower 6 bits verbatim */ + j -= 2; + while (j--) { + i = (i << 1) + GetBit(); + } + return (int)(c | (i & 0x3f)); } /* compression */ diff --git a/pngwutil.c b/pngwutil.c index dd7b150..2f42e07 100644 --- a/pngwutil.c +++ b/pngwutil.c @@ -350,10 +350,11 @@ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) comp->output_ptr[i]=NULL; } if (comp->max_output_ptr != 0) - png_free(png_ptr, comp->output_ptr); - comp->output_ptr=NULL; + png_free(png_ptr, comp->output_ptr); + comp->output_ptr=NULL; /* write anything left in zbuf */ if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) + png_write_chunk_data(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - png_ptr->zstream.avail_out);