From 9459ddeed8adcdb90525f433846abf3b31444c6b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sat, 5 Aug 2006 17:10:23 +0000 Subject: [PATCH] Port mtr to -ng SVN-Revision: 4471 --- net/mtr/Makefile | 94 +++++++ net/mtr/patches/501-dns.patch | 511 ++++++++++++++++++++++++++++++++++ 2 files changed, 605 insertions(+) create mode 100644 net/mtr/Makefile create mode 100644 net/mtr/patches/501-dns.patch diff --git a/net/mtr/Makefile b/net/mtr/Makefile new file mode 100644 index 0000000000..08b7e4be01 --- /dev/null +++ b/net/mtr/Makefile @@ -0,0 +1,94 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +# $Id$ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=mtr +PKG_VERSION:=0.69 +PKG_RELEASE:=1 +PKG_MD5SUM:=58904d6d8d70114195cdeb653d56914c + +PKG_SOURCE_URL:=ftp://ftp.bitwizard.nl/mtr/ +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_CAT:=zcat +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install + +include $(INCLUDE_DIR)/package.mk + +define Package/mtr + SECTION:=net + CATEGORY:=Network + DEPENDS:=+libncurses + TITLE:=Full screen ncurses traceroute tool + DESCRIPTION:=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.\\\ + URL:=http://www.bitwizard.nl/mtr/ +endef + +define Build/Configure + (cd $(PKG_BUILD_DIR); rm -rf config.{cache,status}; \ + touch configure.in; \ + touch aclocal.m4; \ + touch Makefile.in; \ + touch img/Makefile.in; \ + touch stamp-h.in; \ + touch config.h.in; \ + touch configure; \ + $(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 \ + ); +endef + +define Build/Compile + 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 +endef + +define Package/mtr/install + install -d -m0755 $(1)/usr/sbin + $(CP) $(PKG_INSTALL_DIR)/usr/sbin/mtr $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,mtr)) diff --git a/net/mtr/patches/501-dns.patch b/net/mtr/patches/501-dns.patch new file mode 100644 index 0000000000..f1c915580d --- /dev/null +++ b/net/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) + { -- 2.30.2