Diff for /embedaddon/miniupnpd/miniupnpd.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 23:16:02 version 1.1.1.2, 2012/05/29 12:55:57
Line 1 Line 1
 /* $Id$ */  /* $Id$ */
 /* MiniUPnP project  /* MiniUPnP project
  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/   * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
 * (c) 2006-2010 Thomas Bernard * (c) 2006-2011 Thomas Bernard
  * This software is subject to the conditions detailed   * This software is subject to the conditions detailed
  * in the LICENCE file provided within the distribution */   * in the LICENCE file provided within the distribution */
   
Line 63 Line 63
 #include "natpmp.h"  #include "natpmp.h"
 #endif  #endif
 #include "commonrdr.h"  #include "commonrdr.h"
   #include "upnputils.h"
   #ifdef USE_IFACEWATCHER
   #include "ifacewatcher.h"
   #endif
   
 #ifndef DEFAULT_CONFIG  #ifndef DEFAULT_CONFIG
 #define DEFAULT_CONFIG "/etc/miniupnpd.conf"  #define DEFAULT_CONFIG "/etc/miniupnpd.conf"
Line 81  static struct nfq_handle *nfqHandle; Line 85  static struct nfq_handle *nfqHandle;
 static struct sockaddr_in ssdp;  static struct sockaddr_in ssdp;
   
 /* prototypes */  /* prototypes */
 void ProcessSSDPData(int s, char *bufr, struct sockaddr_in sendername, int n, unsigned short port);  
 static int nfqueue_cb( struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) ;  static int nfqueue_cb( struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) ;
 int identify_ip_protocol (char *payload);  int identify_ip_protocol (char *payload);
 int get_udp_dst_port (char *payload);  int get_udp_dst_port (char *payload);
 #endif  #endif
   
/* variables used by signals */
static int sudp = -1; 
 
/* MAX_LAN_ADDR : maximum number of interfaces 
 * to listen to SSDP traffic */ 
/*#define MAX_LAN_ADDR (4)*/ 
 
 static volatile int quitting = 0;  static volatile int quitting = 0;
static volatile int should_send_public_address_change_notif = 0;volatile int should_send_public_address_change_notif = 0;
   
 /* OpenAndConfHTTPSocket() :  /* OpenAndConfHTTPSocket() :
  * setup the socket used to handle incoming HTTP connections. */   * setup the socket used to handle incoming HTTP connections. */
Line 104  OpenAndConfHTTPSocket(unsigned short port) Line 101  OpenAndConfHTTPSocket(unsigned short port)
 {  {
         int s;          int s;
         int i = 1;          int i = 1;
   #ifdef ENABLE_IPV6
           struct sockaddr_in6 listenname;
   #else
         struct sockaddr_in listenname;          struct sockaddr_in listenname;
   #endif
           socklen_t listenname_len;
   
        if( (s = socket(PF_INET, SOCK_STREAM, 0)) < 0)        if( (s = socket(
 #ifdef ENABLE_IPV6
                         PF_INET6,
 #else
                         PF_INET,
 #endif
                         SOCK_STREAM, 0)) < 0)
         {          {
                 syslog(LOG_ERR, "socket(http): %m");                  syslog(LOG_ERR, "socket(http): %m");
                 return -1;                  return -1;
Line 116  OpenAndConfHTTPSocket(unsigned short port) Line 124  OpenAndConfHTTPSocket(unsigned short port)
         {          {
                 syslog(LOG_WARNING, "setsockopt(http, SO_REUSEADDR): %m");                  syslog(LOG_WARNING, "setsockopt(http, SO_REUSEADDR): %m");
         }          }
   #if 0
           /* enable this to force IPV6 only for IPV6 socket.
            * see http://www.ietf.org/rfc/rfc3493.txt section 5.3 */
           if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &i, sizeof(i)) < 0)
           {
                   syslog(LOG_WARNING, "setsockopt(http, IPV6_V6ONLY): %m");
           }
   #endif
   
        memset(&listenname, 0, sizeof(struct sockaddr_in));#ifdef ENABLE_IPV6
         memset(&listenname, 0, sizeof(struct sockaddr_in6));
         listenname.sin6_family = AF_INET6;
         listenname.sin6_port = htons(port);
         listenname.sin6_addr = in6addr_any;
         listenname_len =  sizeof(struct sockaddr_in6);
 #else
         listenname.sin_family = AF_INET;          listenname.sin_family = AF_INET;
         listenname.sin_port = htons(port);          listenname.sin_port = htons(port);
         listenname.sin_addr.s_addr = htonl(INADDR_ANY);          listenname.sin_addr.s_addr = htonl(INADDR_ANY);
           listenname_len =  sizeof(struct sockaddr_in);
   #endif
   
        if(bind(s, (struct sockaddr *)&listenname, sizeof(struct sockaddr_in)) < 0)        if(bind(s, (struct sockaddr *)&listenname, listenname_len) < 0)
         {          {
                 syslog(LOG_ERR, "bind(http): %m");                  syslog(LOG_ERR, "bind(http): %m");
                 close(s);                  close(s);
                 return -1;                  return -1;
         }          }
   
        if(listen(s, 6) < 0)        if(listen(s, 5) < 0)
         {          {
                 syslog(LOG_ERR, "listen(http): %m");                  syslog(LOG_ERR, "listen(http): %m");
                 close(s);                  close(s);
Line 255  static int nfqueue_cb( Line 279  static int nfqueue_cb(
                                         sendername.sin_addr.s_addr = iph->ip_src.s_addr;                                          sendername.sin_addr.s_addr = iph->ip_src.s_addr;
   
                                         /* printf("pkt found %s\n",dd);*/                                          /* printf("pkt found %s\n",dd);*/
                                        ProcessSSDPData (sudp, dd, sendername, size - x, (unsigned short) 5555);                                        ProcessSSDPData (sudp, dd, size - x,
                                                          &sendername, (unsigned short) 5555);
                                 }                                  }
                         }                          }
                 }                  }
Line 472  set_startup_time(int sysuptime) Line 497  set_startup_time(int sysuptime)
 struct runtime_vars {  struct runtime_vars {
         /* LAN IP addresses for SSDP traffic and HTTP */          /* LAN IP addresses for SSDP traffic and HTTP */
         /* moved to global vars */          /* moved to global vars */
         /*int n_lan_addr;*/  
         /*struct lan_addr_s lan_addr[MAX_LAN_ADDR];*/  
         int port;       /* HTTP Port */          int port;       /* HTTP Port */
         int notify_interval;    /* seconds between SSDP announces */          int notify_interval;    /* seconds between SSDP announces */
         /* unused rules cleaning related variables : */          /* unused rules cleaning related variables : */
Line 563  init(int argc, char * * argv, struct runtime_vars * v) Line 586  init(int argc, char * * argv, struct runtime_vars * v)
         /*const char * logfilename = 0;*/          /*const char * logfilename = 0;*/
         const char * presurl = 0;          const char * presurl = 0;
         const char * optionsfile = DEFAULT_CONFIG;          const char * optionsfile = DEFAULT_CONFIG;
           struct lan_addr_s * lan_addr;
           struct lan_addr_s * lan_addr2;
   
         /* only print usage if -h is used */          /* only print usage if -h is used */
         for(i=1; i<argc; i++)          for(i=1; i<argc; i++)
Line 584  init(int argc, char * * argv, struct runtime_vars * v) Line 609  init(int argc, char * * argv, struct runtime_vars * v)
         /* set initial values */          /* set initial values */
         SETFLAG(ENABLEUPNPMASK);          SETFLAG(ENABLEUPNPMASK);
   
        /*v->n_lan_addr = 0;*/        LIST_INIT(&lan_addrs);
         v->port = -1;          v->port = -1;
         v->notify_interval = 30;        /* seconds between SSDP announces */          v->notify_interval = 30;        /* seconds between SSDP announces */
         v->clean_ruleset_threshold = 20;          v->clean_ruleset_threshold = 20;
Line 611  init(int argc, char * * argv, struct runtime_vars * v) Line 636  init(int argc, char * * argv, struct runtime_vars * v)
                                 use_ext_ip_addr = ary_options[i].value;                                  use_ext_ip_addr = ary_options[i].value;
                                 break;                                  break;
                         case UPNPLISTENING_IP:                          case UPNPLISTENING_IP:
                                if(n_lan_addr < MAX_LAN_ADDR)/* if(v->n_lan_addr < MAX_LAN_ADDR)*/                                lan_addr = (struct lan_addr_s *) malloc(sizeof(struct lan_addr_s));
                                 if (lan_addr == NULL)
                                 {                                  {
                                        /*if(parselanaddr(&v->lan_addr[v->n_lan_addr],*/                                        fprintf(stderr, "malloc(sizeof(struct lan_addr_s)): %m");
                                        if(parselanaddr(&lan_addr[n_lan_addr],                                        break;
                                                     ary_options[i].value) == 0) 
                                                n_lan_addr++; /*v->n_lan_addr++; */ 
                                 }                                  }
                                else                                if(parselanaddr(lan_addr, ary_options[i].value) != 0)
                                 {                                  {
                                        fprintf(stderr, "Too many listening ips (max: %d), ignoring %s\n",                                        fprintf(stderr, "can't parse \"%s\" as valid lan address\n", ary_options[i].value);
                                            MAX_LAN_ADDR, ary_options[i].value);                                        free(lan_addr);
                                         break;
                                 }                                  }
                                   LIST_INSERT_HEAD(&lan_addrs, lan_addr, list);
                                 break;                                  break;
                         case UPNPPORT:                          case UPNPPORT:
                                 v->port = atoi(ary_options[i].value);                                  v->port = atoi(ary_options[i].value);
Line 856  init(int argc, char * * argv, struct runtime_vars * v) Line 882  init(int argc, char * * argv, struct runtime_vars * v)
                 case 'a':                  case 'a':
                         if(i+1 < argc)                          if(i+1 < argc)
                         {                          {
                                 int address_already_there = 0;  
                                 int j;  
                                 i++;                                  i++;
                                for(j=0; j<n_lan_addr; j++)                                lan_addr = (struct lan_addr_s *) malloc(sizeof(struct lan_addr_s));
                                 if (lan_addr == NULL)
                                 {                                  {
                                        struct lan_addr_s tmpaddr;                                        fprintf(stderr, "malloc(sizeof(struct lan_addr_s)): %m");
                                        parselanaddr(&tmpaddr, argv[i]); 
                                        if(0 == strcmp(lan_addr[j].str, tmpaddr.str)) 
                                                address_already_there = 1; 
                                } 
                                if(address_already_there) 
                                         break;                                          break;
                                if(n_lan_addr < MAX_LAN_ADDR)                                }
                                 if(parselanaddr(lan_addr, argv[i]) != 0)
                                 {                                  {
                                        if(parselanaddr(&lan_addr[n_lan_addr], argv[i]) == 0)                                        fprintf(stderr, "can't parse \"%s\" as valid lan address\n", argv[i]);
                                                n_lan_addr++;                                        free(lan_addr);
                                         break;
                                 }                                  }
                                else                                /* check if we already have this address */
                                 for(lan_addr2 = lan_addrs.lh_first; lan_addr2 != NULL; lan_addr2 = lan_addr2->list.le_next)
                                 {                                  {
                                        fprintf(stderr, "Too many listening ips (max: %d), ignoring %s\n",                                        if (0 == strncmp(lan_addr2->str, lan_addr->str, 15))
                                            MAX_LAN_ADDR, argv[i]);                                                break;
                                 }                                  }
                                   if (lan_addr2 == NULL)
                                           LIST_INSERT_HEAD(&lan_addrs, lan_addr, list);
                         }                          }
                         else                          else
                                 fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);                                  fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
Line 889  init(int argc, char * * argv, struct runtime_vars * v) Line 914  init(int argc, char * * argv, struct runtime_vars * v)
                         fprintf(stderr, "Unknown option: %s\n", argv[i]);                          fprintf(stderr, "Unknown option: %s\n", argv[i]);
                 }                  }
         }          }
        if(!ext_if_name || (n_lan_addr==0))        if(!ext_if_name || !lan_addrs.lh_first)
         {          {
                 /* bad configuration */                  /* bad configuration */
                 goto print_usage;                  goto print_usage;
Line 942  init(int argc, char * * argv, struct runtime_vars * v) Line 967  init(int argc, char * * argv, struct runtime_vars * v)
         else          else
         {          {
                 snprintf(presentationurl, PRESENTATIONURL_MAX_LEN,                  snprintf(presentationurl, PRESENTATIONURL_MAX_LEN,
                         "http://%s/", lan_addr[0].str);                         "http://%s/", lan_addrs.lh_first->str);
                         /*"http://%s:%d/", lan_addr[0].str, 80);*/                         /*"http://%s:%d/", lan_addrs.lh_first->str, 80);*/
         }          }
   
         /* set signal handler */          /* set signal handler */
Line 1037  int Line 1062  int
 main(int argc, char * * argv)  main(int argc, char * * argv)
 {  {
         int i;          int i;
        int shttpl = -1;        int shttpl = -1;        /* socket for HTTP */
         int sudp = -1;          /* IP v4 socket for receiving SSDP */
 #ifdef ENABLE_IPV6
         int sudpv6 = -1;        /* IP v6 socket for receiving SSDP */
 #endif
 #ifdef ENABLE_NATPMP  #ifdef ENABLE_NATPMP
        int snatpmp[MAX_LAN_ADDR];        int * snatpmp;
 #endif
 #ifdef ENABLE_NFQUEUE  #ifdef ENABLE_NFQUEUE
         int nfqh = -1;          int nfqh = -1;
 #endif  #endif
   #ifdef USE_IFACEWATCHER
           int sifacewatcher = -1;
 #endif  #endif
        int snotify[MAX_LAN_ADDR];
         int * snotify;
         int addr_count;
         LIST_HEAD(httplisthead, upnphttp) upnphttphead;          LIST_HEAD(httplisthead, upnphttp) upnphttphead;
         struct upnphttp * e = 0;          struct upnphttp * e = 0;
         struct upnphttp * next;          struct upnphttp * next;
Line 1064  main(int argc, char * * argv) Line 1098  main(int argc, char * * argv)
         /* variables used for the unused-rule cleanup process */          /* variables used for the unused-rule cleanup process */
         struct rule_state * rule_list = 0;          struct rule_state * rule_list = 0;
         struct timeval checktime = {0, 0};          struct timeval checktime = {0, 0};
           struct lan_addr_s * lan_addr;
         syslog(LOG_INFO, "SNet version started");          syslog(LOG_INFO, "SNet version started");
   
        if(init(argc, argv, &v) != 0)
                 return 1;
         /* count lan addrs */
         addr_count = 0;
         for(lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next)
                 addr_count++;
         snotify = (int*) malloc(addr_count * sizeof(int));
         memset(snotify, 0, sizeof(snotify));          memset(snotify, 0, sizeof(snotify));
 #ifdef ENABLE_NATPMP  #ifdef ENABLE_NATPMP
        for(i = 0; i < MAX_LAN_ADDR; i++)        snatpmp = (int*) malloc(addr_count * sizeof(int));
         for(i = 0; i < addr_count; i++)
                 snatpmp[i] = -1;                  snatpmp[i] = -1;
 #endif  #endif
         if(init(argc, argv, &v) != 0)  
                 return 1;  
   
         LIST_INIT(&upnphttphead);          LIST_INIT(&upnphttphead);
 #ifdef USE_MINIUPNPDCTL  #ifdef USE_MINIUPNPDCTL
Line 1109  main(int argc, char * * argv) Line 1149  main(int argc, char * * argv)
                         v.port = ntohs(sockinfo.sin_port);                          v.port = ntohs(sockinfo.sin_port);
                 }                  }
                 syslog(LOG_NOTICE, "HTTP listening on port %d", v.port);                  syslog(LOG_NOTICE, "HTTP listening on port %d", v.port);
   #ifdef ENABLE_IPV6
                   if(find_ipv6_addr(NULL, ipv6_addr_for_http_with_brackets, sizeof(ipv6_addr_for_http_with_brackets)) > 0) {
                           syslog(LOG_NOTICE, "HTTP IPv6 address given to control points : %s",
                                  ipv6_addr_for_http_with_brackets);
                   } else {
                           memcpy(ipv6_addr_for_http_with_brackets, "[::1]", 6);
                           syslog(LOG_WARNING, "no HTTP IPv6 address");
                   }
   #endif
   
                 /* open socket for SSDP connections */                  /* open socket for SSDP connections */
                sudp = OpenAndConfSSDPReceiveSocket(n_lan_addr, lan_addr);                sudp = OpenAndConfSSDPReceiveSocket(0);
                 if(sudp < 0)                  if(sudp < 0)
                 {                  {
                         syslog(LOG_INFO, "Failed to open socket for receiving SSDP. Trying to use MiniSSDPd");                          syslog(LOG_INFO, "Failed to open socket for receiving SSDP. Trying to use MiniSSDPd");
                        if(SubmitServicesToMiniSSDPD(lan_addr[0].str, v.port) < 0) {                        if(SubmitServicesToMiniSSDPD(lan_addrs.lh_first->str, v.port) < 0) {
                                 syslog(LOG_ERR, "Failed to connect to MiniSSDPd. EXITING");                                  syslog(LOG_ERR, "Failed to connect to MiniSSDPd. EXITING");
                                 return 1;                                  return 1;
                         }                          }
                 }                  }
   #ifdef ENABLE_IPV6
                   sudpv6 = OpenAndConfSSDPReceiveSocket(1);
                   if(sudpv6 < 0)
                   {
                           syslog(LOG_INFO, "Failed to open socket for receiving SSDP (IP v6).");
                   }
   #endif
   
                 /* open socket for sending notifications */                  /* open socket for sending notifications */
                 if(OpenAndConfSSDPNotifySockets(snotify) < 0)                  if(OpenAndConfSSDPNotifySockets(snotify) < 0)
Line 1128  main(int argc, char * * argv) Line 1184  main(int argc, char * * argv)
                                 "messages. EXITING");                                  "messages. EXITING");
                         return 1;                          return 1;
                 }                  }
   
   #ifdef USE_IFACEWATCHER
                   /* open socket for kernel notifications about new network interfaces */
                   if (sudp >= 0)
                   {
                           sifacewatcher = OpenAndConfInterfaceWatchSocket();
                           if (sifacewatcher < 0)
                           {
                                   syslog(LOG_ERR, "Failed to open socket for receiving network interface notifications");
                           }
                   }
   #endif
         }          }
   
 #ifdef ENABLE_NATPMP  #ifdef ENABLE_NATPMP
Line 1141  main(int argc, char * * argv) Line 1209  main(int argc, char * * argv)
                         syslog(LOG_NOTICE, "Listening for NAT-PMP traffic on port %u",                          syslog(LOG_NOTICE, "Listening for NAT-PMP traffic on port %u",
                                NATPMP_PORT);                                 NATPMP_PORT);
                 }                  }
   #if 0
                 ScanNATPMPforExpiration();                  ScanNATPMPforExpiration();
   #endif
         }          }
 #endif  #endif
   
Line 1169  main(int argc, char * * argv) Line 1239  main(int argc, char * * argv)
                 {                  {
                         set_startup_time(GETFLAG(SYSUPTIMEMASK));                          set_startup_time(GETFLAG(SYSUPTIMEMASK));
                 }                   } 
                   /* send public address change notifications if needed */
                   if(should_send_public_address_change_notif)
                   {
                           syslog(LOG_DEBUG, "should send external iface address change notification(s)");
   #ifdef ENABLE_NATPMP
                           if(GETFLAG(ENABLENATPMPMASK))
                                   SendNATPMPPublicAddressChangeNotification(snatpmp, addr_count);
   #endif
   #ifdef ENABLE_EVENTS
                           if(GETFLAG(ENABLEUPNPMASK))
                           {
                                   upnp_event_var_change_notify(EWanIPC);
                           }
   #endif
                           should_send_public_address_change_notif = 0;
                   }
                 /* Check if we need to send SSDP NOTIFY messages and do it if                  /* Check if we need to send SSDP NOTIFY messages and do it if
                  * needed */                   * needed */
                 if(gettimeofday(&timeofday, 0) < 0)                  if(gettimeofday(&timeofday, 0) < 0)
Line 1221  main(int argc, char * * argv) Line 1307  main(int argc, char * * argv)
                         }                          }
                         memcpy(&checktime, &timeofday, sizeof(struct timeval));                          memcpy(&checktime, &timeofday, sizeof(struct timeval));
                 }                  }
                   /* Remove expired port mappings, based on UPnP IGD LeaseDuration
                    * or NAT-PMP lifetime) */
                   if(nextruletoclean_timestamp
                     && (timeofday.tv_sec >= nextruletoclean_timestamp))
                   {
                           syslog(LOG_DEBUG, "cleaning expired Port Mappings");
                           get_upnp_rules_state_list(0);
                   }
                   if(nextruletoclean_timestamp
                     && timeout.tv_sec >= (nextruletoclean_timestamp - timeofday.tv_sec))
                   {
                           timeout.tv_sec = nextruletoclean_timestamp - timeofday.tv_sec;
                           timeout.tv_usec = 0;
                           syslog(LOG_DEBUG, "setting timeout to %u sec",
                                  (unsigned)timeout.tv_sec);
                   }
 #ifdef ENABLE_NATPMP  #ifdef ENABLE_NATPMP
   #if 0
                 /* Remove expired NAT-PMP mappings */                  /* Remove expired NAT-PMP mappings */
                while( nextnatpmptoclean_timestamp && (timeofday.tv_sec >= nextnatpmptoclean_timestamp + startup_time))                while(nextnatpmptoclean_timestamp
                      && (timeofday.tv_sec >= nextnatpmptoclean_timestamp + startup_time))
                 {                  {
                         /*syslog(LOG_DEBUG, "cleaning expired NAT-PMP mappings");*/                          /*syslog(LOG_DEBUG, "cleaning expired NAT-PMP mappings");*/
                         if(CleanExpiredNATPMP() < 0) {                          if(CleanExpiredNATPMP() < 0) {
Line 1231  main(int argc, char * * argv) Line 1335  main(int argc, char * * argv)
                                 break;                                  break;
                         }                          }
                 }                  }
                if(nextnatpmptoclean_timestamp && timeout.tv_sec >= (nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec))                if(nextnatpmptoclean_timestamp
                   && timeout.tv_sec >= (nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec))
                 {                  {
                        /*syslog(LOG_DEBUG, "setting timeout to %d sec", nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec);*/                        /*syslog(LOG_DEBUG, "setting timeout to %d sec",
#ifdef ENABLE_NFQUEUE                               nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec);*/
                if (nfqh >= 0)  
                { 
                        FD_SET(nfqh, &readset); 
                        max_fd = MAX( max_fd, nfqh); 
                } 
#endif 
 
                         timeout.tv_sec = nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec;                          timeout.tv_sec = nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec;
                         timeout.tv_usec = 0;                          timeout.tv_usec = 0;
                 }                  }
 #endif  #endif
   #endif
   
                 /* select open sockets (SSDP, HTTP listen, and all HTTP soap sockets) */                  /* select open sockets (SSDP, HTTP listen, and all HTTP soap sockets) */
                 FD_ZERO(&readset);                  FD_ZERO(&readset);
Line 1254  main(int argc, char * * argv) Line 1353  main(int argc, char * * argv)
                 {                  {
                         FD_SET(sudp, &readset);                          FD_SET(sudp, &readset);
                         max_fd = MAX( max_fd, sudp);                          max_fd = MAX( max_fd, sudp);
   #ifdef USE_IFACEWATCHER
                           if (sifacewatcher >= 0)
                           {
                                   FD_SET(sifacewatcher, &readset);
                                   max_fd = MAX(max_fd, sifacewatcher);
                           }
   #endif
                 }                  }
                   
                 if (shttpl >= 0)                   if (shttpl >= 0) 
                 {                  {
                         FD_SET(shttpl, &readset);                          FD_SET(shttpl, &readset);
                         max_fd = MAX( max_fd, shttpl);                          max_fd = MAX( max_fd, shttpl);
                 }                  }
   #ifdef ENABLE_IPV6
                   if (sudpv6 >= 0)
                   {
                           FD_SET(sudpv6, &readset);
                           max_fd = MAX( max_fd, sudpv6);
                   }
   #endif
   
   #ifdef ENABLE_NFQUEUE
                   if (nfqh >= 0) 
                   {
                           FD_SET(nfqh, &readset);
                           max_fd = MAX( max_fd, nfqh);
                   }
   #endif
   
                 i = 0;  /* active HTTP connections count */                  i = 0;  /* active HTTP connections count */
                 for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next)                  for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next)
                 {                  {
Line 1280  main(int argc, char * * argv) Line 1400  main(int argc, char * * argv)
                 }                  }
 #endif  #endif
 #ifdef ENABLE_NATPMP  #ifdef ENABLE_NATPMP
                for(i=0; i<n_lan_addr; i++) {                for(i=0; i<addr_count; i++) {
                         if(snatpmp[i] >= 0) {                          if(snatpmp[i] >= 0) {
                                 FD_SET(snatpmp[i], &readset);                                  FD_SET(snatpmp[i], &readset);
                                 max_fd = MAX( max_fd, snatpmp[i]);                                  max_fd = MAX( max_fd, snatpmp[i]);
Line 1377  main(int argc, char * * argv) Line 1497  main(int argc, char * * argv)
 #endif  #endif
 #ifdef ENABLE_NATPMP  #ifdef ENABLE_NATPMP
                 /* process NAT-PMP packets */                  /* process NAT-PMP packets */
                for(i=0; i<n_lan_addr; i++)                for(i=0; i<addr_count; i++)
                 {                  {
                         if((snatpmp[i] >= 0) && FD_ISSET(snatpmp[i], &readset))                          if((snatpmp[i] >= 0) && FD_ISSET(snatpmp[i], &readset))
                         {                          {
Line 1391  main(int argc, char * * argv) Line 1511  main(int argc, char * * argv)
                         /*syslog(LOG_INFO, "Received UDP Packet");*/                          /*syslog(LOG_INFO, "Received UDP Packet");*/
                         ProcessSSDPRequest(sudp, (unsigned short)v.port);                          ProcessSSDPRequest(sudp, (unsigned short)v.port);
                 }                  }
   #ifdef ENABLE_IPV6
                   if(sudpv6 >= 0 && FD_ISSET(sudpv6, &readset))
                   {
                           syslog(LOG_INFO, "Received UDP Packet (IPv6)");
                           ProcessSSDPRequest(sudpv6, (unsigned short)v.port);
                   }
   #endif
   #ifdef USE_IFACEWATCHER
                   /* process kernel notifications */
                   if (sifacewatcher >= 0 && FD_ISSET(sifacewatcher, &readset))
                           ProcessInterfaceWatchNotify(sifacewatcher);
   #endif
   
                 /* process active HTTP connections */                  /* process active HTTP connections */
                 /* LIST_FOREACH macro is not available under linux */                  /* LIST_FOREACH macro is not available under linux */
                 for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next)                  for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next)
Line 1406  main(int argc, char * * argv) Line 1539  main(int argc, char * * argv)
                 {                  {
                         int shttp;                          int shttp;
                         socklen_t clientnamelen;                          socklen_t clientnamelen;
   #ifdef ENABLE_IPV6
                           struct sockaddr_storage clientname;
                           clientnamelen = sizeof(struct sockaddr_storage);
   #else
                         struct sockaddr_in clientname;                          struct sockaddr_in clientname;
                         clientnamelen = sizeof(struct sockaddr_in);                          clientnamelen = sizeof(struct sockaddr_in);
   #endif
                         shttp = accept(shttpl, (struct sockaddr *)&clientname, &clientnamelen);                          shttp = accept(shttpl, (struct sockaddr *)&clientname, &clientnamelen);
                         if(shttp<0)                          if(shttp<0)
                         {                          {
Line 1416  main(int argc, char * * argv) Line 1554  main(int argc, char * * argv)
                         else                          else
                         {                          {
                                 struct upnphttp * tmp = 0;                                  struct upnphttp * tmp = 0;
                                syslog(LOG_INFO, "HTTP connection from %s:%d",                                char addr_str[64];
                                        inet_ntoa(clientname.sin_addr),
                                        ntohs(clientname.sin_port) );                                sockaddr_to_string((struct sockaddr *)&clientname, addr_str, sizeof(addr_str));
                                 syslog(LOG_INFO, "HTTP connection from %s", addr_str);
                                 /*if (fcntl(shttp, F_SETFL, O_NONBLOCK) < 0) {                                  /*if (fcntl(shttp, F_SETFL, O_NONBLOCK) < 0) {
                                         syslog(LOG_ERR, "fcntl F_SETFL, O_NONBLOCK");                                          syslog(LOG_ERR, "fcntl F_SETFL, O_NONBLOCK");
                                 }*/                                  }*/
 #ifdef ENABLE_NFQUEUE  
                 /* process NFQ packets */  
                 if(nfqh >= 0 && FD_ISSET(nfqh, &readset))  
                 {  
                         /* syslog(LOG_INFO, "Received NFQUEUE Packet");*/  
                         ProcessNFQUEUE(nfqh);  
                 }  
 #endif  
                                 /* Create a new upnphttp object and add it to                                  /* Create a new upnphttp object and add it to
                                  * the active upnphttp object list */                                   * the active upnphttp object list */
                                 tmp = New_upnphttp(shttp);                                  tmp = New_upnphttp(shttp);
                                 if(tmp)                                  if(tmp)
                                 {                                  {
   #ifdef ENABLE_IPV6
                                           if(clientname.ss_family == AF_INET)
                                           {
                                                   tmp->clientaddr = ((struct sockaddr_in *)&clientname)->sin_addr;
                                           }
                                           else if(clientname.ss_family == AF_INET6)
                                           {
                                                   struct sockaddr_in6 * addr = (struct sockaddr_in6 *)&clientname;
                                                   if(IN6_IS_ADDR_V4MAPPED(&addr->sin6_addr))
                                                   {
                                                           memcpy(&tmp->clientaddr,
                                                                  &addr->sin6_addr.s6_addr[12],
                                                                  4);
                                                   }
                                                   else
                                                   {
                                                           tmp->ipv6 = 1;
                                                           memcpy(&tmp->clientaddr_v6,
                                                                  &addr->sin6_addr,
                                                                  sizeof(struct in6_addr));
                                                   }
                                           }
   #else
                                         tmp->clientaddr = clientname.sin_addr;                                          tmp->clientaddr = clientname.sin_addr;
   #endif
                                         LIST_INSERT_HEAD(&upnphttphead, tmp, entries);                                          LIST_INSERT_HEAD(&upnphttphead, tmp, entries);
                                 }                                  }
                                 else                                  else
Line 1445  main(int argc, char * * argv) Line 1600  main(int argc, char * * argv)
                                 }                                  }
                         }                          }
                 }                  }
   #ifdef ENABLE_NFQUEUE
                   /* process NFQ packets */
                   if(nfqh >= 0 && FD_ISSET(nfqh, &readset))
                   {
                           /* syslog(LOG_INFO, "Received NFQUEUE Packet");*/
                           ProcessNFQUEUE(nfqh);
                   }
   #endif
                 /* delete finished HTTP connections */                  /* delete finished HTTP connections */
                 for(e = upnphttphead.lh_first; e != NULL; )                  for(e = upnphttphead.lh_first; e != NULL; )
                 {                  {
Line 1457  main(int argc, char * * argv) Line 1620  main(int argc, char * * argv)
                         e = next;                          e = next;
                 }                  }
   
                 /* send public address change notifications */  
                 if(should_send_public_address_change_notif)  
                 {  
 #ifdef ENABLE_NATPMP  
                         if(GETFLAG(ENABLENATPMPMASK))  
                                 SendNATPMPPublicAddressChangeNotification(snatpmp/*snotify*/, n_lan_addr);  
 #endif  
 #ifdef ENABLE_EVENTS  
                         if(GETFLAG(ENABLEUPNPMASK))  
                         {  
                                 upnp_event_var_change_notify(EWanIPC);  
                         }  
 #endif  
                         should_send_public_address_change_notif = 0;  
                 }  
         }       /* end of main loop */          }       /* end of main loop */
   
 shutdown:  shutdown:
Line 1485  shutdown: Line 1633  shutdown:
   
         if (sudp >= 0) close(sudp);          if (sudp >= 0) close(sudp);
         if (shttpl >= 0) close(shttpl);          if (shttpl >= 0) close(shttpl);
   #ifdef ENABLE_IPV6
           if (sudpv6 >= 0) close(sudpv6);
           //if (shttplv6 >= 0) close(shttplv6);
   #endif
   #ifdef USE_IFACEWATCHER
           if(sifacewatcher >= 0) close(sifacewatcher);
   #endif
 #ifdef ENABLE_NATPMP  #ifdef ENABLE_NATPMP
        for(i=0; i<n_lan_addr; i++) {        for(i=0; i<addr_count; i++) {
                 if(snatpmp[i]>=0)                  if(snatpmp[i]>=0)
                 {                  {
                         close(snatpmp[i]);                          close(snatpmp[i]);
Line 1509  shutdown: Line 1664  shutdown:
         /*if(SendSSDPGoodbye(snotify, v.n_lan_addr) < 0)*/          /*if(SendSSDPGoodbye(snotify, v.n_lan_addr) < 0)*/
         if (GETFLAG(ENABLEUPNPMASK))          if (GETFLAG(ENABLEUPNPMASK))
         {          {
                if(SendSSDPGoodbye(snotify, n_lan_addr) < 0)                if(SendSSDPGoodbye(snotify, addr_count) < 0)
                 {                  {
                         syslog(LOG_ERR, "Failed to broadcast good-bye notifications");                          syslog(LOG_ERR, "Failed to broadcast good-bye notifications");
                 }                  }
                for(i=0; i<n_lan_addr; i++)/* for(i=0; i<v.n_lan_addr; i++)*/                for(i=0; i<addr_count; i++)
                         close(snotify[i]);                          close(snotify[i]);
         }          }
   
Line 1522  shutdown: Line 1677  shutdown:
                 syslog(LOG_ERR, "Failed to remove pidfile %s: %m", pidfilename);                  syslog(LOG_ERR, "Failed to remove pidfile %s: %m", pidfilename);
         }          }
   
           /* delete lists */
           while(lan_addrs.lh_first != NULL)
           {
                   lan_addr = lan_addrs.lh_first;
                   LIST_REMOVE(lan_addrs.lh_first, list);
                   free(lan_addr);
           }
   
   #ifdef ENABLE_NATPMP
           free(snatpmp);
   #endif
           free(snotify);
         closelog();               closelog();     
         freeoptions();          freeoptions();
                   

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


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