Annotation of embedaddon/mtr/asn.c, revision 1.1.1.2
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:
1.1.1.2 ! misho 19: #include "config.h"
! 20:
1.1 misho 21: #include <unistd.h>
22: #include <stdio.h>
23: #include <stdlib.h>
24: #include <sys/types.h>
25:
1.1.1.2 ! misho 26: #ifdef __APPLE__
1.1 misho 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>