/* Dissect OSC packet */ static void dissect_osc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "OSC"); /* clear out stuff in the info column */ col_clear(pinfo->cinfo, COL_INFO); if(tree) /* we are being asked for details */ { gint len; proto_item *ti = NULL; proto_tree *osc_tree = NULL; /* create OSC packet */ ti = proto_tree_add_item(tree, proto_osc, tvb, 0, -1, ENC_NA); osc_tree = proto_item_add_subtree(ti, ett_osc_packet); len = proto_item_get_len(ti); /* peek first bundle element char */ switch(tvb_get_guint8(tvb, offset)) { case '#': /* this is a bundle */ if(dissect_osc_bundle(tvb, ti, osc_tree, offset, len)) return; else break; case '/': /* this is a message */ if(dissect_osc_message(tvb, ti, osc_tree, offset, len)) return; else break; default: /* neither message nor bundle */ return; } } }
/* Dissect OSC bundle */ static int dissect_osc_bundle(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len) { proto_tree *bundle_tree; gint end = offset + len; guint32 sec; guint32 frac; nstime_t ns; /* check for valid #bundle */ if(tvb_strneql(tvb, offset, bundle_str, 8) != 0) return -1; /* create bundle */ ti = proto_tree_add_item(osc_tree, hf_osc_bundle_type, tvb, offset, len, ENC_NA); bundle_tree = proto_item_add_subtree(ti, ett_osc_bundle); offset += 8; /* skip bundle_str */ /* read timetag */ sec = tvb_get_ntohl(tvb, offset); frac = tvb_get_ntohl(tvb, offset+4); if( (sec == 0) && (frac == 1) ) proto_tree_add_time_format_value(bundle_tree, hf_osc_bundle_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str); else proto_tree_add_item(bundle_tree, hf_osc_bundle_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN); offset += 8; /* ::read size, read block:: */ while(offset < end) { /* peek bundle element size */ gint32 size = tvb_get_ntohl(tvb, offset); /* read bundle element size */ proto_tree_add_int_format_value(bundle_tree, hf_osc_bundle_element_size_type, tvb, offset, 4, size, "%i bytes", size); offset += 4; /* check for zero size bundle element */ if(size == 0) continue; /* peek first bundle element char */ switch(tvb_get_guint8(tvb, offset)) { case '#': /* this is a bundle */ if(dissect_osc_bundle(tvb, ti, bundle_tree, offset, size)) return -1; else break; case '/': /* this is a message */ if(dissect_osc_message(tvb, ti, bundle_tree, offset, size)) return -1; else break; default: return -1; /* neither message nor bundle */ } /* check for integer overflow */ if(size > G_MAXINT - offset) return -1; else offset += size; } if(offset != end) return -1; else return 0; }