Enable portmapping for individual UPnP services

This commit is contained in:
Caleb Callaway 2014-10-18 10:20:57 -07:00
parent 85677eaf1a
commit e34f77ba0e
1 changed files with 49 additions and 24 deletions

View File

@ -472,22 +472,12 @@ func soapRequest(url, device, function, message string) ([]byte, error) {
return resp, nil
}
// Add a port mapping to the specified InternetGatewayDevice.
// Add a port mapping to all relevant services on the specified InternetGatewayDevice.
// Port mapping will fail and return an error if action is fails for _any_ of the relevant services.
// For this reason, it is generally better to configure port mapping for each individual service instead.
func (n *IGD) AddPortMapping(protocol Protocol, externalPort, internalPort int, description string, timeout int) error {
for _, service := range n.services {
tpl := `<u:AddPortMapping xmlns:u="%s">
<NewRemoteHost></NewRemoteHost>
<NewExternalPort>%d</NewExternalPort>
<NewProtocol>%s</NewProtocol>
<NewInternalPort>%d</NewInternalPort>
<NewInternalClient>%s</NewInternalClient>
<NewEnabled>1</NewEnabled>
<NewPortMappingDescription>%s</NewPortMappingDescription>
<NewLeaseDuration>%d</NewLeaseDuration>
</u:AddPortMapping>`
body := fmt.Sprintf(tpl, service.serviceURN, externalPort, protocol, internalPort, n.localIPAddress, description, timeout)
_, err := soapRequest(service.serviceURL, service.serviceURN, "AddPortMapping", body)
err := service.AddPortMapping(n.localIPAddress, protocol, externalPort, internalPort, description, timeout)
if err != nil {
return err
}
@ -495,17 +485,12 @@ func (n *IGD) AddPortMapping(protocol Protocol, externalPort, internalPort int,
return nil
}
// Delete a port mapping from the specified InternetGatewayDevice.
func (n *IGD) DeletePortMapping(protocol Protocol, externalPort int) (err error) {
// Delete a port mapping from all relevant services on the specified InternetGatewayDevice.
// Port mapping will fail and return an error if action is fails for _any_ of the relevant services.
// For this reason, it is generally better to configure port mapping for each individual service instead.
func (n *IGD) DeletePortMapping(protocol Protocol, externalPort int) error {
for _, service := range n.services {
tpl := `<u:DeletePortMapping xmlns:u="%s">
<NewRemoteHost></NewRemoteHost>
<NewExternalPort>%d</NewExternalPort>
<NewProtocol>%s</NewProtocol>
</u:DeletePortMapping>`
body := fmt.Sprintf(tpl, service.serviceURN, externalPort, protocol)
_, err := soapRequest(service.serviceURL, service.serviceURN, "DeletePortMapping", body)
err := service.DeletePortMapping(protocol, externalPort)
if err != nil {
return err
}
@ -547,6 +532,46 @@ type getExternalIPAddressResponse struct {
NewExternalIPAddress string `xml:"NewExternalIPAddress"`
}
// Add a port mapping to the specified IGD service.
func (s *IGDService) AddPortMapping(localIPAddress string, protocol Protocol, externalPort, internalPort int, description string, timeout int) error {
tpl := `<u:AddPortMapping xmlns:u="%s">
<NewRemoteHost></NewRemoteHost>
<NewExternalPort>%d</NewExternalPort>
<NewProtocol>%s</NewProtocol>
<NewInternalPort>%d</NewInternalPort>
<NewInternalClient>%s</NewInternalClient>
<NewEnabled>1</NewEnabled>
<NewPortMappingDescription>%s</NewPortMappingDescription>
<NewLeaseDuration>%d</NewLeaseDuration>
</u:AddPortMapping>`
body := fmt.Sprintf(tpl, s.serviceURN, externalPort, protocol, internalPort, localIPAddress, description, timeout)
_, err := soapRequest(s.serviceURL, s.serviceURN, "AddPortMapping", body)
if err != nil {
return err
}
return nil
}
// Delete a port mapping from the specified IGD service.
func (s *IGDService) DeletePortMapping(protocol Protocol, externalPort int) error {
tpl := `<u:DeletePortMapping xmlns:u="%s">
<NewRemoteHost></NewRemoteHost>
<NewExternalPort>%d</NewExternalPort>
<NewProtocol>%s</NewProtocol>
</u:DeletePortMapping>`
body := fmt.Sprintf(tpl, s.serviceURN, externalPort, protocol)
_, err := soapRequest(s.serviceURL, s.serviceURN, "DeletePortMapping", body)
if err != nil {
return err
}
return nil
}
// Query the IGD service for its external IP address.
// Returns nil if the external IP address is invalid or undefined, along with any relevant errors
func (s *IGDService) GetExternalIPAddress() (net.IP, error) {