English | Français
Last modified on February 5th 2008.
I hadn't noticed when I started to code libnatpmp, but another library was already existing using the same name : Allen Porter made his C++ library in october/november 2007. If you want to have a look at it, it is available here. So what's next ? maybe I should change the name of my library ? what do you think of libnatpmpc ? (c like client or like the C language ?)
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);
}
{
  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
To contact me, use the MiniUPnP forum or use email : miniupnp _AT_ free _DOT_ fr
