搜索
查看: 3196|回复: 6

会编程的帮下upnp映射的方法?

[复制链接]
发表于 2007-4-5 17:27:58 | 显示全部楼层 |阅读模式 来自 日本
小弟一直想在linux下开服务器但是没有upnp映射的方法 正巧看到有一个win的源码 希望达人帮我改成linux的版本谢谢拉
思路及过程(转载)

1.
摘要:使用标准的多播地址 239.255.255.250:1900,利用简单服务发现协议 SSDP 搜索UPNP设备。编程中使用数据报套接字。       发现这个过程主要有两步。第一,使用数据报套接字向239.255.255.250:1900,发送一条多播请求,格式如下
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN:"ssdp:discover"
MX:3
ST:UPnP:rootdevice
这个多播请求的含义如下:M-SEARCH SSDP协议定义的搜索请求方法。HOST必须是这个多播地址。MAN的值也必须是"ssdp:discover" 不可少了双引号。MX的含义是最长等待时间,可以自己设置。ST表示search target 搜索目标。我们在这里用找根设备。另外在编程中我们要在每一行后面加上"rn" 表示换行。(详见源码 UPNPNAT.discovery()).
      第二步,如果你的网络存在一个UPNP设备的话,为了被找到,设备必须向发送查找请求的多播通道的源 IP 地址与端口发送响应信息。所以你可以从239.255.255.250:1900这个地址接收到响应消息。类似下面的消息。
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=100
DATE: Sun, 15 Jan 2006 06:51:02 GMT
EXT:
LOCATION: http://192.168.14.1:1900/igd.xml
SERVER: TP-LINK Wireless Router WR541G/5, UPnP/1.0
ST: upnp:rootdevice
USN:uuid:upnp-InternetGatewayDevice-192168141678900001::upnp:rootdevice
接下来我们要从里面获得我们要的消息。首先,我们必须找到" 200 OK ",说明没有错误发生,否则一切免谈。接着,我们要找到LOCATION项,获得设备描述URL。(程序中的处理归根到底就是一个子字符的查找。)
       到这里,我们的第一步“发现”完成。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注个册吧

×
 楼主| 发表于 2007-4-5 17:35:07 | 显示全部楼层 来自 日本

回复: 会编程的帮下

2.
摘要:通过向路由发送 HTTP GET 请求获得设备描述XML,并解析XML获得控制URL.解析XML文件我使用了   Frank Vanden Berghen 的一个XML Parser 工具(在GPL下发布)。



    我们同样分两步进行,首先下载设备描述文件。(请看源码中UPNPNAT::get_description()函数)
     1.解析描述文件的URL,获得主机(host)、端口(port)、路径(path).(parseUrl函数)
    2.连接到host:port (tcp_connect 函数)
    3.构造类似
                                                GET path HTTP/1.1
                                                Host: host:port

的信息(第二行下要一个空行),并通过刚才的TCP 套接字,发送到路由器。(sprintf ,send 函数).
    4.接收数据,我使用flag为    MSG_WAITALL的recv函数,函数一直阻塞直到数据全部读完。    数据最终保存在std::string description_info中。
    我想通过浏览器下载这个文件的过程是类似的吧。

    然后,解析这个XML文件。(请看源码中UPNPNAT::    parser_description()函数)
我们找到"root"的"deviceType"是"urn:schemas-upnp-org:device:InternetGatewayDevice:1"的"device" childNode ,获得这个"device"的"deviceList",记为A。
    找到A的"deviceType"是"urn:schemas-upnp-org:device:WANDevice:1"的"device" childNode ,获得这个"device"的"deviceList",记为B。
    找到B的"deviceType"是"urn:schemas-upnp-org:device:WANConnectionDevice:1"的"device" childNode ,获得这个"device"的"serviceList",记为C。
    找到C的"serviceType"是"urn:schemas-upnp-org:service:WANIPConnection:1""urn:schemas-upnp-org:service:WANPPPConnection:1" 的"service"  childNode ,记为D.
    获得D的"controlUrl"保存在std::string control_url中。
  
    但是这里获得control_url一般为相对URL,所以要从"root"下面,找到"URLBase"的值,(如果是空,则用describe_url的"htpp://xxx.xxx.xxx.xxx:xxxx"部分代替.)
    最后在相对的control_url前加上URLBasr 获得完整的control_url.

    至此,第二步“获得控制URL”完成。
回复

使用道具 举报

 楼主| 发表于 2007-4-5 17:40:58 | 显示全部楼层 来自 日本

回复: 会编程的帮下

在这里我先把各种控制信息的格式说明一下。(下面的rn都是表示换行,我输入不了反斜杠。)增加端口映射。 "AddPortMapping"
"<NewRemoteHost></NewRemoteHost>rn"                              "<NewExternalPort>ExternalPort</NewExternalPort>rn"                               "<NewProtocol>Protocol</NewProtocol>rn"                                      "<NewInternalPort>InternalPort</NewInternalPort>n"
"<NewInternalClient>InternalClient</NewInternalClient>rn"                 
"<NewEnabled>1</NewEnabled>rn"
"<NewPortMappingDescription>PortMappingDescription"       "</NewPortMappingDescription>rn"      
"<NewLeaseDuration>LeaseDuration</NewLeaseDuration>rn"
删除端口映射 "DeletePortMapping"
"<NewRemoteHost></NewRemoteHost>rn"
"<NewExternalPort>ExternalPort</NewExternalPort>rn"
"<NewProtocol>Protocol</NewProtocol>rn"
获得端口映射信息 "GetGenericPortMappingEntry"
"<NewPortMappingIndex>PortMappingIndex</NewPortMappingIndex>"  "<NewRemoteHost></NewRemoteHost>rn"   "<NewExternalPort></NewExternalPort>rn" "<NewProtocol></NewProtocol>rn"     "<NewInternalPort></NewInternalPort>rn" "<NewInternalClient></NewInternalClient>rn" "<NewEnabled>1</NewEnabled>rn"  "<NewPortMappingDescription>"                                          "</NewPortMappingDescription>rn"            "<NewLeaseDuration></NewLeaseDuration>rn"
回复

使用道具 举报

 楼主| 发表于 2007-4-5 17:41:53 | 显示全部楼层 来自 日本

回复: 会编程的帮下

其中斜体部分需要在编程是填入的。ExternalPort 外部端口。InternalPort内部端口。这 两者一般就填映射的端口。Protocal 填TCP或UDP。InterClient 一般就是本地IP地址。PortMappingDescription 填写端口映射的描述,比如什么程序建立了这个端口。LeaseDuration 是映射的持续时间,用0表示不永久。PortMappingIndex 是端口映射索引,路由上第几个映射。      我们再来看下面这个XML文档结构。
      "<?xml version="1.0" encoding="utf-8"?>rn"
      "<s:Envelope xmlns:s="
      ""http://schemas.xmlsoap.org/soap/envelope/" "
      "s:encodingStyle="                                   
      ""http://schemas.xmlsoap.org/soap/encoding/">rn"
      "<s:Body>rn"
      "<u:actionName xmlns:u="serviceType">rn"
      "actionParams</u:actionName>rn"
      "</s:Body>rn"
      "</s:Envelope>rn"
      我们在actionName 处填入"AddPortMapping" "DeletePortMapping" "GetGenericPortMappingEntry"。serviceType 处填入设备的服务类型。"urn:schemas-upnp-org:service:WANIPConnection:1"或"urn:schemas-upnp-org:service:WANPPPConnection:1"。actionParams 填入上面的各种控制信息。
     最后在前面加上HTTP头。
     "POST path HTTP/1.1rn"
     "HOST: host:portrn"      
     "SOAPACTION:"serviceType#actionName"rn"  
     "CONTENT-TYPE: text/xml ; charset="utf-8"rn"
     "Content-Length: contentLength rnrn"
     path host port 意思很明显。contentLength面那个XML文档的长度。
  然后连接到host:port,发送到整个信息即可完成控制。
回复

使用道具 举报

 楼主| 发表于 2007-4-8 19:16:34 | 显示全部楼层 来自 日本

回复: 会编程的帮下

自己顶了          不是很多人都精通编成的么?
回复

使用道具 举报

发表于 2007-4-8 20:42:28 | 显示全部楼层 来自 中国–福建–漳州

回复: 会编程的帮下

Linux下编程我不会,我只会Window下编程。只是觉得奇怪,为什么Linux下建服要UPNP映射呢?自己手动在路由上映射一个端口不就行了?
回复

使用道具 举报

 楼主| 发表于 2007-4-9 10:59:06 | 显示全部楼层 来自 日本

回复: 会编程的帮下upnp映射的方法?

网络: Wireless 50M Cracked By AXOT
我是用别人的无线路由 那个路由不支持无线配置
回复

使用道具 举报

游客
回复
您需要登录后才可以回帖 登录 | 注个册吧

快速回复 返回顶部 返回列表