From 5958b839bc4917711bcc2759893ab2bdb9b420db Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Fri, 30 Apr 1999 03:16:03 +0000 Subject: [PATCH] Add support for the NetBIOS Session Service. Improve the descriptions of the NetBIOS Name Service errors a bit. svn path=/trunk/; revision=247 --- packet-nbns.c | 209 ++++++++++++++++++++++++++++++++++++++++++-------- packet-tcp.c | 8 +- packet.h | 16 ++-- 3 files changed, 195 insertions(+), 38 deletions(-) diff --git a/packet-nbns.c b/packet-nbns.c index d3220216ca..7909d71e5a 100644 --- a/packet-nbns.c +++ b/packet-nbns.c @@ -1,9 +1,10 @@ /* packet-nbns.c - * Routines for NetBIOS Name Service packet disassembly + * Routines for NetBIOS Name Service, Datagram Service, and Session Service + * packet disassembly (the name dates back to when it had only NBNS) * Gilbert Ramirez * Much stuff added by Guy Harris * - * $Id: packet-nbns.c,v 1.14 1999/03/23 03:14:40 gram Exp $ + * $Id: packet-nbns.c,v 1.15 1999/04/30 03:16:02 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -59,26 +60,6 @@ #define T_NB 32 /* NetBIOS name service RR */ #define T_NBSTAT 33 /* NetBIOS node status RR */ -/* NetBIOS datagram packet, from RFC 1002, page 32 */ -struct nbdgm_header { - guint8 msg_type; - struct { - guint8 more; - guint8 first; - guint8 node_type; - } flags; - guint16 dgm_id; - guint32 src_ip; - guint16 src_port; - - /* For packets with data */ - guint16 dgm_length; - guint16 pkt_offset; - - /* For error packets */ - guint8 error_code; -}; - /* Bit fields in the flags */ #define F_RESPONSE (1<<15) /* packet is response */ #define F_OPCODE (0xF<<11) /* query opcode */ @@ -347,15 +328,15 @@ nbns_add_nbns_flags(proto_tree *nbns_tree, int offset, u_short flags, proto_tree *field_tree; proto_item *tf; static const value_string rcode_vals[] = { - { RCODE_NOERROR, "No error" }, - { RCODE_FMTERROR, "Format error" }, - { RCODE_SERVFAIL, "Server failure" }, - { RCODE_NAMEERROR, "Name error" }, - { RCODE_NOTIMPL, "Not implemented" }, - { RCODE_REFUSED, "Refused" }, - { RCODE_ACTIVE, "Name is active" }, - { RCODE_CONFLICT, "Name is in conflict" }, - { 0, NULL } + { RCODE_NOERROR, "No error" }, + { RCODE_FMTERROR, "Request was invalidly formatted" }, + { RCODE_SERVFAIL, "Server failure" }, + { RCODE_NAMEERROR, "Requested name does not exist" }, + { RCODE_NOTIMPL, "Request is not implemented" }, + { RCODE_REFUSED, "Request was refused" }, + { RCODE_ACTIVE, "Name is owned by another node" }, + { RCODE_CONFLICT, "Name is in conflict" }, + { 0, NULL } }; strcpy(buf, val_to_str(flags & F_OPCODE, opcode_vals, @@ -979,6 +960,25 @@ dissect_nbns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) } } +/* NetBIOS datagram packet, from RFC 1002, page 32 */ +struct nbdgm_header { + guint8 msg_type; + struct { + guint8 more; + guint8 first; + guint8 node_type; + } flags; + guint16 dgm_id; + guint32 src_ip; + guint16 src_port; + + /* For packets with data */ + guint16 dgm_length; + guint16 pkt_offset; + + /* For error packets */ + guint8 error_code; +}; void dissect_nbdgm(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) @@ -1115,3 +1115,150 @@ dissect_nbdgm(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) } } } + +/* + * NetBIOS Session Service message types. + */ +#define SESSION_MESSAGE 0x00 +#define SESSION_REQUEST 0x81 +#define POSITIVE_SESSION_RESPONSE 0x82 +#define NEGATIVE_SESSION_RESPONSE 0x83 +#define RETARGET_SESSION_RESPONSE 0x84 +#define SESSION_KEEP_ALIVE 0x85 + +static const value_string message_types[] = { + { SESSION_MESSAGE, "Session message" }, + { SESSION_REQUEST, "Session request" }, + { POSITIVE_SESSION_RESPONSE, "Positive session response" }, + { NEGATIVE_SESSION_RESPONSE, "Negative session response" }, + { RETARGET_SESSION_RESPONSE, "Retarget session response" }, + { SESSION_KEEP_ALIVE, "Session keep-alive" }, + { 0x0, NULL } +}; + +/* + * NetBIOS Session Service flags. + */ +#define NBSS_FLAGS_E 0x1 + +static const value_string error_codes[] = { + { 0x80, "Not listening on called name" }, + { 0x81, "Not listening for called name" }, + { 0x82, "Called name not present" }, + { 0x83, "Called name present, but insufficient resources" }, + { 0x8F, "Unspecified error" }, + { 0x0, NULL } +}; + +/* + * Dissect a single NBSS packet (there may be more than one in a given TCP + * segment). + */ +static int +dissect_nbss_packet(const u_char *pd, int offset, proto_tree *tree, int max_data) +{ + proto_tree *nbss_tree; + proto_item *ti; + proto_tree *field_tree; + proto_item *tf; + guint8 msg_type; + guint8 flags; + guint16 length; + int len; + char name[32]; + + msg_type = pd[offset]; + flags = pd[offset + 1]; + length = pntohs(&pd[offset + 2]); + if (flags & NBSS_FLAGS_E) + length += 65536; + + ti = proto_tree_add_item(tree, offset, length + 4, + "NetBIOS Session Service"); + nbss_tree = proto_tree_new(); + proto_item_add_subtree(ti, nbss_tree, ETT_NBSS); + + proto_tree_add_item(nbss_tree, offset, 1, "Message Type: %s", + val_to_str(msg_type, message_types, "Unknown")); + offset += 1; + + tf = proto_tree_add_item(nbss_tree, offset, 1, "Flags: 0x%04x", flags); + field_tree = proto_tree_new(); + proto_item_add_subtree(tf, field_tree, ETT_NBSS_FLAGS); + proto_tree_add_item(field_tree, offset, 1, "%s", + decode_boolean_bitfield(flags, NBSS_FLAGS_E, + 8, "Add 65536 to length", "Add 0 to length")); + offset += 1; + + proto_tree_add_item(nbss_tree, offset, 2, "Length: %u", length); + offset += 2; + + switch (msg_type) { + + case SESSION_REQUEST: + len = get_nbns_name(&pd[offset], pd, offset, name); + proto_tree_add_item(nbss_tree, offset, len, + "Called name: %s", name); + offset += len; + + len = get_nbns_name(&pd[offset], pd, offset, name); + proto_tree_add_item(nbss_tree, offset, len, + "Calling name: %s", name); + break; + + case NEGATIVE_SESSION_RESPONSE: + proto_tree_add_item(nbss_tree, offset, 1, + "Error code: %s", + val_to_str(pd[offset], error_codes, "Unknown (%x)")); + break; + + case RETARGET_SESSION_RESPONSE: + proto_tree_add_item(nbss_tree, offset, 4, + "Retarget IP address: %s", + ip_to_str((guint8 *)&pd[offset])); + offset += 4; + + proto_tree_add_item(nbss_tree, offset, 2, + "Retarget port: %u", pntohs(&pd[offset])); + break; + + case SESSION_MESSAGE: + /* + * Here we can pass the packet off to the next protocol. + */ + proto_tree_add_item(nbss_tree, offset, length, + "Data (%u bytes)", length); + break; + } + return length + 4; +} + +void +dissect_nbss(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data) +{ + guint8 msg_type; + guint8 flags; + guint16 length; + int len; + + msg_type = pd[offset]; + flags = pd[offset + 1]; + length = pntohs(&pd[offset + 2]); + if (flags & NBSS_FLAGS_E) + length += 65536; + + if (check_col(fd, COL_PROTOCOL)) + col_add_str(fd, COL_PROTOCOL, "NBSS (TCP)"); + if (check_col(fd, COL_INFO)) { + col_add_fstr(fd, COL_INFO, + val_to_str(msg_type, message_types, "Unknown (%x)")); + } + + if (tree) { + while (max_data > 0) { + len = dissect_nbss_packet(pd, offset, tree, max_data); + offset += len; + max_data -= len; + } + } +} diff --git a/packet-tcp.c b/packet-tcp.c index 85d0919117..8793c62fe9 100644 --- a/packet-tcp.c +++ b/packet-tcp.c @@ -1,7 +1,7 @@ /* packet-tcp.c * Routines for TCP packet disassembly * - * $Id: packet-tcp.c,v 1.20 1999/04/06 02:02:11 guy Exp $ + * $Id: packet-tcp.c,v 1.21 1999/04/30 03:16:02 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -70,6 +70,7 @@ static int info_len; #define TCP_PORT_HTTP 80 #define TCP_PORT_POP 110 #define TCP_PORT_NNTP 119 +#define TCP_PORT_NBSS 139 #define TCP_PORT_PRINTER 515 #define TCP_ALT_PORT_HTTP 8080 @@ -490,6 +491,11 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { case TCP_ALT_PORT_HTTP: dissect_http(pd, offset, fd, tree); break; + + case TCP_PORT_NBSS: + pi.match_port = TCP_PORT_NBSS; + dissect_nbss(pd, offset, fd, tree, payload); + break; default: /* check existence of high level protocols */ diff --git a/packet.h b/packet.h index 3410ae1e8d..c422b2dc9f 100644 --- a/packet.h +++ b/packet.h @@ -1,7 +1,7 @@ /* packet.h * Definitions for packet disassembly structures and routines * - * $Id: packet.h,v 1.46 1999/04/06 02:02:11 guy Exp $ + * $Id: packet.h,v 1.47 1999/04/30 03:16:03 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -223,6 +223,8 @@ enum { ETT_TELNET, ETT_TELNET_SUBOPT, ETT_NNTP, + ETT_NBSS, + ETT_NBSS_FLAGS, NUM_TREE_TYPES /* last item number plus one */ }; @@ -338,8 +340,6 @@ void dissect_data(const u_char *, int, frame_data *, proto_tree *); void dissect_ddp(const u_char *, int, frame_data *, proto_tree *); void dissect_dns(const u_char *, int, frame_data *, proto_tree *); void dissect_esp(const u_char *, int, frame_data *, proto_tree *); -void dissect_ftp(const u_char *, int, frame_data *, proto_tree *, int); -void dissect_ftpdata(const u_char *, int, frame_data *, proto_tree *, int); void dissect_giop(const u_char *, int, frame_data *, proto_tree *); void dissect_http(const u_char *, int, frame_data *, proto_tree *); void dissect_icmp(const u_char *, int, frame_data *, proto_tree *); @@ -354,15 +354,12 @@ void dissect_nbdgm(const u_char *, int, frame_data *, proto_tree *); void dissect_nbipx_ns(const u_char *, int, frame_data *, proto_tree *); void dissect_nbns(const u_char *, int, frame_data *, proto_tree *); void dissect_ncp(const u_char *, int, frame_data *, proto_tree *); -void dissect_nntp(const u_char *, int, frame_data *, proto_tree *, int); void dissect_nwlink_dg(const u_char *, int, frame_data *, proto_tree *); void dissect_osi(const u_char *, int, frame_data *, proto_tree *); void dissect_ospf(const u_char *, int, frame_data *, proto_tree *); void dissect_ospf_hello(const u_char *, int, frame_data *, proto_tree *); -void dissect_pop(const u_char *, int, frame_data *, proto_tree *, int); void dissect_rip(const u_char *, int, frame_data *, proto_tree *); void dissect_tcp(const u_char *, int, frame_data *, proto_tree *); -void dissect_telnet(const u_char *, int, frame_data *, proto_tree *, int); void dissect_tftp(const u_char *, int, frame_data *, proto_tree *); void dissect_trmac(const u_char *, int, frame_data *, proto_tree *); void dissect_udp(const u_char *, int, frame_data *, proto_tree *); @@ -374,6 +371,13 @@ void dissect_vines_ipc(const u_char *, int, frame_data *, proto_tree *); void dissect_vines_rtp(const u_char *, int, frame_data *, proto_tree *); void dissect_vines_spp(const u_char *, int, frame_data *, proto_tree *); +void dissect_ftp(const u_char *, int, frame_data *, proto_tree *, int); +void dissect_ftpdata(const u_char *, int, frame_data *, proto_tree *, int); +void dissect_nbss(const u_char *, int, frame_data *, proto_tree *, int); +void dissect_nntp(const u_char *, int, frame_data *, proto_tree *, int); +void dissect_pop(const u_char *, int, frame_data *, proto_tree *, int); +void dissect_telnet(const u_char *, int, frame_data *, proto_tree *, int); + void init_dissect_udp(void); /* These functions are in ethertype.c */