1 Introduction
2 References
3 What to require
3.1 Getting the Gateway IP
gateway-ip-address
3.2 Timeouts
3.3 Discovering the current external IP address
external-ip-address
3.4 Low-level interface: mapping ports manually
map-port!
unmap-port!
unmap-all-ports!
refresh-mapping!
delete-mapping!
mapping
3.5 High-level interface: persistent mappings
make-persistent-mapping
stop-persistent-mapping!
current-persistent-mapping
refresh-persistent-mapping!
persistent-mapping
5.3.2.2

racket-nat-pmp

Tony Garnock-Jones <tonygarnockjones@gmail.com>

    1 Introduction

    2 References

    3 What to require

      3.1 Getting the Gateway IP

      3.2 Timeouts

      3.3 Discovering the current external IP address

      3.4 Low-level interface: mapping ports manually

      3.5 High-level interface: persistent mappings

If you find that this library lacks some feature you need, or you have a suggestion for improving it, please don’t hesitate to get in touch with me!

1 Introduction

This library implements NAT-PMP, the Apple/IETF protocol for opening TCP and UDP ports on home routers.

Using this library, you can discover the external IP address of your home router, and can manage port mappings from the public internet to internal TCP and UDP ports.

2 References

NAT-PMP is currently defined in an Internet-Draft.

3 What to require

All the functionality below can be accessed with a single require:

 (require (planet tonyg/nat-pmp:1:=1))

3.1 Getting the Gateway IP

NAT-PMP depends on being able to learn the IP address of the current default gateway. Currently, this library learns this information by running the system utility netstat and parsing its output.

procedure

(gateway-ip-address)  string?

Retrieves a string representation of the current gateway IP address, for example "10.0.0.1".

3.2 Timeouts

Requests made to the gateway using NAT-PMP will eventually time out if the gateway does not support NAT-PMP. In this case, an exception is raised.

3.3 Discovering the current external IP address

procedure

(external-ip-address)  string?

Uses the NAT-PMP protocol to ask the current gateway what the current external IP address is.

3.4 Low-level interface: mapping ports manually

If you can’t or don’t want to use the persistent mapping support of this library, these routines let you explicitly manage mappings with the gateway.

procedure

(map-port! protocol    
  local-port    
  requested-port    
  lifetime-seconds)  mapping?
  protocol : (or/c 'udp 'tcp)
  local-port : integer?
  requested-port : integer?
  lifetime-seconds : integer?
Creates a mapping at the gateway, requesting that requested-port on the external IP address be mapped to local-port on the IP address of the local machine. The mapping will survive on the gateway for lifetime-seconds seconds or until the router is rebooted. If both requested-port and lifetime-seconds are zero, an existing mapping for local-port is deleted (but use unmap-port! instead).

procedure

(unmap-port! protocol local-port)  void?

  protocol : (or/c 'udp 'tcp)
  local-port : integer?
Unmaps an existing mapping for local-port.

procedure

(unmap-all-ports! protocol)  void?

  protocol : (or/c 'udp 'tcp)
Unmaps all existing mappings for the local IP address and the given protocol.

procedure

(refresh-mapping! mapping)  mapping?

  mapping : mapping?
Refreshes a mapping by extracting its fields and calling map-port!.

procedure

(delete-mapping! mapping)  void?

  mapping : mapping?
Deletes a mapping by extracting its fields and calling unmap-port!.

struct

(struct mapping (protocol internal-port external-port lifetime)
  #:extra-constructor-name make-mapping
  #:prefab)
  protocol : (or/c 'udp 'tcp)
  internal-port : integer?
  external-port : integer?
  lifetime : integer?
A record of an established mapping.

3.5 High-level interface: persistent mappings

procedure

(make-persistent-mapping protocol 
  local-port 
  requested-port 
  [#:refresh-interval refresh-interval 
  #:on-mapping on-mapping]) 
  persistent-mapping?
  protocol : (or/c 'udp 'tcp)
  local-port : integer?
  requested-port : integer?
  refresh-interval : integer? = 7200
  on-mapping : (-> mapping? any/c) = void
Establishes a persistent mapping, which will refresh itself in the background every #:refresh-interval seconds until told to stop with stop-persistent-mapping!.

Every time the externally mapped port changes (including when the mapping is first established!) the #:on-mapping callback is called with the updated mapping information. Note that the callback is invoked directly from the mapping’s thread - if it raises an exception, it will kill the persistent mapping.

Deletes and stop refreshing an earlier-established persistent mapping. delete-mapping! is called to delete the mapping at the gateway.

Retrieves the current mapping details from a persistent mapping.

Overrides the internal timers in the persistent mapping, causing it to refresh itself at the gateway right now. Normal refreshing will resume thereafter.

struct

(struct persistent-mapping (thread)
  #:extra-constructor-name make-persistent-mapping
  #:prefab)
  thread : thread?
Handle for a persistent mapping. Useful with stop-persistent-mapping!, etc.