From 8588f347d9f9e79ee7ee29529b5b8a000f14bdee Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Wed, 29 Dec 2010 21:42:55 +0100 Subject: [PATCH] import the ISI wireshark plugin from libisi --- .gitignore | 2 + Makefile | 23 ++++ TODO | 4 + src/isi-gps.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++ src/isi-gps.h | 7 + src/isi-simauth.c | 278 +++++++++++++++++++++++++++++++++++++ src/isi-simauth.h | 7 + src/packet-isi.c | 197 ++++++++++++++++++++++++++ src/packet-isi.h | 11 ++ src/plugin.c | 16 +++ 10 files changed, 889 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 TODO create mode 100644 src/isi-gps.c create mode 100644 src/isi-gps.h create mode 100644 src/isi-simauth.c create mode 100644 src/isi-simauth.h create mode 100644 src/packet-isi.c create mode 100644 src/packet-isi.h create mode 100644 src/plugin.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7f18ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +isi.so +src/*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8c52e4e --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +CFLAGS+=-I/usr/include/wireshark -DHAVE_STDARG_H -DHAVE_CONFIG_H -g +OBJECTS:=src/packet-isi.o src/plugin.o src/isi-simauth.o src/isi-gps.o + +PREFIX?=/usr +PLUGINDIR?=lib/wireshark/libwireshark0/plugins + +all: isi.so + +%.o: %.c + @echo "[CC] $<" + @$(CC) -o $@ $(CFLAGS) `pkg-config --cflags glib-2.0` -c -fPIC $< + +isi.so: $(OBJECTS) + @echo "[LD] $@" + @$(CC) -o $@ -shared -Wl,-soname,$@ $^ + +clean: + @rm -f isi.so src/*.o + +install: isi.so + install isi.so $(DESTDIR)${PREFIX}/${PLUGINDIR} + +.PHONEY: clean install diff --git a/TODO b/TODO new file mode 100644 index 0000000..1c2e14f --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ +* port mtc analysis from the lua plugin +* port phone info analysis from the lua plugin +* write network analysis +* try to do resource name translation via dissector diff --git a/src/isi-gps.c b/src/isi-gps.c new file mode 100644 index 0000000..818f93e --- /dev/null +++ b/src/isi-gps.c @@ -0,0 +1,344 @@ +/* isi-gps.c + * Dissector for ISI's GPS resource + * Copyright 2010, Sebastian Reichel + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * GPS Data Packet Reverse Engineered by Luke Dashjr + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "packet-isi.h" +#include "isi-gps.h" + +/* centimeter per second to kilometer per hour */ +#define CMS_TO_KMH 0.036 +#define SAT_PKG_LEN 12 + +static const value_string isi_gps_id[] = { + //{0x0d, "GPS_UNKNOWN_0D"}, + //{0x0e, "GPS_UNKNOWN_0E"}, + {0x7d, "GPS_STATUS_IND"}, + //{0x7e, "GPS_UNKNOWN_7E"}, + //{0x7f, "GPS_UNKNOWN_7F"}, + //{0x82, "GPS_UNKNOWN_82"}, + //{0x83, "GPS_UNKNOWN_83"}, + //{0x84, "GPS_UNKNOWN_84"}, + //{0x85, "GPS_UNKNOWN_85"}, + //{0x90, "GPS_UNKNOWN_90"}, + //{0x91, "GPS_UNKNOWN_91"}, + {0x90, "GPS_POWER_STATUS_REQ"}, + {0x91, "GPS_POWER_STATUS_RSP"}, + {0x92, "GPS_DATA_IND"}, + {0x00, NULL } +}; + +static const value_string isi_gps_sub_id[] = { + {0x02, "GPS_POSITION"}, + {0x03, "GPS_TIME_DATE"}, + {0x04, "GPS_MOVEMENT"}, + {0x05, "GPS_SAT_INFO"}, + {0x07, "GPS_CELL_INFO_GSM"}, + {0x08, "GPS_CELL_INFO_WCDMA"}, + {0x00, NULL } +}; + +static const value_string isi_gps_status[] = { + {0x00, "GPS_DISABLED"}, + {0x01, "GPS_NO_LOCK"}, + {0x02, "GPS_LOCK"}, + {0x00, NULL } +}; + +static dissector_handle_t isi_gps_handle; +static void dissect_isi_gps(tvbuff_t *tvb, packet_info *pinfo, proto_item *tree); + +static guint32 hf_isi_gps_cmd = -1; +static guint32 hf_isi_gps_sub_pkgs = -1; +static guint32 hf_isi_gps_sub_type = -1; +static guint32 hf_isi_gps_sub_len = -1; +static guint32 hf_isi_gps_status = -1; +static guint32 hf_isi_gps_year = -1; +static guint32 hf_isi_gps_month = -1; +static guint32 hf_isi_gps_day = -1; +static guint32 hf_isi_gps_hour = -1; +static guint32 hf_isi_gps_minute = -1; +static guint32 hf_isi_gps_second = -1; +static guint32 hf_isi_gps_latitude = -1; +static guint32 hf_isi_gps_longitude = -1; +static guint32 hf_isi_gps_eph = -1; +static guint32 hf_isi_gps_altitude = -1; +static guint32 hf_isi_gps_epv = -1; +static guint32 hf_isi_gps_course = -1; +static guint32 hf_isi_gps_epd = -1; +static guint32 hf_isi_gps_speed = -1; +static guint32 hf_isi_gps_eps = -1; +static guint32 hf_isi_gps_climb = -1; +static guint32 hf_isi_gps_epc = -1; +static guint32 hf_isi_gps_mcc = -1; +static guint32 hf_isi_gps_mnc = -1; +static guint32 hf_isi_gps_lac = -1; +static guint32 hf_isi_gps_cid = -1; +static guint32 hf_isi_gps_ucid = -1; +static guint32 hf_isi_gps_satellites = -1; +static guint32 hf_isi_gps_prn = -1; +static guint32 hf_isi_gps_sat_used = -1; +static guint32 hf_isi_gps_sat_strength = -1; +static guint32 hf_isi_gps_sat_elevation = -1; +static guint32 hf_isi_gps_sat_azimuth = -1; + +void proto_reg_handoff_isi_gps(void) { + static gboolean initialized=FALSE; + + if (!initialized) { + isi_gps_handle = create_dissector_handle(dissect_isi_gps, proto_isi); + dissector_add("isi.resource", 0x54, isi_gps_handle); + } +} + +void proto_register_isi_gps(void) { + static hf_register_info hf[] = { + { &hf_isi_gps_cmd, + { "Command", "isi.gps.cmd", FT_UINT8, BASE_HEX, isi_gps_id, 0x0, "Command", HFILL }}, + { &hf_isi_gps_sub_pkgs, + { "Number of Subpackets", "isi.gps.pkgs", FT_UINT8, BASE_DEC, NULL, 0x0, "Number of Subpackets", HFILL }}, + { &hf_isi_gps_sub_type, + { "Subpacket Type", "isi.gps.sub.type", FT_UINT8, BASE_HEX, isi_gps_sub_id, 0x0, "Subpacket Type", HFILL }}, + { &hf_isi_gps_sub_len, + { "Subpacket Length", "isi.gps.sub.len", FT_UINT8, BASE_DEC, NULL, 0x0, "Subpacket Length", HFILL }}, + { &hf_isi_gps_status, + { "Status", "isi.gps.status", FT_UINT8, BASE_HEX, isi_gps_status, 0x0, "Status", HFILL }}, + { &hf_isi_gps_year, + { "Year", "isi.gps.date.year", FT_UINT16, BASE_DEC, NULL, 0x0, "Year", HFILL }}, + { &hf_isi_gps_month, + { "Month", "isi.gps.date.month", FT_UINT8, BASE_DEC, NULL, 0x0, "Month", HFILL }}, + { &hf_isi_gps_day, + { "Day", "isi.gps.date.day", FT_UINT8, BASE_DEC, NULL, 0x0, "Day", HFILL }}, + { &hf_isi_gps_hour, + { "Hour", "isi.gps.time.hour", FT_UINT8, BASE_DEC, NULL, 0x0, "Hour", HFILL }}, + { &hf_isi_gps_minute, + { "Minute", "isi.gps.time.minute", FT_UINT8, BASE_DEC, NULL, 0x0, "Minute", HFILL }}, + { &hf_isi_gps_second, + { "Second", "isi.gps.time.second", FT_FLOAT, BASE_NONE, NULL, 0x0, "Second", HFILL }}, + { &hf_isi_gps_latitude, + { "Latitude", "isi.gps.lat", FT_DOUBLE, BASE_NONE, NULL, 0x0, "Latitude", HFILL }}, + { &hf_isi_gps_longitude, + { "Longitude", "isi.gps.lon", FT_DOUBLE, BASE_NONE, NULL, 0x0, "Longitude", HFILL }}, + { &hf_isi_gps_eph, + { "Position Accuracy", "isi.gps.eph", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPH (position accuracy) in meter", HFILL }}, + { &hf_isi_gps_altitude, + { "Altitude", "isi.gps.alt", FT_INT16, BASE_DEC, NULL, 0x0, "Altitude in meter", HFILL }}, + { &hf_isi_gps_epv, + { "Altitude Accuracy", "isi.gps.epv", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPV (altitude accuracy) in meter", HFILL }}, + { &hf_isi_gps_course, + { "Course", "isi.gps.course", FT_FLOAT, BASE_NONE, NULL, 0x0, "Course in degree", HFILL }}, + { &hf_isi_gps_epd, + { "Course Accuracy", "isi.gps.epd", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPD (course accuracy) in degree", HFILL }}, + { &hf_isi_gps_speed, + { "Speed", "isi.gps.speed", FT_FLOAT, BASE_NONE, NULL, 0x0, "Speed in km/h", HFILL }}, + { &hf_isi_gps_eps, + { "Speed Accuracy", "isi.gps.eps", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPS (speed accuracy) in km/h", HFILL }}, + { &hf_isi_gps_climb, + { "Climb", "isi.gps.climb", FT_FLOAT, BASE_NONE, NULL, 0x0, "Climb in km/h", HFILL }}, + { &hf_isi_gps_satellites, + { "Visible Satellites", "isi.gps.satellites", FT_UINT8, BASE_DEC, NULL, 0x0, "Visible Satellites", HFILL }}, + { &hf_isi_gps_prn, + { "Pseudeorandom Noise (PRN)", "isi.gps.sat.prn", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, "Pseudeorandom Noise (PRN)", HFILL }}, + { &hf_isi_gps_sat_used, + { "in use", "isi.gps.sat.used", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "in use", HFILL }}, + { &hf_isi_gps_sat_strength, + { "Signal Strength", "isi.gps.sat.strength", FT_FLOAT, BASE_NONE, NULL, 0x0, "Signal Strength", HFILL }}, + { &hf_isi_gps_sat_elevation, + { "Elevation", "isi.gps.sat.elevation", FT_FLOAT, BASE_NONE, NULL, 0x0, "Elevation", HFILL }}, + { &hf_isi_gps_sat_azimuth, + { "Azimuth", "isi.gps.sat.azimuth", FT_FLOAT, BASE_NONE, NULL, 0x0, "Azimuth", HFILL }}, + { &hf_isi_gps_epc, + { "Climb Accuracy", "isi.gps.epc", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPC (climb accuracy) in km/h", HFILL }}, + { &hf_isi_gps_mcc, + { "Mobile Country Code (MCC)", "isi.gps.gsm.mcc", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Mobile Country Code (MCC)", HFILL }}, + { &hf_isi_gps_mnc, + { "Mobile Network Code (MNC)", "isi.gps.gsm.mnc", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Mobile Network Code (MNC)", HFILL }}, + { &hf_isi_gps_lac, + { "Location Area Code (LAC)", "isi.gps.gsm.lac", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Location Area Code (LAC)", HFILL }}, + { &hf_isi_gps_cid, + { "Cell ID (CID)", "isi.gps.gsm.cid", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Cell ID (CID)", HFILL }}, + { &hf_isi_gps_ucid, + { "Cell ID (UCID)", "isi.gps.gsm.ucid", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, "Cell ID (UCID)", HFILL }} + }; + + proto_register_field_array(proto_isi, hf, array_length(hf)); + register_dissector("isi.gps", dissect_isi_gps, proto_isi); +} + +static void dissect_isi_gps_data(tvbuff_t *tvb, packet_info *pinfo, proto_item *item, proto_tree *tree) { + guint8 len = tvb->length; + int i; + + guint8 pkgcount = tvb_get_guint8(tvb, 0x07); + proto_tree_add_item(tree, hf_isi_gps_sub_pkgs, tvb, 0x07, 1, FALSE); + + size_t offset = 0x0b; // subpackets start here + for(i=0; i 180.0) lat -= 360.0; + proto_tree_add_double(subtree, hf_isi_gps_latitude, tvb, offset+0, 4, lat); + + double lon = tvb_get_ntohl(tvb, offset+4); + lon = (lon*360)/4294967296; + if(lon > 180.0) lon -= 360.0; + proto_tree_add_double(subtree, hf_isi_gps_longitude, tvb, offset+4, 4, lon); + + float eph = tvb_get_ntohl(tvb, offset+12) / 100.0; + proto_tree_add_float(subtree, hf_isi_gps_eph, tvb, offset+12, 4, eph); + + gint32 altitude = (tvb_get_ntohs(tvb, offset+18) - tvb_get_ntohs(tvb, offset+22))/2; + proto_tree_add_int(subtree, hf_isi_gps_altitude, tvb, offset+18, 6, altitude); + + float epv = tvb_get_ntohs(tvb, offset+20) / 2; + proto_tree_add_float(subtree, hf_isi_gps_epv, tvb, offset+20, 2, epv); + + break; + case 0x03: // Date and Time + proto_tree_add_item(subtree, hf_isi_gps_year, tvb, offset+0, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_gps_month, tvb, offset+2, 1, FALSE); + proto_tree_add_item(subtree, hf_isi_gps_day, tvb, offset+3, 1, FALSE); + proto_tree_add_item(subtree, hf_isi_gps_hour, tvb, offset+5, 1, FALSE); + proto_tree_add_item(subtree, hf_isi_gps_minute, tvb, offset+6, 1, FALSE); + + float second = tvb_get_ntohs(tvb, offset+8) / 1000.0; + proto_tree_add_float(subtree, hf_isi_gps_second, tvb, offset+8, 2, second); + break; + case 0x04: ; // Movement + float course = tvb_get_ntohs(tvb, offset+0) / 100.0; + proto_tree_add_float(subtree, hf_isi_gps_course, tvb, offset+0, 2, course); + + float epd = tvb_get_ntohs(tvb, offset+2) / 100.0; + proto_tree_add_float(subtree, hf_isi_gps_epd, tvb, offset+2, 2, epd); + + float speed = tvb_get_ntohs(tvb, offset+6) * CMS_TO_KMH; + proto_tree_add_float(subtree, hf_isi_gps_speed, tvb, offset+6, 2, speed); + + float eps = tvb_get_ntohs(tvb, offset+8) * CMS_TO_KMH; + proto_tree_add_float(subtree, hf_isi_gps_eps, tvb, offset+8, 2, eps); + + float climb = tvb_get_ntohs(tvb, offset+10) * CMS_TO_KMH; + proto_tree_add_float(subtree, hf_isi_gps_climb, tvb, offset+10, 2, climb); + + float epc = tvb_get_ntohs(tvb, offset+12) * CMS_TO_KMH; + proto_tree_add_float(subtree, hf_isi_gps_epc, tvb, offset+12, 2, epc); + break; + case 0x05: ; // Satellite Info + guint8 satellites = tvb_get_guint8(tvb, offset+0); + proto_tree_add_item(subtree, hf_isi_gps_satellites, tvb, offset+0, 1, FALSE); + + int sat; + for(sat = 0; sat < satellites ; sat++) { + int pos = offset+4+(sat*SAT_PKG_LEN); + proto_item *satitem = proto_tree_add_text(subtree, tvb, pos, SAT_PKG_LEN, "Satellite %d", sat); + proto_tree *sattree = proto_item_add_subtree(satitem, ett_isi_msg); + + float signal_strength = tvb_get_ntohs(tvb, pos+3) / 100.0; + float elevation = tvb_get_ntohs(tvb, pos+6) / 100.0; + float azimuth = tvb_get_ntohs(tvb, pos+8) / 100.0; + + proto_tree_add_item(sattree, hf_isi_gps_prn, tvb, pos+1, 1, FALSE); + proto_tree_add_item(sattree, hf_isi_gps_sat_used, tvb, pos+2, 1, FALSE); + proto_tree_add_float(sattree, hf_isi_gps_sat_strength, tvb, pos+3, 2, signal_strength); + proto_tree_add_float(sattree, hf_isi_gps_sat_elevation, tvb, pos+6, 2, elevation); + proto_tree_add_float(sattree, hf_isi_gps_sat_azimuth, tvb, pos+8, 2, azimuth); + } + break; + case 0x07: // CellInfo GSM + proto_tree_add_item(subtree, hf_isi_gps_mcc, tvb, offset+0, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_gps_mnc, tvb, offset+2, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_gps_lac, tvb, offset+4, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_gps_cid, tvb, offset+6, 2, FALSE); + break; + case 0x08: // CellInfo WCDMA + proto_tree_add_item(subtree, hf_isi_gps_mcc, tvb, offset+0, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_gps_mnc, tvb, offset+2, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_gps_ucid, tvb, offset+4, 4, FALSE); + break; + default: + break; + } + + offset += splen - 4; + } + +} + +static void dissect_isi_gps(tvbuff_t *tvb, packet_info *pinfo, proto_item *isitree) { + proto_item *item = NULL; + proto_tree *tree = NULL; + guint8 cmd; + + if(isitree) { + item = proto_tree_add_text(isitree, tvb, 0, -1, "Payload"); + tree = proto_item_add_subtree(item, ett_isi_msg); + + proto_tree_add_item(tree, hf_isi_gps_cmd, tvb, 0, 1, FALSE); + cmd = tvb_get_guint8(tvb, 0); + + switch(cmd) { + case 0x7d: /* GPS Status */ + proto_tree_add_item(tree, hf_isi_gps_status, tvb, 2, 1, FALSE); + guint8 status = tvb_get_guint8(tvb, 2); + col_add_fstr(pinfo->cinfo, COL_INFO, "GPS Status Indication: %s", val_to_str(status, isi_gps_status, "unknown (0x%x)")); + break; + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + col_add_fstr(pinfo->cinfo, COL_INFO, "unknown A-GPS package (0x%02x)", cmd); + break; + case 0x90: /* GPS Power Request */ + col_set_str(pinfo->cinfo, COL_INFO, "GPS Power Request"); + break; + case 0x91: /* GPS Power Request */ + col_set_str(pinfo->cinfo, COL_INFO, "GPS Power Response"); + break; + case 0x92: /* GPS Data */ + col_set_str(pinfo->cinfo, COL_INFO, "GPS Data"); + dissect_isi_gps_data(tvb, pinfo, item, tree); + break; + default: + col_add_fstr(pinfo->cinfo, COL_INFO, "unknown GPS package (0x%02x)", cmd); + break; + } + } +} diff --git a/src/isi-gps.h b/src/isi-gps.h new file mode 100644 index 0000000..6d9dc7c --- /dev/null +++ b/src/isi-gps.h @@ -0,0 +1,7 @@ +#ifndef _ISI_SIMAUTH_H +#define _ISI_SIMAUTH_H + +void proto_reg_handoff_isi_gps(void); +void proto_register_isi_gps(void); + +#endif diff --git a/src/isi-simauth.c b/src/isi-simauth.c new file mode 100644 index 0000000..b69e5e2 --- /dev/null +++ b/src/isi-simauth.c @@ -0,0 +1,278 @@ +/* isi-simauth.c + * Dissector for ISI's SIM authentication resource + * Copyright 2010, Sebastian Reichel + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "packet-isi.h" +#include "isi-simauth.h" + +static const value_string isi_sim_auth_id[] = { + {0x01, "SIM_AUTH_PROTECTED_REQ"}, + {0x02, "SIM_AUTH_PROTECTED_RESP"}, + {0x04, "SIM_AUTH_UPDATE_REQ"}, + {0x05, "SIM_AUTH_UPDATE_SUCCESS_RESP"}, + {0x06, "SIM_AUTH_UPDATE_FAIL_RESP"}, + {0x07, "SIM_AUTH_REQ"}, + {0x08, "SIM_AUTH_SUCCESS_RESP"}, + {0x09, "SIM_AUTH_FAIL_RESP"}, + {0x10, "SIM_AUTH_STATUS_IND"}, + {0x11, "SIM_AUTH_STATUS_REQ"}, + {0x12, "SIM_AUTH_STATUS_RESP"}, + {0x00, NULL } +}; + +static const value_string isi_sim_auth_pw_type[] = { + {0x02, "SIM_AUTH_PIN"}, + {0x03, "SIM_AUTH_PUK"}, + {0x63, "SIM_AUTH_NONE"}, + {0x00, NULL} +}; + +static const value_string isi_sim_auth_protection_req[] = { + {0x00, "SIM_AUTH_PROTECTION_DISABLE"}, + {0x01, "SIM_AUTH_PROTECTION_ENABLE"}, + {0x04, "SIM_AUTH_PROTECTION_STATUS"}, + {0x00, NULL} +}; + +static const value_string isi_sim_auth_resp[] = { + {0x02, "SIM_AUTH_STATUS_RESP_NEED_PIN"}, + {0x03, "SIM_AUTH_STATUS_RESP_NEED_PUK"}, + {0x05, "SIM_AUTH_STATUS_RESP_RUNNING"}, + {0x07, "SIM_AUTH_STATUS_RESP_INIT"}, + {0x00, NULL} +}; + +static const value_string isi_sim_auth_indication[] = { + {0x01, "SIM_AUTH_NEED_AUTH"}, + {0x02, "SIM_AUTH_NEED_NO_AUTH"}, + {0x03, "SIM_AUTH_VALID"}, + {0x04, "SIM_AUTH_INVALID"}, + {0x05, "SIM_AUTH_AUTHORIZED"}, + {0x06, "SIM_AUTH_IND_CONFIG"}, + {0x00, NULL} +}; + +static const value_string isi_sim_auth_indication_cfg[] = { + {0x0B, "SIM_AUTH_PIN_PROTECTED_DISABLE"}, + {0x0C, "SIM_AUTH_PIN_PROTECTED_ENABLE"}, + {0x00, NULL} +}; + +static dissector_handle_t isi_sim_auth_handle; +static void dissect_isi_sim_auth(tvbuff_t *tvb, packet_info *pinfo, proto_item *tree); + +static guint32 hf_isi_sim_auth_cmd = -1; +static guint32 hf_isi_sim_auth_status_rsp = -1; +static guint32 hf_isi_sim_auth_protection_req = -1; +static guint32 hf_isi_sim_auth_protection_rsp = -1; +static guint32 hf_isi_sim_auth_pin = -1; +static guint32 hf_isi_sim_auth_puk = -1; +static guint32 hf_isi_sim_auth_new_pin = -1; +static guint32 hf_isi_sim_auth_pw_type = -1; +static guint32 hf_isi_sim_auth_indication = -1; +static guint32 hf_isi_sim_auth_indication_cfg = -1; + +void proto_reg_handoff_isi_sim_auth(void) { + static gboolean initialized=FALSE; + + if (!initialized) { + isi_sim_auth_handle = create_dissector_handle(dissect_isi_sim_auth, proto_isi); + dissector_add("isi.resource", 0x08, isi_sim_auth_handle); + } +} + +void proto_register_isi_sim_auth(void) { + static hf_register_info hf[] = { + { &hf_isi_sim_auth_cmd, + { "Command", "isi.sim.auth.cmd", FT_UINT8, BASE_HEX, isi_sim_auth_id, 0x0, "Command", HFILL }}, + { &hf_isi_sim_auth_pw_type, + { "Password Type", "isi.sim.auth.type", FT_UINT8, BASE_HEX, isi_sim_auth_pw_type, 0x0, "Password Type", HFILL }}, + { &hf_isi_sim_auth_pin, + { "PIN", "isi.sim.auth.pin", FT_STRING, BASE_NONE, NULL, 0x0, "PIN", HFILL }}, + { &hf_isi_sim_auth_puk, + { "PUK", "isi.sim.auth.puk", FT_STRING, BASE_NONE, NULL, 0x0, "PUK", HFILL }}, + { &hf_isi_sim_auth_new_pin, + { "New PIN", "isi.sim.auth.new_pin", FT_STRING, BASE_NONE, NULL, 0x0, "New PIN", HFILL }}, + { &hf_isi_sim_auth_protection_req, + { "Protection Request", "isi.sim.auth.request.protection", FT_UINT8, BASE_HEX, isi_sim_auth_protection_req, 0x0, "Protection Request", HFILL }}, + { &hf_isi_sim_auth_protection_rsp, + { "Protection Response", "isi.sim.auth.response.protection", FT_BOOLEAN, BASE_HEX, NULL, 0x0, "Protection Response", HFILL }}, + { &hf_isi_sim_auth_status_rsp, + { "Status Response", "isi.sim.auth.response.status", FT_UINT8, BASE_HEX, isi_sim_auth_resp, 0x0, "Status Response", HFILL }}, + { &hf_isi_sim_auth_indication, + { "Indication", "isi.sim.auth.indication", FT_UINT8, BASE_HEX, isi_sim_auth_indication, 0x0, "Indication", HFILL }}, + { &hf_isi_sim_auth_indication_cfg, + { "Configuration", "isi.sim.auth.cfg", FT_UINT8, BASE_HEX, isi_sim_auth_indication_cfg, 0x0, "Configuration", HFILL }} + }; + + proto_register_field_array(proto_isi, hf, array_length(hf)); + register_dissector("isi.sim.auth", dissect_isi_sim_auth, proto_isi); +} + +static void dissect_isi_sim_auth(tvbuff_t *tvb, packet_info *pinfo, proto_item *isitree) { + proto_item *item = NULL; + proto_tree *tree = NULL; + guint8 cmd, code; + + if(isitree) { + item = proto_tree_add_text(isitree, tvb, 0, -1, "Payload"); + tree = proto_item_add_subtree(item, ett_isi_msg); + + proto_tree_add_item(tree, hf_isi_sim_auth_cmd, tvb, 0, 1, FALSE); + cmd = tvb_get_guint8(tvb, 0); + + switch(cmd) { + case 0x01: // SIM_AUTH_PROTECTED_REQ + proto_tree_add_item(tree, hf_isi_sim_auth_protection_req, tvb, 2, 1, FALSE); + cmd = tvb_get_guint8(tvb, 2); + switch(cmd) { + case 0x00: // DISABLE + proto_tree_add_item(tree, hf_isi_sim_auth_pin, tvb, 3, -1, FALSE); + col_set_str(pinfo->cinfo, COL_INFO, "disable SIM startup protection"); + break; + case 0x01: // ENABLE + proto_tree_add_item(tree, hf_isi_sim_auth_pin, tvb, 3, -1, FALSE); + col_set_str(pinfo->cinfo, COL_INFO, "enable SIM startup protection"); + break; + case 0x04: // STATUS + col_set_str(pinfo->cinfo, COL_INFO, "get SIM startup protection status"); + break; + default: + col_set_str(pinfo->cinfo, COL_INFO, "unknown SIM startup protection package"); + break; + } + break; + case 0x02: // SIM_AUTH_PROTECTED_RESP + proto_tree_add_item(tree, hf_isi_sim_auth_protection_rsp, tvb, 1, 1, FALSE); + if(tvb_get_guint8(tvb, 1)) + col_set_str(pinfo->cinfo, COL_INFO, "SIM startup protection enabled"); + else + col_set_str(pinfo->cinfo, COL_INFO, "SIM startup protection disabled"); + break; + case 0x04: // SIM_AUTH_UPDATE_REQ + proto_tree_add_item(tree, hf_isi_sim_auth_pw_type, tvb, 1, 1, FALSE); + code = tvb_get_guint8(tvb, 1); + switch(code) { + case 0x02: // PIN + col_set_str(pinfo->cinfo, COL_INFO, "update SIM PIN"); + proto_tree_add_item(tree, hf_isi_sim_auth_pin, tvb, 2, 11, FALSE); + proto_tree_add_item(tree, hf_isi_sim_auth_new_pin, tvb, 13, 11, FALSE); + break; + case 0x03: // PUK + col_set_str(pinfo->cinfo, COL_INFO, "update SIM PUK"); + break; + default: + col_set_str(pinfo->cinfo, COL_INFO, "unknown SIM Authentication update request"); + break; + } + break; + case 0x05: // SIM_AUTH_UPDATE_SUCCESS_RESP + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication update successful"); + break; + case 0x06: // SIM_AUTH_UPDATE_FAIL_RESP + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication update failed"); + break; + case 0x07: // SIM_AUTH_REQ + proto_tree_add_item(tree, hf_isi_sim_auth_pw_type, tvb, 1, 1, FALSE); + code = tvb_get_guint8(tvb, 1); + switch(code) { + case 0x02: // PIN + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication with PIN"); + proto_tree_add_item(tree, hf_isi_sim_auth_pin, tvb, 2, 11, FALSE); + break; + case 0x03: // PUK + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication with PUK"); + proto_tree_add_item(tree, hf_isi_sim_auth_puk, tvb, 2, 11, FALSE); + proto_tree_add_item(tree, hf_isi_sim_auth_new_pin, tvb, 13, 11, FALSE); + break; + default: + col_set_str(pinfo->cinfo, COL_INFO, "unknown SIM Authentication request"); + break; + } + break; + case 0x08: // SIM_AUTH_SUCCESS_RESP + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication successful"); + break; + case 0x09: // SIM_AUTH_FAIL_RESP + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication failed"); + break; + case 0x10: // SIM_AUTH_STATUS_IND + proto_tree_add_item(tree, hf_isi_sim_auth_indication, tvb, 1, 1, FALSE); + code = tvb_get_guint8(tvb, 1); + proto_tree_add_item(tree, hf_isi_sim_auth_pw_type, tvb, 2, 1, FALSE); + switch(code) { + case 0x01: + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication indication: Authentication needed"); + break; + case 0x02: + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication indication: No Authentication needed"); + break; + case 0x03: + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication indication: Authentication valid"); + break; + case 0x04: + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication indication: Authentication invalid"); + break; + case 0x05: + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication indication: Authorized"); + break; + case 0x06: + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication indication: Config"); + proto_tree_add_item(tree, hf_isi_sim_auth_indication_cfg, tvb, 3, 1, FALSE); + break; + default: + col_set_str(pinfo->cinfo, COL_INFO, "unknown SIM Authentication indication"); + break; + } + break; + case 0x11: // SIM_AUTH_STATUS_REQ + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication status request"); + break; + case 0x12: // SIM_AUTH_STATUS_RESP + proto_tree_add_item(tree, hf_isi_sim_auth_status_rsp, tvb, 1, 1, FALSE); + code = tvb_get_guint8(tvb, 1); + switch(code) { + case 0x02: + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication status: need PIN"); + break; + case 0x03: + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication status: need PUK"); + break; + case 0x05: + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication status: running"); + break; + case 0x07: + col_set_str(pinfo->cinfo, COL_INFO, "SIM Authentication status: initializing"); + break; + default: + col_set_str(pinfo->cinfo, COL_INFO, "unknown SIM Authentication status response package"); + break; + } + break; + default: + col_set_str(pinfo->cinfo, COL_INFO, "unknown SIM Authentication package"); + break; + } + } +} diff --git a/src/isi-simauth.h b/src/isi-simauth.h new file mode 100644 index 0000000..e961e12 --- /dev/null +++ b/src/isi-simauth.h @@ -0,0 +1,7 @@ +#ifndef _ISI_SIMAUTH_H +#define _ISI_SIMAUTH_H + +void proto_reg_handoff_isi_sim_auth(void); +void proto_register_isi_sim_auth(void); + +#endif diff --git a/src/packet-isi.c b/src/packet-isi.c new file mode 100644 index 0000000..5abffb9 --- /dev/null +++ b/src/packet-isi.c @@ -0,0 +1,197 @@ +/* packet-isi.c + * Dissector for ISI protocol + * Copyright 2010, Sebastian Reichel + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "packet-isi.h" +#include "isi-simauth.h" +#include "isi-gps.h" + +#define ISI_LTYPE 0xF5 + +int proto_isi = -1; + +/* These are the handles of our subdissectors */ +static dissector_handle_t data_handle=NULL; +static dissector_handle_t isi_handle; + +/* Dissector table for the isi resource */ +static dissector_table_t isi_resource_dissector_table; + +/* Forward-declare the dissector functions */ +static void dissect_isi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + +static const value_string hf_isi_device[] = { + {0x00, "Modem" }, + {0x6c, "Host" }, + {0xFF, "Any" }, + {0x00, NULL }, +}; + +static const value_string hf_isi_resource[] = { + {0x01, "Call"}, + {0x02, "SMS"}, + {0x06, "Subscriber Services"}, + {0x08, "SIM Authentication"}, + {0x09, "SIM"}, + {0x0A, "Network"}, + {0x10, "Indication"}, + {0x15, "MTC"}, + {0x1B, "Phone Information"}, + {0x31, "GPRS"}, + {0x54, "GPS"}, + {0x62, "EPOC Info"} +}; + +static guint32 hf_isi_rdev = -1; +static guint32 hf_isi_sdev = -1; +static guint32 hf_isi_res = -1; +static guint32 hf_isi_len = -1; +static guint32 hf_isi_robj = -1; +static guint32 hf_isi_sobj = -1; +static guint32 hf_isi_id = -1; + +/* Subtree handles: set by register_subtree_array */ +static guint32 ett_isi = -1; +guint32 ett_isi_msg = -1; + +/* Handler registration */ +void proto_reg_handoff_isi(void) { + static gboolean initialized=FALSE; + + if (!initialized) { + data_handle = find_dissector("data"); + isi_handle = create_dissector_handle(dissect_isi, proto_isi); + dissector_add("sll.ltype", ISI_LTYPE, isi_handle); + + /* handoff resource dissectors */ + proto_reg_handoff_isi_sim_auth(); + proto_reg_handoff_isi_gps(); + } +} + +void proto_register_isi(void) { + /* A header field is something you can search/filter on. + * + * We create a structure to register our fields. It consists of an + * array of hf_register_info structures, each of which are of the format + * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}. + */ + static hf_register_info hf[] = { + { &hf_isi_rdev, + { "Receiver Device", "isi.rdev", FT_UINT8, BASE_HEX, + VALS(hf_isi_device), 0x0, "Receiver Device ID", HFILL }}, + { &hf_isi_sdev, + { "Sender Device", "isi.sdev", FT_UINT8, BASE_HEX, + VALS(hf_isi_device), 0x0, "Sender Device ID", HFILL }}, + { &hf_isi_res, + { "Resource", "isi.res", FT_UINT8, BASE_HEX, + VALS(hf_isi_resource), 0x0, "Resource ID", HFILL }}, + { &hf_isi_len, + { "Length", "isi.len", FT_UINT16, BASE_DEC, + NULL, 0x0, "Length", HFILL }}, + { &hf_isi_robj, + { "Receiver Object", "isi.robj", FT_UINT8, BASE_HEX, + NULL, 0x0, "Receiver Object", HFILL }}, + { &hf_isi_sobj, + { "Sender Object", "isi.sobj", FT_UINT8, BASE_HEX, + NULL, 0x0, "Sender Object", HFILL }}, + { &hf_isi_id, + { "Packet ID", "isi.id", FT_UINT8, BASE_DEC, + NULL, 0x0, "Packet ID", HFILL }} + }; + + static gint *ett[] = { + &ett_isi, + &ett_isi_msg + }; + + proto_isi = proto_register_protocol("Intelligent Service Interface", "ISI", "isi"); + + proto_register_field_array(proto_isi, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + register_dissector("isi", dissect_isi, proto_isi); + + /* create new dissector table for isi resource */ + isi_resource_dissector_table = register_dissector_table("isi.resource", "ISI resource", FT_UINT8, BASE_HEX); + + /* register resource dissectors */ + proto_register_isi_sim_auth(); + proto_register_isi_gps(); +} + +/* The dissector itself */ +static void dissect_isi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + proto_tree *isi_tree = NULL; + guint position = 0; + proto_item *item = NULL; + tvbuff_t *content = NULL; + + guint8 src = 0; + guint8 dst = 0; + guint8 resource = 0; + guint16 length = 0; + + if(check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISI"); + + if(check_col(pinfo->cinfo,COL_INFO)) + col_clear(pinfo->cinfo,COL_INFO); + + if(tree) { + /* If tree != NULL, we're doing a detailed dissection of the + * packet, so we need to construct a tree. */ + + /* Start with a top-level item to add everything else to */ + item = proto_tree_add_item(tree, proto_isi, tvb, position, -1, FALSE); + isi_tree = proto_item_add_subtree(item, ett_isi); + + /* Common Phonet/ISI Header */ + proto_tree_add_item(isi_tree, hf_isi_rdev, tvb, 0, 1, FALSE); + proto_tree_add_item(isi_tree, hf_isi_sdev, tvb, 1, 1, FALSE); + proto_tree_add_item(isi_tree, hf_isi_res, tvb, 2, 1, FALSE); + proto_tree_add_item(isi_tree, hf_isi_len, tvb, 3, 2, FALSE); + proto_tree_add_item(isi_tree, hf_isi_robj, tvb, 5, 1, FALSE); + proto_tree_add_item(isi_tree, hf_isi_sobj, tvb, 6, 1, FALSE); + proto_tree_add_item(isi_tree, hf_isi_id, tvb, 7, 1, FALSE); + + length = tvb_get_ntohs(tvb, 3) - 3; + resource = tvb_get_guint8(tvb, 2); + dst = tvb_get_guint8(tvb, 0); + src = tvb_get_guint8(tvb, 1); + + if(tvb->length - 8 < length) { + expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "Broken Length (%d > %d)", length, tvb->length-8); + length = tvb->length - 8; + } + + col_set_str(pinfo->cinfo, COL_DEF_SRC, val_to_str_const(src, hf_isi_device, "Unknown")); + col_set_str(pinfo->cinfo, COL_DEF_DST, val_to_str_const(dst, hf_isi_device, "Unknown")); + + content = tvb_new_subset(tvb, 8, length, length); + + /* Call subdissector depending on the resource ID */ + if(!dissector_try_port(isi_resource_dissector_table, resource, content, pinfo, isi_tree)) + call_dissector(data_handle, content, pinfo, isi_tree); + } +} diff --git a/src/packet-isi.h b/src/packet-isi.h new file mode 100644 index 0000000..08356db --- /dev/null +++ b/src/packet-isi.h @@ -0,0 +1,11 @@ +#ifndef _PACKET_ISI_H +#define _PACKET_ISI_H + +/* Wireshark ID of the protocol */ +extern int proto_isi; + +/* Subtree variables */ +extern guint32 ett_isi_msg; + + +#endif diff --git a/src/plugin.c b/src/plugin.c new file mode 100644 index 0000000..3d7ad2a --- /dev/null +++ b/src/plugin.c @@ -0,0 +1,16 @@ +#include + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = "0.0.1"; + +extern void proto_register_isi(void); +extern void proto_reg_handoff_isi(void); + +G_MODULE_EXPORT void plugin_register (void) { + proto_register_isi(); +} + +G_MODULE_EXPORT void plugin_reg_handoff(void) { + proto_reg_handoff_isi(); +} +#endif