ncp2222: Use BASE_CUSTOM for date and time fields.

This simplifies some of the logic required for field formatting.

Change-Id: I2f9a612b18e3e4ca01311683d9cf61cbad9950f4
Reviewed-on: https://code.wireshark.org/review/10649
Petri-Dish: Michael Mann <mmann78@netscape.net>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Michael Mann 2015-09-25 10:09:07 -04:00
parent a4a453b13d
commit 3b04a89828
3 changed files with 40 additions and 198 deletions

View File

@ -49,7 +49,6 @@ struct _ptvc_record {
unsigned int var_index : 2;
unsigned int repeat_index : 2;
unsigned int req_cond_index : 8;
unsigned int special_fmt : 2;
};
/*
@ -63,11 +62,6 @@ struct ncp_common_header {
guint8 conn_high; /* type=0x5555 doesn't have this */
};
#define NCP_FMT_NONE 0
#define NCP_FMT_NW_DATE 1
#define NCP_FMT_NW_TIME 2
#define NCP_FMT_UNICODE 3
extern gboolean nds_defragment;
extern gboolean nds_echo_eid;
extern gboolean ncp_echo_err;

View File

@ -2277,36 +2277,6 @@ ncp_record_find(guint8 func, guint8 subfunc)
return NULL;
}
typedef proto_item* (*padd_func_t)(packet_info* pinfo, ptvcursor_t*, const ptvc_record*, gboolean request, gboolean repeat, guint* ret_value);
/*
* XXX - are these just DOS-format dates and times?
*
* Should we put code to understand various date and time formats (UNIX,
* DOS, SMB weird mutant UNIX, NT, Mac, etc. into libwireshark, and have
* the "display" member of an HF_ABSOLUTE_TIME field specify whether
* it's DOS date/DOS time, DOS time/DOS date, NT time, UNIX time_t,
* UNIX "struct timeval", NFSv3/NFSv4 seconds/nanoseconds, Mac, etc.?
*
* What about hijacking the "bitmask" field to specify the precision of
* the time stamp, or putting a combination of precision and format
* into the "display" member?
*
* What about relative times? Should they have units (seconds, milliseconds,
* microseconds, nanoseconds, etc.), precision, and format in there?
*/
typedef struct {
guint year;
guint month;
guint day;
} nw_date_t;
typedef struct {
guint hour;
guint minute;
guint second;
} nw_time_t;
#define NW_UNI_MAX 1024
#define VTYPE_NONE 0 /* no value */
@ -2384,28 +2354,8 @@ typedef struct {
guint32 pflags; /* NDS Protocol Flags */
} nds_val;
/* Given an integer, fill in a nw_date_t struct. */
static void
uint_to_nwdate(guint data, nw_date_t *nwdate)
{
nwdate->day = data & 0x001f;
nwdate->month = (data & 0x01e0) >> 5;
nwdate->year = ((data & 0xfe00) >> 9) + 1980;
}
/* Given an integer, fill in a nw_time_t struct. */
static void
uint_to_nwtime(guint data, nw_time_t *nwtime)
{
/* 2-second resolution */
nwtime->second = (data & 0x001f) * 2;
nwtime->minute = ((data & 0x07e0) >> 5);
nwtime->hour = ((data & 0xf800) >> 11);
}
static proto_item*
padd_normal(packet_info* pinfo, ptvcursor_t *ptvc, const ptvc_record *rec, gboolean request, gboolean repeat, guint* ret_value)
add_ptvc_field(packet_info* pinfo, ptvcursor_t *ptvc, const ptvc_record *rec, gboolean request, gboolean repeat, guint* ret_value)
{
header_field_info* hinfo = proto_registrar_get_nth(*rec->hf_ptr);
@ -2515,96 +2465,32 @@ padd_normal(packet_info* pinfo, ptvcursor_t *ptvc, const ptvc_record *rec, gbool
rec->endianness);
}
/* XXX - This could be a BASE_CUSTOM extension to the hf_ fields that use it */
static proto_item*
padd_date(packet_info* pinfo _U_, ptvcursor_t *ptvc, const ptvc_record *rec, gboolean request _U_, gboolean repeat _U_, guint* ret_value)
/*
* XXX - are these just DOS-format dates and times?
*
* Should we put code to understand various date and time formats (UNIX,
* DOS, SMB weird mutant UNIX, NT, Mac, etc. into libwireshark, and have
* the "display" member of an HF_ABSOLUTE_TIME field specify whether
* it's DOS date/DOS time, DOS time/DOS date, NT time, UNIX time_t,
* UNIX "struct timeval", NFSv3/NFSv4 seconds/nanoseconds, Mac, etc.?
*
* What about hijacking the "bitmask" field to specify the precision of
* the time stamp, or putting a combination of precision and format
* into the "display" member?
*
* What about relative times? Should they have units (seconds, milliseconds,
* microseconds, nanoseconds, etc.), precision, and format in there?
*/
static void
padd_date( gchar *result, guint32 date_value )
{
proto_item *item;
nw_date_t nw_date;
switch(rec->length)
{
case 1:
*ret_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
break;
case 2:
*ret_value = tvb_get_guint16(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
break;
case 3:
*ret_value = tvb_get_guint24(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
break;
case 4:
*ret_value = tvb_get_guint32(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
break;
default:
DISSECTOR_ASSERT(FALSE);
}
uint_to_nwdate(*ret_value, &nw_date);
item = proto_tree_add_uint_format_value(ptvcursor_tree(ptvc), *rec->hf_ptr, ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc),
rec->length, *ret_value, "%04u/%02u/%02u", nw_date.year, nw_date.month, nw_date.day);
ptvcursor_advance(ptvc, rec->length);
return item;
g_snprintf( result, ITEM_LABEL_LENGTH, "%04u/%02u/%02u", ((date_value & 0xfe00) >> 9) + 1980, (date_value & 0x01e0) >> 5, date_value & 0x001f);
}
/* XXX - This could be a BASE_CUSTOM extension to the hf_ fields that use it */
static proto_item*
padd_time(packet_info* pinfo _U_, ptvcursor_t *ptvc, const ptvc_record *rec, gboolean request _U_, gboolean repeat _U_, guint* ret_value)
static void
padd_time( gchar *result, guint32 time_value )
{
proto_item *item;
nw_time_t nw_time;
switch(rec->length)
{
case 1:
*ret_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
break;
case 2:
*ret_value = tvb_get_guint16(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
break;
case 3:
*ret_value = tvb_get_guint24(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
break;
case 4:
*ret_value = tvb_get_guint32(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
break;
default:
DISSECTOR_ASSERT(FALSE);
}
uint_to_nwtime(*ret_value, &nw_time);
item = proto_tree_add_uint_format_value(ptvcursor_tree(ptvc), *rec->hf_ptr, ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc),
rec->length, *ret_value, "%02u:%02u:%02u", nw_time.hour, nw_time.minute, nw_time.second);
ptvcursor_advance(ptvc, rec->length);
return item;
}
/* Convert a string from little-endian unicode to ascii. At the moment we
fake it by taking every odd byte. )-: The caller must free the
result returned. */
/* XXX This prints the proto_item name, but not its value. */
static proto_item*
padd_uni(packet_info* pinfo _U_, ptvcursor_t *ptvc, const ptvc_record *rec, gboolean request _U_, gboolean repeat _U_, guint* ret_value _U_)
{
proto_item *item;
/* nw_uni_t nw_uni; */
/* nw_uni.buffer[0] = '\0'; */
item = ptvcursor_add(ptvc, *rec->hf_ptr,
rec->length,
rec->endianness);
/* if (item) {
proto_item_set_text(item, "%s", get_item_name(item));
proto_item_append_text(item, " %s",
nw_uni.buffer);
}
*/
return item;
g_snprintf( result, ITEM_LABEL_LENGTH, "%02u:%02u:%02u", ((time_value & 0xf800) >> 11), ((time_value & 0x07e0) >> 5), (time_value & 0x001f) * 2);
}
/* Add a value for a ptvc_record, and process the sub-ptvc_record
@ -2702,7 +2588,6 @@ _process_ptvc_record(ptvcursor_t *ptvc, packet_info *pinfo, const ptvc_record *r
const ncp_record *ncp_rec, gboolean request)
{
guint i, repeat_count, repeat_value;
padd_func_t func = NULL;
if (rec->sub_ptvc_rec) {
/* Repeat this? */
@ -2737,25 +2622,8 @@ _process_ptvc_record(ptvcursor_t *ptvc, packet_info *pinfo, const ptvc_record *r
* to set a 'var'. */
if (rec->repeat_index == NO_REPEAT) {
if (really_decode) {
/* Handle any special formatting. */
switch(rec->special_fmt) {
case NCP_FMT_NONE:
func = padd_normal;
break;
case NCP_FMT_NW_DATE:
func = padd_date;
break;
case NCP_FMT_NW_TIME:
func = padd_time;
break;
case NCP_FMT_UNICODE:
func = padd_uni;
break;
default:
DISSECTOR_ASSERT_NOT_REACHED();
}
repeat_value = 0;
func(pinfo, ptvc, rec, request, FALSE, &repeat_value);
add_ptvc_field(pinfo, ptvc, rec, request, FALSE, &repeat_value);
/* Set the value as a 'var' ? */
if (rec->var_index != NO_VAR) {
@ -2781,25 +2649,8 @@ _process_ptvc_record(ptvcursor_t *ptvc, packet_info *pinfo, const ptvc_record *r
/* We do repeat this field. */
repeat_count = repeat_vars[rec->repeat_index];
if (really_decode) {
/* Handle any special formatting. */
switch(rec->special_fmt) {
case NCP_FMT_NONE:
func = padd_normal;
break;
case NCP_FMT_NW_DATE:
func = padd_date;
break;
case NCP_FMT_NW_TIME:
func = padd_time;
break;
case NCP_FMT_UNICODE:
func = padd_uni;
break;
default:
DISSECTOR_ASSERT_NOT_REACHED();
}
for (i = 0; i < repeat_count; i++ ) {
func(pinfo, ptvc, rec, request, i != 0, &repeat_value);
add_ptvc_field(pinfo, ptvc, rec, request, i != 0, &repeat_value);
}
}
else {

View File

@ -278,7 +278,7 @@ class PTVC(NamedList):
x = "static const ptvc_record %s[] = {\n" % (self.Name())
for ptvc_rec in self.list:
x = x + " %s,\n" % (ptvc_rec.Code())
x = x + " { NULL, 0, NULL, NULL, NO_ENDIANNESS, NO_VAR, NO_REPEAT, NO_REQ_COND, NCP_FMT_NONE }\n"
x = x + " { NULL, 0, NULL, NULL, NO_ENDIANNESS, NO_VAR, NO_REPEAT, NO_REQ_COND }\n"
x = x + "};\n"
return x
@ -305,7 +305,7 @@ class PTVCBitfield(PTVC):
x = x + "static const ptvc_record ptvc_%s[] = {\n" % (self.Name())
for ptvc_rec in self.list:
x = x + " %s,\n" % (ptvc_rec.Code())
x = x + " { NULL, 0, NULL, NULL, NO_ENDIANNESS, NO_VAR, NO_REPEAT, NO_REQ_COND, NCP_FMT_NONE }\n"
x = x + " { NULL, 0, NULL, NULL, NO_ENDIANNESS, NO_VAR, NO_REPEAT, NO_REQ_COND }\n"
x = x + "};\n"
x = x + "static const sub_ptvc_record %s = {\n" % (self.Name(),)
@ -402,10 +402,9 @@ class PTVCRecord:
else:
req_info_str = "NULL"
return "{ &%s, %s, %s, %s, %s, %s, %s, %s, %s }" % \
return "{ &%s, %s, %s, %s, %s, %s, %s, %s }" % \
(self.field.HFName(), length, sub_ptvc_name,
req_info_str, endianness, var, repeat, req_cond,
self.field.SpecialFmt())
req_info_str, endianness, var, repeat, req_cond)
def Offset(self):
return self.offset
@ -751,6 +750,7 @@ class Type:
type = "Type"
ftype = None
disp = "BASE_DEC"
custom_func = None
endianness = NA
values = []
@ -760,7 +760,6 @@ class Type:
self.bytes = bytes
self.endianness = endianness
self.hfname = "hf_ncp_" + self.abbrev
self.special_fmt = "NCP_FMT_NONE"
def Length(self):
return self.bytes
@ -786,7 +785,10 @@ class Type:
return self.disp
def ValuesName(self):
return "NULL"
if self.custom_func:
return "CF_FUNC(" + self.custom_func + ")"
else:
return "NULL"
def Mask(self):
return 0
@ -801,16 +803,12 @@ class Type:
return "NULL"
def NWDate(self):
self.special_fmt = "NCP_FMT_NW_DATE"
self.disp = "BASE_CUSTOM"
self.custom_func = "padd_date"
def NWTime(self):
self.special_fmt = "NCP_FMT_NW_TIME"
def NWUnicode(self):
self.special_fmt = "NCP_FMT_UNICODE"
def SpecialFmt(self):
return self.special_fmt
self.disp = "BASE_CUSTOM"
self.custom_func = "padd_time"
#def __cmp__(self, other):
# return cmp(self.hfname, other.hfname)
@ -857,7 +855,7 @@ class struct(PTVC, Type):
return vars
def ReferenceString(self, var, repeat, req_cond):
return "{ PTVC_STRUCT, NO_LENGTH, &%s, NULL, NO_ENDIANNESS, %s, %s, %s, NCP_FMT_NONE }" % \
return "{ PTVC_STRUCT, NO_LENGTH, &%s, NULL, NO_ENDIANNESS, %s, %s, %s }" % \
(self.name, var, repeat, req_cond)
def Code(self):
@ -866,7 +864,7 @@ class struct(PTVC, Type):
x = x + "static const ptvc_record ptvc_%s[] = {\n" % (self.name,)
for ptvc_rec in self.list:
x = x + " %s,\n" % (ptvc_rec.Code())
x = x + " { NULL, NO_LENGTH, NULL, NULL, NO_ENDIANNESS, NO_VAR, NO_REPEAT, NO_REQ_COND, NCP_FMT_NONE }\n"
x = x + " { NULL, NO_LENGTH, NULL, NULL, NO_ENDIANNESS, NO_VAR, NO_REPEAT, NO_REQ_COND }\n"
x = x + "};\n"
x = x + "static const sub_ptvc_record %s = {\n" % (self.name,)
@ -3950,7 +3948,6 @@ TransportType = val_string8("transport_type", "Communications
])
TreeLength = uint32("tree_length", "Tree Length")
TreeName = nstring32("tree_name", "Tree Name")
TreeName.NWUnicode()
TrusteeAccessMask = uint8("trustee_acc_mask", "Trustee Access Mask")
TrusteeRights = bitfield16("trustee_rights_low", "Trustee Rights", [
bf_boolean16(0x0001, "trustee_rights_read", "Read"),