1846. [contrib] query-loc-0.3.0 from Stephane Bortzmeyer

<bortzmeyer@nic.fr>.
This commit is contained in:
Mark Andrews
2005-04-01 05:35:01 +00:00
parent 46cb442c5c
commit 959fb01017
17 changed files with 8027 additions and 0 deletions

View File

@@ -1,3 +1,6 @@
1846. [contrib] query-loc-0.3.0 from Stephane Bortzmeyer
<bortzmeyer@nic.fr>.
1845. [placeholder] rt13745
1844. [bug] inet_pton() accepted more that 4 hexadecimal digits

View File

@@ -0,0 +1,18 @@
The following machines, at least today seem to have LOC
records:
*.cpod.fr (for instance www.cpod.fr)
130.104.3.*
195.202.193.*
Melanie.Tolna.Net
204.92.254.*
mail.vitts.com
alink.net
caida.org
ckdhr.com
distributed.net (rc5stats.distributed.net)
nikhef.nl
yahoo.com
nic.af
$Id: ADDRESSES,v 1.1 2005/04/01 05:34:59 marka Exp $

View File

@@ -0,0 +1,48 @@
Just for info, can be out of date.
RFC 1876, 5.2, specially 5.2.3
Important points:
- LOC RRs are always attached to a *name*.
- we can have two (or more) RRs for one address, one more specific than the other
main
if (host is a name)
getLOCbyname
else # host is an IP address
gethostbyaddr
if (name)
getLOCbyname
# If there is none, do not search. We assume the above was sufficient # (But check 5.2.2)
else
getLOCbyaddress
getLOCbyname (host)
get LOC for host
if (it exists)
OK
else
get all A records of the name
foreach A record
getLOCbyaddress
OK at the first one found
# we assume they are consistent
END
getLOCbyaddress (address)
# May receive a mask. Otherwise, deduce it from the class
makeNetAddress
getLOCbynetwork
getLOCbynetwork
get PTR and A for it
if (exist)
getLOCbyname
******* DIFFICULT : we have to manage a stack. See the code
makeNetAddress (level--)
getLOCbynetwork
else
END

View File

@@ -0,0 +1,9 @@
Type './configure', then 'make' and (as root if necessary) 'make
install'.
It requires a recent libresolv, with loc_ntoa, but use an alternative
which I provide, if not found.
Tested on Linux (i386 and Alpha), Solaris (Sparc) and Digital Unix (Alpha).
$Id: INSTALL,v 1.1 2005/04/01 05:34:59 marka Exp $

View File

@@ -0,0 +1,40 @@
# $Id: Makefile.in,v 1.1 2005/04/01 05:34:59 marka Exp $
CC=@CC@
CFLAGS=@CFLAGS@
LIBS=@LIBS@
DESTDIR=@prefix@
BINDIR=@prefix@/bin
MANDIR=@prefix@/share/man/man1
DISTRIB= README INSTALL ALGO USAGE ADDRESSES Makefile.in configure configure.in config.h.in install-sh loc.h loc.c query-loc.c loc_ntoa.c query-loc.1
OBJS=query-loc.o loc.o @LOC_NTOA@
VERSION=`grep VERSION loc.h | cut -d ' ' -f 3 | sed s/\"//g`
all: query-loc
query-loc: $(OBJS)
$(CC) -o $@ $(OBJS) $(LIBS)
%.o: %.c loc.h
$(CC) $(CFLAGS) -c $<
clean:
rm -f *.o query-loc *~
distclean: clean
rm -f config.h config.cache config.log config.status Makefile
distrib: clean
./reconf
@(echo Query-Loc is version ${VERSION}; \
mkdir query-loc-${VERSION}; \
cp $(DISTRIB) query-loc-${VERSION};\
tar cvf query-loc-${VERSION}.tar query-loc-${VERSION}; \
rm -rf query-loc-${VERSION}; \
gzip -v -9 -f query-loc-${VERSION}.tar);
install:
@INSTALL@ -m 0755 query-loc $(BINDIR)
if [ ! -d $(MANDIR) ]; then \
mkdir $(MANDIR); \
fi
@INSTALL@ -m 0644 query-loc.1 $(MANDIR)

View File

@@ -0,0 +1,20 @@
query-loc: a program to retrieve and display the location
information in the DNS.
It uses the algorithms described in
RFC 1876 (and RFC 1101 to get the network names).
You can find examples of networks wchich implement this scheme
in the ADDRESSES file.
It is under the General Public Licence (GPL, which
you can fetch from <http://www.gnu.org/copyleft/gpl.html>.
Copyright Stéphane Bortzmeyer <bortzmeyer@debian.org>, 1998.
Thanks to Paul Vixie for the RFC and its encouragements. Thanks
to Björn Augustsson for the xtraceroute program
<http://www.dtek.chalmers.se/~d3august/xt/>.
$Id: README,v 1.1 2005/04/01 05:34:59 marka Exp $

View File

@@ -0,0 +1,8 @@
query-loc [-v] [-d nnn] host-name-or-address
Examples of hosts with LOCation info (quite uncommon, if you know more,
please tell me):
- Everything in the 193.105.79.0 network, such as www.humanite.presse.fr
- Everything in the 192.88.144 network, such as www.kei.com

View File

@@ -0,0 +1,69 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* $Id: config.h.in,v 1.1 2005/04/01 05:35:00 marka Exp $ */
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `resolv' library (-lresolv). */
#undef HAVE_LIBRESOLV
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* The size of a `char', as computed by sizeof. */
#undef SIZEOF_CHAR
/* The size of a `int', as computed by sizeof. */
#undef SIZEOF_INT
/* The size of a `long', as computed by sizeof. */
#undef SIZEOF_LONG
/* The size of a `short', as computed by sizeof. */
#undef SIZEOF_SHORT
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Is there a loc_ntoa on this system? */
#undef HAVE_LOC_NTOA

6436
contrib/query-loc-0.3.0/configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
dnl Process this file with autoconf to produce a configure script.
AC_RELEASE("$Id: configure.in,v 1.1 2005/04/01 05:35:00 marka Exp $")
AC_INIT(query-loc.c)
dnl Checks for programs.
AC_PROG_CC
if test "$GCC" = "yes"; then
CFLAGS="${CFLAGS} -Wall"
fi
AC_PROG_INSTALL
dnl Checks for libraries.
AC_CHECK_LIB(resolv, res_query)
dnl Checks for header files.
AC_HEADER_STDC
AC_CONFIG_HEADER(config.h)
AC_CHECK_HEADER(resolv.h, , AC_MSG_ERROR("No headers for name service applications"))
AC_CHECK_HEADER(arpa/nameser.h, , AC_MSG_ERROR("No headers for name service applications"))
AC_CHECK_HEADER(sys/time.h, , AC_MSG_ERROR("Mandatory header missing on your system"))
AC_CHECK_HEADER(unistd.h, , AC_MSG_ERROR("Mandatory header missing on your system"))
dnl This one is only useful for Solaris?
AC_MSG_CHECKING(if libnsl is mandatory)
AC_TRY_LINK([#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
union
{
HEADER hdr;
u_char buf[4096]; /* With RFC 2671, otherwise 512 is enough */
}
response;
char *domain;
int requested_type; ],
[res_query(domain,
C_IN,
requested_type,
(u_char *) & response,
sizeof (response)) ], dnl
[AC_MSG_RESULT(no)], dnl
[AC_MSG_RESULT(yes); LIBS="${LIBS} -lnsl"])
dnl Check for the loc_ntoa macro/function
AC_MSG_CHECKING(loc_ntoa)
AC_TRY_LINK([#include <resolv.h>], dnl
[u_char *cp; char *result; loc_ntoa(cp, result)], dnl
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_LOC_NTOA)], dnl
[AC_MSG_RESULT([no, using the alternative]); LOC_NTOA=loc_ntoa.o])
AC_SUBST(LOC_NTOA)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(char)
dnl Misc.
AC_OUTPUT(Makefile)

View File

@@ -0,0 +1,251 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, 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 M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

View File

@@ -0,0 +1,566 @@
#include "loc.h"
/* $Id: loc.c,v 1.1 2005/04/01 05:35:00 marka Exp $ */
/* Global variables */
short rr_errno;
/*
Prints the actual usage
*/
void
usage ()
{
(void) fprintf (stderr,
"Usage: %s: [-v] [-d nnn] hostname\n", progname);
exit (2);
}
/*
Panics
*/
void
panic (message)
char *message;
{
(void) fprintf (stderr,
"%s: %s\n", progname, message);
exit (2);
}
/*
** IN_ADDR_ARPA -- Convert dotted quad string to reverse in-addr.arpa
** ------------------------------------------------------------------
**
** Returns:
** Pointer to appropriate reverse in-addr.arpa name
** with trailing dot to force absolute domain name.
** NULL in case of invalid dotted quad input string.
*/
#ifndef ARPA_ROOT
#define ARPA_ROOT "in-addr.arpa"
#endif
char *
in_addr_arpa (dottedquad)
char *dottedquad; /* input string with dotted quad */
{
static char addrbuf[4 * 4 + sizeof (ARPA_ROOT) + 2];
unsigned int a[4];
register int n;
n = sscanf (dottedquad, "%u.%u.%u.%u", &a[0], &a[1], &a[2], &a[3]);
switch (n)
{
case 4:
(void) sprintf (addrbuf, "%u.%u.%u.%u.%s.",
a[3] & 0xff, a[2] & 0xff, a[1] & 0xff, a[0] & 0xff, ARPA_ROOT);
break;
case 3:
(void) sprintf (addrbuf, "%u.%u.%u.%s.",
a[2] & 0xff, a[1] & 0xff, a[0] & 0xff, ARPA_ROOT);
break;
case 2:
(void) sprintf (addrbuf, "%u.%u.%s.",
a[1] & 0xff, a[0] & 0xff, ARPA_ROOT);
break;
case 1:
(void) sprintf (addrbuf, "%u.%s.",
a[0] & 0xff, ARPA_ROOT);
break;
default:
return (NULL);
}
while (--n >= 0)
if (a[n] > 255)
return (NULL);
return (addrbuf);
}
/*
Returns a human-readable version of the LOC information or
NULL if it failed. Argument is a name (of a network or a machine)
and a boolean telling is it is a network name or a machine name.
*/
char *
getlocbyname (name, is_network)
const char *name;
short is_network;
{
char *result;
struct list_in_addr *list, *p;
result = findRR (name, T_LOC);
if (result != NULL)
{
if (debug >= 2)
printf ("LOC record found for the name %s\n", name);
return result;
}
else
{
if (!is_network)
{
list = findA (name);
if (debug >= 2)
printf ("No LOC record found for the name %s, trying addresses\n", name);
if (list != NULL)
{
for (p = list; p != NULL; p = p->next)
{
if (debug >= 2)
printf ("Trying address %s\n", inet_ntoa (p->addr));
result = getlocbyaddr (p->addr, NULL);
if (result != NULL)
return result;
}
return NULL;
}
else
{
if (debug >= 2)
printf (" No A record found for %s\n", name);
return NULL;
}
}
else
{
if (debug >= 2)
printf ("No LOC record found for the network name %s\n", name);
return NULL;
}
}
}
/*
Returns a human-readable version of the LOC information or
NULL if it failed. Argument is an IP address.
*/
char *
getlocbyaddr (addr, mask)
const struct in_addr addr;
const struct in_addr *mask;
{
struct in_addr netaddr;
u_int32_t a;
struct in_addr themask;
char *text_addr, *text_mask;
if (mask == NULL)
{
themask.s_addr = (u_int32_t) 0;
}
else
{
themask = *mask;
}
text_addr = (char *) malloc (256);
text_mask = (char *) malloc (256);
strcpy (text_addr, inet_ntoa (addr));
strcpy (text_mask, inet_ntoa (themask));
if (debug >= 2)
printf ("Testing address %s/%s\n", text_addr, text_mask);
if (mask == NULL)
{
a = ntohl (addr.s_addr);
if (IN_CLASSA (a))
{
netaddr.s_addr = htonl (a & IN_CLASSA_NET);
}
else if (IN_CLASSB (a))
{
netaddr.s_addr = htonl (a & IN_CLASSB_NET);
}
else if (IN_CLASSC (a))
{
netaddr.s_addr = htonl (a & IN_CLASSC_NET);
}
else
{
/* Error */
}
return getlocbynet (in_addr_arpa (inet_ntoa (netaddr)), addr, mask);
}
else
{
netaddr.s_addr = addr.s_addr & themask.s_addr;
return getlocbynet (in_addr_arpa (inet_ntoa (netaddr)), addr, mask);
}
}
/*
Returns a human-readable LOC.
Argument is a network name in the 0.z.y.x.in-addr.arpa format
and the original address
*/
char *
getlocbynet (name, addr, mask)
char *name;
struct in_addr addr;
struct in_addr *mask;
{
char *network;
char *result, *result_int;
struct list_in_addr *list;
if (debug >= 2)
printf ("Testing network %s\n", name);
network = findRR (name, T_PTR);
if (network == NULL)
{
if (debug >= 2)
printf ("No name for network %s\n", name);
return NULL;
}
else
{
result = getlocbyname (network, TRUE);
list = findA (network);
if (list == NULL)
{
return result;
}
else if ((mask != NULL) &&
((mask->s_addr) == (list->addr.s_addr)))
{
/* Already checked */
return result;
}
else
{
result_int = getlocbyaddr (addr, &list->addr);
if (result_int == NULL)
return result;
else
return result_int;
}
}
}
/*
The code for these two functions is stolen from the examples in Liu and Albitz
book "DNS and BIND" (O'Reilly).
*/
/****************************************************************
* skipName -- This routine skips over a domain name. If the *
* domain name expansion fails, it crashes. *
* dn_skipname() is probably not on your manual *
* page; it is similar to dn_expand() except that it just *
* skips over the name. dn_skipname() is in res_comp.c if *
* you need to find it. *
****************************************************************/
int
skipName (cp, endOfMsg)
u_char *cp;
u_char *endOfMsg;
{
int n;
if ((n = dn_skipname (cp, endOfMsg)) < 0)
{
panic ("dn_skipname failed\n");
}
return (n);
}
/****************************************************************
* skipToData -- This routine advances the cp pointer to the *
* start of the resource record data portion. On the way, *
* it fills in the type, class, ttl, and data length *
****************************************************************/
int
skipToData (cp, type, class, ttl, dlen, endOfMsg)
u_char *cp;
u_short *type;
u_short *class;
u_int32_t *ttl;
u_short *dlen;
u_char *endOfMsg;
{
u_char *tmp_cp = cp; /* temporary version of cp */
/* Skip the domain name; it matches the name we looked up */
tmp_cp += skipName (tmp_cp, endOfMsg);
/*
* Grab the type, class, and ttl. GETSHORT and GETLONG
* are macros defined in arpa/nameser.h.
*/
GETSHORT (*type, tmp_cp);
GETSHORT (*class, tmp_cp);
GETLONG (*ttl, tmp_cp);
GETSHORT (*dlen, tmp_cp);
return (tmp_cp - cp);
}
/*
Returns a human-readable version of a DNS RR (resource record)
associated with the name 'domain'.
If it does not find, ir returns NULL and sets rr_errno to explain why.
The code for this function is stolen from the examples in Liu and Albitz
book "DNS and BIND" (O'Reilly).
*/
char *
findRR (domain, requested_type)
char *domain;
int requested_type;
{
char *result, *message;
union
{
HEADER hdr; /* defined in resolv.h */
u_char buf[PACKETSZ]; /* defined in arpa/nameser.h */
}
response; /* response buffers */
short found = 0;
int responseLen; /* buffer length */
u_char *cp; /* character pointer to parse DNS packet */
u_char *endOfMsg; /* need to know the end of the message */
u_short class; /* classes defined in arpa/nameser.h */
u_short type; /* types defined in arpa/nameser.h */
u_int32_t ttl; /* resource record time to live */
u_short dlen; /* size of resource record data */
int i, count, dup; /* misc variables */
char *ptrList[1];
int ptrNum = 0;
struct in_addr addr;
result = (char *) malloc (256);
message = (char *) malloc (256);
/*
* Look up the records for the given domain name.
* We expect the domain to be a fully qualified name, so
* we use res_query(). If we wanted the resolver search
* algorithm, we would have used res_search() instead.
*/
if ((responseLen =
res_query (domain, /* the domain we care about */
C_IN, /* Internet class records */
requested_type, /* Look up name server records */
(u_char *) & response, /*response buffer */
sizeof (response))) /*buffer size */
< 0)
{ /*If negative */
rr_errno = h_errno;
return NULL;
}
/*
* Keep track of the end of the message so we don't
* pass it while parsing the response. responseLen is
* the value returned by res_query.
*/
endOfMsg = response.buf + responseLen;
/*
* Set a pointer to the start of the question section,
* which begins immediately AFTER the header.
*/
cp = response.buf + sizeof (HEADER);
/*
* Skip over the whole question section. The question
* section is comprised of a name, a type, and a class.
* QFIXEDSZ (defined in arpa/nameser.h) is the size of
* the type and class portions, which is fixed. Therefore,
* we can skip the question section by skipping the
* name (at the beginning) and then advancing QFIXEDSZ.
* After this calculation, cp points to the start of the
* answer section, which is a list of NS records.
*/
cp += skipName (cp, endOfMsg) + QFIXEDSZ;
count = ntohs (response.hdr.ancount) +
ntohs (response.hdr.nscount);
while ((--count >= 0) /* still more records */
&& (cp < endOfMsg))
{ /* still inside the packet */
/* Skip to the data portion of the resource record */
cp += skipToData (cp, &type, &class, &ttl, &dlen, endOfMsg);
if (type == requested_type)
{
switch (requested_type)
{
case (T_LOC):
loc_ntoa (cp, result);
return result;
break;
case (T_PTR):
ptrList[ptrNum] = (char *) malloc (MAXDNAME);
if (ptrList[ptrNum] == NULL)
{
panic ("Malloc failed");
}
if (dn_expand (response.buf, /* Start of the packet */
endOfMsg, /* End of the packet */
cp, /* Position in the packet */
(u_char *) ptrList[ptrNum], /* Result */
MAXDNAME) /* size of ptrList buffer */
< 0)
{ /* Negative: error */
panic ("dn_expand failed");
}
/*
* Check the name we've just unpacked and add it to
* the list if it is not a duplicate.
* If it is a duplicate, just ignore it.
*/
for (i = 0, dup = 0; (i < ptrNum) && !dup; i++)
dup = !strcasecmp (ptrList[i], ptrList[ptrNum]);
if (dup)
free (ptrList[ptrNum]);
else
ptrNum++;
strcpy (result, ptrList[0]);
return result;
break;
case (T_A):
bcopy ((char *) cp, (char *) &addr, INADDRSZ);
strcat (result, " ");
strcat (result, inet_ntoa (addr));
found = 1;
break;
default:
sprintf (message, "Unexpected type %u", requested_type);
panic (message);
}
}
/* Advance the pointer over the resource record data */
cp += dlen;
} /* end of while */
if (found)
return result;
else
return NULL;
}
struct list_in_addr *
findA (domain)
char *domain;
{
struct list_in_addr *result, *end;
union
{
HEADER hdr; /* defined in resolv.h */
u_char buf[PACKETSZ]; /* defined in arpa/nameser.h */
}
response; /* response buffers */
int responseLen; /* buffer length */
u_char *cp; /* character pointer to parse DNS packet */
u_char *endOfMsg; /* need to know the end of the message */
u_short class; /* classes defined in arpa/nameser.h */
u_short type; /* types defined in arpa/nameser.h */
u_int32_t ttl; /* resource record time to live */
u_short dlen; /* size of resource record data */
int count; /* misc variables */
struct in_addr addr;
end = NULL;
result = NULL;
/*
* Look up the records for the given domain name.
* We expect the domain to be a fully qualified name, so
* we use res_query(). If we wanted the resolver search
* algorithm, we would have used res_search() instead.
*/
if ((responseLen =
res_query (domain, /* the domain we care about */
C_IN, /* Internet class records */
T_A,
(u_char *) & response, /*response buffer */
sizeof (response))) /*buffer size */
< 0)
{ /*If negative */
rr_errno = h_errno;
return NULL;
}
/*
* Keep track of the end of the message so we don't
* pass it while parsing the response. responseLen is
* the value returned by res_query.
*/
endOfMsg = response.buf + responseLen;
/*
* Set a pointer to the start of the question section,
* which begins immediately AFTER the header.
*/
cp = response.buf + sizeof (HEADER);
/*
* Skip over the whole question section. The question
* section is comprised of a name, a type, and a class.
* QFIXEDSZ (defined in arpa/nameser.h) is the size of
* the type and class portions, which is fixed. Therefore,
* we can skip the question section by skipping the
* name (at the beginning) and then advancing QFIXEDSZ.
* After this calculation, cp points to the start of the
* answer section, which is a list of NS records.
*/
cp += skipName (cp, endOfMsg) + QFIXEDSZ;
count = ntohs (response.hdr.ancount) +
ntohs (response.hdr.nscount);
while ((--count >= 0) /* still more records */
&& (cp < endOfMsg))
{ /* still inside the packet */
/* Skip to the data portion of the resource record */
cp += skipToData (cp, &type, &class, &ttl, &dlen, endOfMsg);
if (type == T_A)
{
bcopy ((char *) cp, (char *) &addr, INADDRSZ);
if (end == NULL)
{
result = (void *) malloc (sizeof (struct list_in_addr));
result->addr = addr;
result->next = NULL;
end = result;
}
else
{
end->next = (void *) malloc (sizeof (struct list_in_addr));
end = end->next;
end->addr = addr;
end->next = NULL;
}
}
/* Advance the pointer over the resource record data */
cp += dlen;
} /* end of while */
return result;
}

View File

@@ -0,0 +1,78 @@
/* $Id: loc.h,v 1.1 2005/04/01 05:35:00 marka Exp $ */
#define VERSION "0.3.0"
#include "config.h"
/* Probably too many inclusions but this is to keep 'gcc -Wall' happy... */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <arpa/nameser.h>
#include <resolv.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#if SIZEOF_LONG == 4
#define u_int32_t unsigned long
#ifndef int32_t
#define int32_t long
#endif
#else
#define u_int32_t unsigned int
#ifndef int32_t
#define int32_t int
#endif
#endif
#if SIZEOF_CHAR == 1
#define u_int8_t unsigned char
#ifndef int8_t
#define int8_t char
#endif
#else
#if SIZEOF_SHORT == 1
#define u_int8_t unsigned short
#ifndef int8_t
#define int8_t short
#endif
#else
#error "No suitable native type for storing bytes"
#endif
#endif
#ifndef INADDR_NONE
#define INADDR_NONE (in_addr_t)-1
#endif
struct list_in_addr
{
struct in_addr addr;
void *next;
};
void usage ();
void panic ();
char *getlocbyname ();
char *getlocbyaddr ();
char *getlocbynet ();
char *findRR ();
struct list_in_addr *findA ();
extern char *progname;
extern short debug;

View File

@@ -0,0 +1,248 @@
/* Stolen from BIND */
/*
* Copyright (c) 1985
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies, and that
* the name of Digital Equipment Corporation not be used in advertising or
* publicity pertaining to distribution of the document or software without
* specific, written prior permission.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, 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.
*/
/*
* Portions Copyright (c) 1995 by International Business Machines, Inc.
*
* International Business Machines, Inc. (hereinafter called IBM) grants
* permission under its copyrights to use, copy, modify, and distribute this
* Software with or without fee, provided that the above copyright notice and
* all paragraphs of this notice appear in all copies, and that the name of IBM
* not be used in connection with the marketing of any product incorporating
* the Software or modifications thereof, without specific, written prior
* permission.
*
* To the extent it has a right to do so, IBM grants an immunity from suit
* under its patents, if any, for the use, sale or manufacture of products to
* the extent that such products are used for performing Domain Name System
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
* granted for any product per se or for any other function of any product.
*
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
/*
* Portions Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, 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.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ctype.h>
#include <errno.h>
#include <math.h>
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "loc.h"
const char *precsize_ntoa();
/* takes an on-the-wire LOC RR and formats it in a human readable format. */
const char *
loc_ntoa(binary, ascii)
const u_char *binary;
char *ascii;
{
static char *error = "?";
static char tmpbuf[sizeof
"1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"];
const u_char *cp = binary;
int latdeg, latmin, latsec, latsecfrac;
int longdeg, longmin, longsec, longsecfrac;
char northsouth, eastwest;
int altmeters, altfrac, altsign;
const u_int32_t referencealt = 100000 * 100;
int32_t latval, longval, altval;
u_int32_t templ;
u_int8_t sizeval, hpval, vpval, versionval;
char *sizestr, *hpstr, *vpstr;
versionval = *cp++;
if (ascii == NULL)
ascii = tmpbuf;
if (versionval) {
(void) sprintf(ascii, "; error: unknown LOC RR version");
return (ascii);
}
sizeval = *cp++;
hpval = *cp++;
vpval = *cp++;
GETLONG(templ, cp);
latval = (templ - ((unsigned)1<<31));
GETLONG(templ, cp);
longval = (templ - ((unsigned)1<<31));
GETLONG(templ, cp);
if (templ < referencealt) { /* below WGS 84 spheroid */
altval = referencealt - templ;
altsign = -1;
} else {
altval = templ - referencealt;
altsign = 1;
}
if (latval < 0) {
northsouth = 'S';
latval = -latval;
} else
northsouth = 'N';
latsecfrac = latval % 1000;
latval = latval / 1000;
latsec = latval % 60;
latval = latval / 60;
latmin = latval % 60;
latval = latval / 60;
latdeg = latval;
if (longval < 0) {
eastwest = 'W';
longval = -longval;
} else
eastwest = 'E';
longsecfrac = longval % 1000;
longval = longval / 1000;
longsec = longval % 60;
longval = longval / 60;
longmin = longval % 60;
longval = longval / 60;
longdeg = longval;
altfrac = altval % 100;
altmeters = (altval / 100) * altsign;
if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
sizestr = error;
if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
hpstr = error;
if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
vpstr = error;
sprintf(ascii,
"%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
latdeg, latmin, latsec, latsecfrac, northsouth,
longdeg, longmin, longsec, longsecfrac, eastwest,
altmeters, altfrac, sizestr, hpstr, vpstr);
if (sizestr != error)
free(sizestr);
if (hpstr != error)
free(hpstr);
if (vpstr != error)
free(vpstr);
return (ascii);
}
static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1000000,10000000,100000000,1000000000};
/* takes an XeY precision/size value, returns a string representation. */
const char *
precsize_ntoa(prec)
u_int8_t prec;
{
static char retbuf[sizeof "90000000.00"]; /* XXX nonreentrant */
unsigned long val;
int mantissa, exponent;
mantissa = (int)((prec >> 4) & 0x0f) % 10;
exponent = (int)((prec >> 0) & 0x0f) % 10;
val = mantissa * poweroften[exponent];
(void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);
return (retbuf);
}

View File

@@ -0,0 +1,55 @@
.\" Hey, EMACS: -*- nroff -*-
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH QUERY-LOC SECTION "January 11, 2005"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
query-loc \- to retrieve and display the location information in the DNS
.SH SYNOPSIS
.B query-loc
.RI [-v] [-d nnn] " host"
.SH DESCRIPTION
This manual page documents briefly the
.B query-loc
command.
.PP
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
.\" respectively.
\fBquery-loc\fP is a program to retrieve and display the location
information in the DNS.
It uses the algorithms described in
RFC 1876 (and RFC 1101 to get the network names).
You can find examples of networks wchich implement this scheme
in the ADDRESSES file.
.SH OPTIONS
.TP
.B \-v
Verbose mode.
.TP
.B \-d nnn
Debug mode. Displays the RFC's algorithm
.SH BUGS
Very few hosts have location information.
.SH AUTHOR
This manual page was written by Stephane Bortzmeyer
<bortzmeyer@debian.org>.
.\" $Id: query-loc.1,v 1.1 2005/04/01 05:35:01 marka Exp $

View File

@@ -0,0 +1,98 @@
#include "loc.h"
/* $Id: query-loc.c,v 1.1 2005/04/01 05:35:01 marka Exp $ */
/* Global variables */
char *progname;
short debug;
int
main (argc, argv)
int argc;
char *argv[];
{
extern char *optarg;
extern int optind;
short verbose = FALSE;
char *host;
char ch;
char *loc = NULL;
struct in_addr addr;
struct hostent *hp;
progname = argv[0];
while ((ch = getopt (argc, argv, "vd:")) != EOF)
{
switch (ch)
{
case 'v':
verbose = TRUE;
break;
case 'd':
debug = atoi (optarg);
if (debug <= 0)
{
(void) fprintf (stderr,
"%s: illegal debug value.\n", progname);
exit (2);
}
break;
default:
usage ();
}
}
argc -= optind;
argv += optind;
if (argc != 1)
{
usage ();
}
if (verbose || debug)
{
printf ("\nThis is %s, version %s.\n\n", progname, VERSION);
}
host = argv[0];
(void) res_init ();
if ((addr.s_addr = inet_addr (host)) == INADDR_NONE)
{
if (debug >= 1)
printf ("%s is a name\n", host);
loc = getlocbyname (host, FALSE);
}
else
{
if (debug >= 1)
printf ("%s is an IP address ", host);
hp = (struct hostent *) gethostbyaddr
((char *) &addr, sizeof (addr), AF_INET);
if (hp)
{
if (debug >= 1)
printf ("and %s is its official name\n",
hp->h_name);
loc = getlocbyname (hp->h_name, FALSE);
}
else
{
if (debug >= 1)
printf ("which has no name\n");
loc = getlocbyaddr (addr, NULL);
}
}
if (loc == NULL)
{
printf ("No LOCation found for %s\n", host);
exit (1);
}
else
{
if (verbose || debug)
printf ("LOCation for %s is ", host);
printf ("%s\n", loc);
exit (0);
}
}

View File

@@ -1048,6 +1048,21 @@
./contrib/nslint-2.1a3/savestr.c X 2001
./contrib/nslint-2.1a3/savestr.h X 2001
./contrib/nslint-2.1a3/strerror.c X 2001
./contrib/query-loc-0.3.0/ADDRESSES X 2005
./contrib/query-loc-0.3.0/ALGO X 2005
./contrib/query-loc-0.3.0/INSTALL X 2005
./contrib/query-loc-0.3.0/Makefile.in X 2005
./contrib/query-loc-0.3.0/README X 2005
./contrib/query-loc-0.3.0/USAGE X 2005
./contrib/query-loc-0.3.0/config.h.in X 2005
./contrib/query-loc-0.3.0/configure X 2005
./contrib/query-loc-0.3.0/configure.in X 2005
./contrib/query-loc-0.3.0/install-sh X 2005
./contrib/query-loc-0.3.0/loc.c X 2005
./contrib/query-loc-0.3.0/loc.h X 2005
./contrib/query-loc-0.3.0/loc_ntoa.c X 2005
./contrib/query-loc-0.3.0/query-loc.1 X 2005
./contrib/query-loc-0.3.0/query-loc.c X 2005
./contrib/queryperf/.cvsignore X 2001
./contrib/queryperf/Makefile.in X 2001
./contrib/queryperf/README X 2001