diff --git a/APRSCode.c b/APRSCode.c index fea004a..a9af47a 100644 --- a/APRSCode.c +++ b/APRSCode.c @@ -1581,9 +1581,9 @@ OK: // Copy frame to a DIGIMessage Struct - memcpy(&Msg, monbuff, 21 + (7 * Digis)); // Header, Dest, Source, Addresses and Digis + memcpy(&Msg, monbuff, MSGHDDRLEN + 14 + (7 * Digis)); // Header, Dest, Source, Addresses and Digis - len = Msg.LENGTH - 21 - (7 * Digis); // Payload Length (including CTL and PID + len = Msg.LENGTH - (MSGHDDRLEN + 14) - (7 * Digis); // Payload Length (including CTL and PID memcpy(&Msg.CTL, &AdjBuff->CTL, len); diff --git a/BPQMail.vcproj.DESKTOP-TGEL8RC.John.user b/BPQMail.vcproj.DESKTOP-TGEL8RC.John.user new file mode 100644 index 0000000..40182c4 --- /dev/null +++ b/BPQMail.vcproj.DESKTOP-TGEL8RC.John.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/BPQWinAPP.vcproj.DESKTOP-TGEL8RC.John.user b/BPQWinAPP.vcproj.DESKTOP-TGEL8RC.John.user new file mode 100644 index 0000000..40182c4 --- /dev/null +++ b/BPQWinAPP.vcproj.DESKTOP-TGEL8RC.John.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/Bpq32.c b/Bpq32.c index 9d87e34..1df9d34 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1195,7 +1195,9 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Allow zero resptime (send RR immediately) (13) // Make sure CMD bit is set on UI frames // Add setting Modem Flags in QtSM AGW mode -// If FT847 om PTC Port send a "Cat On" command (16) +// If FT847 om PTC Port send a "Cat On" command (17) +// Fix some 63 port bugs in RigCOntrol (17) +// Fix 63 port bug in Bridging (18) #define CKernel diff --git a/CBPQ32.vcproj.DESKTOP-TGEL8RC.John.user b/CBPQ32.vcproj.DESKTOP-TGEL8RC.John.user new file mode 100644 index 0000000..fdd7820 --- /dev/null +++ b/CBPQ32.vcproj.DESKTOP-TGEL8RC.John.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/IPCode.c b/IPCode.c index 8013b61..efc4d91 100644 --- a/IPCode.c +++ b/IPCode.c @@ -233,7 +233,7 @@ UCHAR ourMACAddr[6] = {02,'B','P','Q',1,1}; UCHAR RealMacAddress[6]; -int IPPortMask = 0; +uint64_t IPPortMask = 0; IPSTATS IPStats = {0}; @@ -1548,7 +1548,8 @@ VOID ProcessEthIPMsg(PETHMSG Buffer) VOID ProcessEthARPMsg(PETHARP arpptr, BOOL FromTAP) { - int i=0, Mask=IPPortMask; + int i=0; + uint64_t Mask=IPPortMask; PARPDATA Arp; PROUTEENTRY Route; BOOL Found; @@ -1748,12 +1749,12 @@ ProxyARPReply: memset(AXARPREQMSG.TARGETHWADDR, 0, 7); AXARPREQMSG.ARPOPCODE = 0x0100; - for (i=1; i<=NUMBEROFPORTS; i++) + for (i = 1; i <= MaxBPQPortNo; i++) { if (Mask & 1) Send_AX_Datagram((PMESSAGE)&AXARPREQMSG, 46, i, QST); - Mask>>=1; + Mask >>= 1; } break; @@ -1847,7 +1848,8 @@ SendBack: VOID ProcessAXARPMsg(PAXARP arpptr) { - int i=0, Mask=IPPortMask; + int i=0; + uint64_t Mask=IPPortMask; PARPDATA Arp; PROUTEENTRY Route; @@ -1954,13 +1956,13 @@ AXProxyARPReply: AXARPREQMSG.TARGETIPADDR = arpptr->TARGETIPADDR; AXARPREQMSG.SENDIPADDR = arpptr->SENDIPADDR; - for (i=1; i<=NUMBEROFPORTS; i++) + for (i=1; i<=MaxBPQPortNo; i++) { if (i != arpptr->MSGHDDR.PORT) if (Mask & 1) Send_AX_Datagram((PMESSAGE)&AXARPREQMSG, 46, i, QST); - Mask>>=1; + Mask >>= 1; } memset(ETHARPREQMSG.MSGHDDR.DEST, 0xff, 6); @@ -3281,7 +3283,7 @@ static BOOL ReadConfigFile() static int ProcessLine(char * buf) { - char * ptr, * p_value, * p_origport, * p_host, * p_port; + char * ptr, * p_value, * p_origport, * p_host; int port, mappedport, ipad, mappedipad; BOOL NATTAP = FALSE; int i; @@ -3447,16 +3449,28 @@ static int ProcessLine(char * buf) if (_stricmp(ptr,"IPPorts") == 0) { - p_port = strtok(p_value, " ,\t\n\r"); - - while (p_port != NULL) + struct _EXTPORTDATA * PORTVEC; + + while (p_value != NULL) { - i=atoi(p_port); + i=atoi(p_value); if (i == 0) return FALSE; - if (i > NUMBEROFPORTS) return FALSE; - IPPortMask |= 1 << (i-1); - p_port = strtok(NULL, " ,\t\n\r"); + PORTVEC = (struct _EXTPORTDATA * )GetPortTableEntryFromPortNum(i); + + if (PORTVEC == NULL) + return FALSE; + + // if not KISS, make sure it can send UI frames + + if (PORTVEC->PORTCONTROL.PORTTYPE == 16) // EXTERNAL + if (PORTVEC->PORTCONTROL.PROTOCOL == 10) // Pactor/WINMOR + if (PORTVEC->PORTCONTROL.UICAPABLE == 0) + return FALSE; + + + IPPortMask |= (uint64_t)1 << (i-1); + p_value = strlop(p_value, ','); } return (TRUE); } diff --git a/MailNode.vcproj.DESKTOP-TGEL8RC.John.user b/MailNode.vcproj.DESKTOP-TGEL8RC.John.user new file mode 100644 index 0000000..40182c4 --- /dev/null +++ b/MailNode.vcproj.DESKTOP-TGEL8RC.John.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/RigControl.c b/RigControl.c index 77b1ffe..4167cd4 100644 --- a/RigControl.c +++ b/RigControl.c @@ -202,7 +202,7 @@ char * RigWebPage = 0; int RigWebPageLen = 0; -struct RIGPORTINFO * PORTInfo[34] = {NULL}; // Records are Malloc'd +struct RIGPORTINFO * PORTInfo[MAXBPQPORTS + 2] = {NULL}; // Records are Malloc'd struct RIGINFO * DLLRIG = NULL; // Rig record for dll PTT interface (currently only for UZ7HO); @@ -782,7 +782,7 @@ int Rig_Command(TRANSPORTENTRY * Session, char * Command) { RIG = &PORT->Rigs[i]; - if (RIG->BPQPort & (1 << Port)) + if (RIG->BPQPort & ((uint64_t)1 << Port)) goto portok; } } @@ -2201,12 +2201,12 @@ DllExport BOOL APIENTRY Rig_Init() NumberofPorts = 0; - for (port = 0; port < 32; port++) + for (port = 0; port < MAXBPQPORTS; port++) PORTInfo[port] = NULL; // See if any rigcontrol defined (either RADIO or RIGCONTROL lines) - for (port = 0; port < 32; port++) + for (port = 0; port < MAXBPQPORTS; port++) { if (RadioConfigMsg[port]) NeedRig++; @@ -2362,15 +2362,6 @@ DllExport BOOL APIENTRY Rig_Init() } else PORT->hPTTDevice = PORT->hDevice; // Use same port for PTT - - - // Looks like FT847 Needa a "Cat On" Command. If PTC port need to send it here - - if (PORT->PTC && strcmp(PORT->Rigs[0].RigName, "FT847") == 0) - { - UCHAR CATON[6] = {0,0,0,0,0}; - SendPTCRadioCommand(PORT->PTC, CATON, 5); - } } for (p = 0; p < NumberofPorts; p++) @@ -2381,7 +2372,7 @@ DllExport BOOL APIENTRY Rig_Init() { int j; int k = 0; - int BitMask; + uint64_t BitMask; struct _EXTPORTDATA * PortEntry; RIG = &PORT->Rigs[i]; @@ -2395,7 +2386,7 @@ DllExport BOOL APIENTRY Rig_Init() // then those with neither BitMask = RIG->BPQPort; - for (j = 0; j < 32; j++) + for (j = 0; j < MAXBPQPORTS; j++) { if (BitMask & 1) { @@ -2408,7 +2399,7 @@ DllExport BOOL APIENTRY Rig_Init() } BitMask = RIG->BPQPort; - for (j = 0; j < 32; j++) + for (j = 0; j < MAXBPQPORTS; j++) { if (BitMask & 1) { @@ -2421,7 +2412,7 @@ DllExport BOOL APIENTRY Rig_Init() } BitMask = RIG->BPQPort; - for (j = 0; j < 32; j++) + for (j = 0; j < MAXBPQPORTS; j++) { if (BitMask & 1) { @@ -3266,7 +3257,7 @@ CheckOtherPorts: { PortRecord = RIG->PortRecord[i]; - if (PortRecord->PORT_EXT_ADDR(6, PortRecord->PORTCONTROL.PORTNUMBER, 1)) + if (PortRecord->PORT_EXT_ADDR && PortRecord->PORT_EXT_ADDR(6, PortRecord->PORTCONTROL.PORTNUMBER, 1)) { // 1 means can't change - release all @@ -7330,7 +7321,7 @@ VOID SetupScanInterLockGroups(struct RIGINFO *RIG) if (TNC->RXRadio == Interlock) { int p = PortRecord->PORTNUMBER; - RIG->BPQPort |= (1 << p); + RIG->BPQPort |= ((uint64_t)1 << p); sprintf(PortString, "%s,%d", PortString, p); TNC->RIG = RIG; @@ -7340,7 +7331,7 @@ VOID SetupScanInterLockGroups(struct RIGINFO *RIG) if (TNC->TXRadio == Interlock && TNC->TXRadio != TNC->RXRadio) { int p = PortRecord->PORTNUMBER; - RIG->BPQPort |= (1 << p); + RIG->BPQPort |= ((uint64_t)1 << p); sprintf(TxPortString, "%s,%d", TxPortString, p); TNC->TXRIG = RIG; @@ -9912,7 +9903,7 @@ void ProcessSDRANGELFrame(struct RIGPORTINFO * PORT) // As we mess with the message, save a copy and restore for each Rig - save = strdup(ptr3); + save = _strdup(ptr3); for (i = 0; i < PORT->ConfiguredRigs; i++) { diff --git a/SCSPactor.c b/SCSPactor.c index eff5512..4ae57be 100644 --- a/SCSPactor.c +++ b/SCSPactor.c @@ -122,6 +122,7 @@ VOID WritetoTrace(struct TNCINFO * TNC, char * Msg, int Len); void SCSTryToSendDATA(struct TNCINFO * TNC, int Stream); VOID UpdateMHwithDigis(struct TNCINFO * TNC, UCHAR * Call, char Mode, char Direction); int standardParams(struct TNCINFO * TNC, char * buf); +int SendPTCRadioCommand(struct TNCINFO * TNC, char * Block, int Length); #define FEND 0xC0 // KISS CONTROL CODES #define FESC 0xDB @@ -3179,10 +3180,23 @@ VOID ProcessDEDFrame(struct TNCINFO * TNC, UCHAR * Msg, int framelen) if (TNC->TNCOK == FALSE) { // Just come up + + struct RIGPORTINFO * PORT; TNC->TNCOK = TRUE; sprintf(TNC->WEB_COMMSSTATE,"%s TNC link OK", TNC->PortRecord->PORTCONTROL.SerialPortName); SetWindowText(TNC->xIDC_COMMSSTATE, TNC->WEB_COMMSSTATE); + + // If using an FT847 on PTC Port it needa a "Cat On" Command. Send it here + + PORT = TNC->RIG->PORT; + + if (PORT->PTC && strcmp(PORT->Rigs[0].RigName, "FT847") == 0) + { + UCHAR CATON[6] = {0,0,0,0,0}; + SendPTCRadioCommand(PORT->PTC, CATON, 5); + } + } Stream = RealStream = Msg[2]; diff --git a/Versions.h b/Versions.h index 411efe1..7619958 100644 --- a/Versions.h +++ b/Versions.h @@ -10,8 +10,8 @@ #endif -#define KVers 6,0,24,16 -#define KVerstring "6.0.24.16\0" +#define KVers 6,0,24,18 +#define KVerstring "6.0.24.18\0" #ifdef CKernel diff --git a/WinRPRHelper.vcproj.DESKTOP-TGEL8RC.John.user b/WinRPRHelper.vcproj.DESKTOP-TGEL8RC.John.user new file mode 100644 index 0000000..d4a1f25 --- /dev/null +++ b/WinRPRHelper.vcproj.DESKTOP-TGEL8RC.John.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/WinmorControl.vcproj.DESKTOP-TGEL8RC.John.user b/WinmorControl.vcproj.DESKTOP-TGEL8RC.John.user new file mode 100644 index 0000000..40182c4 --- /dev/null +++ b/WinmorControl.vcproj.DESKTOP-TGEL8RC.John.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/cMain.c b/cMain.c index abab877..7ca9e2e 100644 --- a/cMain.c +++ b/cMain.c @@ -2213,7 +2213,7 @@ L2Packet: // Bridge if requested - for (toPort = 1; toPort <= NUMBEROFPORTS; toPort++) + for (toPort = 1; toPort <= MaxBPQPortNo; toPort++) { if (BridgeMap[CURRENTPORT][toPort]) { diff --git a/configstructs.h b/configstructs.h index 67a6fbf..9dae4fb 100644 --- a/configstructs.h +++ b/configstructs.h @@ -158,7 +158,7 @@ struct CONFIGTABLE char C_IDMSG[512]; char C_CTEXT[512]; char C_INFOMSG[2048]; - UCHAR CfgBridgeMap[MaxBPQPortNo][MaxBPQPortNo]; + UCHAR CfgBridgeMap[MaxBPQPortNo + 1][MaxBPQPortNo + 1]; struct ROUTECONFIG C_ROUTE[MaxLockedRoutes]; struct APPLCONFIG C_APPL[NumberofAppls]; struct PORTCONFIG C_PORT[MaxBPQPortNo + 4]; diff --git a/rigcontrol.h b/rigcontrol.h index 2868704..13e0218 100644 --- a/rigcontrol.h +++ b/rigcontrol.h @@ -67,7 +67,7 @@ struct RIGINFO void * BPQtoRADIO_Q; // Frames from switch for radio - UINT BPQPort; // Port this radio is attached to. Bit Map, as may be more than one port controlling radio + uint64_t BPQPort; // Port this radio is attached to. Bit Map, as may be more than one port controlling radio // int PortNum; // Number of port that defined this rig int Interlock; // Interlock group for this Radio int IC735; // Old ICOM with shorter freq message diff --git a/upnp-DESKTOP-TGEL8RC.c b/upnp-DESKTOP-TGEL8RC.c new file mode 100644 index 0000000..70a8081 --- /dev/null +++ b/upnp-DESKTOP-TGEL8RC.c @@ -0,0 +1,187 @@ +// Includes code from MiniUPnPc, used subject to the following conditions: + +/* + +MiniUPnPc +Copyright (c) 2005-2020, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#define MINIUPNP_STATICLIB + +#include +#ifdef _WIN32 +#include "upnpcommands.h" +#include "miniupnpc.h" +#include "upnperrors.h" +#include +#else +#include +#include +#include +#include +#endif + +int AddMap(char * controlURL, char * eport, char * iport, char * proto); +int DeleteMap(char * controlURL, char * eport, char * iport, char * proto); + +void Consoleprintf(const char * format, ...); + +struct UPNP +{ + struct UPNP * Next; + char * Protocol; + char * LANport; + char * WANPort; +}; + +extern struct UPNP * UPNPConfig; + +char * controlURL = 0; +char * servicetype = 0; +char iaddr[] = "IP"; +char * inClient = NULL; +#ifdef LINBPQ +char desc[] = "LinBPQ "; +#else +char desc[] = "BPQ32 "; +#endif +char * remoteHost = NULL; +char * leaseDuration = NULL; + +struct UPNPDev * devlist = 0; +char lanaddr[64] = "unset"; /* my ip address on the LAN */ +struct UPNPUrls urls; +struct IGDdatas data; + +int i; +const char * rootdescurl = 0; +const char * multicastif = 0; +const char * minissdpdpath = 0; +int localport = UPNP_LOCAL_PORT_ANY; +int retcode = 0; +int error = 0; +int ipv6 = 0; +int ignore = 0; +unsigned char ttl = 2; + + +int upnpInit() +{ + struct UPNP * Config = UPNPConfig; + int i; +#ifdef WIN32 + WSADATA wsaData; + int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); + if(nResult != NO_ERROR) + { + fprintf(stderr, "WSAStartup() failed.\n"); + return -1; + } +#endif + + while (Config) + { + if (devlist == NULL) + { + devlist = upnpDiscover(2000, multicastif, minissdpdpath, localport, ipv6, ttl, &error); + + if (devlist == NULL) + { + Consoleprintf("Failed to find a UPNP device"); + return 0; + } + + i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); + } + + AddMap(devlist->descURL, Config->LANport, Config->WANPort, Config->Protocol); + Config = Config->Next; + } + + return 0; +} + +int upnpClose() +{ + struct UPNP * Config = UPNPConfig; + int i; + + while (Config) + { + if (devlist == NULL) + { + devlist = upnpDiscover(2000, multicastif, minissdpdpath, localport, ipv6, ttl, &error); + + if (devlist == NULL) + { + Consoleprintf("Failed to find a UPNP device"); + return 0; + } + + i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); + } + + DeleteMap(devlist->descURL, Config->LANport, Config->WANPort, Config->Protocol); + Config = Config->Next; + } + + return 0; +} + +int AddMap(char * controlURL, char * eport, char * iport, char * proto) +{ + int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + eport, iport, lanaddr, desc, + proto, remoteHost, leaseDuration); + + if (r != UPNPCOMMAND_SUCCESS) + { + Consoleprintf("UPNP AddPortMapping(%s, %s, %s) failed with code %d (%s)", eport, iport, lanaddr, r, strupnperror(r)); + return -2; + } + Consoleprintf("UPNP AddPortMapping(%s, %s, %s) Succeeded", eport, iport, lanaddr, r); + return 0; +} + +int DeleteMap(char * controlURL, char * eport, char * iport, char * proto) +{ + int r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, eport, proto, remoteHost); + + if(r != UPNPCOMMAND_SUCCESS) + { + Consoleprintf("UPNP DeletePortMapping(%s, %s, %s) failed with code %d (%s)", eport, iport, lanaddr, r, strupnperror(r)); + return -2; + } + Consoleprintf("UPNP DeletePortMapping(%s, %s, %s) Succeeded", eport, iport, lanaddr, r); + + return 0; +} + + + + diff --git a/upnp.c b/upnp.c index cdc68a4..6299446 100644 --- a/upnp.c +++ b/upnp.c @@ -39,13 +39,21 @@ POSSIBILITY OF SUCH DAMAGE. #include "miniupnpc.h" #include "upnperrors.h" #include -#else +#endif +#ifdef LINBPQ +#ifndef MACBPQ #include #include #include #include #endif - +#endif +#ifdef MACBPQ +#include +#include +#include +#include +#endif int AddMap(char * controlURL, char * eport, char * iport, char * proto); int DeleteMap(char * controlURL, char * eport, char * iport, char * proto); diff --git a/upnp.c.bak b/upnp.c.bak new file mode 100644 index 0000000..cdc68a4 --- /dev/null +++ b/upnp.c.bak @@ -0,0 +1,187 @@ +// Includes code from MiniUPnPc, used subject to the following conditions: + +/* + +MiniUPnPc +Copyright (c) 2005-2020, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#define MINIUPNP_STATICLIB + +#include +#ifdef _WIN32 +#include "upnpcommands.h" +#include "miniupnpc.h" +#include "upnperrors.h" +#include +#else +#include +#include +#include +#include +#endif + +int AddMap(char * controlURL, char * eport, char * iport, char * proto); +int DeleteMap(char * controlURL, char * eport, char * iport, char * proto); + +void Consoleprintf(const char * format, ...); + +struct UPNP +{ + struct UPNP * Next; + char * Protocol; + char * LANport; + char * WANPort; +}; + +extern struct UPNP * UPNPConfig; + +char * controlURL = 0; +char * servicetype = 0; +char iaddr[] = "IP"; +char * inClient = NULL; +#ifdef LINBPQ +char desc[] = "LinBPQ "; +#else +char desc[] = "BPQ32 "; +#endif +char * remoteHost = NULL; +char * leaseDuration = NULL; + +struct UPNPDev * devlist = 0; +char lanaddr[64] = "unset"; /* my ip address on the LAN */ +struct UPNPUrls urls; +struct IGDdatas data; + +int i; +const char * rootdescurl = 0; +const char * multicastif = 0; +const char * minissdpdpath = 0; +int localport = UPNP_LOCAL_PORT_ANY; +int retcode = 0; +int error = 0; +int ipv6 = 0; +int ignore = 0; +unsigned char ttl = 2; + + +int upnpInit() +{ + struct UPNP * Config = UPNPConfig; + int i; +#ifdef WIN32 + WSADATA wsaData; + int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); + if(nResult != NO_ERROR) + { + fprintf(stderr, "WSAStartup() failed.\n"); + return -1; + } +#endif + + while (Config) + { + if (devlist == NULL) + { + devlist = upnpDiscover(2000, multicastif, minissdpdpath, localport, ipv6, ttl, &error); + + if (devlist == NULL) + { + Consoleprintf("Failed to find a UPNP device"); + return 0; + } + + i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); + } + + AddMap(devlist->descURL, Config->LANport, Config->WANPort, Config->Protocol); + Config = Config->Next; + } + + return 0; +} + +int upnpClose() +{ + struct UPNP * Config = UPNPConfig; + int i; + + while (Config) + { + if (devlist == NULL) + { + devlist = upnpDiscover(2000, multicastif, minissdpdpath, localport, ipv6, ttl, &error); + + if (devlist == NULL) + { + Consoleprintf("Failed to find a UPNP device"); + return 0; + } + + i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); + } + + DeleteMap(devlist->descURL, Config->LANport, Config->WANPort, Config->Protocol); + Config = Config->Next; + } + + return 0; +} + +int AddMap(char * controlURL, char * eport, char * iport, char * proto) +{ + int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + eport, iport, lanaddr, desc, + proto, remoteHost, leaseDuration); + + if (r != UPNPCOMMAND_SUCCESS) + { + Consoleprintf("UPNP AddPortMapping(%s, %s, %s) failed with code %d (%s)", eport, iport, lanaddr, r, strupnperror(r)); + return -2; + } + Consoleprintf("UPNP AddPortMapping(%s, %s, %s) Succeeded", eport, iport, lanaddr, r); + return 0; +} + +int DeleteMap(char * controlURL, char * eport, char * iport, char * proto) +{ + int r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, eport, proto, remoteHost); + + if(r != UPNPCOMMAND_SUCCESS) + { + Consoleprintf("UPNP DeletePortMapping(%s, %s, %s) failed with code %d (%s)", eport, iport, lanaddr, r, strupnperror(r)); + return -2; + } + Consoleprintf("UPNP DeletePortMapping(%s, %s, %s) Succeeded", eport, iport, lanaddr, r); + + return 0; +} + + + +