File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mtr / asn.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Nov 1 09:33:48 2016 UTC (7 years, 7 months ago) by misho
Branches: mtr, elwix, MAIN
CVS tags: v0_86, HEAD
mtr 0.86

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>