diff --git a/AGWAPI.c b/AGWAPI.c
index dcf3494..126a72a 100644
--- a/AGWAPI.c
+++ b/AGWAPI.c
@@ -36,7 +36,8 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
struct AGWHeader
{
- unsigned int Port;
+ uint8_t Port;
+ uint8_t filler1[3];
unsigned char DataKind;
unsigned char filler2;
unsigned char PID;
@@ -128,7 +129,7 @@ int DataSocket_Write(struct AGWSocketConnectionInfo * sockptr, SOCKET sock);
int AGWGetSessionKey(char * key, struct AGWSocketConnectionInfo * sockptr);
int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr);
int SendDataToAppl(int Stream, byte * Buffer, int Length);
-int InternalAGWDecodeFrame(char * msg, char * buffer, time_t Stamp, int * FrameType, int useLocalTime, int doNodes);
+int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * FrameType, int useLocalTime, int doNodes);
int AGWDataSocket_Disconnect( struct AGWSocketConnectionInfo * sockptr);
int SendRawPacket(struct AGWSocketConnectionInfo * sockptr, char *txmsg, int Length);
int ShowApps();
@@ -720,7 +721,7 @@ int AGWDoMonitorData()
RawLen = monbuff->LENGTH;
- if (RawLen < 7 || RawLen > 350)
+ if (RawLen < MSGHDDRLEN || RawLen > 350)
{
ReleaseBuffer(monbuff);
FreeSemaphore(&Semaphore);
@@ -734,12 +735,16 @@ int AGWDoMonitorData()
ReleaseBuffer(monbuff);
FreeSemaphore(&Semaphore);
+
+ // Set monbuff to point to the copy
+
+ monbuff = (MESSAGE *)Buffer;
//' 4 byte chain
//' 1 byte port - top bit = transmit
//' 2 byte length (LO-HI)
- Port = Buffer[4];
+ Port = monbuff->PORT;
if (Port > 127)
{
@@ -751,6 +756,12 @@ int AGWDoMonitorData()
RXFlag = TRUE;
}
+ if (Port == 0)
+ {
+ Debugprintf("AGWMON Port number is zero");
+ return 0;
+ }
+
// Can now have different mon flags per connection, so need to run decode for each socket
for (n = 1; n<= CurrentSockets; n++)
@@ -759,7 +770,7 @@ int AGWDoMonitorData()
if (sockptr->SocketActive && sockptr->MonFlag && (RXFlag || LoopMonFlag))
{
- Length = InternalAGWDecodeFrame(Buffer, AGWBuffer, Stamp, &Frametype, sockptr->useLocalTime, sockptr->doNodes);
+ Length = InternalAGWDecodeFrame(monbuff, AGWBuffer, Stamp, &Frametype, sockptr->useLocalTime, sockptr->doNodes);
if (Length > 0)
{
@@ -803,7 +814,7 @@ int AGWDoMonitorData()
}
}
- RawLen = RawLen - 6;
+ RawLen = RawLen - (MSGHDDRLEN - 1); // One more for KISS control
if (RXFlag || Loopflag) // Send transmitted frames if requested
{
@@ -811,8 +822,12 @@ int AGWDoMonitorData()
//
// Send raw data to any sockets that have requested Raw frames
//
-
- Buffer[6]=0;
+
+ // Format is ax.25 packet prceeded by a KISS command byte 00 for channel 1 0x10 for channel 2 etc
+ // As this is an application API I think all should go as Port 1
+
+
+ Buffer[MSGHDDRLEN - 1] = 0; // Just in case big-endian
AGWTXHeader.Port = Port - 1; // AGW Ports start from 0
AGWTXHeader.DataKind = 'K';
@@ -824,14 +839,12 @@ int AGWDoMonitorData()
sockptr=&Sockets[n];
if (sockptr->SocketActive && sockptr->RawFlag)
- SendRawPacket(sockptr, &Buffer[6], RawLen);
+ SendRawPacket(sockptr, &Buffer[MSGHDDRLEN - 1], RawLen);
}
}
}
-
- return 0;
-
+ return 0;
}
int DeleteConnection(struct BPQConnectionInfo * Con)
@@ -1128,6 +1141,7 @@ int AGWDataSocket_Read(struct AGWSocketConnectionInfo * sockptr, SOCKET sock)
int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr)
{
int AGWVersion[2]={2003,999};
+ byte AGWPortCaps[12] = { 0, 255, 30, 10, 63, 10, 4, 0, 1, 0, 0, 0 };
char AGWRegReply[1];
struct BPQConnectionInfo * Connection;
int Stream;
@@ -1195,7 +1209,7 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr)
// Need to convert port index (used by AGW) to port number
- conport=GetPortNumber(VisiblePortToRealPort[key[0]-48]);
+ conport=GetPortNumber(VisiblePortToRealPort[key[0]-49] + 1);
n = sprintf(ConnectMsg,"C %d %s",conport,ToCall);
@@ -1293,9 +1307,7 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr)
// Version
memset(&AGWTXHeader,0,36);
-
AGWTXHeader.DataKind = 'R';
-
AGWTXHeader.DataLength = 8; // Length
SendtoSocket(sockptr->socket, (char *)&AGWVersion[0]);
@@ -1309,15 +1321,27 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr)
memset(&AGWTXHeader,0,36);
-
AGWTXHeader.DataKind = 'G';
-
AGWTXHeader.DataLength =(int)strlen(AGWPorts)+1; // Length
SendtoSocket(sockptr->socket, AGWPorts);
return 0;
+
+ case 'g':
+
+ // Port capabilities. Currently hard-coded.
+
+ AGWTXHeader.Port = sockptr->AGWRXHeader.Port;
+ AGWTXHeader.DataKind = 'g';
+ AGWTXHeader.DataLength = 12;
+
+ SendtoSocket(sockptr->socket, (char *)&AGWPortCaps[0]);
+
+ return 0;
+
+
case 'k':
@@ -1416,6 +1440,8 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr)
AGWTXHeader.DataKind = 'X';
+ memcpy(&AGWTXHeader.callfrom, RegCall, 10);
+
AGWTXHeader.DataLength = 1; // Length
AGWRegReply[0] = 1;
diff --git a/AGWMoncode.c b/AGWMoncode.c
index 7427804..2c26191 100644
--- a/AGWMoncode.c
+++ b/AGWMoncode.c
@@ -49,9 +49,14 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#define DM 0x0F
#define UA 0x63
#define FRMR 0x87
+#define XID 0xAF
+#define TEST 0xE3
#define RR 1
#define RNR 5
#define REJ 9
+#define SREJ 0x0D
+#define SABME 0x6F
+
#define PFBIT 0x10 // POLL/FINAL BIT IN CONTROL BYTE
@@ -261,6 +266,18 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra
strcpy(SUP, "FRMR");
FRMRFLAG = 1;
break;
+
+ case XID:
+
+ strcpy(SUP, "XID");
+ XIDFLAG = 1;
+ break;
+
+ case TEST:
+
+ strcpy(SUP, "TEST");
+ TESTFLAG = 1;
+ break;
}
Output += sprintf((char *)Output, "<%s%s%s>", SUP, CRCHAR, PFCHAR);
@@ -270,7 +287,7 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra
// Super
int NR = (CTL >> 5) & 7;
- char SUP[4] = "??";
+ char SUP[5] = "??";
switch (CTL & 0x0F)
{
@@ -288,6 +305,13 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra
strcpy(SUP, "REJ");
break;
+
+
+ case SREJ:
+
+ strcpy(SUP, "SREJ");
+ break;
+
}
Output += sprintf((char *)Output, "<%s%s%s R%d>", SUP, CRCHAR, PFCHAR, NR);
@@ -300,6 +324,72 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra
if (FRMRFLAG)
Output += sprintf((char *)Output, "%02X %02X %02X", ADJBUFFER->PID, ADJBUFFER->L2DATA[0], ADJBUFFER->L2DATA[1]);
+ if (XIDFLAG)
+ {
+ // Decode and display XID
+
+ UCHAR * ptr = &ADJBUFFER->PID;
+
+ if (*ptr++ == 0x82 && *ptr++ == 0x80)
+ {
+ int Type;
+ int Len;
+ unsigned int value;
+ int xidlen = *(ptr++) << 8;
+ xidlen += *ptr++;
+
+ // XID is set of Type, Len, Value n-tuples
+
+// G8BPQ-2>G8BPQ:(XID cmd, p=1) Half-Duplex SREJ modulo-128 I-Field-Length-Rx=256 Window-Size-Rx=32 Ack-Timer=3000 Retries=10
+
+
+ while (xidlen > 0)
+ {
+ Type = *ptr++;
+ Len = *ptr++;
+
+ value = 0;
+ xidlen -= (Len + 2);
+
+ while (Len--)
+ {
+ value <<=8;
+ value += *ptr++;
+ }
+ switch(Type)
+ {
+ case 2: //Bin fields
+ case 3:
+
+ Output += sprintf((char *)Output, " %d=%x", Type, value);
+ break;
+
+ case 6: //RX Size
+
+ Output += sprintf((char *)Output, " RX Paclen=%d", value / 8);
+ break;
+
+ case 8: //RX Window
+
+ Output += sprintf((char *)Output, " RX Window=%d", value);
+ break;
+
+ case 16:
+
+ Output += sprintf((char *)Output, " Can Compress");
+ break;
+
+ case 17:
+
+ Output += sprintf((char *)Output, " Compress ok");
+ break;
+ }
+ }
+ }
+ }
+
+
+
if (Info)
{
// We have an info frame
diff --git a/ARDOP.c b/ARDOP.c
index 8230039..ade0ecf 100644
--- a/ARDOP.c
+++ b/ARDOP.c
@@ -2061,21 +2061,12 @@ VOID * ARDOPExtInit(EXTPORTDATA * PortEntry)
strcat(TempScript, "ARQTIMEOUT 90\r");
// strcat(TempScript, "ROBUST False\r");
- strcat(TempScript, TNC->InitScript);
-
- free(TNC->InitScript);
- TNC->InitScript = TempScript;
-
- // Set MYCALL
-
-// strcat(TNC->InitScript,"FECRCV True\r");
-// strcat(TNC->InitScript,"AUTOBREAK True\r");
+ // Make MYAUX and MYCALL overridable
+
sprintf(Msg, "MYCALL %s\r", TNC->NodeCall);
- strcat(TNC->InitScript, Msg);
-// strcat(TNC->InitScript,"PROCESSID\r");
-// strcat(TNC->InitScript,"CODEC TRUE\r");
-// strcat(TNC->InitScript,"LISTEN TRUE\r");
+ strcat(TempScript, Msg);
+
for (i = 0; i < 32; i++)
{
@@ -2099,9 +2090,25 @@ VOID * ARDOPExtInit(EXTPORTDATA * PortEntry)
if (strlen(Aux) > 8)
{
Aux[strlen(Aux) - 1] = '\r';
- strcat(TNC->InitScript, Aux);
+ strcat(TempScript, Aux);
}
+
+ strcat(TempScript, TNC->InitScript);
+
+ free(TNC->InitScript);
+ TNC->InitScript = TempScript;
+
+
+
+// strcat(TNC->InitScript,"FECRCV True\r");
+// strcat(TNC->InitScript,"AUTOBREAK True\r");
+// strcat(TNC->InitScript,"PROCESSID\r");
+// strcat(TNC->InitScript,"CODEC TRUE\r");
+// strcat(TNC->InitScript,"LISTEN TRUE\r");
+
+
+
strcpy(TNC->CurrentMYC, TNC->NodeCall);
if (TNC->WL2K == NULL)
diff --git a/BBSUtilities.c b/BBSUtilities.c
index d7291d0..90b4c7b 100644
--- a/BBSUtilities.c
+++ b/BBSUtilities.c
@@ -69,6 +69,10 @@ extern BPQVECSTRUC ** BPQHOSTVECPTR;
UCHAR * GetLogDirectory();
DllExport int APIENTRY SessionStateNoAck(int stream, int * state);
int RefreshWebMailIndex();
+struct PORTCONTROL * GetPortTableEntryFromSlot(int portslot);
+int GetPortHardwareType(struct PORTCONTROL *PORT);
+int GetNumberofPorts();
+
#else
__declspec(dllimport) BPQVECSTRUC ** BPQHOSTVECPTR;
typedef char * (WINAPI FAR *FARPROCZ)();
@@ -5252,7 +5256,6 @@ char * CheckToAddress(CIRCUIT * conn, char * Addr)
return NewAddr;
}
}
- else
{
WPRecP WP = LookupWP(Addr);
@@ -5473,7 +5476,18 @@ BOOL DecodeSendParams(CIRCUIT * conn, char * Context, char ** From, char *To, ch
}
else
{
- conn->LocalMsg = TRUE;
+ // See if a WP entry
+
+ WP = LookupWP(To);
+
+ if (WP)
+ {
+ *ATBBS = WP->first_homebbs;
+ nodeprintf(conn, "Address @%s added from WP\r", *ATBBS);
+ conn->LocalMsg = FALSE;
+ }
+ else
+ conn->LocalMsg = TRUE;
}
}
else
@@ -9052,6 +9066,10 @@ CheckForSID:
return TRUE;
}
+#ifndef LINBPQ
+extern FARPROCX pGetPortHardwareType;
+#endif
+
VOID Parse_SID(CIRCUIT * conn, char * SID, int len)
{
ChangeSessionIdletime(conn->BPQStream, BBSIDLETIME); // Default Idletime for BBS Sessions
@@ -9108,10 +9126,44 @@ VOID Parse_SID(CIRCUIT * conn, char * SID, int len)
{
// We should really only do this on Telnet Connections, as OpenBCM flag is used to remove relnet transparency
+ // See if Telnet
+
+ struct PORTCONTROL * PORT;
+ char Call[11] = "";
+ int port, dummy;
+
+ GetConnectionInfo(conn->BPQStream, Call, &port, &dummy, &dummy, &dummy, &dummy);
+
+ PORT = GetPortTableEntryFromSlot(0); // Get first entry
+
+ do
+ {
+ if (PORT->PORTNUMBER == port)
+ break;
+
+ PORT=PORT->PORTPOINTER;
+
+ } while (PORT);
+
+#define H_TELNET 6
+
+#ifndef LINBPQ
+
+ if (pGetPortHardwareType)
+ {
+ if (PORT && GetPortHardwareType(PORT) == H_TELNET)
+ conn->OpenBCM = TRUE;
+ }
+ else
+ conn->OpenBCM = TRUE; // Old Node version so follow old behavoiur and treat all as telnet
+#else
+ if (PORT && GetPortHardwareType(PORT) == H_TELNET)
+ conn->OpenBCM = TRUE;
+#endif
- conn->OpenBCM = TRUE;
}
+
if (_memicmp(SID, "PMS-3.2", 7) == 0)
{
// Paccom TNC that doesn't send newline prompt ater receiving subject
diff --git a/BPQINP3.c b/BPQINP3.c
index 2b1e3ae..aa4929c 100644
--- a/BPQINP3.c
+++ b/BPQINP3.c
@@ -1341,6 +1341,9 @@ VOID SendRIPToNeighbour(struct ROUTE * Route)
if (Msg == NULL)
Msg = Route->Msg = CreateRIFHeader(Route);
+ if (Msg == NULL)
+ return;
+
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH],
Dest->DEST_CALL, Dest->DEST_ALIAS,
Entry->Hops + 1, Entry->SRTT + Entry->ROUT_NEIGHBOUR->SRTT/10);
diff --git a/BPQMail.c b/BPQMail.c
index 0ac9f1c..2aab885 100644
--- a/BPQMail.c
+++ b/BPQMail.c
@@ -1153,6 +1153,7 @@
// Save FBB transfer restart data over program restarts (69)
// Add Send and Receive byte counts to status displays (69)
// Validate Mode and Frequency and fix formatting in Connected Message (71)
+// Fix using OpenBCM on other than Telnet connections (75)
#include "bpqmail.h"
#include "winstdint.h"
@@ -1173,6 +1174,7 @@ FARPROCX pRunEventProgram;
FARPROCX pGetPortFrequency;
FARPROCX pSendWebRequest;
FARPROCX pGetLatLon;
+FARPROCX pGetPortHardwareType;
BOOL WINE = FALSE;
@@ -1956,6 +1958,8 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
pGetPortFrequency = GetProcAddress(ExtDriver,"_GetPortFrequency@8");
pSendWebRequest = GetProcAddress(ExtDriver,"_SendWebRequest@16");
pGetLatLon = GetProcAddress(ExtDriver,"_GetLatLon@8");
+ pGetPortHardwareType = GetProcAddress(ExtDriver,"_GetPortHardwareType@4");
+
if (pGetLOC)
diff --git a/Bpq32.c b/Bpq32.c
index fc36356..b282d88 100644
--- a/Bpq32.c
+++ b/Bpq32.c
@@ -1267,6 +1267,15 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Add MHUV and MHLV commands (Verbose listing with timestamps in clock time) (70)
// Improvements to INP3 (71)
// Improvements to KAM driver including support for GTOR connects (71)
+// Support IPv6 for Telnet outward connects (72)
+// Fix decaying NETROM routes (72)
+// Add OnlyVer2point0 config command (72)
+// Add option to allow AX/UDP on a network using NAT (72)
+// Include AGWAPI fixes from Martin KD6YAM to enable use with Paracon terminal (72)
+// Fix 64 bit compatiblility issues with AGWAPI (73)
+// Fix KAM Pactor Interlock (73)
+// Fix Node map reporting, broken in .73 (74)
+
#define CKernel
diff --git a/ChatHTMLConfig.c b/ChatHTMLConfig.c
index c4071cf..604db8f 100644
--- a/ChatHTMLConfig.c
+++ b/ChatHTMLConfig.c
@@ -590,7 +590,7 @@ VOID SendChatStatusPage(char * Reply, int * ReplyLen, char * Key)
{
if (conn->Flags & CHATLINK)
{
- if (conn->BPQStream > 64 || conn->u.link == 0)
+ if (conn->BPQStream > 64 || conn->u.link == 0 || conn->u.link->alias == 0)
Len += sprintf(&Streams[Len], "
** Corrupt ChatLink ** | "
" | | | |
", i, i);
else
@@ -600,7 +600,7 @@ VOID SendChatStatusPage(char * Reply, int * ReplyLen, char * Key)
"", conn->OutputQueueLength - conn->OutputGetPointer);
}
else
- if ((conn->Flags & CHATMODE) && conn->topic)
+ if ((conn->Flags & CHATMODE) && conn->topic && conn->u.user && conn->u.user->call)
{
Len += sprintf(&Streams[Len], "%s | %s | %d | %s | %d |
",
i, i, conn->u.user->name, conn->u.user->call, conn->BPQStream,
diff --git a/CommonCode.c b/CommonCode.c
index ecac115..9c0032d 100644
--- a/CommonCode.c
+++ b/CommonCode.c
@@ -2142,7 +2142,16 @@ int CanPortDigi(int Port)
return TRUE;
}
-struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum)
+DllExport int APIENTRY GetPortHardwareType(struct PORTCONTROL *PORT)
+{
+ if (PORT)
+ return PORT->Hardware;
+
+ return 0;
+}
+
+
+DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum)
{
struct PORTCONTROL * PORTVEC = PORTTABLE;
diff --git a/KAMPactor.c b/KAMPactor.c
index ec461d3..239b183 100644
--- a/KAMPactor.c
+++ b/KAMPactor.c
@@ -915,24 +915,39 @@ VOID KAMPoll(int Port)
calllen = ConvFromAX25(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4USER, TNC->Streams[0].MyCall);
TNC->Streams[0].MyCall[calllen] = 0;
- EncodeAndSend(TNC, "X", 1); // ??Return to packet mode??
- if (TNC->VeryOldMode)
- datalen = sprintf(TXMsg, "C20MYCALL %s", TNC->Streams[0].MyCall);
- else
- datalen = sprintf(TXMsg, "C20MYPTCALL %s", TNC->Streams[0].MyCall);
+ EncodeAndSend(TNC, "X", 1); // ??Return to packet mode??
+
+ if (TNC->VeryOldMode)
+ {
+ datalen = sprintf(TXMsg, "C20MYCALL %s", TNC->Streams[0].MyCall);
EncodeAndSend(TNC, TXMsg, datalen);
- TNC->InternalCmd = 'M';
+ }
+ else
+ {
+ datalen = sprintf(TXMsg, "C20MYPTCALL %s", TNC->Streams[0].MyCall);
+ EncodeAndSend(TNC, TXMsg, datalen);
+
+ if (TNC->OldMode == 0)
+ {
+ EncodeAndSend(TNC, TXMsg, datalen);
+ datalen = sprintf(TXMsg, "C20MYGTCALL %s", TNC->Streams[0].MyCall);
+ }
+ }
+
+ TNC->InternalCmd = 'M';
- TNC->NeedPACTOR = 0; // Cancel enter Pactor
+ TNC->NeedPACTOR = 0; // Cancel enter Pactor
- sprintf(TNC->WEB_TNCSTATE, "In Use by %s", TNC->Streams[0].MyCall);
- SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
+ SuspendOtherPorts(TNC);
- // Stop Scanning
+ sprintf(TNC->WEB_TNCSTATE, "In Use by %s", TNC->Streams[0].MyCall);
+ SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
- sprintf(Msg, "%d SCANSTOP", TNC->Port);
+ // Stop Scanning
+
+ sprintf(Msg, "%d SCANSTOP", TNC->Port);
- Rig_Command( (TRANSPORTENTRY *) -1, Msg);
+ Rig_Command( (TRANSPORTENTRY *) -1, Msg);
}
}
@@ -1065,9 +1080,22 @@ VOID KAMPoll(int Port)
UCHAR TXMsg[80] = "D20";
if (TNC->VeryOldMode)
+ {
datalen = sprintf(TXMsg, "C20MYCALL %s", TNC->NodeCall);
+ EncodeAndSend(TNC, TXMsg, datalen);
+ }
else
+ {
datalen = sprintf(TXMsg, "C20MYPTCALL %s", TNC->NodeCall);
+ EncodeAndSend(TNC, TXMsg, datalen);
+
+ if (TNC->OldMode == 0)
+ {
+ datalen = sprintf(TXMsg, "C20MYGTCALL %s", TNC->NodeCall);
+ EncodeAndSend(TNC, TXMsg, datalen);
+ }
+ }
+
EncodeAndSend(TNC, TXMsg, datalen);
if (TNC->OldMode)
@@ -1075,6 +1103,7 @@ VOID KAMPoll(int Port)
else
EncodeAndSend(TNC, "C20TOR", 6); // Back to Listen
+
TNC->InternalCmd = 'T';
TNC->Timeout = 50;
TNC->IntCmdDelay--;
@@ -1758,6 +1787,76 @@ VOID ProcessKHOSTPacket(struct TNCINFO * TNC, UCHAR * Msg, int Len)
if (Msg[0] == '?') // Status
{
TNC->Timeout = 0;
+
+/*
+ The response frame from the TNC will be:
+ ?0MSXY - where MSXY are coded as follows:
+ M One byte indicating the current mode of operation.
+ A=Packet
+ B=RTTY
+ C=ASCII
+ D=AMTOR
+ E=FEC
+ F=SELFEC
+ G=LAMTOR
+ H=PACTOR
+ I=PTLISTEN
+ J=GTOR
+ K=NAVTEX
+ L=CW
+ M=TOR Standby
+ N=GMON
+ O=PSK31
+ S One byte indicating a sub-mode of operation. The byte
+ contains an ASCII character as follows:
+ 0=Standby
+ 1=Phasing
+ 2=Connected
+ 3=Disconnecting
+ 4=FEC
+ 5=SELFEC
+ 6=PTFEC
+ X One byte (called status byte X). This byte is bit-
+ encoded to indicate specific conditions as follows:
+ Bit 0 = (IDLE) set to 1 when receiving IDLE
+ characters in a frame.
+ Bit 1 = (ERR) set to 1 to indicate the received frame
+ failed CRC check, or was not a valid CS
+ response frame.
+ Bit 2 = (Combined receive) set to 1 to indicate that
+ the data was constructed through the use of
+ error correction (i.e. Golay error correction
+ for G-TOR or Memory ARQ for Pactor).
+ Bit 3 = (RQ) set to 1 to indicate an RQ frame. If you
+ are the ISS, it indicates that the receiving
+ station has asked for a repeat of the last
+ data due to received errors. When you are the
+ IRS, it indicates that the transmitting
+ station has sent the same data that you have
+ already received. This means that the sending
+ station did not properly copy your
+ acknowledgement (CS code).
+ Bit 4 = (Huffman) set to 1 to indicate that this
+ frame contains data which uses Huffman
+ compression.
+ Bit 5 = (ISS) set to 1 to indicate that your station
+ is currently the ISS.
+ Bit 6&7 = (Speed) these two bits indicate the current
+ speed of an ARQ link or the PSK31 mode. The
+ coding of the bits is:
+ 00 = 100 baud or BPSK31
+ 01 = 200 baud or QPSK31
+ 10 = 300 baud
+ Y One byte (called status byte Y). This byte is bit-
+ encoded to indicate specific conditions as follows:
+ Bit 0 = reserved (set to 0).
+ Bit 1 = (PTT) PTT is active.
+ Bit 2 = (Changeover) changeover in progress
+ Bits 3-7 = reserved (set to 0).
+*/
+
+
+
return;
}
diff --git a/L2Code.c b/L2Code.c
index 5b13919..76924bf 100644
--- a/L2Code.c
+++ b/L2Code.c
@@ -154,6 +154,8 @@ extern BOOL LogAllConnects;
APPLCALLS * APPL;
+int SUPPORT2point2 = 1;
+
void SendL2ToMonMap(struct PORTCONTROL * PORT, char * ReportCall, char Mode, char Direction)
{
@@ -3242,7 +3244,7 @@ VOID L2TimerProc()
if (PORT == NULL)
{
LINK++;
- continue; // just ion case!!
+ continue; // just in case!!
}
if (LINK->L2TIMER)
@@ -4003,7 +4005,7 @@ VOID CONNECTREFUSED(struct _LINKTABLE * LINK)
ConnectFailedOrRefused(LINK, "Busy from");
}
-VOID L3CONNECTFAILED(struct _LINKTABLE * LINK);
+
VOID L3LINKSETUPFAILED(struct _LINKTABLE * LINK);
diff --git a/L3Code.c b/L3Code.c
index b516634..48f71bc 100644
--- a/L3Code.c
+++ b/L3Code.c
@@ -1332,34 +1332,6 @@ VOID L3LINKSETUPFAILED(struct _LINKTABLE * LINK)
Debugprintf("INP3 Route to %s connect failed", Normcall);
}
-
- ROUTE->NEIGHBOUR_LINK = 0; // CLEAR IT
-
- L3TRYNEXTDEST(ROUTE); // RESET ASSOCIATED DEST ENTRIES
-}
-
-
-VOID L3CONNECTFAILED(struct _LINKTABLE * LINK)
-{
- // L2 LINK SETUP HAS FAILED - SEE IF ANOTHER NEIGHBOUR CAN BE USED
-
- struct PORTCONTROL * PORT = PORTTABLE;
- struct ROUTE * ROUTE;
-
-
- ROUTE = LINK->NEIGHBOUR; // TO NEIGHBOUR
-
- if (ROUTE == NULL)
- return; // NOTHING ???
-
- if (ROUTE->INP3Node)
- {
- char Normcall[10];
- Normcall[ConvFromAX25(ROUTE->NEIGHBOUR_CALL, Normcall)] = 0;
- Debugprintf("INP3 Route to %s connect failed or refused", Normcall);
- }
-
-
TellINP3LinkSetupFailed(ROUTE);
ROUTE->NEIGHBOUR_LINK = 0; // CLEAR IT
@@ -1368,6 +1340,7 @@ VOID L3CONNECTFAILED(struct _LINKTABLE * LINK)
}
+
VOID L3TRYNEXTDEST(struct ROUTE * ROUTE)
{
// FIND ANY DESINATIONS WITH ROUTE AS ACTIVE NEIGHBOUR, AND
diff --git a/MHSave.txt b/MHSave.txt
deleted file mode 100644
index e69de29..0000000
diff --git a/TelnetV6.c b/TelnetV6.c
index 62b0885..a0a0272 100644
--- a/TelnetV6.c
+++ b/TelnetV6.c
@@ -1498,6 +1498,8 @@ void * TelnetExtInit(EXTPORTDATA * PortEntry)
PortEntry->PORTCONTROL.TNC = TNC;
+ PortEntry->PORTCONTROL.Hardware = TNC->Hardware;
+
TNC->WebWindowProc = WebProc;
TNC->WebWinX = 260;
TNC->WebWinY = 325;
@@ -6342,26 +6344,80 @@ int TCPConnect(struct TNCINFO * TNC, struct TCPINFO * TCP, struct STREAMINFO * S
struct ConnectionInfo * sockptr;
SOCKET sock;
struct sockaddr_in sinx;
- struct sockaddr_in destaddr;
int addrlen=sizeof(sinx);
- int i;
+ char PortString[20];
+ struct addrinfo hints, *res = 0, *saveres;
+
+
+ sprintf(PortString, "%d", Port);
+
+ // get host info, make socket, and connect it
+
+ memset(&hints, 0, sizeof hints);
+
+ if (TCP->IPV6 == 0 && TCP->IPV4)
+ hints.ai_family = AF_INET;
+ else if (TCP->IPV4 == 0 && TCP->IPV6)
+ hints.ai_family = AF_INET6;
+ else if (TCP->IPV4 && TCP->IPV6)
+ hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
+
+ else
+ {
+ ReportError(STREAM, "Neither IPv4 nor IPv5 are enabled");
+ return FALSE; // Resolve failed
+ }
+
+
+ hints.ai_socktype = SOCK_STREAM;
+ getaddrinfo(Host, PortString, &hints, &res);
+
+ if (!res)
+ {
+ char Msg[256];
+ err = WSAGetLastError();
+ sprintf(Msg, "Resolve HostName Failed - Error %d", err);
+ ReportError(STREAM, Msg);
+ return FALSE; // Resolve failed
+ }
+
+ // Step thorough the list of hosts
+
+ saveres = res; // Save for free
+
+/* if (res->ai_next) // More than one
+ {
+ int n = ISHostIndex;
+
+ while (n && res->ai_next)
+ {
+ res = res->ai_next;
+ n--;
+ }
+
+ if (n)
+ {
+ // We have run off the end of the list
+
+ ISHostIndex = 0; // Back to start
+ res = saveres;
+ }
+ else
+ ISHostIndex++;
+
+ }
+*/
+// getnameinfo(res->ai_addr, (int)res->ai_addrlen, RealISHost, 256, serv, 256, 0);
sockptr = STREAM->ConnectionInfo;
- sock = sockptr->socket = socket(AF_INET, SOCK_STREAM, 0);
+ sock = sockptr->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (sock == INVALID_SOCKET)
- {
- ReportError(STREAM, "Create Socket Failed");
- return FALSE;
- }
-
sockptr->SocketActive = TRUE;
sockptr->InputLen = 0;
sockptr->LoginState = 2;
sockptr->UserPointer = 0;
sockptr->DoEcho = FALSE;
-
sockptr->FBBMode = FBB; // Raw Data
if (sockptr->ADIF == NULL)
@@ -6370,49 +6426,19 @@ int TCPConnect(struct TNCINFO * TNC, struct TCPINFO * TCP, struct STREAMINFO * S
memset(sockptr->ADIF, 0, sizeof(struct ADIF));
- // Resolve Name if needed
-
- sockptr->sin.sin_family = AF_INET;
- sockptr->sin.sin_port = htons(Port);
-
- sockptr->sin.sin_addr.s_addr = inet_addr(Host);
-
- if (sockptr->sin.sin_addr.s_addr == INADDR_NONE)
+ if (sock == INVALID_SOCKET)
{
- struct hostent * HostEnt;
-
- // Resolve name to address
-
- HostEnt = gethostbyname(Host);
-
- if (!HostEnt)
- {
- ReportError(STREAM, "Resolve HostName Failed");
- return FALSE; // Resolve failed
- }
- i = 0;
- while (HostEnt->h_addr_list[i] != 0)
- {
- struct in_addr addr;
- addr.s_addr = *(u_long *) HostEnt->h_addr_list[i++];
- }
- memcpy(&sockptr->sin.sin_addr.s_addr, HostEnt->h_addr, 4);
+ ReportError(STREAM, "Create Socket Failed");
+ return FALSE;
}
- ioctl (sockptr->socket, FIONBIO, ¶m);
-
- setsockopt (sockptr->socket, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4);
+ ioctl (sock, FIONBIO, ¶m);
- sinx.sin_family = AF_INET;
- sinx.sin_addr.s_addr = INADDR_ANY;
- sinx.sin_port = 0;
+ setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4);
- if (bind(sockptr->socket, (struct sockaddr *) &sinx, addrlen) != 0 )
- {
- ReportError(STREAM, "Bind Failed");
- return FALSE;
- }
+// memcpy(work, res->ai_addr->sa_data, 4);
+
if (LogEnabled)
{
char logmsg[512];
@@ -6421,21 +6447,21 @@ int TCPConnect(struct TNCINFO * TNC, struct TCPINFO * TCP, struct STREAMINFO * S
WriteLog (logmsg);
}
-
- if (connect(sockptr->socket,(struct sockaddr *) &sockptr->sin, sizeof(destaddr)) == 0)
+ if (connect(sock, res->ai_addr, (int)res->ai_addrlen) == 0)
{
//
// Connected successful
//
ReportError(STREAM, "*** Connected");
-
- // Get Send Buffer Size
+ freeaddrinfo(saveres);
return TRUE;
}
else
{
+ freeaddrinfo(saveres);
+
err=WSAGetLastError();
if (err == 10035 || err == 115 || err == 36) //EWOULDBLOCK
@@ -6461,7 +6487,6 @@ int TCPConnect(struct TNCINFO * TNC, struct TCPINFO * TCP, struct STREAMINFO * S
}
return FALSE;
-
}
diff --git a/Versions.h b/Versions.h
index a8b7c24..181a6ab 100644
--- a/Versions.h
+++ b/Versions.h
@@ -10,15 +10,15 @@
#endif
-#define KVers 6,0,24,71
-#define KVerstring "6.0.24.71\0"
+#define KVers 6,0,24,75
+#define KVerstring "6.0.24.75\0"
#ifdef CKernel
#define Vers KVers
#define Verstring KVerstring
-#define Datestring "April 2025"
+#define Datestring "June 2025"
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
#define VerCopyright "Copyright © 2001-2025 John Wiseman G8BPQ\0"
#define VerDesc "BPQ32 Switch\0"
diff --git a/WebMail.c b/WebMail.c
index 6510618..2c97f84 100644
--- a/WebMail.c
+++ b/WebMail.c
@@ -2822,6 +2822,18 @@ VOID SaveNewMessage(struct HTTPConnectionInfo * Session, char * MsgPtr, char * R
strcpy(Msg->via, ToUser->HomeBBS);
sprintf(Prompt, "%s added from HomeBBS. Message Saved", Msg->via);
}
+ else
+ {
+ // No HomeBBS - check WP
+
+ WPRecP WP = LookupWP(Msg->to);
+
+ if (WP)
+ {
+ strcpy(Msg->via, WP->first_homebbs);
+ sprintf(Prompt, "%s added from WP", Msg->via);
+ }
+ }
}
else
{
@@ -4239,6 +4251,18 @@ VOID SaveTemplateMessage(struct HTTPConnectionInfo * Session, char * MsgPtr, cha
strcpy(Msg->via, ToUser->HomeBBS);
sprintf(Prompt, "%s added from HomeBBS. Message Saved", Msg->via);
}
+ else
+ {
+ // No HomeBBS - Check WP
+
+ WPRecP WP = LookupWP(Msg->to);
+
+ if (WP)
+ {
+ strcpy(Msg->via, WP->first_homebbs);
+ sprintf(Prompt, "%s added from WP", Msg->via);
+ }
+ }
}
else
{
@@ -4459,6 +4483,18 @@ VOID BuildMessageFromHTMLInput(struct HTTPConnectionInfo * Session, char * Reply
strcpy(Msg->via, ToUser->HomeBBS);
sprintf(Prompt, "%s added from HomeBBS", Msg->via);
}
+ else
+ {
+ // No HomeBBS - Check WP
+
+ WPRecP WP = LookupWP(Msg->to);
+
+ if (WP)
+ {
+ strcpy(Msg->via, WP->first_homebbs);
+ sprintf(Prompt, "%s added from WP", Msg->via);
+ }
+ }
}
else
{
diff --git a/asmstrucs.h b/asmstrucs.h
index 34b8ce5..aa73b93 100644
--- a/asmstrucs.h
+++ b/asmstrucs.h
@@ -727,6 +727,9 @@ typedef struct PORTCONTROL
UCHAR * TX; // % Sending
UCHAR * BUSY; // % Active (Normally DCD active or TX)
+ int Hardware; // TNC H_TYPE. Copied here for access from application context
+
+
} PORTCONTROLX, *PPORTCONTROL;
typedef struct FULLPORTDATA
@@ -1371,6 +1374,7 @@ struct arp_table_entry
// SOCKET SourceSocket;
struct AXIPPORTINFO * PORT;
BOOL noUpdate; // Don't update dest address from incoming packet
+ BOOL replytoSourcePort; // Update map entry dest port from source port of each packet.
time_t LastHeard; // Last Packet received from this ststiom
};
diff --git a/bpq32.h b/bpq32.h
index bdc5a20..2bab90a 100644
--- a/bpq32.h
+++ b/bpq32.h
@@ -22,6 +22,8 @@ count on BPQ32.dll gets messed up, and the code will not unload cleanly.
struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portslot);
struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
+int APIENTRY GetPortHardwareType(struct PORTCONTROL *PORT);
+
// Returns number of free buffers
// (BPQHOST function 7 (part)).
diff --git a/bpqaxip.c b/bpqaxip.c
index 92cc9ab..d5afb62 100644
--- a/bpqaxip.c
+++ b/bpqaxip.c
@@ -204,7 +204,7 @@ int Update_MH_KeepAlive(struct AXIPPORTINFO * PORT, struct in_addr ipad, char pr
unsigned short int compute_crc(unsigned char *buf,int l);
unsigned int find_arp(unsigned char * call);
BOOL add_arp_entry(struct AXIPPORTINFO * PORT, unsigned char * call, UCHAR * ip, int len, int port,unsigned char * name,
-int keepalive, BOOL BCFlag, BOOL AutoAdded, int TCPMode, int SourcePort, BOOL IPv6, int noUpdate);
+ int keepalive, BOOL BCFlag, BOOL AutoAdded, int TCPMode, int SourcePort, BOOL IPv6, int noUpdate, int useSourcePort);
BOOL add_bc_entry(struct AXIPPORTINFO * PORT, unsigned char * call, int len);
BOOL convtoax25(unsigned char * callsign, unsigned char * ax25call, int * calllen);
static BOOL ReadConfigFile(int Port);
@@ -213,7 +213,7 @@ int CheckKeepalives(struct AXIPPORTINFO * PORT);
BOOL CopyScreentoBuffer(char * buff, struct AXIPPORTINFO * PORT);
int DumpFrameInHex(unsigned char * msg, int len);
VOID SendFrame(struct AXIPPORTINFO * PORT, struct arp_table_entry * arp_table, UCHAR * buff, int txlen);
-BOOL CheckSourceisResolvable(struct AXIPPORTINFO * PORT, char * call, int Port, VOID * rxaddr);
+BOOL CheckSourceisResolvable(struct AXIPPORTINFO * PORT, char * call, int FromPort, VOID * rxaddr, int ToPort);
int DataSocket_Read(struct arp_table_entry * sockptr, SOCKET sock);
int GetMessageFromBuffer(struct AXIPPORTINFO * PORT, char * Buffer);
int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len);
@@ -429,7 +429,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
if (PORT->Checkifcanreply)
{
- if (CheckSourceisResolvable(PORT, call, 0, &RXaddr))
+ if (CheckSourceisResolvable(PORT, call, 0, &RXaddr, 0))
return 1;
@@ -437,7 +437,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
// Can't reply. If AutoConfig is set, add to table and accept, else reject
if (PORT->AutoAddARP)
- return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr.sin_addr.s_addr, 7, 0, inet_ntoa(RXaddr.rxaddr.sin_addr), 0, PORT->AutoAddBC, TRUE, 0, 0, FALSE, 0);
+ return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr.sin_addr.s_addr, 7, 0, inet_ntoa(RXaddr.rxaddr.sin_addr), 0, PORT->AutoAddBC, TRUE, 0, 0, FALSE, 0, 0);
else
{
char From[11] = "|";
@@ -536,7 +536,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
if (PORT->Checkifcanreply)
{
- if (CheckSourceisResolvable(PORT, call, htons(RXaddr.rxaddr.sin_port), &RXaddr))
+ if (CheckSourceisResolvable(PORT, call, htons(RXaddr.rxaddr.sin_port), &RXaddr, PORT->udpport[i]))
return 1;
else
{
@@ -547,10 +547,10 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
{
char Addr[80];
Format_Addr((UCHAR *)&RXaddr.rxaddr6.sin6_addr, Addr, TRUE);
- return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr6.sin6_addr, 7, htons(RXaddr.rxaddr6.sin6_port), Addr, 0, PORT->AutoAddBC, TRUE, 0, PORT->udpport[i], TRUE, 0);
+ return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr6.sin6_addr, 7, htons(RXaddr.rxaddr6.sin6_port), Addr, 0, PORT->AutoAddBC, TRUE, 0, PORT->udpport[i], TRUE, 0, 0);
}
else
- return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr.sin_addr.s_addr, 7, htons(RXaddr.rxaddr.sin_port), inet_ntoa(RXaddr.rxaddr.sin_addr), 0, PORT->AutoAddBC, TRUE, 0, PORT->udpport[i], FALSE, 0);
+ return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr.sin_addr.s_addr, 7, htons(RXaddr.rxaddr.sin_port), inet_ntoa(RXaddr.rxaddr.sin_addr), 0, PORT->AutoAddBC, TRUE, 0, PORT->udpport[i], FALSE, 0, 0);
else
{
char From[11] = "|";
@@ -1343,6 +1343,7 @@ LRESULT FAR PASCAL ConfigWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lPa
char axcall[7];
BOOL UDPFlag, BCFlag;
struct AXIPPORTINFO * PORT;
+ int useSourcePort = 0;
for (i=1; i <= MAXBPQPORTS; i++)
{
@@ -1391,7 +1392,7 @@ LRESULT FAR PASCAL ConfigWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lPa
{
if (convtoax25(call,axcall,&calllen))
{
- add_arp_entry(PORT, axcall,0,calllen,port,host,Interval, BCFlag, FALSE, 0, port, FALSE, 0);
+ add_arp_entry(PORT, axcall,0,calllen,port,host,Interval, BCFlag, FALSE, 0, port, FALSE, 0, useSourcePort);
ResolveDelay = 2;
return(DestroyWindow(hWnd));
}
@@ -2147,6 +2148,7 @@ static int ProcessLine(char * buf, struct AXIPPORTINFO * PORT)
int Interval;
int noUpdate=FALSE;
int TCPMode;
+ int useSourcePort = 0;
ptr = strtok(buf, " \t\n\r");
@@ -2234,6 +2236,7 @@ static int ProcessLine(char * buf, struct AXIPPORTINFO * PORT)
bcflag=0;
TCPMode=0;
SourcePort = 0;
+ useSourcePort = 0;
//
// Look for (optional) KEEPALIVE, DYNAMIC, UDP or BROADCAST params
@@ -2264,7 +2267,14 @@ static int ProcessLine(char * buf, struct AXIPPORTINFO * PORT)
if (p_udpport == NULL) return (FALSE);
- port = atoi(p_udpport);
+ if (_stricmp(p_udpport,"FROMPORT") == 0)
+ {
+ useSourcePort = TRUE;
+ port = 0;
+ }
+ else
+ port = atoi(p_udpport);
+
p_UDP = strtok(NULL, " \t\n\r");
continue;
}
@@ -2327,7 +2337,7 @@ static int ProcessLine(char * buf, struct AXIPPORTINFO * PORT)
if (SourcePort == 0)
SourcePort = port;
- add_arp_entry(PORT, axcall, 0, calllen, port, p_ipad, Interval, bcflag, FALSE, TCPMode, SourcePort, FALSE, noUpdate);
+ add_arp_entry(PORT, axcall, 0, calllen, port, p_ipad, Interval, bcflag, FALSE, TCPMode, SourcePort, FALSE, noUpdate, useSourcePort);
return (TRUE);
}
} // End of Process MAP
@@ -2438,7 +2448,7 @@ BOOL convtoax25(unsigned char * callsign, unsigned char * ax25call,int * calllen
}
BOOL add_arp_entry(struct AXIPPORTINFO * PORT, UCHAR * call, UCHAR * ip, int len, int port,
- UCHAR * name, int keepalive, BOOL BCFlag, BOOL AutoAdded, int TCPFlag, int SourcePort, BOOL IPv6, int noUpdate)
+ UCHAR * name, int keepalive, BOOL BCFlag, BOOL AutoAdded, int TCPFlag, int SourcePort, BOOL IPv6, int noUpdate, int useSourcePort)
{
struct arp_table_entry * arp;
@@ -2457,7 +2467,8 @@ BOOL add_arp_entry(struct AXIPPORTINFO * PORT, UCHAR * call, UCHAR * ip, int len
arp->PORT = PORT;
- if (port == 0) PORT->needip = 1; // Enable Raw IP Mode
+ if (port == 0 && arp->replytoSourcePort == 0)
+ PORT->needip = 1; // Enable Raw IP Mode
arp->ResolveFlag=TRUE;
PORT->NeedResolver=TRUE;
@@ -2476,6 +2487,7 @@ BOOL add_arp_entry(struct AXIPPORTINFO * PORT, UCHAR * call, UCHAR * ip, int len
arp->TCPMode = TCPFlag;
arp->noUpdate = noUpdate;
PORT->arp_table_len++;
+ arp->replytoSourcePort = useSourcePort;
if (PORT->MaxResWindowlength < (PORT->arp_table_len * 14) + 70)
PORT->MaxResWindowlength = (PORT->arp_table_len * 14) + 70;
@@ -2576,7 +2588,7 @@ int CheckKeepalives(struct AXIPPORTINFO * PORT)
return (0);
}
-BOOL CheckSourceisResolvable(struct AXIPPORTINFO * PORT, char * call, int Port, VOID * rxaddr)
+BOOL CheckSourceisResolvable(struct AXIPPORTINFO * PORT, char * call, int FromPort, VOID * rxaddr, int ToPort)
{
// Makes sure we can reply to call before accepting message
@@ -2606,9 +2618,15 @@ BOOL CheckSourceisResolvable(struct AXIPPORTINFO * PORT, char * call, int Port,
struct sockaddr_in * SA = rxaddr;
memcpy(&arp->destaddr.sin_addr.s_addr, &SA->sin_addr, 4);
}
- // Dont think I should update port
+ // Dont think I should update port unless using source port for dest
- //arp->port = Port;
+ if (arp->replytoSourcePort)
+ {
+ arp->port = FromPort;
+ arp->destaddr.sin_port = htons(arp->port);
+ if (arp->SourcePort == 0)
+ arp->SourcePort = ToPort;
+ }
}
arp->LastHeard = time(NULL);
return 1; // Ok to process
diff --git a/cMain.c b/cMain.c
index 1815950..c87fac2 100644
--- a/cMain.c
+++ b/cMain.c
@@ -858,6 +858,9 @@ BOOL Start()
PREFERINP3ROUTES = cfg->C_PREFERINP3ROUTES;
+ if (cfg->C_OnlyVer2point0)
+ SUPPORT2point2 = 0;
+
// Get pointers to PASSWORD and APPL1 commands
diff --git a/cheaders.h b/cheaders.h
index 4b765a2..4951cac 100644
--- a/cheaders.h
+++ b/cheaders.h
@@ -105,7 +105,7 @@ VOID CLOSECURRENTSESSION(TRANSPORTENTRY * Session);
VOID SendCommandReply(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer, int Len);
-struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum);
+DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum);
int cCOUNT_AT_L2(struct _LINKTABLE * LINK);
VOID SENDL4CONNECT(TRANSPORTENTRY * Session);
@@ -202,8 +202,6 @@ int TrytoGuessCode(unsigned char * Char, int Len);
#define XID 0xAF
#define TEST 0xE3
-#define SUPPORT2point2 1
-
// XID Optional Functions
#define OPMustHave 0x02A080 // Sync TEST 16 bit FCS Extended Address
@@ -438,6 +436,9 @@ extern int MQTT_PORT;
extern char MQTT_USER[80];
extern char MQTT_PASS[80];
+extern int SUPPORT2point2;
+
+
DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqStringMhz);
diff --git a/config.c b/config.c
index 2ca25d3..a1b39a2 100644
--- a/config.c
+++ b/config.c
@@ -308,7 +308,8 @@ static char *keywords[] =
"BTEXT:", "NETROMCALL", "C_IS_CHAT", "MAXRTT", "MAXHOPS", // IPGATEWAY= no longer allowed
"LogL4Connects", "LogAllConnects", "SAVEMH", "ENABLEADIFLOG", "ENABLEEVENTS", "SAVEAPRSMSGS",
"EnableM0LTEMap", "MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS",
-"L4Compress", "L4CompMaxframe", "L4CompPaclen", "L2Compress", "L2CompMaxframe", "L2CompPaclen", "PREFERINP3ROUTES"
+"L4Compress", "L4CompMaxframe", "L4CompPaclen", "L2Compress", "L2CompMaxframe",
+"L2CompPaclen", "PREFERINP3ROUTES", "OnlyVer2point0"
}; /* parameter keywords */
static void * offset[] =
@@ -331,7 +332,7 @@ static void * offset[] =
&xxcfg.C_LogL4Connects, &xxcfg.C_LogAllConnects, &xxcfg.C_SaveMH, &xxcfg.C_ADIF, &xxcfg.C_EVENTS, &xxcfg.C_SaveAPRSMsgs,
&xxcfg.C_M0LTEMap, &xxcfg.C_MQTT, &xxcfg.C_MQTT_HOST, &xxcfg.C_MQTT_PORT, &xxcfg.C_MQTT_USER, &xxcfg.C_MQTT_PASS,
&xxcfg.C_L4Compress, &xxcfg.C_L4CompMaxframe, &xxcfg.C_L4CompPaclen, &xxcfg.C_L2Compress, &xxcfg.C_L2CompMaxframe,
-&xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES}; /* offset for corresponding data in config file */
+&xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES, &xxcfg.C_OnlyVer2point0}; /* offset for corresponding data in config file */
static int routine[] =
{
@@ -353,7 +354,7 @@ static int routine[] =
2, 2, 1, 2, 2, 2,
2, 2, 0, 1, 20, 20,
1, 1, 1, 1, 1,
-1, 1} ; // Routine to process param
+1, 1, 1} ; // Routine to process param
int PARAMLIM = sizeof(routine)/sizeof(int);
//int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int);
@@ -629,7 +630,7 @@ BOOL ProcessConfig()
paramok[90]=1; // L2Compress Maxframe
paramok[91]=1; // L2Compress Paclen
paramok[92]=1; // PREFERINP3ROUTES
-
+ paramok[93]=1; // C_ONLYVer2point0
for (i=0; i < PARAMLIM; i++)
{
diff --git a/configstructs.h b/configstructs.h
index f2efec3..9fb75cf 100644
--- a/configstructs.h
+++ b/configstructs.h
@@ -178,6 +178,7 @@ struct CONFIGTABLE
int C_L2CompMaxframe;
int C_L2CompPaclen;
int C_PREFERINP3ROUTES;
+ int C_OnlyVer2point0;
//#define ApplOffset 80000 // Applications offset in config buffer