I have solved this issue as follows:
- I have uninstalled miniupnpd, luci-app-upnp and miniupnpc. I will not use them.
- I used the following python scripts:
-
- scripts#1: that will send m-search command to my ISP router (192.168.1.1)
import socket
msg = \
'M-SEARCH * HTTP/1.1\r\n' \
'HOST:192.168.16.1:1900\r\n' \
'ST:upnp:rootdevice\r\n' \
'MX:2\r\n' \
'MAN:"ssdp:discover"\r\n' \
'\r\n'
# Set up UDP socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.settimeout(2)
s.sendto(msg, ('192.168.1.1', 1900) )
try:
while True:
data, addr = s.recvfrom(65507)
print addr, data
except socket.timeout:
pass
The output for this script contains this line :
Location: http://192.168.1.1:2869/DeviceDescription.xml
By running this location in a browser, you will get a list of xml entries. The relevant entry for us is the controlURL
. For my router, the controlURL returned was /UD/?8
.
- Script#2: This script will use the previously returned parameters from script#1 and do the port forwarding work for us. Of course, upnp must be enabled in the ISP router.
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import urllib2
HOST = '192.168.1.1'
PORT = 2869
CONTROL = '/UD/?8'
URL = 'http://' + HOST + ':' + str(PORT) + CONTROL
NEW_EXTERNAL_PORT = 1194 #ovpn port
NEW_INTERNAL_PORT = 1194
NEW_INTERNAL_CLIENT = '192.168.1.3' # ip address of my openwrt device
NEW_PROTOCOL = 'UDP'
LEASE_DURATION = '0'
DESCRIPTION = 'test'
SOAP = '<?xml version="1.0"?>\r\n'
SOAP += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">\r\n'
SOAP += '<s:Body>\r\n'
SOAP += '<m:AddPortMapping xmlns:m="urn:schemas-upnp-org:service:WANPPPConnection:1">\r\n'
SOAP += '<NewRemoteHost></NewRemoteHost>\r\n'
SOAP += '<NewExternalPort>' + str(NEW_EXTERNAL_PORT) + '</NewExternalPort>\r\n'
SOAP += '<NewProtocol>' + NEW_PROTOCOL + '</NewProtocol>\r\n'
SOAP += '<NewInternalPort>' + str(NEW_INTERNAL_PORT) + '</NewInternalPort>\r\n'
SOAP += '<NewInternalClient>' + NEW_INTERNAL_CLIENT + '</NewInternalClient>\r\n'
SOAP += '<NewEnabled>1</NewEnabled>\r\n'
SOAP += '<NewPortMappingDescription>' + DESCRIPTION + '</NewPortMappingDescription>\r\n'
SOAP += '<NewLeaseDuration>' + LEASE_DURATION + '</NewLeaseDuration>\r\n'
SOAP += '</m:AddPortMapping>\r\n'
SOAP += '</s:Body>\r\n'
SOAP += '</s:Envelope>\r\n'
req = urllib2.Request(URL)
req.add_header('Content-Type', 'text/xml; charset="utf-8"')
req.add_header('SOAPACTION', '"urn:schemas-upnp-org:service:WANPPPConnection:1#AddPortMapping"')
req.add_data(SOAP)
try:
res = urllib2.urlopen(req)
print res.read()
except urllib2.HTTPError, e:
print e.code
print e.msg
This is what was shown in my router's new upnp table entry:
|状態 |サービスホスト |プロトコル |内部ポート番号 |リモートホスト |外部ポート番号 |有効期限 |サービスの説明 |
|---|---|---|---|---|---|---|---|
|有効 |192.168.1.3 |UDP |1194 |---- |1194 |無期限 |test |
I believe that I can use miniupnpc to achieve the same thing but when I ran upnpc command from the openwrt machine and checked in tcpdump for destination port 1900, I could not see anything. Maybe a firewall issue?? I tried iptables -A INPUT --dport 1900 -j ACCEPT
but still upnpc didn't work. Maybe someone can comment on this.