summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package/Config.in1
-rw-r--r--package/Makefile2
-rw-r--r--package/mtr/Config.in17
-rw-r--r--package/mtr/Makefile68
-rw-r--r--package/mtr/ipkg/mtr.control17
-rw-r--r--package/mtr/patches/501-dns.patch511
6 files changed, 616 insertions, 0 deletions
diff --git a/package/Config.in b/package/Config.in
index 1991e9f083..c134829e61 100644
--- a/package/Config.in
+++ b/package/Config.in
@@ -73,6 +73,7 @@ source "package/linux-atm/Config.in"
source "package/maradns/Config.in"
source "package/mini_httpd/Config.in"
source "package/mini_sendmail/Config.in"
+source "package/mtr/Config.in"
source "package/ndisc/Config.in"
source "package/net-snmp/Config.in"
source "package/netstat-nat/Config.in"
diff --git a/package/Makefile b/package/Makefile
index cbb1bf4e6a..4b8bca3b97 100644
--- a/package/Makefile
+++ b/package/Makefile
@@ -103,6 +103,7 @@ package-$(BR2_PACKAGE_MONIT) += monit
package-$(BR2_PACKAGE_MPD) += mpd
package-$(BR2_PACKAGE_MT_DAAPD) += mt-daapd
package-$(BR2_PACKAGE_MTD) += mtd
+package-$(BR2_PACKAGE_MTR) += mtr
package-$(BR2_PACKAGE_MYSQL) += mysql
package-$(BR2_PACKAGE_NANO) += nano
package-$(BR2_PACKAGE_NCURSES) += ncurses
@@ -232,6 +233,7 @@ libxslt-compile: libxml2-compile
lighttpd-compile: openssl-compile pcre-compile
mini_httpd-compile: matrixssl-compile
mt-daapd-compile: howl-compile libgdbm-compile libid3tag-compile
+mtr-compile: ncurses-compile
mysql-compile: ncurses-compile zlib-compile
nano-compile: ncurses-compile
net-snmp-compile: libelf-compile
diff --git a/package/mtr/Config.in b/package/mtr/Config.in
new file mode 100644
index 0000000000..fc7963b634
--- /dev/null
+++ b/package/mtr/Config.in
@@ -0,0 +1,17 @@
+config BR2_PACKAGE_MTR
+ tristate "mtr - Full screen ncurses traceroute tool"
+ default m if CONFIG_DEVEL
+ select BR2_PACKAGE_LIBNCURSES
+ help
+ mtr combines the functionality of the 'traceroute' and 'ping' programs
+ in a single network diagnostic tool.
+ .
+ As mtr starts, it investigates the network connection between the host
+ mtr runs on and a user-specified destination host. After it
+ determines the address of each network hop between the machines,
+ it sends a sequence ICMP ECHO requests to each one to determine the
+ quality of the link to each machine. As it does this, it prints
+ running statistics about each machine.
+ .
+ http://www.bitwizard.nl/mtr/
+
diff --git a/package/mtr/Makefile b/package/mtr/Makefile
new file mode 100644
index 0000000000..d911716a3a
--- /dev/null
+++ b/package/mtr/Makefile
@@ -0,0 +1,68 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mtr
+PKG_VERSION:=0.69
+PKG_RELEASE:=1
+PKG_MD5SUM:=58904d6d8d70114195cdeb653d56914c
+
+PKG_SOURCE_URL:=ftp://ftp.de.debian.org/debian/pool/main/m/mtr
+PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).orig.tar.gz
+PKG_CAT:=zcat
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
+
+include $(TOPDIR)/package/rules.mk
+
+$(eval $(call PKG_template,MTR,mtr,$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
+
+$(PKG_BUILD_DIR)/.configured: $(PKG_BUILD_DIR)/.prepared
+ (cd $(PKG_BUILD_DIR); \
+ $(TARGET_CONFIGURE_OPTS) \
+ CFLAGS="$(TARGET_CFLAGS)" \
+ CPPFLAGS="-I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \
+ LDFLAGS="-L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib" \
+ ac_cv_lib_resolv_res_mkquery=yes \
+ ./configure \
+ --target=$(GNU_TARGET_NAME) \
+ --host=$(GNU_TARGET_NAME) \
+ --build=$(GNU_HOST_NAME) \
+ --program-prefix="" \
+ --program-suffix="" \
+ --prefix=/usr \
+ --exec-prefix=/usr \
+ --bindir=/usr/bin \
+ --datadir=/usr/share \
+ --includedir=/usr/include \
+ --infodir=/usr/share/info \
+ --libdir=/usr/lib \
+ --libexecdir=/usr/lib \
+ --localstatedir=/var \
+ --mandir=/usr/share/man \
+ --sbindir=/usr/sbin \
+ --sysconfdir=/etc \
+ $(DISABLE_LARGEFILE) \
+ $(DISABLE_NLS) \
+ --without-gtk \
+ );
+ touch $@
+
+$(PKG_BUILD_DIR)/.built:
+ rm -rf $(PKG_INSTALL_DIR)
+ mkdir -p $(PKG_INSTALL_DIR)
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ DESTDIR="$(PKG_INSTALL_DIR)" \
+ CFLAGS="$(TARGET_CFLAGS)" \
+ CPPFLAGS="-I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \
+ LDFLAGS="-L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib" \
+ all install
+ touch $@
+
+$(IPKG_MTR):
+ install -d -m0755 $(IDIR_MTR)/usr/sbin
+ cp -fpR $(PKG_INSTALL_DIR)/usr/sbin/mtr $(IDIR_MTR)/usr/sbin/
+ $(RSTRIP) $(IDIR_MTR)
+ $(IPKG_BUILD) $(IDIR_MTR) $(PACKAGE_DIR)
+
+mostlyclean:
+ -$(MAKE) -C $(PKG_BUILD_DIR) clean
+ rm -f $(PKG_BUILD_DIR)/.built
diff --git a/package/mtr/ipkg/mtr.control b/package/mtr/ipkg/mtr.control
new file mode 100644
index 0000000000..fd4bbc2f49
--- /dev/null
+++ b/package/mtr/ipkg/mtr.control
@@ -0,0 +1,17 @@
+Package: mtr
+Priority: optional
+Section: net
+Maintainer: OpenWrt Developers Team <openwrt-devel@openwrt.org>, Thomas Reifferscheid <reiffert@student.physik.uni-mainz.de>
+Depends: libncurses
+Source: http://openwrt.org/cgi-bin/viewcvs.cgi/openwrt/package/iptraf/
+Description: Full screen ncurses traceroute/ping tool
+ mtr combines the functionality of the 'traceroute' and 'ping' programs
+ in a single network diagnostic tool.
+ .
+ As mtr starts, it investigates the network connection between the host
+ mtr runs on and a user-specified destination host. After it
+ determines the address of each network hop between the machines,
+ it sends a sequence ICMP ECHO requests to each one to determine the
+ quality of the link to each machine. As it does this, it prints
+ running statistics about each machine.
+
diff --git a/package/mtr/patches/501-dns.patch b/package/mtr/patches/501-dns.patch
new file mode 100644
index 0000000000..f1c915580d
--- /dev/null
+++ b/package/mtr/patches/501-dns.patch
@@ -0,0 +1,511 @@
+diff -Naur mtr-0.69.old/dns.c mtr-0.69.new/dns.c
+--- mtr-0.69.old/dns.c 2005-01-11 09:32:42.000000000 +0100
++++ mtr-0.69.new/dns.c 2005-10-03 21:31:27.000000000 +0200
+@@ -853,6 +853,507 @@
+ fputs("\r",stderr);
+ }
+
++#ifdef __UCLIBC__
++
++static const char digits[] = "0123456789";
++#define __set_errno(e) (errno = (e))
++
++#define NS_PUT16(s, cp) do { \
++ register u_int16_t t_s = (u_int16_t)(s); \
++ register u_char *t_cp = (u_char *)(cp); \
++ *t_cp++ = t_s >> 8; \
++ *t_cp = t_s; \
++ (cp) += NS_INT16SZ; \
++} while (0)
++
++
++
++#define NS_PUT32(l, cp) do { \
++ register u_int32_t t_l = (u_int32_t)(l); \
++ register u_char *t_cp = (u_char *)(cp); \
++ *t_cp++ = t_l >> 24; \
++ *t_cp++ = t_l >> 16; \
++ *t_cp++ = t_l >> 8; \
++ *t_cp = t_l; \
++ (cp) += NS_INT32SZ; \
++} while (0)
++
++
++void
++ns_put16(u_int src, u_char *dst) {
++ NS_PUT16(src, dst);
++}
++
++void
++ns_put32(u_long src, u_char *dst) {
++ NS_PUT32(src, dst);
++}
++
++void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
++void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
++
++int
++mklower(int ch) {
++ if (ch >= 0x41 && ch <= 0x5A)
++ return (ch + 0x20);
++ return (ch);
++}
++
++
++static int
++dn_find(const u_char *domain, const u_char *msg,
++ const u_char * const *dnptrs,
++ const u_char * const *lastdnptr)
++{
++ const u_char *dn, *cp, *sp;
++ const u_char * const *cpp;
++ u_int n;
++
++ for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
++ sp = *cpp;
++ /*
++ * terminate search on:
++ * root label
++ * compression pointer
++ * unusable offset
++ */
++ while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
++ (sp - msg) < 0x4000) {
++ dn = domain;
++ cp = sp;
++ while ((n = *cp++) != 0) {
++ /*
++ * check for indirection
++ */
++ switch (n & NS_CMPRSFLGS) {
++ case 0: /* normal case, n == len */
++ if (n != *dn++)
++ goto next;
++ for ((void)NULL; n > 0; n--)
++ if (mklower(*dn++) !=
++ mklower(*cp++))
++ goto next;
++ /* Is next root for both ? */
++ if (*dn == '\0' && *cp == '\0')
++ return (sp - msg);
++ if (*dn)
++ continue;
++ goto next;
++
++ case NS_CMPRSFLGS: /* indirection */
++ cp = msg + (((n & 0x3f) << 8) | *cp);
++ break;
++
++ default: /* illegal type */
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ }
++ next:
++ sp += *sp + 1;
++ }
++ }
++ __set_errno (ENOENT);
++ return (-1);
++}
++
++
++int
++ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
++ const u_char **dnptrs, const u_char **lastdnptr)
++{
++ u_char *dstp;
++ const u_char **cpp, **lpp, *eob, *msg;
++ const u_char *srcp;
++ int n, l, first = 1;
++
++ srcp = src;
++ dstp = dst;
++ eob = dstp + dstsiz;
++ lpp = cpp = NULL;
++ if (dnptrs != NULL) {
++ if ((msg = *dnptrs++) != NULL) {
++ for (cpp = dnptrs; *cpp != NULL; cpp++)
++ (void)NULL;
++ lpp = cpp; /* end of list to search */
++ }
++ } else
++ msg = NULL;
++
++ /* make sure the domain we are about to add is legal */
++ l = 0;
++ do {
++ n = *srcp;
++ if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ if (n == 0x41)
++ n = *++srcp / 8;
++ l += n + 1;
++ if (l > MAXCDNAME) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ srcp += n + 1;
++ } while (n != 0);
++
++ /* from here on we need to reset compression pointer array on error */
++ srcp = src;
++ do {
++ /* Look to see if we can use pointers. */
++ n = *srcp;
++ if (n != 0 && n != 0x41 && msg != NULL) {
++ l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
++ (const u_char * const *)lpp);
++ if (l >= 0) {
++ if (dstp + 1 >= eob) {
++ goto cleanup;
++ }
++ *dstp++ = (l >> 8) | NS_CMPRSFLGS;
++ *dstp++ = l % 256;
++ return (dstp - dst);
++ }
++ /* Not found, save it. */
++ if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
++ (dstp - msg) < 0x4000 && first) {
++ *cpp++ = dstp;
++ *cpp = NULL;
++ first = 0;
++ }
++ }
++ /* copy label to buffer */
++ if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) { /* Should not happen. */
++ goto cleanup;
++ }
++ if (n == 0x41) {
++ n = *++srcp / 8;
++ if (dstp + 1 >= eob)
++ goto cleanup;
++ *dstp++ = 0x41;
++ }
++ if (dstp + 1 + n >= eob) {
++ goto cleanup;
++ }
++ memcpy(dstp, srcp, n + 1);
++ srcp += n + 1;
++ dstp += n + 1;
++ } while (n != 0);
++
++ if (dstp > eob) {
++cleanup:
++ if (msg != NULL)
++ *lpp = NULL;
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ return (dstp - dst);
++}
++
++
++int
++ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
++ u_char *label, *bp, *eom;
++ int c, n, escaped;
++ char *cp;
++
++ escaped = 0;
++ bp = dst;
++ eom = dst + dstsiz;
++ label = bp++;
++
++ while ((c = *src++) != 0) {
++ if (escaped) {
++ if ((cp = strchr(digits, c)) != NULL) {
++ n = (cp - digits) * 100;
++ if ((c = *src++) == 0 ||
++ (cp = strchr(digits, c)) == NULL) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ n += (cp - digits) * 10;
++ if ((c = *src++) == 0 ||
++ (cp = strchr(digits, c)) == NULL) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ n += (cp - digits);
++ if (n > 255) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ c = n;
++ } else if (c == '[' && label == bp - 1 && *src == 'x') {
++ /* Theoretically we would have to handle \[o
++ as well but we do not since we do not need
++ it internally. */
++ *label = 0x41;
++ label = bp++;
++ ++src;
++ while (isxdigit (*src)) {
++ n = *src > '9' ? *src - 'a' + 10 : *src - '0';
++ ++src;
++ if (! isxdigit(*src)) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ n <<= 4;
++ n += *src > '9' ? *src - 'a' + 10 : *src - '0';
++ if (bp + 1 >= eom) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ *bp++ = n;
++ ++src;
++ }
++ *label = (bp - label - 1) * 8;
++ if (*src++ != ']' || *src++ != '.') {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ escaped = 0;
++ label = bp++;
++ if (bp >= eom) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ continue;
++ }
++ escaped = 0;
++ } else if (c == '\\') {
++ escaped = 1;
++ continue;
++ } else if (c == '.') {
++ c = (bp - label - 1);
++ if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ if (label >= eom) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ *label = c;
++ /* Fully qualified ? */
++ if (*src == '\0') {
++ if (c != 0) {
++ if (bp >= eom) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ *bp++ = '\0';
++ }
++ if ((bp - dst) > MAXCDNAME) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ return (1);
++ }
++ if (c == 0 || *src == '.') {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ label = bp++;
++ continue;
++ }
++ if (bp >= eom) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ *bp++ = (u_char)c;
++ }
++ c = (bp - label - 1);
++ if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ if (label >= eom) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ *label = c;
++ if (c != 0) {
++ if (bp >= eom) {
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ *bp++ = 0;
++ }
++ if ((bp - dst) > MAXCDNAME) { /* src too big */
++ __set_errno (EMSGSIZE);
++ return (-1);
++ }
++ return (0);
++}
++
++
++
++int
++ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
++ const u_char **dnptrs, const u_char **lastdnptr)
++{
++ u_char tmp[NS_MAXCDNAME];
++
++ if (ns_name_pton(src, tmp, sizeof tmp) == -1)
++ return (-1);
++ return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
++}
++
++
++int
++dn_comp(const char *src, u_char *dst, int dstsiz,
++ u_char **dnptrs, u_char **lastdnptr)
++{
++ return (ns_name_compress(src, dst, (size_t)dstsiz,
++ (const u_char **)dnptrs,
++ (const u_char **)lastdnptr));
++}
++
++
++
++
++int
++res_nmkquery(res_state statp,
++ int op, /* opcode of query */
++ const char *dname, /* domain name */
++ int class, int type, /* class and type of query */
++ const u_char *data, /* resource record data */
++ int datalen, /* length of data */
++ const u_char *newrr_in, /* new rr for modify or append */
++ u_char *buf, /* buffer to put query */
++ int buflen) /* size of buffer */
++{
++ register HEADER *hp;
++ register u_char *cp;
++ register int n;
++ u_char *dnptrs[20], **dpp, **lastdnptr;
++
++#ifdef DEBUG
++ if (statp->options & RES_DEBUG)
++ printf(";; res_nmkquery(%s, %s, %s, %s)\n",
++ _res_opcodes[op], dname, p_class(class), p_type(type));
++#endif
++ /*
++ * Initialize header fields.
++ */
++ if ((buf == NULL) || (buflen < HFIXEDSZ))
++ return (-1);
++ memset(buf, 0, HFIXEDSZ);
++ hp = (HEADER *) buf;
++ /* We randomize the IDs every time. The old code just
++ incremented by one after the initial randomization which
++ still predictable if the application does multiple
++ requests. */
++#if 0
++ hp->id = htons(++statp->id);
++#else
++ hp->id = htons(statp->id);
++ int randombits;
++ do
++ {
++#ifdef RANDOM_BITS
++ RANDOM_BITS (randombits);
++#else
++ struct timeval tv;
++ gettimeofday (&tv, NULL);
++ randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
++#endif
++ }
++ while ((randombits & 0xffff) == 0);
++ statp->id = (statp->id + randombits) & 0xffff;
++#endif
++ hp->opcode = op;
++ hp->rd = (statp->options & RES_RECURSE) != 0;
++ hp->rcode = NOERROR;
++ cp = buf + HFIXEDSZ;
++ buflen -= HFIXEDSZ;
++ dpp = dnptrs;
++ *dpp++ = buf;
++ *dpp++ = NULL;
++ lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
++ /*
++ * perform opcode specific processing
++ */
++ switch (op) {
++ case QUERY: /*FALLTHROUGH*/
++ case NS_NOTIFY_OP:
++ if ((buflen -= QFIXEDSZ) < 0)
++ return (-1);
++ if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
++ return (-1);
++ cp += n;
++ buflen -= n;
++ __putshort(type, cp);
++ cp += INT16SZ;
++ __putshort(class, cp);
++ cp += INT16SZ;
++ hp->qdcount = htons(1);
++ if (op == QUERY || data == NULL)
++ break;
++ /*
++ * Make an additional record for completion domain.
++ */
++ buflen -= RRFIXEDSZ;
++ n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
++ if (n < 0)
++ return (-1);
++ cp += n;
++ buflen -= n;
++ __putshort(T_NULL, cp);
++ cp += INT16SZ;
++ __putshort(class, cp);
++ cp += INT16SZ;
++ __putlong(0, cp);
++ cp += INT32SZ;
++ __putshort(0, cp);
++ cp += INT16SZ;
++ hp->arcount = htons(1);
++ break;
++
++ case IQUERY:
++ /*
++ * Initialize answer section
++ */
++ if (buflen < 1 + RRFIXEDSZ + datalen)
++ return (-1);
++ *cp++ = '\0'; /* no domain name */
++ __putshort(type, cp);
++ cp += INT16SZ;
++ __putshort(class, cp);
++ cp += INT16SZ;
++ __putlong(0, cp);
++ cp += INT32SZ;
++ __putshort(datalen, cp);
++ cp += INT16SZ;
++ if (datalen) {
++ memcpy(cp, data, datalen);
++ cp += datalen;
++ }
++ hp->ancount = htons(1);
++ break;
++
++ default:
++ return (-1);
++ }
++ return (cp - buf);
++}
++
++int
++res_mkquery(int op, /* opcode of query */
++ const char *dname, /* domain name */
++ int class, int type, /* class and type of query */
++ const u_char *data, /* resource record data */
++ int datalen, /* length of data */
++ const u_char *newrr_in, /* new rr for modify or append */
++ u_char *buf, /* buffer to put query */
++ int buflen) /* size of buffer */
++{
++ return (res_nmkquery(&_res, op, dname, class, type,
++ data, datalen,
++ newrr_in, buf, buflen));
++}
++
++#endif
+
+ void dorequest(char *s,int type,word id)
+ {