home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.shrubbery.net
/
2015-02-07.ftp.shrubbery.net.tar
/
ftp.shrubbery.net
/
pub
/
astraceroute
/
astraceroute-1.4.a12.2.tar.gz
/
astraceroute-1.4.a12.2.tar
/
astraceroute-1.4.a12.2
/
asns.c
< prev
next >
Wrap
C/C++ Source or Header
|
2007-01-25
|
5KB
|
200 lines
/*
* $Id: asns.c,v 1.3 2007/01/25 09:36:45 heas Exp $
*
* Copyright (c) 2007, heas@shrubbery.net
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <arpa/nameser.h>
#include <netdb.h>
#include <netinet/in.h>
#include <resolv.h>
#include <string.h>
#include <sys/socket.h>
#include "traceroute.h"
#define DOFF_Q 4
#define DOFF_DATA 12 /* header length / data offset, TCP
* transport adds 2 bytes to each for
* the msg length */
#define DTYPE_TXT 16
static int dns_skip(uint8_t **, uint16_t *);
extern int h_errno;
static u_char answer[1024],
*ap;
#define NAMELEN 257
static char name[NAMELEN];
static char dname[NAMELEN];
extern int asns;
uint32_t
asn_lookup(struct sockaddr_in *sin)
{
int ecode, len;
u_char ipv4[4];
uint16_t a, resid, rdatalen, q;
uint32_t ASN = 0;
if (!(_res.options & RES_INIT))
if (res_init()) {
fprintf(stderr, "resolver initialization failed\n");
asns = 0;
}
if (sin->sin_family != AF_INET)
return(0);
/* XXX add support for INET6 when routeviews offers it */
memcpy(ipv4, &sin->sin_addr, 4);
if (snprintf(dname, NAMELEN, "%d.%d.%d.%d.asn.routeviews.org", ipv4[3],
ipv4[2], ipv4[1], ipv4[0]) >= NAMELEN) {
return(0);
}
if ((len = res_query(dname, C_IN, T_TXT, answer, sizeof(answer))) == -1) {
switch (h_errno) {
case HOST_NOT_FOUND:
fprintf(stderr, "no route\n");
break;
case TRY_AGAIN:
break;
case NO_RECOVERY:
fprintf(stderr, "no recovery\n");
break;
case NO_DATA:
fprintf(stderr, "no data\n");
break;
default:
fprintf(stderr, "unknown error\n");
break;
}
return(0);
}
ap = answer + DOFF_Q;
memcpy(&q, ap, 2);
q = ntohs(q);
ap += 2;
memcpy(&a, ap, 2);
a = ntohs(a);
if (!a)
return(0);
ap = answer + DOFF_DATA;
resid = len - DOFF_DATA;
/* skip questions */
while (q--) {
if (dns_skip((uint8_t **)&ap, &resid) < 0)
return(0);
/* skip question RR type and class */
ap += 4;
resid -= 4;
}
while (a--) {
if ((ecode = dn_expand(answer, answer + len, ap, name, sizeof(name)))
< 1) {
return(0);
}
if (dns_skip((uint8_t **)&ap, &resid) < 0)
return(0);
if (strcasecmp(name, dname) != 0) {
skip:
/* skip RR type, class and TTL */
ap += 8;
resid -= 8;
memcpy(&rdatalen, ap, 2);
rdatalen = ntohs(rdatalen);
ap += 2 + rdatalen;
resid -= 2 + rdatalen;
continue;
}
/* skip RR type, class and TTL */
memcpy(&rdatalen, ap, 2);
if (ntohs(rdatalen) != DTYPE_TXT)
goto skip;
ap += 8;
resid -= 8;
memcpy(&rdatalen, ap, 2);
if ((rdatalen = ntohs(rdatalen)) <= 0)
return(0);
ap += 2;
resid -= 2;
if ((ecode = dn_expand(answer, answer + len, ap, name, sizeof(name)))
< 1) {
return(0);
}
break;
}
/* first word of the TXT RDATA will be the ASN */
ASN = (uint32_t) strtoul(name, NULL, 10);
return(ASN);
}
/* skip a DNS label */
static int
dns_skip(uint8_t **cp, uint16_t *resid)
{
uint8_t *bp;
uint8_t n;
bp = *cp;
while (*resid > 0) {
/* label length */
n = **cp;
(*cp) ++;
(*resid)--;
/* label terminator */
if (n == 0)
break;
/* for compression pointer, 2 MSBs are 11 (6 LSBs are offset) */
if ((n & 0xc0) == 192) {
if (*resid == 0)
return(-1);
(*cp)++;
(*resid)--;
break;
} else {
if (n > *resid)
return(-1);
(*cp) += n;
(*resid) -= n;
}
}
/* did we run out of space? */
if (! *resid && *cp != 0)
return(-1);
return(*cp - bp);
}