【问题标题】:how to use libminiupnpc to setup port forwarding如何使用 libminiupnpc 设置端口转发
【发布时间】:2014-09-08 12:00:28
【问题描述】:

我想使用 libminiupnpc (github) 来查找设备并进行 TCP 端口转发/映射。但是,我找不到一个像样的文档或示例代码来说明如何使用 miniupnpc API。

有人知道如何使用这个库的好文档或示例代码吗?

我现在拥有的是:

#include <miniupnpc/miniupnpc.h>
...
int error = 0;
UPNPDev *dev = upnpDiscover(2000, nullptr, nullptr, 0, 0, &error);

...这似乎正确地返回了关于我的路由器的信息:

2014-09-08 11:36:17.417132 debug  - UPnP ERROR: 0
2014-09-08 11:36:17.417394 debug  - UPnP device:
    url: http://192.168.1.1:5431/dyndev/uuid:207605a3-efd0-d0ef-a320-162376a3d04000
    st:  urn:schemas-upnp-org:device:InternetGatewayDevice:1
    buf: http://192.168.1.1:5431/dyndev/uuid:207605a3-efd0-d0ef-a320-162376a3d04000

问题不是upnpDiscover(),接下来需要调用什么并不明显。

【问题讨论】:

  • 你最好把同样的问题发到the project's forum
  • 请注意该论坛不活跃。每月大约有 1 个帖子。我的问题(到目前为止)在论坛上没有得到解答。

标签: linux upnp miniupnpc


【解决方案1】:

Miniupnp 的文档记录不是很好(或根本没有?)。这是我最终发现添加和列出端口映射所必需的。我将省略错误处理。

int error = 0;
struct UPNPDev *upnp_dev = upnpDiscover(
        2000    , // time to wait (milliseconds)
        nullptr , // multicast interface (or null defaults to 239.255.255.250)
        nullptr , // path to minissdpd socket (or null defaults to /var/run/minissdpd.sock)
        0       , // source port to use (or zero defaults to port 1900)
        0       , // 0==IPv4, 1==IPv6
        &error  ); // error condition

char lan_address[64];
struct UPNPUrls upnp_urls;
struct IGDdatas upnp_data;
int status = UPNP_GetValidIGD(upnp_dev, &upnp_urls, &upnp_data, lan_address, sizeof(lan_address));
// look up possible "status" values, the number "1" indicates a valid IGD was found

// get the external (WAN) IP address
char wan_address[64];
UPNP_GetExternalIPAddress(upnp_urls.controlURL, upnp_data.first.servicetype, wan_address);

// add a new TCP port mapping from WAN port 12345 to local host port 24680
error = UPNP_AddPortMapping(
            upnp_urls.controlURL,
            upnp_data.first.servicetype,
            "12345"     ,  // external (WAN) port requested
            "24680"     ,  // internal (LAN) port to which packets will be redirected
            lan_address , // internal (LAN) address to which packets will be redirected
            "FooBar server for XYZ", // text description to indicate why or who is responsible for the port mapping
            "TCP"       , // protocol must be either TCP or UDP
            nullptr     , // remote (peer) host address or nullptr for no restriction
            "86400"     ); // port map lease duration (in seconds) or zero for "as long as possible"

// list all port mappings
size_t index = 0;
while (true)
{
    char map_wan_port           [200] = "";
    char map_lan_address        [200] = "";
    char map_lan_port           [200] = "";
    char map_protocol           [200] = "";
    char map_description        [200] = "";
    char map_mapping_enabled    [200] = "";
    char map_remote_host        [200] = "";
    char map_lease_duration     [200] = ""; // original time, not remaining time :(

    error = UPNP_GetGenericPortMappingEntry(
                upnp_urls.controlURL            ,
                upnp_data.first.servicetype     ,
                std::to_string(index).c_str()   ,
                map_wan_port                    ,
                map_lan_address                 ,
                map_lan_port                    ,
                map_protocol                    ,
                map_description                 ,
                map_mapping_enabled             ,
                map_remote_host                 ,
                map_lease_duration              );

    if (error)
    {
        break; // no more port mappings available
    }

    std::cout << ....print out or do whatever you want with the map_* fields
}

两个有用的文件是upnpc.cupnpcommands.c,来自https://github.com/miniupnp/miniupnp/tree/master/miniupnpc 的github 项目。

【讨论】:

  • &amp;error 之前有一个 ttl 参数,应该设置为 2。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-06
  • 2015-05-23
  • 2018-10-05
  • 1970-01-01
  • 2021-12-30
相关资源
最近更新 更多