[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#772104: unblock: pptpd/1.4.0-5



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Regards,

Please unblock pptpd (1.4.0-5) 

The differences to the jessie version 1.4.0-3 are:

* -4 fixed an important bug where overlong interface names
  might crash the bcrelay program (#765442)
* -5 fixed the patch description, that was an error on my side and I'd
  really like to see the wrong attribution removed.

The debdiff is attached. It got a bit bigger since upstream decided to
re-arrange the affected code.

If you want to take a closer look, the upstream commit IDs are part of the
path, upstream git is at 
    git://git.code.sf.net/p/poptop/git

Regards,

    Christoph

-- System Information:
Debian Release: jessie/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 3.17.4 (SMP w/4 CPU cores; PREEMPT)
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
Shell: /bin/sh linked to /bin/dash
diff -Nru pptpd-1.4.0/debian/changelog pptpd-1.4.0/debian/changelog
--- pptpd-1.4.0/debian/changelog	2014-07-15 18:41:01.000000000 +0200
+++ pptpd-1.4.0/debian/changelog	2014-11-04 23:41:32.000000000 +0100
@@ -1,3 +1,17 @@
+pptpd (1.4.0-5) unstable; urgency=medium
+
+  * Fix description of patch introduced in 1.4.0-4
+
+ -- Christoph Biedl <debian.axhn@manchmal.in-ulm.de>  Tue, 04 Nov 2014 23:30:46 +0100
+
+pptpd (1.4.0-4) unstable; urgency=medium
+
+  * Fix buffer overflow from overlong interface names in bcrelay.
+    Closes: #765442
+  * Fixes an important bug, urgency set to medium
+
+ -- Christoph Biedl <debian.axhn@manchmal.in-ulm.de>  Sun, 26 Oct 2014 20:50:20 +0100
+
 pptpd (1.4.0-3) unstable; urgency=low
 
   * Fix status check in init script. Closes: #747146
diff -Nru pptpd-1.4.0/debian/patches/cherry-pick.1.4.0-11-g4ea2db6.ff.patch pptpd-1.4.0/debian/patches/cherry-pick.1.4.0-11-g4ea2db6.ff.patch
--- pptpd-1.4.0/debian/patches/cherry-pick.1.4.0-11-g4ea2db6.ff.patch	1970-01-01 01:00:00.000000000 +0100
+++ pptpd-1.4.0/debian/patches/cherry-pick.1.4.0-11-g4ea2db6.ff.patch	2014-11-04 23:40:37.000000000 +0100
@@ -0,0 +1,1479 @@
+Subject: Cherry-pick 1.4.0-11-g4ea2db6 ff. to fix sprintf usage
+Author: James Cameron <quozl@laptop.org>
+Date: Thu Oct 16 08:22:36 2014 +1100
+Origin:
+    commit 4ea2db6028cc1079aa84ac1b92e23ba8a7ce9d8e
+    commit 2521c45c19106722f299c66d4e0ef86ff7486b54
+    commit eee8ad1adece7cc5dfcadaa3cf838cfaf0b01b05
+Bug-Debian: https://bugs.debian.org/765442
+Last-Update: 2014-10-25
+
+--- a/bcrelay.c
++++ b/bcrelay.c
+@@ -1,6 +1,6 @@
+-// A broadcast packet repeater.  This packet repeater (currently designed for
+-// udp packets) will listen for broadcast packets.
+-// When it receives the packets, it will then re-broadcast the packet.
++// A broadcast packet repeater.  This packet repeater (currently
++// designed for udp packets) will listen for broadcast packets.  When
++// it receives the packets, it will then re-broadcast the packet.
+ //
+ // Written by TheyCallMeLuc(at)yahoo.com.au
+ // I accept no responsiblity for the function of this program if you
+@@ -8,58 +8,70 @@
+ // Modified for Poptop by Richard de Vroede <r.devroede@linvision.com>
+ // Ditto on the no responsibility.
+ //
+-// Rewritten by Norbert van Bolhuis <norbert@vanbolhuis.demon.nl> bcrelay (v1.0+)
+-// now supports/does:
+-// 1) Relaying from PPP (VPN tunnel) interfaces, hereby creating a virtual
+-//    LAN (w.r.t. UDP broadcasts) for VPN clients and ethernet PCs
+-//    belonging/matching the subnet portion of the VPN IP addresses.
+-//    So now broadcasting to/from all systems of the VPN has been implemented.
+-//    Note that bcrelay v0.5 only relayed from LAN to VPN clients.
+-//    It doesn't matter whether the systems on the VPN are on the LAN of the
+-//    VPN server or have a VPN/PPTP connection (over the internet) to the VPN
+-//    server. Broadcasts will always be relayed to/from all given interfaces. And
+-//    as long as the subnet portion of the IP addresses of the systems on the VPN
+-//    matches, the VPN server will be able to route properly. This means all
+-//    networking applications/games that rely on a UDP broadcast from one or
+-//    more PPP (VPN tunnel) interfaces will now see eachother and work over
+-//    the VPN.
+-//    Note that it depends on the networking application/game and whoever
+-//    acts as application/game server/host who is sending (UPD) broadcasts
+-//    and who is listening.
+-// 2) UDP broadcasts received on a PPP interface (VPN tunnel) sometimes
+-//    don't carry the VPN IP address which pptpd provisioned. I've seen
+-//    this happening on a WinXP SP1 box, especially when the application
+-//    responsible for the UDP broadcasts isn't aware of the PPP interface.
+-//    In this case it just uses the LAN IP src address for the IP src
+-//    address of the inner (GRE encapsulated) IP packet. This breaks
+-//    the "virtual LAN" and therefore bcrelay, as of this version, changes
+-//    the src IP address to the VPN IP address (which pptpd provisioned)
++// Rewritten by Norbert van Bolhuis <norbert@vanbolhuis.demon.nl>
++// bcrelay (v1.0+) now supports/does:
++//
++// 1) Relaying from PPP (VPN tunnel) interfaces, hereby creating a
++//    virtual LAN (w.r.t. UDP broadcasts) for VPN clients and ethernet
++//    PCs belonging/matching the subnet portion of the VPN IP
++//    addresses.  So now broadcasting to/from all systems of the VPN
++//    has been implemented.  Note that bcrelay v0.5 only relayed from
++//    LAN to VPN clients.  It doesn't matter whether the systems on
++//    the VPN are on the LAN of the VPN server or have a VPN/PPTP
++//    connection (over the internet) to the VPN server. Broadcasts
++//    will always be relayed to/from all given interfaces. And as long
++//    as the subnet portion of the IP addresses of the systems on the
++//    VPN matches, the VPN server will be able to route properly. This
++//    means all networking applications/games that rely on a UDP
++//    broadcast from one or more PPP (VPN tunnel) interfaces will now
++//    see eachother and work over the VPN.
++//
++//    Note that it depends on the networking application/game and
++//    whoever acts as application/game server/host who is sending
++//    (UDP) broadcasts and who is listening.
++//
++// 2) UDP broadcasts received on a PPP interface (VPN tunnel)
++//    sometimes don't carry the VPN IP address which pptpd
++//    provisioned. I've seen this happening on a WinXP SP1 box,
++//    especially when the application responsible for the UDP
++//    broadcasts isn't aware of the PPP interface.  In this case it
++//    just uses the LAN IP src address for the IP src address of the
++//    inner (GRE encapsulated) IP packet. This breaks the "virtual
++//    LAN" and therefore bcrelay, as of this version, changes the src
++//    IP address to the VPN IP address (which pptpd provisioned)
+ //    before relaying.
+-// 3) To avoid a UDP broadcast loop, bcrelay changes the IP TTL and the
+-//    UDP checksum (to 1 and 0 respectively) of the UDP broadcasts it relays.
+-//    No relaying will be done for UDP broadcasts with IP TTL=1 and UDP
+-//    checksum=0. Could also (mis)use IP identification for this, but IP TTL
+-//    and UDP chksum combination is expected to work fine.
+-// 4) bcrelay v0.5 forgot to update IP/UDP checksum when it changed the
+-//    dest. IP address (e.g. from 192.168.1.255 to 255.255.255.255).
+-//    Of course as of this version bcrelay always updates the IP/UDP
+-//    checksum since the IP TTL and src IP address will change also.
+-// 5) Enhanced the (syslog) debugging capabilities. By default bcrelay will
+-//    show what it is doing. Bcrelay will syslog the IP interfaces it tries
+-//    to read/relay UDP broadcasts from/to. These interfaces are called
+-//    the 'active interfaces', bcrelay will syslog the initial set of active
+-//    interfaces and whenever the set changes. Currently there is no difference
+-//    between an incoming interface (given with -i) and an outgoing interface
+-//    (given with -o), so bcrelay won't show this attribute. Also, bcrelay will
+-//    syslog a successfully relayed UDP broadcast, including the UDP port numbers,
+-//    the incoming interface and the interface(s) to which it was successfully
+-//    relayed. The (new) -n option allows to suppress syslog tracing.
+-//    If -n is given, bcrelay shows/syslogs nothing, except fatal error
+-//    messages.
++//
++// 3) To avoid a UDP broadcast loop, bcrelay changes the IP TTL and
++//    the UDP checksum (to 1 and 0 respectively) of the UDP broadcasts
++//    it relays.  No relaying will be done for UDP broadcasts with IP
++//    TTL=1 and UDP checksum=0. Could also (mis)use IP identification
++//    for this, but IP TTL and UDP chksum combination is expected to
++//    work fine.
++//
++// 4) bcrelay v0.5 forgot to update IP/UDP checksum when it changed
++//    the dest. IP address (e.g. from 192.168.1.255 to
++//    255.255.255.255).  Of course as of this version bcrelay always
++//    updates the IP/UDP checksum since the IP TTL and src IP address
++//    will change also.
++//
++// 5) Enhanced the (syslog) debugging capabilities. By default bcrelay
++//    will show what it is doing. Bcrelay will syslog the IP
++//    interfaces it tries to read/relay UDP broadcasts from/to. These
++//    interfaces are called the 'active interfaces', bcrelay will
++//    syslog the initial set of active interfaces and whenever the set
++//    changes. Currently there is no difference between an incoming
++//    interface (given with -i) and an outgoing interface (given with
++//    -o), so bcrelay won't show this attribute. Also, bcrelay will
++//    syslog a successfully relayed UDP broadcast, including the UDP
++//    port numbers, the incoming interface and the interface(s) to
++//    which it was successfully relayed. The (new) -n option allows to
++//    suppress syslog tracing.  If -n is given, bcrelay shows/syslogs
++//    nothing, except fatal error messages.
+ //
+ // This software is completely free.  You can use and/or modify this
+-// software to your hearts content.  You are free to redistribute it as
+-// long as it is accompanied with the source and my credit is included.
++// software to your hearts content.  You are free to redistribute it
++// as long as it is accompanied with the source and my credit is
++// included.
+ 
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+@@ -126,14 +138,16 @@
+ #define IP_UDPPDU_CHECKSUM_MSB_PTR(udppdu) ((unsigned char *)(udppdu) + 6 )
+ #define IP_UDPPDU_CHECKSUM_LSB_PTR(udppdu) ((unsigned char *)(udppdu) + 7 )
+ 
+-#define MAXIF 255               // Maximum interfaces to use
+-#define MAX_SELECT_WAIT 3       // Maximum time (in secs) to wait for input on the socket/interfaces
+-                                // A time-out triggers the discovery of new interfaces.
+-#define MAX_NODISCOVER_IFS 12   // Maximum time (in secs) to elaps before a discovery of new
+-                                // interfaces is triggered. Only when a packet keeps coming in
+-                                // (this prevents a select time-out) a variable initialized with
+-                                // this #define becomes 0 and a rediscovery of the interfaces is
+-                                // triggered.
++// Maximum interfaces to use
++#define MAXIF 255
++// Maximum time (in secs) to wait for input on the socket/interfaces A
++// time-out triggers the discovery of new interfaces.
++#define MAX_SELECT_WAIT 3
++// Maximum time (in secs) to elapse before a discovery of new
++// interfaces is triggered. Only when a packet keeps coming in (this
++// prevents a select time-out) a variable initialized with this
++// #define becomes 0 and a rediscovery of the interfaces is triggered.
++#define MAX_NODISCOVER_IFS 12
+ #define MAX_IFLOGTOSTR 16
+ 
+ /* Local function prototypes */
+@@ -152,15 +166,13 @@ struct packet {
+ 
+ 
+ /*
+- * struct that keeps track of the interfaces of the system
+- * selected upon usage by bcrelay (with -i and -o option).
+- * An array of this struct is returned by discoverActiveInterfaces.
+- * This array is reset (filled from scratch) each time
+- * discoverActiveInterfaces is called.
++ * struct that keeps track of the interfaces of the system selected
++ * upon usage by bcrelay (with -i and -o option).  An array of this
++ * struct is returned by discoverActiveInterfaces.  This array is
++ * reset (filled from scratch) each time discoverActiveInterfaces is
++ * called.
+  */
+ struct iflist {
+-//Fix 3mar2003
+-  //char index;
+   int index;
+   u_int32_t bcast;
+   char ifname[16+1];
+@@ -176,10 +188,10 @@ struct iflist {
+ 
+ 
+ /*
+- * struct that keeps track of the socket fd's for every interface
+- * that is in use (and thus present in iflist).
+- * Two permanent arrays of this struct are used, one for the
+- * previous/old list and one for the current list.
++ * struct that keeps track of the socket fd's for every interface that
++ * is in use (and thus present in iflist).  Two permanent arrays of
++ * this struct are used, one for the previous/old list and one for the
++ * current list.
+  */
+ struct ifsnr {
+   int sock_nr;
+@@ -198,7 +210,7 @@ static void bind_to_iface(int fd, int if
+ 
+ /*
+  * This global variable determines whether NVBCR_PRINTF actually
+- * displays something. While developping v1.0, NVBCR_PRINTF were
++ * displays something. While developing v1.0, NVBCR_PRINTF were
+  * printf and a lot of tracing/logging/debugging was done with these.
+  * Of course, by default these 'info' messages have been turned off
+  * now. Enable by setting variable to 1. Note that output will only
+@@ -209,100 +221,100 @@ static int do_org_info_printfs = 0;
+ static int vnologging = 0;
+ static int vdaemon = 0;
+ 
+-#define NVBCR_PRINTF( args ) \
+- if ((vdaemon == 0) && (do_org_info_printfs == 1)) printf args
++#define NVBCR_PRINTF( args )                                    \
++  if ((vdaemon == 0) && (do_org_info_printfs == 1)) printf args
+ 
+ static char empty[1] = "";
+-static char interfaces[32];
++static char reg_interfaces[MAX_IFLOGTOSTR*2+2];
+ static char log_interfaces[MAX_IFLOGTOSTR*MAXIF];
+-static char log_relayed[(MAX_IFLOGTOSTR-1)*MAXIF+81];
++static char log_relayed[MAX_IFLOGTOSTR*MAXIF+81];
+ static char *ipsec = empty;
+ 
+ static void showusage(char *prog)
+ {
+-        printf("\nBCrelay v%s\n\n", VERSION);
+-        printf("A broadcast packet repeater. This packet repeater (currently designed for udp packets) will listen\n");
+-        printf(" for broadcast packets. When it receives the packets, it will then re-broadcast the packet.\n\n");
+-        printf("Usage: %s [options], where options are:\n\n", prog);
+-        printf(" [-d] [--daemon]           Run as daemon.\n");
+-        printf(" [-h] [--help]             Displays this help message.\n");
+-        printf(" [-i] [--incoming <ifin>]  Defines from which interface broadcasts will be relayed.\n");
+-        printf(" [-n] [--nolog]            No logging/tracing to /var/log/messages.\n");
+-        printf(" [-o] [--outgoing <ifout>] Defines to which interface broadcasts will be relayed.\n");
+-        printf(" [-s] [--ipsec <arg>]      Defines an ipsec tunnel to be relayed to.\n");
+-        printf("                           Since ipsec tunnels terminate on the same interface, we need to define the broadcast\n");
+-        printf("                           address of the other end-point of the tunnel.  This is done as ipsec0:x.x.x.255\n");
+-        printf(" [-v] [--version]          Displays the BCrelay version number.\n");
+-        printf("\nLog messages and debugging go to syslog as DAEMON.\n\n");
+-        printf("\nInterfaces can be specified as regexpressions, ie. ppp[0-9]+\n\n");
++  printf("\nBCrelay v%s\n\n", VERSION);
++  printf("A broadcast packet repeater. This packet repeater (currently designed for udp packets) will listen\n");
++  printf(" for broadcast packets. When it receives the packets, it will then re-broadcast the packet.\n\n");
++  printf("Usage: %s [options], where options are:\n\n", prog);
++  printf(" [-d] [--daemon]           Run as daemon.\n");
++  printf(" [-h] [--help]             Displays this help message.\n");
++  printf(" [-i] [--incoming <ifin>]  Defines from which interface broadcasts will be relayed.\n");
++  printf(" [-n] [--nolog]            No logging/tracing to /var/log/messages.\n");
++  printf(" [-o] [--outgoing <ifout>] Defines to which interface broadcasts will be relayed.\n");
++  printf(" [-s] [--ipsec <arg>]      Defines an ipsec tunnel to be relayed to.\n");
++  printf("                           Since ipsec tunnels terminate on the same interface, we need to define the broadcast\n");
++  printf("                           address of the other end-point of the tunnel.  This is done as ipsec0:x.x.x.255\n");
++  printf(" [-v] [--version]          Displays the BCrelay version number.\n");
++  printf("\nLog messages and debugging go to syslog as DAEMON.\n\n");
++  printf("\nInterfaces can be specified as regexpressions, ie. ppp[0-9]+\n\n");
+ }
+ 
+ static void showversion()
+ {
+-        printf("BCrelay v%s\n", VERSION);
++  printf("BCrelay v%s\n", VERSION);
+ }
+ 
+ #ifndef HAVE_DAEMON
+ static void my_daemon(int argc, char **argv)
+ {
+-        pid_t pid;
++  pid_t pid;
+ #ifndef BCRELAY_BIN
+-/* Need a smart way to locate the binary -rdv */
++  /* Need a smart way to locate the binary -rdv */
+ #define BCRELAY_BIN argv[0]
+ #endif
+ #ifndef HAVE_FORK
+-        /* need to use vfork - eg, uClinux */
+-        char **new_argv;
+-        extern char **environ;
+-        int minusd=0;
+-        int i;
+-        int fdr;
+-
+-        /* Strip -d option */
+-        new_argv = malloc((argc) * sizeof(char **));
+-        fdr = open("/dev/null", O_RDONLY);
+-        new_argv[0] = BCRELAY_BIN;
+-        for (i = 1; argv[i] != NULL; i++) {
+-                if (fdr != 0) { dup2(fdr, 0); close(fdr); }
+-                if ( (strcmp(argv[i],"-d")) == 0 ) {
+-                        minusd=1;
+-                }
+-                if (minusd) {
+-                        new_argv[i] = argv[i+1];
+-                } else {
+-                        new_argv[i] = argv[i];
+-                }
+-        }
+-        syslog(LOG_DEBUG, "Option parse OK, re-execing as daemon");
+-        fflush(stderr);
+-        if ((pid = vfork()) == 0) {
+-                if (setsid() < 0) {                      /* shouldn't fail */
+-                        syslog(LOG_ERR, "Setsid failed!");
+-                        _exit(1);
+-                }
+-                chdir("/");
+-                umask(0);
+-                /* execve only returns on an error */
+-                execve(BCRELAY_BIN, new_argv, environ);
+-                exit(1);
+-        } else if (pid > 0) {
+-                syslog(LOG_DEBUG, "Success re-execing as daemon!");
+-                exit(0);
+-        } else {
+-                syslog(LOG_ERR, "Error vforking");
+-                exit(1);
+-        }
+-#else
+-    pid=fork();
+-    if (pid<0) { syslog(LOG_ERR, "Error forking"); _exit(1); }
+-    if (pid>0) { syslog(LOG_DEBUG, "Parent exits"); _exit(0); }
+-    if (pid==0) { syslog(LOG_DEBUG, "Running as child"); }
+-    /* child (daemon) continues */
++  /* need to use vfork - eg, uClinux */
++  char **new_argv;
++  extern char **environ;
++  int minusd=0;
++  int i;
++  int fdr;
++
++  /* Strip -d option */
++  new_argv = malloc((argc) * sizeof(char **));
++  fdr = open("/dev/null", O_RDONLY);
++  new_argv[0] = BCRELAY_BIN;
++  for (i = 1; argv[i] != NULL; i++) {
++    if (fdr != 0) { dup2(fdr, 0); close(fdr); }
++    if ( (strcmp(argv[i],"-d")) == 0 ) {
++      minusd=1;
++    }
++    if (minusd) {
++      new_argv[i] = argv[i+1];
++    } else {
++      new_argv[i] = argv[i];
++    }
++  }
++  syslog(LOG_DEBUG, "Option parse OK, re-execing as daemon");
++  fflush(stderr);
++  if ((pid = vfork()) == 0) {
+     if (setsid() < 0) {                      /* shouldn't fail */
+       syslog(LOG_ERR, "Setsid failed!");
+       _exit(1);
+     }
+     chdir("/");
++    umask(0);
++    /* execve only returns on an error */
++    execve(BCRELAY_BIN, new_argv, environ);
++    exit(1);
++  } else if (pid > 0) {
++    syslog(LOG_DEBUG, "Success re-execing as daemon!");
++    exit(0);
++  } else {
++    syslog(LOG_ERR, "Error vforking");
++    exit(1);
++  }
++#else
++  pid=fork();
++  if (pid<0) { syslog(LOG_ERR, "Error forking"); _exit(1); }
++  if (pid>0) { syslog(LOG_DEBUG, "Parent exits"); _exit(0); }
++  if (pid==0) { syslog(LOG_DEBUG, "Running as child"); }
++  /* child (daemon) continues */
++  if (setsid() < 0) {                      /* shouldn't fail */
++    syslog(LOG_ERR, "Setsid failed!");
++    _exit(1);
++  }
++  chdir("/");
+ #endif
+ }
+ #endif
+@@ -321,78 +333,81 @@ int main(int argc, char **argv) {
+   exit(1);
+ #endif
+ 
+-        /* open a connection to the syslog daemon */
+-        openlog("bcrelay", LOG_PID, PPTP_FACILITY);
++  /* open a connection to the syslog daemon */
++  openlog("bcrelay", LOG_PID, PPTP_FACILITY);
+ 
+   while (1) {
+-                int option_index = 0;
++    int option_index = 0;
+ 
+-                static struct option long_options[] =
+-                {
+-                        {"nolog", 0, 0, 0},
+-                        {"daemon", 0, 0, 0},
+-                        {"help", 0, 0, 0},
+-                        {"incoming", 1, 0, 0},
+-                        {"outgoing", 1, 0, 0},
+-                        {"ipsec", 1, 0, 0},
+-                        {"version", 0, 0, 0},
+-                        {0, 0, 0, 0}
+-                };
+-
+-                c = getopt_long(argc, argv, "ndhi:o:s:v", long_options, &option_index);
+-                if (c == -1)
+-                        break;
+-                /* convert long options to short form */
+-                if (c == 0)
+-                        c = "ndhiosv"[option_index];
+-                switch (c) {
+-                case 'n':
+-                        vnologging = 1;
+-                        break;
+-                case 'd':
+-                        vdaemon = 1;
+-                        break;
+-                case 'h':
+-                        showusage(argv[0]);
+-                        return 0;
+-                case 'i':
+-                        ifin = strdup(optarg);
+-                        break;
+-                case 'o':
+-                        ifout = strdup(optarg);
+-                        break;
+-                case 's':
+-                        ipsec = strdup(optarg);
+-                        // Validate the ipsec parameters
+-                        regcomp(&preg, "ipsec[0-9]+:[0-9]+.[0-9]+.[0-9]+.255", REG_EXTENDED);
+-                        if (regexec(&preg, ipsec, 0, NULL, 0)) {
+-                                syslog(LOG_INFO,"Bad syntax: %s", ipsec);
+-                                fprintf(stderr, "\nBad syntax: %s\n", ipsec);
+-                                showusage(argv[0]);
+-                                return 0;
+-                        } else {
+-                                regfree(&preg);
+-                                break;
+-                        }
+-                case 'v':
+-                        showversion();
+-                        return 0;
+-                default:
+-                        showusage(argv[0]);
+-                        return 1;
+-                }
++    static struct option long_options[] =
++      {
++        {"nolog", 0, 0, 0},
++        {"daemon", 0, 0, 0},
++        {"help", 0, 0, 0},
++        {"incoming", 1, 0, 0},
++        {"outgoing", 1, 0, 0},
++        {"ipsec", 1, 0, 0},
++        {"version", 0, 0, 0},
++        {0, 0, 0, 0}
++      };
++
++    c = getopt_long(argc, argv, "ndhi:o:s:v", long_options, &option_index);
++    if (c == -1)
++      break;
++    /* convert long options to short form */
++    if (c == 0)
++      c = "ndhiosv"[option_index];
++    switch (c) {
++    case 'n':
++      vnologging = 1;
++      break;
++    case 'd':
++      vdaemon = 1;
++      break;
++    case 'h':
++      showusage(argv[0]);
++      return 0;
++    case 'i':
++      ifin = strdup(optarg);
++      break;
++    case 'o':
++      ifout = strdup(optarg);
++      break;
++    case 's':
++      ipsec = strdup(optarg);
++      // Validate the ipsec parameters
++      regcomp(&preg, "ipsec[0-9]+:[0-9]+.[0-9]+.[0-9]+.255", REG_EXTENDED);
++      if (regexec(&preg, ipsec, 0, NULL, 0)) {
++        syslog(LOG_INFO,"Bad syntax: %s", ipsec);
++        fprintf(stderr, "\nBad syntax: %s\n", ipsec);
++        showusage(argv[0]);
++        return 0;
++      } else {
++        regfree(&preg);
++        break;
++      }
++    case 'v':
++      showversion();
++      return 0;
++    default:
++      showusage(argv[0]);
++      return 1;
++    }
+   }
+   if (ifin == empty) {
+-       syslog(LOG_INFO,"Incoming interface required!");
+-       showusage(argv[0]);
+-       _exit(1);
++    syslog(LOG_INFO,"Incoming interface required!");
++    showusage(argv[0]);
++    _exit(1);
+   }
+   if (ifout == empty && ipsec == empty) {
+-       syslog(LOG_INFO,"Listen-mode or outgoing or IPsec interface required!");
+-       showusage(argv[0]);
+-       _exit(1);
+-  } else {
+-        sprintf(interfaces,"%s|%s", ifin, ifout);
++    syslog(LOG_INFO,"Listen-mode or outgoing or IPsec interface required!");
++    showusage(argv[0]);
++    _exit(1);
++  }
++  if (snprintf(reg_interfaces, sizeof(reg_interfaces),
++               "%s|%s", ifin, ifout) >= sizeof(reg_interfaces)) {
++    syslog(LOG_ERR, "interface names exceed size");
++    _exit(1);
+   }
+ 
+   // If specified, become Daemon.
+@@ -426,7 +441,6 @@ static void mainloop(int argc, char **ar
+ {
+   socklen_t salen = sizeof(struct sockaddr_ll);
+   int i, s, rcg, j, no_discifs_cntr, ifs_change;
+-  int logstr_cntr;
+   struct iflist *iflist = NULL;         // Initialised after the 1st packet
+   struct sockaddr_ll sa;
+   struct packet *ipp_p;
+@@ -436,7 +450,10 @@ static void mainloop(int argc, char **ar
+   static struct ifsnr old_ifsnr[MAXIF+1]; // Old iflist to socket fd's mapping list
+   static struct ifsnr cur_ifsnr[MAXIF+1]; // Current iflist to socket fd's mapping list
+   unsigned char buf[1518];
+-  char *logstr = empty;
++
++  char *lptr;           /* log buffer pointer for next chunk append */
++  int lsize = 0;        /* count of remaining unused bytes in log buffer */
++  int chunk;            /* bytes to be added to log buffer by chunk */
+ 
+   no_discifs_cntr = MAX_NODISCOVER_IFS;
+   ifs_change = 0;
+@@ -449,7 +466,8 @@ static void mainloop(int argc, char **ar
+ 
+ 
+   /*
+-   * Discover interfaces (initial set) and create a dedicated socket bound to the interface
++   * Discover interfaces (initial set) and create a dedicated socket
++   * bound to the interface
+    */
+   memset(old_ifsnr, -1, sizeof(old_ifsnr));
+   memset(cur_ifsnr, -1, sizeof(cur_ifsnr));
+@@ -464,313 +482,367 @@ static void mainloop(int argc, char **ar
+   }
+   NVBCR_PRINTF(("Displaying INITIAL active interfaces..\n"));
+   if (vnologging == 0) {
+-    logstr = log_interfaces;
+-    logstr_cntr = sprintf(logstr, "Initial active interfaces: ");
+-    logstr += logstr_cntr;
++    lptr = log_interfaces;
++    lsize = sizeof(log_interfaces);
++    chunk = snprintf(lptr, lsize, "%s ", "Initial active interfaces:");
++    if (chunk < lsize) {
++      lptr += chunk;
++      lsize -= chunk;
++    }
+   }
+   for (i = 0; iflist[i].index; i++)
+-  {
+-    NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
+-    if (vnologging == 0) {
+-      logstr_cntr = sprintf(logstr, "%s ", iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
+-      logstr += logstr_cntr;
++    {
++      NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
++      if (vnologging == 0) {
++        chunk = snprintf(lptr, lsize, "%s ",
++                         iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
++        if (chunk < lsize) {
++          lptr += chunk;
++          lsize -= chunk;
++        }
++      }
+     }
+-  }
+   if (vnologging == 0) syslog(LOG_INFO, "%s", log_interfaces);
+ 
+   // Main loop
+   while (1)
+-  {
+-
+-    /* 
+-     * Check all (interface) sockets for incoming packets
+-     */
+-    FD_ZERO(&sock_set);
+-    for (i=0; iflist[i].index; ++i)
+-    {
+-      if (cur_ifsnr[i].sock_nr >= 0) {
+-        FD_SET(cur_ifsnr[i].sock_nr, &sock_set);
+-      }
+-    }
+-
+-    /*
+-     * Don't wait more than MAX_SELECT_WAIT seconds
+-     */
+-    time_2_wait.tv_sec = MAX_SELECT_WAIT;
+-    time_2_wait.tv_usec = 0L;
+-
+-    /* select on sockets */
+-    rcg = select(MAXIF, &sock_set, (fd_set *) NULL,(fd_set *) NULL, &time_2_wait);
+-
+-    if (rcg < 0)
+     {
+-      syslog(LOG_ERR, "Error, select error! (rv=%d, errno=%d)", rcg, errno);
+-      exit(1);
+-    }
+ 
+-    if (rcg == 0)
+-    {
+-      /* TimeOut, rediscover interfaces */
+-      NVBCR_PRINTF(("Select timeout, rediscover interfaces\n"));
+-      copy_ifsnr(cur_ifsnr, old_ifsnr);
+-      memset(cur_ifsnr, -1, sizeof(cur_ifsnr));
+-      iflist = discoverActiveInterfaces(s);
+       /*
+-       * Build new cur_ifsnr list.
+-       * Make iflist[i] correspond with cur_ifsnr[i], so iflist[i].index == cur_ifsnr[i].ifindex
+-       * The old list (old_ifsnr) is used to compare.
++       * Check all (interface) sockets for incoming packets
+        */
+-      for (i=0; iflist[i].index; ++i) {
+-        /* check to see if it is a NEW interface */
+-        int fsnr = find_sock_nr(old_ifsnr, iflist[i].index);
+-        if (fsnr == -1) {
+-          /* found new interface, open dedicated socket and bind it to the interface */
+-          if ((cur_ifsnr[i].sock_nr = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 0) {
+-            syslog(LOG_ERR, "mainloop: Error, socket error! (rv=%d, errno=%d)", cur_ifsnr[i].sock_nr, errno);
+-            exit(1);
+-          }
+-          bind_to_iface(cur_ifsnr[i].sock_nr, iflist[i].index);
+-          ifs_change = 1;
+-        }
+-        else
++      FD_ZERO(&sock_set);
++      for (i=0; iflist[i].index; ++i)
+         {
+-          /*
+-           * not a new interface, socket already openen, interface already
+-           * bound. Update cur_ifsnr.
+-           */
+-          cur_ifsnr[i].sock_nr = fsnr;
+-        }
+-        cur_ifsnr[i].ifindex = iflist[i].index;
+-      }
+-      /* Close disappeared interfaces */
+-      for (i=0; i<MAXIF; ++i)
+-      {
+-        if ((old_ifsnr[i].sock_nr != -1) && (old_ifsnr[i].ifindex != -1) &&
+-            (find_sock_nr(cur_ifsnr, old_ifsnr[i].ifindex) == -1)) {
+-          NVBCR_PRINTF(("Closing an interface (it disappeared), namely: (s_nr=%d, ifidx=%d)\n", old_ifsnr[i].sock_nr, old_ifsnr[i].ifindex));
+-          close(old_ifsnr[i].sock_nr);
+-          old_ifsnr[i].sock_nr = -1;
+-          old_ifsnr[i].ifindex = -1;
+-          ifs_change = 1;
+-        }
+-      }
+-      if (ifs_change == 1)
+-      {
+-        NVBCR_PRINTF(("Active interface set changed --> displaying current active interfaces..\n"));
+-        if (vnologging == 0) {
+-          logstr = log_interfaces;
+-          logstr_cntr = sprintf(logstr, "Active interface set changed to: ");
+-          logstr += logstr_cntr;
+-        }
+-        for (i = 0; iflist[i].index; i++)
+-        {
+-          NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
+-          if (vnologging == 0) {
+-            logstr_cntr = sprintf(logstr, "%s ", iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
+-            logstr += logstr_cntr;
++          if (cur_ifsnr[i].sock_nr >= 0) {
++            FD_SET(cur_ifsnr[i].sock_nr, &sock_set);
+           }
+         }
+-        if (vnologging == 0) syslog(LOG_INFO, "%s", log_interfaces);
+-        ifs_change = 0;
+-      }
+-      continue;
+-    }
+ 
+-    if (rcg > 0)
+-    {
+-      /* rcg interfaces have pending input */
+-      for (i=0; ((iflist[i].index != 0) && (rcg > 0)); ++i)
+-      {
+-        if ((cur_ifsnr[i].sock_nr != -1) && (FD_ISSET(cur_ifsnr[i].sock_nr,&sock_set)))
+-        {
+-          /* Valid socket number and pending input, let's read */
+-          int rlen = read(cur_ifsnr[i].sock_nr, buf, sizeof(buf));
+-          ipp_p = (struct packet *)&(buf[0]);
+-          NVBCR_PRINTF(("IP_Packet=(tot_len=%d, id=%02x%02x, ttl=%d, prot=%s, src_ip=%d.%d.%d.%d, dst_ip=%d.%d.%d.%d) (on if: %d/%d) ", ntohs(ipp_p->ip.tot_len), (ntohs(ipp_p->ip.id))>>8, (ntohs(ipp_p->ip.id))&0x00ff, ipp_p->ip.ttl, IpProtToString(ipp_p->ip.protocol), (ntohl(ipp_p->ip.saddr))>>24, ((ntohl(ipp_p->ip.saddr))&0x00ff0000)>>16, ((ntohl(ipp_p->ip.saddr))&0x0000ff00)>>8, (ntohl(ipp_p->ip.saddr))&0x000000ff, (ntohl(ipp_p->ip.daddr))>>24, ((ntohl(ipp_p->ip.daddr))&0x00ff0000)>>16, ((ntohl(ipp_p->ip.daddr))&0x0000ff00)>>8, (ntohl(ipp_p->ip.daddr))&0x000000ff, i, iflist[i].index));
+-          rcg -= 1;
+-
+-          if ( (ipp_p->ip.protocol == IPPROTO_UDP) &&
+-               (((ntohl(ipp_p->ip.daddr)) & 0x000000ff) == 0x000000ff) &&
+-               (ipp_p->ip.ttl != 1) &&
+-               (!((*IP_UDPPDU_CHECKSUM_MSB_PTR((unsigned char *)ipp_p+(4*ipp_p->ip.ihl)) == 0) &&
+-               (*IP_UDPPDU_CHECKSUM_LSB_PTR((unsigned char *)ipp_p+(4*ipp_p->ip.ihl)) == 0))) )
+-          {
+-            int nrsent;
+-            int ifindex_to_exclude = iflist[i].index;
++      /*
++       * Don't wait more than MAX_SELECT_WAIT seconds
++       */
++      time_2_wait.tv_sec = MAX_SELECT_WAIT;
++      time_2_wait.tv_usec = 0L;
+ 
+-            NVBCR_PRINTF(("is an UDP BROADCAST (dstPort=%d, srcPort=%d) (with TTL!=1 and UDP_CHKSUM!=0)\n\n",
+-                           ntohs(ipp_p->udp.dest), ntohs(ipp_p->udp.source)));
+-            if (vnologging == 0) {
+-              logstr = log_relayed;
+-              logstr_cntr = sprintf(logstr, "UDP_BroadCast(sp=%d,dp=%d) from: %s relayed to: ", ntohs(ipp_p->udp.source),
+-                                    ntohs(ipp_p->udp.dest), iflistLogRToString(&(iflist[i]), i, &(cur_ifsnr[i])));
+-              logstr += logstr_cntr;
+-            }
++      /* select on sockets */
++      rcg = select(MAXIF, &sock_set, (fd_set *) NULL,(fd_set *) NULL, &time_2_wait);
+ 
+-            /* going to relay a broadcast packet on all the other interfaces */
+-            for (j=0; iflist[j].index; ++j)
+-            {
+-              int prepare_ipp = 0; // Changing the incoming UDP broadcast needs to be done once
++      if (rcg < 0)
++        {
++          syslog(LOG_ERR, "Error, select error! (rv=%d, errno=%d)", rcg, errno);
++          exit(1);
++        }
+ 
+-              if (iflist[j].index != ifindex_to_exclude)
++      if (rcg == 0)
++        {
++          /* TimeOut, rediscover interfaces */
++          NVBCR_PRINTF(("Select timeout, rediscover interfaces\n"));
++          copy_ifsnr(cur_ifsnr, old_ifsnr);
++          memset(cur_ifsnr, -1, sizeof(cur_ifsnr));
++          iflist = discoverActiveInterfaces(s);
++          /*
++           * Build new cur_ifsnr list.  Make iflist[i] correspond with
++           * cur_ifsnr[i], so iflist[i].index == cur_ifsnr[i].ifindex
++           * The old list (old_ifsnr) is used to compare.
++           */
++          for (i=0; iflist[i].index; ++i) {
++            /* check to see if it is a NEW interface */
++            int fsnr = find_sock_nr(old_ifsnr, iflist[i].index);
++            if (fsnr == -1) {
++              /* found new interface, open dedicated socket and bind
++              it to the interface */
++              if ((cur_ifsnr[i].sock_nr = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 0) {
++                syslog(LOG_ERR, "mainloop: Error, socket error! (rv=%d, errno=%d)", cur_ifsnr[i].sock_nr, errno);
++                exit(1);
++              }
++              bind_to_iface(cur_ifsnr[i].sock_nr, iflist[i].index);
++              ifs_change = 1;
++            }
++            else
+               {
+-                NVBCR_PRINTF(("Going to sent UDP Broadcast on interface: %s, sock_nr=%d\n", iflistToString(&(iflist[j])), cur_ifsnr[j].sock_nr));
+-
+-                memset(&sa, 0, salen);
+-
+-                sa.sll_family          = AF_PACKET;
+-                sa.sll_ifindex = iflist[j].index; /* Must be the SIOCGIFINDEX number */
+-                // Set the outgoing hardware address to 1's.  True Broadcast
+-                sa.sll_addr[0] = sa.sll_addr[1] = sa.sll_addr[2] = sa.sll_addr[3] = 0xff;
+-                sa.sll_addr[4] = sa.sll_addr[5] = sa.sll_addr[6] = sa.sll_addr[7] = 0xff;
+-                sa.sll_halen = 6;
+-
+                 /*
+-                 * htons(ETH_P_IP) is necessary otherwise sendto will
+-                 * succeed but no packet is actually sent on the wire (this
+-                 * was the case for PPP interfaces, for ETH interfaces an unknown
+-                 * LAN frame is sent if htons(ETH_P_IP) is not set as protocol).
++                 * not a new interface, socket already openen,
++                 * interface already bound. Update cur_ifsnr.
+                  */
+-                sa.sll_protocol = htons(ETH_P_IP); /* ETH_P_PPP_MP */
++                cur_ifsnr[i].sock_nr = fsnr;
++              }
++            cur_ifsnr[i].ifindex = iflist[i].index;
++          }
++          /* Close disappeared interfaces */
++          for (i=0; i<MAXIF; ++i)
++            {
++              if ((old_ifsnr[i].sock_nr != -1) && (old_ifsnr[i].ifindex != -1) &&
++                  (find_sock_nr(cur_ifsnr, old_ifsnr[i].ifindex) == -1)) {
++                NVBCR_PRINTF(("Closing an interface (it disappeared), namely: (s_nr=%d, ifidx=%d)\n", old_ifsnr[i].sock_nr, old_ifsnr[i].ifindex));
++                close(old_ifsnr[i].sock_nr);
++                old_ifsnr[i].sock_nr = -1;
++                old_ifsnr[i].ifindex = -1;
++                ifs_change = 1;
++              }
++            }
++          if (ifs_change == 1)
++            {
++              NVBCR_PRINTF(("Active interface set changed --> displaying current active interfaces..\n"));
++              if (vnologging == 0) {
++                lptr = log_interfaces;
++                lsize = sizeof(log_interfaces);
++                chunk = snprintf(lptr, lsize, "%s ",
++                                 "Active interface set changed to:");
++                if (chunk < lsize) {
++                  lptr += chunk;
++                  lsize -= chunk;
++                }
++              }
++              for (i = 0; iflist[i].index; i++)
++                {
++                  NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
++                  if (vnologging == 0) {
++                    chunk = snprintf(lptr, lsize, "%s ",
++                                           iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
++                    if (chunk < lsize) {
++                      lptr += chunk;
++                      lsize -= chunk;
++                    }
++                  }
++                }
++              if (vnologging == 0) syslog(LOG_INFO, "%s", log_interfaces);
++              ifs_change = 0;
++            }
++          continue;
++        }
++
++      if (rcg > 0)
++        {
++          /* rcg interfaces have pending input */
++          for (i=0; ((iflist[i].index != 0) && (rcg > 0)); ++i)
++            {
++              if ((cur_ifsnr[i].sock_nr != -1) && (FD_ISSET(cur_ifsnr[i].sock_nr,&sock_set)))
++                {
++                  /* Valid socket number and pending input, let's read */
++                  int rlen = read(cur_ifsnr[i].sock_nr, buf, sizeof(buf));
++                  ipp_p = (struct packet *)&(buf[0]);
++                  NVBCR_PRINTF(("IP_Packet=(tot_len=%d, id=%02x%02x, ttl=%d, prot=%s, src_ip=%d.%d.%d.%d, dst_ip=%d.%d.%d.%d) (on if: %d/%d) ", ntohs(ipp_p->ip.tot_len), (ntohs(ipp_p->ip.id))>>8, (ntohs(ipp_p->ip.id))&0x00ff, ipp_p->ip.ttl, IpProtToString(ipp_p->ip.protocol), (ntohl(ipp_p->ip.saddr))>>24, ((ntohl(ipp_p->ip.saddr))&0x00ff0000)>>16, ((ntohl(ipp_p->ip.saddr))&0x0000ff00)>>8, (ntohl(ipp_p->ip.saddr))&0x000000ff, (ntohl(ipp_p->ip.daddr))>>24, ((ntohl(ipp_p->ip.daddr))&0x00ff0000)>>16, ((ntohl(ipp_p->ip.daddr))&0x0000ff00)>>8, (ntohl(ipp_p->ip.daddr))&0x000000ff, i, iflist[i].index));
++                  rcg -= 1;
++
++                  if ( (ipp_p->ip.protocol == IPPROTO_UDP) &&
++                       (((ntohl(ipp_p->ip.daddr)) & 0x000000ff) == 0x000000ff) &&
++                       (ipp_p->ip.ttl != 1) &&
++                       (!((*IP_UDPPDU_CHECKSUM_MSB_PTR((unsigned char *)ipp_p+(4*ipp_p->ip.ihl)) == 0) &&
++                          (*IP_UDPPDU_CHECKSUM_LSB_PTR((unsigned char *)ipp_p+(4*ipp_p->ip.ihl)) == 0))) )
++                    {
++                      int nrsent;
++                      int ifindex_to_exclude = iflist[i].index;
++
++                      NVBCR_PRINTF(("is an UDP BROADCAST (dstPort=%d, srcPort=%d) (with TTL!=1 and UDP_CHKSUM!=0)\n\n",
++                                    ntohs(ipp_p->udp.dest), ntohs(ipp_p->udp.source)));
++                      if (vnologging == 0) {
++                        lptr = log_relayed;
++                        lsize = sizeof(log_relayed);
++                        chunk = snprintf(lptr, lsize,
++                                         "UDP_BroadCast(sp=%d,dp=%d) from: %s relayed to: ",
++                                         ntohs(ipp_p->udp.source),
++                                         ntohs(ipp_p->udp.dest),
++                                         iflistLogRToString(&(iflist[i]), i, &(cur_ifsnr[i])));
++                        if (chunk < lsize) {
++                          lptr += chunk;
++                          lsize -= chunk;
++                        }
++                      }
+ 
+-                if (prepare_ipp == 0) {
+-                  // change TimeToLive to 1, This is to avoid loops, bcrelay will *NOT* relay
+-                  // anything with TTL==1.
+-                  ipp_p->ip.ttl = 1;
++                      /* going to relay a broadcast packet on all the
++                      other interfaces */
++                      for (j=0; iflist[j].index; ++j)
++                        {
++                          int prepare_ipp = 0; // Changing the incoming UDP broadcast needs to be done once
++
++                          if (iflist[j].index != ifindex_to_exclude)
++                            {
++                              NVBCR_PRINTF(("Going to sent UDP Broadcast on interface: %s, sock_nr=%d\n", iflistToString(&(iflist[j])), cur_ifsnr[j].sock_nr));
++
++                              memset(&sa, 0, salen);
++
++                              sa.sll_family          = AF_PACKET;
++                              sa.sll_ifindex = iflist[j].index; /* Must be the SIOCGIFINDEX number */
++                              // Set the outgoing hardware address to 1's.  True Broadcast
++                              sa.sll_addr[0] = sa.sll_addr[1] = sa.sll_addr[2] = sa.sll_addr[3] = 0xff;
++                              sa.sll_addr[4] = sa.sll_addr[5] = sa.sll_addr[6] = sa.sll_addr[7] = 0xff;
++                              sa.sll_halen = 6;
++
++                              /*
++                               * htons(ETH_P_IP) is necessary
++                               * otherwise sendto will succeed but no
++                               * packet is actually sent on the wire
++                               * (this was the case for PPP
++                               * interfaces, for ETH interfaces an
++                               * unknown LAN frame is sent if
++                               * htons(ETH_P_IP) is not set as
++                               * protocol).
++                               */
++                              sa.sll_protocol = htons(ETH_P_IP); /* ETH_P_PPP_MP */
++
++                              if (prepare_ipp == 0) {
++                                // change TimeToLive to 1, This is to
++                                // avoid loops, bcrelay will *NOT*
++                                // relay anything with TTL==1.
++                                ipp_p->ip.ttl = 1;
+   
+-                  // The CRC gets broken here when sending over ipsec tunnels but that
+-                  // should not matter as we reassemble the packet at the other end.
+-                  ipp_p->ip.daddr = iflist[j].bcast;
++                                // The CRC gets broken here when
++                                // sending over ipsec tunnels but that
++                                // should not matter as we reassemble
++                                // the packet at the other end.
++                                ipp_p->ip.daddr = iflist[j].bcast;
+   
+-                  // check IP srcAddr (on some winXP boxes it is found to be
+-                  // different from the configured ppp address).
+-                  // Only do this for PPP interfaces.
+-                  if ((iflist[i].flags1 & IFLIST_FLAGS1_IF_IS_PPP) &&
+-                      (ntohl(ipp_p->ip.saddr) != iflist[i].ifdstaddr))
+-                  {
+-                    ipp_p->ip.saddr = htonl(iflist[i].ifdstaddr);
+-                    iflist[i].flags1 |= IFLIST_FLAGS1_CHANGED_INNER_SADDR;
+-                  }
++                                // check IP srcAddr (on some winXP
++                                // boxes it is found to be different
++                                // from the configured ppp address).
++                                // Only do this for PPP interfaces.
++                                if ((iflist[i].flags1 & IFLIST_FLAGS1_IF_IS_PPP) &&
++                                    (ntohl(ipp_p->ip.saddr) != iflist[i].ifdstaddr))
++                                  {
++                                    ipp_p->ip.saddr = htonl(iflist[i].ifdstaddr);
++                                    iflist[i].flags1 |= IFLIST_FLAGS1_CHANGED_INNER_SADDR;
++                                  }
+   
+-                  // Update IP checkSum (TTL and src/dest IP Address might have changed)
+-                  ip_update_checksum((unsigned char *)ipp_p);
+-                  /* Disable upper layer checksum */
+-                  udppdu = (unsigned char *)ipp_p + (4 * ipp_p->ip.ihl);
+-                  *IP_UDPPDU_CHECKSUM_MSB_PTR(udppdu) = (unsigned char)0;
+-                  *IP_UDPPDU_CHECKSUM_LSB_PTR(udppdu) = (unsigned char)0;
+-
+-                  prepare_ipp = 1;
++                                // Update IP checkSum (TTL and
++                                // src/dest IP Address might have
++                                // changed)
++                                ip_update_checksum((unsigned char *)ipp_p);
++                                /* Disable upper layer checksum */
++                                udppdu = (unsigned char *)ipp_p + (4 * ipp_p->ip.ihl);
++                                *IP_UDPPDU_CHECKSUM_MSB_PTR(udppdu) = (unsigned char)0;
++                                *IP_UDPPDU_CHECKSUM_LSB_PTR(udppdu) = (unsigned char)0;
++
++                                prepare_ipp = 1;
++                              }
++
++                              /*
++                               * The beauty of sending IP packets on a
++                               * PACKET socket of type SOCK_DGRAM is
++                               * that there is no need to concern
++                               * about the physical/link layer header
++                               * because it is filled in automatically
++                               * (based on the contents of sa).
++                               */
++                              if ((nrsent = sendto(cur_ifsnr[j].sock_nr, ipp_p, rlen, MSG_DONTWAIT|MSG_TRYHARD, (struct sockaddr *)&sa, salen)) < 0)
++                                {
++                                  if (errno == ENETDOWN) {
++                                    syslog(LOG_NOTICE, "ignored ENETDOWN from sendto(), a network interface was going down?");
++                                  } else if (errno == ENXIO) {
++                                    syslog(LOG_NOTICE, "ignored ENXIO from sendto(), a network interface went down?");
++                                  } else if (errno == ENOBUFS) {
++                                    syslog(LOG_NOTICE, "ignored ENOBUFS from sendto(), temporary shortage of buffer memory");
++                                  } else {
++                                    syslog(LOG_ERR, "mainloop: Error, sendto failed! (rv=%d, errno=%d)", nrsent, errno);
++                                    exit(1);
++                                  }
++                                }
++                              NVBCR_PRINTF(("Successfully relayed %d bytes \n", nrsent));
++                              if (vnologging == 0) {
++                                chunk = snprintf(lptr, lsize, "%s ",
++                                                 iflistLogRToString(&(iflist[j]), j, &(cur_ifsnr[j])));
++                                if (chunk < lsize) {
++                                  lptr += chunk;
++                                  lsize -= chunk;
++                                }
++                              }
++                            }
++                        }
++                      if (vnologging == 0) syslog(LOG_INFO, "%s", log_relayed);
++                    } else {
++                    NVBCR_PRINTF(("is NOT an UDP BROADCAST (with TTL!=1 and UDP_CHKSUM!=0)\n\n"));
++                  }
+                 }
++            }
++          /*
++           * Don't forget to discover new interfaces if we keep
++           * getting incoming packets (on an already discovered
++           * interface).
++           */
++          if (no_discifs_cntr == 0)
++            {
++              no_discifs_cntr = MAX_NODISCOVER_IFS;
+ 
+-                /*
+-                 * The beauty of sending IP packets on a PACKET socket of type SOCK_DGRAM is that
+-                 * there is no need to concern about the physical/link layer header because it is
+-                 * filled in automatically (based on the contents of sa).
+-                 */
+-                if ((nrsent = sendto(cur_ifsnr[j].sock_nr, ipp_p, rlen, MSG_DONTWAIT|MSG_TRYHARD, (struct sockaddr *)&sa, salen)) < 0)
+-                {
+-                  if (errno == ENETDOWN) {
+-                    syslog(LOG_NOTICE, "ignored ENETDOWN from sendto(), a network interface was going down?");
+-                  } else if (errno == ENXIO) {
+-                    syslog(LOG_NOTICE, "ignored ENXIO from sendto(), a network interface went down?");
+-                  } else if (errno == ENOBUFS) {
+-                    syslog(LOG_NOTICE, "ignored ENOBUFS from sendto(), temporary shortage of buffer memory");
+-                  } else {
+-                    syslog(LOG_ERR, "mainloop: Error, sendto failed! (rv=%d, errno=%d)", nrsent, errno);
++              /* no_discifs_cntr became 0, rediscover interfaces */
++              NVBCR_PRINTF(("no_discifs_cntr became 0, rediscover interfaces\n"));
++              copy_ifsnr(cur_ifsnr, old_ifsnr);
++              memset(cur_ifsnr, -1, sizeof(cur_ifsnr));
++              iflist = discoverActiveInterfaces(s);
++              /*
++               * Build new cur_ifsnr list.
++               * Make iflist[i] correspond with cur_ifsnr[i], so iflist[i].index == cur_ifsnr[i].ifindex
++               * The old list (old_ifsnr) is used to compare.
++               */
++              for (i=0; iflist[i].index; ++i) {
++                /* check to see if it is a NEW interface */
++                int fsnr = find_sock_nr(old_ifsnr, iflist[i].index);
++                if (fsnr == -1) {
++                  /* found new interface, open dedicated socket and
++                  bind it to the interface */
++                  if ((cur_ifsnr[i].sock_nr = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 0) {
++                    syslog(LOG_ERR, "mainloop: Error, socket error! (rv=%d, errno=%d)", cur_ifsnr[i].sock_nr, errno);
+                     exit(1);
+                   }
++                  bind_to_iface(cur_ifsnr[i].sock_nr, iflist[i].index);
++                  ifs_change = 1;
+                 }
+-                NVBCR_PRINTF(("Successfully relayed %d bytes \n", nrsent));
+-                if (vnologging == 0) {
+-                  logstr_cntr = sprintf(logstr, "%s ", iflistLogRToString(&(iflist[j]), j, &(cur_ifsnr[j])));
+-                  logstr += logstr_cntr;
+-                }
++                else
++                  {
++                    /*
++                     * not a new interface, socket already opened,
++                     * interface already bound. Update cur_ifsnr.
++                     */
++                    cur_ifsnr[i].sock_nr = fsnr;
++                  }
++                cur_ifsnr[i].ifindex = iflist[i].index;
+               }
++              /* Close disappeared interfaces */
++              for (i=0; i<MAXIF; ++i)
++                {
++                  if ((old_ifsnr[i].sock_nr != -1) && (old_ifsnr[i].ifindex != -1) &&
++                      (find_sock_nr(cur_ifsnr, old_ifsnr[i].ifindex) == -1)) {
++                    NVBCR_PRINTF(("Closing an interface (it disappeared), namely: (s_nr=%d, ifidx=%d)\n", old_ifsnr[i].sock_nr, old_ifsnr[i].ifindex));
++                    close(old_ifsnr[i].sock_nr);
++                    old_ifsnr[i].sock_nr = -1;
++                    old_ifsnr[i].ifindex = -1;
++                    ifs_change = 1;
++                  }
++                }
++              if (ifs_change == 1)
++                {
++                  NVBCR_PRINTF(("Active interface set changed --> displaying current active interfaces..\n"));
++                  if (vnologging == 0) {
++                    lptr = log_interfaces;
++                    lsize = sizeof(log_interfaces);
++                    chunk = snprintf(lptr, lsize, "%s ",
++                                     "Active interface set changed to:");
++                    if (chunk < lsize) {
++                      lptr += chunk;
++                      lsize -= chunk;
++                    }
++                  }
++                  for (i = 0; iflist[i].index; i++)
++                    {
++                      NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
++                      if (vnologging == 0) {
++                        chunk = snprintf(lptr, lsize, "%s ",
++                                         iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
++                        if (chunk < lsize) {
++                          lptr += chunk;
++                          lsize -= chunk;
++                        }
++                      }
++                    }
++                  if (vnologging == 0) syslog(LOG_INFO, "%s", log_interfaces);
++                  ifs_change = 0;
++                }
+             }
+-            if (vnologging == 0) syslog(LOG_INFO, "%s", log_relayed);
+-          } else {
+-            NVBCR_PRINTF(("is NOT an UDP BROADCAST (with TTL!=1 and UDP_CHKSUM!=0)\n\n"));
+-          }
+-        }
+-      }
+-      /*
+-       * Don't forget to discover new interfaces if we keep getting
+-       * incoming packets (on an already discovered interface).
+-       */
+-      if (no_discifs_cntr == 0)
+-      {
+-        no_discifs_cntr = MAX_NODISCOVER_IFS;
+-
+-        /* no_discifs_cntr became 0, rediscover interfaces */
+-        NVBCR_PRINTF(("no_discifs_cntr became 0, rediscover interfaces\n"));
+-        copy_ifsnr(cur_ifsnr, old_ifsnr);
+-        memset(cur_ifsnr, -1, sizeof(cur_ifsnr));
+-        iflist = discoverActiveInterfaces(s);
+-        /*
+-         * Build new cur_ifsnr list.
+-         * Make iflist[i] correspond with cur_ifsnr[i], so iflist[i].index == cur_ifsnr[i].ifindex
+-         * The old list (old_ifsnr) is used to compare.
+-         */
+-        for (i=0; iflist[i].index; ++i) {
+-          /* check to see if it is a NEW interface */
+-          int fsnr = find_sock_nr(old_ifsnr, iflist[i].index);
+-          if (fsnr == -1) {
+-            /* found new interface, open dedicated socket and bind it to the interface */
+-            if ((cur_ifsnr[i].sock_nr = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 0) {
+-              syslog(LOG_ERR, "mainloop: Error, socket error! (rv=%d, errno=%d)", cur_ifsnr[i].sock_nr, errno);
+-              exit(1);
+-            }
+-            bind_to_iface(cur_ifsnr[i].sock_nr, iflist[i].index);
+-            ifs_change = 1;
+-          }
+           else
+-          {
+-            /*
+-             * not a new interface, socket already openen, interface already
+-             * bound. Update cur_ifsnr.
+-             */
+-            cur_ifsnr[i].sock_nr = fsnr;
+-          }
+-          cur_ifsnr[i].ifindex = iflist[i].index;
+-        }
+-        /* Close disappeared interfaces */
+-        for (i=0; i<MAXIF; ++i)
+-        {
+-          if ((old_ifsnr[i].sock_nr != -1) && (old_ifsnr[i].ifindex != -1) &&
+-              (find_sock_nr(cur_ifsnr, old_ifsnr[i].ifindex) == -1)) {
+-            NVBCR_PRINTF(("Closing an interface (it disappeared), namely: (s_nr=%d, ifidx=%d)\n", old_ifsnr[i].sock_nr, old_ifsnr[i].ifindex));
+-            close(old_ifsnr[i].sock_nr);
+-            old_ifsnr[i].sock_nr = -1;
+-            old_ifsnr[i].ifindex = -1;
+-            ifs_change = 1;
+-          }
+-        }
+-        if (ifs_change == 1)
+-        {
+-          NVBCR_PRINTF(("Active interface set changed --> displaying current active interfaces..\n"));
+-          if (vnologging == 0) {
+-            logstr = log_interfaces;
+-            logstr_cntr = sprintf(logstr, "Active interface set changed to: ");
+-            logstr += logstr_cntr;
+-          }
+-          for (i = 0; iflist[i].index; i++)
+-          {
+-            NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
+-            if (vnologging == 0) {
+-              logstr_cntr = sprintf(logstr, "%s ", iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
+-              logstr += logstr_cntr;
++            {
++              no_discifs_cntr -= MAX_SELECT_WAIT;
+             }
+-          }
+-          if (vnologging == 0) syslog(LOG_INFO, "%s", log_interfaces);
+-          ifs_change = 0;
+         }
+-      }
+-      else
+-      {
+-        no_discifs_cntr -= MAX_SELECT_WAIT;
+-      }
+     }
+-  }
+ }
+ 
+ // Discover active interfaces
+@@ -788,102 +860,102 @@ discoverActiveInterfaces(int s) {
+   /* Reset ifs */
+   memset(&ifs, 0, sizeof(ifs));
+ 
+-  //regcomp(&preg, argv[1], REG_ICASE|REG_EXTENDED);
+-  regcomp(&preg, interfaces, REG_ICASE|REG_EXTENDED);
++  regcomp(&preg, reg_interfaces, REG_ICASE|REG_EXTENDED);
+   ifs.ifc_len = MAXIF*sizeof(struct ifreq);
+   ifs.ifc_req = malloc(ifs.ifc_len);
+   ioctl(s, SIOCGIFCONF, &ifs);                  // Discover active interfaces
+   for (i = 0; i * sizeof(struct ifreq) < ifs.ifc_len && cntr < MAXIF; i++)
+-  {
+-    if (regexec(&preg, ifs.ifc_req[i].ifr_name, 0, NULL, 0) == 0) {
+-
+-      /*
+-       * Get interface flags and check status and type.
+-       * Only if interface is up it will be used.
+-       */
+-      memset(&ifrflags, 0, sizeof(ifrflags));
+-      strncpy(ifrflags.ifr_name, ifs.ifc_req[i].ifr_name, strlen(ifs.ifc_req[i].ifr_name));
+-      if (ioctl(s, SIOCGIFFLAGS, &ifrflags) < 0) {
+-        syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFFLAGS Failed! (errno=%d)", errno);
+-        exit(1);
+-      }
+-
+-      if (ifrflags.ifr_flags & IFF_UP)
+-      {
+-        /*
+-         * Get interface index
+-         */
+-        ioctl(s, SIOCGIFINDEX, &ifs.ifc_req[i]);
+-//Fix 3mar2003
+-        //iflist[cntr].index = (char)ifs.ifc_req[i].ifr_ifindex;
+-        iflist[cntr].index = ifs.ifc_req[i].ifr_ifindex;
+-
+-        /*
+-         * Get interface name
+-         */
+-        strncpy(iflist[cntr].ifname, ifs.ifc_req[i].ifr_ifrn.ifrn_name,
+-                sizeof(iflist[cntr].ifname));
+-        iflist[cntr].ifname[sizeof(iflist[cntr].ifname)-1] = 0;
++    {
++      if (regexec(&preg, ifs.ifc_req[i].ifr_name, 0, NULL, 0) == 0) {
+ 
+         /*
+-         * Get local IP address 
++         * Get interface flags and check status and type.
++         * Only if interface is up it will be used.
+          */
+-        memset(&ifr, 0, sizeof(ifr));
+-        ifr.ifr_addr.sa_family = AF_INET;
+-        (void)strncpy(ifr.ifr_name, iflist[cntr].ifname, strlen(iflist[cntr].ifname)+1);
+-        if (ioctl(s, SIOCGIFADDR, (char *)&ifr) < 0) {
+-          syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFADDR Failed! (errno=%d)", errno);
++        memset(&ifrflags, 0, sizeof(ifrflags));
++        strncpy(ifrflags.ifr_name, ifs.ifc_req[i].ifr_name, strlen(ifs.ifc_req[i].ifr_name));
++        if (ioctl(s, SIOCGIFFLAGS, &ifrflags) < 0) {
++          syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFFLAGS Failed! (errno=%d)", errno);
+           exit(1);
+         }
+-        sin = (struct sockaddr_in *)&ifr.ifr_addr;
+-        iflist[cntr].ifaddr = ntohl(sin->sin_addr.s_addr);
+ 
+-        iflist[cntr].flags1 = 0;
++        if (ifrflags.ifr_flags & IFF_UP)
++          {
++            /*
++             * Get interface index
++             */
++            ioctl(s, SIOCGIFINDEX, &ifs.ifc_req[i]);
++            //Fix 3mar2003
++            //iflist[cntr].index = (char)ifs.ifc_req[i].ifr_ifindex;
++            iflist[cntr].index = ifs.ifc_req[i].ifr_ifindex;
+ 
+-        if (ifrflags.ifr_flags & IFF_POINTOPOINT) {
+-          /*
+-           * Get remote IP address (only for PPP interfaces)
+-           */
+-          memset(&ifr, 0, sizeof(ifr));
+-          ifr.ifr_addr.sa_family = AF_INET;
+-          (void)strncpy(ifr.ifr_name, iflist[cntr].ifname, strlen(iflist[cntr].ifname)+1);
+-          if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifr) < 0) {
+-            syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFDSTADDR Failed! (errno=%d)", errno);
+-            exit(1);
+-          }
+-          sin = (struct sockaddr_in *)&ifr.ifr_addr;
+-          iflist[cntr].ifdstaddr = ntohl(sin->sin_addr.s_addr);
++            /*
++             * Get interface name
++             */
++            strncpy(iflist[cntr].ifname, ifs.ifc_req[i].ifr_ifrn.ifrn_name,
++                    sizeof(iflist[cntr].ifname));
++            iflist[cntr].ifname[sizeof(iflist[cntr].ifname)-1] = 0;
+ 
+-          iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_PPP;
+-          iflist[cntr].bcast = INADDR_BROADCAST;
+-        }
+-        else if (ifrflags.ifr_flags & IFF_BROADCAST)
+-        {
+-          iflist[cntr].ifdstaddr = 0;
+-          iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_ETH;
+-          iflist[cntr].bcast = INADDR_BROADCAST;
+-        }
+-        else
+-        {
+-          iflist[cntr].ifdstaddr = 0;
+-          iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_UNKNOWN;
+-          iflist[cntr].bcast = INADDR_BROADCAST;
+-        }
++            /*
++             * Get local IP address 
++             */
++            memset(&ifr, 0, sizeof(ifr));
++            ifr.ifr_addr.sa_family = AF_INET;
++            (void)strncpy(ifr.ifr_name, iflist[cntr].ifname, strlen(iflist[cntr].ifname)+1);
++            if (ioctl(s, SIOCGIFADDR, (char *)&ifr) < 0) {
++              syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFADDR Failed! (errno=%d)", errno);
++              exit(1);
++            }
++            sin = (struct sockaddr_in *)&ifr.ifr_addr;
++            iflist[cntr].ifaddr = ntohl(sin->sin_addr.s_addr);
+ 
+-        cntr++;
+-      }
+-    // IPSEC tunnels are a fun one.  We must change the destination address
+-    // so that it will be routed to the correct tunnel end point.
+-    // We can define several tunnel end points for the same ipsec interface.
+-    } else if (ipsec != empty && strncmp(ifs.ifc_req[i].ifr_name, "ipsec", 5) == 0) {
+-      if (strncmp(ifs.ifc_req[i].ifr_name, ipsec, 6) == 0) {
+-        struct hostent *hp = gethostbyname(ipsec+7);
+-        ioctl(s, SIOCGIFINDEX, &ifs.ifc_req[i]);
+-        iflist[cntr].index = ifs.ifc_req[i].ifr_ifindex; /* Store the SIOCGIFINDEX number */
+-        memcpy(&(iflist[cntr++].bcast), hp->h_addr, sizeof(u_int32_t));
++            iflist[cntr].flags1 = 0;
++
++            if (ifrflags.ifr_flags & IFF_POINTOPOINT) {
++              /*
++               * Get remote IP address (only for PPP interfaces)
++               */
++              memset(&ifr, 0, sizeof(ifr));
++              ifr.ifr_addr.sa_family = AF_INET;
++              (void)strncpy(ifr.ifr_name, iflist[cntr].ifname, strlen(iflist[cntr].ifname)+1);
++              if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifr) < 0) {
++                syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFDSTADDR Failed! (errno=%d)", errno);
++                exit(1);
++              }
++              sin = (struct sockaddr_in *)&ifr.ifr_addr;
++              iflist[cntr].ifdstaddr = ntohl(sin->sin_addr.s_addr);
++
++              iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_PPP;
++              iflist[cntr].bcast = INADDR_BROADCAST;
++            }
++            else if (ifrflags.ifr_flags & IFF_BROADCAST)
++              {
++                iflist[cntr].ifdstaddr = 0;
++                iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_ETH;
++                iflist[cntr].bcast = INADDR_BROADCAST;
++              }
++            else
++              {
++                iflist[cntr].ifdstaddr = 0;
++                iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_UNKNOWN;
++                iflist[cntr].bcast = INADDR_BROADCAST;
++              }
++
++            cntr++;
++          }
++        // IPSEC tunnels are a fun one.  We must change the
++        // destination address so that it will be routed to the
++        // correct tunnel end point.  We can define several tunnel end
++        // points for the same ipsec interface.
++      } else if (ipsec != empty && strncmp(ifs.ifc_req[i].ifr_name, "ipsec", 5) == 0) {
++        if (strncmp(ifs.ifc_req[i].ifr_name, ipsec, 6) == 0) {
++          struct hostent *hp = gethostbyname(ipsec+7);
++          ioctl(s, SIOCGIFINDEX, &ifs.ifc_req[i]);
++          iflist[cntr].index = ifs.ifc_req[i].ifr_ifindex; /* Store the SIOCGIFINDEX number */
++          memcpy(&(iflist[cntr++].bcast), hp->h_addr, sizeof(u_int32_t));
++        }
+       }
+     }
+-  }
+ 
+   iflist[cntr].index = 0;                       // Terminate list
+   free(ifs.ifc_req);                            // Stop that leak.
+@@ -934,28 +1006,33 @@ void ip_update_checksum(unsigned char *i
+ static char *IpProtToString( unsigned char prot )
+ {
+   switch( prot )
+-  {
+-  case 0x11:
+-    return "UDP";
+-  case 0x6:
+-    return "TCP";
+-  case 0x2f:
+-    return "GRE";
+-  case 0x1:
+-    return "ICMP";
+-  default:
+-    return "???";
+-  }
++    {
++    case 0x11:
++      return "UDP";
++    case 0x6:
++      return "TCP";
++    case 0x2f:
++      return "GRE";
++    case 0x1:
++      return "ICMP";
++    default:
++      return "???";
++    }
+ }
+ 
+ static char *iflistToString( struct iflist *ifp )
+ {
+-  static char str_tr[80+1];
++  static char str_tr[MAX_IFLOGTOSTR+90];
+ 
+-  sprintf(str_tr, "index=%d, ifname=%s, ifaddr=%ld.%ld.%ld.%ld, ifdstaddr=%ld.%ld.%ld.%ld, flags1=0x%04lx",
++  snprintf(str_tr, sizeof(str_tr), "index=%d, ifname=%s, ifaddr=%ld.%ld.%ld.%ld, ifdstaddr=%ld.%ld.%ld.%ld, flags1=0x%04lx",
+           ifp->index, ifp->ifname,
+-          (ifp->ifaddr)>>24, ((ifp->ifaddr)&0x00ff0000)>>16, ((ifp->ifaddr)&0x0000ff00)>>8, (ifp->ifaddr)&0x000000ff,
+-          (ifp->ifdstaddr)>>24, ((ifp->ifdstaddr)&0x00ff0000)>>16, ((ifp->ifdstaddr)&0x0000ff00)>>8, 
++          (ifp->ifaddr)>>24,
++          ((ifp->ifaddr)&0x00ff0000)>>16,
++          ((ifp->ifaddr)&0x0000ff00)>>8,
++          (ifp->ifaddr)&0x000000ff,
++          (ifp->ifdstaddr)>>24,
++          ((ifp->ifdstaddr)&0x00ff0000)>>16,
++          ((ifp->ifdstaddr)&0x0000ff00)>>8,
+           (ifp->ifdstaddr)&0x000000ff, ifp->flags1);
+ 
+   return str_tr;
+@@ -963,21 +1040,16 @@ static char *iflistToString( struct ifli
+ 
+ static char *iflistLogRToString( struct iflist *ifp, int idx, struct ifsnr *ifnr )
+ {
+-  static char str_tr[MAX_IFLOGTOSTR]; /*
+-                                       * This makes function: 1) non-reentrant (doesn't matter).
+-                                       *                      2) not useable multiple times by (s)printf.
+-                                       */
+-  sprintf(str_tr, "%s", ifp->ifname);
++  static char str_tr[MAX_IFLOGTOSTR];
++  snprintf(str_tr, sizeof(str_tr), "%s", ifp->ifname);
+   return str_tr;
+ }
+ 
+ static char *iflistLogIToString( struct iflist *ifp, int idx, struct ifsnr *ifnr )
+ {
+-  static char str_tr[MAX_IFLOGTOSTR]; /*
+-                                       * This makes function: 1) non-reentrant (doesn't matter).
+-                                       *                      2) not useable multiple times by (s)printf.
+-                                       */
+-  sprintf(str_tr, "%s(%d/%d/%d)", ifp->ifname, idx, ifp->index, ifnr->sock_nr);
++  static char str_tr[MAX_IFLOGTOSTR+64];
++  snprintf(str_tr, sizeof(str_tr), "%s(%d/%d/%d)", ifp->ifname,
++           idx, ifp->index, ifnr->sock_nr);
+   return str_tr;
+ }
+ 
+@@ -1001,10 +1073,10 @@ static void copy_ifsnr(struct ifsnr *fro
+   int i;
+ 
+   for (i=0; i<MAXIF; ++i)
+-  {
+-    to[i].sock_nr = from[i].sock_nr;
+-    to[i].ifindex = from[i].ifindex;
+-  }
++    {
++      to[i].sock_nr = from[i].sock_nr;
++      to[i].ifindex = from[i].ifindex;
++    }
+ }
+ 
+ static int find_sock_nr(struct ifsnr *l, int ifidx)
+@@ -1016,4 +1088,3 @@ static int find_sock_nr(struct ifsnr *l,
+   /* not found */
+   return -1;
+ }
+-
diff -Nru pptpd-1.4.0/debian/patches/series pptpd-1.4.0/debian/patches/series
--- pptpd-1.4.0/debian/patches/series	2013-10-20 15:32:16.000000000 +0200
+++ pptpd-1.4.0/debian/patches/series	2014-10-26 20:50:10.000000000 +0100
@@ -1,3 +1,3 @@
 build_hardening-flags.patch
 build_plugin.patch
-
+cherry-pick.1.4.0-11-g4ea2db6.ff.patch

Attachment: signature.asc
Description: Digital signature


Reply to: