aboutsummaryrefslogtreecommitdiffstats
path: root/natpmp.go
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-02-03 02:22:39 +0800
committerobscuren <geffobscura@gmail.com>2014-02-03 02:22:39 +0800
commit3f503ffc7f85287fc3716afb704f90a1a4e7b21b (patch)
tree0428a976a08d04c8791ce4e2764c4bb39ef5cdf7 /natpmp.go
parentae0d4eb7aa644b4c295d7a7cd28c38e92777a52f (diff)
downloaddexon-3f503ffc7f85287fc3716afb704f90a1a4e7b21b.tar.gz
dexon-3f503ffc7f85287fc3716afb704f90a1a4e7b21b.tar.zst
dexon-3f503ffc7f85287fc3716afb704f90a1a4e7b21b.zip
Implemented support for UPnP
Diffstat (limited to 'natpmp.go')
-rw-r--r--natpmp.go54
1 files changed, 54 insertions, 0 deletions
diff --git a/natpmp.go b/natpmp.go
new file mode 100644
index 000000000..9a1fb652b
--- /dev/null
+++ b/natpmp.go
@@ -0,0 +1,54 @@
+package eth
+
+import (
+ natpmp "code.google.com/p/go-nat-pmp"
+ "fmt"
+ "net"
+)
+
+// Adapt the NAT-PMP protocol to the NAT interface
+
+// TODO:
+// + Register for changes to the external address.
+// + Re-register port mapping when router reboots.
+// + A mechanism for keeping a port mapping registered.
+
+type natPMPClient struct {
+ client *natpmp.Client
+}
+
+func NewNatPMP(gateway net.IP) (nat NAT) {
+ return &natPMPClient{natpmp.NewClient(gateway)}
+}
+
+func (n *natPMPClient) GetExternalAddress() (addr net.IP, err error) {
+ response, err := n.client.GetExternalAddress()
+ if err != nil {
+ return
+ }
+ ip := response.ExternalIPAddress
+ addr = net.IPv4(ip[0], ip[1], ip[2], ip[3])
+ return
+}
+
+func (n *natPMPClient) AddPortMapping(protocol string, externalPort, internalPort int,
+ description string, timeout int) (mappedExternalPort int, err error) {
+ if timeout <= 0 {
+ err = fmt.Errorf("timeout must not be <= 0")
+ return
+ }
+ // Note order of port arguments is switched between our AddPortMapping and the client's AddPortMapping.
+ response, err := n.client.AddPortMapping(protocol, internalPort, externalPort, timeout)
+ if err != nil {
+ return
+ }
+ mappedExternalPort = int(response.MappedExternalPort)
+ return
+}
+
+func (n *natPMPClient) DeletePortMapping(protocol string, externalPort, internalPort int) (err error) {
+ // To destroy a mapping, send an add-port with
+ // an internalPort of the internal port to destroy, an external port of zero and a time of zero.
+ _, err = n.client.AddPortMapping(protocol, internalPort, 0, 0)
+ return
+}