Annotation of embedaddon/mtr/asn.c, revision 1.1
1.1 ! misho 1: /*
! 2: mtr -- a network diagnostic tool
! 3: Copyright (C) 1997,1998 Matt Kimball
! 4:
! 5: This program is free software; you can redistribute it and/or modify
! 6: it under the terms of the GNU General Public License version 2 as
! 7: published by the Free Software Foundation.
! 8:
! 9: This program is distributed in the hope that it will be useful,
! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 12: GNU General Public License for more details.
! 13:
! 14: You should have received a copy of the GNU General Public License
! 15: along with this program; if not, write to the Free Software
! 16: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! 17: */
! 18:
! 19: #include <unistd.h>
! 20: #include <stdio.h>
! 21: #include <stdlib.h>
! 22: #include <sys/types.h>
! 23:
! 24: #ifndef __APPLE__
! 25: #define BIND_8_COMPAT
! 26: #endif
! 27: #include <arpa/nameser.h>
! 28: #ifdef HAVE_ARPA_NAMESER_COMPAT_H
! 29: #include <arpa/nameser_compat.h>
! 30: #endif
! 31: #include <netdb.h>
! 32: #include <netinet/in.h>
! 33: #include <resolv.h>
! 34: #include <string.h>
! 35: #include <sys/socket.h>
! 36: #include <search.h>
! 37:
! 38: #include "config.h"
! 39: #include "mtr.h"
! 40: #include "asn.h"
! 41:
! 42: /*
! 43: #ifndef IIDEBUG
! 44: #define IIDEBUG
! 45: #include <syslog.h>
! 46: #endif
! 47: */
! 48:
! 49: #define IIHASH_HI 128
! 50: #define ITEMSMAX 15
! 51: #define ITEMSEP '|'
! 52: #define NAMELEN 127
! 53: #define UNKN "???"
! 54:
! 55: int ipinfo_no = -1;
! 56: int ipinfo_max = -1;
! 57: int iihash = 0;
! 58: char fmtinfo[32];
! 59: extern int af; /* address family of remote target */
! 60:
! 61: // items width: ASN, Route, Country, Registry, Allocated
! 62: int iiwidth[] = { 6, 19, 4, 8, 11}; // item len + space
! 63: int iiwidth_len = sizeof(iiwidth)/sizeof((iiwidth)[0]);
! 64:
! 65: typedef char* items_t[ITEMSMAX + 1];
! 66: items_t items_a; // without hash: items
! 67: char txtrec[NAMELEN + 1]; // without hash: txtrec
! 68: items_t* items = &items_a;
! 69:
! 70:
! 71: char *ipinfo_lookup(const char *domain) {
! 72: unsigned char answer[PACKETSZ], *pt;
! 73: char host[128];
! 74: char *txt;
! 75: int len, exp, size, txtlen, type;
! 76:
! 77:
! 78: if(res_init() < 0) {
! 79: fprintf(stderr,"@res_init failed\n");
! 80: return NULL;
! 81: }
! 82:
! 83: memset(answer, 0, PACKETSZ);
! 84: if((len = res_query(domain, C_IN, T_TXT, answer, PACKETSZ)) < 0) {
! 85: #ifdef IIDEBUG
! 86: if (iihash)
! 87: syslog(LOG_INFO, "Malloc-txt: %s", UNKN);
! 88: #endif
! 89: return (iihash)?strdup(UNKN):UNKN;
! 90: }
! 91:
! 92: pt = answer + sizeof(HEADER);
! 93:
! 94: if((exp = dn_expand(answer, answer + len, pt, host, sizeof(host))) < 0) {
! 95: printf("@dn_expand failed\n"); return NULL;
! 96: }
! 97:
! 98: pt += exp;
! 99:
! 100: GETSHORT(type, pt);
! 101: if(type != T_TXT) {
! 102: printf("@Broken DNS reply.\n"); return NULL;
! 103: }
! 104:
! 105: pt += INT16SZ; /* class */
! 106:
! 107: if((exp = dn_expand(answer, answer + len, pt, host, sizeof(host))) < 0) {
! 108: printf("@second dn_expand failed\n"); return NULL;
! 109: }
! 110:
! 111: pt += exp;
! 112: GETSHORT(type, pt);
! 113: if(type != T_TXT) {
! 114: printf("@Not a TXT record\n"); return NULL;
! 115: }
! 116:
! 117: pt += INT16SZ; /* class */
! 118: pt += INT32SZ; /* ttl */
! 119: GETSHORT(size, pt);
! 120: txtlen = *pt;
! 121:
! 122:
! 123: if(txtlen >= size || !txtlen) {
! 124: printf("@Broken TXT record (txtlen = %d, size = %d)\n", txtlen, size); return NULL;
! 125: }
! 126:
! 127: if (txtlen > NAMELEN)
! 128: txtlen = NAMELEN;
! 129:
! 130: if (iihash) {
! 131: if (!(txt = malloc(txtlen + 1)))
! 132: return NULL;
! 133: } else
! 134: txt = (char*)txtrec;
! 135:
! 136: pt++;
! 137: strncpy(txt, (char*) pt, txtlen);
! 138: txt[txtlen] = 0;
! 139:
! 140: #ifdef IIDEBUG
! 141: if (iihash)
! 142: syslog(LOG_INFO, "Malloc-txt(%p): %s", txt, txt);
! 143: #endif
! 144:
! 145: return txt;
! 146: }
! 147:
! 148: char* trimsep(char *s) {
! 149: int l;
! 150: char *p = s;
! 151: while (*p == ' ' || *p == ITEMSEP)
! 152: *p++ = '\0';
! 153: for (l = strlen(p)-1; p[l] == ' ' || p[l] == ITEMSEP; l--)
! 154: p[l] = '\0';
! 155: return p;
! 156: }
! 157:
! 158: // originX.asn.cymru.com txtrec: ASN | Route | Country | Registry | Allocated
! 159: char* split_txtrec(char *txtrec) {
! 160: if (!txtrec)
! 161: return NULL;
! 162: if (iihash) {
! 163: #ifdef IIDEBUG
! 164: syslog(LOG_INFO, "Malloc-tbl: %s", txtrec);
! 165: #endif
! 166: if (!(items = malloc(sizeof(*items)))) {
! 167: #ifdef IIDEBUG
! 168: syslog(LOG_INFO, "Free-txt(%p)", txtrec);
! 169: #endif
! 170: free(txtrec);
! 171: return NULL;
! 172: }
! 173: }
! 174:
! 175: char* prev = (*items)[0] = trimsep(txtrec);
! 176: char* next;
! 177: int i = 0, j;
! 178:
! 179: while ((next = strchr(prev, ITEMSEP)) && (i < ITEMSMAX)) {
! 180: *next++ = '\0';
! 181: (*items)[i++] = trimsep(prev);
! 182: (*items)[i] = prev = trimsep(next);
! 183: }
! 184: if (i < ITEMSMAX)
! 185: i++;
! 186: for (j = i; j <= ITEMSMAX; j++)
! 187: (*items)[j] = NULL;
! 188:
! 189: if (i > ipinfo_max)
! 190: ipinfo_max = i;
! 191: if (ipinfo_no >= i) {
! 192: if (ipinfo_no >= ipinfo_max)
! 193: ipinfo_no = 0;
! 194: return (*items)[0];
! 195: } else
! 196: return (*items)[ipinfo_no];
! 197: }
! 198:
! 199: #ifdef ENABLE_IPV6
! 200: // from dns.c:addr2ip6arpa()
! 201: void reverse_host6(struct in6_addr *addr, char *buff) {
! 202: int i;
! 203: char *b = buff;
! 204: for (i=(sizeof(*addr)/2-1); i>=0; i--, b+=4) // 64b portion
! 205: sprintf(b, "%x.%x.", addr->s6_addr[i] & 0xf, addr->s6_addr[i] >> 4);
! 206: buff[strlen(buff) - 1] = '\0';
! 207: }
! 208: #endif
! 209:
! 210: char *get_ipinfo(ip_t *addr) {
! 211: if (!addr)
! 212: return NULL;
! 213:
! 214: char key[NAMELEN];
! 215: char lookup_key[NAMELEN];
! 216:
! 217: if (af == AF_INET6) {
! 218: #ifdef ENABLE_IPV6
! 219: reverse_host6(addr, key);
! 220: if (snprintf(lookup_key, NAMELEN, "%s.origin6.asn.cymru.com", key) >= NAMELEN)
! 221: return NULL;
! 222: #else
! 223: return NULL;
! 224: #endif
! 225: } else {
! 226: unsigned char buff[4];
! 227: memcpy(buff, addr, 4);
! 228: if (snprintf(key, NAMELEN, "%d.%d.%d.%d", buff[3], buff[2], buff[1], buff[0]) >= NAMELEN)
! 229: return NULL;
! 230: if (snprintf(lookup_key, NAMELEN, "%s.origin.asn.cymru.com", key) >= NAMELEN)
! 231: return NULL;
! 232: }
! 233:
! 234: char *val = NULL;
! 235: ENTRY item;
! 236:
! 237: if (iihash) {
! 238: #ifdef IIDEBUG
! 239: syslog(LOG_INFO, ">> Search: %s", key);
! 240: #endif
! 241: item.key = key;;
! 242: ENTRY *found_item;
! 243: if ((found_item = hsearch(item, FIND))) {
! 244: if (!(val = (*((items_t*)found_item->data))[ipinfo_no]))
! 245: val = (*((items_t*)found_item->data))[0];
! 246: #ifdef IIDEBUG
! 247: syslog(LOG_INFO, "Found (hashed): %s", val);
! 248: #endif
! 249: }
! 250: }
! 251:
! 252: if (!val) {
! 253: #ifdef IIDEBUG
! 254: syslog(LOG_INFO, "Lookup: %s", key);
! 255: #endif
! 256: if ((val = split_txtrec(ipinfo_lookup(lookup_key)))) {
! 257: #ifdef IIDEBUG
! 258: syslog(LOG_INFO, "Looked up: %s", key);
! 259: #endif
! 260: if (iihash)
! 261: if ((item.key = strdup(key))) {
! 262: item.data = items;
! 263: hsearch(item, ENTER);
! 264: #ifdef IIDEBUG
! 265: syslog(LOG_INFO, "Insert into hash: %s", key);
! 266: #endif
! 267: }
! 268: }
! 269: }
! 270:
! 271: return val;
! 272: }
! 273:
! 274: int get_iiwidth(void) {
! 275: return (ipinfo_no < iiwidth_len) ? iiwidth[ipinfo_no] : iiwidth[ipinfo_no % iiwidth_len];
! 276: }
! 277:
! 278: char *fmt_ipinfo(ip_t *addr) {
! 279: char *ipinfo = get_ipinfo(addr);
! 280: char fmt[8];
! 281: snprintf(fmt, sizeof(fmt), "%s%%-%ds", ipinfo_no?"":"AS", get_iiwidth());
! 282: snprintf(fmtinfo, sizeof(fmtinfo), fmt, ipinfo?ipinfo:UNKN);
! 283: return fmtinfo;
! 284: }
! 285:
! 286: int is_printii(void) {
! 287: return ((ipinfo_no >= 0) && (ipinfo_no != ipinfo_max));
! 288: }
! 289:
! 290: void asn_open(void) {
! 291: if (ipinfo_no >= 0) {
! 292: #ifdef IIDEBUG
! 293: syslog(LOG_INFO, "hcreate(%d)", IIHASH_HI);
! 294: #endif
! 295: if (!(iihash = hcreate(IIHASH_HI)))
! 296: perror("ipinfo hash");
! 297: }
! 298: }
! 299:
! 300: void asn_close(void) {
! 301: if (iihash) {
! 302: #ifdef IIDEBUG
! 303: syslog(LOG_INFO, "hdestroy()");
! 304: #endif
! 305: hdestroy();
! 306: iihash = 0;
! 307: }
! 308: }
! 309:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>