mirror of
https://bitbucket.org/King_DuckZ/keepupnpup.git
synced 2024-11-07 21:29:00 +00:00
Implement listing redirections.
This commit is contained in:
parent
06562e9f0e
commit
0fa232d074
2 changed files with 163 additions and 7 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
build/
|
||||
*.swp
|
||||
compile_commands.json
|
||||
.ycm_extra_conf.py
|
||||
|
|
169
src/main.cpp
169
src/main.cpp
|
@ -4,27 +4,81 @@
|
|||
#include "upnperrors.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <ciso646>
|
||||
#include <cstdint>
|
||||
#include <strings.h>
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
# define KUU_VERBOSE
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
enum Protocol {
|
||||
ProtocolUDP,
|
||||
ProtocolTCP,
|
||||
ProtocolOther
|
||||
};
|
||||
|
||||
class UPNPUrlsResource {
|
||||
public:
|
||||
UPNPUrlsResource () :
|
||||
m_initialized(false)
|
||||
enum IGDReply {
|
||||
IGDValid = 1,
|
||||
IGDNotConnected = 2,
|
||||
IGDUpnpNotSureIGD = 3,
|
||||
IGDNotSure,
|
||||
IGDNone
|
||||
};
|
||||
|
||||
explicit UPNPUrlsResource (struct UPNPDev* parDevList) :
|
||||
m_lanaddr(64, ' '),
|
||||
m_igd_reply(IGDNone)
|
||||
{
|
||||
const auto i = UPNP_GetValidIGD(parDevList, &m_urls, &m_data, &m_lanaddr[0], m_lanaddr.size());
|
||||
|
||||
switch (i) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
m_igd_reply = static_cast<IGDReply>(i);
|
||||
break;
|
||||
default:
|
||||
m_igd_reply = IGDNotSure;
|
||||
}
|
||||
|
||||
const auto idx = m_lanaddr.find('\0');
|
||||
if (idx != m_lanaddr.npos)
|
||||
m_lanaddr.resize(idx);
|
||||
}
|
||||
|
||||
~UPNPUrlsResource() noexcept {
|
||||
if (m_initialized) {
|
||||
m_initialized = false;
|
||||
if (IGDNone != m_igd_reply) {
|
||||
m_igd_reply = IGDNone;
|
||||
FreeUPNPUrls(&m_urls);
|
||||
}
|
||||
}
|
||||
|
||||
struct UPNPUrls* urls() { return &m_urls; }
|
||||
const struct UPNPUrls* urls() const { return &m_urls; }
|
||||
const struct IGDdatas* data() const { return &m_data; }
|
||||
IGDReply igd_reply() const { return m_igd_reply; }
|
||||
const std::string& lanaddr() const { return m_lanaddr; }
|
||||
|
||||
private:
|
||||
std::string m_lanaddr;
|
||||
struct UPNPUrls m_urls;
|
||||
bool m_initialized;
|
||||
struct IGDdatas m_data;
|
||||
IGDReply m_igd_reply;
|
||||
};
|
||||
|
||||
struct Redirection {
|
||||
std::string internal_client;
|
||||
std::string remote_host;
|
||||
std::string desc;
|
||||
Protocol protocol;
|
||||
uint32_t duration;
|
||||
uint16_t internal_port;
|
||||
uint16_t external_port;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
using UPNPDevsPtr = std::unique_ptr<struct UPNPDev, void(*)(struct UPNPDev*)>;
|
||||
|
@ -36,6 +90,83 @@ namespace {
|
|||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool is_enabled (const std::string& parEnabled) {
|
||||
if (parEnabled.size() == 4) {
|
||||
if (strncasecmp("true", parEnabled.c_str(), 4) == 0)
|
||||
return true;
|
||||
}
|
||||
else if (parEnabled.size() == 2) {
|
||||
if (strncasecmp("on", parEnabled.c_str(), 2) == 0)
|
||||
return true;
|
||||
}
|
||||
else if (parEnabled.size() == 3) {
|
||||
if (strncasecmp("yes", parEnabled.c_str(), 3) == 0)
|
||||
return true;
|
||||
}
|
||||
if (parEnabled == "1")
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<Redirection> get_redirections (const UPNPUrlsResource& parResource) {
|
||||
char intClient[40];
|
||||
char intPort[6];
|
||||
char extPort[6];
|
||||
char protocol[4];
|
||||
char desc[80];
|
||||
char enabled[6];
|
||||
char rHost[64];
|
||||
char duration[16];
|
||||
int r;
|
||||
|
||||
int z = 0;
|
||||
std::vector<Redirection> retval;
|
||||
do {
|
||||
rHost[0] = '\0';
|
||||
enabled[0] = '\0';
|
||||
duration[0] = '\0';
|
||||
desc[0] = '\0';
|
||||
extPort[0] = '\0';
|
||||
intPort[0] = '\0';
|
||||
intClient[0] = '\0';
|
||||
|
||||
r = UPNP_GetGenericPortMappingEntry(
|
||||
parResource.urls()->controlURL,
|
||||
parResource.data()->first.servicetype,
|
||||
std::to_string(z).c_str(),
|
||||
extPort,
|
||||
intClient,
|
||||
intPort,
|
||||
protocol,
|
||||
desc,
|
||||
enabled,
|
||||
rHost,
|
||||
duration
|
||||
);
|
||||
|
||||
//if (r)
|
||||
// printf("GetGenericPortMappingEntry() returned %d (%s)\n",
|
||||
// r, strupnperror(r));
|
||||
|
||||
if (not r) {
|
||||
Redirection redir;
|
||||
redir.protocol = (std::string(protocol) == "TCP" ? ProtocolTCP : (std::string(protocol) == "UDP" ? ProtocolUDP : ProtocolOther));
|
||||
redir.internal_client = intClient;
|
||||
redir.remote_host = rHost;
|
||||
redir.desc = desc;
|
||||
redir.duration = static_cast<uint32_t>(stoul(std::string(duration)));
|
||||
redir.internal_port = static_cast<uint16_t>(stoul(std::string(intPort)));
|
||||
redir.external_port = static_cast<uint16_t>(stoul(std::string(extPort)));
|
||||
redir.enabled = is_enabled(std::string(enabled));
|
||||
|
||||
retval.push_back(redir);
|
||||
}
|
||||
|
||||
++z;
|
||||
} while (not r);
|
||||
return retval;
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
int main() {
|
||||
|
@ -62,9 +193,33 @@ int main() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if defined(KUU_VERBOSE)
|
||||
std::cout << "Found: " << devs.front()->descURL << ", " << devs.front()->st << '\n';
|
||||
//struct IGDdatas data;
|
||||
|
||||
UPNPUrlsResource urls(devlist.get());
|
||||
switch (urls.igd_reply()) {
|
||||
case UPNPUrlsResource::IGDValid:
|
||||
std::cout << "Found valid IGD: " << urls.urls()->controlURL << '\n';
|
||||
break;
|
||||
case UPNPUrlsResource::IGDNotConnected:
|
||||
std::cout << "Found a (not connected?) IGD: " << urls.urls()->controlURL << '\n';
|
||||
break;
|
||||
case UPNPUrlsResource::IGDUpnpNotSureIGD:
|
||||
std::cout << "UPnP device found. Is it an IGD? " << urls.urls()->controlURL << '\n';
|
||||
break;
|
||||
case UPNPUrlsResource::IGDNotSure:
|
||||
std::cout << "Found device (igd?): " << urls.urls()->controlURL << '\n';
|
||||
}
|
||||
|
||||
std::cout << "Local LAN ip address: " << urls.lanaddr() << '\n';
|
||||
#endif
|
||||
|
||||
const auto redirs = get_redirections(urls);
|
||||
for (auto& redir : redirs) {
|
||||
std::cout << redir.protocol << ", " << redir.remote_host << ":" << redir.external_port << " --> " <<
|
||||
redir.internal_client << ":" << redir.internal_port << ", " << redir.duration << ", " <<
|
||||
redir.enabled << R"(, ")" << redir.desc << "\"\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue