Coverage Report

Created: 2026-06-30 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-e164.c
Line
Count
Source
1
/* packet-e164.c
2
 * Routines for output and filtering of E164 numbers common
3
 * to many dissectors.
4
 * Copyright 2004, Anders Broman <anders.broman@ericsson.com>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 *
12
 * Ref ITU-T E.164 05/97
13
 *     Annex to ITU Operational Bulletin No. 991 - 1.XI.2011
14
 *     Amendment No. 10 ITU Operational Bulletin No. 1057 - 1.VIII.2014
15
 * Find the bulletins here:
16
 * http://www.itu.int/pub/T-SP-OB
17
 */
18
19
#include "config.h"
20
21
#include <epan/packet.h>
22
#include "packet-e164.h"
23
#include "expert.h"
24
25
void proto_register_e164(void);
26
27
const value_string E164_country_code_value[] = {
28
  { 0,  "Reserved"},
29
  { 1,  "Americas"},
30
  { 7,  "Russian Federation, Kazakstan (Republic of)"},
31
  { 20, "Egypt (Arab Republic of)"},
32
  { 27, "South Africa (Republic of)"},
33
  { 30, "Greece"},
34
  { 31, "Netherlands (Kingdom of the)"},
35
  { 32, "Belgium"},
36
  { 33, "France"},
37
  { 34, "Spain"},
38
  { 36, "Hungary (Republic of)"},
39
  { 39, "Italy"},
40
  { 40, "Romania"},
41
  { 41, "Switzerland (Confederation of)"},
42
  { 43, "Austria"},
43
  { 44, "United Kingdom of Great Britain and Northern Ireland"},
44
  { 45, "Denmark"},
45
  { 46, "Sweden"},
46
  { 47, "Norway"},
47
  { 48, "Poland (Republic of)"},
48
  { 49, "Germany (Federal Republic of)"},
49
  { 51, "Peru"},
50
  { 52, "Mexico"},
51
  { 53, "Cuba"},
52
  { 54, "Argentine Republic"},
53
  { 55, "Brazil (Federative Republic of)"},
54
  { 56, "Chile"},
55
  { 57, "Colombia (Republic of)"},
56
  { 58, "Venezuela(Bolivarian Republic of)"},
57
  { 60, "Malaysia"},
58
  { 61, "Australia"},
59
  { 62, "Indonesia (Republic of)"},
60
  { 63, "Philippines (Republic of the)"},
61
  { 64, "New Zealand"},
62
  { 65, "Singapore (Republic of)"},
63
  { 66, "Thailand"},
64
  { 81, "Japan"},
65
  { 82, "Korea (Republic of)"},
66
  { 84, "Viet Nam (Socialist Republic of)"},
67
  { 86, "China (People's Republic of)"},
68
  { 90, "Turkey"},
69
  { 91, "India (Republic of)"},
70
  { 92, "Pakistan (Islamic Republic of)"},
71
  { 93, "Afghanistan"},
72
  { 94, "Sri Lanka (Democratic Socialist Republic of)"},
73
  { 95, "Myanmar (the Republic of the Union of)"},
74
  { 98, "Iran (Islamic Republic of)"},
75
  { 210,  "Spare code"},
76
  { 211,  "South Sudan (Republic of)"},
77
  { 212,  "Morocco (Kingdom of)"},
78
  { 213,  "Algeria (People's Democratic Republic of)"},
79
  { 214,  "Spare code"},
80
  { 215,  "Spare code"},
81
  { 216,  "Tunisia"},
82
  { 217,  "Spare code"},
83
  { 218,  "Libya (Socialist People's Libyan Arab Jamahiriya)"},
84
  { 219,  "Spare code"},
85
  { 220,  "Gambia (Republic of)"},
86
  { 221,  "Senegal (Republic of)"},
87
  { 222,  "Mauritania (Islamic Republic of)"},
88
  { 223,  "Mali (Republic of)"},
89
  { 224,  "Guinea (Republic of)"},
90
  { 225,  "Cote d'Ivoire (Republic of)"},
91
  { 226,  "Burkina Faso"},
92
  { 227,  "Niger (Republic of the)"},
93
  { 228,  "Togolese Republic"},
94
  { 229,  "Benin (Republic of)"},
95
  { 230,  "Mauritius (Republic of)"},
96
  { 231,  "Liberia (Republic of)"},
97
  { 232,  "Sierra Leone"},
98
  { 233,  "Ghana"},
99
  { 234,  "Nigeria (Federal Republic of)"},
100
  { 235,  "Chad (Republic of)"},
101
  { 236,  "Central African Republic"},
102
  { 237,  "Cameroon (Republic of)"},
103
  { 238,  "Cape Verde (Republic of)"},
104
  { 239,  "Sao Tome and Principe (Democratic Republic of)"},
105
  { 240,  "Equatorial Guinea (Republic of)"},
106
  { 241,  "Gabonese Republic"},
107
  { 242,  "Congo (Republic of the)"},
108
  { 243,  "Democratic Republic of Congo"},
109
  { 244,  "Angola (Republic of)"},
110
  { 245,  "Guinea-Bissau (Republic of)"},
111
  { 246,  "Diego Garcia"},
112
  { 247,  "Saint Helena, Ascension and Tristan da Cunha"},
113
  { 248,  "Seychelles (Republic of)"},
114
  { 249,  "Sudan (Republic of the)"},
115
  { 250,  "Rwanda (Republic of)"},
116
  { 251,  "Ethiopia (Federal Democratic Republic of)"},
117
  { 252,  "Somali Democratic Republic"},
118
  { 253,  "Djibouti (Republic of)"},
119
  { 254,  "Kenya (Republic of)"},
120
  { 255,  "Tanzania (United Republic of)"},
121
  { 256,  "Uganda (Republic of)"},
122
  { 257,  "Burundi (Republic of)"},
123
  { 258,  "Mozambique (Republic of)"},
124
  { 259,  "Spare code"},
125
  { 260,  "Zambia (Republic of)"},
126
  { 261,  "Madagascar (Republic of)"},
127
  { 262,  "French Departments and Territories in the Indian Ocean"},
128
  { 263,  "Zimbabwe (Republic of)"},
129
  { 264,  "Namibia (Republic of)"},
130
  { 265,  "Malawi"},
131
  { 266,  "Lesotho (Kingdom of)"},
132
  { 267,  "Botswana (Republic of)"},
133
  { 268,  "Swaziland (Kingdom of)"},
134
  { 269,  "Comoros (Union of the)"},
135
  { 280,  "Spare code"},
136
  { 281,  "Spare code"},
137
  { 282,  "Spare code"},
138
  { 283,  "Spare code"},
139
  { 284,  "Spare code"},
140
  { 285,  "Spare code"},
141
  { 286,  "Spare code"},
142
  { 287,  "Spare code"},
143
  { 288,  "Spare code"},
144
  { 289,  "Spare code"},
145
  { 290,  "Saint Helena, Ascension and Tristan da Cunha"},
146
  { 291,  "Eritrea"},
147
  { 292,  "Spare code"},
148
  { 293,  "Spare code"},
149
  { 294,  "Spare code"},
150
  { 295,  "Spare code"},
151
  { 296,  "Spare code"},
152
  { 297,  "Aruba"},
153
  { 298,  "Faroe Islands"},
154
  { 299,  "Greenland (Denmark)"},
155
  { 350,  "Gibraltar"},
156
  { 351,  "Portugal"},
157
  { 352,  "Luxembourg"},
158
  { 353,  "Ireland"},
159
  { 354,  "Iceland"},
160
  { 355,  "Albania (Republic of)"},
161
  { 356,  "Malta"},
162
  { 357,  "Cyprus (Republic of)"},
163
  { 358,  "Finland"},
164
  { 359,  "Bulgaria (Republic of)"},
165
  { 370,  "Lithuania (Republic of)"},
166
  { 371,  "Latvia (Republic of)"},
167
  { 372,  "Estonia (Republic of)"},
168
  { 373,  "Moldova (Republic of)"},
169
  { 374,  "Armenia (Republic of)"},
170
  { 375,  "Belarus (Republic of)"},
171
  { 376,  "Andorra (Principality of)"},
172
  { 377,  "Monaco (Principality of)"},
173
  { 378,  "San Marino (Republic of)"},
174
  { 379,  "Vatican City State"},
175
  { 380,  "Ukraine"},
176
  { 381,  "Serbia (Republic of)"},
177
  { 382,  "Montenegro (Republic of)"},
178
  { 383,  "Spare code"},
179
  { 384,  "Spare code"},
180
  { 385,  "Croatia (Republic of)"},
181
  { 386,  "Slovenia (Republic of)"},
182
  { 387,  "Bosnia and Herzegovina"},
183
  { 388,  "Group of countries, shared code"},
184
  { 389,  "The Former Yugoslav Republic of Macedonia"},
185
  { 420,  "Czech Republic"},
186
  { 421,  "Slovak Republic"},
187
  { 422,  "Spare code"},
188
  { 423,  "Liechtenstein (Principality of)"},
189
  { 424,  "Spare code"},
190
  { 425,  "Spare code"},
191
  { 426,  "Spare code"},
192
  { 427,  "Spare code"},
193
  { 428,  "Spare code"},
194
  { 429,  "Spare code"},
195
  { 500,  "Falkland Islands (Malvinas)"},
196
  { 501,  "Belize"},
197
  { 502,  "Guatemala (Republic of)"},
198
  { 503,  "El Salvador (Republic of)"},
199
  { 504,  "Honduras (Republic of)"},
200
  { 505,  "Nicaragua"},
201
  { 506,  "Costa Rica"},
202
  { 507,  "Panama (Republic of)"},
203
  { 508,  "Saint Pierre and Miquelon (Collectivite territoriale de la Republique francaise)"},
204
  { 509,  "Haiti (Republic of)"},
205
  { 590,  "Guadeloupe (French Department of)"},
206
  { 591,  "Bolivia (Plurinational State of)"},
207
  { 592,  "Guyana"},
208
  { 593,  "Ecuador"},
209
  { 594,  "French Guiana (French Department of)"},
210
  { 595,  "Paraguay (Republic of)"},
211
  { 596,  "Martinique (French Department of)"},
212
  { 597,  "Suriname (Republic of)"},
213
  { 598,  "Uruguay (Eastern Republic of)"},
214
  { 599,  "Bonaire, Saint Eustatius and Saba, Curacao"},
215
  { 670,  "Democratic Republic of Timor-Leste"},
216
  { 671,  "Spare code"},
217
  { 672,  "Australian External Territories"},
218
  { 673,  "Brunei Darussalam"},
219
  { 674,  "Nauru (Republic of)"},
220
  { 675,  "Papua New Guinea"},
221
  { 676,  "Tonga (Kingdom of)"},
222
  { 677,  "Solomon Islands"},
223
  { 678,  "Vanuatu (Republic of)"},
224
  { 679,  "Fiji (Republic of)"},
225
  { 680,  "Palau (Republic of)"},
226
  { 681,  "Wallis and Futuna (Territoire francais d'outre-mer)"},
227
  { 682,  "Cook Islands"},
228
  { 683,  "Niue"},
229
  { 684,  "Spare code"},
230
  { 685,  "Samoa (Independent State of)"},
231
  { 686,  "Kiribati (Republic of)"},
232
  { 687,  "New Caledonia (Territoire francais d'outre-mer)"},
233
  { 688,  "Tuvalu"},
234
  { 689,  "French Polynesia (Territoire francais d'outre-mer)"},
235
  { 690,  "Tokelau"},
236
  { 691,  "Micronesia (Federated States of)"},
237
  { 692,  "Marshall Islands (Republic of the)"},
238
  { 693,  "Spare code"},
239
  { 694,  "Spare code"},
240
  { 695,  "Spare code"},
241
  { 696,  "Spare code"},
242
  { 697,  "Spare code"},
243
  { 698,  "Spare code"},
244
  { 699,  "Spare code"},
245
  { 800,  "International Freephone Service"},
246
  { 801,  "Spare code"},
247
  { 802,  "Spare code"},
248
  { 803,  "Spare code"},
249
  { 804,  "Spare code"},
250
  { 805,  "Spare code"},
251
  { 806,  "Spare code"},
252
  { 807,  "Spare code"},
253
  { 808,  "International Shared Cost Service (ISCS)"},
254
  { 809,  "Spare code"},
255
  { 830,  "Spare code"},
256
  { 831,  "Spare code"},
257
  { 832,  "Spare code"},
258
  { 833,  "Spare code"},
259
  { 834,  "Spare code"},
260
  { 835,  "Spare code"},
261
  { 836,  "Spare code"},
262
  { 837,  "Spare code"},
263
  { 838,  "Spare code"},
264
  { 839,  "Spare code"},
265
  { 850,  "Democratic People's Republic of Korea"},
266
  { 851,  "Spare code"},
267
  { 852,  "Hong Kong, China"},
268
  { 853,  "Macau, China"},
269
  { 854,  "Spare code"},
270
  { 855,  "Cambodia (Kingdom of)"},
271
  { 856,  "Lao People's Democratic Republic"},
272
  { 857,  "Spare code"},
273
  { 858,  "Spare code"},
274
  { 859,  "Spare code"},
275
  { 870,  "Inmarsat SNAC"},
276
  { 871,  "Spare code"},
277
  { 872,  "Spare code"},
278
  { 873,  "Spare code"},
279
  { 874,  "Spare code"},
280
  { 875,  "Reserved - Maritime Mobile Service Applications"},
281
  { 876,  "Reserved - Maritime Mobile Service Applications"},
282
  { 877,  "Reserved - Maritime Mobile Service Applications"},
283
  { 878,  "Universal Personal Telecommunication Service (UPT)"},
284
  { 879,  "Reserved for national non-commercial purposes"},
285
  { 880,  "Bangladesh"},
286
  { 881,  "Global Mobile Satellite System (GMSS), shared code"},
287
  { 882,  "International Networks, shared code"},
288
  { 883,  "International Networks, shared code"},
289
  { 884,  "Spare code"},
290
  { 885,  "Spare code"},
291
  { 886,  "Taiwan, China"},
292
  { 887,  "Spare code"},
293
  { 888,  "Telecommunications for Disaster Relief (TDR)"},
294
  { 889,  "Spare code"},
295
  { 890,  "Spare code"},
296
  { 891,  "Spare code"},
297
  { 892,  "Spare code"},
298
  { 893,  "Spare code"},
299
  { 894,  "Spare code"},
300
  { 895,  "Spare code"},
301
  { 896,  "Spare code"},
302
  { 897,  "Spare code"},
303
  { 898,  "Spare code"},
304
  { 899,  "Spare code"},
305
  { 960,  "Maldives (Republic of)"},
306
  { 961,  "Lebanon"},
307
  { 962,  "Jordan (Hashemite Kingdom of)"},
308
  { 963,  "Syrian Arab Republic"},
309
  { 964,  "Iraq (Republic of)"},
310
  { 965,  "Kuwait (State of)"},
311
  { 966,  "Saudi Arabia (Kingdom of)"},
312
  { 967,  "Yemen (Republic of)"},
313
  { 968,  "Oman (Sultanate of)"},
314
  { 969,  "Reserved - reservation currently under investigation"},
315
  { 970,  "Reserved"},
316
  { 971,  "United Arab Emirates"},
317
  { 972,  "Israel (State of)"},
318
  { 973,  "Bahrain (Kingdom of)"},
319
  { 974,  "Qatar (State of)"},
320
  { 975,  "Bhutan (Kingdom of)"},
321
  { 976,  "Mongolia"},
322
  { 977,  "Nepal (Federal Democratic Republic of)"},
323
  { 978,  "Spare code"},
324
  { 979,  "International Premium Rate Service (IPRS)"},
325
  { 990,  "Spare code"},
326
  { 991,  "Trial of a proposed new international telecommunication public correspondence service, shared code"},
327
  { 992,  "Tajikstan (Republic of)"},
328
  { 993,  "Turkmenistan"},
329
  { 994,  "Azerbaijan"},
330
  { 995,  "Georgia"},
331
  { 996,  "Kyrgyz Republic"},
332
  { 997,  "Spare code"},
333
  { 998,  "Uzbekistan (Republic of)"},
334
  { 999,  "Reserved for future global service"},
335
  { 0,  NULL }
336
};
337
static value_string_ext E164_country_code_value_ext = VALUE_STRING_EXT_INIT(E164_country_code_value);
338
339
/* Country code from ITU-T E.164 to ISO 3166 two letters country name */
340
const value_string E164_ISO3166_country_code_short_value[] = {
341
    { 1,  "us" }, { 7,  "ru" }, { 20,   "eg" }, { 27,   "za" },
342
    { 30,   "gr" }, { 31,   "nl" }, { 32,   "be" }, { 33,   "fr" },
343
    { 34,   "es" }, { 36,   "hu" }, { 39,   "it" }, { 40,   "ro" },
344
    { 41,   "ch" }, { 43,   "at" }, { 44,   "gb" }, { 45,   "dk" },
345
    { 46,   "se" }, { 47,   "no" }, { 48,   "pl" }, { 49,   "de" },
346
    { 51,   "pe" }, { 52,   "mx" }, { 53,   "cu" }, { 54,   "ar" },
347
    { 55,   "br" }, { 56,   "cl" }, { 57,   "co" }, { 58,   "ve" },
348
    { 60,   "my" }, { 61,   "au" }, { 62,   "id" }, { 63,   "ph" },
349
    { 64,   "nz" }, { 65,   "sg" }, { 66,   "th" }, { 81,   "jp" },
350
    { 82,   "kr" }, { 84,   "vn" }, { 86,   "cn" }, { 90,   "tr" },
351
    { 91,   "in" }, { 92,   "pk" }, { 93,   "af" }, { 94,   "lk" },
352
    { 98,   "ir" }, { 95,   "mm" },
353
354
    { 212,  "ma" }, { 213,  "dz" }, { 216,  "tn" }, { 218,  "ly" },
355
    { 220,  "gm" }, { 221,  "sn" }, { 222,  "mr" }, { 223,  "ml" },
356
    { 224,  "gn" }, { 225,  "ci" }, { 226,  "bf" }, { 227,  "ne" },
357
    { 228,  "tg" }, { 229,  "bj" }, { 230,  "mu" }, { 231,  "lr" },
358
    { 232,  "sl" }, { 233,  "gh" }, { 234,  "ng" }, { 235,  "td" },
359
    { 236,  "cf" }, { 237,  "cm" }, { 238,  "cv" }, { 239,  "st" },
360
    { 240,  "gq" }, { 241,  "ga" }, { 242,  "cg" }, { 243,  "cd" },
361
    { 244,  "ao" }, { 245,  "gw" }, { 248,  "sc" }, { 249,  "sd" },
362
    { 250,  "rw" }, { 251,  "et" }, { 252,  "so" }, { 253,  "dj" },
363
    { 254,  "ke" }, { 255,  "tz" }, { 256,  "ug" }, { 257,  "bi" },
364
    { 258,  "mz" }, { 260,  "zm" }, { 261,  "mg" }, { 262,  "fr" },
365
    { 263,  "zw" }, { 264,  "na" }, { 265,  "mw" }, { 266,  "ls" },
366
    { 267,  "bw" }, { 268,  "sz" }, { 269,  "km" }, { 290,  "sh" },
367
    { 291,  "er" }, { 297,  "aw" }, { 298,  "fo" }, { 299,  "gl" },
368
369
    { 350,  "gi" }, { 351,  "pt" }, { 352,  "lu" }, { 353,  "ie" },
370
    { 354,  "is" }, { 355,  "al" }, { 356,  "mt" }, { 357,  "cy" },
371
    { 358,  "fi" }, { 359,  "bg" }, { 370,  "lt" }, { 371,  "lv" },
372
    { 372,  "ee" }, { 373,  "md" }, { 374,  "am" }, { 375,  "by" },
373
    { 376,  "ad" }, { 377,  "mc" }, { 378,  "sm" }, { 379,  "va" },
374
    { 380,  "ua" }, { 385,  "hr" }, { 386,  "si" }, { 387,  "ba" },
375
376
    { 420,  "cz" }, { 421,  "sk" }, { 423,  "li" },
377
378
    { 500,  "fk" }, { 501,  "bz" }, { 502,  "gt" }, { 503,  "sv" },
379
    { 504,  "hn" }, { 505,  "ni" }, { 506,  "cr" }, { 507,  "pa" },
380
    { 508,  "pm" }, { 509,  "ht" }, { 590,  "gp" }, { 591,  "bo" },
381
    { 592,  "gy" }, { 593,  "ec" }, { 594,  "gf" }, { 595,  "py" },
382
    { 596,  "mq" }, { 597,  "sr" }, { 598,  "uy" },
383
384
    { 673,  "bn" }, { 682,  "ck" }, { 670,  "tl" }, { 674,  "nr" },
385
    { 675,  "pg" }, { 676,  "to" }, { 677,  "sb" }, { 678,  "vu" },
386
    { 679,  "fj" }, { 680,  "pw" }, { 681,  "wf" }, { 683,  "nu" },
387
    { 685,  "ws" }, { 686,  "ki" }, { 687,  "nc" }, { 688,  "tv" },
388
    { 689,  "pf" }, { 690,  "tk" }, { 691,  "fm" }, { 692,  "mh" },
389
390
    { 850,  "kp" }, { 852,  "hk" }, { 853,  "mo" }, { 855,  "kh" },
391
    { 856,  "la" }, { 880,  "bd" },
392
393
    { 960,  "mv" }, { 961,  "lb" }, { 962,  "jo" }, { 963,  "sy" },
394
    { 964,  "iq" }, { 965,  "kw" }, { 966,  "sa" }, { 967,  "ye" },
395
    { 968,  "om" }, { 971,  "ae" }, { 972,  "il" }, { 973,  "bh" },
396
    { 974,  "qa" }, { 975,  "bt" }, { 976,  "mn" }, { 977,  "np" },
397
    { 992,  "tj" }, { 993,  "tm" }, { 994,  "az" }, { 995,  "ge" },
398
    { 996,  "kg" }, { 998,  "uz" },
399
400
    { 0,  NULL }
401
};
402
value_string_ext E164_ISO3166_country_code_short_value_ext = VALUE_STRING_EXT_INIT(E164_ISO3166_country_code_short_value);
403
404
static const value_string E164_GMSS_vals[] = {
405
  { 6,  "Iridium Satellite LLC"},
406
  { 7,  "Iridium Satellite LLC"},
407
  { 8,  "Globalstar"},
408
  { 9,  "Globalstar"},
409
  { 0,  NULL }
410
};
411
412
static const value_string E164_International_Networks_882_vals[] = {
413
  { 10, "Global Office Application"},
414
  { 12, "HyperStream International (HSI) Data Network"},
415
  { 13, "EMS Regional Mobile Satellite System"},
416
  { 15, "Global international ATM Network"},
417
  { 16, "Thuraya RMSS Network"},
418
  { 20, "Garuda Mobile Telecommunication Satellite System"},
419
  { 22, "Cable & Wireless Global Network"},
420
  { 23, "Sita-Equant Network"},
421
  { 24, "TeliaSonera Sverige AB"},
422
  { 28, "Deutsche Telekom's Next Generation Network"},
423
  { 31, "Global International ATM Network"},
424
  { 32, "MCP network"},
425
  { 33, "Oration Technologies Network"},
426
  { 34, "BebbiCell AG"},
427
  { 35, "Jasper System"},
428
  { 36, "Jersey Telecom"},
429
  { 37, "Cingular Wireless network"},
430
  { 39, "Vodafone Malta"},
431
  { 40, "Oy Communications"},
432
  { 41, "Intermatica"},
433
  { 42, "Seanet Maritime Communication"},
434
  { 43, "Beeline"},
435
  { 45, "Telecom Italia"},
436
  { 46, "Tyntec GmbH"},
437
  { 47, "Transatel"},
438
  { 97, "Smart Communications Inc"},
439
  { 98, "Onair GSM services"},
440
  { 99, "Telenor GSM network - services in aircraft"},
441
  { 0,  NULL }
442
};
443
static value_string_ext E164_International_Networks_882_vals_ext = VALUE_STRING_EXT_INIT(E164_International_Networks_882_vals);
444
445
static const value_string E164_International_Networks_883_vals[] = {
446
  { 100,  "MediaLincc Ltd"},
447
  { 110,  "Aicent Inc"},
448
  { 120,  "Telenor Connexion AB"},
449
  { 130,  "France Telecom Orange"},
450
  { 140,  "Multiregional TransitTelecom (MTT)"},
451
  { 150,  "BodyTrace Netherlands B.V"},
452
  { 5100, "Voxbone SA"},
453
  { 5110, "Bandwidth.com Inc"},
454
  { 5120, "MTX Connect Ltd"},
455
  { 5130, "SIMPE Ltd"},
456
  { 5140, "Ellipsat Inc"},
457
  { 5150, "Wins Limited"},
458
  { 0,  NULL }
459
};
460
461
static int proto_e164;
462
static int hf_E164_calling_party_number;
463
static int hf_E164_called_party_number;
464
static int hf_E164_msisdn;
465
static int hf_E164_isdn;
466
static int hf_E164_identification_code;
467
static int hf_E164_country_code;
468
469
static int ett_e164_msisdn;
470
471
static expert_field ei_E164_country_code_non_decimal;
472
static expert_field ei_E164_identification_code_non_decimal;
473
474
void
475
dissect_e164_number(tvbuff_t *tvb, proto_tree *tree, int offset, int length, e164_info_t e164_info)
476
148
{
477
148
  proto_item *pi;
478
479
148
  switch (e164_info.e164_number_type) {
480
41
  case CALLING_PARTY_NUMBER:
481
41
    proto_tree_add_string(tree, hf_E164_calling_party_number, tvb, offset,
482
41
              length, e164_info.E164_number_str);
483
41
    break;
484
485
107
  case CALLED_PARTY_NUMBER:
486
107
    proto_tree_add_string(tree, hf_E164_called_party_number, tvb, offset,
487
107
              length, e164_info.E164_number_str);
488
107
    break;
489
490
0
  default:
491
0
    break;
492
148
  }
493
494
148
  if (e164_info.nature_of_address == E164_NA_INTERNATIONAL_NUMBER) {
495
17
    pi = proto_tree_add_string(tree, hf_E164_msisdn, tvb, offset, length, e164_info.E164_number_str);
496
17
    proto_item_set_hidden(pi);
497
17
  }
498
148
}
499
500
/**
501
 * Convert 16bit integer in BCD encoding to decimal.
502
 * @param bcd   BCD value to convert.
503
 * @param[out] dec  Pointer to decimal result.
504
 * @return true if ok, false if bcd contains a nibble > 9.
505
 */
506
static bool
507
convert_bcd_to_dec(uint16_t bcd, uint16_t * dec)
508
256
{
509
256
  bool rok = true;
510
256
  uint16_t result = 0;
511
256
  uint16_t mult = 1;
512
785
  while (bcd) {
513
529
    if ((bcd & 0x0f) > 9)
514
113
      rok = false;
515
529
    result += (bcd & 0x0f) * mult;
516
529
    bcd >>= 4;
517
529
    mult *= 10;
518
529
  }
519
256
  *dec = result;
520
256
  return rok;
521
256
}
522
523
void
524
dissect_e164_cc(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset, e164_encoding_t encoding)
525
257
{
526
257
  int cc_offset;
527
257
  uint8_t address_digit_pair;
528
257
  uint16_t  id_code = 0;
529
257
  uint8_t cc_length;
530
257
  uint8_t length;
531
257
  uint16_t cc = 0;
532
257
  bool bcd_ok = false;
533
257
  proto_item *item = NULL;
534
535
257
  cc_offset = offset;
536
257
  address_digit_pair = tvb_get_uint8(tvb, cc_offset);
537
538
  /* Get the first 3 digits of the MSISDN */
539
257
  switch (encoding) {
540
0
  case E164_ENC_BINARY:
541
    /* Dissect country code after removing non significant zeros */
542
0
    while (address_digit_pair == 0) {
543
0
      cc_offset = cc_offset + 1;
544
0
      address_digit_pair = tvb_get_uint8(tvb, cc_offset);
545
0
    }
546
0
    cc = tvb_get_ntohs(tvb, cc_offset);
547
0
    if ((address_digit_pair & 0xf0) != 0) {
548
0
      cc = cc >> 4;
549
0
    }
550
0
    break;
551
229
  case E164_ENC_BCD:
552
229
    cc = address_digit_pair &0x0f;
553
229
    cc = cc << 4;
554
229
    cc = cc | (address_digit_pair &0xf0)>>4;
555
229
    cc = cc << 4;
556
229
    if (tvb_bytes_exist(tvb, cc_offset+1, 1)) {
557
229
      address_digit_pair = tvb_get_uint8(tvb, cc_offset+1);
558
229
      cc = cc | (address_digit_pair &0x0f);
559
229
    }
560
229
    break;
561
27
  case E164_ENC_UTF8:
562
    /* XXX - do we need to worry about leading 0s? */
563
27
    cc  = (tvb_get_uint8(tvb, cc_offset)   - '0') << 8;
564
27
    cc |= (tvb_get_uint8(tvb, cc_offset+1) - '0') << 4;
565
27
    cc |= (tvb_get_uint8(tvb, cc_offset+2) - '0');
566
27
    break;
567
257
  }
568
569
  /* Determine how many of those digits are the Country Code */
570
256
  switch (cc & 0x0f00) {
571
33
  case 0x0:
572
33
    cc_length = 1;
573
33
    break;
574
41
  case 0x0100:
575
41
    cc_length = 1;
576
41
    break;
577
7
  case 0x0200:
578
7
    switch (cc & 0x00f0) {
579
4
    case 0:
580
4
    case 0x70:
581
4
      cc_length = 2;
582
4
      break;
583
3
    default:
584
3
      cc_length = 3;
585
3
      break;
586
7
    }
587
7
    break;
588
17
  case 0x0300:
589
17
    switch (cc & 0x00f0) {
590
2
    case 0:
591
4
    case 0x10:
592
7
    case 0x20:
593
12
    case 0x30:
594
14
    case 0x40:
595
14
    case 0x60:
596
15
    case 0x90:
597
15
      cc_length = 2;
598
15
      break;
599
2
    default:
600
2
      cc_length = 3;
601
2
      break;
602
17
    }
603
17
    break;
604
17
  case 0x0400:
605
4
    switch (cc & 0x00f0) {
606
1
    case 0x20:
607
1
      cc_length = 3;
608
1
      break;
609
3
    default:
610
3
      cc_length = 2;
611
3
      break;
612
4
    }
613
4
    break;
614
4
  case 0x0500:
615
4
    switch (cc & 0x00f0) {
616
2
    case 0:
617
2
    case 0x90:
618
2
      cc_length = 3;
619
2
      break;
620
2
    default:
621
2
      cc_length = 2;
622
2
      break;
623
4
    }
624
4
    break;
625
4
  case 0x0600:
626
2
    switch (cc & 0x00f0) {
627
0
    case 0x70:
628
0
    case 0x80:
629
0
    case 0x90:
630
0
      cc_length = 3;
631
0
      break;
632
2
    default:
633
2
      cc_length = 2;
634
2
      break;
635
2
    }
636
2
    break;
637
26
  case 0x0700:
638
26
    cc_length = 1;
639
26
    break;
640
72
  case 0x0800:
641
72
    switch (cc & 0x00f0) {
642
0
    case 0x10:
643
1
    case 0x20:
644
1
    case 0x40:
645
1
    case 0x60:
646
1
      cc_length = 2;
647
1
      break;
648
71
    default:
649
71
      cc_length = 3;
650
71
      break;
651
72
    }
652
72
    break;
653
72
  case 0x0900:
654
8
    switch (cc & 0x00f0) {
655
1
    case 0:
656
3
    case 0x10:
657
3
    case 0x20:
658
3
    case 0x30:
659
5
    case 0x40:
660
5
    case 0x50:
661
6
    case 0x80:
662
6
      cc_length = 2;
663
6
      break;
664
2
    default:
665
2
      cc_length = 3;
666
2
      break;
667
8
    }
668
8
    break;
669
670
42
  default:
671
42
    cc_length = 0;
672
42
    break;
673
256
  } /* End switch cc */
674
675
  /* (Now that we know how long the CC is,)
676
   * shift off any extra digits we got.
677
   */
678
256
  switch (cc_length) {
679
100
  case 1:
680
100
    cc = cc >> 8;
681
100
    length = 1;
682
100
    break;
683
33
  case 2:
684
33
    cc = cc >> 4;
685
33
    length = 1;
686
33
    break;
687
123
  default:
688
123
    length = 2;
689
123
    break;
690
256
  } /* end switch cc_length */
691
692
  /* Now process the CC as decimal */
693
256
  bcd_ok = convert_bcd_to_dec(cc, &cc);
694
695
  /* Display the CC */
696
256
  if (encoding == E164_ENC_UTF8)
697
27
      item = proto_tree_add_uint(tree, hf_E164_country_code, tvb, cc_offset, cc_length, cc);
698
229
  else
699
229
      item = proto_tree_add_uint(tree, hf_E164_country_code, tvb, cc_offset, length, cc);
700
256
  if (!bcd_ok) {
701
67
    expert_add_info(pinfo, item, &ei_E164_country_code_non_decimal);
702
67
  }
703
704
  /* Handle special Country Codes */
705
256
  switch (cc) {
706
0
  case 881:
707
    /* Get the 1-digit ID code */
708
0
    switch (encoding) {
709
0
    case E164_ENC_BINARY:
710
0
      id_code = tvb_get_uint8(tvb, cc_offset + 1) & 0x0f;
711
0
      break;
712
0
    case E164_ENC_BCD:
713
0
      id_code = (tvb_get_uint8(tvb, cc_offset + 1) & 0xf0) >> 4;
714
0
      break;
715
0
    case E164_ENC_UTF8:
716
0
      id_code = tvb_get_uint8(tvb, cc_offset + cc_length) - '0';
717
0
      break;
718
0
    }
719
0
    bcd_ok = (id_code <= 9);
720
0
    item = proto_tree_add_uint_format_value(tree, hf_E164_identification_code, tvb, (cc_offset + 1), 1,
721
0
            id_code, "%d %s", id_code, val_to_str_const(id_code, E164_GMSS_vals, "Unknown"));
722
0
    if (!bcd_ok) {
723
0
      expert_add_info(pinfo, item, &ei_E164_identification_code_non_decimal);
724
0
    }
725
0
    break;
726
0
  case 882:
727
    /* Get the 2-digit ID code */
728
0
    switch (encoding) {
729
0
    case E164_ENC_BINARY:
730
0
      id_code = tvb_get_ntohs(tvb, cc_offset + 1);
731
0
      id_code = (id_code & 0x0ff0) >> 4;
732
0
      break;
733
0
    case E164_ENC_BCD:
734
0
      id_code  = tvb_get_uint8(tvb, cc_offset + 1) & 0xf0;
735
0
      id_code |= tvb_get_uint8(tvb, cc_offset + 2) & 0x0f;
736
0
      break;
737
0
    case E164_ENC_UTF8:
738
0
      id_code  = (tvb_get_uint8(tvb, cc_offset+cc_length)   - '0') << 4;
739
0
      id_code |= (tvb_get_uint8(tvb, cc_offset+cc_length+1) - '0');
740
0
      break;
741
0
    }
742
0
    bcd_ok = convert_bcd_to_dec(id_code, &id_code);
743
0
    item = proto_tree_add_uint_format_value(tree, hf_E164_identification_code, tvb, (cc_offset + 1), 2,
744
0
            id_code, "%d %s", id_code, val_to_str_ext_const(id_code, &E164_International_Networks_882_vals_ext, "Unknown"));
745
0
    if (!bcd_ok) {
746
0
      expert_add_info(pinfo, item, &ei_E164_identification_code_non_decimal);
747
0
    }
748
0
    break;
749
0
  case 883:
750
    /* Get the 3-digit ID code */
751
0
    switch (encoding) {
752
0
    case E164_ENC_BINARY:
753
0
      id_code = tvb_get_ntohs(tvb, cc_offset + 1);
754
0
      id_code = id_code & 0x0fff;
755
0
      break;
756
0
    case E164_ENC_BCD:
757
0
      id_code  = (tvb_get_uint8(tvb, cc_offset + 1) & 0xf0) << 4;
758
0
      id_code |= (tvb_get_uint8(tvb, cc_offset + 2) & 0x0f) << 4;
759
0
      id_code |= (tvb_get_uint8(tvb, cc_offset + 2) & 0xf0) >> 4;
760
0
      break;
761
0
    case E164_ENC_UTF8:
762
0
      id_code  = (tvb_get_uint8(tvb, cc_offset+cc_length)   - '0') << 8;
763
0
      id_code |= (tvb_get_uint8(tvb, cc_offset+cc_length+1) - '0') << 4;
764
0
      id_code |= (tvb_get_uint8(tvb, cc_offset+cc_length+2) - '0');
765
0
      break;
766
0
    }
767
0
    if ((id_code & 0x0ff0) == 0x510) {
768
      /* Get the 4th digit of the ID code */
769
0
      switch (encoding) {
770
0
      case E164_ENC_BINARY:
771
0
        id_code = (id_code << 4) | ((tvb_get_uint8(tvb, cc_offset + 3) & 0xf0) >> 4);
772
0
        break;
773
0
      case E164_ENC_BCD:
774
0
        id_code = (id_code << 4) | (tvb_get_uint8(tvb, cc_offset + 3) & 0x0f);
775
0
        break;
776
0
      case E164_ENC_UTF8:
777
0
        id_code = (id_code << 4) | (tvb_get_uint8(tvb, cc_offset + cc_length + 3) - '0');
778
0
        break;
779
0
      }
780
0
      bcd_ok = convert_bcd_to_dec(id_code, &id_code);
781
0
      item = proto_tree_add_uint_format_value(tree, hf_E164_identification_code, tvb, (cc_offset + 1), 3,
782
0
          id_code, "%d %s", id_code, val_to_str_const(id_code, E164_International_Networks_883_vals, "Unknown"));
783
0
      if (!bcd_ok) {
784
0
        expert_add_info(pinfo, item, &ei_E164_identification_code_non_decimal);
785
0
      }
786
0
    } else {
787
0
      bcd_ok = convert_bcd_to_dec(id_code, &id_code);
788
0
      item = proto_tree_add_uint_format_value(tree, hf_E164_identification_code, tvb, (cc_offset + 1), 2,
789
0
          id_code, "%d %s", id_code, val_to_str_const(id_code, E164_International_Networks_883_vals, "Unknown"));
790
0
      if (!bcd_ok) {
791
0
        expert_add_info(pinfo, item, &ei_E164_identification_code_non_decimal);
792
0
      }
793
0
    }
794
0
    break;
795
256
  default:
796
256
    break;
797
256
  }
798
799
256
}
800
801
static const char *
802
dissect_e164(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset, int length, e164_encoding_t encoding, int name_type)
803
267
{
804
267
  proto_item *pi;
805
267
  proto_tree *subtree;
806
267
  unsigned    str_encoding;
807
267
  char       *number_str;
808
809
267
  switch (encoding) {
810
27
  case E164_ENC_UTF8:
811
27
    str_encoding = ENC_UTF_8;
812
27
    break;
813
240
  case E164_ENC_BCD:
814
240
    str_encoding = ENC_BCD_DIGITS_0_9|ENC_LITTLE_ENDIAN;
815
240
    break;
816
0
  case E164_ENC_BINARY:
817
0
  default:
818
0
    DISSECTOR_ASSERT_NOT_REACHED();
819
267
  }
820
821
267
  pi = proto_tree_add_item_ret_display_string(tree, name_type, tvb, offset, length, str_encoding, pinfo->pool, &number_str);
822
823
267
  subtree = proto_item_add_subtree(pi, ett_e164_msisdn);
824
825
267
  dissect_e164_cc(tvb, pinfo, subtree, offset, encoding);
826
827
267
  return number_str;
828
267
}
829
830
const char *
831
dissect_e164_msisdn(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset, int length, e164_encoding_t encoding)
832
267
{
833
267
  return dissect_e164(tvb, pinfo, tree, offset, length, encoding, hf_E164_msisdn);
834
267
}
835
836
const char *
837
dissect_e164_isdn(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset, int length, e164_encoding_t encoding)
838
0
{
839
0
  return dissect_e164(tvb, pinfo, tree, offset, length, encoding, hf_E164_isdn);
840
0
}
841
842
/*
843
 * Register the protocol with Wireshark.
844
 */
845
846
void
847
proto_register_e164(void)
848
14
{
849
850
  /* Setup list of header fields  See Section 1.6.1 for details */
851
14
  static hf_register_info hf[] = {
852
14
    { &hf_E164_calling_party_number,
853
14
      { "E.164 Calling party number digits", "e164.calling_party_number.digits",
854
14
      FT_STRING, BASE_NONE, NULL, 0x0,
855
14
      NULL, HFILL }},
856
857
14
    { &hf_E164_called_party_number,
858
14
      { "E.164 Called party number digits", "e164.called_party_number.digits",
859
14
      FT_STRING, BASE_NONE, NULL, 0x0,
860
14
      NULL, HFILL }},
861
862
14
    { &hf_E164_msisdn,
863
14
      { "E.164 number (MSISDN)", "e164.msisdn",
864
14
      FT_STRING, BASE_NONE, NULL, 0x0,
865
14
      NULL, HFILL }},
866
867
14
    { &hf_E164_isdn,
868
14
      { "E.164 number (ISDN)", "e164.isdn",
869
14
      FT_STRING, BASE_NONE, NULL, 0x0,
870
14
      NULL, HFILL }},
871
872
14
    { &hf_E164_identification_code,
873
14
      { "Identification Code", "e164.identification_code",
874
14
      FT_UINT32, BASE_DEC, NULL, 0x0,
875
14
      NULL, HFILL }},
876
877
14
    { &hf_E164_country_code,
878
14
      { "Country Code", "e164.country_code",
879
14
      FT_UINT16, BASE_DEC|BASE_EXT_STRING, &E164_country_code_value_ext, 0x0,
880
14
      NULL, HFILL }},
881
14
  };
882
883
14
  static int *ett_e164_array[] = {
884
14
      &ett_e164_msisdn,
885
14
  };
886
887
14
  static ei_register_info ei[] = {
888
14
  { &ei_E164_country_code_non_decimal, { "e164.country_code.non_decimal", PI_MALFORMED, PI_WARN, "Country Code contains non-decimal digits", EXPFILL }},
889
14
  { &ei_E164_identification_code_non_decimal, { "e164.identification_code.non_decimal", PI_MALFORMED, PI_WARN, "Identification Code contains non-decimal digits", EXPFILL }},
890
14
  };
891
892
14
  expert_module_t* expert_e164;
893
894
895
14
  proto_e164 = proto_register_protocol("ITU-T E.164 number", "E.164", "e164");
896
897
14
  proto_register_field_array(proto_e164, hf, array_length(hf));
898
14
  proto_register_subtree_array(ett_e164_array, array_length(ett_e164_array));
899
900
14
  expert_e164 = expert_register_protocol(proto_e164);
901
14
  expert_register_field_array(expert_e164, ei, array_length(ei));
902
14
}
903
904
/*
905
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
906
 *
907
 * Local variables:
908
 * c-basic-offset: 8
909
 * tab-width: 8
910
 * indent-tabs-mode: t
911
 * End:
912
 *
913
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
914
 * :indentSize=8:tabSize=8:noTabs=false:
915
 */