Diff for /embedaddon/miniupnpd/upnpredirect.c between versions 1.1.1.1 and 1.1.1.3

version 1.1.1.1, 2012/02/21 23:16:02 version 1.1.1.3, 2013/07/22 00:32:35
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-2009 Thomas Bernard  * (c) 2006-2012 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 18 Line 18
 #include <ctype.h>  #include <ctype.h>
 #include <unistd.h>  #include <unistd.h>
   
   #include "macros.h"
 #include "config.h"  #include "config.h"
 #include "upnpredirect.h"  #include "upnpredirect.h"
 #include "upnpglobalvars.h"  #include "upnpglobalvars.h"
Line 47 Line 48
 #define PRIu64 "llu"  #define PRIu64 "llu"
 #endif  #endif
   
/* proto_atoi() /* proto_atoi()
  * convert the string "UDP" or "TCP" to IPPROTO_UDP and IPPROTO_UDP */   * convert the string "UDP" or "TCP" to IPPROTO_UDP and IPPROTO_UDP */
 static int  static int
 proto_atoi(const char * protocol)  proto_atoi(const char * protocol)
Line 59  proto_atoi(const char * protocol) Line 60  proto_atoi(const char * protocol)
 }  }
   
 #ifdef ENABLE_LEASEFILE  #ifdef ENABLE_LEASEFILE
static int lease_file_add( unsigned short eport, const char * iaddr, unsigned short iport, int proto, const char * desc)static int
 lease_file_add(unsigned short eport,
                const char * iaddr,
                unsigned short iport,
                int proto,
                const char * desc,
                unsigned int timestamp)
 {  {
         FILE * fd;          FILE * fd;
   
Line 71  static int lease_file_add( unsigned short eport, const Line 78  static int lease_file_add( unsigned short eport, const
                 return -1;                  return -1;
         }          }
   
        fprintf( fd, "%s:%hu:%s:%hu:%s\n",        fprintf(fd, "%s:%hu:%s:%hu:%u:%s\n",
                 ((proto==IPPROTO_TCP)?"TCP":"UDP"), eport, iaddr, iport, desc);                ((proto==IPPROTO_TCP)?"TCP":"UDP"), eport, iaddr, iport,
                 timestamp, desc);
         fclose(fd);          fclose(fd);
        
         return 0;          return 0;
 }  }
   
static int lease_file_remove( unsigned short eport, int proto)static int
 lease_file_remove(unsigned short eport, int proto)
 {  {
         FILE* fd, *fdt;          FILE* fd, *fdt;
         int tmp;          int tmp;
Line 116  static int lease_file_remove( unsigned short eport, in Line 125  static int lease_file_remove( unsigned short eport, in
         fdt = fdopen(tmp, "a");          fdt = fdopen(tmp, "a");
   
         buf[sizeof(buf)-1] = 0;          buf[sizeof(buf)-1] = 0;
        while( fgets( buf, sizeof(buf)-1, fd) != NULL) {        while( fgets(buf, sizeof(buf)-1, fd) != NULL) {
                 buf_size = strlen(buf);                  buf_size = strlen(buf);
   
                if (buf_size < str_size || strncmp( str, buf, str_size)!=0) {                if (buf_size < str_size || strncmp(str, buf, str_size)!=0) {
                         fwrite(buf, buf_size, 1, fdt);                          fwrite(buf, buf_size, 1, fdt);
                 }                  }
         }          }
         fclose(fdt);          fclose(fdt);
         fclose(fd);          fclose(fd);
        
        if (rename( tmpfilename, lease_file) < 0) {        if (rename(tmpfilename, lease_file) < 0) {
                 syslog(LOG_ERR, "could not rename temporary lease file to %s", lease_file);                  syslog(LOG_ERR, "could not rename temporary lease file to %s", lease_file);
                remove( tmpfilename);                remove(tmpfilename);
         }          }
        
         return 0;          return 0;
        
 }  }
   
 /* reload_from_lease_file()  /* reload_from_lease_file()
Line 146  int reload_from_lease_file() Line 155  int reload_from_lease_file()
         char * proto;          char * proto;
         char * iaddr;          char * iaddr;
         char * desc;          char * desc;
           char * rhost;
           unsigned int leaseduration;
           unsigned int timestamp;
           time_t current_time;
         char line[128];          char line[128];
         int r;          int r;
   
Line 159  int reload_from_lease_file() Line 172  int reload_from_lease_file()
                 syslog(LOG_WARNING, "could not unlink file %s : %m", lease_file);                  syslog(LOG_WARNING, "could not unlink file %s : %m", lease_file);
         }          }
   
           current_time = time(NULL);
         while(fgets(line, sizeof(line), fd)) {          while(fgets(line, sizeof(line), fd)) {
                 syslog(LOG_DEBUG, "parsing lease file line '%s'", line);                  syslog(LOG_DEBUG, "parsing lease file line '%s'", line);
                 proto = line;                  proto = line;
Line 181  int reload_from_lease_file() Line 195  int reload_from_lease_file()
                         continue;                          continue;
                 }                  }
                 *(p++) = '\0';                  *(p++) = '\0';
                   iport = (unsigned short)atoi(p);
                   p = strchr(p, ':');
                   if(!p) {
                           syslog(LOG_ERR, "unrecognized data in lease file");
                           continue;
                   }
                   *(p++) = '\0';
                 desc = strchr(p, ':');                  desc = strchr(p, ':');
                 if(!desc) {                  if(!desc) {
                         syslog(LOG_ERR, "unrecognized data in lease file");                          syslog(LOG_ERR, "unrecognized data in lease file");
                         continue;                          continue;
                 }                  }
                 *(desc++) = '\0';                  *(desc++) = '\0';
                iport = (unsigned short)atoi(p);                /*timestamp = (unsigned int)atoi(p);*/
                 timestamp = (unsigned int)strtoul(p, NULL, 10);
                 /* trim description */                  /* trim description */
                 while(isspace(*desc))                  while(isspace(*desc))
                         desc++;                          desc++;
Line 197  int reload_from_lease_file() Line 219  int reload_from_lease_file()
                 while(isspace(*p) && (p > desc))                  while(isspace(*p) && (p > desc))
                         *(p--) = '\0';                          *(p--) = '\0';
   
                r = upnp_redirect(eport, iaddr, iport, proto, desc);                if(timestamp > 0) {
                         if(timestamp <= (unsigned int)current_time) {
                                 syslog(LOG_NOTICE, "already expired lease in lease file");
                                 continue;
                         } else {
                                 leaseduration = timestamp - current_time;
                         }
                 } else {
                         leaseduration = 0;      /* default value */
                 }
                 rhost = NULL;
                 r = upnp_redirect(rhost, eport, iaddr, iport, proto, desc, leaseduration);
                 if(r == -1) {                  if(r == -1) {
                         syslog(LOG_ERR, "Failed to redirect %hu -> %s:%hu protocol %s",                          syslog(LOG_ERR, "Failed to redirect %hu -> %s:%hu protocol %s",
                                eport, iaddr, iport, proto);                                 eport, iaddr, iport, proto);
                 } else if(r == -2) {                  } else if(r == -2) {
                         /* Add the redirection again to the lease file */                          /* Add the redirection again to the lease file */
                        lease_file_add(eport, iaddr, iport, proto_atoi(proto), desc);                        lease_file_add(eport, iaddr, iport, proto_atoi(proto),
                                        desc, timestamp);
                 }                  }
         }          }
         fclose(fd);          fclose(fd);
        
         return 0;          return 0;
 }  }
 #endif  #endif
   
/* upnp_redirect() /* upnp_redirect()
  * calls OS/fw dependant implementation of the redirection.   * calls OS/fw dependant implementation of the redirection.
  * protocol should be the string "TCP" or "UDP"   * protocol should be the string "TCP" or "UDP"
  * returns: 0 on success   * returns: 0 on success
Line 221  int reload_from_lease_file() Line 255  int reload_from_lease_file()
  *          -3 permission check failed   *          -3 permission check failed
  */   */
 int  int
upnp_redirect(unsigned short eport, upnp_redirect(const char * rhost, unsigned short eport,
               const char * iaddr, unsigned short iport,                const char * iaddr, unsigned short iport,
              const char * protocol, const char * desc)              const char * protocol, const char * desc,
               unsigned int leaseduration)
 {  {
         int proto, r;          int proto, r;
         char iaddr_old[32];          char iaddr_old[32];
         unsigned short iport_old;          unsigned short iport_old;
         struct in_addr address;          struct in_addr address;
           unsigned int timestamp;
   
         proto = proto_atoi(protocol);          proto = proto_atoi(protocol);
         if(inet_aton(iaddr, &address) < 0) {          if(inet_aton(iaddr, &address) < 0) {
                 syslog(LOG_ERR, "inet_aton(%s) : %m", iaddr);                  syslog(LOG_ERR, "inet_aton(%s) : %m", iaddr);
Line 242  upnp_redirect(unsigned short eport,  Line 279  upnp_redirect(unsigned short eport, 
                 return -3;                  return -3;
         }          }
         r = get_redirect_rule(ext_if_name, eport, proto,          r = get_redirect_rule(ext_if_name, eport, proto,
                              iaddr_old, sizeof(iaddr_old), &iport_old, 0, 0, 0, 0);                              iaddr_old, sizeof(iaddr_old), &iport_old, 0, 0,
                               0, 0,
                               &timestamp, 0, 0);
         if(r == 0) {          if(r == 0) {
                 /* if existing redirect rule matches redirect request return success                  /* if existing redirect rule matches redirect request return success
                  * xbox 360 does not keep track of the port it redirects and will                   * xbox 360 does not keep track of the port it redirects and will
                  * redirect another port when receiving ConflictInMappingEntry */                   * redirect another port when receiving ConflictInMappingEntry */
                if(strcmp(iaddr,iaddr_old)==0 && iport==iport_old) {                if(strcmp(iaddr, iaddr_old)==0 && iport==iport_old) {
                         syslog(LOG_INFO, "ignoring redirect request as it matches existing redirect");                          syslog(LOG_INFO, "ignoring redirect request as it matches existing redirect");
                 } else {                  } else {
   
Line 256  upnp_redirect(unsigned short eport,  Line 295  upnp_redirect(unsigned short eport, 
                         return -2;                          return -2;
                 }                  }
         } else {          } else {
                   timestamp = (leaseduration > 0) ? time(NULL) + leaseduration : 0;
                 syslog(LOG_INFO, "redirecting port %hu to %s:%hu protocol %s for: %s",                  syslog(LOG_INFO, "redirecting port %hu to %s:%hu protocol %s for: %s",
                        eport, iaddr, iport, protocol, desc);                                           eport, iaddr, iport, protocol, desc);
                return upnp_redirect_internal(eport, iaddr, iport, proto, desc);                return upnp_redirect_internal(rhost, eport, iaddr, iport, proto,
                                               desc, timestamp);
         }          }
   
         return 0;          return 0;
 }  }
   
 int  int
upnp_redirect_internal(unsigned short eport,upnp_redirect_internal(const char * rhost, unsigned short eport,
                        const char * iaddr, unsigned short iport,                         const char * iaddr, unsigned short iport,
                       int proto, const char * desc)                       int proto, const char * desc,
                        unsigned int timestamp)
 {  {
         /*syslog(LOG_INFO, "redirecting port %hu to %s:%hu protocol %s for: %s",          /*syslog(LOG_INFO, "redirecting port %hu to %s:%hu protocol %s for: %s",
                 eport, iaddr, iport, protocol, desc);                   */                  eport, iaddr, iport, protocol, desc);                   */
        if(add_redirect_rule2(ext_if_name, eport, iaddr, iport, proto, desc) < 0) {        if(add_redirect_rule2(ext_if_name, rhost, eport, iaddr, iport, proto,
                               desc, timestamp) < 0) {
                 return -1;                  return -1;
         }          }
   
 #ifdef ENABLE_LEASEFILE  #ifdef ENABLE_LEASEFILE
        lease_file_add( eport, iaddr, iport, proto, desc);        lease_file_add( eport, iaddr, iport, proto, desc, timestamp);
 #endif  #endif
 /*      syslog(LOG_INFO, "creating pass rule to %s:%hu protocol %s for: %s",  /*      syslog(LOG_INFO, "creating pass rule to %s:%hu protocol %s for: %s",
                 iaddr, iport, protocol, desc);*/                  iaddr, iport, protocol, desc);*/
        if(add_filter_rule2(ext_if_name, iaddr, eport, iport, proto, desc) < 0) {        if(add_filter_rule2(ext_if_name, rhost, iaddr, eport, iport, proto, desc) < 0) {
                 /* clean up the redirect rule */                  /* clean up the redirect rule */
 #if !defined(__linux__)  #if !defined(__linux__)
                 delete_redirect_rule(ext_if_name, eport, proto);                  delete_redirect_rule(ext_if_name, eport, proto);
 #endif  #endif
                 return -1;                  return -1;
         }          }
           if(timestamp > 0) {
                   if(!nextruletoclean_timestamp || (timestamp < nextruletoclean_timestamp))
                           nextruletoclean_timestamp = timestamp;
           }
 #ifdef ENABLE_EVENTS  #ifdef ENABLE_EVENTS
           /* the number of port mappings changed, we must
            * inform the subscribers */
         upnp_event_var_change_notify(EWanIPC);          upnp_event_var_change_notify(EWanIPC);
 #endif  #endif
         return 0;          return 0;
Line 295  upnp_redirect_internal(unsigned short eport, Line 344  upnp_redirect_internal(unsigned short eport,
   
   
   
   /* Firewall independant code which call the FW dependant code. */
 int  int
 upnp_get_redirection_infos(unsigned short eport, const char * protocol,  upnp_get_redirection_infos(unsigned short eport, const char * protocol,
                            unsigned short * iport,                             unsigned short * iport,
                            char * iaddr, int iaddrlen,                             char * iaddr, int iaddrlen,
                           char * desc, int desclen)                           char * desc, int desclen,
                            char * rhost, int rhostlen,
                            unsigned int * leaseduration)
 {  {
           int r;
           unsigned int timestamp;
           time_t current_time;
   
         if(desc && (desclen > 0))          if(desc && (desclen > 0))
                 desc[0] = '\0';                  desc[0] = '\0';
        return get_redirect_rule(ext_if_name, eport, proto_atoi(protocol),        if(rhost && (rhostlen > 0))
                                 iaddr, iaddrlen, iport, desc, desclen, 0, 0);                rhost[0] = '\0';
         r = get_redirect_rule(ext_if_name, eport, proto_atoi(protocol),
                               iaddr, iaddrlen, iport, desc, desclen,
                               rhost, rhostlen, &timestamp,
                               0, 0);
         if(r == 0 &&
            timestamp > 0 &&
            timestamp > (unsigned int)(current_time = time(NULL))) {
                 *leaseduration = timestamp - current_time;
         } else {
                 *leaseduration = 0;
         }
         return r;
 }  }
   
 int  int
 upnp_get_redirection_infos_by_index(int index,  upnp_get_redirection_infos_by_index(int index,
                                     unsigned short * eport, char * protocol,                                      unsigned short * eport, char * protocol,
                                    unsigned short * iport,                                     unsigned short * iport,
                                     char * iaddr, int iaddrlen,                                      char * iaddr, int iaddrlen,
                                    char * desc, int desclen)                                    char * desc, int desclen,
                                     char * rhost, int rhostlen,
                                     unsigned int * leaseduration)
 {  {
         /*char ifname[IFNAMSIZ];*/          /*char ifname[IFNAMSIZ];*/
         int proto = 0;          int proto = 0;
           unsigned int timestamp;
           time_t current_time;
   
         if(desc && (desclen > 0))          if(desc && (desclen > 0))
                 desc[0] = '\0';                  desc[0] = '\0';
           if(rhost && (rhostlen > 0))
                   rhost[0] = '\0';
         if(get_redirect_rule_by_index(index, 0/*ifname*/, eport, iaddr, iaddrlen,          if(get_redirect_rule_by_index(index, 0/*ifname*/, eport, iaddr, iaddrlen,
                                      iport, &proto, desc, desclen, 0, 0) < 0)                                      iport, &proto, desc, desclen,
                                       rhost, rhostlen, &timestamp,
                                       0, 0) < 0)
                 return -1;                  return -1;
         else          else
         {          {
                   current_time = time(NULL);
                   *leaseduration = (timestamp > (unsigned int)current_time)
                                    ? (timestamp - current_time)
                                    : 0;
                 if(proto == IPPROTO_TCP)                  if(proto == IPPROTO_TCP)
                         memcpy(protocol, "TCP", 4);                          memcpy(protocol, "TCP", 4);
                 else                  else
Line 332  upnp_get_redirection_infos_by_index(int index, Line 412  upnp_get_redirection_infos_by_index(int index,
         }          }
 }  }
   
   /* called from natpmp.c too */
 int  int
 _upnp_delete_redir(unsigned short eport, int proto)  _upnp_delete_redir(unsigned short eport, int proto)
 {  {
Line 360  upnp_delete_redirection(unsigned short eport, const ch Line 441  upnp_delete_redirection(unsigned short eport, const ch
 }  }
   
 /* upnp_get_portmapping_number_of_entries()  /* upnp_get_portmapping_number_of_entries()
 * TODO: improve this code */ * TODO: improve this code. */
 int  int
 upnp_get_portmapping_number_of_entries()  upnp_get_portmapping_number_of_entries()
 {  {
         int n = 0, r = 0;          int n = 0, r = 0;
         unsigned short eport, iport;          unsigned short eport, iport;
        char protocol[4], iaddr[32], desc[64];        char protocol[4], iaddr[32], desc[64], rhost[32];
         unsigned int leaseduration;
         do {          do {
                 protocol[0] = '\0'; iaddr[0] = '\0'; desc[0] = '\0';                  protocol[0] = '\0'; iaddr[0] = '\0'; desc[0] = '\0';
                 r = upnp_get_redirection_infos_by_index(n, &eport, protocol, &iport,                  r = upnp_get_redirection_infos_by_index(n, &eport, protocol, &iport,
                                                         iaddr, sizeof(iaddr),                                                          iaddr, sizeof(iaddr),
                                                        desc, sizeof(desc) );                                                        desc, sizeof(desc),
                                                         rhost, sizeof(rhost),
                                                         &leaseduration);
                 n++;                  n++;
         } while(r==0);          } while(r==0);
         return (n-1);          return (n-1);
 }  }
   
/* functions used to remove unused rules *//* functions used to remove unused rules
  * As a side effect, delete expired rules (based on LeaseDuration) */
 struct rule_state *  struct rule_state *
 get_upnp_rules_state_list(int max_rules_number_target)  get_upnp_rules_state_list(int max_rules_number_target)
 {  {
         /*char ifname[IFNAMSIZ];*/          /*char ifname[IFNAMSIZ];*/
         int proto;          int proto;
         unsigned short iport;          unsigned short iport;
           unsigned int timestamp;
         struct rule_state * tmp;          struct rule_state * tmp;
         struct rule_state * list = 0;          struct rule_state * list = 0;
           struct rule_state * * p;
         int i = 0;          int i = 0;
           time_t current_time;
   
         /*ifname[0] = '\0';*/          /*ifname[0] = '\0';*/
         tmp = malloc(sizeof(struct rule_state));          tmp = malloc(sizeof(struct rule_state));
         if(!tmp)          if(!tmp)
                 return 0;                  return 0;
           current_time = time(NULL);
           nextruletoclean_timestamp = 0;
         while(get_redirect_rule_by_index(i, /*ifname*/0, &tmp->eport, 0, 0,          while(get_redirect_rule_by_index(i, /*ifname*/0, &tmp->eport, 0, 0,
                                      &iport, &proto, 0, 0,                                      &iport, &proto, 0, 0, 0,0, &timestamp,
                                                                   &tmp->packets, &tmp->bytes) >= 0)                                                                    &tmp->packets, &tmp->bytes) >= 0)
         {          {
                   tmp->to_remove = 0;
                   if(timestamp > 0) {
                           /* need to remove this port mapping ? */
                           if(timestamp <= (unsigned int)current_time)
                                   tmp->to_remove = 1;
                           else if((nextruletoclean_timestamp <= (unsigned int)current_time)
                                  || (timestamp < nextruletoclean_timestamp))
                                   nextruletoclean_timestamp = timestamp;
                   }
                 tmp->proto = (short)proto;                  tmp->proto = (short)proto;
                 /* add tmp to list */                  /* add tmp to list */
                 tmp->next = list;                  tmp->next = list;
Line 406  get_upnp_rules_state_list(int max_rules_number_target) Line 506  get_upnp_rules_state_list(int max_rules_number_target)
                         break;                          break;
         }          }
         free(tmp);          free(tmp);
           /* remove the redirections that need to be removed */
           for(p = &list, tmp = list; tmp; tmp = *p)
           {
                   if(tmp->to_remove)
                   {
                           syslog(LOG_NOTICE, "remove port mapping %hu %s because it has expired",
                                  tmp->eport, (tmp->proto==IPPROTO_TCP)?"TCP":"UDP");
                           _upnp_delete_redir(tmp->eport, tmp->proto);
                           *p = tmp->next;
                           free(tmp);
                           i--;
                   } else {
                           p = &(tmp->next);
                   }
           }
         /* return empty list if not enough redirections */          /* return empty list if not enough redirections */
         if(i<=max_rules_number_target)          if(i<=max_rules_number_target)
                 while(list)                  while(list)
Line 426  remove_unused_rules(struct rule_state * list) Line 541  remove_unused_rules(struct rule_state * list)
         struct rule_state * tmp;          struct rule_state * tmp;
         u_int64_t packets;          u_int64_t packets;
         u_int64_t bytes;          u_int64_t bytes;
           unsigned int timestamp;
         int n = 0;          int n = 0;
   
         while(list)          while(list)
         {          {
                 /* remove the rule if no traffic has used it */                  /* remove the rule if no traffic has used it */
                 if(get_redirect_rule(ifname, list->eport, list->proto,                  if(get_redirect_rule(ifname, list->eport, list->proto,
                                 0, 0, &iport, 0, 0, &packets, &bytes) >= 0)                                 0, 0, &iport, 0, 0, 0, 0, &timestamp,
                                      &packets, &bytes) >= 0)
                 {                  {
                         if(packets == list->packets && bytes == list->bytes)                          if(packets == list->packets && bytes == list->bytes)
                         {                          {
Line 447  remove_unused_rules(struct rule_state * list) Line 565  remove_unused_rules(struct rule_state * list)
                 syslog(LOG_NOTICE, "removed %d unused rules", n);                  syslog(LOG_NOTICE, "removed %d unused rules", n);
 }  }
   
   /* upnp_get_portmappings_in_range()
    * return a list of all "external" ports for which a port
    * mapping exists */
   unsigned short *
   upnp_get_portmappings_in_range(unsigned short startport,
                                  unsigned short endport,
                                  const char * protocol,
                                  unsigned int * number)
   {
           int proto;
           proto = proto_atoi(protocol);
           if(!number)
                   return NULL;
           return get_portmappings_in_range(startport, endport, proto, number);
   }
   
 /* stuff for miniupnpdctl */  /* stuff for miniupnpdctl */
 #ifdef USE_MINIUPNPDCTL  #ifdef USE_MINIUPNPDCTL
 void  void
 write_ruleset_details(int s)  write_ruleset_details(int s)
 {  {
         char ifname[IFNAMSIZ];  
         int proto = 0;          int proto = 0;
         unsigned short eport, iport;          unsigned short eport, iport;
         char desc[64];          char desc[64];
         char iaddr[32];          char iaddr[32];
           char rhost[32];
           unsigned int timestamp;
         u_int64_t packets;          u_int64_t packets;
         u_int64_t bytes;          u_int64_t bytes;
         int i = 0;          int i = 0;
         char buffer[256];          char buffer[256];
         int n;          int n;
        ifname[0] = '\0';
         write(s, "Ruleset :\n", 10);          write(s, "Ruleset :\n", 10);
        while(get_redirect_rule_by_index(i, ifname, &eport, iaddr, sizeof(iaddr),        while(get_redirect_rule_by_index(i, 0/*ifname*/, &eport, iaddr, sizeof(iaddr),
                                          &iport, &proto, desc, sizeof(desc),                                           &iport, &proto, desc, sizeof(desc),
                                            rhost, sizeof(rhost),
                                            &timestamp,
                                          &packets, &bytes) >= 0)                                           &packets, &bytes) >= 0)
         {          {
                n = snprintf(buffer, sizeof(buffer), "%2d %s %s %hu->%s:%hu "                n = snprintf(buffer, sizeof(buffer),
                                                     "'%s' %" PRIu64 " %" PRIu64 "\n",                             "%2d %s %s:%hu->%s:%hu "
                                                     /*"'%s' %llu %llu\n",*/                             "'%s' %u %" PRIu64 " %" PRIu64 "\n",
                             i, ifname, proto==IPPROTO_TCP?"TCP":"UDP",                             /*"'%s' %llu %llu\n",*/
                             eport, iaddr, iport, desc, packets, bytes);                             i, proto==IPPROTO_TCP?"TCP":"UDP", rhost,
                              eport, iaddr, iport, desc, timestamp, packets, bytes);
                 write(s, buffer, n);                  write(s, buffer, n);
                 i++;                  i++;
         }          }

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


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