1 /* Routines for 'Metadata' disassembly 2 * 3 * Wireshark - Network traffic analyzer 4 * By Gerald Combs <gerald@wireshark.org> 5 * Copyright 1998 Gerald Combs 6 * 7 * SPDX-License-Identifier: GPL-2.0-or-later 8 */ 9 10 #include "config.h" 11 12 13 #include <epan/packet.h> 14 #include <wiretap/wtap.h> 15 #include <epan/expert.h> 16 #include <epan/proto_data.h> 17 #include "packet-sscop.h" 18 #include "packet-gsm_a_common.h" 19 20 void proto_register_meta(void); 21 void proto_reg_handoff_meta(void); 22 23 /* schemas */ 24 #define META_SCHEMA_PCAP 1 25 #define META_SCHEMA_DXT 2 26 27 /* protocols */ 28 #define META_PROTO_DXT_ETHERNET 1 29 #define META_PROTO_DXT_ETHERNET_CRC 36 30 #define META_PROTO_DXT_ATM 41 31 #define META_PROTO_DXT_ERF_AAL5 49 32 #define META_PROTO_DXT_M3UA 61 33 #define META_PROTO_DXT_NBAP 69 34 #define META_PROTO_DXT_ATM_AAL2 76 35 #define META_PROTO_DXT_FP_HINT 82 36 #define META_PROTO_DXT_HDLC 106 37 #define META_PROTO_DXT_CONTAINER 127 38 #define META_PROTO_DXT_FP_CAPTURE 193 39 #define META_PROTO_DXT_UTRAN_CAPSULE 194 40 41 /* data types */ 42 #define META_TYPE_NONE 0 43 #define META_TYPE_BOOLEAN 1 44 #define META_TYPE_UINT8 2 45 #define META_TYPE_UINT16 3 46 #define META_TYPE_UINT32 4 47 #define META_TYPE_UINT64 5 48 #define META_TYPE_STRING 16 49 50 /* item ids */ 51 #define META_ID_NULL 0 52 #define META_ID_DIRECTION 1 53 #define META_ID_SIGNALING 2 54 #define META_ID_INCOMPLETE 3 55 #define META_ID_DECIPHERED 4 56 #define META_ID_PAYLOADCUT 5 57 #define META_ID_TIMESTAMP64 6 58 #define META_ID_AAL5PROTO 7 59 #define META_ID_PHYLINKID 256 60 #define META_ID_LOCALDEVID 257 61 #define META_ID_REMOTEDEVID 258 62 #define META_ID_TAPGROUPID 259 63 #define META_ID_IMSI 1024 64 #define META_ID_IMEI 1025 65 #define META_ID_CELL 1026 66 #define META_ID_TLLI 1027 67 #define META_ID_NSAPI 1028 68 #define META_ID_APN 1029 69 #define META_ID_RAT 1030 70 #define META_ID_CALLING 1031 71 #define META_ID_CALLED 1032 72 73 enum meta_direction { 74 META_DIR_UP, 75 META_DIR_DOWN 76 }; 77 78 static int proto_meta = -1; 79 extern int proto_sscop; 80 81 /* fields */ 82 static int hf_meta_schema = -1; 83 static int hf_meta_hdrlen = -1; 84 static int hf_meta_proto = -1; 85 static int hf_meta_reserved = -1; 86 static int hf_meta_item = -1; 87 static int hf_meta_item_id = -1; 88 static int hf_meta_item_type = -1; 89 static int hf_meta_item_len = -1; 90 static int hf_meta_item_data = -1; 91 /* specific fields */ 92 static int hf_meta_item_direction = -1; 93 static int hf_meta_item_ts = -1; 94 static int hf_meta_item_phylinkid = -1; 95 static int hf_meta_item_nsapi = -1; 96 static int hf_meta_item_imsi_value = -1; 97 static int hf_meta_item_imsi_digits = -1; 98 static int hf_meta_item_imei_value = -1; 99 static int hf_meta_item_imei_digits = -1; 100 static int hf_meta_item_signaling = -1; 101 static int hf_meta_item_incomplete = -1; 102 static int hf_meta_item_deciphered = -1; 103 static int hf_meta_item_apn = -1; 104 static int hf_meta_item_rat = -1; 105 static int hf_meta_item_aal5proto = -1; 106 static int hf_meta_item_cell = -1; 107 static int hf_meta_item_localdevid = -1; 108 static int hf_meta_item_remotedevid = -1; 109 static int hf_meta_item_tapgroupid = -1; 110 static int hf_meta_item_tlli = -1; 111 static int hf_meta_item_calling = -1; 112 static int hf_meta_item_called = -1; 113 114 /* subtrees */ 115 static gint ett_meta = -1; 116 static gint ett_meta_item = -1; 117 static gint ett_meta_cell = -1; 118 static gint ett_meta_imsi = -1; 119 static gint ett_meta_imei = -1; 120 121 static expert_field ei_meta_malformed = EI_INIT; 122 static expert_field ei_meta_invalid_header = EI_INIT; 123 124 /* default handle */ 125 static dissector_handle_t data_handle; 126 static dissector_handle_t atm_untrunc_handle; 127 static dissector_handle_t sscf_nni_handle; 128 static dissector_handle_t alcap_handle; 129 static dissector_handle_t nbap_handle; 130 static dissector_handle_t ethwithfcs_handle; 131 static dissector_handle_t ethwithoutfcs_handle; 132 static dissector_handle_t fphint_handle; 133 static dissector_handle_t mtp2_handle; 134 135 static dissector_table_t meta_dissector_table; 136 137 static const value_string meta_schema_vals[] = { 138 { META_SCHEMA_PCAP, "PCAP" }, 139 { META_SCHEMA_DXT, "DXT" }, 140 { 0, NULL } 141 }; 142 143 static const value_string meta_proto_vals[] = { 144 { META_PROTO_DXT_ETHERNET, "Ethernet without FCS" }, 145 { META_PROTO_DXT_ETHERNET_CRC, "Ethernet with FCS" }, 146 { META_PROTO_DXT_ATM, "ATM" }, 147 { META_PROTO_DXT_ERF_AAL5, "ERF AAL5" }, 148 /* XXX: META_PROTO_DXT_M3UA ? */ 149 /* XXX: META_PROTO_DXT_NBAP ? */ 150 { META_PROTO_DXT_ATM_AAL2, "ATM AAL2" }, 151 { META_PROTO_DXT_FP_HINT, "FP Hint" }, 152 { META_PROTO_DXT_HDLC, "HDLC" }, 153 { META_PROTO_DXT_CONTAINER, "DXT CONTAINER" }, 154 { META_PROTO_DXT_FP_CAPTURE, "FP CAPTURE" }, 155 { META_PROTO_DXT_UTRAN_CAPSULE, "UTRAN CAPSULE" }, 156 { 0, NULL } 157 }; 158 static value_string_ext meta_proto_vals_ext = VALUE_STRING_EXT_INIT(meta_proto_vals); 159 160 static const value_string meta_type_vals[] = { 161 { META_TYPE_NONE, "NONE" }, 162 { META_TYPE_BOOLEAN, "BOOLEAN" }, 163 { META_TYPE_UINT8, "UINT8" }, 164 { META_TYPE_UINT16, "UINT16" }, 165 { META_TYPE_UINT32, "UINT32" }, 166 { META_TYPE_UINT64, "UINT64" }, 167 { META_TYPE_STRING, "STRING" }, 168 { 0, NULL } 169 }; 170 171 /* TODO: this must be on a per-schema basis! */ 172 static const value_string meta_id_vals[] = { 173 { META_ID_NULL, "NULL" }, 174 { META_ID_DIRECTION, "Direction" }, 175 { META_ID_SIGNALING, "Signaling" }, 176 { META_ID_INCOMPLETE, "Incomplete" }, 177 { META_ID_DECIPHERED, "Deciphered" }, 178 { META_ID_PAYLOADCUT, "Payload cutted" }, 179 { META_ID_TIMESTAMP64, "Timestamp" }, 180 { META_ID_AAL5PROTO, "AAL5 Protocol Type" }, 181 { META_ID_PHYLINKID, "Physical Link ID" }, 182 { META_ID_LOCALDEVID, "Local Device ID" }, 183 { META_ID_REMOTEDEVID, "Remote Device ID" }, 184 { META_ID_TAPGROUPID, "Tap Group ID" }, 185 { META_ID_IMSI, "IMSI" }, 186 { META_ID_IMEI, "IMEI" }, 187 { META_ID_CELL, "Mobile Cell" }, 188 { META_ID_TLLI, "TLLI" }, 189 { META_ID_NSAPI, "NSAPI" }, 190 { META_ID_APN, "APN" }, 191 { META_ID_RAT, "RAT" }, 192 { META_ID_CALLING, "Calling Station ID" }, 193 { META_ID_CALLED, "Called Station ID" }, 194 { 0, NULL } 195 }; 196 static value_string_ext meta_id_vals_ext = VALUE_STRING_EXT_INIT(meta_id_vals); 197 198 #define META_AAL5PROTO_MTP3 2 199 #define META_AAL5PROTO_NS 3 200 #define META_AAL5PROTO_ALCAP 5 201 #define META_AAL5PROTO_NBAP 6 202 static const value_string meta_aal5proto_vals[] = { 203 { META_AAL5PROTO_MTP3, "SSCOP MTP3" }, 204 { META_AAL5PROTO_ALCAP, "SSCOP ALCAP" }, 205 { META_AAL5PROTO_NBAP, "SSCOP NBAP" }, 206 { META_AAL5PROTO_NS, "GPRS NS" }, 207 { 0, NULL } 208 }; 209 210 static const value_string meta_direction_vals[] = { 211 { 0, "Up" }, 212 { 1, "Down" }, 213 { 0, NULL } 214 }; 215 216 static guint16 skip_item(proto_tree *meta_tree, tvbuff_t *tvb, packet_info *pinfo _U_, guint16 offs) 217 { 218 guint16 id; 219 guint8 type; 220 guint16 len, aligned_len, total_len; 221 proto_tree *item_tree; 222 proto_item *subti; 223 224 id = tvb_get_letohs(tvb, offs); offs += 2; 225 type = tvb_get_guint8(tvb, offs); offs++; 226 len = tvb_get_guint8(tvb, offs); offs++; 227 aligned_len = (len + 3) & 0xfffc; 228 total_len = aligned_len + 4; /* 4: id, type, len fields */ 229 230 subti = proto_tree_add_item(meta_tree, hf_meta_item, tvb, offs - 4, 231 aligned_len + 4, ENC_NA); 232 item_tree = proto_item_add_subtree(subti, ett_meta_item); 233 proto_tree_add_uint(item_tree, hf_meta_item_id, tvb, offs - 4, 2, id); 234 proto_tree_add_uint(item_tree, hf_meta_item_type, tvb, offs - 2, 1, type); 235 proto_tree_add_uint(item_tree, hf_meta_item_len, 236 tvb, offs - 1, 1, len); 237 if (len > 0) 238 proto_tree_add_item(item_tree, hf_meta_item_data, 239 tvb, offs, len, ENC_NA); 240 241 return total_len; 242 } 243 244 /* 245 * offs: current offset in tvb 246 */ 247 static guint16 evaluate_meta_item_pcap(proto_tree *meta_tree, tvbuff_t *tvb, packet_info *pinfo, guint16 offs) 248 { 249 guint16 id; 250 guint8 type; 251 guint16 len, aligned_len, total_len; 252 proto_tree *item_tree; 253 proto_item *subti; 254 /* field values */ 255 guint8 dir; 256 guint64 ts; 257 258 id = tvb_get_letohs(tvb, offs); offs += 2; 259 type = tvb_get_guint8(tvb, offs); offs++; 260 len = tvb_get_guint8(tvb, offs); offs++; 261 aligned_len = (len + 3) & 0xfffc; 262 total_len = aligned_len + 4; /* 4: id, type, len fields */ 263 264 switch (id) { 265 case META_ID_DIRECTION: 266 dir = tvb_get_guint8(tvb, offs); 267 pinfo->p2p_dir = dir == META_DIR_UP ? P2P_DIR_RECV : P2P_DIR_SENT; 268 proto_tree_add_uint(meta_tree, hf_meta_item_direction, tvb, offs, 1, dir); 269 break; 270 case META_ID_TIMESTAMP64: 271 ts = tvb_get_letoh64(tvb, offs); 272 proto_tree_add_uint64(meta_tree, hf_meta_item_ts, tvb, offs, 8, ts); 273 break; 274 case META_ID_SIGNALING: 275 proto_tree_add_boolean(meta_tree, hf_meta_item_signaling, tvb, 276 offs, 0, 1); 277 break; 278 case META_ID_INCOMPLETE: 279 proto_tree_add_boolean(meta_tree, hf_meta_item_incomplete, tvb, 280 offs, 0, 1); 281 break; 282 default: 283 subti = proto_tree_add_item(meta_tree, hf_meta_item, tvb, offs - 4, 284 aligned_len + 4, ENC_NA); 285 item_tree = proto_item_add_subtree(subti, ett_meta_item); 286 proto_tree_add_uint(item_tree, hf_meta_item_id, tvb, offs - 4, 2, id); 287 proto_tree_add_uint(item_tree, hf_meta_item_type, tvb, offs - 2, 1, type); 288 proto_tree_add_uint(item_tree, hf_meta_item_len, 289 tvb, offs - 1, 1, len); 290 if (len > 0) 291 proto_tree_add_item(item_tree, hf_meta_item_data, 292 tvb, offs, len, ENC_NA); 293 } 294 return total_len; 295 } 296 297 /* 298 * offs: current offset in tvb 299 */ 300 static guint16 evaluate_meta_item_dxt(proto_tree *meta_tree, tvbuff_t *tvb, packet_info *pinfo, guint16 offs, struct atm_phdr *atm_info) 301 { 302 guint16 id; 303 guint8 type; 304 guint16 len, aligned_len, total_len; 305 proto_tree *item_tree; 306 proto_item *subti; 307 /* field values */ 308 guint8 dir, nsapi, rat, aal5proto; 309 guint16 phylinkid, localdevid, remotedevid, tapgroupid; 310 guint32 tlli; 311 guint64 ts, cell; 312 sscop_payload_info *p_sscop_info; 313 proto_item *cell_item, *imsi_item, *imei_item; 314 proto_tree *cell_tree, *imsi_tree, *imei_tree; 315 316 id = tvb_get_letohs(tvb, offs); offs += 2; 317 type = tvb_get_guint8(tvb, offs); offs++; 318 len = tvb_get_guint8(tvb, offs); offs++; 319 aligned_len = (len + 3) & 0xfffc; 320 total_len = aligned_len + 4; /* 4: id, type, len fields */ 321 322 switch (id) { 323 case META_ID_DIRECTION: 324 dir = tvb_get_guint8(tvb, offs); 325 pinfo->p2p_dir = (dir == META_DIR_UP ? P2P_DIR_RECV : P2P_DIR_SENT); 326 proto_tree_add_uint(meta_tree, hf_meta_item_direction, tvb, offs, 1, dir); 327 break; 328 case META_ID_TIMESTAMP64: 329 ts = tvb_get_letoh64(tvb, offs); 330 proto_tree_add_uint64(meta_tree, hf_meta_item_ts, tvb, offs, 8, ts); 331 break; 332 case META_ID_PHYLINKID: 333 phylinkid = tvb_get_letohs(tvb, offs); 334 pinfo->link_number = phylinkid; 335 proto_tree_add_uint(meta_tree, hf_meta_item_phylinkid, tvb, 336 offs, 2, phylinkid); 337 break; 338 case META_ID_NSAPI: 339 nsapi = tvb_get_guint8(tvb, offs); 340 proto_tree_add_uint(meta_tree, hf_meta_item_nsapi, tvb, 341 offs, 1, nsapi); 342 break; 343 case META_ID_IMSI: 344 imsi_item = proto_tree_add_item(meta_tree, hf_meta_item_imsi_digits, tvb, 345 offs, 8, ENC_BCD_DIGITS_0_9); 346 imsi_tree = proto_item_add_subtree(imsi_item, ett_meta_imsi); 347 proto_tree_add_item(imsi_tree, hf_meta_item_imsi_value, 348 tvb, offs, 8, ENC_LITTLE_ENDIAN); 349 break; 350 case META_ID_IMEI: 351 imei_item = proto_tree_add_item(meta_tree, hf_meta_item_imei_digits, tvb, 352 offs, 8, ENC_BCD_DIGITS_0_9); 353 imei_tree = proto_item_add_subtree(imei_item, ett_meta_imei); 354 proto_tree_add_item(imei_tree, hf_meta_item_imei_value, 355 tvb, offs, 8, ENC_LITTLE_ENDIAN); 356 break; 357 case META_ID_APN: 358 proto_tree_add_item(meta_tree, hf_meta_item_apn, tvb, 359 offs, len, ENC_ASCII|ENC_NA); 360 break; 361 case META_ID_RAT: 362 rat = tvb_get_guint8(tvb, offs); 363 proto_tree_add_uint(meta_tree, hf_meta_item_rat, tvb, 364 offs, 1, rat); 365 break; 366 case META_ID_CELL: 367 cell = tvb_get_ntoh64(tvb, offs); 368 cell_item = proto_tree_add_uint64_format(meta_tree, hf_meta_item_cell, 369 tvb, offs, 8, cell, "Mobile Cell"); 370 cell_tree = proto_item_add_subtree(cell_item, ett_meta_cell); 371 de_gmm_rai(tvb, cell_tree, pinfo, offs, 8, NULL, 0); 372 de_cell_id(tvb, cell_tree, pinfo, offs + 6, 2, NULL, 0); 373 break; 374 case META_ID_SIGNALING: 375 proto_tree_add_boolean(meta_tree, hf_meta_item_signaling, tvb, 376 offs, 0, 1); 377 break; 378 case META_ID_INCOMPLETE: 379 proto_tree_add_boolean(meta_tree, hf_meta_item_incomplete, tvb, 380 offs, 0, 1); 381 break; 382 case META_ID_DECIPHERED: 383 proto_tree_add_boolean(meta_tree, hf_meta_item_deciphered, tvb, 384 offs, 0, 1); 385 break; 386 case META_ID_AAL5PROTO: 387 aal5proto = tvb_get_guint8(tvb, offs); 388 p_sscop_info = (sscop_payload_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_sscop, 0); 389 if (!p_sscop_info) { 390 p_sscop_info = wmem_new0(wmem_file_scope(), sscop_payload_info); 391 p_add_proto_data(wmem_file_scope(), pinfo, proto_sscop, 0, p_sscop_info); 392 } 393 switch (aal5proto) { 394 case META_AAL5PROTO_MTP3: 395 p_sscop_info->subdissector = sscf_nni_handle; 396 /* hint for ATM dissector that this frame contains SSCOP */ 397 memset(atm_info, 0, sizeof(*atm_info)); 398 atm_info->type = TRAF_SSCOP; 399 break; 400 case META_AAL5PROTO_ALCAP: 401 p_sscop_info->subdissector = alcap_handle; 402 break; 403 case META_AAL5PROTO_NBAP: 404 p_sscop_info->subdissector = nbap_handle; 405 break; 406 case META_AAL5PROTO_NS: 407 /* hint for ATM dissector that this frame contains GPRS NS */ 408 memset(atm_info, 0, sizeof(*atm_info)); 409 atm_info->type = TRAF_GPRS_NS; 410 break; 411 /* TODO: check for additional protos on Iu 802 LLC/SNAP ... */ 412 default: 413 /* TODO: add warning */ 414 p_remove_proto_data(wmem_file_scope(), pinfo, proto_sscop, 0); 415 } 416 proto_tree_add_uint(meta_tree, hf_meta_item_aal5proto, tvb, 417 offs, 1, aal5proto); 418 break; 419 case META_ID_LOCALDEVID: 420 localdevid = tvb_get_letohs(tvb, offs); 421 proto_tree_add_uint(meta_tree, hf_meta_item_localdevid, tvb, 422 offs, 2, localdevid); 423 break; 424 case META_ID_REMOTEDEVID: 425 remotedevid = tvb_get_letohs(tvb, offs); 426 proto_tree_add_uint(meta_tree, hf_meta_item_remotedevid, tvb, 427 offs, 2, remotedevid); 428 break; 429 case META_ID_TAPGROUPID: 430 tapgroupid = tvb_get_letohs(tvb, offs); 431 proto_tree_add_uint(meta_tree, hf_meta_item_tapgroupid, tvb, 432 offs, 2, tapgroupid); 433 break; 434 case META_ID_TLLI: 435 tlli = tvb_get_letohs(tvb, offs); 436 proto_tree_add_uint(meta_tree, hf_meta_item_tlli, tvb, 437 offs, 4, tlli); 438 break; 439 case META_ID_CALLING: 440 proto_tree_add_item(meta_tree, hf_meta_item_calling, tvb, 441 offs, len, ENC_ASCII|ENC_NA); 442 break; 443 case META_ID_CALLED: 444 proto_tree_add_item(meta_tree, hf_meta_item_called, tvb, 445 offs, len, ENC_ASCII|ENC_NA); 446 break; 447 default: 448 subti = proto_tree_add_item(meta_tree, hf_meta_item, tvb, offs - 4, 449 aligned_len + 4, ENC_NA); 450 item_tree = proto_item_add_subtree(subti, ett_meta_item); 451 proto_tree_add_uint(item_tree, hf_meta_item_id, tvb, offs - 4, 2, id); 452 proto_tree_add_uint(item_tree, hf_meta_item_type, tvb, offs - 2, 1, type); 453 proto_tree_add_uint(item_tree, hf_meta_item_len, 454 tvb, offs - 1, 1, len); 455 if (len > 0) 456 proto_tree_add_item(item_tree, hf_meta_item_data, 457 tvb, offs, len, ENC_NA); 458 } 459 return total_len; 460 } 461 462 /* 463 * offs: current offset within tvb 464 * header_length: length of meta header 465 */ 466 static gint32 evaluate_meta_items(guint16 schema, tvbuff_t *tvb, packet_info *pinfo, 467 proto_tree *meta_tree, guint16 offs, gint32 header_length, 468 struct atm_phdr *atm_info) 469 { 470 gint16 item_len; 471 gint32 total_len = 0; 472 473 while (total_len < header_length) { 474 switch (schema) { 475 case META_SCHEMA_DXT: 476 item_len = evaluate_meta_item_dxt(meta_tree, tvb, pinfo, offs + total_len, atm_info); 477 break; 478 case META_SCHEMA_PCAP: 479 item_len = evaluate_meta_item_pcap(meta_tree, tvb, pinfo, offs + total_len); 480 break; 481 default: 482 item_len = skip_item(meta_tree, tvb, pinfo, offs + total_len); 483 } 484 if (item_len < 4) { /* 4 is the minimum length of an item: id + type + length field */ 485 expert_add_info_format(pinfo, meta_tree, &ei_meta_malformed, 486 "Malformed Packet %s (wrong item encoding)", pinfo->current_proto); 487 return -1; 488 } 489 total_len += item_len; 490 } 491 return total_len; 492 } 493 494 static int 495 dissect_meta(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) 496 { 497 #define META_HEADER_SIZE 8 498 guint16 schema, proto, hdrlen, reserved; 499 gint32 item_len; 500 guint32 aal2_ext, atm_hdr; 501 proto_tree *meta_tree = NULL; 502 proto_item *ti = NULL; 503 tvbuff_t *next_tvb = NULL; 504 dissector_handle_t next_dissector = data_handle; 505 void *next_dissector_data = NULL; 506 struct atm_phdr atm_info; 507 508 col_set_str(pinfo->cinfo, COL_PROTOCOL, "META"); 509 510 schema = tvb_get_letohs(tvb, 0); 511 hdrlen = tvb_get_letohs(tvb, 2); 512 proto = tvb_get_letohs(tvb, 4); 513 reserved = tvb_get_letohs(tvb, 6); 514 515 if (tree) { 516 ti = proto_tree_add_item(tree, proto_meta, tvb, 0, hdrlen + 4, ENC_NA); 517 meta_tree = proto_item_add_subtree(ti, ett_meta); 518 proto_tree_add_uint(meta_tree, hf_meta_schema, tvb, 0, 2, schema); 519 proto_tree_add_uint(meta_tree, hf_meta_hdrlen, tvb, 2, 2, hdrlen); 520 proto_tree_add_uint(meta_tree, hf_meta_proto, tvb, 4, 2, proto); 521 proto_tree_add_uint(meta_tree, hf_meta_reserved, tvb, 6, 2, reserved); 522 } 523 item_len = evaluate_meta_items(schema, tvb, pinfo, meta_tree, META_HEADER_SIZE, hdrlen, &atm_info); 524 525 if (item_len < 0) { 526 /* evaluate_meta_items signalled an error */ 527 return META_HEADER_SIZE; /* stop parsing */ 528 } 529 530 if (hdrlen != item_len) { 531 expert_add_info(pinfo, ti, &ei_meta_invalid_header); 532 return META_HEADER_SIZE; 533 } 534 535 /* find next subdissector based on the chosen schema */ 536 switch (schema) { 537 case META_SCHEMA_PCAP: 538 /* TODO */ 539 break; 540 case META_SCHEMA_DXT: 541 switch (proto) { 542 case META_PROTO_DXT_ETHERNET: 543 next_dissector = ethwithoutfcs_handle; 544 break; 545 case META_PROTO_DXT_ETHERNET_CRC: 546 next_dissector = ethwithfcs_handle; 547 break; 548 case META_PROTO_DXT_FP_HINT: 549 next_dissector = fphint_handle; 550 break; 551 case META_PROTO_DXT_ATM: 552 memset(&atm_info, 0, sizeof atm_info); 553 atm_info.aal = AAL_OAMCELL; 554 atm_info.type = TRAF_UNKNOWN; 555 next_dissector = atm_untrunc_handle; 556 next_dissector_data = &atm_info; 557 break; 558 case META_PROTO_DXT_ATM_AAL2: 559 aal2_ext = tvb_get_ntohl(tvb, item_len + META_HEADER_SIZE); item_len += 4; 560 atm_hdr = tvb_get_ntohl(tvb, item_len + META_HEADER_SIZE); item_len += 4; 561 memset(&atm_info, 0, sizeof(atm_info)); 562 atm_info.aal = AAL_2; 563 /* atm_info.flags = pinfo->p2p_dir; */ 564 atm_info.vpi = ((atm_hdr & 0x0ff00000) >> 20); 565 atm_info.vci = ((atm_hdr & 0x000ffff0) >> 4); 566 atm_info.aal2_cid = aal2_ext & 0x000000ff; 567 atm_info.type = TRAF_UMTS_FP; 568 next_dissector = atm_untrunc_handle; 569 next_dissector_data = &atm_info; 570 break; 571 case META_PROTO_DXT_ERF_AAL5: 572 atm_hdr = tvb_get_ntohl(tvb, item_len + META_HEADER_SIZE); item_len += 4; 573 atm_info.vpi = ((atm_hdr & 0x0ff00000) >> 20); 574 atm_info.vci = ((atm_hdr & 0x000ffff0) >> 4); 575 atm_info.aal = AAL_5; 576 next_dissector = atm_untrunc_handle; 577 next_dissector_data = &atm_info; 578 break; 579 case META_PROTO_DXT_HDLC: 580 next_dissector = mtp2_handle; 581 next_tvb = tvb_new_subset_length_caplen(tvb, item_len + META_HEADER_SIZE, 582 tvb_reported_length(tvb)-item_len-META_HEADER_SIZE-2, -1); 583 break; 584 default: 585 next_dissector = 586 dissector_get_uint_handle(meta_dissector_table, proto); 587 } 588 } 589 if (!next_tvb) 590 next_tvb = tvb_new_subset_remaining(tvb, item_len + META_HEADER_SIZE); 591 592 call_dissector_with_data(next_dissector, next_tvb, pinfo, tree, 593 next_dissector_data); 594 return tvb_captured_length(tvb); 595 } 596 597 void 598 proto_register_meta(void) 599 { 600 static hf_register_info hf[] = { 601 /* metadata header */ 602 { &hf_meta_schema, 603 { "Schema", "meta.schema", 604 FT_UINT16, BASE_DEC, VALS(meta_schema_vals), 0, 605 NULL, HFILL } 606 }, 607 { &hf_meta_hdrlen, 608 { "Header Length", "meta.hdrlen", 609 FT_UINT16, BASE_DEC, NULL, 0, 610 NULL, HFILL } 611 }, 612 { &hf_meta_proto, 613 { "Protocol", "meta.proto", 614 FT_UINT16, BASE_DEC | BASE_EXT_STRING, &meta_proto_vals_ext, 0, 615 NULL, HFILL } 616 }, 617 { &hf_meta_reserved, 618 { "Reserved", "meta.reserved", 619 FT_UINT16, BASE_HEX, NULL, 0, 620 NULL, HFILL } 621 }, 622 623 /* general meta item */ 624 { &hf_meta_item, 625 { "Unknown Item", "meta.item", 626 FT_NONE, BASE_NONE, NULL, 0, 627 NULL, HFILL } 628 }, 629 { &hf_meta_item_id, 630 { "Item ID", "meta.item.id", 631 FT_UINT16, BASE_HEX | BASE_EXT_STRING, &meta_id_vals_ext, 0x0, 632 NULL, HFILL } 633 }, 634 { &hf_meta_item_type, 635 { "Item Type", "meta.item.type", 636 FT_UINT8, BASE_HEX, VALS(meta_type_vals), 0x0, 637 NULL, HFILL } 638 }, 639 { &hf_meta_item_len, 640 { "Item Length", "meta.item.len", 641 FT_UINT8, BASE_DEC, NULL, 0, 642 NULL, HFILL } 643 }, 644 { &hf_meta_item_data, 645 { "Item Data", "meta.item.data", 646 FT_BYTES, BASE_NONE, NULL, 0x0, 647 NULL, HFILL } 648 }, 649 650 /* specific meta items */ 651 { &hf_meta_item_direction, 652 { "Direction", "meta.direction", 653 FT_UINT8, BASE_DEC, VALS(meta_direction_vals), 0, 654 NULL, HFILL } 655 }, 656 { &hf_meta_item_ts, 657 { "Timestamp", "meta.timestamp", 658 FT_UINT64, BASE_DEC, NULL, 0, 659 NULL, HFILL } 660 }, 661 { &hf_meta_item_phylinkid, 662 { "Physical Link ID", "meta.phylinkid", 663 FT_UINT16, BASE_DEC, NULL, 0, 664 NULL, HFILL } 665 }, 666 { &hf_meta_item_nsapi, 667 { "NSAPI", "meta.nsapi", 668 FT_UINT8, BASE_DEC, NULL, 0, 669 NULL, HFILL } 670 }, 671 { &hf_meta_item_imsi_digits, 672 { "IMSI digits", "meta.imsi_digits", 673 FT_STRING, BASE_NONE, NULL, 0, 674 NULL, HFILL } 675 }, 676 { &hf_meta_item_imsi_value, 677 { "IMSI value", "meta.imsi_value", 678 FT_UINT64, BASE_HEX, NULL, 0, 679 NULL, HFILL } 680 }, 681 { &hf_meta_item_imei_digits, 682 { "IMEI digits", "meta.imei_digits", 683 FT_STRING, BASE_NONE, NULL, 0, 684 NULL, HFILL } 685 }, 686 { &hf_meta_item_imei_value, 687 { "IMEI value", "meta.imei_value", 688 FT_UINT64, BASE_HEX, NULL, 0, 689 NULL, HFILL } 690 }, 691 { &hf_meta_item_signaling, 692 { "Signaling", "meta.signaling", 693 FT_BOOLEAN, BASE_NONE, NULL, 0, 694 NULL, HFILL } 695 }, 696 { &hf_meta_item_incomplete, 697 { "Incomplete", "meta.incomplete", 698 FT_BOOLEAN, BASE_NONE, NULL, 0, 699 NULL, HFILL } 700 }, 701 { &hf_meta_item_deciphered, 702 { "Deciphered", "meta.deciphered", 703 FT_BOOLEAN, BASE_NONE, NULL, 0, 704 NULL, HFILL } 705 }, 706 { &hf_meta_item_apn, 707 { "APN", "meta.apn", 708 FT_STRINGZ, BASE_NONE, NULL, 0, 709 NULL, HFILL } 710 }, 711 { &hf_meta_item_rat, 712 { "RAT", "meta.rat", 713 FT_UINT8, BASE_DEC, NULL, 0, 714 NULL, HFILL } 715 }, 716 { &hf_meta_item_aal5proto, 717 { "AAL5 Protocol Type", "meta.aal5proto", 718 FT_UINT8, BASE_DEC, VALS(meta_aal5proto_vals), 0, 719 NULL, HFILL } 720 }, 721 { &hf_meta_item_cell, 722 { "Mobile Cell", "meta.cell", 723 FT_UINT64, BASE_HEX, NULL, 0, 724 NULL, HFILL } 725 }, 726 727 { &hf_meta_item_localdevid, 728 { "Local Device ID", "meta.localdevid", 729 FT_UINT16, BASE_DEC, NULL, 0, 730 NULL, HFILL } 731 }, 732 { &hf_meta_item_remotedevid, 733 { "Remote Device ID", "meta.remotedevid", 734 FT_UINT16, BASE_DEC, NULL, 0, 735 NULL, HFILL } 736 }, 737 { &hf_meta_item_tapgroupid, 738 { "Tap Group ID", "meta.tapgroupid", 739 FT_UINT16, BASE_DEC, NULL, 0, 740 NULL, HFILL } 741 }, 742 { &hf_meta_item_tlli, 743 { "TLLI", "meta.tlli", 744 FT_UINT32, BASE_DEC, NULL, 0, 745 NULL, HFILL } 746 }, 747 { &hf_meta_item_calling, 748 { "Calling Station ID", "meta.calling", 749 FT_STRINGZ, BASE_NONE, NULL, 0, 750 NULL, HFILL } 751 }, 752 { &hf_meta_item_called, 753 { "Called Station ID", "meta.called", 754 FT_STRINGZ, BASE_NONE, NULL, 0, 755 NULL, HFILL } 756 }, 757 }; 758 759 static gint *ett[] = { 760 &ett_meta, 761 &ett_meta_item, 762 &ett_meta_cell, 763 &ett_meta_imsi, 764 &ett_meta_imei 765 }; 766 767 static ei_register_info ei[] = { 768 { &ei_meta_malformed, { "meta.malformed", PI_MALFORMED, PI_ERROR, "Malformed data", EXPFILL }}, 769 { &ei_meta_invalid_header, { "meta.invalid_header_length", PI_MALFORMED, PI_ERROR, "Invalid Header Length", EXPFILL }}, 770 }; 771 772 expert_module_t* expert_meta; 773 774 proto_meta = proto_register_protocol("Metadata", "META", "meta"); 775 register_dissector("meta", dissect_meta, proto_meta); 776 777 proto_register_field_array(proto_meta, hf, array_length(hf)); 778 proto_register_subtree_array(ett, array_length(ett)); 779 expert_meta = expert_register_protocol(proto_meta); 780 expert_register_field_array(expert_meta, ei, array_length(ei)); 781 782 meta_dissector_table = register_dissector_table("meta.proto", 783 "META protocol", proto_meta, FT_UINT16, BASE_DEC); 784 } 785 786 void 787 proto_reg_handoff_meta(void) 788 { 789 #if 0 /* enable once WTAP_ENCAP_META exists */ 790 dissector_handle_t meta_handle; 791 792 meta_handle = find_dissector("meta"); 793 dissector_add_uint("wtap_encap", WTAP_ENCAP_META, meta_handle); 794 #endif 795 data_handle = find_dissector("data"); 796 alcap_handle = find_dissector_add_dependency("alcap", proto_meta); 797 atm_untrunc_handle = find_dissector_add_dependency("atm_untruncated", proto_meta); 798 nbap_handle = find_dissector_add_dependency("nbap", proto_meta); 799 sscf_nni_handle = find_dissector_add_dependency("sscf-nni", proto_meta); 800 ethwithfcs_handle = find_dissector_add_dependency("eth_withfcs", proto_meta); 801 ethwithoutfcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_meta); 802 fphint_handle = find_dissector_add_dependency("fp_hint", proto_meta); 803 mtp2_handle = find_dissector_add_dependency("mtp2", proto_meta); 804 } 805 806 /* 807 * Editor modelines - https://www.wireshark.org/tools/modelines.html 808 * 809 * Local variables: 810 * c-basic-offset: 4 811 * tab-width: 8 812 * indent-tabs-mode: nil 813 * End: 814 * 815 * vi: set shiftwidth=4 tabstop=8 expandtab: 816 * :indentSize=4:tabSize=8:noTabs=true: 817 */ 818