* Portions Copyright (c) Gilbert Ramirez 2000-2002
* Portions Copyright (c) Novell, Inc. 2000-2003
*
- * $Id: packet-ncp2222.inc,v 1.62 2003/09/23 22:04:02 guy Exp $
+ * $Id: packet-ncp2222.inc,v 1.70 2004/02/29 08:01:22 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
request_value->nds_version = 0;
strcpy(request_value->object_name, " ");
request_value->nds_frag = TRUE;
- strcpy(request_value->info_string, "\0");
g_hash_table_insert(ncp_req_hash, request_key, request_value);
guint
get_item_value(proto_item *item)
{
- return fvalue_get_integer(PITEM_FINFO(item)->value);
+ return fvalue_get_integer(&PITEM_FINFO(item)->value);
}
char *
get_item_string(proto_item *item)
{
- return fvalue_get(PITEM_FINFO(item)->value);
+ return fvalue_get(&PITEM_FINFO(item)->value);
}
char *
revent = tvb_get_letohs(tvb, voffset); /* Event */
proto_tree_add_uint_format(nvtree, hf_nds_revent, tvb, voffset,
2, revent, "Event: %d", revent);
- voffset = voffset+14;
+ voffset = voffset+2;
voffset += align_4(tvb, voffset);
break;
case 0x00000017: /* Back Link */
* these values on the first fragment and then populate the values in the final
* fragment. We only do this on the first dissection.
*
+ * XXX - this has several problems:
+ *
+ * 1) it uses global variables ("frags");
+ *
+ * 2) the sequence numbers don't start at a fixed value, they're
+ * per-connection sequence numbers;
+ *
+ * 3) the fragment size and handle aren't put into the protocol
+ * tree for fragments other than the last fragment.
+ *
+ * 2) needs to be fixed by having a way of doing defragmentation using
+ * connection sequence numbers; that's needed for fragmentation in
+ * connection-oriented protocols, e.g. COTP, as well.
+ * That might let us fix 1) as well.
+ *
+ * 3) should be fixed by putting that into the protocol tree ourselves
+ * if this isn't the first fragment.
*/
void
nds_defrag(tvbuff_t *tvb, packet_info *pinfo, guint16 nw_connection, guint8 sequence, guint16 type, proto_tree *tree)
}
}
/* Check to see if defragmentation is enabeled in the dissector */
- if (!nds_defragment || type != NCP_SERVICE_REPLY) {
+ if (!nds_defragment) {
dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree);
return;
}
}
/* Validate that this is an NDS packet */
/* If this isn't an NDS packet then just return */
- if (request_value->ncp_rec->func!=104 || request_value->ncp_rec->subfunc!=2) {
+ if (!request_value->ncp_rec ||
+ request_value->ncp_rec->func!=104 || request_value->ncp_rec->subfunc!=2) {
dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree);
return;
}
guint16 type, proto_tree *ncp_tree)
{
guint8 func, subfunc = 0;
- gboolean requires_subfunc;
- gboolean has_length = TRUE;
+ gboolean requires_subfunc = FALSE;
+ gboolean has_length = FALSE;
ncp_req_hash_value *request_value = NULL;
const ncp_record *ncp_rec = NULL;
conversation_t *conversation;
gboolean run_info_str = FALSE;
guint32 length_remaining;
guint32 testvar;
- char col_str[256];
func = tvb_get_guint8(tvb, 6);
- requires_subfunc = ncp_requires_subfunc(func);
- has_length = ncp_has_length_parameter(func);
- if (requires_subfunc) {
- if (has_length) {
- subfunc = tvb_get_guint8(tvb, 9);
- }
- else {
- subfunc = tvb_get_guint8(tvb, 7);
- }
- }
/* Determine which ncp_record to use. */
switch (type) {
case NCP_ALLOCATE_SLOT:
}
break;
case NCP_SERVICE_REQUEST:
+ requires_subfunc = ncp_requires_subfunc(func);
+ has_length = ncp_has_length_parameter(func);
+ if (requires_subfunc) {
+ if (has_length) {
+ subfunc = tvb_get_guint8(tvb, 9);
+ }
+ else {
+ subfunc = tvb_get_guint8(tvb, 7);
+ }
+ }
ncp_rec = ncp_record_find(func, subfunc);
break;
case NCP_DEALLOCATE_SLOT:
break;
default:
ncp_rec = NULL;
+ break;
}
/* Fill in the INFO column. */
if (check_col(pinfo->cinfo, COL_INFO)) {
if (ncp_rec) {
col_add_fstr(pinfo->cinfo, COL_INFO, "C %s", ncp_rec->name);
+ if (ncp_rec->req_info_str) {
+ /* We want to add more stuff to the Info
+ column. */
+ run_info_str = TRUE;
+ }
}
else {
if (requires_subfunc) {
* check to see if this NCP type uses a "request condition".
* If so, we have to build a proto_tree because request conditions
* use display filters to work, and without a proto_tree,
- * display filters can't possibly work. If we already have
- * a proto_tree, then wonderful. If we don't, we need to build
- * one. */
+ * display filters can't possibly work. */
if (ncp_rec) {
if (ncp_rec->req_cond_indexes) {
run_req_cond = TRUE;
}
- /* We also have to use a tree if we have to construct an info_str */
- if ((run_info_str || run_req_cond) && !ncp_tree) {
- proto_item *ti;
-
- temp_tree = proto_tree_create_root();
- proto_tree_set_visible(temp_tree, FALSE);
- ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, FALSE);
- ncp_tree = proto_item_add_subtree(ti, ett_ncp);
- }
}
}
- /* Only create info string if COL_INFO is available. */
- if (ncp_rec->req_info_str && check_col(pinfo->cinfo, COL_INFO)) {
- run_info_str = TRUE;
- }
+
+ /* If we have to handle a request condition, or have to
+ add to the Info column, we need to construct a protocol
+ tree. If we already have a proto_tree, then wonderful.
+ If we don't, we need to build one. */
+ if ((run_info_str || run_req_cond) && !ncp_tree) {
+ proto_item *ti;
+
+ temp_tree = proto_tree_create_root();
+ proto_tree_set_visible(temp_tree, FALSE);
+ ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, FALSE);
+ ncp_tree = proto_item_add_subtree(ti, ett_ncp);
+ }
+
if (ncp_tree) {
/* If the dissection throws an exception, be sure to free
* the temporary proto_tree that was created. Because of the
proto_tree_prime_hfid(ncp_tree, *ncp_rec->req_info_str->hf_ptr);
}
- conversation = find_conversation(&pinfo->src, &pinfo->dst,
- PT_NCP, nw_connection, nw_connection, 0);
-
switch (type) {
case NCP_BROADCAST_SLOT:
; /* nothing */
/* The group is not part of the packet, but it's useful
* information to display anyway. */
if (ncp_rec) {
- proto_tree_add_text(ncp_tree, tvb, 6, 1, "Group: %s",
+ proto_tree_add_text(ncp_tree, tvb, 0, 0, "Group: %s",
ncp_groups[ncp_rec->group]);
}
process_ptvc_record(ptvc, ncp_rec->request_ptvc, NULL, TRUE, ncp_rec);
}
ptvcursor_free(ptvc);
+ /* NMAS packets are dessected in packet-ncp-nmas.c */
+ if (func == 0x5e && ncp_tree) {
+ dissect_nmas_request(tvb, pinfo, ncp_tree, request_value);
+ }
/* Now that the dissection is done, do we need to run
* some display filters on the resulting tree in order
if (info_type != 0) { /* Is this a string or not? */
if (info_type == 1) { /* Is this bytes? */
- byte_string = bytes_to_str(fvalue_get(finfo->value), fvalue_length(finfo->value));
- sprintf(col_str, ncp_rec->req_info_str->first_string, byte_string);
- strcpy(request_value->info_string, col_str);
+ byte_string = bytes_to_str(fvalue_get(&finfo->value), fvalue_length(&finfo->value));
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ (const gchar*) ncp_rec->req_info_str->first_string,
+ byte_string);
}
else
{
if (info_type == 2) { /* Is this a String? */
- uni_to_string(fvalue_get(finfo->value), fvalue_length(finfo->value), non_uni_string);
- sprintf(col_str, ncp_rec->req_info_str->first_string, non_uni_string);
- strcpy(request_value->info_string, col_str);
+ uni_to_string(fvalue_get(&finfo->value), fvalue_length(&finfo->value), non_uni_string);
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ (const gchar*) ncp_rec->req_info_str->first_string,
+ non_uni_string);
}
else
{
- sprintf(col_str, ncp_rec->req_info_str->first_string, fvalue_get(finfo->value));
- strcpy(request_value->info_string, col_str);
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ (const gchar*) ncp_rec->req_info_str->first_string,
+ fvalue_get(&finfo->value));
}
}
}
else
{
- sprintf(col_str, ncp_rec->req_info_str->first_string, fvalue_get_integer(finfo->value));
- strcpy(request_value->info_string, col_str);
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ (const gchar*) ncp_rec->req_info_str->first_string,
+ fvalue_get_integer(&finfo->value));
}
}
if (len > 1) {
if (info_type != 0) { /* Is this a string or not? */
if (info_type == 1)
{ /* Is this bytes? */
- byte_string = bytes_to_str(fvalue_get(finfo->value), fvalue_length(finfo->value));
- sprintf(col_str, ncp_rec->req_info_str->repeat_string, byte_string);
- strcat(request_value->info_string, col_str);
+ byte_string = bytes_to_str(fvalue_get(&finfo->value), fvalue_length(&finfo->value));
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ (const gchar*) ncp_rec->req_info_str->repeat_string,
+ byte_string);
}
else
{
if (info_type == 2) { /* Is this a String? */
- uni_to_string(fvalue_get(finfo->value), fvalue_length(finfo->value), non_uni_string);
- sprintf(col_str, ncp_rec->req_info_str->repeat_string, non_uni_string);
- strcat(request_value->info_string, col_str);
+ uni_to_string(fvalue_get(&finfo->value), fvalue_length(&finfo->value), non_uni_string);
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ (const gchar*) ncp_rec->req_info_str->repeat_string,
+ non_uni_string);
}
else
{
- sprintf(col_str, ncp_rec->req_info_str->repeat_string, fvalue_get(finfo->value));
- strcat(request_value->info_string, col_str);
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ (const gchar*) ncp_rec->req_info_str->repeat_string,
+ fvalue_get(&finfo->value));
}
}
}
else
{
- sprintf(col_str, ncp_rec->req_info_str->repeat_string, fvalue_get_integer(finfo->value));
- strcat(request_value->info_string, col_str);
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ (const gchar*) ncp_rec->req_info_str->repeat_string,
+ fvalue_get_integer(&finfo->value));
}
}
}
/* Free the temporary proto_tree */
CLEANUP_CALL_AND_POP;
}
- if (run_info_str)
- {
- if (!request_value)
- {
- conversation = find_conversation(&pinfo->src, &pinfo->dst,
- PT_NCP, nw_connection, nw_connection, 0);
- if (conversation != NULL) {
- /* find the record telling us the request made that caused
- this reply */
- request_value = ncp_hash_lookup(conversation, sequence);
- }
- if (!conversation || !request_value)
- {
- return;
- }
- }
- if (strlen(request_value->info_string) > 1)
- {
- col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
- request_value->info_string);
- }
- }
}
/* Decode NDS Reply packets */
if (ncp_rec) {
+ /* Dissect NMAS Reply packets */
+ if (ncp_rec->func == 0x5e && request_value)
+ {
+ dissect_nmas_reply(tvb, pinfo, ncp_tree, ncp_rec->func, ncp_rec->subfunc, request_value);
+ }
if ((ncp_rec->func == 0x68 && ncp_rec->subfunc == 0x01) && completion_code == 0) {
ping_version = tvb_get_guint8(tvb, 8);
proto_tree_add_item(ncp_tree, hf_ping_version, tvb, 8, 1, TRUE);
conversation_t *conversation;
ptvcursor_t *ptvc = NULL;
proto_tree *temp_tree = NULL;
+ gboolean run_req_cond = FALSE;
+ gboolean run_info_str = FALSE;
guint8 nds_verb = 0;
char * verb_string = "";
guint32 nds_frag = 0;
+ gboolean added_arrow;
nds_val pvalues[9];
char string_buffer[9][1024];
guint8 nds_version = 0;
guint32 foffset = 0;
- guint32 nds_reply_buffer;
nw_uni_t req_buffer;
char global_object_name[256];
guint32 global_eid=0;
gboolean resolve_eid=FALSE;
guint32 global_flags=0;
int i;
- char col_str[256];
for (i = 0; i < 9; i++) {
pvalues[i].vtype = 0;
nds_version = 0;
foffset = 28;
}
- nds_reply_buffer = tvb_get_letohl(tvb, foffset);
- proto_tree_add_uint(ncp_tree, hf_nds_buffer_size, tvb, foffset,
- 4, nds_reply_buffer);
+ if (type == NCP_SERVICE_REQUEST) {
+ proto_tree_add_item(ncp_tree, hf_nds_buffer_size, tvb, foffset,
+ 4, TRUE);
+ }
foffset = foffset+4;
verb_string = val_to_str(nds_verb, ncp_nds_verb_vals,
"Continuation Fragment");
/* Fill in the INFO column. */
if (check_col(pinfo->cinfo, COL_INFO)) {
if (ncp_rec) {
-
col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDS");
if (nds_frag != 0xffffffff) {
col_add_fstr(pinfo->cinfo, COL_INFO, "C Continue NDS Fragment %08x", nds_frag);
else {
col_add_fstr(pinfo->cinfo, COL_INFO, "C NDS %s", verb_string);
}
+ run_info_str = TRUE;
}
else {
col_add_fstr(pinfo->cinfo, COL_INFO,
/* It's not part of any conversation - create a new one. */
conversation = conversation_new(&pinfo->src, &pinfo->dst,
PT_NCP, nw_connection, nw_connection, 0);
-
+ }
+
+ if (!pinfo->fd->flags.visited) {
request_value = ncp_hash_insert(conversation, sequence, ncp_rec);
request_value->req_frame_num = pinfo->fd->num;
request_value->req_frame_time.secs=pinfo->fd->abs_secs;
request_value->req_frame_time.nsecs=pinfo->fd->abs_usecs*1000;
- }
-
- if (!pinfo->fd->flags.visited) {
+
/* If this is the first time we're examining the packet,
* check to see if this NCP type uses a "request condition".
* If so, we have to build a proto_tree because request conditions
* a proto_tree, then wonderful. If we don't, we need to build
* one. */
if (ncp_rec && !ncp_tree) {
- proto_item *ti;
-
- temp_tree = proto_tree_create_root();
- proto_tree_set_visible(temp_tree, FALSE);
- ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, FALSE);
- ncp_tree = proto_item_add_subtree(ti, ett_ncp);
+ run_req_cond = TRUE;
}
}
+ /* If we have to handle a request condition, or have to
+ add to the Info column, we need to construct a protocol
+ tree. If we already have a proto_tree, then wonderful.
+ If we don't, we need to build one. */
+ if ((run_info_str || run_req_cond) && !ncp_tree) {
+ proto_item *ti;
+
+ temp_tree = proto_tree_create_root();
+ proto_tree_set_visible(temp_tree, FALSE);
+ ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, FALSE);
+ ncp_tree = proto_item_add_subtree(ti, ett_ncp);
+ }
+
if (ncp_tree) {
/* If the dissection throws an exception, be sure to free
* the temporary proto_tree that was created. Because of the
proto_tree_add_uint_format(ncp_tree, hf_ncp_nds_verb, tvb, 24, 4,
nds_verb, "NDS Verb: %d, (0x%02x), %s",
nds_verb, nds_verb, verb_string);
+ added_arrow = FALSE;
for (i = 0; i < 9; i++) {
switch (pvalues[i].vtype) {
* for MVTYPE_PROC_ENTRY_SPECIFIERS,
* to add string to columninfo
*/
- sprintf(col_str, "%s", pvalues[i].vstring);
- strcat(request_value->info_string, col_str);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ if (!added_arrow) {
+ col_append_str(pinfo->cinfo, COL_INFO, " -> ");
+ added_arrow = TRUE;
+ }
+ col_append_str(pinfo->cinfo, COL_INFO, pvalues[i].vstring);
+ }
}
break;
* and the last string for MVTYPE_ATTR_REQUEST,
* by "process_multivalues()".
*/
- sprintf(col_str, "%s", pvalues[i].vstring);
- strcat(request_value->info_string, col_str);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ if (!added_arrow) {
+ col_append_str(pinfo->cinfo, COL_INFO, " -> ");
+ added_arrow = TRUE;
+ }
+ col_append_str(pinfo->cinfo, COL_INFO, pvalues[i].vstring);
+ }
}
break;
}
/* For NDS requests with just an EID, resolve name from hash table. */
}
+ request_eid_value = ncp_eid_hash_lookup(conversation, global_eid);
+ if(resolve_eid) {
+ if (request_eid_value) {
+ strcpy(global_object_name, request_eid_value->object_name);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ col_append_str(pinfo->cinfo, COL_INFO, ", Object Name - ");
+ col_append_str(pinfo->cinfo, COL_INFO, global_object_name);
+ }
+ }
+ }
+ if (request_value)
+ {
+ request_value->nds_request_verb = nds_verb;
+ request_value->nds_version = nds_version;
+ strcpy(request_value->object_name, global_object_name);
+ request_value->req_nds_flags = global_flags;
+ }
}
break;
/* Free the temporary proto_tree */
CLEANUP_CALL_AND_POP;
}
- if (!request_value)
- {
- conversation = find_conversation(&pinfo->src, &pinfo->dst,
- PT_NCP, nw_connection, nw_connection, 0);
- if (conversation != NULL) {
- /* find the record telling us the request made that caused
- this reply */
- request_value = ncp_hash_lookup(conversation, sequence);
- }
- if (!conversation || !request_value)
- {
- return;
- }
- }
- if (strlen(request_value->info_string) > 1)
- {
- if (check_col(pinfo->cinfo, COL_INFO)) {
- col_append_str(pinfo->cinfo, COL_INFO, " -> ");
- col_append_str(pinfo->cinfo, COL_INFO, request_value->info_string);
- }
- }
- request_eid_value = ncp_eid_hash_lookup(conversation, global_eid);
- if(resolve_eid) {
- if (request_eid_value) {
- strcpy(global_object_name, request_eid_value->object_name);
- if (check_col(pinfo->cinfo, COL_INFO))
- {
- col_append_str(pinfo->cinfo, COL_INFO, ", Object Name - ");
- col_append_str(pinfo->cinfo, COL_INFO, global_object_name);
- }
- }
- }
- if (request_value)
- {
- request_value->nds_request_verb = nds_verb;
- request_value->nds_version = nds_version;
- strcpy(request_value->object_name, global_object_name);
- request_value->req_nds_flags = global_flags;
- }
}
/*