Henry's Notebook
Many strange things
搜索
菜单
导航
首页
最近更改
随机页面
帮助
Henry's Home
个人资料
个人资料
创建账户
登录
消息
目前您没有通知。请访问您的
讨论页
以查看过去消息。
页面工具
内容页面
讨论
查看源代码
历史
首页
»
页面s
查看“Upnpsync”的源代码
←
Upnpsync
页面上次由
HenryHu
编辑于12年前
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:emailconfirmed
您可以查看与复制此页面的源代码。
[[Category:脚本]] upnpsync是个小脚本。主要用来同步路由器的UPnP转发信息和Cable Modem的转发信息。 最近在Time Warner的Cable Modem后面搞了个无线路由。之后又给这个路由刷了dd-wrt。 虽然一切都不错,但是对于要用UPnP进行端口转发的程序来说,因为它只会通过UPnP让路由转发,没有通知Cable Modem,导致它即使设置了端口转发,外网还是无法连接到它监听的端口。 网络结构是: Internet <-> <74.73.xx.xx> [Time Warner Cable Modem] <192.168.0.1> <-> <192.168.0.x> [DLink Wireless Router] <192.168.1.1> <-> <192.168.1.x> [My Computer] Time Warnar那个破Modem居然连配置都没法配,所有配置界面都锁死了,直接filter了23,80端口…… 幸好它居然留着UPnP。端口扫描扫出来5555和8081俩端口,尝试了一下,http://192.168.0.1:5555/ 就是它的UPnP地址…… 于是搞了个小脚本,可以根据无线路由上UPnP的端口转发信息,在Cable Modem上用UPnP自动配好对应的端口转发~ 后来又加了个小功能,会自动把在本地找不到的Modem上的转发信息干掉,这样在程序结束后能自动清理。 <source lang='perl'> #!/usr/bin/perl sub get_external($) { my ($url) = @_; $_ = `/usr/local/bin/upnpc -u $url -s | grep External`; /ExternalIPAddress = ([0-9\.]+)+/; return $1; } sub get_fwd_list($) { my ($url) = @_; $_ = `/usr/local/bin/upnpc -u $url -l | grep '\\\->'`; @result = (); foreach $line(split(/\n/)) { if ($line =~ m/\s*(\d+)\s+([A-Za-z]+)\s+(\d+)->([0-9\.]+):(\d+)\s+'(.*)'\s+'(.*)'/) { # print "No.$1 Proto:$2 Ext.Port:$3 LocalIP:$4 LocalPort:$5 Desc:$6 Note:$7\n"; $result[$1] = {"proto"=>$2, "extport"=>$3, "localip"=>$4, "localport"=>$5, "desc"=>$6, "note"=>$7}; } } return @result; } $router_ip = "192.168.1.1"; $modem_ip = "192.168.0.1"; $router_upnp = "http://192.168.1.1:1780/InternetGatewayDevice.xml"; $modem_upnp = "http://192.168.0.1:5555/"; $router_external = get_external($router_upnp); $modem_external = get_external($modem_upnp); @router_fwd = get_fwd_list($router_upnp); @modem_fwd = get_fwd_list($modem_upnp); print "Modem External IP: $modem_external\n"; print "Router External IP: $router_external\n"; foreach $router_pair (@router_fwd) { $proto = $router_pair->{"proto"}; $extport = $router_pair->{"extport"}; $found = 0; $good_pair = ""; print "Router: $proto $router_external:$extport -> $router_pair->{'localip'}:$router_pair->{'localport'}"; foreach $modem_pair (@modem_fwd) { if ($modem_pair->{"proto"} eq $proto and $modem_pair->{"localport"} == $extport) { $found = 1; $good_pair = $modem_pair; $modem_pair->{"router_pair"} = $router_pair; if ($modem_pair->{"localip"} ne $router_external) { $modem_local = $modem_pair->{"localip"}; print "\nWarning: Modem forwarding to strange IP: $modem_local\n"; } } } if (not $found) { print "... Not found!\n"; $ret = `/usr/local/bin/upnpc -u $modem_upnp -a $router_external $extport $extport $proto`; if ($? != 0) { print "ERROR adding port forwarding pair!\n"; print $ret; } else { print "Added forwarding $proto $modem_external:$extport->$router_external:$extport\n"; } } else { print "... Found\n"; print "Modem: $good_pair->{'proto'} $modem_external:$good_pair->{'extport'} -> $good_pair->{'localip'}:$good_pair->{'localport'}\n"; } } foreach $modem_pair (@modem_fwd) { if (not $modem_pair->{"router_pair"}) { $proto = $modem_pair->{'proto'}; $extport = $modem_pair->{'extport'}; print "Found extra modem pair: $proto $modem_external:$extport -> $modem_pair->{'localip'}:$modem_pair->{'localport'}\n"; $ret = `/usr/local/bin/upnpc -u $modem_upnp -d $extport $proto`; if ($? != 0) { print "ERROR deleting modem pair!\n"; print $ret; } else { print "Extra pair deleted.\n"; } } } </source> 这里的router_ip和modem_ip都是对内IP,应该都很清楚。 router_upnp和modem_upnp都是对应设备的UPnP地址。可以通过在计算机与该设备直连的情况下,用upnpc -l发现出来(自动发现还是不太靠谱啊……)。
返回至
Upnpsync
。