Browse Source

Initial Debianisation

Christoph Biedl 4 years ago
parent
commit
b787b2861a

+ 35 - 0
debian/README.debian

@@ -0,0 +1,35 @@
+
+bgpdump library not included
+----------------------------
+This package provides the bpgdump binary only. If you're in need of
+the libbgpdump library, file a bugreport severity wishlist.
+
+
+Running upstream's test
+-----------------------
+Upstream included some huge dump files to be tested for regressions
+during build. They have been removed from the source package as they
+are pretty huge: Full upstream tarball: 42 Mbyte, after re-packing
+some 41 kbyte.
+
+To run the test during build
+
+$ tar --wildcards --strip-components=1 -xjvf <upstream.tar>.bz2 '*/test_*'
+$ ls -1 test_*/* >>debian/source/include-binaries
+
+Then rebuild as usual.
+
+
+quagga configuration
+--------------------
+Since quagga documentation (10.15 "Dump BGP packets and table") is a
+bit terse, here a few hints:
+
+Add to your bgpd configuration, depending on whether you're interested
+in all messages or updates only:
+
+    dump bgp all|updates <path> [<interval>]
+
+Where <interval> is in seconds. The <path> is a filename that must
+be writable by quagga. It may contain format specifiers as described
+in strftime(3).

+ 2 - 0
debian/bgpdump.manpages

@@ -0,0 +1,2 @@
+
+debian/bgpdump.1

+ 118 - 0
debian/bgpdump.txt

@@ -0,0 +1,118 @@
+
+BGPDUMP(1)
+==========
+
+NAME
+----
+bgpdump - translate MRT format files into readable output
+
+VERSION
+-------
+Version 1.4.99.15+hg127
+
+SYNOPSIS
+--------
+
+Usage:
+
+----
+    bgpdump [-m|-M] [-t dump|-t change] [-O <output-file>] <input-file>
+----
+
+OPTIONS
+-------
+Output mode:
+
+*-H*::
+
+multi-line, human-readable (the default)
+
+*-m*::
+
+one-line per entry with unix timestamps
+
+*-M*::
+
+one-line per entry with human readable timestamps (there are other
+differences between -m and -M)
+
+
+Common options:
+
+*-O 'file'*::
+
+output to 'file' instead of STDOUT
+
+*-s*::
+
+log to syslog (the default)
+
+*-v*::
+
+log to STDERR
+
+
+Options for -m and -M modes:
+
+*-t dump*::
+
+timestamps for RIB dumps reflect the time of the dump (the default)
+
+*-t change*::
+
+timestamps for RIB dumps reflect the last route modification
+
+Special options:
+
+*-T*::
+
+run unit tests and exit
+
+
+INPUT FORMATS
+-------------
+
+* MRT routing table dump entries in TABLE_DUMP or TABLE_DUMP_V2 types
+* Zebra/Quagga BGP records:
+  ** BGP messages (OPEN, UPDATE, NOTIFY, KEEPALIVE)
+  ** BGP state changes
+* File may be gzipped or bzip2'd and/or passed in through stdin
+
+The file format is described in the Internet Draft grow-mrt-13:
+<http://tools.ietf.org/html/draft-ietf-grow-mrt-13>
+
+
+BUGS
+----
+
+If a single update message contains more than 8192 added or
+withdrawn prefixes, all those above that number are ignored.
+
+Files with a name longer than 999 characters cannot be processed.
+
+
+DEBIAN
+------
+
+Besides bug fixes, the following changes were done in the packaging
+for the Debian distribution:
+
+* The maximum number of prefixes processed from a single update
+  messages was raised from 2050 to 8192.
+
+* The BGP FSM state values 7 and 8, not mentioned in RFC 4271 but used
+  by the quagga routing daemon are translated into a descriptive text.
+
+
+AUTHOR
+------
+
+bgpdump was originally written by Dan Ardelean and the RIPE NCC
+took over maintenance in 2005.
+
+bgpdump is Copyright (C) 2007-2011 RIPE NCC
+
+This manpage is based on bgpdump's usage output, the bgpdump's
+homepage, and other sources. It was written for the Debian project
+by Christoph Biedl <debian.axhn@manchmal.in-ulm.de> but may be used
+by others.

+ 5 - 0
debian/changelog

@@ -0,0 +1,5 @@
+bgpdump (1.4.99.15+hg127-1) unstable; urgency=low
+
+  * Initial version, based on latest upstream commit. Closes: #733453
+
+ -- Christoph Biedl <debian.axhn@manchmal.in-ulm.de>  Wed, 20 Jul 2016 22:39:30 +0200

+ 1 - 0
debian/compat

@@ -0,0 +1 @@
+9

+ 19 - 0
debian/control

@@ -0,0 +1,19 @@
+Source: bgpdump
+Maintainer: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Homepage: https://bitbucket.org/ripencc/bgpdump/wiki/Home
+Standards-Version: 3.9.8
+Build-Depends: debhelper (>= 9~),
+    asciidoc,
+    dh-autoreconf,
+    libbz2-dev,
+    xmlto,
+    zlib1g-dev,
+Priority: optional
+Section: admin
+
+Package: bgpdump
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends},
+Description: Translate binary zebra/quagga/MRT files into readable output
+ The bgpdump programs analyses the dump files produced by the quagga
+ routing daemon or the Multithreaded Routing Toolkit (MRT).

+ 52 - 0
debian/copyright

@@ -0,0 +1,52 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+# 43 Mbyte test data excluded:
+Files-Excluded:
+    test_data
+    test_expect
+
+Files: *
+Copyright:
+ 2007 - 2011 RIPE NCC
+License: Old-MIT+GPL2+
+
+Comment:
+ The name for the actual license is unknown. It seems to be an older
+ MIT license with a no-advertising clause.
+License: Old-MIT+GPL2+
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose and without fee is hereby granted, provided
+ that the above copyright notice appear in all copies and that both that
+ copyright notice and this permission notice appear in supporting
+ documentation, and that the name of the author not be used in advertising or
+ publicity pertaining to distribution of the software without specific,
+ written prior permission.
+ .
+ THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
+ AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ .
+ .
+ Parts of this code have been engineered after analiyzing GNU Zebra's
+ source code and therefore might contain declarations/code from GNU
+ Zebra, Copyright (C) 1999 Kunihiro Ishiguro. Zebra is a free routing
+ software, distributed under the GNU General Public License.
+ .
+ .
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".

+ 15 - 0
debian/patches/add-prototype.patch

@@ -0,0 +1,15 @@
+Description: Add prototype to avoid a compiler warning
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug: https://bitbucket.org/ripencc/bgpdump/issues/27/
+Last-Update: 2016-07-18
+
+--- a/bgpdump_lib.c
++++ b/bgpdump_lib.c
+@@ -42,6 +42,7 @@
+ #include <assert.h>
+ 
+ void	  bgpdump_free_attr(attributes_t *attr);
++int       process_mrtd_bgp(struct mstream *s, BGPDUMP_ENTRY *entry);
+ static    int process_mrtd_table_dump(struct mstream *s,BGPDUMP_ENTRY *entry);
+ static    int process_mrtd_table_dump_v2(struct mstream *s,BGPDUMP_ENTRY *entry);
+ static    int process_mrtd_table_dump_v2_peer_index_table(struct mstream *s,BGPDUMP_ENTRY *entry);

+ 276 - 0
debian/patches/catch-alloc-failures.patch

@@ -0,0 +1,276 @@
+Description: Catch *alloc failures
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug: https://bitbucket.org/ripencc/bgpdump/issues/28/
+Last-Update: 2016-07-13
+
+    Better exit(1) than doing null pointer accesses
+
+--- a/bgpdump_lib.c
++++ b/bgpdump_lib.c
+@@ -94,7 +94,7 @@
+         return NULL;
+     }
+     
+-    BGPDUMP *this_dump = malloc(sizeof(BGPDUMP));
++    BGPDUMP *this_dump = malloc_check(sizeof(BGPDUMP));
+     strcpy(this_dump->filename, "[STDIN]");
+     if(filename && strcmp(filename, "-")) {
+         if (strlen(filename) >= BGPDUMP_MAX_FILE_LEN - 1) {
+@@ -137,7 +137,7 @@
+     int ok=0;
+     u_int32_t bytes_read;
+ 
+-    this_entry = malloc(sizeof(BGPDUMP_ENTRY));
++    this_entry = malloc_check(sizeof(BGPDUMP_ENTRY));
+ 
+     bytes_read = cfr_read_n(dump->f, &(this_entry->time), 4);
+     bytes_read += cfr_read_n(dump->f, &(this_entry->type), 2);
+@@ -182,7 +182,7 @@
+     dump->parsed++;
+     this_entry->attr=NULL;
+ 
+-    buffer = malloc(this_entry->length);
++    buffer = malloc_check(this_entry->length);
+     bytes_read = cfr_read_n(dump->f, buffer, this_entry->length);
+     if(bytes_read != this_entry->length) {
+ 	err("bgpdump_read_next: incomplete dump record (%d bytes read, expecting %d)",
+@@ -456,7 +456,7 @@
+ 		free(table_dump_v2_peer_index_table);
+ 	}
+ 
+-	table_dump_v2_peer_index_table = malloc(sizeof(BGPDUMP_TABLE_DUMP_V2_PEER_INDEX_TABLE));
++	table_dump_v2_peer_index_table = malloc_check(sizeof(BGPDUMP_TABLE_DUMP_V2_PEER_INDEX_TABLE));
+ 	t = table_dump_v2_peer_index_table;
+ 	t->entries = NULL;
+ 
+@@ -793,7 +793,7 @@
+     entry->body.zebra_message.notify_len = entry->body.zebra_message.size - 21;
+ 
+     if(entry->body.zebra_message.notify_len > 0) {
+-	entry->body.zebra_message.notify_data = malloc(entry->body.zebra_message.notify_len);
++	entry->body.zebra_message.notify_data = malloc_check(entry->body.zebra_message.notify_len);
+ 	mstream_get(s, entry->body.zebra_message.notify_data, entry->body.zebra_message.notify_len);
+     }
+ 
+@@ -808,7 +808,7 @@
+     mstream_getc(s, &entry->body.zebra_message.opt_len);
+ 
+     if(entry->body.zebra_message.opt_len) {
+-	entry->body.zebra_message.opt_data = malloc(entry->body.zebra_message.opt_len);
++	entry->body.zebra_message.opt_data = malloc_check(entry->body.zebra_message.opt_len);
+ 	mstream_get(s, entry->body.zebra_message.opt_data, entry->body.zebra_message.opt_len);
+     }
+ 
+@@ -844,9 +844,9 @@
+ 
+ static attributes_t *attr_init(struct mstream *s, int len) {
+ 
+-    attributes_t *attr = malloc(sizeof(struct attr));
++    attributes_t *attr = malloc_check(sizeof(struct attr));
+     
+-    attr->data=malloc(len);
++    attr->data=malloc_check(len);
+     memcpy(attr->data, &s->start[s->position], len);
+     
+     attr->len = len;
+@@ -865,7 +865,7 @@
+     attr->aspath			= NULL;
+     attr->community		= NULL;
+     attr->transit		= NULL;
+-    attr->mp_info		= calloc(1, sizeof(struct mp_info));;
++    attr->mp_info		= calloc_check(1, sizeof(struct mp_info));;
+ 
+     attr->unknown_num = 0;
+     attr->unknown = NULL;
+@@ -881,14 +881,14 @@
+ static void process_unknown_attr(struct mstream *s, attributes_t *attr, int flag, int type, int len) {
+     /* Unknown attribute. Save as is */
+     attr->unknown_num++;
+-    attr->unknown = realloc(attr->unknown, attr->unknown_num * sizeof(struct unknown_attr));
++    attr->unknown = realloc_check(attr->unknown, attr->unknown_num * sizeof(struct unknown_attr));
+     
+     /* Pointer to the unknown attribute we want to fill in */
+     struct unknown_attr unknown = {
+         .flag = flag,
+         .type = type,
+         .len = len,
+-        .raw = malloc(len)
++        .raw = malloc_check(len)
+     };
+     
+     attr->unknown[attr->unknown_num - 1] = unknown;
+@@ -956,9 +956,9 @@
+             break;
+         case BGP_ATTR_COMMUNITIES:
+             assert(! attr->community);
+-            attr->community		= malloc(sizeof(struct community));
++            attr->community		= malloc_check(sizeof(struct community));
+             attr->community->size	= len / 4;
+-            attr->community->val	= malloc(len);
++            attr->community->val	= malloc_check(len);
+             mstream_get(s,attr->community->val,len);
+             attr->community->str	= NULL;
+             process_attr_community_string(attr->community);
+@@ -982,9 +982,9 @@
+             break;
+         case BGP_ATTR_CLUSTER_LIST:
+             assert(! attr->cluster);
+-            attr->cluster		= malloc(sizeof(struct cluster_list));
++            attr->cluster		= malloc_check(sizeof(struct cluster_list));
+             attr->cluster->length	= len/4;
+-            attr->cluster->list = malloc((attr->cluster->length) * sizeof(struct in_addr));
++            attr->cluster->list = malloc_check((attr->cluster->length) * sizeof(struct in_addr));
+             
+             int i; // cluster index
+             for (i = 0; i < attr->cluster->length; i++)
+@@ -1014,14 +1014,14 @@
+ }
+ 
+ struct aspath *create_aspath(u_int16_t len, u_int8_t asn_len) {
+-  struct aspath *aspath = malloc(sizeof(struct aspath));
++  struct aspath *aspath = malloc_check(sizeof(struct aspath));
+   if(aspath) {
+     aspath->asn_len	= asn_len;
+     aspath->length	= len;
+     aspath->count	= 0;
+     aspath->str		= NULL;
+     if(len > 0)
+-       aspath->data	= malloc(len);
++       aspath->data	= malloc_check(len);
+     else
+        aspath->data	= NULL;
+   }
+@@ -1036,13 +1036,13 @@
+     as->str = NULL;
+   }
+ 
+-  as->str = malloc(strlen(ASPATH_STR_ERROR) + 1);
++  as->str = malloc_check(strlen(ASPATH_STR_ERROR) + 1);
+   strcpy(as->str, ASPATH_STR_ERROR);
+ }
+ 
+ void process_attr_aspath_string(struct aspath *as) {
+     const int MAX_ASPATH_LEN = 8000;  
+-    as->str = malloc(MAX_ASPATH_LEN);
++    as->str = malloc_check(MAX_ASPATH_LEN);
+     
+     /* Set default values */
+     int space = 0;
+@@ -1210,12 +1210,12 @@
+ 	}
+     }
+ 
+-    com->str = malloc(strlen(buf)+1);
++    com->str = malloc_check(strlen(buf)+1);
+     strcpy(com->str, buf);
+ }
+ 
+ static struct mp_nlri *get_nexthop(struct mstream *s, u_int16_t afi) {
+-    struct mp_nlri *nlri = calloc(1, sizeof(struct mp_nlri));
++    struct mp_nlri *nlri = calloc_check(1, sizeof(struct mp_nlri));
+     
+     nlri->nexthop_len = mstream_getc(s, NULL);
+     
+@@ -1300,7 +1300,7 @@
+ 	}
+ 
+ 	/* Allocate structure */
+-	mp_nlri = malloc(sizeof(struct mp_nlri));
++	mp_nlri = malloc_check(sizeof(struct mp_nlri));
+ 	memset(mp_nlri, 0, sizeof(struct mp_nlri));
+ 	info->withdraw[afi][safi] = mp_nlri;
+ 
+@@ -1439,7 +1439,7 @@
+   while(mergedpath->count < path->count - newpath->count) {
+     /* Make room */
+     newlen = mergedpath->length + sizeof(struct assegment) + segment->length * ASN32_LEN;
+-    mergedpath->data = realloc(mergedpath->data, newlen);
++    mergedpath->data = realloc_check(mergedpath->data, newlen);
+ 
+     /* Create a new AS-path segment */
+     mergedsegment = (struct assegment *) (mergedpath->data + mergedpath->length);
+@@ -1464,7 +1464,7 @@
+   }
+ 
+   /* Append NEW_AS_PATH to merged path */
+-  mergedpath->data = realloc(mergedpath->data, mergedpath->length + newpath->length);
++  mergedpath->data = realloc_check(mergedpath->data, mergedpath->length + newpath->length);
+   memcpy(mergedpath->data + mergedpath->length, newpath->data, newpath->length);
+   mergedpath->length += newpath->length;
+ 
+--- a/cfile_tools.c
++++ b/cfile_tools.c
+@@ -73,7 +73,7 @@
+   format = 2;  // skip specials 0, 1 
+ 
+   // Do action dependent on file format
+-  retval = (CFRFILE *) calloc(1,sizeof(CFRFILE));
++  retval = (CFRFILE *) calloc_check(1,sizeof(CFRFILE));
+   retval->eof = 0;
+   retval->error1 = 0;
+   retval->error2 = 0;
+@@ -357,12 +357,12 @@
+ 
+       // allocate initial buffer if none was passed or size was zero
+       if (*lineptr == NULL) {
+-        *lineptr = (char *) calloc(120, 1);
++        *lineptr = (char *) calloc_check(120, 1);
+         *n = 120;
+       }
+       if (*n == 0) {
+         *n = 120;
+-        *lineptr = (char *) realloc(*lineptr, *n); // to avoid memory-leaks
++        *lineptr = (char *) realloc_check(*lineptr, *n); // to avoid memory-leaks
+       }
+ 
+       count = 0;
+@@ -375,7 +375,7 @@
+         count ++;
+         if (count >= *n) {
+           *n = 2 * *n;
+-          *lineptr = (char *) realloc(*lineptr, *n);
++          *lineptr = (char *) realloc_check(*lineptr, *n);
+           if (*lineptr == NULL) {
+             stream->error1 = errno;
+             return(-1);
+@@ -551,3 +551,29 @@
+ }
+ #endif
+     
++void *malloc_check(size_t __size) {
++    void *ptr = malloc(__size);
++    if(ptr==NULL) {
++	fputs ("Out of memory!", stderr);
++	exit(1);
++    }
++    return ptr;
++}
++
++void *calloc_check(size_t __nmemb, size_t __size) {
++    void *ptr = calloc(__nmemb, __size);
++    if(ptr==NULL) {
++	fputs ("Out of memory!", stderr);
++	exit(1);
++    }
++    return ptr;
++}
++
++void *realloc_check(void *__ptr, size_t __size) {
++    void *ptr = realloc(__ptr, __size);
++    if(ptr==NULL) {
++	fputs ("Out of memory!", stderr);
++	exit(1);
++    }
++    return ptr;
++}
+--- a/cfile_tools.h
++++ b/cfile_tools.h
+@@ -89,5 +89,8 @@
+ const char * _bz2_strerror(int err);
+ #endif
+ 
++void *malloc_check(size_t size);
++void *calloc_check(size_t __nmemb, size_t __size);
++void *realloc_check(void *__ptr, size_t __size);
+ 
+ #endif

+ 18 - 0
debian/patches/catch-overlong-filename.patch

@@ -0,0 +1,18 @@
+Description: Catch file names that exceed the buffer limit
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug: https://bitbucket.org/ripencc/bgpdump/issues/29/
+Last-Update: 2014-05-28
+
+--- a/bgpdump_lib.c
++++ b/bgpdump_lib.c
+@@ -97,6 +97,10 @@
+     BGPDUMP *this_dump = malloc(sizeof(BGPDUMP));
+     strcpy(this_dump->filename, "[STDIN]");
+     if(filename && strcmp(filename, "-")) {
++        if (strlen(filename) >= BGPDUMP_MAX_FILE_LEN - 1) {
++            fprintf (stderr, "File name %s is too long.\n", filename);
++            exit(1);
++        }
+ 	strcpy(this_dump->filename, filename);
+     }
+ 

+ 35 - 0
debian/patches/clarify-pointer-cast.patch

@@ -0,0 +1,35 @@
+Description: Clarify pointer usage
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug: https://bitbucket.org/ripencc/bgpdump/issues/30/
+Last-Update: 2016-07-19
+
+    The read_asn function handles pointer to as_t and u_int16_t as well,
+    behaviour is controlled by the third parameter.
+
+    Type-cast parameter 2 to avoid incompatible-pointer-types warnings
+    from gcc.
+
+--- a/bgpdump_lib.c
++++ b/bgpdump_lib.c
+@@ -337,10 +337,10 @@
+     switch(entry->subtype) {
+     case BGPDUMP_SUBTYPE_MRTD_BGP_UPDATE:
+     case BGPDUMP_SUBTYPE_MRTD_BGP_KEEPALIVE:
+-	read_asn(s, &entry->body.mrtd_message.source_as, ASN16_LEN);
++	read_asn(s, (as_t*) &entry->body.mrtd_message.source_as, ASN16_LEN);
+ 	entry->body.mrtd_message.source_ip = mstream_get_ipv4(s);
+ 
+-	read_asn(s, &entry->body.mrtd_message.destination_as, ASN16_LEN);
++	read_asn(s, (as_t*) &entry->body.mrtd_message.destination_as, ASN16_LEN);
+ 	entry->body.mrtd_message.destination_ip = mstream_get_ipv4(s);
+ 
+ 	mstream_t withdraw_stream = mstream_copy(s, mstream_getw(s, NULL));
+@@ -355,7 +355,7 @@
+ 								   &entry->body.mrtd_message.incomplete);
+ 	break;
+     case BGPDUMP_SUBTYPE_MRTD_BGP_STATE_CHANGE:
+-	read_asn(s, &entry->body.mrtd_state_change.destination_as, ASN16_LEN);
++	read_asn(s, (as_t*) &entry->body.mrtd_state_change.destination_as, ASN16_LEN);
+ 	entry->body.mrtd_state_change.destination_ip = mstream_get_ipv4(s);
+ 	entry->body.mrtd_state_change.old_state = mstream_getw(s, NULL);
+ 	entry->body.mrtd_state_change.new_state = mstream_getw(s, NULL);

+ 38 - 0
debian/patches/disable-cfr_strerror.patch

@@ -0,0 +1,38 @@
+Description: Disable the cfr_strerror function
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug: https://bitbucket.org/ripencc/bgpdump/issues/31/
+Last-Update: 2016-07-19
+
+    This function does not check the asprintf return value but it's not
+    used anyany. So disable it.
+
+--- a/cfile_tools.c
++++ b/cfile_tools.c
+@@ -443,6 +443,7 @@
+ }
+ 
+ 
++#if 0
+ char * cfr_strerror(CFRFILE *stream) {
+   // Result is "stream-i/o: <stream-error> <compressor>[: <compressor error>]"
+   // Do not modify result. 
+@@ -482,6 +483,7 @@
+   free(msg); 
+   return(res);
+ }
++#endif
+ 
+ const char * cfr_compressor_str(CFRFILE *stream) {
+   // Returns the name of the compressor used
+--- a/cfile_tools.h
++++ b/cfile_tools.h
+@@ -80,7 +80,9 @@
+ ssize_t      cfr_getline(char **lineptr, size_t *n, CFRFILE *stream);
+ int          cfr_eof(CFRFILE *stream);
+ int          cfr_error(CFRFILE *stream);
++#if 0
+ char       * cfr_strerror(CFRFILE *stream);
++#endif
+ const char * cfr_compressor_str(CFRFILE *stream);
+ 
+ #ifndef DONT_HAVE_BZ2

+ 36 - 0
debian/patches/fix-bgp-state-out-of-bonds.patch

@@ -0,0 +1,36 @@
+Description: Fix array out of bond access in process()
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug: https://bitbucket.org/ripencc/bgpdump/issue/19/
+Last-Update: 2016-07-13
+
+    The current code happily assumes the state value is within the range
+    of hard-coded values. Handle unknown values gracefully.
+
+--- a/bgpdump.c
++++ b/bgpdump.c
+@@ -244,6 +244,15 @@
+ 	NULL
+ };
+ 
++static const char *bgp_state_name_lookup(unsigned state, char *buffer) {
++    if (state >= sizeof(bgp_state_name)/sizeof(bgp_state_name[0])-1) {
++        sprintf(buffer, "Unknown-%u", state);
++        return buffer;
++    }
++    return bgp_state_name[state];
++}
++
++
+ void process(BGPDUMP_ENTRY *entry) {
+ 
+ 	struct tm *date;
+@@ -926,7 +935,8 @@
+ 			//	printf(" N/A ");
+ 		    	printf("AS%u\n",entry->body.zebra_state_change.source_as);
+ 
+-		    	printf("STATE: %s/%s\n",bgp_state_name[entry->body.zebra_state_change.old_state],bgp_state_name[entry->body.zebra_state_change.new_state]);
++			char temp1[16], temp2[16];
++		    	printf("STATE: %s/%s\n",bgp_state_name_lookup(entry->body.zebra_state_change.old_state,temp1),bgp_state_name_lookup(entry->body.zebra_state_change.new_state,temp2));
+ 		    }
+ 		    else if (mode==1 || mode==2 ) //-m -M
+ 		    {

+ 29 - 0
debian/patches/fix-buffer-weirdness.patch

@@ -0,0 +1,29 @@
+Description: These operations aren't broken, but just weird
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Forwarded: No
+Last-Update: 2014-06-07
+
+--- a/util.c
++++ b/util.c
+@@ -46,7 +46,7 @@
+     _log(LOG_##lvl, #lvl_str, fmt, args)
+ 
+ static char *now_str() {
+-    static char buffer[1000];
++    static char buffer[20];
+     time_t now = time(0);
+     strftime(buffer, sizeof buffer, "%Y-%m-%d %H:%M:%S", localtime(&now));
+     return buffer;
+@@ -56,9 +56,9 @@
+     if(use_syslog) {
+         syslog(lvl, fmt, args);
+     } else {
+-        char prefix[strlen(fmt) + 1000];
+-        sprintf(prefix, "%s [%s] %s\n", now_str(), lvl_str, fmt);
+-        vfprintf(stderr, prefix, args);
++        fprintf(stderr, "%s [%s] ", now_str(), lvl_str);
++        vfprintf(stderr, fmt, args);
++        fputc ('\n', stderr);
+     }
+ }
+ 

+ 32 - 0
debian/patches/fix-crash-on-huge-prefix-lists.patch

@@ -0,0 +1,32 @@
+Description: Handle prefix lists with more than MAX_PREFIXES prefixes gracefully
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug: https://bitbucket.org/ripencc/bgpdump/issue/2/
+Bug: https://bitbucket.org/ripencc/bgpdump/issue/10/
+Bug: https://bitbucket.org/ripencc/bgpdump/issue/13/
+Bug: https://bitbucket.org/ripencc/bgpdump/issue/17/
+Bug: https://bitbucket.org/ripencc/bgpdump/issue/18/
+Last-Update: 2016-07-13
+
+--- a/bgpdump_lib.c
++++ b/bgpdump_lib.c
+@@ -1325,11 +1325,16 @@
+             break;
+         }
+         
+-        struct prefix *prefix = prefixes + count;
++        struct prefix *prefix;
+         
+-        if(count++ > MAX_PREFIXES)
+-            continue;
+-
++        if(count < MAX_PREFIXES) {
++            prefix = prefixes + count;
++        } else {
++            /* read and discard */
++            static struct prefix void_prefix;
++            prefix = &void_prefix;
++        }
++        count++;
+         *prefix = (struct prefix) { .len = p_len };
+         mstream_get(s, &prefix->address, p_bytes);
+     }

+ 56 - 0
debian/patches/fix-gzfile-type-usage.patch

@@ -0,0 +1,56 @@
+Description: Fix gzFile type usage
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug: https://bitbucket.org/ripencc/bgpdump/issues/32/
+Last-Update: 2016-07-20
+
+    The gzFile type is already a pointer. Don't pointer it.
+
+--- a/cfile_tools.c
++++ b/cfile_tools.c
+@@ -82,7 +82,7 @@
+ #ifndef DONT_HAVE_GZ
+   if((path == NULL) || (strcmp(path, "-") == 0)) {
+ 	/* dump from stdin */
+-	gzFile *f;
++	gzFile f;
+ 	while (format < CFR_NUM_FORMATS) {
+ 		if (strcmp(cfr_extensions[format], ".gz") == 0)
+         		break;
+@@ -157,7 +157,7 @@
+ #ifndef DONT_HAVE_GZ
+   case 3:  // gzip
+     { 
+-	gzFile *f;
++	gzFile f;
+       	// get file 
+ 	f = gzopen(path, "r");
+ 	if(f == NULL) {
+@@ -302,8 +302,8 @@
+ #ifndef DONT_HAVE_GZ
+   case 3:  // gzip
+     { 
+-      gzFile * in;
+-      in = (gzFile *)(stream->data2);
++      gzFile in;
++      in = (gzFile)(stream->data2);
+       retval = gzread(in, ptr, size*nmemb);
+       if (retval != nmemb*size) {
+         // fprintf(stderr,"short read!!!\n");
+@@ -391,7 +391,7 @@
+ #ifndef DONT_HAVE_GZ
+   case 3:  // gzip
+     { 
+-      char * return_ptr = gzgets((gzFile *)(stream->data2), *lineptr, *n );
++      char * return_ptr = gzgets((gzFile)(stream->data2), *lineptr, *n );
+       if (return_ptr == Z_NULL) {
+         stream->error2 = errno;
+         return(-1);
+@@ -474,7 +474,7 @@
+     asprintf(&msg2, 
+              "%s: %s",
+              msg, 
+-             gzerror((gzFile*)(stream->data2), &(stream->error2)));
++             gzerror((gzFile)(stream->data2), &(stream->error2)));
+     free(msg);
+     msg = msg2;
+   }

+ 60 - 0
debian/patches/fix-sprintf-append.patch

@@ -0,0 +1,60 @@
+Description: Fix undefined sprintf usage
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug: https://bitbucket.org/ripencc/bgpdump/issues/33/
+Last-Update: 2016-07-18
+
+    Documentation states appending to a buffer using
+        sprintf (buf, "%s.foo", buf);
+    results in undefined behaviour. Work around it.
+
+--- a/bgpdump.c
++++ b/bgpdump.c
+@@ -261,19 +261,20 @@
+ 	char time_str_fixed[128];
+     char prefix[BGPDUMP_ADDRSTRLEN];
+     char *bgp4mp_format;
++    int len;
+ 	
+ 	date=gmtime(&entry->time);
+ 	time2str(date,time_str_fixed);
+     
+     if (mode == 1) {
+         // Timestamp mode
+-        sprintf(time_str, "%ld", entry->time);
++        len = sprintf(time_str, "%ld", entry->time);
+     } else {
+-        time2str(date,time_str);
++        len = time2str(date,time_str);
+     }
+     // Appending microseconds to time_str if needed
+     if (entry->type == BGPDUMP_TYPE_ZEBRA_BGP_ET) {
+-        sprintf(time_str, "%s.%06ld", time_str, entry->ms);
++        sprintf(time_str + len, ".%06ld", entry->ms);
+     }
+     
+ 	if (mode==0)
+--- a/util.c
++++ b/util.c
+@@ -66,9 +66,9 @@
+ void warn(const char *fmt, ...) { log(WARNING, warn); }
+ void debug(const char *fmt, ...) { log(INFO, info); }
+ 
+-void time2str(struct tm* date,char *time_str)
++int time2str(struct tm* date,char *time_str)
+ {
+-    sprintf(time_str, "%02d/%02d/%02d %02d:%02d:%02d", date->tm_mon+1, date->tm_mday, date->tm_year%100,
++    return sprintf(time_str, "%02d/%02d/%02d %02d:%02d:%02d", date->tm_mon+1, date->tm_mday, date->tm_year%100,
+             date->tm_hour, date->tm_min, date->tm_sec);
+ }
+ 
+--- a/util.h
++++ b/util.h
+@@ -38,7 +38,7 @@
+ char *fmt_ipv6(BGPDUMP_IP_ADDRESS addr, char *buffer);
+ void test_fmt_ip(void);
+ 
+-void time2str(struct tm* date,char *time_str);
++int time2str(struct tm* date,char *time_str);
+ int int2str(uint32_t value, char* str);
+ void test_utils(void);
+ 

+ 16 - 0
debian/patches/fix-test.patch

@@ -0,0 +1,16 @@
+Description: Fix the test run, Debian has zcat, not gzcat
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug: https://bitbucket.org/ripencc/bgpdump/issues/34/
+Last-Update: 2016-07-18
+
+--- a/test.sh
++++ b/test.sh
+@@ -9,7 +9,7 @@
+     echo -n "      testing $mrt..."
+     OUT=$mrt.bgp.gz
+     ./bgpdump -vm test_data/$mrt > test_out/$OUT
+-    gzcat test_expect/$OUT | diff -q test_out/$OUT -
++    zcat test_expect/$OUT | diff -q test_out/$OUT -
+     if [ $? == 0 ]; then
+         echo "success"
+     else

+ 19 - 0
debian/patches/increase-max-prefixes.patch

@@ -0,0 +1,19 @@
+Description: Increase limit of maximum prefixes
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Forwarded: No
+Last-Update: 2016-07-13
+
+    Appearently update messages with more than 1000 prefixes to exist,
+    raise the limit.
+
+--- a/bgpdump_attr.h
++++ b/bgpdump_attr.h
+@@ -212,7 +212,7 @@
+     u_char		len;
+ };
+ 
+-#define MAX_PREFIXES 2050
++#define MAX_PREFIXES 8192
+ struct mp_nlri {
+   u_char		nexthop_len;
+ 

+ 16 - 0
debian/patches/more-bgp-states.patch

@@ -0,0 +1,16 @@
+Description: Add two more BGP states as described in the quagga sources
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug: https://bitbucket.org/ripencc/bgpdump/issues/35/
+Last-Update: 2016-07-13
+
+--- a/bgpdump.c
++++ b/bgpdump.c
+@@ -241,6 +241,8 @@
+ 	"Opensent",
+ 	"Openconfirm",
+ 	"Established",
++	"Clearing",
++	"Deleted",
+ 	NULL
+ };
+ 

+ 67 - 0
debian/patches/re-autoconfig.patch

@@ -0,0 +1,67 @@
+Description: Redo autoconfig stuff
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Forwarded: No
+Last-Update: 2016-07-20
+
+--- /dev/null
++++ b/Makefile.am
+@@ -0,0 +1,14 @@
++ACLOCAL_AMFLAGS	= -I m4
++
++noinst_LTLIBRARIES		= libbgpdump.la
++libbgpdump_la_SOURCES	= bgpdump-config.h bgpdump_attr.h bgpdump_formats.h bgpdump_lib.c bgpdump_lib.h bgpdump_mstream.c bgpdump_mstream.h cfile_tools.c cfile_tools.h inet_ntop.c util.c util.h
++
++bin_PROGRAMS 	= bgpdump
++bgpdump_SOURCES	= bgpdump.c
++bgpdump_LDADD 	= libbgpdump.la
++
++check-clean:
++	rm -f test_out/*.bgp.gz
++
++test: check-clean bgpdump
++	[ ! -d test_data ] || ./test.sh
+--- /dev/null
++++ b/configure.ac
+@@ -0,0 +1,42 @@
++AC_REVISION([m4_esyscmd([dpkg-parsechangelog -SVersion])])
++
++AC_INIT([libbgpdump], 1.4.99.15, [ris@ripe.net])
++
++AM_INIT_AUTOMAKE([foreign])
++
++AC_CONFIG_SRCDIR([bgpdump_lib.c])
++AC_CONFIG_HEADERS([bgpdump-config.h])
++
++# Checks for programs.
++AC_PROG_CC
++
++AC_PROG_LIBTOOL
++AC_CONFIG_MACRO_DIRS([m4])
++
++# Checks for header files.
++AC_CHECK_HEADERS([arpa/inet.h netinet/in.h syslog.h])
++AC_STRUCT_TM
++
++# Check for u_*_t
++AC_CHECK_TYPE(u_char_t, , AC_DEFINE(u_char_t, uchar_t, [Define if system headers do not define u_char_t]))
++AC_CHECK_TYPE(u_int8_t, , AC_DEFINE(u_int8_t, uint8_t, [Define if system headers do not define u_int8_t]))
++AC_CHECK_TYPE(u_int16_t, , AC_DEFINE(u_int16_t, uint16_t, [Define if system headers do not define u_int16_t]))
++AC_CHECK_TYPE(u_int32_t, , AC_DEFINE(u_int32_t, uint32_t, [Define if system headers do not define u_int32_t]))
++
++AC_CHECK_LIB(z, gzopen, [], AC_DEFINE(DONT_HAVE_GZ, 1, Define if libz not present))
++AC_CHECK_LIB(bz2, BZ2_bzReadOpen, [], AC_DEFINE(DONT_HAVE_BZ2, 1, Define if libbzip2 not present))
++
++# Check for inet_ntoa in -lnsl if not found (Solaris)
++AC_CHECK_FUNCS(inet_ntoa, [], AC_CHECK_LIB(nsl, inet_ntoa, [], AC_MSG_ERROR([inet_ntoa not found],1)))
++AC_CHECK_FUNCS(inet_ntop, [], AC_CHECK_LIB(nsl, inet_ntop, [], AC_MSG_ERROR([inet_ntop not found],1)))
++
++case `uname` in
++	Darwin*) LDFLAGS="$LDFLAGS -dynamiclib" ;;
++	*)       LDFLAGS="$LDFLAGS -shared" ;;
++esac
++
++AC_SUBST(CFLAGS)
++AC_SUBST(LDFLAGS)
++AC_SUBST(LIBS)
++
++AC_OUTPUT([bgpdump.spec Makefile])

+ 21 - 0
debian/patches/series

@@ -0,0 +1,21 @@
+# packaging
+re-autoconfig.patch
+
+# upstream code cleanup
+disable-cfr_strerror.patch
+fix-bgp-state-out-of-bonds.patch
+fix-crash-on-huge-prefix-lists.patch
+catch-overlong-filename.patch
+fix-buffer-weirdness.patch
+catch-alloc-failures.patch
+add-prototype.patch
+clarify-pointer-cast.patch
+fix-gzfile-type-usage.patch
+
+# features
+fix-sprintf-append.patch
+increase-max-prefixes.patch
+more-bgp-states.patch
+
+# big test (see README.Debian)
+fix-test.patch

+ 24 - 0
debian/rules

@@ -0,0 +1,24 @@
+#!/usr/bin/make -f
+
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+%:
+	dh $@ --with autoreconf
+
+override_dh_clean:
+	dh_clean
+	-rm debian/bgpdump.1
+
+override_dh_autoreconf:
+	-rm configure.in Makefile.in
+	dh_autoreconf
+
+override_dh_install:
+	dh_install
+	# don't ship the library for the time being, see README.Debian
+	rm -rf debian/bgpdump/usr/lib/
+	rm -rf debian/bgpdump/usr/include/
+
+override_dh_installman:
+	a2x --format=manpage --no-xmllint debian/bgpdump.txt
+	dh_installman

+ 1 - 0
debian/source/format

@@ -0,0 +1 @@
+3.0 (quilt)

+ 5 - 0
debian/watch

@@ -0,0 +1,5 @@
+version=4
+https://bitbucket.org/ripencc/bgpdump/downloads \
+    /ripencc/bgpdump/get/([0-9.]+)\.tar\.bz2 \
+    debian uupdate
+