snoop_dns.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "snoop.h"
/* The string used to indent detail lines */
#define DNS_INDENT " "
/*
* From RFC1035, the maximum size of a character-string is limited by the
* one octet length field. We add one character to that to make sure the
* result is terminated.
*/
/* private functions */
static char *binary_string(char data);
void
{
typedef HEADER dns_header;
char *line;
if (proto == IPPROTO_TCP) {
/* not supported now */
return;
}
/* We need at least the header in order to parse a packet. */
if (sizeof (dns_header) > len) {
return;
}
/*
* Copy the header into a local structure for aligned access to
* each field.
*/
line = get_sum_line();
/* answer */
/* reply is OK */
while (qdcount--) {
return;
}
}
/* the answers are following the questions */
if (ancount > 0) {
(void) print_answer(line,
}
} else {
}
} else {
/* question */
return;
}
FALSE);
}
}
show_space();
/* answer */
"Response ID = %d", id);
"%s%s%s",
"Response Code: %d (%s)",
"Reply to %d question(s)", qdcount);
count = 0;
while (qdcount--) {
return;
}
count++;
show_space();
}
"%d answer(s)", ancount);
count = 0;
while (ancount--) {
return;
}
count++;
show_space();
}
"%d name server resource(s)", nscount);
count = 0;
while (nscount--) {
return;
}
count++;
show_space();
}
"%d additional record(s)", arcount);
count = 0;
count++;
show_space();
}
} else {
/* question */
"Query ID = %d", id);
"%s%s",
"%d question(s)", qdcount);
count = 0;
count++;
show_space();
}
}
}
}
static char *
{
static char buffer[64];
switch (opcode) {
case ns_o_query: return ("Query");
case ns_o_iquery: return ("Inverse Query");
case ns_o_status: return ("Status");
default:
opcode);
return (buffer);
}
}
static char *
{
static char buffer[64];
switch (rcode) {
case ns_r_noerror: return ("OK");
case ns_r_formerr: return ("Format Error");
case ns_r_servfail: return ("Server Fail");
case ns_r_nxdomain: return ("Name Error");
case ns_r_notimpl: return ("Unimplemented");
case ns_r_refused: return ("Refused");
default:
return (buffer);
}
}
static char *
{
static char buffer[64];
switch (type) {
case ns_t_null: return ("NULL");
case ns_t_minfo:
case ns_t_mailb:
default:
return (buffer);
}
}
static char *
{
static char buffer[64];
switch (cls) {
default:
return (buffer);
}
}
static size_t
{
char dummy_buffer[NS_MAXDNAME];
dummy_buffer + sizeof (dummy_buffer));
/* Skip the 32 bits of class and type that follow the domain name */
}
static size_t
{
if (detail) {
DNS_INDENT "Domain Name: ");
}
/*
* Make sure we don't run off the end of the packet by reading the
* type and class.
*
* The pointer subtraction on the left side of the following
* expression has a signed result of type ptrdiff_t, and the right
* side has an unsigned result of type size_t. We therefore need
* to cast the right side of the expression to be of the same
* signed type to keep the result of the pointer arithmetic to be
* automatically cast to an unsigned value. We do a similar cast
* in other similar expressions throughout this file.
*/
if (detail) {
DNS_INDENT "Class: %u (%s)",
} else {
}
}
static size_t
{
int linepos;
if (detail) {
DNS_INDENT "Domain Name: ");
}
/*
* Make sure we don't run off the end of the packet by reading the
* type, class, ttl, and length.
*/
}
if (detail) {
} else {
}
if (detail) {
}
if (detail) {
}
switch (type) {
case ns_t_a:
break;
case ns_t_aaaa:
break;
case ns_t_hinfo:
break;
break;
case ns_t_ns:
case ns_t_cname:
case ns_t_mb:
case ns_t_mg:
case ns_t_mr:
case ns_t_ptr:
break;
case ns_t_mx:
break;
if (detail) {
data_end);
} else {
data_end);
}
break;
case ns_t_soa:
if (!detail)
break;
DNS_INDENT "MNAME (Server name): ");
data_end);
break;
DNS_INDENT "RNAME (Resposible mailbox): ");
break;
DNS_INDENT "Refresh: %u Retry: %u "
"Expire: %u Minimum: %u",
break;
case ns_t_wks:
if (!detail)
break;
break;
switch (protocol) {
case IPPROTO_UDP:
break;
case IPPROTO_TCP:
break;
}
DNS_INDENT "Service bitmap:");
DNS_INDENT "0 8 16 24");
linepos = 4;
if (linepos == 4) {
linepos = 0;
}
linepos++;
data_next++;
}
break;
case ns_t_minfo:
if (!detail)
break;
DNS_INDENT "RMAILBX (Resposible mailbox): ");
data_end);
DNS_INDENT "EMAILBX (mailbox to receive err message): ");
break;
}
}
static char *
binary_string(char data)
{
char *ptr;
int i;
for (i = 0; i < 8; i++) {
}
*ptr = (char)0;
return (bstring);
}
static void
{
void *addr;
switch (af) {
case AF_INET:
return;
break;
case AF_INET6:
if (len != sizeof (in6_addr_t))
return;
break;
}
}
/*
* charbuf is assumed to be of size MAX_CHAR_STRING_SIZE.
*/
static const uchar_t *
{
int i = 0;
/*
* From RFC1035, a character-string is a single length octet followed
* by that number of characters.
*/
if (datalen > 1) {
data++;
}
}
name[i] = '\0';
return (data);
}
static size_t
{
char charbuf[MAX_CHAR_STRING_SIZE];
}
/*
* header: the entire message header, this is where we start to
* count the offset of the compression scheme
* data: the start of the domain name
* namebuf: user supplied buffer
* return: the next byte after what we have parsed
*/
static const uchar_t *
{
/*
* From RFC1035, a domain name is a sequence of labels, where each
* label consists of a length octet followed by that number of
* octets. The domain name terminates with the zero length octet
* for the null label of the root.
*/
/* The length octet is off the end of the packet. */
break;
}
if (len == 0) {
/*
* Domain names end with a length byte of zero,
* which represents the null label of the root.
*/
break;
}
/*
* test if we are using the compression scheme
*/
/*
* From RFC1035, message compression allows a
* domain name or a list of labels at the end of a
* domain name to be replaced with a pointer to a
* prior occurance of the same name. In this
* scheme, the pointer is a two octet sequence
* where the most significant two bits are set, and
* the remaining 14 bits are the offset from the
* start of the message of the next label.
*/
data--;
/*
* The offset octets aren't entirely
* contained within this pakcet.
*/
break;
}
/*
* We must verify that the offset is valid by
* checking that it is less than the current data
* pointer and that it isn't off the end of the
* packet.
*/
break;
return (data);
} else {
/*
* The label isn't entirely contained
* within the packet. Don't read it. The
* caller checks that the data pointer is
* not beyond the end after we've
* incremented it.
*/
break;
}
name++;
data++;
len--;
}
*name = '.';
name++;
}
}
*name = '\0';
return (data);
}
static size_t
{
char name[NS_MAXDNAME];
}