/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* References used throughout this code:
*
* [RFC1001] : PROTOCOL STANDARD FOR A NetBIOS SERVICE
* CONCEPTS AND METHODS
* NetBIOS Working Group, March 1987
*
* [RFC1002] : PROTOCOL STANDARD FOR A NetBIOS SERVICE
* DETAILED SPECIFICATIONS
* NetBIOS Working Group, March 1987
*/
#include <fcntl.h>
#include "snoop.h"
#include <stdio.h>
#include <ctype.h>
#include "snoop.h"
extern char *dlc_header;
char *show_type();
/* See snoop_smb.c */
/*
* NBT Session Packet Header
* [RFC 1002, Sec. 4.3.1]
*/
struct nbt_ss {
};
/*
* NBT Session Request Packet trailer
* [RFC 1002, Sec. 4.3.2]
*/
struct callnames {
};
char *xtra);
/*
* Helpers to read network-order values,
* with NO alignment assumed.
*/
static ushort_t
return (p[1] + (p[0]<<8));
}
static uint_t
{
return (p[3] + (p[2]<<8) + (p[1]<<16) + (p[0]<<24));
}
/*
* NM_FLAGS fields in the NetBIOS Name Service Packet header.
* [RFC 1002, Sec. 4.2.1.1]
*/
static void
{
}
/*
* Possible errors in NetBIOS name service packets.
* [RFC 1002, Sec. 4.2.6, 4.2.11, 4.2.14]
*/
static void
{
switch (error) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
default:
break;
}
}
/*
* OPCODE fields in the NetBIOS Name Service Packet header.
* [RFC 1002, Sec. 4.2.1.1]
*/
static void
{
char *optype;
switch (opcode) {
case 0:
optype = "Query";
break;
case 5:
optype = "Registration";
break;
case 6:
optype = "Release";
break;
case 7:
optype = "WACK";
break;
case 8:
optype = "Refresh";
break;
default:
optype = "Unknown";
break;
}
else
}
/*
* Interpret Datagram Packets
* [RFC 1002, Sec. 4.4]
*/
void
{
int packetlen;
data++;
return;
data += 14;
"NBT Datagram Service Type=%d Source=%s",
}
show_space();
data[0]);
data++;
data += 2;
data += 4;
data += 2;
data += 2;
data += 3;
data += 34;
packetlen - 68);
show_trailer();
}
}
/*
* Interpret NetBIOS Name Service packets.
* [RFC 1002, Sec. 4.2]
*/
void
{
int transid;
int rdatalen;
int rrflags;
int nameptr;
int nodecode;
char *nodetype;
data++;
}
show_space();
"Additional Record Count = %d", arcount);
/*
* Question Section Packet Description from
* [RFC 1002, Sec. 4.2.1.2]
*/
if (qcount) {
data++;
data += 33;
data += 2;
data += 2;
}
/*
* Resrouce Record Packet Description from
* [RFC 1002, Sec. 4.2.1.3]
*/
/* Second level encoding from RFC883 (p.31, 32) */
if (data[0] & 0xc0) {
"Resource Record Name = %s", name);
data += 2;
} else {
data++;
"Resource Record Name = %s", name);
data += 33;
}
"Resource Record Type = 0x%.4x",
data += 2;
"Resource Record Class = 0x%.4x",
data += 2;
"Time to Live (Milliseconds) = %d",
data += 4;
rdatalen);
data += 2;
/* 15.4.2.1.3 */
if (rdatalen == 6) {
data += 2;
"Resource Record Flags = 0x%.4x",
rrflags);
"Group NetBIOS Name":
"Unique NetBIOS Name", nodetype);
"Owner IP Address = %d.%d.%d.%d",
}
}
show_trailer();
}
}
/*
* Interpret NetBIOS session packets.
* [RFC 1002, Sec. 4.3]
*/
void
{
char *type;
return;
/*
* Packets that are fragments of a large NetBIOS session
* message will have no NetBIOS header. (Only the first
* TCP segment will have a NetBIOS header.) It turns out
* that very often, such fragments start with SMB data, so
* we should try to recognize and decode them.
*/
if (data[0] == 0xff &&
return;
}
/* LINTED PTRALIGN */
extrainfo[0] = '\0';
case 0x00:
type = "SESSION MESSAGE";
break;
case 0x81:
type = "SESSION REQUEST";
break;
case 0x82:
type = "POSITIVE SESSION RESPONSE";
break;
case 0x83:
type = "NEGATIVE SESSION RESPONSE";
break;
case 0x84:
type = "RETARGET SESSION RESPONSE";
break;
case 0x85:
type = "SESSION KEEP ALIVE";
break;
default:
type = "Unknown";
break;
}
(void) sprintf(get_sum_line(),
}
show_space();
case 0x00:
"Type = SESSION MESSAGE");
break;
case 0x81:
"Type = SESSION REQUEST");
break;
case 0x82:
"Type = POSITIVE SESSION RESPONSE");
break;
case 0x83:
"Type = NEGATIVE SESSION RESPONSE");
break;
case 0x84:
"Type = RETARGET SESSION RESPONSE");
break;
case 0x85:
"Type = SESSION KEEP ALIVE");
break;
default:
"Type = Unknown");
break;
}
show_trailer();
}
/*
* SMB packets have { 0xff, 'S', 'M', 'B' }
* in the first four bytes. If we find that,
* let snoop_smb.c have a look at it.
*/
length > 0 &&
trailer[0] == 0xff &&
}
/*
* NetBIOS name encoding (First Level Encoding)
* [RFC 1001, Sec. 4.1]
*/
static void
{
int c, i, j;
i = j = 0;
for (;;) {
c = nbname[i++] - 'A';
c = (c << 4) +
nbname[i++] - 'A';
/* 16th char is the "type" */
if (i >= 32)
break;
if (iscntrl(c))
c = '.';
if (c != ' ')
aname[j++] = c;
}
}
/*
* Interpret the names in a Session Request packet.
* [RFC 1002, Sec. 4.3.2]
*/
static void
{
return;
}
}
}