Your message dated Sat, 6 Dec 2014 17:51:24 +0100 with message-id <20141206165123.ga20...@ugent.be> and subject line Re: Bug#772104: unblock: pptpd/1.4.0-5 has caused the Debian Bug report #772104, regarding unblock: pptpd/1.4.0-5 to be marked as done.
This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact ow...@bugs.debian.org immediately.) -- 772104: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=772104 Debian Bug Tracking System Contact ow...@bugs.debian.org with problems
--- Begin Message ---Package: release.debian.org Severity: normal User: release.debian....@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/dashdiff -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.a...@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.a...@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 <qu...@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.devro...@linvision.com> + // Ditto on the no responsibility. + // +-// Rewritten by Norbert van Bolhuis <norb...@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 <norb...@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.patchsignature.asc
Description: Digital signature
--- End Message ---
--- Begin Message ---Hi, On Fri, Dec 05, 2014 at 08:54:55AM +0100, Christoph Biedl wrote: > * -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. You really should have cleaned up the patch to avoid all these irrelevant changes. Anyway, unblocked. Cheers, Ivo
--- End Message ---