Diff for /embedaddon/miniupnpd/natpmp.c between versions 1.1 and 1.1.1.2

version 1.1, 2012/02/21 23:16:02 version 1.1.1.2, 2012/05/29 12:55:57
Line 39  int OpenAndConfNATPMPSocket(in_addr_t addr) Line 39  int OpenAndConfNATPMPSocket(in_addr_t addr)
                 natpmp_addr.sin_port = htons(NATPMP_PORT);                  natpmp_addr.sin_port = htons(NATPMP_PORT);
                 //natpmp_addr.sin_addr.s_addr = INADDR_ANY;                  //natpmp_addr.sin_addr.s_addr = INADDR_ANY;
                 natpmp_addr.sin_addr.s_addr = addr;                  natpmp_addr.sin_addr.s_addr = addr;
                 //natpmp_addr.sin_addr.s_addr = inet_addr("192.168.0.1");  
                 if(bind(snatpmp, (struct sockaddr *)&natpmp_addr, sizeof(natpmp_addr)) < 0)                  if(bind(snatpmp, (struct sockaddr *)&natpmp_addr, sizeof(natpmp_addr)) < 0)
                 {                  {
                         syslog(LOG_ERR, "bind(natpmp): %m");                          syslog(LOG_ERR, "bind(natpmp): %m");
Line 53  int OpenAndConfNATPMPSocket(in_addr_t addr) Line 52  int OpenAndConfNATPMPSocket(in_addr_t addr)
 int OpenAndConfNATPMPSockets(int * sockets)  int OpenAndConfNATPMPSockets(int * sockets)
 {  {
         int i, j;          int i, j;
        for(i=0; i<n_lan_addr; i++)        struct lan_addr_s * lan_addr;
         for(i = 0, lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next, i++)
         {          {
                sockets[i] = OpenAndConfNATPMPSocket(lan_addr[i].addr.s_addr);                sockets[i] = OpenAndConfNATPMPSocket(lan_addr->addr.s_addr);
                 if(sockets[i] < 0)                  if(sockets[i] < 0)
                 {                  {
                         for(j=0; j<i; j++)                          for(j=0; j<i; j++)
Line 85  static void FillPublicAddressResponse(unsigned char *  Line 85  static void FillPublicAddressResponse(unsigned char * 
                         resp[3] = 3;    /* Network Failure (e.g. NAT box itself                          resp[3] = 3;    /* Network Failure (e.g. NAT box itself
                                          * has not obtained a DHCP lease) */                                           * has not obtained a DHCP lease) */
                 } else {                  } else {
                        inet_pton(AF_INET, tmp, resp+8);                        inet_pton(AF_INET, tmp, resp+8); /* ok */
                 }                  }
         }          }
 #else  #else
        int i;        struct lan_addr_s * lan_addr;
        for(lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next) {
        for(i = 0; i<n_lan_addr; i++) {                if( (senderaddr & lan_addr->mask.s_addr)
                if( (senderaddr & lan_addr[i].mask.s_addr)                   == (lan_addr->addr.s_addr & lan_addr->mask.s_addr)) {
                   == (lan_addr[i].addr.s_addr & lan_addr[i].mask.s_addr)) {                        memcpy(resp+8, &lan_addr->ext_ip_addr,
                        memcpy(resp+8, &lan_addr[i].ext_ip_addr,                               sizeof(lan_addr->ext_ip_addr));
                               sizeof(lan_addr[i].ext_ip_addr)); 
                         break;                          break;
                 }                  }
         }          }
Line 138  void ProcessIncomingNATPMPPacket(int s) Line 137  void ProcessIncomingNATPMPPacket(int s)
         memset(resp, 0, sizeof(resp));          memset(resp, 0, sizeof(resp));
         resplen = 8;          resplen = 8;
         resp[1] = 128 + req[1]; /* response OPCODE is request OPCODE + 128 */          resp[1] = 128 + req[1]; /* response OPCODE is request OPCODE + 128 */
        /* setting response TIME STAMP */        /* setting response TIME STAMP :
          * time elapsed since its port mapping table was initialized on
          * startup or reset for any other reason */
         *((uint32_t *)(resp+4)) = htonl(time(NULL) - startup_time);          *((uint32_t *)(resp+4)) = htonl(time(NULL) - startup_time);
         if(req[0] > 0) {          if(req[0] > 0) {
                 /* invalid version */                  /* invalid version */
Line 161  void ProcessIncomingNATPMPPacket(int s) Line 162  void ProcessIncomingNATPMPPacket(int s)
                         int proto;                          int proto;
                         char iaddr_old[16];                          char iaddr_old[16];
                         unsigned short iport_old;                          unsigned short iport_old;
                           unsigned int timestamp;
   
                         iport = ntohs(*((uint16_t *)(req+4)));                          iport = ntohs(*((uint16_t *)(req+4)));
                         eport = ntohs(*((uint16_t *)(req+6)));                          eport = ntohs(*((uint16_t *)(req+6)));
                         lifetime = ntohl(*((uint32_t *)(req+8)));                          lifetime = ntohl(*((uint32_t *)(req+8)));
Line 185  void ProcessIncomingNATPMPPacket(int s) Line 188  void ProcessIncomingNATPMPPacket(int s)
                                         while(get_redirect_rule_by_index(index, 0,                                          while(get_redirect_rule_by_index(index, 0,
                                                   &eport2, iaddr2, sizeof(iaddr2),                                                    &eport2, iaddr2, sizeof(iaddr2),
                                                           &iport2, &proto2,                                                            &iport2, &proto2,
                                                          desc, sizeof(desc), 0, 0) >= 0) {                                                          desc, sizeof(desc),
                                                   0, 0, &timestamp, 0, 0) >= 0) {
                                                 syslog(LOG_DEBUG, "%d %d %hu->'%s':%hu '%s'",                                                  syslog(LOG_DEBUG, "%d %d %hu->'%s':%hu '%s'",
                                                        index, proto2, eport2, iaddr2, iport2, desc);                                                         index, proto2, eport2, iaddr2, iport2, desc);
                                                 if(0 == strcmp(iaddr2, senderaddrstr)                                                  if(0 == strcmp(iaddr2, senderaddrstr)
                                                  && 0 == memcmp(desc, "NAT-PMP ", 8)) {                                                  && 0 == memcmp(desc, "NAT-PMP", 7)) {
                                                         r = _upnp_delete_redir(eport2, proto2);                                                          r = _upnp_delete_redir(eport2, proto2);
                                                         /* TODO : check return value */                                                          /* TODO : check return value */
                                                         if(r<0) {                                                          if(r<0) {
                                                                 syslog(LOG_ERR, "failed to remove port mapping");                                                                  syslog(LOG_ERR, "failed to remove port mapping");
                                                                 index++;                                                                  index++;
                                                         } else {                                                          } else {
                                                                syslog(LOG_INFO, "NAT-PMP %s port %hu mapping removed", proto2==IPPROTO_TCP?"TCP":"UDP", eport2);                                                                syslog(LOG_INFO, "NAT-PMP %s port %hu mapping removed",
                                                                        proto2==IPPROTO_TCP?"TCP":"UDP", eport2);
                                                         }                                                          }
                                                 } else {                                                  } else {
                                                         index++;                                                          index++;
Line 209  void ProcessIncomingNATPMPPacket(int s) Line 214  void ProcessIncomingNATPMPPacket(int s)
                                         r = _upnp_delete_redir(eport, proto);                                          r = _upnp_delete_redir(eport, proto);
                                         /*syslog(LOG_DEBUG, "%hu %d r=%d", eport, proto, r);*/                                          /*syslog(LOG_DEBUG, "%hu %d r=%d", eport, proto, r);*/
                                         if(r<0) {                                          if(r<0) {
                                                syslog(LOG_ERR, "Failed to remove NAT-PMP mapping eport %hu, protocol %s", eport, (proto==IPPROTO_TCP)?"TCP":"UDP");                                                syslog(LOG_ERR, "Failed to remove NAT-PMP mapping eport %hu, protocol %s",
                                                        eport, (proto==IPPROTO_TCP)?"TCP":"UDP");
                                                 resp[3] = 2;    /* Not Authorized/Refused */                                                  resp[3] = 2;    /* Not Authorized/Refused */
                                         }                                          }
                                 }                                  }
Line 220  void ProcessIncomingNATPMPPacket(int s) Line 226  void ProcessIncomingNATPMPPacket(int s)
                         } else do {                          } else do {
                                 r = get_redirect_rule(ext_if_name, eport, proto,                                  r = get_redirect_rule(ext_if_name, eport, proto,
                                                       iaddr_old, sizeof(iaddr_old),                                                        iaddr_old, sizeof(iaddr_old),
                                                      &iport_old, 0, 0, 0, 0);                                                      &iport_old, 0, 0, 0, 0,
                                                       &timestamp, 0, 0);
                                 if(r==0) {                                  if(r==0) {
                                         if(strcmp(senderaddrstr, iaddr_old)==0                                          if(strcmp(senderaddrstr, iaddr_old)==0
                                        && iport==iport_old) {                                         && iport==iport_old) {
                                                 /* redirection allready existing */                                                  /* redirection allready existing */
                                                syslog(LOG_INFO, "port %hu %s already redirected to %s:%hu, replacing", eport, (proto==IPPROTO_TCP)?"tcp":"udp", iaddr_old, iport_old);                                                syslog(LOG_INFO, "port %hu %s already redirected to %s:%hu, replacing",
                                                        eport, (proto==IPPROTO_TCP)?"tcp":"udp", iaddr_old, iport_old);
                                                 /* remove and then add again */                                                  /* remove and then add again */
                                                 if(_upnp_delete_redir(eport, proto) < 0) {                                                  if(_upnp_delete_redir(eport, proto) < 0) {
                                                         syslog(LOG_ERR, "failed to remove port mapping");                                                          syslog(LOG_ERR, "failed to remove port mapping");
Line 238  void ProcessIncomingNATPMPPacket(int s) Line 246  void ProcessIncomingNATPMPPacket(int s)
                                 }                                  }
                                 { /* do the redirection */                                  { /* do the redirection */
                                         char desc[64];                                          char desc[64];
                                        unsigned timestamp = (unsigned)(time(NULL) - startup_time)#if 0
                                         timestamp = (unsigned)(time(NULL) - startup_time)
                                                               + lifetime;                                                                + lifetime;
                                         snprintf(desc, sizeof(desc), "NAT-PMP %u", timestamp);                                          snprintf(desc, sizeof(desc), "NAT-PMP %u", timestamp);
   #else
                                           timestamp = time(NULL) + lifetime;
                                           snprintf(desc, sizeof(desc), "NAT-PMP %hu %s",
                                                    eport, (proto==IPPROTO_TCP)?"tcp":"udp");
   #endif
                                         /* TODO : check return code */                                          /* TODO : check return code */
                                        if(upnp_redirect_internal(eport, senderaddrstr,                                        if(upnp_redirect_internal(NULL, eport, senderaddrstr,
                                                                  iport, proto, desc) < 0) {                                                                  iport, proto, desc,
                                                                   timestamp) < 0) {
                                                 syslog(LOG_ERR, "Failed to add NAT-PMP %hu %s->%s:%hu '%s'",                                                  syslog(LOG_ERR, "Failed to add NAT-PMP %hu %s->%s:%hu '%s'",
                                                        eport, (proto==IPPROTO_TCP)?"tcp":"udp", senderaddrstr, iport, desc);                                                         eport, (proto==IPPROTO_TCP)?"tcp":"udp", senderaddrstr, iport, desc);
                                                 resp[3] = 3;  /* Failure */                                                  resp[3] = 3;  /* Failure */
   #if 0
                                         } else if( !nextnatpmptoclean_eport                                          } else if( !nextnatpmptoclean_eport
                                                  || timestamp < nextnatpmptoclean_timestamp) {                                                   || timestamp < nextnatpmptoclean_timestamp) {
                                                 nextnatpmptoclean_timestamp = timestamp;                                                  nextnatpmptoclean_timestamp = timestamp;
                                                 nextnatpmptoclean_eport = eport;                                                  nextnatpmptoclean_eport = eport;
                                                 nextnatpmptoclean_proto = proto;                                                  nextnatpmptoclean_proto = proto;
   #endif
                                         }                                          }
                                         break;                                          break;
                                 }                                  }
                         } while(r==0);                          } while(r==0);
                         *((uint16_t *)(resp+8)) = htons(iport); /* private port */                          *((uint16_t *)(resp+8)) = htons(iport); /* private port */
                         *((uint16_t *)(resp+10)) = htons(eport);        /* public port */                          *((uint16_t *)(resp+10)) = htons(eport);        /* public port */
                        *((uint32_t *)(resp+12)) = htonl(lifetime);                        *((uint32_t *)(resp+12)) = htonl(lifetime);     /* Port Mapping lifetime */
                 }                  }
                 resplen = 16;                  resplen = 16;
                 break;                  break;
Line 275  void ProcessIncomingNATPMPPacket(int s) Line 292  void ProcessIncomingNATPMPPacket(int s)
         }          }
 }  }
   
   #if 0
 /* iterate through the redirection list to find those who came  /* iterate through the redirection list to find those who came
  * from NAT-PMP and select the first to expire */   * from NAT-PMP and select the first to expire */
 int ScanNATPMPforExpiration()  int ScanNATPMPforExpiration()
Line 289  int ScanNATPMPforExpiration() Line 307  int ScanNATPMPforExpiration()
         for(i = 0; ; i++) {          for(i = 0; ; i++) {
                 r = get_redirect_rule_by_index(i, 0, &eport, 0, 0,                  r = get_redirect_rule_by_index(i, 0, &eport, 0, 0,
                                                &iport, &proto, desc, sizeof(desc),                                                 &iport, &proto, desc, sizeof(desc),
                                               0, 0);                                               &timestamp, 0, 0);
                 if(r<0)                  if(r<0)
                         break;                          break;
                 if(sscanf(desc, "NAT-PMP %u", &timestamp) == 1) {                  if(sscanf(desc, "NAT-PMP %u", &timestamp) == 1) {
Line 315  int CleanExpiredNATPMP() Line 333  int CleanExpiredNATPMP()
         if(get_redirect_rule(ext_if_name, nextnatpmptoclean_eport,          if(get_redirect_rule(ext_if_name, nextnatpmptoclean_eport,
                              nextnatpmptoclean_proto,                               nextnatpmptoclean_proto,
                              0, 0,                               0, 0,
                             &iport, desc, sizeof(desc), 0, 0) < 0)                             &iport, desc, sizeof(desc), &timestamp, 0, 0) < 0)
                 return ScanNATPMPforExpiration();                  return ScanNATPMPforExpiration();
         /* check desc - this is important since we keep expiration time as part          /* check desc - this is important since we keep expiration time as part
          * of the desc.           * of the desc.
Line 333  int CleanExpiredNATPMP() Line 351  int CleanExpiredNATPMP()
                nextnatpmptoclean_proto==IPPROTO_TCP?"TCP":"UDP");                 nextnatpmptoclean_proto==IPPROTO_TCP?"TCP":"UDP");
         return ScanNATPMPforExpiration();          return ScanNATPMPforExpiration();
 }  }
   #endif
   
 /* SendNATPMPPublicAddressChangeNotification()  /* SendNATPMPPublicAddressChangeNotification()
  * should be called when the public IP address changed */   * should be called when the public IP address changed */
Line 342  void SendNATPMPPublicAddressChangeNotification(int * s Line 361  void SendNATPMPPublicAddressChangeNotification(int * s
         unsigned char notif[12];          unsigned char notif[12];
         int j, n;          int j, n;
   
        notif[0] = 0;        notif[0] = 0;   /* vers */
        notif[1] = 128;        notif[1] = 128; /* OP code */
        notif[2] = 0;        notif[2] = 0;   /* result code */
        notif[3] = 0;        notif[3] = 0;   /* result code */
         /* seconds since "start of epoch" :
          * time elapsed since the port mapping table was initialized on
          * startup or reset for any other reason */
         *((uint32_t *)(notif+4)) = htonl(time(NULL) - startup_time);          *((uint32_t *)(notif+4)) = htonl(time(NULL) - startup_time);
 #ifndef MULTIPLE_EXTERNAL_IP  #ifndef MULTIPLE_EXTERNAL_IP
         FillPublicAddressResponse(notif, 0);          FillPublicAddressResponse(notif, 0);
Line 358  void SendNATPMPPublicAddressChangeNotification(int * s Line 380  void SendNATPMPPublicAddressChangeNotification(int * s
 #endif  #endif
         memset(&sockname, 0, sizeof(struct sockaddr_in));          memset(&sockname, 0, sizeof(struct sockaddr_in));
     sockname.sin_family = AF_INET;      sockname.sin_family = AF_INET;
     sockname.sin_port = htons(NATPMP_PORT);  
     sockname.sin_addr.s_addr = inet_addr(NATPMP_NOTIF_ADDR);      sockname.sin_addr.s_addr = inet_addr(NATPMP_NOTIF_ADDR);
   
         for(j=0; j<n_sockets; j++)          for(j=0; j<n_sockets; j++)
Line 366  void SendNATPMPPublicAddressChangeNotification(int * s Line 387  void SendNATPMPPublicAddressChangeNotification(int * s
                 if(sockets[j] < 0)                  if(sockets[j] < 0)
                         continue;                          continue;
 #ifdef MULTIPLE_EXTERNAL_IP  #ifdef MULTIPLE_EXTERNAL_IP
                FillPublicAddressResponse(notif, lan_addr[j].addr.s_addr);                {
                         struct lan_addr_s * lan_addr = lan_addrs.lh_first;
                         int i;
                         for(i=0; i<j; i++)
                                 lan_addr = lan_addr->list.le_next;
                         FillPublicAddressResponse(notif, lan_addr->addr.s_addr);
                 }
 #endif  #endif
                   /* Port to use in 2006 version of the NAT-PMP specification */
           sockname.sin_port = htons(NATPMP_PORT);
                   n = sendto(sockets[j], notif, 12, 0,
                              (struct sockaddr *)&sockname, sizeof(struct sockaddr_in));
                   if(n < 0)
                   {       
                           syslog(LOG_ERR, "%s: sendto(s_udp=%d): %m",
                                  "SendNATPMPPublicAddressChangeNotification", sockets[j]);
                           return;
                   }
                   /* Port to use in 2008 version of the NAT-PMP specification */
           sockname.sin_port = htons(NATPMP_NOTIF_PORT);
                 n = sendto(sockets[j], notif, 12, 0,                  n = sendto(sockets[j], notif, 12, 0,
                            (struct sockaddr *)&sockname, sizeof(struct sockaddr_in));                             (struct sockaddr *)&sockname, sizeof(struct sockaddr_in));
                 if(n < 0)                  if(n < 0)

Removed from v.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>