* Routines for Universal Computer Protocol dissection
* Copyright 2001, Tom Uijldert <tom.uijldert@cmg.nl>
*
- * $Id: packet-ucp.c,v 1.14 2002/03/10 03:07:16 guy Exp $
+ * $Id$
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
#include <ctype.h>
#include <time.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-
#include <glib.h>
-#ifdef NEED_SNPRINTF_H
-# include "snprintf.h"
-#endif
-
#include <epan/packet.h>
/* #include "packet-ucp.h" */ /* We autoregister */
static int hf_ucp_parm_NoB = -1;
static int hf_ucp_parm_NAC = -1;
static int hf_ucp_parm_PNC = -1;
+static int hf_ucp_parm_AMsg = -1;
static int hf_ucp_parm_LNo = -1;
static int hf_ucp_parm_LST = -1;
static int hf_ucp_parm_TNo = -1;
/* Initialize the subtree pointers */
static gint ett_ucp = -1;
+static gint ett_sub = -1;
static gint ett_XSer = -1;
/*
length = tvb_find_guint8(tvb, offset, -1, UCP_ETX);
if (length == -1) {
+ /* XXX - should we have an option to request reassembly? */
*endpkt = tvb_reported_length_remaining(tvb, offset);
return UCP_SHORTENED;
}
if (length > (int) tvb_reported_length(tvb)) {
+ /* XXX - "cannot happen" */
*endpkt = 0;
return UCP_MALFORMED;
}
r_time.tm_mday = 10 * (datestr[0] - '0') + (datestr[1] - '0');
r_time.tm_mon = (10 * (datestr[2] - '0') + (datestr[3] - '0')) - 1;
r_time.tm_year = 10 * (datestr[4] - '0') + (datestr[5] - '0');
- if (r_time.tm_year < 90)
+ if (r_time.tm_year < 90)
r_time.tm_year += 100;
r_time.tm_hour = 10 * (datestr[6] - '0') + (datestr[7] - '0');
r_time.tm_min = 10 * (datestr[8] - '0') + (datestr[9] - '0');
if (datestr[10])
r_time.tm_sec = 10 * (datestr[10] - '0') + (datestr[11] - '0');
+ else
+ r_time.tm_sec = 0;
r_time.tm_isdst = -1;
return mktime(&r_time);
}
static void
ucp_handle_string(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
{
- char strval[BUFSIZ];
+ gint idx, len;
+
+ idx = tvb_find_guint8(tvb, *offset, -1, '/');
+ if (idx == -1) {
+ /* Force the appropriate exception to be thrown. */
+ len = tvb_length_remaining(tvb, *offset);
+ tvb_ensure_bytes_exist(tvb, *offset, len + 1);
+ } else
+ len = idx - *offset;
+ if (len > 0)
+ proto_tree_add_item(tree, field, tvb, *offset, len, FALSE);
+ *offset += len;
+ if (idx != -1)
+ *offset += 1; /* skip terminating '/' */
+}
+
+static void
+ucp_handle_IRAstring(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
+{
+ char strval[BUFSIZ + 1],
+ *p_dst = strval;
+ guint8 byte;
int idx = 0;
- int tmpoff = *offset;
+ int tmpoff = *offset;
- idx = 0;
- while ((strval[idx++] = tvb_get_guint8(tvb, tmpoff++)) != '/')
- ;
- if (idx > 1) {
- strval[--idx] = '\0';
- proto_tree_add_string(tree, field, tvb, *offset, idx, strval);
+ while (((byte = tvb_get_guint8(tvb, tmpoff++)) != '/') &&
+ (idx < BUFSIZ))
+ {
+ if (byte >= '0' && byte <= '9')
+ {
+ *p_dst = (byte - '0') * 16;
+ }
+ else
+ {
+ *p_dst = (byte - 'A' + 10) * 16;
+ }
+ if ((byte = tvb_get_guint8(tvb, tmpoff++)) == '/')
+ {
+ break;
+ }
+ if (byte >= '0' && byte <= '9')
+ {
+ *p_dst++ += byte - '0';
+ }
+ else
+ {
+ *p_dst++ += byte - 'A' + 10;
+ }
+ idx++;
}
+ strval[idx] = '\0';
+ if (idx == BUFSIZ)
+ {
+ /*
+ * Data clipped, eat rest of field
+ */
+ while ((tvb_get_guint8(tvb, tmpoff++)) != '/')
+ ;
+ }
+ if ((tmpoff - *offset) > 1)
+ proto_tree_add_string(tree, field, tvb, *offset,
+ tmpoff - *offset - 1, strval);
*offset = tmpoff;
}
static guint
ucp_handle_int(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
{
- char strval[BUFSIZ];
+ gint idx, len;
+ char *strval;
guint intval = 0;
- int tmpoff = *offset;
- int idx = 0;
-
- while ((strval[idx++] = tvb_get_guint8(tvb, tmpoff++)) != '/')
- ;
- if (idx > 1) {
- strval[--idx] = '\0';
+
+ idx = tvb_find_guint8(tvb, *offset, -1, '/');
+ if (idx == -1) {
+ /* Force the appropriate exception to be thrown. */
+ len = tvb_length_remaining(tvb, *offset);
+ tvb_ensure_bytes_exist(tvb, *offset, len + 1);
+ } else
+ len = idx - *offset;
+ strval = tvb_get_string(tvb, *offset, len);
+ if (len > 0) {
intval = atoi(strval);
proto_tree_add_uint(tree, field, tvb, *offset, idx, intval);
}
- *offset = tmpoff;
+ g_free(strval);
+ *offset += len;
+ if (idx != -1)
+ *offset += 1; /* skip terminating '/' */
return intval;
}
static void
ucp_handle_time(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
{
- char strval[BUFSIZ];
+ gint idx, len;
+ char *strval;
time_t tval;
nstime_t tmptime;
- int tmpoff = *offset;
- int idx = 0;
- while ((strval[idx++] = tvb_get_guint8(tvb, tmpoff++)) != '/')
- ;
- if (idx > 1) {
- strval[--idx] = '\0';
+ idx = tvb_find_guint8(tvb, *offset, -1, '/');
+ if (idx == -1) {
+ /* Force the appropriate exception to be thrown. */
+ len = tvb_length_remaining(tvb, *offset);
+ tvb_ensure_bytes_exist(tvb, *offset, len + 1);
+ } else
+ len = idx - *offset;
+ strval = tvb_get_string(tvb, *offset, len);
+ if (len > 0) {
tval = ucp_mktime(strval);
tmptime.secs = tval;
tmptime.nsecs = 0;
proto_tree_add_time(tree, field, tvb, *offset, idx, &tmptime);
}
- *offset = tmpoff;
+ g_free(strval);
+ *offset += len;
+ if (idx != -1)
+ *offset += 1; /* skip terminating '/' */
}
static void
while (tvb_get_guint8(tvb, tmpoff++) != '/')
;
- if ((tmpoff - *offset) > 1)
+ if ((tmpoff - *offset) > 1)
proto_tree_add_item(tree, field, tvb, *offset,
tmpoff - *offset - 1, FALSE);
*offset = tmpoff;
static void
ucp_handle_mt(proto_tree *tree, tvbuff_t *tvb, int *offset)
{
- char strval[BUFSIZ];
guint intval;
- int idx;
intval = ucp_handle_byte(tree, tvb, hf_ucp_parm_MT, offset);
switch (intval) {
ucp_handle_string(tree, tvb, hf_ucp_parm_NB, offset);
/* fall through here for the data piece */
case '2':
- case '3':
ucp_handle_data(tree, tvb, hf_ucp_data_section, offset);
break;
+ case '3':
+ ucp_handle_IRAstring(tree, tvb, hf_ucp_parm_AMsg, offset);
+ break;
case '5':
ucp_handle_byte(tree, tvb, hf_ucp_parm_PNC, offset);
ucp_handle_string(tree, tvb, hf_ucp_parm_LNo, offset);
*/
#define UcpHandleString(field) ucp_handle_string(tree, tvb, (field), &offset)
+#define UcpHandleIRAString(field) \
+ ucp_handle_IRAstring(tree, tvb, (field), &offset)
+
#define UcpHandleByte(field) ucp_handle_byte(tree, tvb, (field), &offset)
#define UcpHandleInt(field) ucp_handle_int(tree, tvb, (field), &offset)
UcpHandleByte(hf_ucp_parm_Dst);
UcpHandleInt(hf_ucp_parm_Rsn);
UcpHandleTime(hf_ucp_parm_DSCTS);
- UcpHandleByte(hf_ucp_parm_MT);
+ intval = UcpHandleByte(hf_ucp_parm_MT);
UcpHandleString(hf_ucp_parm_NB);
- UcpHandleData(hf_ucp_data_section);
+ if (intval != '3')
+ UcpHandleData(hf_ucp_data_section);
+ else
+ UcpHandleIRAString(hf_ucp_parm_AMsg);
UcpHandleByte(hf_ucp_parm_MMS);
UcpHandleByte(hf_ucp_parm_PR);
UcpHandleByte(hf_ucp_parm_DCs);
} else {
UcpHandleByte(hf_ucp_parm_STYP1);
}
- UcpHandleData(hf_ucp_parm_PWD);
- UcpHandleData(hf_ucp_parm_NPWD);
+ UcpHandleIRAString(hf_ucp_parm_PWD);
+ UcpHandleIRAString(hf_ucp_parm_NPWD);
UcpHandleString(hf_ucp_parm_VERS);
UcpHandleString(hf_ucp_parm_LAdC);
UcpHandleByte(hf_ucp_parm_LTON);
* End of convenient shorthands
*/
#undef UcpHandleString
+#undef UcpHandleIRAString
#undef UcpHandleByte
#undef UcpHandleInt
#undef UcpHandleTime
return FALSE;
/*
- * Try getting the operation-type and whether it's a request/response
+ * Try getting the operation-type and whether it's a request/response
*/
O_R = tvb_get_guint8(tvb, UCP_O_R_OFFSET);
if (match_strval(O_R, vals_hdr_O_R) == NULL)
proto_item *ti;
proto_item *sub_ti;
proto_tree *ucp_tree;
+ proto_tree *sub_tree;
tvbuff_t *tmp_tvb;
O_R = tvb_get_guint8(tvb, UCP_O_R_OFFSET);
tmp_tvb = tvb_new_subset(tvb, offset, -1, -1);
sub_ti = proto_tree_add_item(ucp_tree, hf_ucp_oper_section, tvb,
offset, endpkt - offset, FALSE);
+ sub_tree = proto_item_add_subtree(sub_ti, ett_sub);
switch (OT) {
+ case 0:
+ O_R == 'O' ? add_00O(sub_tree,tmp_tvb) : add_00R(sub_tree,tmp_tvb);
+ break;
case 1:
- O_R == 'O' ? add_01O(sub_ti,tmp_tvb) : add_01R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_01O(sub_tree,tmp_tvb) : add_01R(sub_tree,tmp_tvb);
break;
case 2:
- O_R == 'O' ? add_02O(sub_ti,tmp_tvb) : add_02R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_02O(sub_tree,tmp_tvb) : add_02R(sub_tree,tmp_tvb);
break;
case 3:
- O_R == 'O' ? add_03O(sub_ti,tmp_tvb) : add_03R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_03O(sub_tree,tmp_tvb) : add_03R(sub_tree,tmp_tvb);
break;
case 4:
- O_R == 'O' ? add_04O(sub_ti,tmp_tvb) : add_04R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_04O(sub_tree,tmp_tvb) : add_04R(sub_tree,tmp_tvb);
break;
case 5:
- O_R == 'O' ? add_05O(sub_ti,tmp_tvb) : add_05R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_05O(sub_tree,tmp_tvb) : add_05R(sub_tree,tmp_tvb);
break;
case 6:
- O_R == 'O' ? add_06O(sub_ti,tmp_tvb) : add_06R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_06O(sub_tree,tmp_tvb) : add_06R(sub_tree,tmp_tvb);
break;
case 7:
- O_R == 'O' ? add_07O(sub_ti,tmp_tvb) : add_07R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_07O(sub_tree,tmp_tvb) : add_07R(sub_tree,tmp_tvb);
break;
case 8:
- O_R == 'O' ? add_08O(sub_ti,tmp_tvb) : add_08R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_08O(sub_tree,tmp_tvb) : add_08R(sub_tree,tmp_tvb);
break;
case 9:
- O_R == 'O' ? add_09O(sub_ti,tmp_tvb) : add_09R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_09O(sub_tree,tmp_tvb) : add_09R(sub_tree,tmp_tvb);
break;
case 10:
- O_R == 'O' ? add_10O(sub_ti,tmp_tvb) : add_10R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_10O(sub_tree,tmp_tvb) : add_10R(sub_tree,tmp_tvb);
break;
case 11:
- O_R == 'O' ? add_11O(sub_ti,tmp_tvb) : add_11R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_11O(sub_tree,tmp_tvb) : add_11R(sub_tree,tmp_tvb);
break;
case 12:
- O_R == 'O' ? add_12O(sub_ti,tmp_tvb) : add_12R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_12O(sub_tree,tmp_tvb) : add_12R(sub_tree,tmp_tvb);
break;
case 13:
- O_R == 'O' ? add_13O(sub_ti,tmp_tvb) : add_13R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_13O(sub_tree,tmp_tvb) : add_13R(sub_tree,tmp_tvb);
break;
case 14:
- O_R == 'O' ? add_14O(sub_ti,tmp_tvb) : add_14R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_14O(sub_tree,tmp_tvb) : add_14R(sub_tree,tmp_tvb);
break;
case 15:
- O_R == 'O' ? add_15O(sub_ti,tmp_tvb) : add_15R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_15O(sub_tree,tmp_tvb) : add_15R(sub_tree,tmp_tvb);
break;
case 16:
- O_R == 'O' ? add_16O(sub_ti,tmp_tvb) : add_16R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_16O(sub_tree,tmp_tvb) : add_16R(sub_tree,tmp_tvb);
break;
case 17:
- O_R == 'O' ? add_17O(sub_ti,tmp_tvb) : add_17R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_17O(sub_tree,tmp_tvb) : add_17R(sub_tree,tmp_tvb);
break;
case 18:
- O_R == 'O' ? add_18O(sub_ti,tmp_tvb) : add_18R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_18O(sub_tree,tmp_tvb) : add_18R(sub_tree,tmp_tvb);
break;
case 19:
- O_R == 'O' ? add_19O(sub_ti,tmp_tvb) : add_19R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_19O(sub_tree,tmp_tvb) : add_19R(sub_tree,tmp_tvb);
break;
case 20:
- O_R == 'O' ? add_20O(sub_ti,tmp_tvb) : add_20R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_20O(sub_tree,tmp_tvb) : add_20R(sub_tree,tmp_tvb);
break;
case 21:
- O_R == 'O' ? add_21O(sub_ti,tmp_tvb) : add_21R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_21O(sub_tree,tmp_tvb) : add_21R(sub_tree,tmp_tvb);
break;
case 22:
- O_R == 'O' ? add_22O(sub_ti,tmp_tvb) : add_22R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_22O(sub_tree,tmp_tvb) : add_22R(sub_tree,tmp_tvb);
break;
case 23:
- O_R == 'O' ? add_23O(sub_ti,tmp_tvb) : add_23R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_23O(sub_tree,tmp_tvb) : add_23R(sub_tree,tmp_tvb);
break;
case 24:
- O_R == 'O' ? add_24O(sub_ti,tmp_tvb) : add_24R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_24O(sub_tree,tmp_tvb) : add_24R(sub_tree,tmp_tvb);
break;
case 30:
- O_R == 'O' ? add_30O(sub_ti,tmp_tvb) : add_30R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_30O(sub_tree,tmp_tvb) : add_30R(sub_tree,tmp_tvb);
break;
case 31:
- O_R == 'O' ? add_31O(sub_ti,tmp_tvb) : add_31R(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_31O(sub_tree,tmp_tvb) : add_31R(sub_tree,tmp_tvb);
break;
case 51: case 52: case 53: case 54: case 55: case 56: case 57:
case 58:
- O_R == 'O' ? add_5xO(sub_ti,tmp_tvb) : add_5xR(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_5xO(sub_tree,tmp_tvb) : add_5xR(sub_tree,tmp_tvb);
break;
case 60: case 61:
- O_R == 'O' ? add_6xO(sub_ti,tmp_tvb,OT) : add_6xR(sub_ti,tmp_tvb);
+ O_R == 'O' ? add_6xO(sub_tree,tmp_tvb,OT) : add_6xR(sub_tree,tmp_tvb);
break;
default:
break;
HFILL
}
},
+ { &hf_ucp_parm_AMsg,
+ { "AMsg", "ucp.parm.AMsg",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "The alphanumeric message that is being sent.",
+ HFILL
+ }
+ },
{ &hf_ucp_parm_LNo,
{ "LNo", "ucp.parm.LNo",
FT_STRING, BASE_NONE, NULL, 0x00,
},
{ &hf_ucp_parm_R_T,
{ "R_T", "ucp.parm.R_T",
- FT_STRING, BASE_NONE, NULL, 0x00,
+ FT_UINT8, BASE_DEC, VALS(vals_parm_R_T), 0x00,
"Message number.",
HFILL
}
},
{ &hf_ucp_parm_PWD,
{ "PWD", "ucp.parm.PWD",
- FT_NONE, BASE_DEC, NULL, 0x00,
+ FT_STRING, BASE_NONE, NULL, 0x00,
"Current password.",
HFILL
}
},
{ &hf_ucp_parm_NPWD,
{ "NPWD", "ucp.parm.NPWD",
- FT_NONE, BASE_DEC, NULL, 0x00,
+ FT_STRING, BASE_NONE, NULL, 0x00,
"New password.",
HFILL
}
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_ucp,
+ &ett_sub,
&ett_XSer
};
/* Register the protocol name and description */