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 >
C/C++ Source or Header  |  2007-01-25  |  5KB  |  200 lines

  1. /*
  2.  * $Id: asns.c,v 1.3 2007/01/25 09:36:45 heas Exp $
  3.  *
  4.  * Copyright (c) 2007, heas@shrubbery.net
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that: (1) source code distributions
  8.  * retain the above copyright notice and this paragraph in its entirety, (2)
  9.  * distributions including binary code include the above copyright notice and
  10.  * this paragraph in its entirety in the documentation or other materials
  11.  * provided with the distribution, and (3) all advertising materials mentioning
  12.  * features or use of this software display the following acknowledgement:
  13.  * ``This product includes software developed by the University of California,
  14.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  15.  * the University nor the names of its contributors may be used to endorse
  16.  * or promote products derived from this software without specific prior
  17.  * written permission.
  18.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  19.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  20.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  21.  */
  22.  
  23. #include <unistd.h>
  24. #include <stdlib.h>
  25. #include <sys/types.h>
  26.  
  27. #include <arpa/nameser.h>
  28. #include <netdb.h>
  29. #include <netinet/in.h>
  30. #include <resolv.h>
  31. #include <string.h>
  32. #include <sys/socket.h>
  33.  
  34. #include "traceroute.h"
  35.  
  36. #define    DOFF_Q        4
  37. #define    DOFF_DATA    12        /* header length / data offset, TCP
  38.                      * transport adds 2 bytes to each for
  39.                      * the msg length                    */
  40. #define    DTYPE_TXT    16
  41.  
  42. static int dns_skip(uint8_t **, uint16_t *);
  43.  
  44. extern int h_errno;
  45.  
  46. static u_char    answer[1024],
  47.         *ap;
  48. #define NAMELEN    257
  49. static char    name[NAMELEN];
  50. static char    dname[NAMELEN];
  51. extern int    asns;
  52.  
  53. uint32_t
  54. asn_lookup(struct sockaddr_in *sin)
  55. {
  56.     int            ecode, len;
  57.     u_char        ipv4[4];
  58.     uint16_t        a, resid, rdatalen, q;
  59.     uint32_t        ASN = 0;
  60.  
  61.     if (!(_res.options & RES_INIT))
  62.     if (res_init()) {
  63.         fprintf(stderr, "resolver initialization failed\n");
  64.         asns = 0;
  65.     }
  66.  
  67.     if (sin->sin_family != AF_INET)
  68.     return(0);
  69.     /* XXX add support for INET6 when routeviews offers it */
  70.  
  71.     memcpy(ipv4, &sin->sin_addr, 4);
  72.     if (snprintf(dname, NAMELEN, "%d.%d.%d.%d.asn.routeviews.org", ipv4[3],
  73.          ipv4[2], ipv4[1], ipv4[0]) >= NAMELEN) {
  74.     return(0);
  75.     }
  76.     if ((len = res_query(dname, C_IN, T_TXT, answer, sizeof(answer))) == -1) {
  77.     switch (h_errno) {
  78.     case HOST_NOT_FOUND:
  79.         fprintf(stderr, "no route\n");
  80.         break;
  81.     case TRY_AGAIN:
  82.         break;
  83.     case NO_RECOVERY:
  84.         fprintf(stderr, "no recovery\n");
  85.         break;
  86.     case NO_DATA:
  87.         fprintf(stderr, "no data\n");
  88.         break;
  89.     default:
  90.         fprintf(stderr, "unknown error\n");
  91.         break;
  92.     }
  93.     return(0);
  94.     }
  95.  
  96.     ap = answer + DOFF_Q;
  97.     memcpy(&q, ap, 2);
  98.     q = ntohs(q);
  99.     ap += 2;
  100.     memcpy(&a, ap, 2);
  101.     a = ntohs(a);
  102.     if (!a)
  103.     return(0);
  104.     ap = answer + DOFF_DATA;
  105.     resid = len - DOFF_DATA;
  106.  
  107.     /* skip questions */
  108.     while (q--) {
  109.     if (dns_skip((uint8_t **)&ap, &resid) < 0)
  110.         return(0);
  111.     /* skip question RR type and class */
  112.     ap += 4;
  113.     resid -= 4;
  114.     }
  115.  
  116.     while (a--) {
  117.     if ((ecode = dn_expand(answer, answer + len, ap, name, sizeof(name)))
  118.         < 1) {
  119.         return(0);
  120.     }
  121.     if (dns_skip((uint8_t **)&ap, &resid) < 0)
  122.         return(0);
  123.  
  124.     if (strcasecmp(name, dname) != 0) {
  125. skip:
  126.         /* skip RR type, class and TTL */
  127.         ap += 8;
  128.         resid -= 8;
  129.         memcpy(&rdatalen, ap, 2);
  130.         rdatalen = ntohs(rdatalen);
  131.         ap += 2 + rdatalen;
  132.         resid -= 2 + rdatalen;
  133.         continue;
  134.     }
  135.  
  136.     /* skip RR type, class and TTL */
  137.     memcpy(&rdatalen, ap, 2);
  138.     if (ntohs(rdatalen) != DTYPE_TXT)
  139.         goto skip;
  140.     ap += 8;
  141.     resid -= 8;
  142.     memcpy(&rdatalen, ap, 2);
  143.     if ((rdatalen = ntohs(rdatalen)) <= 0)
  144.         return(0);
  145.     ap += 2;
  146.     resid -= 2;
  147.  
  148.     if ((ecode = dn_expand(answer, answer + len, ap, name, sizeof(name)))
  149.         < 1) {
  150.         return(0);
  151.     }
  152.     break;
  153.     }
  154.  
  155.     /* first word of the TXT RDATA will be the ASN */
  156.     ASN = (uint32_t) strtoul(name, NULL, 10);
  157.  
  158.     return(ASN);
  159. }
  160.  
  161. /* skip a DNS label */
  162. static int
  163. dns_skip(uint8_t **cp, uint16_t *resid)
  164. {
  165.     uint8_t     *bp;
  166.     uint8_t     n;
  167.  
  168.     bp = *cp;
  169.     while (*resid > 0) {
  170.     /* label length */
  171.     n = **cp;
  172.     (*cp) ++;
  173.     (*resid)--;
  174.  
  175.     /* label terminator */
  176.     if (n == 0)
  177.         break;
  178.  
  179.     /* for compression pointer, 2 MSBs are 11 (6 LSBs are offset) */
  180.     if ((n & 0xc0) == 192) {
  181.         if (*resid == 0)
  182.         return(-1);
  183.         (*cp)++;
  184.         (*resid)--;
  185.         break;
  186.     } else {
  187.         if (n > *resid)
  188.         return(-1);
  189.         (*cp) += n;
  190.         (*resid) -= n;
  191.     }
  192.     }
  193.  
  194.     /* did we run out of space? */
  195.     if (! *resid && *cp != 0)
  196.     return(-1);
  197.  
  198.     return(*cp - bp);
  199. }
  200.