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..de4bf76 100644 --- a/BPQINP3.c +++ b/BPQINP3.c @@ -747,6 +747,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 diff --git a/Bpq32.c b/Bpq32.c index 41d4e64..7215b3b 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1406,6 +1406,7 @@ void initAIS(); void initADSB(); int CloseAllSessions(); int CloseAllLinks(); +void NETROMTCPResolve(); extern BOOL ADIFLogEnabled; @@ -1413,6 +1414,8 @@ int CloseOnError = 0; char UIClassName[]="UIMAINWINDOW"; // the main window class name +char ClosingClassName[]="CLOSING"; // the main window class name + HWND UIhWnd; extern char AUTOSAVE; @@ -2216,6 +2219,8 @@ VOID TimerProcX() Start(); + NETROMTCPResolve(); + INITIALISEPORTS(); // Restart Ports SetApplPorts(); @@ -2398,7 +2403,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 } @@ -2632,6 +2637,7 @@ Check_Timer() WSAStartup(MAKEWORD(2, 0), &WsaData); + // Load Psapi.dll if possible ExtDriver = LoadLibrary("Psapi.dll"); @@ -2646,6 +2652,8 @@ Check_Timer() Start(); + NETROMTCPResolve(); + INITIALISEPORTS(); OpenReportingSockets(); @@ -2969,6 +2977,8 @@ BOOL APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReser } else { + NETROMTCPResolve(); + SetApplPorts(); GetUIConfig(); @@ -5967,14 +5977,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..d532a1e 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; @@ -903,8 +905,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 @@ -2665,7 +2671,8 @@ NoPort: // SEE IF CALL TO ANY OF OUR HOST SESSIONS - UNLESS DIGIS SPECIFIED - if (axcalls[7] == 0 && axcalls[9] ) +// 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,24 +2723,29 @@ 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) + // 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 (cmdCopy[0] != ' ') { - if (i > 0) // Some digits + i = 0; + + while (cmdCopy[i] >= '0' && cmdCopy[i]<= '9') + i++; + + if (cmdCopy[i] != ' ') + goto Downlink; + else { - haveService = 1; - Service = atoi(cmdCopy); + if (i > 0) // Some digits + { + haveService = 1; + Service = atoi(cmdCopy); + } } } 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..d095bd9 100644 --- a/Events.c +++ b/Events.c @@ -57,6 +57,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 +68,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 +148,11 @@ 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->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"); @@ -217,9 +222,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,6 +237,8 @@ void hookL2SessionConnected(struct _LINKTABLE * LINK) char UDPMsg[1024]; int udplen; + L2CONNECTSOUT++; + if (NodeAPISocket) { LINK->lastStatusSentTime = time(NULL); @@ -251,6 +258,7 @@ void hookL2SessionClosed(struct _LINKTABLE * LINK, char * Reason, char * Directi char UDPMsg[1024]; int udplen; + time_t Now = time(NULL); if (NodeAPISocket) { @@ -259,16 +267,21 @@ 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\"}", + "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d, \"reason\": \"%s\"," + " \"time\": %d, \"upForSecs\": %d, \"frmsQdPeak\": %d}", NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->receivingCall, LINK->callingCall, - LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason); + LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason, + (int)Now, (int)Now - LINK->ConnectTime, LINK->maxQueued); 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\"}", + "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d, \"reason\": \"%s\"," + " \"time\": %d, \"upForSecs\": %d, \"frmsQdPeak\": %d}", NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall, - LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason); + LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason, + (int)Now, (int)Now - LINK->ConnectTime, LINK->maxQueued); -// Debugprintf(UDPMsg); + + Debugprintf(UDPMsg); sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest)); } @@ -280,23 +293,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}", + NODECALLLOPPED, UDPSeq++, 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); 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}", + NODECALLLOPPED, UDPSeq++, 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); -// Debugprintf(UDPMsg); + LINK->intervalMaxQueued = 0; + + Debugprintf(UDPMsg); sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest)); } @@ -412,8 +439,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 +466,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); @@ -633,7 +662,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; @@ -650,13 +714,22 @@ void APIL2Trace(struct _MESSAGE * Message, char Dirn) int NS; int NR; + if ((Message->ORIGIN[6] & 1) == 0) // Digis return; destcall[ConvFromAX25(Message->DEST, destcall)] = 0; srcecall[ConvFromAX25(Message->ORIGIN, srcecall)] = 0; - // See if any Digis + // 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; @@ -784,9 +857,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\", \"dirn\": \"%s\", \"reportFrom\": \"%s\", \"port\": \"%d\", \"srce\": \"%s\", \"dest\": \"%s\", \"ctrl\": %d," + "\"l2Type\": \"%s\", \"modulo\": 8, \"cr\": \"%s\"", + Dirn, NODECALLLOPPED, Message->PORT, srcecall, destcall, Message->CTL, Type, CR); if (UIFlag) { @@ -921,6 +994,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 +1035,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 +1057,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 +1161,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..5704e49 100644 --- a/L4Code.c +++ b/L4Code.c @@ -1601,7 +1601,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 +1675,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; } @@ -2028,7 +2031,7 @@ TryAgain: while (n--) { - if (DEST->DEST_COUNT == 0 && DEST->DEST_RTT == 0) // Not used and not INP3 + if (DEST->DEST_COUNT == 0 && DEST->DEST_RTT == 0 && (DEST->DEST_STATE & 0x80) == 0) // Not used and not INP3 and not Appl { if (DEST->NRROUTE[0].ROUT_QUALITY < WorstQual) { diff --git a/LinBPQ.c b/LinBPQ.c index 1c16ef4..ad749d0 100644 --- a/LinBPQ.c +++ b/LinBPQ.c @@ -85,6 +85,7 @@ VOID GetPGConfig(); void SendBBSDataToPktMap(); void CloseAllLinks(); void hookNodeClosing(char * Reason); +void NETROMTCPResolve(); extern uint64_t INP3timeLoadedMS; @@ -1015,6 +1016,8 @@ int main(int argc, char * argv[]) return (0); } + NETROMTCPResolve(); + for (i=0;PWTEXT[i] > 0x20;i++); //Scan for cr or null PWLen=i; @@ -1546,6 +1549,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..63c0494 100644 --- a/NETROMTCP.c +++ b/NETROMTCP.c @@ -1,551 +1,585 @@ -/* -Copyright 2001-2022 John Wiseman G8BPQ - -This file is part of LinBPQ/BPQ32. - -LinBPQ/BPQ32 is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -LinBPQ/BPQ32 is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses -*/ - -/* -Netrom over TCP Support - -This is intended for operation over radio links with an IP interface, eg New Packet Radio or possibly microwave links - -To simplify interface to the rest of the oode dummy LINK and PORT records are created - -Packet Format is Length (2 byte little endian) Call (10 bytes ASCII) NETROM L3/4 Packet, starting 0xcf (to detect framing errors). - -A TCP message can contain multiple packets and/or partial packets - -It uses the Telnet Server, with port defined in NETROMPORT - -ROUTE definitions have an extra field, the TCP Port Number - -*/ - -//#pragma data_seg("_BPQDATA") - - -#define _CRT_SECURE_NO_DEPRECATE - -#include "time.h" -#include "stdio.h" -#include -//#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); + +struct NRTCPMsg +{ + short Length; + char Call[10]; + unsigned char PID; + char Packet[1024]; +}; + +struct NRTCPSTRUCT +{ + struct ConnectionInfo * sockptr; + struct _LINKTABLE * LINK; // Dummy Link Record for this ROUTE + struct ROUTE * Route; // May need backlink + char Call[10]; +}; + +struct NRTCPSTRUCT * NRTCPInfo[256] = {0}; + +// Do we want to use normal TCP server connections, which are limited, or our own. Let's try our own for now + +struct ConnectionInfo * AllocateNRTCPRec() +{ + struct ConnectionInfo * sockptr = 0; + struct NRTCPSTRUCT * Info; + int i; + + for (i = 0; i < 255; i++) + { + if (NRTCPInfo[i] == 0) + { + // only allocate as many as needed + + Info = NRTCPInfo[i] = (struct NRTCPSTRUCT *)zalloc(sizeof(struct NRTCPSTRUCT)); + Info->sockptr = (struct ConnectionInfo *)zalloc(sizeof(struct ConnectionInfo)); + Info->LINK = (struct _LINKTABLE *)zalloc(sizeof(struct _LINKTABLE)); + Info->sockptr->Number = i; + } + else + Info = NRTCPInfo[i]; + + sockptr = Info->sockptr; + + if (sockptr->SocketActive == FALSE) + { + sockptr->SocketActive = TRUE; + sockptr->ConnectTime = sockptr->LastSendTime = time(NULL); + + Debugprintf("NRTCP Allocated %d", i); + return sockptr; + } + } + return 0; +} + +void checkNRTCPSockets(int portNo) +{ + SOCKET sock; + int Active = 0; + SOCKET maxsock; + int retval; + int i; + + struct timeval timeout; + fd_set readfd, writefd, exceptfd; + + struct ConnectionInfo * sockptr; + + timeout.tv_sec = 0; + timeout.tv_usec = 0; // poll + + maxsock = 0; + + FD_ZERO(&readfd); + FD_ZERO(&writefd); + FD_ZERO(&exceptfd); + + for (i = 0; i < 255; i++) + { + if (NRTCPInfo[i] == 0) + break; // only as many as have been used + + sockptr = NRTCPInfo[i]->sockptr; + + if (sockptr->SocketActive == 0) + continue; + + if (sockptr->Connecting) + { + // look for complete or failed + + FD_SET(sockptr->socket, &writefd); + FD_SET(sockptr->socket, &exceptfd); + } + else + { + FD_SET(sockptr->socket, &readfd); + FD_SET(sockptr->socket, &exceptfd); + } + + Active++; + + if (sockptr->socket > maxsock) + maxsock = sockptr->socket; + } + + if (Active) + { + retval = select((int)maxsock + 1, &readfd, &writefd, &exceptfd, &timeout); + + if (retval == -1) + { + perror("data select"); + Debugprintf("NRTCP Select Error %d Active %d", WSAGetLastError(), Active); + } + else + { + if (retval) + { + // see who has data + + for (i = 0; i < 255; i++) + { + if (NRTCPInfo[i] == 0) + break; + + sockptr = NRTCPInfo[i]->sockptr; + + if (sockptr->SocketActive == 0) + continue; + + sock = sockptr->socket; + + if (FD_ISSET(sock, &writefd)) + NETROMConnected(sockptr, sock, NRTCPInfo[i]); + + if (FD_ISSET(sock, &readfd)) + DataSocket_ReadNETROM(sockptr, sock, NRTCPInfo[i], portNo); + + if (FD_ISSET(sock, &exceptfd)) + NETROMConnectionLost(sockptr); + } + } + } + } +} + +int NETROMOpenConnection(struct ROUTE * Route) +{ + struct NRTCPSTRUCT * Info; + struct ConnectionInfo * sockptr; + + Debugprintf("Opening NRTCP Connection"); + + if (Route->TCPSession) + { + // SESSION ALREADY EXISTS + + sockptr = Route->TCPSession->sockptr; + + if (sockptr->Connected || sockptr->Connecting) + return TRUE; + + // previous connect failed + } + else + { + sockptr = AllocateNRTCPRec(); + + if (sockptr == NULL) + return 0; + + Info = Route->TCPSession = NRTCPInfo[sockptr->Number]; + memcpy(Info->Call, MYNETROMCALL, 10); + Route->NEIGHBOUR_LINK = Info->LINK; + + Info->Route = Route; + Info->LINK->NEIGHBOUR = Route; + Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT); + } + + return NETROMTCPConnect(Route, sockptr); + +} + +void NETROMTCPResolve() +{ + struct ROUTE * Route = NEIGHBOURS; + int n = MAXNEIGHBOURS; + struct addrinfo hints, *res = 0; + char PortString[20]; + int err; + + while (n--) + { + if (Route->TCPAddress) + { + // try to resolve host + + sprintf(PortString, "%d", Route->TCPPort); + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + getaddrinfo(Route->TCPHost, PortString, &hints, &res); + + err = WSAGetLastError(); + + if (res) + { + Route->TCPAddress->ai_family = res->ai_family; + Route->TCPAddress->ai_socktype = res->ai_socktype; + Route->TCPAddress->ai_protocol = res->ai_protocol; + Route->TCPAddress->ai_addrlen = res->ai_addrlen; + memcpy(Route->TCPAddress->ai_addr, res->ai_addr, sizeof(struct sockaddr)); + freeaddrinfo(res); + } + } + + Route++; + } +} + +int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr) +{ + int err; + u_long param=1; + BOOL bcopt=TRUE; + SOCKET sock; + struct sockaddr_in sinx; + int addrlen=sizeof(sinx); + char PortString[20]; + struct addrinfo * res = Route->TCPAddress; + int Port = Route->TCPPort; + + sprintf(PortString, "%d", Port); + + // get host info, make socket, and connect it + + if (res->ai_family == 0) + { +// err = WSAGetLastError(); +// Debugprintf("Resolve HostName %s Failed - Error %d", Route->TCPHost, err); + return FALSE; // Resolve failed + } + + sock = sockptr->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + if (sock == INVALID_SOCKET) + { + Debugprintf, ("Netrom over TCP Create Socket Failed"); + return FALSE; + } + + ioctl(sock, FIONBIO, ¶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) + { + // something wrong - maybe connection reused + } + + // Format as if come from an ax.25 link + + L3Msg = GetBuff(); + + if (L3Msg == 0) + goto seeifMore; + + L3Msg->LENGTH = (Msg->Length - 12) + MSGHDDRLEN; + L3Msg->Next = 0; + L3Msg->Port = portNo; + L3Msg->L3PID = NETROM_PID; + memcpy(&L3Msg->L3SRCE, Msg->Packet, Msg->Length - 13); + + // Create a dummy L2 message so we can trace it + + Buffer = GetBuff(); + + if (Buffer) + { + Buffer->CHAIN = 0; + Buffer->CTL = 0; + Buffer->PORT = portNo; + + ConvToAX25(Info->Call, Buffer->ORIGIN); + ConvToAX25(MYNETROMCALL, Buffer->DEST); + + memcpy(Buffer->L2DATA, &L3Msg->L3SRCE[0], Msg->Length - 13); + Buffer->ORIGIN[6] |= 1; // Set end of calls + Buffer->PID = NETROM_PID; + Buffer->LENGTH = Msg->Length + 10; + time(&Buffer->Timestamp); + + BPQTRACE(Buffer, FALSE); + ReleaseBuffer(Buffer); + } + + NETROMMSG(Info->LINK, L3Msg); + +seeifMore: + + sockptr->InputLen -= Msg->Length; + + if (sockptr->InputLen > 0) + { + memmove(sockptr->InputBuffer, &sockptr->InputBuffer[Msg->Length], sockptr->InputLen); + goto checkLen; + } + + return 0; +} + +VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame) +{ + struct NRTCPMsg Msg; + unsigned char * Data = (unsigned char *)&Frame->L3SRCE[0]; + int DataLen = Frame->LENGTH - (MSGHDDRLEN + 1); // Not including PID + int Ret; + PMESSAGE Buffer; + + Msg.Length = DataLen + 13; // include PID + memcpy(Msg.Call, MYNETROMCALL, 10); + Msg.PID = NETROM_PID; + memcpy(Msg.Packet, Data, DataLen); + + if (Route->TCPSession == 0) + return; + + Ret = send(Route->TCPSession->sockptr->socket, (char *)&Msg, DataLen + 13, 0); + + // Create a dummy L2 message so we can trace it + + Buffer = GetBuff(); + + if (Buffer) + { + Buffer->CHAIN = 0; + Buffer->CTL = 0; + Buffer->PORT = Route->NEIGHBOUR_PORT | 128; // TX Flag + + ConvToAX25(Route->TCPSession->Call, Buffer->DEST); + ConvToAX25(MYNETROMCALL, Buffer->ORIGIN); + + memcpy(Buffer->L2DATA, &Frame->L3SRCE[0], DataLen); + Buffer->ORIGIN[6] |= 1; // Set end of calls + Buffer->PID = NETROM_PID; + Buffer->LENGTH = DataLen + 15 + MSGHDDRLEN; + time(&Buffer->Timestamp); + + BPQTRACE(Buffer, FALSE); + ReleaseBuffer(Buffer); + } + +} + + +void NETROMConnectionLost(struct ConnectionInfo * sockptr) +{ + struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number]; + struct ROUTE * Route; + + closesocket(sockptr->socket); + + // If there is an attached route (there should be) clear all connections + + if (Info) + { + Route = Info->Route; + + if (sockptr->Connected) + L3LINKCLOSED(Info->LINK, LINKLOST); + + if (sockptr->Connecting) + L3LINKCLOSED(Info->LINK, SETUPFAILED); + + if (Route) + Route->TCPSession = 0; + + Info->Call[0] = 0; + } + + sockptr->SocketActive = FALSE; + + memset(sockptr, 0, sizeof(struct ConnectionInfo)); +} + 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..f5d5fb8 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,9 +#define KVerstring "6.0.25.9\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..89e5277 100644 --- a/asmstrucs.h +++ b/asmstrucs.h @@ -250,7 +250,8 @@ typedef struct ROUTE char * TCPHost; // For NETROM over TCP int TCPPort; - struct NRTCPSTRUCT * TCPSession; + struct NRTCPSTRUCT * TCPSession; + struct addrinfo * TCPAddress; // Resolved Address } *PROUTE; @@ -977,6 +978,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 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..1eda80c 100644 --- a/cMain.c +++ b/cMain.c @@ -57,7 +57,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" @@ -1416,12 +1416,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 +2031,7 @@ VOID ReadNodes() ptr = strtok_s(NULL, seps, &Context); // INP3 if (ptr == NULL) continue; - if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0); // Not LOCKED ROUTE + if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0) // Not LOCKED ROUTE ROUTE->OtherendsRouteQual = atoi(ptr); ptr = strtok_s(NULL, seps, &Context); // INP3 @@ -2279,7 +2282,7 @@ VOID TIMERINTERRUPT() Message = (struct _MESSAGE *)Buffer; if(NodeAPISocket) - APIL2Trace(Message, 'T'); + APIL2Trace(Message, "sent"); Message->PORT |= 0x80; // Set TX Bit @@ -2394,7 +2397,7 @@ L2Packet: MQTTKISSRX(Buffer); if(NodeAPISocket &&PORT->PROTOCOL == 0) - APIL2Trace(Message, 'R'); + APIL2Trace(Message, "rcvd"); // Bridge if requested diff --git a/config.c b/config.c index bb0b2f2..33213df 100644 --- a/config.c +++ b/config.c @@ -635,6 +635,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++) { 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);