diff options
Diffstat (limited to 'packet-smb.c')
-rw-r--r-- | packet-smb.c | 310 |
1 files changed, 260 insertions, 50 deletions
diff --git a/packet-smb.c b/packet-smb.c index 7ebb3aa70d..a67034c298 100644 --- a/packet-smb.c +++ b/packet-smb.c @@ -2,7 +2,7 @@ * Routines for smb packet dissection * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com> * - * $Id: packet-smb.c,v 1.51 1999/12/07 06:36:12 sharpe Exp $ + * $Id: packet-smb.c,v 1.52 1999/12/10 11:53:18 sharpe Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@unicom.net> @@ -8890,7 +8890,7 @@ int pd_p_current = 0, pd_d_current = 0, in_params = 0, need_data = 0; /* Initialize the various data structure */ void -dissect_transact_engine_init(const u_char *pd, const char *param_desc, const char *data_desc, int ParameterOffset, int ParameterCount, int DataOffset, int DataCount) +dissect_transact_engine_init(const u_char *pd, const char *param_desc, const char *data_desc, int SMB_offset, int ParameterOffset, int ParameterCount, int DataOffset, int DataCount) { d_count = DataCount; @@ -8945,125 +8945,219 @@ int dissect_transact_next(u_char *pd, char *Name, int dirn, proto_tree *tree) int bc; while (1) { - if (dirn == 1) { /* Request stuff */ - switch (in_params) { - case 0: /* We are in the params area ... */ + if (p_desc[p_offset] == 0) return 0; /* No more ... */ - switch (params[p_offset++]) { + switch (in_params) { - case 'r': + case 0: /* We are in the params area ... */ - break; /* Do nothing about the above, because it is not there */ + switch (p_desc[p_offset++]) { - case 'W': /* Word Parameter */ + case 'r': + if (dirn == 0) { /* We need to process the data ... */ + + need_data = 1; + + } + + break; + + case 'h': /* A WORD parameter received */ + + if (dirn == 0) { + + WParam = GSHORT(pd, pd_p_current); + + proto_tree_add_text(tee, pd_p_current, 2, "%s: %u (%04X)", (Name) ? Name : "Returned Word", WParam, WParam); + + pd_p_current += 2; + + return 1; + + } + + break; + + case 'W': /* Word Parameter */ + + if (dirn == 1) { /* A request ... */ + /* Insert a word param */ WParam = GSHORT(pd, pd_p_current); - proto_tree_add_text(tree, pd_p_current, 2, "Word Param: %u", WParam); + proto_tree_add_text(tree, pd_p_current, 2, "%s: %u (%04X)", (Name) ? Name : "Word Param", WParam, WParam); pd_p_current += 2; - break; + return 1; /* That's it here ... we have dissected a param */ - case 'D': /* Double Word parameter */ + } + + break; + + case 'D': /* Double Word parameter */ + + if (dirn == 1) { LParam = GWORD(pd, pd_p_current); - proto_tree_add_text(tree, pd_p_current, 4, "DWord Param: %u", LParam); + proto_tree_add_text(tree, pd_p_current, 4, "%s: %u (%08X)", (Name) ? Name : "DWord Param", LParam, LParam); pd_p_current += 2; - break; + return 1; /* That's it here */ + + } + + break; + + case 'g': /* A byte or series of bytes is returned */ + + if (dirn == 0) { + + bc = get_byte_count(pd + pd_p_current); /* Not clean */ + + proto_tree_add_text(tree, pd_p_current, bc, "%s%u: %s", (Name) ? Name : "B", (bc) ? bc : 1, format_text( pd + pd_p_current, (bc) ? bc : 1)); + + pd_p_current += (bc) ? bc : 1; + + return 1; + + } + + break; + + case 'b': /* A byte or series of bytes */ - case 'b': /* A byte or series of bytes */ + if (dirn == 1) { bc = get_byte_count(pd + pd_p_current); /* This is not clean */ /*Bytes = g_malloc(bc + 1); / * Is this needed ? */ - proto_tree_add_text(tree, pd_p_current, bc, "B%u: %s", format_text(pd + pd_p_current, (bc) ? bc : 1)); + proto_tree_add_text(tree, pd_p_current, bc, "%s%u: %s", (Name) ? Name : "B", (bc) ? bc : 1, format_text(pd + pd_p_current, (bc) ? bc : 1)); pd_p_current += (bc) ? bc : 1; - break; + return 1; /* That's it here ... */ - case 'O': /* A null pointer */ + } + + break; + + case 'O': /* A null pointer */ + + if (dirn == 1) { - proto_tree_add_text(tree, pd_p_current, 0, "Null Pointer"); + proto_tree_add_text(tree, pd_p_current, 0, "%s: Null Pointer", (Name) ? Name : "Unknown"); + + return 1; /* That's it here */ + + } + + break; - break; + case 'z': /* An AsciiZ string */ - case 'z': /* An AsciiZ string */ + if (dirn == 1) { AsciiZ = pd + pd_p_current; - proto_tree_add_text(tree, pd_p_current, strlen(AsciiZ) + 1, "AsciiZ: %s", AsciiZ); + proto_tree_add_text(tree, pd_p_current, strlen(AsciiZ) + 1, "%s: %s", (Name) ? Name : "AsciiZ", AsciiZ); pd_p_current += strlen(AsciiZ) + 1; - break; + return 1; /* That's it here ... */ - case 'F': /* One or more pad bytes */ + } + + break; + + case 'F': /* One or more pad bytes */ + + if (dirn == 1) { bc = get_byte_count(pd); - proto_tree_add_text(tree, pd_p_current, bc, "Pad%u: %s", format_text(pd + pd_p_current, bc)); + proto_tree_add_text(tree, pd_p_current, bc, "%s%u: %s", (Name) ? Name : "Pad", bc, format_text(pd + pd_p_current, bc)); pd_p_current += bc; - break; + return 1; /* That's it here */ + + } + + break; + + case 'L': /* Receive buffer len: Short */ - case 'L': /* Receive buffer len: Short */ + if (dirn == 1) { WParam = GSHORT(pd, pd_p_current); - proto_tree_add_text(tree, pd_p_current, 2, "Word: %u", WParam); + proto_tree_add_text(tree, pd_p_current, 2, "%s: %u (%04X)", (Name) ? Name : "Receive Buffer Len", WParam, WParam); pd_p_current += 2; - break; + return 1; /* That's it here ... */ - case 's': /* Send buf ... */ + } + + break; + + case 's': /* Send buf ... */ + + if (dirn == 1) { need_data = 1; LParam = GWORD(pd, pd_p_current); - proto_tree_add_text(tree, pd_p_current, 4, "Buffer Ptr: %u", LParam); + proto_tree_add_text(tree, pd_p_current, 4, "%s: %u", (Name) ? Name : "Send Buffer Ptr", LParam); pd_p_current += 4; - break; + return 1; /* That's it here ... */ + + } + + break; + + case 'T': - case 'T': + if (dirn == 1) { WParam = GSHORT(pd, pd_p_current); - proto_tree_add_text(tree, pd_p_current, 2, "Buffer Len: %u", WParam); + proto_tree_add_text(tree, pd_p_current, 2, "%s: %u", (Name) ? Name : "Send Buffer Len", WParam); pd_p_current += 2; - break; - - default: - - break; + return 1; } break; - - case 1: /* We are in the data area ... */ - + + default: break; } + + break; + + case 1: /* We are in the data area ... */ + + + break; + } } + return 0; } @@ -9786,6 +9880,60 @@ void dissect_server_flags(proto_tree *tree, int offset, int length, int flags) } +/* + * The following data structure describes the LANMAN requests we understand + * + * Simply fill in the number, name, and parameter names if you know them + * Try to keep them in order + */ + +struct lanman_desc { + int lanman_num; + char *lanman_name; + char *params[10]; +}; + +struct lanman_desc lmd[] = { + {0, "NetShareEnum", + {"Detail Level", "Return Buffer Size", NULL}}, + {1, "NetShareGetInfo", + {"Share Name", "Detail Level", "Receive Buffer Size", NULL}}, + {13, "NetServerGetInfo", + {"Detail Level", "Receive Buffer Size", NULL}}, + {56, "NetUserGetInfo", + {"User Name", "Detail Level", "Receive Buffer Size", NULL}}, + {104, "NetServerEnum2", + {"Detail Level", "Return Buffer Size", "Server Type", "Domain", NULL}}, + {132, "NetWkstaUserLogon", + {"Reserved1", "Reserved2", "Detail Level", "UserInfoStruct?", "Length of UStruct", "Receive Buffer Size", NULL}}, + {133, "NetWkstaUserLogoff", + {"Reserved1", "Reserved2", "Detail Level", "UserInfoStruct?", "Length of UStruct", "Receive Buffer Size", NULL}}, + {-1, NULL, NULL} +}; + +struct lanman_desc * +find_lanman(int lanman_num) +{ + int i = 0; + + /* FIXME, This could be more efficient */ + + while (lmd[i].lanman_num != -1) { + + if (lmd[i].lanman_num == lanman_num) { + + return &lmd[i]; + + } + + i++; + + } + + return NULL; + +} + guint32 dissect_pipe_lanman(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn, const u_char *command, int DataOffset, int DataCount, int ParameterOffset, int ParameterCount) { @@ -9798,6 +9946,7 @@ dissect_pipe_lanman(const u_char *pd, int offset, frame_data *fd, proto_tree *pa const char *ReturnDescriptor; proto_tree *lanman_tree = NULL, *flags_tree = NULL; proto_item *ti; + struct lanman_desc *lanman; if (check_col(fd, COL_PROTOCOL)) col_add_fstr(fd, COL_PROTOCOL, "LANMAN"); @@ -9810,7 +9959,7 @@ dissect_pipe_lanman(const u_char *pd, int offset, frame_data *fd, proto_tree *pa switch (FunctionCode) { - case NETSHAREENUM: + case NETSHAREENUM + 10000: if (check_col(fd, COL_INFO)) { @@ -9881,7 +10030,7 @@ dissect_pipe_lanman(const u_char *pd, int offset, frame_data *fd, proto_tree *pa break; - case NETSERVERENUM2: /* Process a NetServerEnum2 */ + case NETSERVERENUM2 + 10000: /* Process a NetServerEnum2 */ if (check_col(fd, COL_INFO)) { @@ -9969,10 +10118,75 @@ dissect_pipe_lanman(const u_char *pd, int offset, frame_data *fd, proto_tree *pa return 1; break; - default: /* Just try to handle what is there ... */ + default: /* Just try to handle what is there ... */ + + lanman = find_lanman(FunctionCode); + + if (check_col(fd, COL_INFO)) { + + if (lanman) { + col_add_fstr(fd, COL_INFO, "%s Request", lanman -> lanman_name); + } + else { + col_add_fstr(fd, COL_INFO, "Unknown LANMAN Request: %u", FunctionCode); + } + } + + if (tree) { + + ti = proto_tree_add_item(parent, proto_lanman, SMB_offset + ParameterOffset, ParameterCount, NULL); + lanman_tree = proto_item_add_subtree(ti, ett_lanman); - dissect_transact_engine_init(pd, ParameterDescriptor, ReturnDescriptor, ParameterOffset, ParameterCount, DataOffset, DataCount); + if (lanman) { + proto_tree_add_text(lanman_tree, loc_offset, 2, "%s Request", lanman -> lanman_name); + } + else { + proto_tree_add_text(lanman_tree, loc_offset, 2, "Function Code: Unknown LANMAN Request: %u", FunctionCode); + } + } + + loc_offset += 2; + + ParameterDescriptor = pd + loc_offset; + + if (si.request_val -> last_param_descrip) g_free(si.request_val -> last_param_descrip); + si.request_val -> last_param_descrip = g_malloc(strlen(ParameterDescriptor) + 1); + if (si.request_val -> last_param_descrip) + strcpy(si.request_val -> last_param_descrip, ParameterDescriptor); + + if (tree) { + + proto_tree_add_text(lanman_tree, loc_offset, strlen(ParameterDescriptor) + 1, "Parameter Descriptor: %s", ParameterDescriptor); + + } + + loc_offset += strlen(ParameterDescriptor) + 1; + + ReturnDescriptor = pd + loc_offset; + + if (si.request_val -> last_data_descrip) g_free(si.request_val -> last_data_descrip); + si.request_val -> last_data_descrip = g_malloc(strlen(ReturnDescriptor) + 1); + if (si.request_val -> last_data_descrip) + strcpy(si.request_val -> last_data_descrip, ReturnDescriptor); + + if (tree) { + + proto_tree_add_text(lanman_tree, loc_offset, strlen(ReturnDescriptor) + 1, "Return Descriptor: %s", ReturnDescriptor); + + } + + loc_offset += strlen(ReturnDescriptor) + 1; + + if (tree) { + + int i = 0; + + dissect_transact_engine_init(pd, ParameterDescriptor, ReturnDescriptor,SMB_offset, loc_offset, ParameterCount, DataOffset, DataCount); + + while (dissect_transact_next(pd, (lanman) ? lanman -> params[i++] : NULL, dirn, lanman_tree)) + ; + } break; @@ -10166,10 +10380,6 @@ dissect_pipe_lanman(const u_char *pd, int offset, frame_data *fd, proto_tree *pa loc_offset += 2; - if (! BYTES_ARE_IN_FRAME(loc_offset, 26 * EntCount) ) { - return 1; - } - if (tree) { ti = proto_tree_add_text(lanman_tree, loc_offset, 26 * EntCount, "Servers"); |