libnatpmp

Accueil | Téléchargements | Compatibilité | libnatpmp | xchat upnp patch | Forum

English | Français

Dernière modification : 4 juilet 2008.

Le protocole «NAT Port Mapping Protocol» (NAT-PMP)

Le protocole NAT-PMP est un concurrent direct de la spécification UPnP sur les passerelles internet (IDG). Ce protocole fournit un moyen de faire du NAT traversal. Il fait partie des spécifications de protocoles Bonjour. Une description de ce protocole simple est disponible ici ou en lisant le brouillon de la norme. Au jour d'aujourd'hui, ce sont surtout les matériels et logiciels de marque Apple qui utilisent cette norme. Si vous voulez ajouter le support de NAT-PMP à votre routeur tournant sous *BSD, Linux ou (Open)Solaris, vous devriez regarder du coté de MiniUPnPd qui comprend NAT-PMP en plus de UPnP depuis décembre 2007 !

description de libnatpmp

libnatpmp est une tentative d'implémenter le protocole NAT-PMP d'une maniére portable et compètement conforme. libnatpmp utilise des sockets non bloquantes et tous les appels de l'API sont asynchrone. Il est donc très facile d'intégrer ce code dans du code évènementiel.

Télécharger et compiler libnatpmp

Pour télécharger le code source, allez sur la page de téléchargement.
Utilisez gmake ou make pour compiler la bibliothèque et les exemples. Pour les utilisateurs de Mingw32, un fichier .bat est fourni.

Utiliser libnatpmp dans un programme

L'utilisation de libnatpmp dans un programme C ou C++ devrait être facile. Tout l'API est décrite (en anglais) dans le fichier natpmp.h.

Code d'exemple

Le contrôle des erreurs a été délibérément oublié. Vérifiez tous les codes de retour qui sont présents dans le fichier natpmp.h.

Un example simple

Cet exemple très simple requiert une redirection et retourne quand cela est fait.
void redirect(uint16_t privateport, uint16_t publicport)
{
  int r;
  natpmp_t natpmp;
  natpmpresp_t response;
  initnatpmp(&natpmp);
  sendnewportmappingrequest(&natpmp, NATPMP_PROTOCOL_TCP, privateport, publicport, 3600);
  do {
    fd_set fds;
    struct timeval timeout;
    FD_ZERO(&fds);
    FD_SET(natpmp.s, &fds);
    getnatpmprequesttimeout(&natpmp, &timeout);
    select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
    r = readnatpmpresponseorretry(&natpmp, &response);
  } while(r==NATPMP_TRYAGAIN);
  printf("mapped public port %hu to localport %hu liftime %u\n",
         response.newportmapping.mappedpublicport,
         response.newportmapping.privateport,
         response.newportmapping.lifetime);
  closenatpmp(&natpmp);
}

Un exemple plus complexe

Imaginons la phase d'initialisation d'un logiciel P2P. Pendant cette phase, le logiciel essaye d'obtenir l'adresse IP publique de son LAN et un mapping de port. À la fin ce ce processus, la valeur de natpmpstate sera soit Sdone, soit Serror.
{
  natpmp_t natpmp;
  natpmpresp_t response;
  enum { Sinit=0, Ssendpub, Srecvpub, Ssendmap, Srecvmap, Sdone, Serror=1000 } natpmpstate = Sinit;
  int r;
  [...]
  if(initnatpmp(&natpmp)<0)
    natpmpstate = Serror;
  else
    natpmpstate = Ssendpub;
  [...]
  while(!finished_all_init_stuff) {
    [...]
    other init stuff :)
    [...]
    switch(natpmpstate) {
    case Ssendpub:
      if(sendpublicaddressrequest(&natpmp)<0);
        natpmpstate = Serror;
      else
        natpmpstate = Srecvpub;
      break;
    case Srecvpub:
      r = readnatpmpresponseorretry(&natpmp, &response);
      if(r<0 && r!=NATPMP_TRYAGAIN)
        natpmpstate = Serror;
      else if(r!=NATPMP_TRYAGAIN) {
        copy(publicaddress, response.publicaddress.addr);
        natpmpstate = Ssendmap;
      }
      break;
    case Ssendmap:
      if(sendnewportmappingrequest(&natpmp, protocol, privateport, publicport, lifetime)<0);
        natpmpstate = Serror;
      else
        natpmpstate = Srecvmap;
      break;
    case Srecvmap:
      r = readnatpmpresponseorretry(&natpmp, &response);
      if(r<0 && r!=NATPMP_TRYAGAIN)
        natpmpstate = Serror;
      else if(r!=NATPMP_TRYAGAIN) {
        copy(publicport, response.newportmapping.mappedpublicport);
        copy(privateport, response.newportmapping.privateport);
        copy(mappinglifetime, response.newportmapping.lifetime);
        natpmpclose(&natpmp);
        natpmpstate = Sdone;
      }
      break;
    }
    [...]
  }
  [...]
}

Thomas Bernard

Pour me contacter, utilisez le forum MiniUPnP (en anglais) ou envoyez moi directement un email : miniupnp _AROBASE_ free _POINT_ fr

Valid XHTML 1.0 Transitional Valid CSS!