Added preliminary support for NetBIOS Name Services over IPX and UDP. Note

that these are two very different implementations of NetBIOS name services and
at the protocol level are not similar. I have put the UDP protocol in
packet-nbns.c, since it will be a very big module. I have all of rfc 1002 to
read and implement. I am planning on putting many different NetBIOS over IPX
functions in packet-nbipx.c, however, since there is no RFC or published
standard. I have to hack the protocol, and as such, I do not expect it to be
as full-featured as the IP-world equivalents.

svn path=/trunk/; revision=50
This commit is contained in:
Gilbert Ramirez 1998-10-14 04:09:15 +00:00
parent 23ab0b90bd
commit 4ef47e6cfb
6 changed files with 319 additions and 12 deletions

View File

@ -24,6 +24,8 @@ ethereal_SOURCES = \
packet-ip.c \
packet-ipv6.c \
packet-ipx.c \
packet-nbipx.c \
packet-nbns.c \
packet-ncp.c \
packet-null.c \
packet-osi.c \

View File

@ -2,7 +2,7 @@
* Routines for NetWare's IPX
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
* $Id: packet-ipx.c,v 1.8 1998/10/02 22:14:29 gram Exp $
* $Id: packet-ipx.c,v 1.9 1998/10/14 04:09:12 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@unicom.net>
@ -88,7 +88,7 @@ static struct port_info ports[] = {
{ 0x0451, dissect_ncp, "NCP" },
{ 0x0452, dissect_sap, "SAP" },
{ 0x0453, dissect_ipxrip, "RIP" },
{ 0x0455, NULL, "NetBIOS" },
{ 0x0455, dissect_nbipx, "NetBIOS" },
{ 0x0456, NULL, "Diagnostic" },
{ 0x0457, NULL, "Serialization" },
{ 0x055d, NULL, "Attachmate Gateway" },
@ -134,7 +134,7 @@ ipx_packet_type(u_char val)
return "NCP";
}
else if (val == 20) {
return "NetBIOS";
return "NetBIOS Name Packet";
}
else if (val >= 16 && val <= 31) {
return "Experimental Protocol";
@ -145,7 +145,7 @@ ipx_packet_type(u_char val)
}
gchar*
network_to_string(const guint8 *ad)
ipxnet_to_string(const guint8 *ad)
{
static gchar str[3][12];
static gchar *cur;
@ -173,8 +173,8 @@ dissect_ipx(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
void (*dissect) (const u_char *, int, frame_data *, GtkTree *);
/* Calculate here for use in win_info[] and in tree */
dnet = network_to_string((guint8*)&pd[offset+6]);
snet = network_to_string((guint8*)&pd[offset+18]);
dnet = ipxnet_to_string((guint8*)&pd[offset+6]);
snet = ipxnet_to_string((guint8*)&pd[offset+18]);
dsocket = pntohs(&pd[offset+16]);
if (fd->win_info[COL_NUM]) {
@ -224,7 +224,7 @@ dissect_ipx(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
break;
case 20: /* NetBIOS */
dissect_data(pd, offset, fd, tree);
dissect_nbipx(pd, offset, fd, tree);
break;
case 0: /* IPX, fall through to default */
@ -369,14 +369,14 @@ dissect_ipxrip(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
if (operation == IPX_RIP_REQUEST - 1) {
add_item_to_tree(rip_tree, cursor, 8,
"Route Vector: %s, %d hop%s, %d tick%s",
network_to_string((guint8*)&route.network),
ipxnet_to_string((guint8*)&route.network),
route.hops, route.hops == 1 ? "" : "s",
route.ticks, route.ticks == 1 ? "" : "s");
}
else {
add_item_to_tree(rip_tree, cursor, 8,
"Route Vector: %s, %d hop%s, %d tick%s (%d ms)",
network_to_string((guint8*)&route.network),
ipxnet_to_string((guint8*)&route.network),
route.hops, route.hops == 1 ? "" : "s",
route.ticks, route.ticks == 1 ? "" : "s",
route.ticks * 1000 / 18);
@ -499,7 +499,7 @@ dissect_sap(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
add_item_to_tree(s_tree, cursor, 2, "Server Type: %s (0x%04X)",
server_type(server.server_type), server.server_type);
add_item_to_tree(s_tree, cursor+50, 4, "Network: %s",
network_to_string((guint8*)&pd[cursor+50]));
ipxnet_to_string((guint8*)&pd[cursor+50]));
add_item_to_tree(s_tree, cursor+54, 6, "Node: %s",
ether_to_str((guint8*)&pd[cursor+54]));
add_item_to_tree(s_tree, cursor+60, 2, "Socket: %s (0x%04X)",

140
packet-nbipx.c Normal file
View File

@ -0,0 +1,140 @@
/* packet-nbipx.c
* Routines for NetBIOS over IPX packet disassembly
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
* $Id: packet-nbipx.c,v 1.1 1998/10/14 04:09:12 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 1998 Gerald Combs
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <gtk/gtk.h>
#include <pcap.h>
#include <stdio.h>
#include <memory.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#include "ethereal.h"
#include "packet.h"
#include "packet-ipx.h" /* for ipxnet_to_string() */
/* There is no RFC or public specification of Netware or Microsoft
* NetBIOS over IPX packets. I have had to decode the protocol myself,
* so there are holes and perhaps errors in this code. (gram)
*/
struct nbipx_header {
guint32 router[8];
guint8 name_type;
guint8 packet_type;
char name[17];
};
void
dissect_nbipx(const u_char *pd, int offset, frame_data *fd, GtkTree *tree)
{
GtkWidget *nbipx_tree, *ti;
struct nbipx_header header;
int i, rtr_offset;
char *packet_type[] = {
"",
"Name Query"
};
header.name_type = pd[offset+32];
header.packet_type = pd[offset+33];
memcpy(header.name, &pd[offset+34], 16);
header.name[16] = 0; /* null-terminate the string */
if (fd->win_info[COL_NUM]) {
strcpy(fd->win_info[COL_PROTOCOL], "NetBIOS");
switch (header.packet_type) {
case 1:
sprintf(fd->win_info[COL_INFO], "Name Query for %s",
header.name);
break;
default:
strcpy(fd->win_info[COL_INFO], "NetBIOS over IPX");
}
}
if (tree) {
ti = add_item_to_tree(GTK_WIDGET(tree), offset, END_OF_FRAME,
"NetBIOS over IPX");
nbipx_tree = gtk_tree_new();
add_subtree(ti, nbipx_tree, ETT_NBIPX);
if (header.packet_type <= 1) {
add_item_to_tree(nbipx_tree, offset+33, 1,
"Packet Type: %s (%02X)", packet_type[header.packet_type],
header.packet_type);
}
else {
add_item_to_tree(nbipx_tree, offset+33, 1,
"Packet Type: Unknown (%02X)", header.packet_type);
}
/* Eight routers are listed */
for (i = 0; i < 8; i++) {
rtr_offset = offset + (i << 2);
memcpy(&header.router[i], &pd[rtr_offset], 4);
if (header.router[i] != 0) {
add_item_to_tree(nbipx_tree, rtr_offset, 4, "IPX Network: %s",
ipxnet_to_string((guint8*)&header.router[i]));
}
}
add_item_to_tree(nbipx_tree, offset+32, 1, "Name Type: %02X",
header.name_type);
add_item_to_tree(nbipx_tree, offset+34, 16, "Name String: %s",
header.name);
}
}

157
packet-nbns.c Normal file
View File

@ -0,0 +1,157 @@
/* packet-nbns.c
* Routines for NetBIOS Name Service packet disassembly
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
* $Id: packet-nbns.c,v 1.1 1998/10/14 04:09:11 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 1998 Gerald Combs
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <gtk/gtk.h>
#include <pcap.h>
#include <stdio.h>
#include <memory.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#include "ethereal.h"
#include "packet.h"
/* Packet structure taken from RFC 1002. See also RFC 1001.
* The Samba source code, specifically nmblib.c, also helps a lot. */
struct nbns_header {
guint16 name_tran_id;
guint8 r;
guint8 opcode;
struct {
guint8 bcast;
guint8 recursion_available;
guint8 recursion_desired;
guint8 trunc;
guint8 authoritative;
} nm_flags;
guint8 rcode;
guint16 qdcount;
guint16 ancount;
guint16 nscount;
guint16 arcount;
};
void
dissect_nbns(const u_char *pd, int offset, frame_data *fd, GtkTree *tree)
{
GtkWidget *nbns_tree, *ti;
struct nbns_header header;
int nm_flags;
char *opcode[] = {
"Query",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Registration",
"Release",
"Wait and Acknowledge",
"Refresh"
"Refresh(altcode)"
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Multi-Homed Registration",
};
if (fd->win_info[COL_NUM]) {
/*strcpy(fd->win_info[COL_PROTOCOL], "NBNS (UDP)");*/
strcpy(fd->win_info[COL_PROTOCOL], "NBNS");
strcpy(fd->win_info[COL_INFO], "NetBIOS Name Service");
}
if (tree) {
ti = add_item_to_tree(GTK_WIDGET(tree), offset, END_OF_FRAME,
"NetBIOS Name Service");
nbns_tree = gtk_tree_new();
add_subtree(ti, nbns_tree, ETT_NBNS);
/* This is taken from samba/source/nmlib.c, parse_nmb() */
header.name_tran_id = pntohs(&pd[offset]);
header.opcode = (pd[offset+2] >> 3) & 0xf;
header.r = (pd[offset+2] >> 7) & 1;
nm_flags = ((pd[offset+2] & 0x7) << 4) + (pd[offset+3] >> 4);
header.nm_flags.bcast = (nm_flags & 1) ? 1 : 0;
header.nm_flags.recursion_available = (nm_flags & 8) ? 1 : 0;
header.nm_flags.recursion_desired = (nm_flags & 0x10) ? 1 : 0;
header.nm_flags.trunc = (nm_flags & 0x20) ? 1 : 0;
header.nm_flags.authoritative = (nm_flags & 0x40) ? 1 : 0;
header.rcode = pd[offset+3] & 0xf;
header.qdcount = pletohs(&pd[offset+4]);
header.ancount = pletohs(&pd[offset+6]);
header.nscount = pletohs(&pd[offset+8]);
header.arcount = pletohs(&pd[offset+10]);
add_item_to_tree(nbns_tree, offset, 2, "Transaction ID: 0x%04X",
header.name_tran_id);
add_item_to_tree(nbns_tree, offset + 2, 1, "Type: %s",
header.r == 0 ? "Request" : "Response" );
if (header.opcode <= 15) {
add_item_to_tree(nbns_tree, offset + 2, 1, "Operation: %s (%d)",
opcode[header.opcode], header.opcode);
}
else {
add_item_to_tree(nbns_tree, offset + 2, 1, "Operation: Unknown (%d)",
header.opcode);
}
/* add_item_to_tree(nbns_tree, offset+2, 2, */
}
}

View File

@ -1,7 +1,7 @@
/* packet-udp.c
* Routines for UDP packet disassembly
*
* $Id: packet-udp.c,v 1.4 1998/09/27 22:12:40 gerald Exp $
* $Id: packet-udp.c,v 1.5 1998/10/14 04:09:13 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -88,6 +88,9 @@ dissect_udp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
/* we should check the source port too (RIP: UDP src and dst port 520) */
dissect_rip(pd, offset, fd, tree);
break;
case UDP_PORT_NBNS:
dissect_nbns(pd, offset, fd, tree);
break;
case UDP_PORT_IPX: /* RFC 1234 */
dissect_ipx(pd, offset, fd, tree);
break;

View File

@ -1,7 +1,7 @@
/* packet.h
* Definitions for packet disassembly structures and routines
*
* $Id: packet.h,v 1.13 1998/10/13 05:40:02 guy Exp $
* $Id: packet.h,v 1.14 1998/10/14 04:09:14 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -365,6 +365,7 @@ typedef struct _e_udphdr {
#define UDP_PORT_DNS 53
#define UDP_PORT_BOOTPS 67
#define UDP_PORT_IPX 213
#define UDP_PORT_NBNS 137
#define UDP_PORT_RIP 520
/* TCP Ports */
@ -425,6 +426,8 @@ enum {
ETT_IPXRIP,
ETT_IPXSAP,
ETT_IPXSAP_SERVER,
ETT_NBNS,
ETT_NBIPX,
NUM_TREE_TYPES /* last item number plus one */
};
@ -515,6 +518,8 @@ void dissect_ipv6(const u_char *, int, frame_data *, GtkTree *);
void dissect_ipx(const u_char *, int, frame_data *, GtkTree *);
void dissect_llc(const u_char *, int, frame_data *, GtkTree *);
void dissect_lpd(const u_char *, int, frame_data *, GtkTree *);
void dissect_nbipx(const u_char *, int, frame_data *, GtkTree *);
void dissect_nbns(const u_char *, int, frame_data *, GtkTree *);
void dissect_ncp(const u_char *, int, frame_data *, GtkTree *);
void dissect_osi(const u_char *, int, frame_data *, GtkTree *);
void dissect_ospf(const u_char *, int, frame_data *, GtkTree *);