igmpproxy: Update to 0.2.1
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 11 May 2019 01:20:15 +0000 (02:20 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 11 May 2019 01:20:15 +0000 (02:20 +0100)
This updates the package to its latest upstream version and should
be able to support IGMPv3.

Fixes: #12074
Suggested-by: Marc Roland <marc.roland@outlook.com>
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
lfs/igmpproxy
src/patches/igmpproxy-001-Send-IGMP-packets-with-IP-Router-Alert-option-RFC-21.patch [deleted file]
src/patches/igmpproxy-002-Change-default-interface-state-to-disabled-wrt-29458.patch [deleted file]
src/patches/igmpproxy-003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch [deleted file]
src/patches/igmpproxy-004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch [deleted file]
src/patches/igmpproxy-100-use-monotic-clock-instead-of-time-of-day.patch [deleted file]

index 53e4a8f..e1a1ae0 100644 (file)
@@ -24,7 +24,7 @@
 
 include Config
 
-VER        = 0.1
+VER        = 0.2.1
 
 THISAPP    = igmpproxy-$(VER)
 DL_FILE    = $(THISAPP).tar.gz
@@ -32,7 +32,7 @@ DL_FROM    = $(URL_IPFIRE)
 DIR_APP    = $(DIR_SRC)/$(THISAPP)
 TARGET     = $(DIR_INFO)/$(THISAPP)
 PROG       = igmpproxy
-PAK_VER    = 4
+PAK_VER    = 5
 
 DEPS       = ""
 
@@ -44,7 +44,7 @@ objects = $(DL_FILE)
 
 $(DL_FILE) = $(DL_FROM)/$(DL_FILE)
 
-$(DL_FILE)_MD5 = c56f41ec195bc1fe016369bf74efc5a1
+$(DL_FILE)_MD5 = 3a9c2cb42c1f5ee0cb769a4884545641
 
 install : $(TARGET)
 
@@ -77,13 +77,6 @@ $(subst %,%_MD5,$(objects)) :
 $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
        @$(PREBUILD)
        @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
-       cd $(DIR_APP) && patch -Np1  < $(DIR_SRC)/src/patches/igmpproxy-001-Send-IGMP-packets-with-IP-Router-Alert-option-RFC-21.patch
-       cd $(DIR_APP) && patch -Np1  < $(DIR_SRC)/src/patches/igmpproxy-002-Change-default-interface-state-to-disabled-wrt-29458.patch
-       cd $(DIR_APP) && patch -Np1  < $(DIR_SRC)/src/patches/igmpproxy-003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch
-       cd $(DIR_APP) && patch -Np1  < $(DIR_SRC)/src/patches/igmpproxy-004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch
-       cd $(DIR_APP) && patch -Np1  < $(DIR_SRC)/src/patches/igmpproxy-100-use-monotic-clock-instead-of-time-of-day.patch
-       cd $(DIR_APP) && aclocal && automake --add-missing && autoreconf
-       $(UPDATE_AUTOMAKE)
        cd $(DIR_APP) && ./configure --prefix=/usr --sysconfdir=/etc
        cd $(DIR_APP) && make $(MAKETUNING)
        cd $(DIR_APP) && make install
diff --git a/src/patches/igmpproxy-001-Send-IGMP-packets-with-IP-Router-Alert-option-RFC-21.patch b/src/patches/igmpproxy-001-Send-IGMP-packets-with-IP-Router-Alert-option-RFC-21.patch
deleted file mode 100644 (file)
index ffe1cf1..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From fed8c3db10bc9d3a1e799a774924c00522595d0c Mon Sep 17 00:00:00 2001
-From: Evgeny Yurchenko <evg.yurch@rogers.com>
-Date: Mon, 4 Jan 2010 05:13:59 +0500
-Subject: [PATCH] Send IGMP packets with IP Router Alert option [RFC 2113] included in IP header
-
----
- src/igmp.c      |   17 ++++++++++++-----
- src/igmpproxy.h |    1 +
- 2 files changed, 13 insertions(+), 5 deletions(-)
-
-diff --git a/src/igmp.c b/src/igmp.c
-index a0cd27d..b547688 100644
---- a/src/igmp.c
-+++ b/src/igmp.c
-@@ -67,7 +67,7 @@ void initIgmp() {
-      * - Checksum (let the kernel fill it in)
-      */
-     ip->ip_v   = IPVERSION;
--    ip->ip_hl  = sizeof(struct ip) >> 2;
-+    ip->ip_hl  = (sizeof(struct ip) + 4) >> 2; /* +4 for Router Alert option */
-     ip->ip_tos = 0xc0;      /* Internet Control */
-     ip->ip_ttl = MAXTTL;    /* applies to unicasts only */
-     ip->ip_p   = IPPROTO_IGMP;
-@@ -213,7 +213,7 @@ void buildIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, i
-     ip                      = (struct ip *)send_buf;
-     ip->ip_src.s_addr       = src;
-     ip->ip_dst.s_addr       = dst;
--    ip_set_len(ip, MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen);
-+    ip_set_len(ip, IP_HEADER_RAOPT_LEN + IGMP_MINLEN + datalen);
-     if (IN_MULTICAST(ntohl(dst))) {
-         ip->ip_ttl = curttl;
-@@ -221,13 +221,20 @@ void buildIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, i
-         ip->ip_ttl = MAXTTL;
-     }
--    igmp                    = (struct igmp *)(send_buf + MIN_IP_HEADER_LEN);
-+    /* Add Router Alert option */
-+    ((u_char*)send_buf+MIN_IP_HEADER_LEN)[0] = IPOPT_RA;
-+    ((u_char*)send_buf+MIN_IP_HEADER_LEN)[1] = 0x04;
-+    ((u_char*)send_buf+MIN_IP_HEADER_LEN)[2] = 0x00;
-+    ((u_char*)send_buf+MIN_IP_HEADER_LEN)[3] = 0x00;
-+
-+    igmp                    = (struct igmp *)(send_buf + IP_HEADER_RAOPT_LEN);
-     igmp->igmp_type         = type;
-     igmp->igmp_code         = code;
-     igmp->igmp_group.s_addr = group;
-     igmp->igmp_cksum        = 0;
-     igmp->igmp_cksum        = inetChksum((u_short *)igmp,
--                                         IGMP_MINLEN + datalen);
-+                                         IP_HEADER_RAOPT_LEN + datalen);
-+
- }
- /* 
-@@ -257,7 +264,7 @@ void sendIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, in
- #endif
-     sdst.sin_addr.s_addr = dst;
-     if (sendto(MRouterFD, send_buf,
--               MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen, 0,
-+               IP_HEADER_RAOPT_LEN + IGMP_MINLEN + datalen, 0,
-                (struct sockaddr *)&sdst, sizeof(sdst)) < 0) {
-         if (errno == ENETDOWN)
-             my_log(LOG_ERR, errno, "Sender VIF was down.");
-diff --git a/src/igmpproxy.h b/src/igmpproxy.h
-index 0de7791..4df8a79 100644
---- a/src/igmpproxy.h
-+++ b/src/igmpproxy.h
-@@ -64,6 +64,7 @@
- #define MAX_IP_PACKET_LEN     576
- #define MIN_IP_HEADER_LEN     20
- #define MAX_IP_HEADER_LEN     60
-+#define IP_HEADER_RAOPT_LEN   24
- #define MAX_MC_VIFS    32     // !!! check this const in the specific includes
--- 
-1.7.2.5
-
diff --git a/src/patches/igmpproxy-002-Change-default-interface-state-to-disabled-wrt-29458.patch b/src/patches/igmpproxy-002-Change-default-interface-state-to-disabled-wrt-29458.patch
deleted file mode 100644 (file)
index d7550d7..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-From 85e240727305b156097ee7aa0f0c4473a136291f Mon Sep 17 00:00:00 2001
-From: Constantin Baranov <const@mimas.ru>
-Date: Tue, 23 Feb 2010 21:08:02 +0400
-Subject: [PATCH] Change default interface state to disabled (wrt #2945877)
-
----
- src/ifvc.c      |    2 +-
- src/igmpproxy.c |    6 ++++--
- 2 files changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/src/ifvc.c b/src/ifvc.c
-index 545b3b4..9d7ee97 100644
---- a/src/ifvc.c
-+++ b/src/ifvc.c
-@@ -139,7 +139,7 @@ void buildIfVc() {
-             IfDescEp->allowednets->subnet_addr = subnet;
-             // Set the default params for the IF...
--            IfDescEp->state         = IF_STATE_DOWNSTREAM;
-+            IfDescEp->state         = IF_STATE_DISABLED;
-             IfDescEp->robustness    = DEFAULT_ROBUSTNESS;
-             IfDescEp->threshold     = DEFAULT_THRESHOLD;   /* ttl limit */
-             IfDescEp->ratelimit     = DEFAULT_RATELIMIT; 
-diff --git a/src/igmpproxy.c b/src/igmpproxy.c
-index 1ece15a..35000c7 100644
---- a/src/igmpproxy.c
-+++ b/src/igmpproxy.c
-@@ -186,8 +186,10 @@ int igmpProxyInit() {
-                     }
-                 }
--                addVIF( Dp );
--                vifcount++;
-+                if (Dp->state != IF_STATE_DISABLED) {
-+                    addVIF( Dp );
-+                    vifcount++;
-+                }
-             }
-         }
--- 
-1.7.2.5
-
diff --git a/src/patches/igmpproxy-003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch b/src/patches/igmpproxy-003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch
deleted file mode 100644 (file)
index 90d4d5f..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-From 65f777e7f66b55239d935c1cf81bb5abc0f6c89f Mon Sep 17 00:00:00 2001
-From: Grinch <grinch79@users.sourceforge.net>
-Date: Sun, 16 Aug 2009 19:58:26 +0500
-Subject: [PATCH] Restrict igmp reports for downstream interfaces (wrt #2833339)
-
-atm all igmp membership reports are forwarded to the upstream interface.
-Unfortunately some ISP Providers restrict some multicast groups (esp. those
-that are defined as local link groups and that are not supposed to be
-forwarded to the wan, i.e 224.0.0.0/24). Therefore there should be some
-kind of black oder whitelisting.
-As whitelisting can be accomplished quite easy I wrote a litte patch, which
-is attached to this request.
----
- doc/igmpproxy.conf.5.in |   19 +++++++++++++++++++
- src/config.c            |   23 ++++++++++++++++++++++-
- src/igmpproxy.h         |    1 +
- src/request.c           |   20 ++++++++++++++++----
- 4 files changed, 58 insertions(+), 5 deletions(-)
-
-diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in
-index a4ea7d0..56efa22 100644
---- a/doc/igmpproxy.conf.5.in
-+++ b/doc/igmpproxy.conf.5.in
-@@ -116,6 +116,25 @@ This is especially useful for the upstream interface, since the source for multi
- traffic is often from a remote location. Any number of altnet parameters can be specified.
- .RE
-+.B whitelist
-+.I networkaddr
-+.RS
-+Defines a whitelist for multicast groups. The network address must be in the following
-+format 'a.b.c.d/n'. If you want to allow one single group use a network mask of /32,
-+i.e. 'a.b.c.d/32'. 
-+
-+By default all multicast groups are allowed on any downstream interface. If at least one
-+whitelist entry is defined, all igmp membership reports for not explicitly whitelisted
-+multicast groups will be ignored and therefore not be served by igmpproxy. This is especially
-+useful, if your provider does only allow a predefined set of multicast groups. These whitelists
-+are only obeyed by igmpproxy itself, they won't prevent any other igmp client running on the
-+same machine as igmpproxy from requesting 'unallowed' multicast groups.
-+
-+You may specify as many whitelist entries as needed. Although you should keep it as simple as
-+possible, as this list is parsed for every membership report and therefore this increases igmp
-+response times. Often used or large groups should be defined first, as parsing ends as soon as
-+a group matches an entry.
-+.RE
- .SH EXAMPLE
- ## Enable quickleave
-diff --git a/src/config.c b/src/config.c
-index 5a96ce0..d72619f 100644
---- a/src/config.c
-+++ b/src/config.c
-@@ -46,6 +46,9 @@ struct vifconfig {
-     // Keep allowed nets for VIF.
-     struct SubnetList*  allowednets;
-+
-+    // Allowed Groups
-+    struct SubnetList*  allowedgroups;
-     
-     // Next config in list...
-     struct vifconfig*   next;
-@@ -202,6 +205,8 @@ void configureVifs() {
-                     // Insert the configured nets...
-                     vifLast->next = confPtr->allowednets;
-+                  Dp->allowedgroups = confPtr->allowedgroups;
-+
-                     break;
-                 }
-             }
-@@ -215,7 +220,7 @@ void configureVifs() {
- */
- struct vifconfig *parsePhyintToken() {
-     struct vifconfig  *tmpPtr;
--    struct SubnetList **anetPtr;
-+    struct SubnetList **anetPtr, **agrpPtr;
-     char *token;
-     short parseError = 0;
-@@ -239,6 +244,7 @@ struct vifconfig *parsePhyintToken() {
-     tmpPtr->threshold = 1;
-     tmpPtr->state = IF_STATE_DOWNSTREAM;
-     tmpPtr->allowednets = NULL;
-+    tmpPtr->allowedgroups = NULL;
-     // Make a copy of the token to store the IF name
-     tmpPtr->name = strdup( token );
-@@ -248,6 +254,7 @@ struct vifconfig *parsePhyintToken() {
-     // Set the altnet pointer to the allowednets pointer.
-     anetPtr = &tmpPtr->allowednets;
-+    agrpPtr = &tmpPtr->allowedgroups; 
-     // Parse the rest of the config..
-     token = nextConfigToken();
-@@ -266,6 +273,20 @@ struct vifconfig *parsePhyintToken() {
-                 anetPtr = &(*anetPtr)->next;
-             }
-         }
-+      else if(strcmp("whitelist", token)==0) {
-+          // Whitelist
-+          token = nextConfigToken();
-+          my_log(LOG_DEBUG, 0, "Config: IF: Got whitelist token %s.", token);
-+      
-+          *agrpPtr = parseSubnetAddress(token);
-+          if(*agrpPtr == NULL) {
-+              parseError = 1;
-+              my_log(LOG_WARNING, 0, "Unable to parse subnet address.");
-+              break;
-+          } else {
-+              agrpPtr = &(*agrpPtr)->next;
-+          }
-+      }
-         else if(strcmp("upstream", token)==0) {
-             // Upstream
-             my_log(LOG_DEBUG, 0, "Config: IF: Got upstream token.");
-diff --git a/src/igmpproxy.h b/src/igmpproxy.h
-index 4dabd1c..0de7791 100644
---- a/src/igmpproxy.h
-+++ b/src/igmpproxy.h
-@@ -145,6 +145,7 @@ struct IfDesc {
-     short               Flags;
-     short               state;
-     struct SubnetList*  allowednets;
-+    struct SubnetList*  allowedgroups;
-     unsigned int        robustness;
-     unsigned char       threshold;   /* ttl limit */
-     unsigned int        ratelimit; 
-diff --git a/src/request.c b/src/request.c
-index e3589f6..89b91de 100644
---- a/src/request.c
-+++ b/src/request.c
-@@ -82,10 +82,22 @@ void acceptGroupReport(uint32_t src, uint32_t group, uint8_t type) {
-         my_log(LOG_DEBUG, 0, "Should insert group %s (from: %s) to route table. Vif Ix : %d",
-             inetFmt(group,s1), inetFmt(src,s2), sourceVif->index);
--        // The membership report was OK... Insert it into the route table..
--        insertRoute(group, sourceVif->index);
--
--
-+      // If we don't have a whitelist we insertRoute and done
-+      if(sourceVif->allowedgroups == NULL)
-+      {
-+          insertRoute(group, sourceVif->index);
-+          return;
-+      }
-+      // Check if this Request is legit on this interface
-+      struct SubnetList *sn;
-+      for(sn = sourceVif->allowedgroups; sn != NULL; sn = sn->next)
-+          if((group & sn->subnet_mask) == sn->subnet_addr)
-+          {
-+              // The membership report was OK... Insert it into the route table..
-+              insertRoute(group, sourceVif->index);
-+              return;
-+          }
-+      my_log(LOG_INFO, 0, "The group address %s may not be requested from this interface. Ignoring.", inetFmt(group, s1));
-     } else {
-         // Log the state of the interface the report was recieved on.
-         my_log(LOG_INFO, 0, "Mebership report was recieved on %s. Ignoring.",
--- 
-1.7.2.5
-
diff --git a/src/patches/igmpproxy-004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch b/src/patches/igmpproxy-004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch
deleted file mode 100644 (file)
index a4caed7..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-From bcd7c648e86d97263c931de53a008c9629e7797e Mon Sep 17 00:00:00 2001
-From: Stefan Becker <stefan.becker@nokia.com>
-Date: Fri, 11 Dec 2009 21:08:57 +0200
-Subject: [PATCH] Restrict igmp reports forwarding to upstream interface
-
-Utilize the new "whitelist" keyword also on the upstream interface definition.
-If specified then only whitelisted multicast groups will be forwarded upstream.
-
-This can be used to avoid publishing private multicast groups to the world,
-e.g. SSDP from a UPnP server on the internal network.
----
- doc/igmpproxy.conf.5.in |    5 +++++
- src/rttable.c           |   17 +++++++++++++++++
- 2 files changed, 22 insertions(+), 0 deletions(-)
-
-diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in
-index 56efa22..d916f05 100644
---- a/doc/igmpproxy.conf.5.in
-+++ b/doc/igmpproxy.conf.5.in
-@@ -134,6 +134,11 @@ You may specify as many whitelist entries as needed. Although you should keep it
- possible, as this list is parsed for every membership report and therefore this increases igmp
- response times. Often used or large groups should be defined first, as parsing ends as soon as
- a group matches an entry.
-+
-+You may also specify whitelist entries for the upstream interface. Only igmp membership reports
-+for explicitely whitelisted multicast groups will be sent out on the upstream interface. This
-+is useful if you want to use multicast groups only between your downstream interfaces, like SSDP
-+from a UPnP server.
- .RE
- .SH EXAMPLE
-diff --git a/src/rttable.c b/src/rttable.c
-index f0701a8..77dd791 100644
---- a/src/rttable.c
-+++ b/src/rttable.c
-@@ -117,6 +117,23 @@ void sendJoinLeaveUpstream(struct RouteTable* route, int join) {
-         my_log(LOG_ERR, 0 ,"FATAL: Unable to get Upstream IF.");
-     }
-+    // Check if there is a white list for the upstram VIF
-+    if (upstrIf->allowedgroups != NULL) {
-+      uint32_t           group = route->group;
-+        struct SubnetList* sn;
-+
-+        // Check if this Request is legit to be forwarded to upstream
-+        for(sn = upstrIf->allowedgroups; sn != NULL; sn = sn->next)
-+            if((group & sn->subnet_mask) == sn->subnet_addr)
-+                // Forward is OK...
-+                break;
-+
-+        if (sn == NULL) {
-+          my_log(LOG_INFO, 0, "The group address %s may not be forwarded upstream. Ignoring.", inetFmt(group, s1));
-+            return;
-+        }
-+    }
-+
-     // Send join or leave request...
-     if(join) {
--- 
-1.7.2.5
-
diff --git a/src/patches/igmpproxy-100-use-monotic-clock-instead-of-time-of-day.patch b/src/patches/igmpproxy-100-use-monotic-clock-instead-of-time-of-day.patch
deleted file mode 100644 (file)
index e75283c..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-From d0e66e0719ae8eb549f7cc220fdc66575d3db332 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Thu, 29 Mar 2012 17:01:11 +0200
-Subject: [PATCH 4/4] use monotic clock instead of time of day
-
-The time of day might chance e.g. by daylight savings time during the
-runtime, which causes timers to fire repeatedly for a long time.
-
-Contributed by T-Labs, Deutsche Telekom Innovation Laboratories
-
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
----
- configure.ac    |    2 ++
- src/igmpproxy.c |   26 +++++++++++++-------------
- src/igmpproxy.h |    3 ++-
- 3 files changed, 17 insertions(+), 14 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index 85beb08..bd84eba 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -25,6 +25,8 @@ AC_CHECK_MEMBERS([struct sockaddr_in.sin_len], [], [], [[
- #include <netinet/in.h>
- ]])
-+AC_SEARCH_LIBS([clock_gettime],[rt])
-+
- AC_CONFIG_FILES([
-       Makefile
-       doc/Makefile
-diff --git a/src/igmpproxy.c b/src/igmpproxy.c
-index 35000c7..3a9ccad 100644
---- a/src/igmpproxy.c
-+++ b/src/igmpproxy.c
-@@ -234,13 +234,13 @@ void igmpProxyRun() {
-     int     MaxFD, Rt, secs;
-     fd_set  ReadFDS;
-     socklen_t dummy = 0;
--    struct  timeval  curtime, lasttime, difftime, tv; 
-+    struct  timespec  curtime, lasttime, difftime, tv; 
-     // The timeout is a pointer in order to set it to NULL if nessecary.
--    struct  timeval  *timeout = &tv;
-+    struct  timespec  *timeout = &tv;
-     // Initialize timer vars
--    difftime.tv_usec = 0;
--    gettimeofday(&curtime, NULL);
-+    difftime.tv_nsec = 0;
-+    clock_gettime(CLOCK_MONOTONIC, &curtime);
-     lasttime = curtime;
-     // First thing we send a membership query in downstream VIF's...
-@@ -263,7 +263,7 @@ void igmpProxyRun() {
-         if(secs == -1) {
-             timeout = NULL;
-         } else {
--            timeout->tv_usec = 0;
-+            timeout->tv_nsec = 0;
-             timeout->tv_sec = secs;
-         }
-@@ -274,7 +274,7 @@ void igmpProxyRun() {
-         FD_SET( MRouterFD, &ReadFDS );
-         // wait for input
--        Rt = select( MaxFD +1, &ReadFDS, NULL, NULL, timeout );
-+        Rt = pselect( MaxFD +1, &ReadFDS, NULL, NULL, timeout, NULL );
-         // log and ignore failures
-         if( Rt < 0 ) {
-@@ -307,20 +307,20 @@ void igmpProxyRun() {
-              */
-             if (Rt == 0) {
-                 curtime.tv_sec = lasttime.tv_sec + secs;
--                curtime.tv_usec = lasttime.tv_usec;
-+                curtime.tv_nsec = lasttime.tv_nsec;
-                 Rt = -1; /* don't do this next time through the loop */
-             } else {
--                gettimeofday(&curtime, NULL);
-+                clock_gettime(CLOCK_MONOTONIC, &curtime);
-             }
-             difftime.tv_sec = curtime.tv_sec - lasttime.tv_sec;
--            difftime.tv_usec += curtime.tv_usec - lasttime.tv_usec;
--            while (difftime.tv_usec > 1000000) {
-+            difftime.tv_nsec += curtime.tv_nsec - lasttime.tv_nsec;
-+            while (difftime.tv_nsec > 1000000000) {
-                 difftime.tv_sec++;
--                difftime.tv_usec -= 1000000;
-+                difftime.tv_nsec -= 1000000000;
-             }
--            if (difftime.tv_usec < 0) {
-+            if (difftime.tv_nsec < 0) {
-                 difftime.tv_sec--;
--                difftime.tv_usec += 1000000;
-+                difftime.tv_nsec += 1000000000;
-             }
-             lasttime = curtime;
-             if (secs == 0 || difftime.tv_sec > 0)
-diff --git a/src/igmpproxy.h b/src/igmpproxy.h
-index 4df8a79..36a4f04 100644
---- a/src/igmpproxy.h
-+++ b/src/igmpproxy.h
-@@ -44,12 +44,13 @@
- #include <string.h>
- #include <fcntl.h>
- #include <stdbool.h>
-+#include <time.h>
- #include <sys/socket.h>
- #include <sys/un.h>
--#include <sys/time.h>
- #include <sys/ioctl.h>
- #include <sys/param.h>
-+#include <sys/select.h>
- #include <net/if.h>
- #include <netinet/in.h>
--- 
-1.7.2.5
-