通过UPnP管理您的网关设备

通过UPnP管理您的网关设备

由于某些应用程序本身不支持,您是否需要手动下载或转发端口才需要重新连接? 那么这对你来说是正确的! 这个方法涵盖了Perl脚本,允许您通过UPnP管理网关设备。 您可以重新连接,添加和删除端口转发条目等等。

此Perl脚本允许您执行以下操作:

  • 触发重新连接
  • 打印您的网关提供的所有信息
  • 添加端口转发表项
  • 删除端口转发表项
  • 打印端口转发表项
  • 打印所有端口转发条目的列表
  • 删除所有端口转发表项
  • 启用或禁用全球互联网访问

安装

如果要尝试,请按照以下步骤安装脚本。

  1. 将脚本复制到文件
    您可以在本文的底部找到该脚本。 打开你最喜爱的编辑器并粘贴脚本。 保存到〜/ igdctl.pl

    通过执行此命令使脚本可执行:

    chmod +x ./igdctl.pl
  2. 安装perl模块
    该脚本需要一个名为Net :: UPnP的perl模块正常工作。 在终端中运行以下命令:
    sudo apt-get install -y libnet-upnp-perl

    这仅适用于基于DEB的系统。 对于基于RPM的系统,您需要一个不同的安装命令。

触发重新连接

如果您希望DSL路由器获取新的IP地址,请执行以下命令:

./igdctl.pl -r

说明:脚本自动查找互联网网关设备。 -r告诉脚本向网关发送ForceTermination信号。

打印信息

您可以通过UPnP打印网关提供的所有信息。 使用以下命令:

./igdctl.pl -p

说明 :-p告诉脚本调用返回设备提供的一些信息。

添加端口转发表项

如果要使用不支持通过UPnP或NAT进行端口转发的程序,则需要执行此过程。 当然,您可以通过网关的Web界面设置端口转发,但这里描述的方式更加舒适。

语法很简单:

./igdctl.pl -a -e PORT -i PORT -E REMOTE -I CLIENT -P [TCP|UDP]

说明: -a告诉脚本添加端口映射条目。 -e告诉外部端口号, -i表示内部端口号。 在大多数情况下,端口号是等效的。 -E告诉远程主机。 该参数是可选的 - 在大多数情况下,它是被忽略的。 告诉客户地址。 -P告诉可以是TCPUDP的协议

./igdctl.pl -a -e 4332 -i 4332 -I 192.168.0.5 -P TCP

说明:该命令设置从外部端口4332到客户端192.168.0.5的内部端口4332TCP端口转发

删除端口转发表项

如果要删除之前添加的端口转发条目,可以使用删除过程。

语法与上述一样简单:

./igdctl.pl -R -e PORT -E REMOTE -P [TCP/UDP]

说明: span class =“system”> - R告诉脚本删除以前添加的端口映射条目。 -e告诉外部端口号。 您不必指定内部端口号。 -E告诉远程主机。 此参数是可选的。 -P告诉可以是TCPUDP的协议

./igdctl.pl -R -e 4332 -P TCP

说明:该命令将删除以前添加的端口映射条目(见上文)。

打印端口转发表项

您可以通过外部端口号,远程主机和协议打印有关端口转发条目的信息。

语法几乎等于删除语法:

./igdctl.pl -g -e PORT -E REMOTE -P [TCP/UDP]

说明: span class =“system”> - g告诉脚本打印有关以前添加的端口映射条目的信息。 -e告诉外部端口号。 -E告诉远程主机。 此参数是可选的。 -P告诉协议。

./igdctl.pl -g -e 4332 -P TCP

说明:此命令将打印以前添加的端口映射条目(见上文)。

打印所有端口转发条目的列表

如果要查看正在转发给客户端的所有端口,请使用此过程。

./igdctl.pl -l -I CLIENT

说明: -l -I告诉客户端地址。 这是可选的。 如果您只想打印属于特定客户端的条目,请使用此选项。

./igdctl.pl -l -I 192.168.0.5

说明:这将打印所有端口转发表项192.168.0.5

一次删除所有端口转发条目

如果要全局或特定客户端删除所有端口转发条目,则非常有用。

./igdctl.pl -c -I CLIENT

说明: -c -I告诉客户端地址。 这是可选的。 如果您只想删除属于特定客户端的条目,请使用此选项。

./igdctl.pl -c -I 192.168.0.5

说明:这将删除所有端口转发表项192.168.0.5

启用或禁用全球互联网访问

如果您的网关制造商实施了此功能,您可以全局启用或禁用Internet访问。

警告:此功能几乎未被实现。 不要担心,如果你有错误。

./igdctl.pl [--enable|--disable]

说明:我认为语法是自我解释的。 --enable--disable告诉脚本在全局启用或禁用Internet访问。

列表

igdctl.pl

#!/usr/bin/perl
#########################################################################################
#
#    igdctl -:- Internet gateway device administration tool written in perl
#
#    VERSION:   0.1
#    AUTHOR:    Vincent Wochnik
#    EMAIL:     v.wochnik@yahoo.com
#    WWW:       ubuntu.blogetery.com
#    COPYRIGHT: (c) by Vincent Wochnik 2009
#
#    Permission is hereby granted, free of charge, to any person obtaining a copy
#    of this software and associated documentation files (the "Software"), to
#    deal in the Software without restriction, including without limitation the
#    rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
#    sell copies of the Software, and to permit persons to whom the Software is
#    furnished to do so, subject to the following conditions:
#
#    The above copyright notice and this permission notice shall be included in
#    all copies or substantial portions of the Software.
#
#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
#    IN THE SOFTWARE.
#
#########################################################################################
use strict;
use Getopt::Long;
use Net::UPnP::Device;
use Net::UPnP::ControlPoint;
## allow bundling of command line options
Getopt::Long::Configure('bundling');
##
## PARSE COMMAND LINE OPTIONS
##
my $help               = 0;
my $verbose            = 0;
my $action_print       = 0;
my $action_enable      = 0;
my $action_disable     = 0;
my $action_reconnect   = 0;
my $action_add_port    = 0;
my $action_get_port    = 0;
my $action_remove_port = 0;
my $action_list_ports  = 0;
my $action_clear_ports = 0;
my $devnum             = -1;
my $external_ip        = '';
my $external_port      = '';
my $internal_ip        = '';
my $internal_port      = '';
my $protocol           = '';
my $duration           = '';
my $active             = 1;        ## flag is set by default
if (!GetOptions('h|help',           => \$help,
                'v|verbose',        => \$verbose,
                'p|print'           => \$action_print,            ## print statistics
                'r|reconnect'       => \$action_reconnect,        ## reconnect
                'enable'            => \$action_enable,            ## enable internet access
                'disable'           => \$action_disable,        ## disable internet access
                'a|add-port'        => \$action_add_port,        ## add port mapping
                'g|get-port'        => \$action_get_port,        ## get a port by external host, ip and protocol
                'R|remove-port'     => \$action_remove_port,    ## remove port mapping
                'c|clear-ports'     => \$action_clear_ports,    ## clear port mapping list
                'l|list-ports'      => \$action_list_ports,        ## list port mappings
                'd|device=i'        => \$devnum,                ## device number
                'E|external-ip=s'   => \$external_ip,            ## external ip address
                'e|external-port=i' => \$external_port,            ## external port
                'I|internal-ip=s'   => \$internal_ip,            ## client ip address
                'i|internal-port=i' => \$internal_port,            ## internal port
                'P|protocol=s'        => \$protocol,                ## protocol (TCP/UDP
                'D|duration=i'      => \$duration,                ## expiration time
                'A|active=i'        => \$active)) {                ## active flag
    $help = 1;
}
if ($action_print+$action_enable+$action_disable+$action_reconnect+$action_add_port+$action_get_port+$action_remove_port+$action_clear_ports+$action_list_ports > 1) {
    ## No multiple action parameters!!!
    $help = 1;
} elsif ($action_print+$action_enable+$action_disable+$action_reconnect+$action_add_port+$action_get_port+$action_remove_port+$action_clear_ports+$action_list_ports == 0) {
    ## No action parameter found!!!
    $help = 1;
} elsif ($action_print+$action_enable+$action_disable+$action_reconnect == 1) {
    ## Some action parameters don't require additional parameters
    if (($external_ip) || ($external_port) || ($internal_ip) || ($internal_port) || ($duration)) {
        $help = 1;
    }
} elsif ($action_add_port+$action_get_port+$action_remove_port+$action_clear_ports+$action_list_ports == 1) {
    ## Check if all parameters are valid
    if (
        ((($action_add_port) || ((($action_clear_ports) || ($action_list_ports)) && ($internal_ip))) && ($internal_ip !~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)) ||
        ((($action_add_port) || ($action_remove_port) || ($action_get_port)) && ($external_ip) && ($external_ip !~ m/^[0-9*]{1,3}\.[0-9*]{1,3}\.[0-9*]{1,3}\.[0-9*]{1,3}$/)) ||
        (($action_add_port) && (($internal_port < 0) || ($internal_port > 65535))) ||
        ((($action_add_port) || ($action_remove_port) || ($action_get_port)) && (($external_port < 0) || ($external_port > 65535))) ||
        (($action_add_port) && (($duration) && ($duration < 0))) ||
        ((($action_add_port) || ($action_remove_port) || ($action_get_port)) && ($protocol !~ m/(TCP|UDP)/)) ||
        (($action_add_port) && ($duration) && ($duration !~ m/^\d$/)) ||
        (($action_add_port) && ($active) && ($active !~ m/^(0|1)$/))
       ) {
        $help = 1;
    }
}
## Display help content and exit
if ($help) {
    ## Help content is located at the bottom after the __DATA__ statement
    print STDOUT <data> and exit 2;
}
## scanning for devices
print STDOUT "Scanning for devices ...\n" if $verbose;
my @devices = get_igd_devices();
my $devcount = length(@devices);
## error handling
print STDERR "No device found.\n\n" and exit 1 if (!@devices);
## if there is only one device, auto-choose
$devnum = 0 if ($devcount == 1);
## if verbose or device number invalid
if (($verbose) || ($devnum < 0) || ($devnum >= $devcount)) {
    printf STDOUT 'Found %d ', $devcount;
    print STDOUT "device.\n\n" if ($devcount == 1);
    print STDOUT "devices.\n\n" if ($devcount != 1);
}
## print list and ask the user if no device number is given per command argument
if (($devnum < 0) || ($devnum >= $devcount)) {
    ## print device list
    list_devices(@devices);
    ## user choice
    while (($devnum !~ m/^[0-9]+$/) || ($devnum >= $devcount)) {
        print("Please select a device.\nDevice: ");
        chomp($devnum = );
        print STDOUT "Invalid choice. Try again!\n" if (($devnum < 0) || ($devnum >= $devcount));
        print STDOUT "\n";
    }
}
## Get chosen device
my $device = @devices[$devnum];
my $service;
## get service handler
if ($action_enable+$action_disable+$action_print) {
    ## Get WANIPCommonInterfaceConfig service
    $service = $device->getservicebyname("urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1");
    print STDERR "WANCommonInterfaceConfig service not avaleble.\n\n" and exit 1 if (!$service);
} else {##if ($action_reconnect+$action_add_port+$action_get_port+$action_remove_port+$action_clear_ports+$action_list_ports)
    ## Get WANIPConnection service
    $service = $device->getservicebyname("urn:schemas-upnp-org:service:WANIPConnection:1");
    print STDERR "WANCommonInterfaceConfig service not avaleble.\n\n" and exit 1 if (!$service);
}
if ($action_print) {
    my $res, my $out_args, my $out="";
    ## Get internet enabled
    print STDOUT "Trying to get internet access state ...\n" if $verbose;
    $res = $service->postaction("GetEnabledForInternet");
    if ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
        $out_args = $res->getargumentlist();
        if ($out_args->{'NewEnabledForInternet'}) {
            $out .= sprintf('Internet access                   : enabled'."\n");
        } else {
            $out .= sprintf('Internet access                   : disabled'."\n");
        }
    }
    ## Get connection properties ...
    print STDOUT "Trying to get connection properties ...\n" if $verbose;
    $res = $service->postaction("GetCommonLinkProperties");
    if ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
        $out_args = $res->getargumentlist();
        $out .= sprintf('WAN access type                   : %s'."\n", $out_args->{'NewWANAccessType'});
        $out .= sprintf('Maximum upstream rate             : %s bps'."\n", $out_args->{'NewLayer1UpstreamMaxBitRate'});
        $out .= sprintf('Maximum downstream rate           : %s bps'."\n", $out_args->{'NewLayer1DownstreamMaxBitRate'});
        $out .= sprintf('Physical link state               : %s'."\n", $out_args->{'NewPhysicalLinkStatus'});
    }
    ## Get wan access provider
    print STDOUT "Trying to get WAN access provider ...\n" if $verbose;
    $res = $service->postaction("GetWANAccessProvider");
    if ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
        $out_args = $res->getargumentlist();
        $out .= sprintf('WAN access provider               : %s'."\n", $out_args->{'NewWANAccessProvider'});
    }
    ## Get maximum number of active connections
    print STDOUT "Trying to get maximum number of active connections ...\n" if $verbose;
    $res = $service->postaction("GetMaximumActiveConnections");
    if ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
        $out_args = $res->getargumentlist();
        $out .= sprintf('Max. number of active connections : %d'."\n", $out_args->{'MaximumActiveConnections'});
    }
    ## Get total bytes sent
    print STDOUT "Trying to get total number of bytes sent ...\n" if $verbose;
    $res = $service->postaction("GetTotalBytesSent");
    if ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
        $out_args = $res->getargumentlist();
        $out .= sprintf('Total bytes sent                  : %s'."\n", readable_size($out_args->{'NewTotalBytesSent'}));
    }
    ## Get total packets sent
    print STDOUT "Trying to get total number of packets sent ...\n" if $verbose;
    $res = $service->postaction("GetTotalPacketsSent");
    if ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
        $out_args = $res->getargumentlist();
        $out .= sprintf('Total packets sent                : %d'."\n", $out_args->{'NewTotalPacketsReceived'});
    }
    ## Get total bytes received
    print STDOUT "Trying to get total number of bytes received ...\n" if $verbose;
    $res = $service->postaction("GetTotalBytesReceived");
    if ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
        $out_args = $res->getargumentlist();
        $out .= sprintf('Total bytes received              : %s'."\n", readable_size($out_args->{'NewTotalBytesReceived'}));
    }
    ## Get total packets received
    print STDOUT "Trying to get total number of packets received ...\n" if $verbose;
    $res = $service->postaction("GetTotalPacketsReceived");
    if ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
        $out_args = $res->getargumentlist();
        $out .= sprintf('Total packets received            : %d'."\n", $out_args->{'NewTotalPacketsReceived'});
    }
    print STDOUT $out."\n" and exit 0 if $out;                ## print information
    print STDERR "Nothing to print out.\n" and exit 1;        ## otherwise print an error
} elsif ($action_enable) {        ## OK <-- based on Documentation
    my $res, my %in_args, my $success=1;
    %in_args = ('NewEnabledForInternet' => '1');
    ## Enable internet access ...
    print STDOUT "Trying to enable internet access ...\n" if $verbose;
    $res = $service->postaction("SetEnabledForInternet", \%in_args);
    ## error handling
    if ($res->getstatuscode() == 401) {
        print STDERR "Operation not supported. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
    }
    print STDOUT "Command successful.\n" and exit 0 if $success;
    print STDERR "Command failed.\n" and exit 1;
} elsif ($action_disable) {        ## OK <-- based on Documentation
    my $res, my %in_args, my $success=1;
    %in_args = ('NewEnabledForInternet' => '0');
    ## Disable internet access ...
    print STDOUT "Trying to disable internet access ...\n" if $verbose;
    $res = $service->postaction("SetEnabledForInternet", \%in_args);
    ## error handling
    if ($res->getstatuscode() == 401) {
        print STDERR "Operation not supported. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
    }
    print STDOUT "Command successful.\n" and exit 0 if $success;
    print STDERR "Command failed.\n" and exit 1;
} elsif ($action_reconnect) {        ## OK <-- based on Documentation
    my $res, my $success=1;
    ## Force termination ...
    print STDOUT "Trying to terminate WANIPConnection ...\n" if $verbose;
    $res = $service->postaction("ForceTermination");
    ## error handling
    if ($res->getstatuscode() == 501) {
        print STDERR "Action failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() == 710) {
        print STDERR "Invalid connection type. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() == 702) {
        print STDERR "Disconnect in progress. (WARNING ".$res->getstatuscode().")\n\n" if $verbose;
    } elsif ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
    }
    print STDERR "Command failed.\n" and exit 1 if (!$success);
    ## Requesting new connection ...
    print STDOUT "Requesting new connection ...\n" if $verbose;
    $res = $service->postaction("RequestConnection");
    ## error handling
    if ($res->getstatuscode() == 704) {
        print STDERR "Connection setup failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() == 708) {
        print STDERR "Invalid Layer2 address. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() == 709) {
        print STDERR "Internet access disabled. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() == 710) {
        print STDERR "Invalid connection type. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() == 705) {
        print STDERR "Connection setup in progress. (WARNING ".$res->getstatuscode().")\n\n" if $verbose;
    } elsif ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
    }
    print STDOUT "Command successful.\n" and exit 0 if $success;
    print STDERR "Command failed.\n" and exit 1;
} elsif ($action_add_port) {
    my $res, my %in_args, my $success=1;
    %in_args = ('NewRemoteHost' => $external_ip,
                'NewExternalPort' => $external_port,
                'NewProtocol' => $protocol,
                'NewInternalPort' => $internal_port,
                'NewInternalClient' => $internal_ip,
                'NewEnabled' => $active,
                'NewPortMappingDescription' => 'mapped by '.__FILE__,
                'NewLeaseDuration' => $duration);
    ## trying to add port mapping entry
    print STDOUT "Trying to add a port mapping entry ...\n" if $verbose;
    $res = $service->postaction("AddPortMapping", \%in_args);
    ## error handling
    if ($res->getstatuscode() == 402) {
        print STDERR "Invalid args. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() == 715) {
        print STDERR "Wildcard not allowed in remote host address. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() == 716) {
        print STDERR "Wildcard not allowed in external port. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() == 718) {
        print STDERR "Conflicting with another mapping entry. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } elsif ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
    }
    print STDOUT "Command successful.\n" and exit 0 if $success;
    print STDERR "Command failed.\n" and exit 1;
} elsif ($action_remove_port) {
    my $res, my %in_args, my $success=1;
    %in_args = ('NewRemoteHost' => $external_ip,
                'NewExternalPort' => $external_port,
                'NewProtocol' => $protocol);
    ## remove port mapping entry
    print STDOUT "Trying to remove a port mapping entry matching specified criteria ...\n" if $verbose;
    $res = $service->postaction("DeletePortMapping", \%in_args);
    ## error handling
    if ($res->getstatuscode() == 714) {
        print STDERR "Entry not found. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
    } elsif ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
        $success = 0;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
    }
    print STDOUT "Command successful.\n" and exit 0 if $success;
    print STDERR "Command failed.\n" and exit 1;
} elsif ($action_get_port) {
    my $res, my %in_args, my $out_args, my $out;
    %in_args = ('NewRemoteHost' => $external_ip,
                'NewExternalPort' => $external_port,
                'NewProtocol' => $protocol);
    ## print port mapping entry
    print STDOUT "Trying to print a port mapping entry matching specified criteria ...\n" if $verbose;
    $res = $service->postaction("GetSpecificPortMappingEntry", \%in_args);
    ## error handling
    if ($res->getstatuscode() == 714) {
        print STDERR "Entry not found. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
    } elsif ($res->getstatuscode() != 200) {
        print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
    } else {
        print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
        $out_args = $res->getargumentlist();
        $out = sprintf('%6s %15s %13s %15s %13s %10s'."\n", 'ACTIVE', 'REMOTE HOST', 'EXTERNAL PORT', 'CLIENT HOST', 'INTERNAL PORT', 'LEASE TIME') if (!$out);
        if ($external_ip) {
            $out .= sprintf('%6s %15s %13s %15s %13s %10s'."\n", $out_args->{'NewEnabled'}, $external_ip, $external_port, $out_args->{'NewInternalClient'}, $out_args->{'NewInternalPort'}, $out_args->{'NewLeaseDuration'});
        } else {
            $out .= sprintf('%6s %15s %13s %15s %13s %10s'."\n", $out_args->{'NewEnabled'}, '*', $external_port, $out_args->{'NewInternalClient'}, $out_args->{'NewInternalPort'}, $out_args->{'NewLeaseDuration'});
        }
    }
    print STDOUT $out."\n" and exit 0 if $out;                ## print information
    print STDERR "Nothing to print out.\n" and exit 1;        ## otherwise print an error
} elsif ($action_list_ports) {
    my $res, my %in_args, my $out_args, my $i=0, my $out="";
    while ($i >= 0) {
        %in_args = ('NewPortMappingIndex' => $i);
        ## search port mapping entry
        print STDOUT "Trying to search port mapping entry ...\n" if $verbose;
        $res = $service->postaction("GetGenericPortMappingEntry", \%in_args);
        ## error handling
        if ($res->getstatuscode() != 200) {
            print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
            $i = -1;    ## stop loop - there are no more entries
        } else {
            print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
            $out_args = $res->getargumentlist();
            if ((!$internal_ip) || ($out_args->{'NewInternalClient'} =~ m/^($internal_ip)$/)) {
                $out = sprintf('%6s %15s %13s %15s %13s %10s'."\n", 'ACTIVE', 'REMOTE HOST', 'EXTERNAL PORT', 'CLIENT HOST', 'INTERNAL PORT', 'LEASE TIME') if (!$out);
                if ($out_args->{'NewRemoteHost'}) {
                    $out .= sprintf('%6s %15s %13s %15s %13s %10s'."\n", $out_args->{'NewEnabled'}, $out_args->{'NewRemoteHost'}, $out_args->{'NewExternalPort'}, $out_args->{'NewInternalClient'}, $out_args->{'NewInternalPort'}, $out_args->{'NewLeaseDuration'});
                } else {
                    $out .= sprintf('%6s %15s %13s %15s %13s %10s'."\n", $out_args->{'NewEnabled'}, '*', $out_args->{'NewExternalPort'}, $out_args->{'NewInternalClient'}, $out_args->{'NewInternalPort'}, $out_args->{'NewLeaseDuration'});
                }
            }
            $i++;
        }
    }
    print STDOUT $out."\n" and exit 0 if $out;                ## print information
    print STDERR "Nothing to print out.\n" and exit 1;        ## otherwise print an error
} elsif ($action_clear_ports) {
    my $res, my %in_args, my $out_args, my $i=0, my $success=1;
    while ($i >= 0) {
        %in_args = ('NewPortMappingIndex' => $i);
        ## search port mapping entry
        print STDOUT "Trying to search port mapping entry ...\n" if $verbose;
        $res = $service->postaction("GetGenericPortMappingEntry", \%in_args);
        ## error handling
        if ($res->getstatuscode() != 200) {
            print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
            $i = -1;    ## stop loop - there are no more entries
        } else {
            print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
            $out_args = $res->getargumentlist();
            if ((!$internal_ip) || ($out_args->{'NewInternalClient'} =~ m/^($internal_ip)$/)) {
                %in_args = ('NewRemoteHost' => $out_args->{'NewRemoteHost'},
                            'NewExternalPort' => $out_args->{'NewExternalPort'},
                            'NewProtocol' => $out_args->{'NewProtocol'});
                ## remove port mapping entry
                printf STDOUT 'Trying to remove port mapping entry number %d...'."\n", $i+1 if $verbose;
                $res = $service->postaction("DeletePortMapping", \%in_args);
                ## error handling
                if ($res->getstatuscode() == 714) {
                    print STDERR "Entry not found. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
                    $success=0;
                    $i = -1;    ## stop loop - there is an error
                } elsif ($res->getstatuscode() != 200) {
                    print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
                    $success=0;
                    $i = -1;    ## stop loop - there is an error
                } else {
                    print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
                }
            } else {
                $i++;
            }
        }
    }
    print STDOUT "Command successful.\n" and exit 0 if $success;
    print STDERR "Command failed.\n" and exit 1;
}
sub get_igd_devices() {
    my $cp, my @devices, my $device, my @filtereddevs;
    $cp = Net::UPnP::ControlPoint->new();
    ## scan for devices
    @devices = $cp->search(st => 'upnp:rootdevice', mx => '1');
    ## and another time if none found
    @devices = $cp->search(st => 'upnp:rootdevice', mx => '3') if (!@devices);
    if (@devices) {
        foreach $device (@devices) {
            my $devtype = $device->getdevicetype();
            if ($devtype =~ m/^urn:schemas-upnp-org:device:InternetGatewayDevice:1$/) {
                push(@filtereddevs, $device);
            }
        }
    }
    @filtereddevs;
}
sub list_devices() {
    my @devices, $devcount;
    my $devnum, my $devmanuf, my $devmodel, my $devsn, my $devudn, my $devupc;
    @devices = $_[0];
    $devcount = length(@devices);
    for ($devnum = 0; $devnum < $devcount; $devnum++) {
        $devmanuf = $devices[$devnum]->getmanufacturer();
        $devmodel = $devices[$devnum]->getmodelname();
        $devsn = $devices[$devnum]->getserialnumber();
        $devudn = $devices[$devnum]->getudn();
        $devupc = $devices[$devnum]->getupc();
        $devsn = "n/a" if (!$devsn);
        $devudn = "n/a" if (!$devudn);
        $devupc = "n/a" if (!$devupc);
        printf STDOUT 'Device:       : %d'."\n", $devnum;
        printf STDOUT 'Manufacturer  : %s'."\n", $devmanuf;
        printf STDOUT 'Model         : %s'."\n", $devmodel;
        printf STDOUT 'Serial number : %s'."\n", $devsn;
        printf STDOUT 'UDN           : %s'."\n", $devudn;
        printf STDOUT 'UPC           : %s'."\n\n", $devupc;
    }
}
sub readable_size() {
    my $size = $_[0];
    my $readable;
    if ($size >= 1024*1024*1024*1024) {
        $readable = sprintf('%.2f TB', $size/1024/1024/1024/1024);
    } elsif ($size >= 1024*1024*1024) {
        $readable = sprintf('%.2f GB', $size/1024/1024/1024);
    } elsif ($size >= 1024*1024) {
        $readable = sprintf('%.2f MB', $size/1024/1024);
    } elsif ($size >= 1024*1024*1024*1024) {
        $readable = sprintf('%.2f KB', $size/1024);
    } else {
        $readable = sprintf('%.2f Bytes', $size);
    }
    $readable;
}
__DATA__
igdctl -:- IGD administration tool written in perl
Version 0.1
USAGE
  ./igdctl.pl [-h|-p|-r|-a|-g|-R|-l|-c|--enable|--disable]
  [-d DEVICE] [-E IP] [-e PORT] [-I IP] [-i PORT]
  [-P PROTOCOL] [-D DURATION] [-A ACTIVE]
Example:
  ./igdctl.pl -r
Actions:
  -h, --help                : Displays this help text.
  -v, --verbose             : Verbose mode.
  -p, --print               : Prints connection information avaleble.
      --enable              : Enable internet access if supported.
      --disable             : Disable internet access if supported.
  -r, --reconnect           : Triggers a reconnect.
  -a, --add-port            : Adds or overwrites a port mapping entry with the
                              same internal client address.
                              -e, -I, -i, -P are needed, -E, -D, -A are
                              optional.
  -g, --get-port            : Gets a port mapping entry by remote host,
                              port and protocol. -e, -P are needed, -E is
                              optional.
  -R, --remove-port         : Removes a port mapping entry.
                              -e, -P are needed, -E is optional.
  -l, --list-ports          : Lists all port mapping entries. If -I was
                              specified, only entries by a given IP are shown.
  -c, --clear-ports         : Removes all port mapping entries. If -I was
                              specified, only entries by a given IP are
                              removed.
Options:
  -d, --device=DEV          : specifies the device number when more then one
                              devices are avaleble.
  -E, --external-ip=IP      : specifies a remote host. Wildcards are supported.
  -e, --external-port=PORT  : specifies an external port number.
  -I, --internal-ip=IP      : specifies a client ip address.
  -i, --internal-port=PORT  : specifies a client port number.
  -P, --protocol=PROTOCOL   : specifies a protocol. TCP and UDP are allowed.
  -D, --duration=DURATION   : specifies a number of seconds until a port mapping
                              entry expires.
  -A, --active=ACTIVE       : Specifies whether a port mapping entry is enabled.
                              Values 0 and 1 are allowed.
赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏