print-domain.c revision 21262
118334Speter/* 218334Speter * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 318334Speter * The Regents of the University of California. All rights reserved. 418334Speter * 518334Speter * Redistribution and use in source and binary forms, with or without 618334Speter * modification, are permitted provided that: (1) source code distributions 718334Speter * retain the above copyright notice and this paragraph in its entirety, (2) 818334Speter * distributions including binary code include the above copyright notice and 918334Speter * this paragraph in its entirety in the documentation or other materials 1018334Speter * provided with the distribution, and (3) all advertising materials mentioning 1118334Speter * features or use of this software display the following acknowledgement: 1218334Speter * ``This product includes software developed by the University of California, 1318334Speter * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1418334Speter * the University nor the names of its contributors may be used to endorse 1518334Speter * or promote products derived from this software without specific prior 1618334Speter * written permission. 1718334Speter * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1818334Speter * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1918334Speter * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2018334Speter */ 2118334Speter 2218334Speter#ifndef lint 2318334Speterstatic char rcsid[] = 2418334Speter "@(#) $Header: print-domain.c,v 1.35 96/07/23 14:17:22 leres Exp $ (LBL)"; 2518334Speter#endif 2618334Speter 2718334Speter#include <sys/param.h> 2818334Speter#include <sys/time.h> 2918334Speter#include <sys/socket.h> 3018334Speter 3118334Speter#if __STDC__ 3218334Speterstruct mbuf; 3318334Speterstruct rtentry; 3418334Speter#endif 3518334Speter#include <net/if.h> 3618334Speter 3718334Speter#include <netinet/in.h> 3818334Speter#include <net/ethernet.h> 3918334Speter#include <netinet/in_systm.h> 4018334Speter#include <netinet/ip.h> 4118334Speter#include <netinet/ip_var.h> 4218334Speter#include <netinet/udp.h> 4318334Speter#include <netinet/udp_var.h> 4418334Speter#include <netinet/tcp.h> 4518334Speter#include <netinet/tcpip.h> 4618334Speter 4718334Speter#undef NOERROR /* Solaris sucks */ 4818334Speter#undef T_UNSPEC /* SINIX does too */ 4918334Speter#include <arpa/nameser.h> 5018334Speter 5118334Speter#include <stdio.h> 5218334Speter 5318334Speter#include "interface.h" 5418334Speter#include "addrtoname.h" 5518334Speter#include "extract.h" /* must come after interface.h */ 5618334Speter 5718334Speter/* Compatibility */ 5818334Speter#ifndef T_TXT 5918334Speter#define T_TXT 16 /* text strings */ 6018334Speter#endif 6118334Speter#ifndef T_RP 6218334Speter#define T_RP 17 /* responsible person */ 6318334Speter#endif 6418334Speter#ifndef T_AFSDB 6518334Speter#define T_AFSDB 18 /* AFS cell database */ 6618334Speter#endif 6718334Speter#ifndef T_X25 6818334Speter#define T_X25 19 /* X_25 calling address */ 6918334Speter#endif 7018334Speter#ifndef T_ISDN 7118334Speter#define T_ISDN 20 /* ISDN calling address */ 7218334Speter#endif 7318334Speter#ifndef T_RT 7418334Speter#define T_RT 21 /* router */ 7518334Speter#endif 7618334Speter#ifndef T_NSAP 7718334Speter#define T_NSAP 22 /* NSAP address */ 7818334Speter#endif 7918334Speter#ifndef T_NSAP_PTR 8018334Speter#define T_NSAP_PTR 23 /* reverse NSAP lookup (deprecated) */ 8118334Speter#endif 8218334Speter#ifndef T_SIG 8318334Speter#define T_SIG 24 /* security signature */ 8418334Speter#endif 8518334Speter#ifndef T_KEY 8618334Speter#define T_KEY 25 /* security key */ 8718334Speter#endif 8818334Speter#ifndef T_PX 8918334Speter#define T_PX 26 /* X.400 mail mapping */ 9018334Speter#endif 9118334Speter#ifndef T_GPOS 9218334Speter#define T_GPOS 27 /* geographical position (withdrawn) */ 9318334Speter#endif 9418334Speter#ifndef T_AAAA 9518334Speter#define T_AAAA 28 /* IP6 Address */ 9618334Speter#endif 9718334Speter#ifndef T_LOC 9818334Speter#define T_LOC 29 /* Location Information */ 9918334Speter#endif 10018334Speter 10118334Speter#ifndef T_UNSPEC 10218334Speter#define T_UNSPEC 103 /* Unspecified format (binary data) */ 10318334Speter#endif 10418334Speter#ifndef T_UNSPECA 10518334Speter#define T_UNSPECA 104 /* "unspecified ascii". Ugly MIT hack */ 10618334Speter#endif 10718334Speter 10818334Speter#ifndef C_CHAOS 10918334Speter#define C_CHAOS 3 /* for chaos net (MIT) */ 11018334Speter#endif 11118334Speter#ifndef C_HS 11218334Speter#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */ 11318334Speter#endif 11418334Speter 11518334Speterstatic char *ns_ops[] = { 11618334Speter "", " inv_q", " stat", " op3", " notify", " op5", " op6", " op7", 11718334Speter " op8", " updataA", " updateD", " updateDA", 11818334Speter " updateM", " updateMA", " zoneInit", " zoneRef", 11918334Speter}; 12018334Speter 12118334Speterstatic char *ns_resp[] = { 12218334Speter "", " FormErr", " ServFail", " NXDomain", 12318334Speter " NotImp", " Refused", " Resp6", " Resp7", 12418334Speter " Resp8", " Resp9", " Resp10", " Resp11", 12518334Speter " Resp12", " Resp13", " Resp14", " NoChange", 12618334Speter}; 12718334Speter 12818334Speter/* skip over a domain name */ 12918334Speterstatic const u_char * 13018334Speterns_nskip(register const u_char *cp, register const u_char *bp) 13118334Speter{ 13218334Speter register u_char i; 13318334Speter 13418334Speter if (((i = *cp++) & INDIR_MASK) == INDIR_MASK) 13518334Speter return (cp + 1); 13618334Speter while (i && cp < snapend) { 13718334Speter cp += i; 13818334Speter i = *cp++; 13918334Speter } 14018334Speter return (cp); 14118334Speter} 14218334Speter 14318334Speter/* print a <domain-name> */ 14418334Speterstatic const u_char * 14518334Speterns_nprint(register const u_char *cp, register const u_char *bp) 14618334Speter{ 14718334Speter register u_int i; 14818334Speter register const u_char *rp; 14918334Speter register int compress; 15018334Speter 15118334Speter i = *cp++; 15218334Speter rp = cp + i; 15318334Speter if ((i & INDIR_MASK) == INDIR_MASK) { 15418334Speter rp = cp + 1; 15518334Speter compress = 1; 15618334Speter } else 15718334Speter compress = 0; 15818334Speter if (i != 0) 15918334Speter while (i && cp < snapend) { 16018334Speter if ((i & INDIR_MASK) == INDIR_MASK) { 16118334Speter cp = bp + (((i << 8) | *cp) & 0x3fff); 16218334Speter i = *cp++; 16318334Speter continue; 16418334Speter } 16518334Speter if (fn_printn(cp, i, snapend)) 16618334Speter break; 16718334Speter cp += i; 16818334Speter putchar('.'); 16918334Speter i = *cp++; 17018334Speter if (!compress) 17118334Speter rp += i + 1; 17218334Speter } 17318334Speter else 17418334Speter putchar('.'); 17518334Speter return (rp); 17618334Speter} 17718334Speter 17818334Speter/* print a <character-string> */ 17918334Speterstatic const u_char * 18018334Speterns_cprint(register const u_char *cp, register const u_char *bp) 18118334Speter{ 18218334Speter register u_int i; 18318334Speter 18418334Speter i = *cp++; 18518334Speter (void)fn_printn(cp, i, snapend); 18618334Speter return (cp + i); 18718334Speter} 18818334Speter 18918334Speterstatic struct tok type2str[] = { 19018334Speter { T_A, "A" }, 19118334Speter { T_NS, "NS" }, 19218334Speter { T_MD, "MD" }, 19318334Speter { T_MF, "MF" }, 19418334Speter { T_CNAME, "CNAME" }, 19518334Speter { T_SOA, "SOA" }, 19618334Speter { T_MB, "MB" }, 19718334Speter { T_MG, "MG" }, 19818334Speter { T_MR, "MR" }, 19918334Speter { T_NULL, "NULL" }, 20018334Speter { T_WKS, "WKS" }, 20118334Speter { T_PTR, "PTR" }, 20218334Speter { T_HINFO, "HINFO" }, 20318334Speter { T_MINFO, "MINFO" }, 20418334Speter { T_MX, "MX" }, 20518334Speter { T_TXT, "TXT" }, 20618334Speter { T_RP, "RP" }, 20718334Speter { T_AFSDB, "AFSDB" }, 20818334Speter { T_X25, "X25" }, 20918334Speter { T_ISDN, "ISDN" }, 21018334Speter { T_RT, "RT" }, 21118334Speter { T_NSAP, "NSAP" }, 21218334Speter { T_NSAP_PTR, "NSAP_PTR" }, 21318334Speter { T_SIG, "SIG" }, 21418334Speter { T_KEY, "KEY" }, 21518334Speter { T_PX, "PX" }, 21618334Speter { T_GPOS, "GPOS" }, 21718334Speter { T_AAAA, "AAAA" }, 21818334Speter { T_LOC , "LOC " }, 21918334Speter { T_UINFO, "UINFO" }, 22018334Speter { T_UID, "UID" }, 22118334Speter { T_GID, "GID" }, 22218334Speter { T_UNSPEC, "UNSPEC" }, 22318334Speter { T_UNSPECA, "UNSPECA" }, 22418334Speter { T_AXFR, "AXFR" }, 22518334Speter { T_MAILB, "MAILB" }, 22618334Speter { T_MAILA, "MAILA" }, 22718334Speter { T_ANY, "ANY" }, 22818334Speter { 0, NULL } 22918334Speter}; 23018334Speter 23118334Speterstatic struct tok class2str[] = { 23218334Speter { C_IN, "IN" }, /* Not used */ 23318334Speter { C_CHAOS, "CHAOS)" }, 23418334Speter { C_HS, "HS" }, 23518334Speter { C_ANY, "ANY" }, 23618334Speter { 0, NULL } 23718334Speter}; 23818334Speter 23918334Speter/* print a query */ 24018334Speterstatic void 24118334Speterns_qprint(register const u_char *cp, register const u_char *bp) 24218334Speter{ 24318334Speter register const u_char *np = cp; 24418334Speter register u_int i; 24518334Speter 24618334Speter cp = ns_nskip(cp, bp); 24718334Speter 24818334Speter if (cp + 4 > snapend) 24918334Speter return; 25018334Speter 25118334Speter /* print the qtype and qclass (if it's not IN) */ 25218334Speter i = *cp++ << 8; 25318334Speter i |= *cp++; 25418334Speter printf(" %s", tok2str(type2str, "Type%d", i)); 25518334Speter i = *cp++ << 8; 25618334Speter i |= *cp++; 25718334Speter if (i != C_IN) 25818334Speter printf(" %s", tok2str(class2str, "(Class %d)", i)); 25918334Speter 26018334Speter fputs("? ", stdout); 26118334Speter ns_nprint(np, bp); 26218334Speter} 26318334Speter 26418334Speter/* print a reply */ 26518334Speterstatic const u_char * 26618334Speterns_rprint(register const u_char *cp, register const u_char *bp) 26718334Speter{ 26818334Speter register u_int i; 26918334Speter register u_short typ, len; 27018334Speter register const u_char *rp; 27118334Speter 27218334Speter if (vflag) { 27318334Speter putchar(' '); 27418334Speter cp = ns_nprint(cp, bp); 27518334Speter } else 27618334Speter cp = ns_nskip(cp, bp); 27718334Speter 27818334Speter if (cp + 10 > snapend) 27918334Speter return (snapend); 28018334Speter 28118334Speter /* print the type/qtype and class (if it's not IN) */ 28218334Speter typ = *cp++ << 8; 28318334Speter typ |= *cp++; 28418334Speter i = *cp++ << 8; 28518334Speter i |= *cp++; 28618334Speter if (i != C_IN) 28718334Speter printf(" %s", tok2str(class2str, "(Class %d)", i)); 28818334Speter 28918334Speter /* ignore ttl */ 29018334Speter cp += 4; 29118334Speter 29218334Speter len = *cp++ << 8; 29318334Speter len |= *cp++; 29418334Speter 295 rp = cp + len; 296 297 printf(" %s", tok2str(type2str, "Type%d", typ)); 298 switch (typ) { 299 300 case T_A: 301 printf(" %s", ipaddr_string(cp)); 302 break; 303 304 case T_NS: 305 case T_CNAME: 306 case T_PTR: 307 putchar(' '); 308 (void)ns_nprint(cp, bp); 309 break; 310 311 case T_MX: 312 putchar(' '); 313 (void)ns_nprint(cp + 2, bp); 314 printf(" %d", EXTRACT_16BITS(cp)); 315 break; 316 317 case T_TXT: 318 putchar(' '); 319 (void)ns_cprint(cp, bp); 320 break; 321 322 case T_UNSPECA: /* One long string */ 323 printf(" %.*s", len, cp); 324 break; 325 } 326 return (rp); /* XXX This isn't always right*/ 327} 328 329void 330ns_print(register const u_char *bp, u_int length) 331{ 332 register const HEADER *np; 333 register int qdcount, ancount, nscount, arcount; 334 register const u_char *cp; 335 336 np = (const HEADER *)bp; 337 /* get the byte-order right */ 338 qdcount = ntohs(np->qdcount); 339 ancount = ntohs(np->ancount); 340 nscount = ntohs(np->nscount); 341 arcount = ntohs(np->arcount); 342 343 if (np->qr) { 344 /* this is a response */ 345 printf(" %d%s%s%s%s%s", 346 ntohs(np->id), 347 ns_ops[np->opcode], 348 ns_resp[np->rcode], 349 np->aa? "*" : "", 350 np->ra? "" : "-", 351 np->tc? "|" : ""); 352 if (qdcount != 1) 353 printf(" [%dq]", qdcount); 354 /* Print QUESTION section on -vv */ 355 if (vflag > 1) { 356 fputs(" q: ", stdout); 357 cp = ns_nprint((const u_char *)(np + 1), bp); 358 } else 359 cp = ns_nskip((const u_char *)(np + 1), bp); 360 printf(" %d/%d/%d", ancount, nscount, arcount); 361 if (ancount--) { 362 cp = ns_rprint(cp + 4, bp); 363 while (ancount-- && cp < snapend) { 364 putchar(','); 365 cp = ns_rprint(cp, bp); 366 } 367 } 368 } 369 else { 370 /* this is a request */ 371 printf(" %d%s%s", 372 ntohs(np->id), 373 ns_ops[np->opcode], 374 np->rd? "+" : ""); 375 376 /* any weirdness? */ 377 if (*(((u_short *)np)+1) & htons(0x6ff)) 378 printf(" [b2&3=0x%x]", ntohs(*(((u_short *)np)+1))); 379 380 if (np->opcode == IQUERY) { 381 if (qdcount) 382 printf(" [%dq]", qdcount); 383 if (ancount != 1) 384 printf(" [%da]", ancount); 385 } 386 else { 387 if (ancount) 388 printf(" [%da]", ancount); 389 if (qdcount != 1) 390 printf(" [%dq]", qdcount); 391 } 392 if (nscount) 393 printf(" [%dn]", nscount); 394 if (arcount) 395 printf(" [%dau]", arcount); 396 397 ns_qprint((const u_char *)(np + 1), (const u_char *)np); 398 } 399 printf(" (%d)", length); 400} 401