NAME

Net::NAT::PMP - Poke holes in a router's NAT using the nat-pmp protocol

SYNOPSIS

use Net::NAT::PMP;
$nat_pmp = new Net::NAT::PMP or die "Net::NAT::PMP: $!";
$external_address = $nat_pmp->external_address;
$external_port = $nat_pmp->create_mapping(40000);

DESCRIPTION

Net::NAT::PMP is a client for the NAT Port Mapping Protocol (NAT-PMP), which is currently an RFC draft. NAT-PMP is designed so that you can have rich network applications that can still work even behind your home router's NAT.

FUNCTIONS

new($router_address)

Creates a new Net::NAT::PMP object and tries to discover the address of the gateway (router). This currently only works on Mac OS X 10.5 and Linux. Other platforms must pass the $router_address parameter to new().

external_address()

This queries the router for its external address. On success it returns the address as a string in dotted quad format.

create_mapping($internal_port, $external_port, $lifetime_seconds, $udp)

This asks the router to open a up an external port and map it to $internal_port. The mapping will last for $lifetime_seconds. According to the RFC draft, the mapping should be rerequested when have the lifetime has elapsed. Net::NAT::PMP does not do this for you.

If $external_port is zero then the router will pick a port for you.

If $external_port is undef then Net::NAT::PMP will request that the external port be the same as the internal port.

If $lifetime_seconds is undef then the default of 3600 (one hour) is assumed.

If $lifetime_seconds and $external_port are both 0 then the mapping is destroyed instead of created. It's probably clearer to use the destroy_mapping() member function in this case.

If $udp is true then the mapping will be for UDP connection. If false then it will be for TCP connections.

create_mapping() will return the external port number. You shouldn't assume this will be the same as the port you requested. The router is free to choose a different port number if it doesn't like the requested port number for whatever reason.

destroy_mapping($internal_port, $udp)

This will destroy a mapping.

BUGS

This barely implements the protocol. Specifically no attempt is made to retry or time out network transactions. Patches are welcome.

This protocol relies on being able to get the IP address of the router. There appears to be no standard POSIX way to do this, so the code has to support each OS separately. Currenly only Mac OS X and Linux are supported. Linux should be fairly stable since it is implemented by reading /proc/net/route which is what the route program itself does. The Mac OS X version, however, scrapes data from netstat which seems really fragile. It seems the way to do it natively involves interfacing with sysctl(). Again, patches are welcome.

SEE ALSO

http://tools.ietf.org/html/draft-cheshire-nat-pmp-03

COPYRIGHT

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

Copyright (C) 2009 David Caldwell

AUTHOR

David Caldwell <david@porkrind.org>