2 * Routines for ISO-8583 Protocol dissection
3 * Copyright 2015, Paulo Roberto Brandao <brandao@ubiqua.inf.br>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * ISO 8583 Financial transaction card originated messages - Interchange
14 * message specifications is the International Organization for Standardization
15 * standard for systems that exchange electronic transactions made by
16 * cardholders using payment cards.
23 #include <epan/packet.h>
24 #include <epan/expert.h>
25 #include <epan/prefs.h>
26 #include <epan/wmem_scopes.h>
27 #include "packet-tcp.h"
29 #include <wsutil/strtoi.h>
38 /* conversion types */
40 TYPE_BCD
, /* nibble */
41 TYPE_BIN
/* raw data */
45 /* ISO bits content types */
66 /* ISO 8583-1 version 1987 Bit type specification */
67 static struct iso_type iso_1987
[128] = {
68 { ISO_TB
, 0, 0 }, /*Bit 1*/
69 { ISO_TN
, 19, 2 }, /*Bit 2*/
70 { ISO_TN
, 6, 0 }, /*Bit 3*/
71 { ISO_TN
, 12, 0 }, /*Bit 4*/
72 { ISO_TN
, 12, 0 }, /*Bit 5*/
73 { ISO_TN
, 12, 0 }, /*Bit 6*/
74 { ISO_TN
, 10, 0 }, /*Bit 7*/
75 { ISO_TN
, 8, 0 }, /*Bit 8*/
76 { ISO_TN
, 8, 0 }, /*Bit 9*/
77 { ISO_TN
, 8, 0 }, /*Bit 10*/
78 { ISO_TN
, 6, 0 }, /*Bit 11*/
79 { ISO_TN
, 6, 0 }, /*Bit 12*/
80 { ISO_TN
, 4, 0 }, /*Bit 13*/
81 { ISO_TN
, 4, 0 }, /*Bit 14*/
82 { ISO_TN
, 4, 0 }, /*Bit 15*/
83 { ISO_TN
, 4, 0 }, /*Bit 16*/
84 { ISO_TN
, 4, 0 }, /*Bit 17*/
85 { ISO_TN
, 4, 0 }, /*Bit 18*/
86 { ISO_TN
, 3, 0 }, /*Bit 19*/
87 { ISO_TN
, 3, 0 }, /*Bit 20*/
88 { ISO_TN
, 3, 0 }, /*Bit 21*/
89 { ISO_TN
, 3, 0 }, /*Bit 22*/
90 { ISO_TN
, 3, 0 }, /*Bit 23*/
91 { ISO_TN
, 3, 0 }, /*Bit 24*/
92 { ISO_TN
, 2, 0 }, /*Bit 25*/
93 { ISO_TN
, 2, 0 }, /*Bit 26*/
94 { ISO_TN
, 1, 0 }, /*Bit 27*/
95 { ISO_TXN
, 9, 0 }, /*Bit 28*/
96 { ISO_TXN
, 9, 0 }, /*Bit 29*/
97 { ISO_TXN
, 9, 0 }, /*Bit 30*/
98 { ISO_TXN
, 9, 0 }, /*Bit 31*/
99 { ISO_TN
, 11, 2 }, /*Bit 32*/
100 { ISO_TN
, 11, 2 }, /*Bit 33*/
101 { ISO_TNS
, 28, 2 }, /*Bit 34*/
102 { ISO_TZ
, 37, 2 }, /*Bit 35*/
103 { ISO_TAN
, 104, 3 }, /*Bit 36*/
104 { ISO_TAN
, 12, 0 }, /*Bit 37*/
105 { ISO_TAN
, 6, 0 }, /*Bit 38*/
106 { ISO_TAN
, 2, 0 }, /*Bit 39*/
107 { ISO_TANS
, 3, 0 }, /*Bit 40*/
108 { ISO_TANS
, 8, 0 }, /*Bit 41*/
109 { ISO_TANS
, 15, 0 }, /*Bit 42*/
110 { ISO_TANS
, 40, 0 }, /*Bit 43*/
111 { ISO_TANS
, 25, 2 }, /*Bit 44*/
112 { ISO_TANS
, 76, 2 }, /*Bit 45*/
113 { ISO_TANS
, 999, 3 }, /*Bit 46*/
114 { ISO_TANS
, 999, 3 }, /*Bit 47*/
115 { ISO_TANS
, 999, 3 }, /*Bit 48*/
116 { ISO_TANS
, 3, 0 }, /*Bit 49*/
117 { ISO_TAN
, 3, 0 }, /*Bit 50*/
118 { ISO_TAN
, 3, 0 }, /*Bit 51*/
119 /*{ ISO_TB, 64, 0 },*/ /*Bit 52*/
120 { ISO_TB
, 8, 0 }, /*Bit 52*/
121 { ISO_TN
, 8, 0 }, /*Bit 53*/
122 { ISO_TAN
, 120, 3 }, /*Bit 54*/
123 { ISO_TANS
, 999, 3 }, /*Bit 55*/
124 { ISO_TANS
, 999, 3 }, /*Bit 56*/
125 { ISO_TANS
, 999, 3 }, /*Bit 57*/
126 { ISO_TANS
, 999, 3 }, /*Bit 58*/
127 { ISO_TANS
, 999, 3 }, /*Bit 59*/
128 { ISO_TANS
, 999, 3 }, /*Bit 60*/
129 { ISO_TANS
, 999, 3 }, /*Bit 61*/
130 { ISO_TANS
, 999, 3 }, /*Bit 62*/
131 { ISO_TANS
, 999, 3 }, /*Bit 63*/
132 { ISO_TB
, 8, 0 }, /*Bit 64*/
133 { ISO_TB
, 0, 0 }, /*Bit 65*/
134 { ISO_TN
, 1, 0 }, /*Bit 66*/
135 { ISO_TN
, 2, 0 }, /*Bit 67*/
136 { ISO_TN
, 3, 0 }, /*Bit 68*/
137 { ISO_TN
, 3, 0 }, /*Bit 69*/
138 { ISO_TN
, 3, 0 }, /*Bit 70*/
139 { ISO_TN
, 4, 0 }, /*Bit 71*/
140 { ISO_TN
, 4, 0 }, /*Bit 72*/
141 { ISO_TN
, 6, 0 }, /*Bit 73*/
142 { ISO_TN
, 10, 0 }, /*Bit 74*/
143 { ISO_TN
, 10, 0 }, /*Bit 75*/
144 { ISO_TN
, 10, 0 }, /*Bit 76*/
145 { ISO_TN
, 10, 0 }, /*Bit 77*/
146 { ISO_TN
, 10, 0 }, /*Bit 78*/
147 { ISO_TN
, 10, 0 }, /*Bit 79*/
148 { ISO_TN
, 10, 0 }, /*Bit 80*/
149 { ISO_TN
, 10, 0 }, /*Bit 81*/
150 { ISO_TN
, 12, 0 }, /*Bit 82*/
151 { ISO_TN
, 12, 0 }, /*Bit 83*/
152 { ISO_TN
, 12, 0 }, /*Bit 84*/
153 { ISO_TN
, 12, 0 }, /*Bit 85*/
154 { ISO_TN
, 15, 0 }, /*Bit 86*/
155 { ISO_TN
, 15, 0 }, /*Bit 87*/
156 { ISO_TN
, 15, 0 }, /*Bit 88*/
157 { ISO_TN
, 15, 0 }, /*Bit 89*/
158 { ISO_TN
, 42, 0 }, /*Bit 90*/
159 { ISO_TANS
, 1, 0 }, /*Bit 91*/
160 { ISO_TN
, 2, 0 }, /*Bit 92*/
161 { ISO_TN
, 5, 0 }, /*Bit 93*/
162 { ISO_TANS
, 7, 0 }, /*Bit 94*/
163 { ISO_TANS
, 42, 0 }, /*Bit 95*/
164 { ISO_TB
, 8, 0 }, /*Bit 96*/
165 { ISO_TXN
, 17, 0 }, /*Bit 97*/
166 { ISO_TANS
, 25, 0 }, /*Bit 98*/
167 { ISO_TN
, 11, 2 }, /*Bit 99*/
168 { ISO_TN
, 11, 2 }, /*Bit 100*/
169 { ISO_TANS
, 17, 2 }, /*Bit 101*/
170 { ISO_TANS
, 28, 2 }, /*Bit 102*/
171 { ISO_TANS
, 28, 2 }, /*Bit 103*/
172 { ISO_TANS
, 100, 3 }, /*Bit 104*/
173 { ISO_TANS
, 999, 3 }, /*Bit 105*/
174 { ISO_TANS
, 999, 3 }, /*Bit 106*/
175 { ISO_TANS
, 999, 3 }, /*Bit 107*/
176 { ISO_TANS
, 999, 3 }, /*Bit 108*/
177 { ISO_TANS
, 999, 3 }, /*Bit 109*/
178 { ISO_TANS
, 999, 3 }, /*Bit 110*/
179 { ISO_TANS
, 999, 3 }, /*Bit 111*/
180 { ISO_TANS
, 999, 3 }, /*Bit 112*/
181 { ISO_TANS
, 999, 3 }, /*Bit 113*/
182 { ISO_TANS
, 999, 3 }, /*Bit 114*/
183 { ISO_TANS
, 999, 3 }, /*Bit 115*/
184 { ISO_TANS
, 999, 3 }, /*Bit 116*/
185 { ISO_TANS
, 999, 3 }, /*Bit 117*/
186 { ISO_TANS
, 999, 3 }, /*Bit 118*/
187 { ISO_TANS
, 999, 3 }, /*Bit 119*/
188 { ISO_TANS
, 999, 3 }, /*Bit 120*/
189 { ISO_TANS
, 999, 3 }, /*Bit 121*/
190 { ISO_TANS
, 999, 3 }, /*Bit 122*/
191 { ISO_TANS
, 999, 3 }, /*Bit 123*/
192 { ISO_TANS
, 999, 3 }, /*Bit 124*/
193 { ISO_TANS
, 999, 3 }, /*Bit 125*/
194 { ISO_TANS
, 999, 3 }, /*Bit 126*/
195 { ISO_TANS
, 999, 3 }, /*Bit 127*/
196 { ISO_TB
, 8, 0 } /*Bit 128*/
199 /* ISO 8583-1 version 1993 Bit type specification */
200 static struct iso_type iso_1993
[128] = {
201 { ISO_TB
, 0, 0 }, /*Bit 1*/
202 { ISO_TN
, 19, 2 }, /*Bit 2*/
203 { ISO_TN
, 6, 0 }, /*Bit 3*/
204 { ISO_TN
, 12, 0 }, /*Bit 4*/
205 { ISO_TN
, 12, 0 }, /*Bit 5*/
206 { ISO_TN
, 12, 0 }, /*Bit 6*/
207 { ISO_TN
, 10, 0 }, /*Bit 7*/
208 { ISO_TN
, 8, 0 }, /*Bit 8*/
209 { ISO_TN
, 8, 0 }, /*Bit 9*/
210 { ISO_TN
, 8, 0 }, /*Bit 10*/
211 { ISO_TN
, 6, 0 }, /*Bit 11*/
212 { ISO_TN
, 12, 0 }, /*Bit 12*/
213 { ISO_TN
, 4, 0 }, /*Bit 13*/
214 { ISO_TN
, 4, 0 }, /*Bit 14*/
215 { ISO_TN
, 4, 0 }, /*Bit 15*/
216 { ISO_TN
, 4, 0 }, /*Bit 16*/
217 { ISO_TN
, 4, 0 }, /*Bit 17*/
218 { ISO_TN
, 4, 0 }, /*Bit 18*/
219 { ISO_TN
, 3, 0 }, /*Bit 19*/
220 { ISO_TN
, 3, 0 }, /*Bit 20*/
221 { ISO_TN
, 3, 0 }, /*Bit 21*/
222 { ISO_TAN
, 12, 0 }, /*Bit 22*/
223 { ISO_TN
, 3, 0 }, /*Bit 23*/
224 { ISO_TN
, 3, 0 }, /*Bit 24*/
225 { ISO_TN
, 4, 0 }, /*Bit 25*/
226 { ISO_TN
, 4, 0 }, /*Bit 26*/
227 { ISO_TN
, 1, 0 }, /*Bit 27*/
228 { ISO_TN
, 6, 0 }, /*Bit 28*/
229 { ISO_TN
, 3, 0 }, /*Bit 29*/
230 { ISO_TN
, 24, 0 }, /*Bit 30*/
231 { ISO_TANS
, 99, 2 }, /*Bit 31*/
232 { ISO_TN
, 11, 2 }, /*Bit 32*/
233 { ISO_TN
, 11, 2 }, /*Bit 33*/
234 { ISO_TNS
, 28, 2 }, /*Bit 34*/
235 { ISO_TZ
, 37, 2 }, /*Bit 35*/
236 { ISO_TZ
, 104, 3 }, /*Bit 36*/
237 { ISO_TAN
, 12, 0 }, /*Bit 37*/
238 { ISO_TAN
, 6, 0 }, /*Bit 38*/
239 { ISO_TN
, 3, 0 }, /*Bit 39*/
240 { ISO_TN
, 3, 0 }, /*Bit 40*/
241 { ISO_TANS
, 8, 0 }, /*Bit 41*/
242 { ISO_TANS
, 15, 0 }, /*Bit 42*/
243 { ISO_TANS
, 99, 2 }, /*Bit 43*/
244 { ISO_TANS
, 99, 2 }, /*Bit 44*/
245 { ISO_TANS
, 76, 2 }, /*Bit 45*/
246 { ISO_TANS
, 204, 3 }, /*Bit 46*/
247 { ISO_TANS
, 999, 3 }, /*Bit 47*/
248 { ISO_TANS
, 999, 3 }, /*Bit 48*/
249 { ISO_TAN
, 3, 0 }, /*Bit 49*/
250 { ISO_TAN
, 3, 0 }, /*Bit 50*/
251 { ISO_TAN
, 3, 0 }, /*Bit 51*/
252 /*{ ISO_TB, 64, 0 },*/ /*Bit 52*/
253 { ISO_TB
, 8, 0 }, /*Bit 52*/
254 { ISO_TB
, 48, 0 }, /*Bit 53*/
255 { ISO_TANS
, 120, 3 }, /*Bit 54*/
256 { ISO_TB
, 255, 3 }, /*Bit 55*/
257 { ISO_TN
, 35, 2 }, /*Bit 56*/
258 { ISO_TN
, 3, 0 }, /*Bit 57*/
259 { ISO_TN
, 11, 2 }, /*Bit 58*/
260 { ISO_TANS
, 999, 3 }, /*Bit 59*/
261 { ISO_TANS
, 999, 3 }, /*Bit 60*/
262 { ISO_TANS
, 999, 3 }, /*Bit 61*/
263 { ISO_TANS
, 999, 3 }, /*Bit 62*/
264 { ISO_TANS
, 999, 3 }, /*Bit 63*/
265 { ISO_TB
, 8, 0 }, /*Bit 64*/
266 { ISO_TB
, 0, 0 }, /*Bit 65*/
267 { ISO_TANS
, 204, 3 }, /*Bit 66*/
268 { ISO_TN
, 2, 0 }, /*Bit 67*/
269 { ISO_TN
, 3, 0 }, /*Bit 68*/
270 { ISO_TN
, 3, 0 }, /*Bit 69*/
271 { ISO_TN
, 3, 0 }, /*Bit 70*/
272 { ISO_TN
, 6, 0 }, /*Bit 71*/
273 { ISO_TANS
, 999, 3 }, /*Bit 72*/
274 { ISO_TN
, 6, 0 }, /*Bit 73*/
275 { ISO_TN
, 10, 0 }, /*Bit 74*/
276 { ISO_TN
, 10, 0 }, /*Bit 75*/
277 { ISO_TN
, 10, 0 }, /*Bit 76*/
278 { ISO_TN
, 10, 0 }, /*Bit 77*/
279 { ISO_TN
, 10, 0 }, /*Bit 78*/
280 { ISO_TN
, 10, 0 }, /*Bit 79*/
281 { ISO_TN
, 10, 0 }, /*Bit 80*/
282 { ISO_TN
, 10, 0 }, /*Bit 81*/
283 { ISO_TN
, 10, 0 }, /*Bit 82*/
284 { ISO_TN
, 10, 0 }, /*Bit 83*/
285 { ISO_TN
, 10, 0 }, /*Bit 84*/
286 { ISO_TN
, 10, 0 }, /*Bit 85*/
287 { ISO_TN
, 16, 0 }, /*Bit 86*/
288 { ISO_TN
, 16, 0 }, /*Bit 87*/
289 { ISO_TN
, 16, 0 }, /*Bit 88*/
290 { ISO_TN
, 16, 0 }, /*Bit 89*/
291 { ISO_TN
, 10, 0 }, /*Bit 90*/
292 { ISO_TN
, 3, 0 }, /*Bit 91*/
293 { ISO_TN
, 3, 0 }, /*Bit 92*/
294 { ISO_TN
, 11, 2 }, /*Bit 93*/
295 { ISO_TN
, 11, 2 }, /*Bit 94*/
296 { ISO_TANS
, 99, 2 }, /*Bit 95*/
297 { ISO_TB
, 999, 3 }, /*Bit 96*/
298 { ISO_TXN
, 17, 0 }, /*Bit 97*/
299 { ISO_TANS
, 25, 0 }, /*Bit 98*/
300 { ISO_TAN
, 11, 2 }, /*Bit 99*/
301 { ISO_TN
, 11, 2 }, /*Bit 100*/
302 { ISO_TANS
, 17, 2 }, /*Bit 101*/
303 { ISO_TANS
, 28, 2 }, /*Bit 102*/
304 { ISO_TANS
, 28, 2 }, /*Bit 103*/
305 { ISO_TANS
, 100, 3 }, /*Bit 104*/
306 { ISO_TN
, 16, 0 }, /*Bit 105*/
307 { ISO_TN
, 16, 0 }, /*Bit 106*/
308 { ISO_TN
, 10, 0 }, /*Bit 107*/
309 { ISO_TN
, 10, 0 }, /*Bit 108*/
310 { ISO_TANS
, 84, 2 }, /*Bit 109*/
311 { ISO_TANS
, 84, 2 }, /*Bit 110*/
312 { ISO_TANS
, 999, 3 }, /*Bit 111*/
313 { ISO_TANS
, 999, 3 }, /*Bit 112*/
314 { ISO_TANS
, 999, 3 }, /*Bit 113*/
315 { ISO_TANS
, 999, 3 }, /*Bit 114*/
316 { ISO_TANS
, 999, 3 }, /*Bit 115*/
317 { ISO_TANS
, 999, 3 }, /*Bit 116*/
318 { ISO_TANS
, 999, 3 }, /*Bit 117*/
319 { ISO_TANS
, 999, 3 }, /*Bit 118*/
320 { ISO_TANS
, 999, 3 }, /*Bit 119*/
321 { ISO_TANS
, 999, 3 }, /*Bit 120*/
322 { ISO_TANS
, 999, 3 }, /*Bit 121*/
323 { ISO_TANS
, 999, 3 }, /*Bit 122*/
324 { ISO_TANS
, 999, 3 }, /*Bit 123*/
325 { ISO_TANS
, 999, 3 }, /*Bit 124*/
326 { ISO_TANS
, 999, 3 }, /*Bit 125*/
327 { ISO_TANS
, 999, 3 }, /*Bit 126*/
328 { ISO_TANS
, 999, 3 }, /*Bit 127*/
329 { ISO_TB
, 8, 0 } /*Bit 128*/
332 void proto_reg_handoff_iso8583(void);
333 void proto_register_iso8583(void);
335 static dissector_handle_t iso8583_handle
;
337 static int proto_iso8583
;
339 static int hf_iso8583_len
;
340 static int hf_iso8583_mti
;
341 static int hf_iso8583_bitmap1
;
342 static int hf_iso8583_bitmap2
;
344 /* TODO: This array should be renamed to hf_iso8583_data_bit[] when checkhf.pl allow. */
345 static int iso8583_data_bit
[128];
347 static int ett_iso8583
;
349 static expert_field ei_iso8583_MALFORMED
;
351 static struct iso_type
*data_array
;
353 /* Types definitions */
354 #define ASCII_CHARSET 1
355 #define NUM_NIBBLE_CHARSET 2
356 #define BIN_ASCII_ENC 1
357 #define BIN_BIN_ENC 2
359 /* Global preference */
360 static int charset_pref
= ASCII_CHARSET
;
361 static int bin_encode_pref
= BIN_ASCII_ENC
;
363 static int len_byte_order
= LITEND
;
366 * Functions that check field type against specification.
370 * Macro used by functions that check correctness of
371 * the message type. Go through string checking the
372 * condition passed as argument.
374 #define char_cond( cond )\
376 const char *end= string + size;\
377 for(c=string; c< end && ( cond ) ; c++);\
378 return size && c==end
380 /* Hexa representation of Binary field */
381 static int ishex_str(const char* string
, unsigned size
)
383 /*char_cond(g_ascii_isdigit(*c) || ( g_ascii_toupper(*c)>= 'A' && g_ascii_toupper(*c)<= 'F'));*/
384 char_cond(g_ascii_isxdigit(*c
));
388 static int isnum_str(const char* string
, unsigned int size
)
390 char_cond( g_ascii_isdigit(*c
) );
394 static int isalspec_str(const char* string
, unsigned int size
)
396 char_cond(g_ascii_isalpha(*c
) || g_ascii_isspace(*c
) || g_ascii_ispunct(*c
));
400 static int isalpha_str(const char* string
, unsigned int size
)
402 char_cond( g_ascii_isalpha(*c
));
406 static int isalnum_str(const char* string
, unsigned int size
)
408 char_cond( g_ascii_isalnum(*c
));
412 static int isalnumspec_str(const char* string
, unsigned int size
)
414 char_cond(g_ascii_isalnum(*c
) || g_ascii_isspace(*c
) || g_ascii_ispunct(*c
));
418 static int isnumspec_str(const char* string
, unsigned int size
)
420 char_cond(g_ascii_isdigit(*c
) || g_ascii_isspace(*c
) || g_ascii_ispunct(*c
));
424 static int isspec_str(const char* string
, unsigned int size
)
426 char_cond(g_ascii_isspace(*c
) || g_ascii_ispunct(*c
));
429 static bool isstrtype_ok( int type
, const char* string
, unsigned int size
)
434 return isalpha_str(string
, size
);
436 return isnum_str(string
, size
);
438 return ishex_str(string
, size
);
440 return isspec_str(string
, size
);
442 return isalspec_str(string
, size
);
444 return isalnum_str(string
, size
);
446 return isalnumspec_str(string
, size
);
448 return isnumspec_str(string
, size
);
450 return ishex_str(string
, size
);
452 if(charset_pref
== ASCII_CHARSET
)
453 return isalnumspec_str(string
, size
);
455 return ishex_str(string
, size
);
461 static const enum_val_t enumendians
[] = {
462 { "bigendian", "Big endian", BIGEND
},
463 { "littleendian", "Little endian", LITEND
},
468 static const enum_val_t enum_charset
[] = {
469 {"ascii", "Digits represented as ASCII Characters", ASCII_CHARSET
},
470 {"bcd", "Digits represented in nibbles", NUM_NIBBLE_CHARSET
},
475 static const enum_val_t enum_bin_encode
[] = {
476 {"ascii", "Bin data represented as Hex Ascii characters", BIN_ASCII_ENC
},
477 {"bin", "Bin data not encoded", BIN_BIN_ENC
},
482 #define iso8583_MIN_LENGTH 22 /* 2 (len) + 4 (mti) + 16 (fst bitmap in hexa) */
485 /* ISO standard version */
486 static const value_string packetversionnames
[] = {
487 { 48, ":1987"}, /*48 == '0'*/
488 { 49, ":1993"}, /*49 == '1'*/
489 { 50, ":2003"}, /*50 == '2'*/
493 static const value_string packettypenames
[] = {
494 { 48, "Reserved by ISO"}, /*48 == '0'*/
495 { 49, "Authorization Message"}, /*49 == '1'*/
496 { 50, "Financial Messages"}, /*50 == '2'*/
497 { 51, "File Actions Message"}, /*51 == '3'*/
498 { 52, "Reversal and Chargeback"}, /*52 == '4'*/
499 { 53, "Reconciliation Message"}, /*53 == '5'*/
500 { 54, "Administrative Message"}, /*54 == '6'*/
501 { 55, "Fee Collection Messages"}, /*54 == '7'*/
502 { 56, "Network Management"}, /*56 == '8'*/
503 { 57, "Reserved by ISO"}, /*57 == '9'*/
506 #define FRAME_HEADER_LEN 2
508 static unsigned get_iso8583_msg_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
510 const unsigned enc
= (len_byte_order
== BIGEND
)?ENC_BIG_ENDIAN
:ENC_LITTLE_ENDIAN
;
512 return tvb_get_uint16(tvb
, offset
, enc
) + 2;
515 #define NIBBLE_2_ASCHEX(nibble)\
516 ( ((nibble)>9) ? (((nibble)-10))+'A' : ((nibble)+'0') )
519 * Convert a sequence of nibbles to a string of ASCII characters
520 * corresponding to the hex digits in those nibbles.
522 static char* bin2hex(wmem_allocator_t
*pool
, const uint8_t *bin
, enum bin2hex_enum type
, uint32_t len
)
526 const uint8_t* str
= bin
;
530 /* "size" characters, plus terminating NUL */
531 ret
= (char *)wmem_alloc(pool
, size
+ 1);
535 if(size
% 2) /* odd */
538 *buff
++ = NIBBLE_2_ASCHEX(ch
);
547 ch
= (*str
>> 4) & 0x0f;
548 *buff
++ = NIBBLE_2_ASCHEX(ch
);
550 *buff
++ = NIBBLE_2_ASCHEX(ch
);
557 static uint64_t hex2bin(const char* hexstr
, int len
)
563 for(i
=0; i
< len
&& i
<16; i
++)
567 if (g_ascii_isdigit(nibble
))
570 bin
|= g_ascii_toupper(nibble
) - 55; /* nibble - ('A') + 10 ; */
576 #define checksize(len)\
577 if((offset -2 + len) > iso8583_len)\
580 static char *get_bit(unsigned ind
, packet_info
*pinfo
, tvbuff_t
*tvb
, unsigned *off_set
, proto_tree
*tree
, proto_item
**exp
, int *length
, uint32_t iso8583_len
)
585 unsigned offset
= *off_set
;
586 bool str_input
= false;
588 /* Check if it is a fixed or variable length
591 if(data_array
[ind
].varlen
== 0)
592 len
= data_array
[ind
].maxsize
; /* fixed len */
596 len
= data_array
[ind
].varlen
;
605 sizestr
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, len
, ENC_ASCII
);
607 if (!ws_strtou32(sizestr
, NULL
, &len
))
611 case NUM_NIBBLE_CHARSET
:
618 tvb_memcpy(tvb
, aux
, offset
, len
);
626 sizestr
= sizestr
*100 + (((uint8_t)(*tmp
)>>4) & 0x0f)*10 +
627 (((uint8_t)(*tmp
)) & 0x0f);
641 if((unsigned)len
> data_array
[ind
].maxsize
)
644 if(data_array
[ind
].type
== ISO_TN
|| data_array
[ind
].type
== ISO_TXN
)
646 if(charset_pref
== ASCII_CHARSET
)
649 ret
= (char *)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
,
653 else if(charset_pref
== NUM_NIBBLE_CHARSET
)
655 int tlen
= (len
%2)? len
/2 + 1 : len
/2;
657 tvb_memcpy(tvb
, aux
, offset
, tlen
);
658 if((ret
= bin2hex(pinfo
->pool
, (uint8_t *)aux
, TYPE_BCD
, len
)) == NULL
)
660 *length
= (int)strlen(ret
);
666 else if(data_array
[ind
].type
== ISO_TB
|| data_array
[ind
].type
== ISO_TZ
)
668 if( bin_encode_pref
== BIN_ASCII_ENC
)
670 if(data_array
[ind
].type
== ISO_TB
)
674 ret
= (char *)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
,
680 tvb_memcpy(tvb
, aux
, offset
, len
);
681 if((ret
= bin2hex(pinfo
->pool
, (uint8_t *)aux
, TYPE_BIN
, len
)) == NULL
)
683 *length
= (int)strlen(ret
);
691 ret
= (char *)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
,
695 /* TODO: check type of ret content */
696 if(str_input
&& tree
!= NULL
)
697 *exp
= proto_tree_add_string(tree
, iso8583_data_bit
[ind
], tvb
, offset
, len
, ret
);
698 else if (tree
!= NULL
)
699 *exp
= proto_tree_add_item(tree
, iso8583_data_bit
[ind
], tvb
,
700 offset
, len
, ENC_ASCII
);
702 *off_set
= offset
+ len
;
714 static int get_bitmap(packet_info
*pinfo
, tvbuff_t
*tvb
, uint64_t* bitmap
, unsigned offset
, int* nbitmaps
, uint32_t iso8583_len
)
718 bool isbreak
= false;
724 if(bin_encode_pref
== BIN_BIN_ENC
)
726 if((offset
-2 + 8) > iso8583_len
)
730 bitmap
[i
] = tvb_get_bits64(tvb
, offset
*8, 64, ENC_BIG_ENDIAN
);
736 if((offset
-2 + len
) > iso8583_len
)
739 hexbit
= (char *)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, len
, ENC_ASCII
);
742 if(!ishex_str(hexbit
, len
))
745 bitmap
[i
] = hex2bin(hexbit
, len
);
748 if(! (bitmap
[i
] & (((uint64_t)1) << 63))) /*bit 1 is set; there is a second bitmap*/
760 static int dissect_databits(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
761 int offset
, int nofbitmaps
, uint64_t *bitmap
, uint32_t iso8583_len
)
764 int nofbits
= nofbitmaps
*64, i
;
772 for(i
=0; i
< nofbits
; i
++)
779 if(bitmap
[i
/64] & (((uint64_t)1)<< (63 -bit
)))
781 cod
= get_bit(i
, pinfo
, tvb
, &offset
, tree
, &exp
, &len
, iso8583_len
);
782 if(cod
== NULL
|| ! isstrtype_ok(data_array
[i
].type
, cod
, len
))
785 exp
= proto_tree_add_string(tree
, iso8583_data_bit
[i
], tvb
, offset
, 0, "");
786 expert_add_info(pinfo
, exp
, &ei_iso8583_MALFORMED
);
790 if( i
== 2 || i
== 69) /*Processing code or Net. info code*/
792 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s. cod: %s", ((i
==2)?"Proc":"Net"), cod
);
796 /*test if exp is of type expected*/
802 return tvb_captured_length(tvb
);
805 static int dissect_iso8583_msg(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
808 proto_item
*ti
, *exp
;
809 proto_tree
*iso8583_tree
;
812 char *msg_type
, *msg_bitmap
;
814 uint64_t bitmap
[3]= {0,0,0};
817 uint32_t iso8583_len
;
820 /* Check that the packet is long enough for it to belong to ISO 8583-1. */
821 if (tvb_reported_length(tvb
) < iso8583_MIN_LENGTH
)
826 /* Heuristic: 4 bytes MTI - all digits */
827 if(charset_pref
== ASCII_CHARSET
) /* ASCII NUMBER REPRESENTATION */
830 msg_type
= (char*) tvb_get_string_enc(pinfo
->pool
, tvb
, 2, len
, ENC_ASCII
);
832 else /* NUMBERS REPRESENTED IN NIBBLES */
835 tvb_memcpy(tvb
, aux
, 2, len
);
836 if((msg_type
= bin2hex(pinfo
->pool
, (uint8_t *)aux
, TYPE_BCD
, len
*2)) == NULL
)
840 if(strlen(msg_type
) == 4 && !isnum_str(msg_type
,4)) /*MTI is composed of 4 digits*/
845 /* Heuristic: 16 bytes Bitmap1 - all HEX digits */
847 if(bin_encode_pref
== BIN_BIN_ENC
) /* ASCII NUMBER REPRESENTATION */
848 msg_bitmap
= (char *)tvb_get_string_enc(pinfo
->pool
, tvb
, 6, BM_LEN
*2 , ENC_ASCII
);
851 tvb_memcpy(tvb
, aux
, 6, BM_LEN
);
852 if((msg_bitmap
= bin2hex(pinfo
->pool
, (uint8_t *)aux
, TYPE_BCD
, BM_LEN
)) == NULL
)
856 if(strlen(msg_bitmap
) == 16 && !ishex_str(msg_bitmap
, BM_LEN
*2)) /*MTI is composed of 4 digits*/
861 /* check for message type format */
862 if(msg_type
[0] == '0')
863 data_array
= iso_1987
;
864 else if (msg_type
[0] == '1')
865 data_array
= iso_1993
;
872 /* Set the Protocol column */
873 col_clear(pinfo
->cinfo
, COL_PROTOCOL
);
874 col_add_fstr(pinfo
->cinfo
, COL_PROTOCOL
, "ISO 8583-1%s",
875 val_to_str_const((unsigned)msg_type
[0], packetversionnames
, " Unknown VERSION"));
876 col_clear(pinfo
->cinfo
, COL_INFO
);
877 /* print version of the packet*/
878 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Type %s - %s", msg_type
,
879 val_to_str_const((unsigned)msg_type
[1], packettypenames
, "Unknown type"));
881 /*** PROTOCOL TREE ***/
883 /* create display subtree for the protocol */
884 ti
= proto_tree_add_item(tree
, proto_iso8583
, tvb
, 0, -1, ENC_NA
);
885 proto_item_append_text(ti
, ": Type %s - %s", msg_type
,
886 val_to_str_const((unsigned)msg_type
[1], packettypenames
, "Unknown type"));
888 iso8583_tree
= proto_item_add_subtree(ti
, ett_iso8583
);
890 /*Length of the package*/
892 proto_tree_add_item_ret_uint(iso8583_tree
, hf_iso8583_len
, tvb
,
893 offset
, len
, (len_byte_order
== BIGEND
)?ENC_BIG_ENDIAN
:ENC_LITTLE_ENDIAN
,
900 /* TODO: check BCD or ASCII */
901 if(charset_pref
== ASCII_CHARSET
) /* ASCII NUMBER REPRESENTATION */
904 proto_tree_add_item(iso8583_tree
, hf_iso8583_mti
, tvb
,
905 offset
, len
, ENC_ASCII
| ENC_NA
);
910 proto_tree_add_string(iso8583_tree
, hf_iso8583_mti
, tvb
, offset
, len
, msg_type
);
916 get_bitmap(pinfo
, tvb
, bitmap
, offset
, &nofbitmaps
, iso8583_len
);
920 expert_add_info(pinfo
, ti
, &ei_iso8583_MALFORMED
);
925 if(bin_encode_pref
== BIN_ASCII_ENC
)
928 exp
= proto_tree_add_item(iso8583_tree
, hf_iso8583_bitmap1
, tvb
,
929 offset
, len
, ENC_ASCII
);
930 if(!ishex_str((char *)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, len
, ENC_ASCII
), len
))
932 expert_add_info(pinfo
, exp
, &ei_iso8583_MALFORMED
);
940 hexstr
= tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
, len
);
941 exp
= proto_tree_add_string(iso8583_tree
, hf_iso8583_bitmap1
, tvb
, offset
, len
, hexstr
);
948 if(bin_encode_pref
== BIN_ASCII_ENC
)
950 exp
= proto_tree_add_item(iso8583_tree
, hf_iso8583_bitmap2
, tvb
,
951 offset
, len
, ENC_ASCII
);
952 if(!ishex_str((char *)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, len
, ENC_ASCII
), len
))
954 expert_add_info(pinfo
, exp
, &ei_iso8583_MALFORMED
);
960 char* hexstr
= tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
, len
);
961 exp
= proto_tree_add_string(iso8583_tree
, hf_iso8583_bitmap2
, tvb
, offset
, len
, hexstr
);
969 expert_add_info(pinfo
, exp
, &ei_iso8583_MALFORMED
);
974 ret
= dissect_databits(tvb
, pinfo
, iso8583_tree
, offset
, nofbitmaps
, bitmap
,
980 static int dissect_iso8583(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
983 tcp_dissect_pdus(tvb
, pinfo
, tree
, true, FRAME_HEADER_LEN
, get_iso8583_msg_len
, dissect_iso8583_msg
, data
);
985 return tvb_captured_length(tvb
);
991 proto_register_iso8583(void)
993 module_t
*iso8583_module
;
994 expert_module_t
*expert_iso8583
;
997 static hf_register_info hf
[] = {
999 { "Message length", "iso8583.len",
1000 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1001 "Message length field", HFILL
}
1004 { "MTI", "iso8583.mti",
1005 FT_STRING
, BASE_NONE
, NULL
, 0,
1006 "Message Type Indicator (MTI)", HFILL
}
1008 { &hf_iso8583_bitmap1
,
1009 { "Bitmap 1", "iso8583.map1",
1010 FT_STRING
, BASE_NONE
, NULL
, 0,
1011 "First Bitmap (hex representation)", HFILL
}
1013 { &hf_iso8583_bitmap2
,
1014 { "Bitmap 2", "iso8583.map2",
1015 FT_STRING
, BASE_NONE
, NULL
, 0,
1016 "Second Bitmap (hex representation)", HFILL
}
1020 static hf_register_info hf_data
[128];
1022 static const char *hf_data_blurb
[128] = {
1024 "Second Bit map present",
1026 "Primary account number (PAN)",
1030 "Amount, transaction",
1032 "Amount, settlement",
1034 "Amount, cardholder billing",
1036 "Transmission date &",
1038 "Amount, cardholder billing fee",
1040 "Conversion rate, settlement",
1042 "Conversion rate, cardholder billing",
1044 "System trace audit number",
1046 "Time, local transaction (hhmmss)",
1048 "Date, local transaction (MMDD)",
1060 "Acquiring institution country code",
1062 "PAN extended, country code",
1064 "Forwarding institution. country code",
1066 "Point of service entry mode",
1068 "Application PAN sequence number",
1070 "Function code (ISO 8583:1993)/Network International identifier (NII)",
1072 "Point of service condition code",
1074 "Point of service capture code",
1076 "Authorizing identification response length",
1078 "Amount, transaction fee",
1080 "Amount, settlement fee",
1082 "Amount, transaction processing fee",
1084 "Amount, settlement processing fee",
1086 "Acquiring institution identification code",
1088 "Forwarding institution identification code",
1090 "Primary account number, extended",
1096 "Retrieval reference number",
1098 "Authorization identification response",
1102 "Service restriction code",
1104 "Card acceptor terminal identification",
1106 "Card acceptor identification code",
1108 "Card acceptor name/location (1-23 address 24-36 city 37-38 state 39-40 country)",
1110 "Additional response data",
1114 "Additional data - ISO",
1116 "Additional data - national",
1118 "Additional data - private",
1120 "Currency code, transaction",
1122 "Currency code, settlement",
1124 "Currency code, cardholder billing",
1126 "Personal identification number data",
1128 "Security related control information",
1130 "Additional amounts",
1136 "Reserved national",
1138 "Reserved national",
1140 "Reserved national",
1142 "Reserved national",
1150 "Message authentication code (MAC)",
1152 "Third Bitmap, extended",
1156 "Extended payment code",
1158 "Receiving institution country code",
1160 "Settlement institution country code",
1162 "Network management information code",
1166 "Message number, last",
1168 "Date, action (YYMMDD)",
1172 "Credits, reversal number",
1176 "Debits, reversal number",
1180 "Transfer, reversal number",
1184 "Authorizations, number",
1186 "Credits, processing fee amount",
1188 "Credits, transaction fee amount",
1190 "Debits, processing fee amount",
1192 "Debits, transaction fee amount",
1196 "Credits, reversal amount",
1200 "Debits, reversal amount",
1202 "Original data elements",
1206 "File security code",
1208 "Response indicator",
1210 "Service indicator",
1212 "Replacement amounts",
1214 "Message security code",
1216 "Amount, net settlement",
1220 "Settlement institution identification code",
1222 "Receiving institution identification code",
1226 "Account identification 1",
1228 "Account identification 2",
1230 "Transaction description",
1232 "Reserved for ISO use",
1234 "Reserved for ISO use",
1236 "Reserved for ISO use",
1238 "Reserved for ISO use",
1240 "Reserved for ISO use",
1242 "Reserved for ISO use",
1244 "Reserved for ISO use",
1246 "Reserved for national use",
1248 "Reserved for national use",
1250 "Reserved for national use",
1252 "Reserved for national use",
1254 "Reserved for national use",
1256 "Reserved for national use",
1258 "Reserved for national use",
1260 "Reserved for national use",
1262 "Reserved for private use",
1264 "Reserved for private use",
1266 "Reserved for private use",
1268 "Reserved for private use",
1270 "Reserved for private use",
1272 "Reserved for private use",
1274 "Reserved for private use",
1276 "Reserved for private use",
1278 "Message authentication code"
1281 static int *ett
[] = {
1285 static ei_register_info ei
[] = {
1286 { &ei_iso8583_MALFORMED
,
1287 { "iso8583.MALFORMED", PI_MALFORMED
, PI_ERROR
,
1288 "MALFORMED", EXPFILL
}
1292 proto_iso8583
= proto_register_protocol("ISO 8583-1", "ISO 8583", "iso8583");
1294 /* Function calls to register the header fields and subtrees */
1295 proto_register_field_array(proto_iso8583
, hf
, array_length(hf
));
1296 for (i
= 0; i
< 128; i
++) {
1297 HFILL_INIT(hf_data
[i
]);
1298 hf_data
[i
].p_id
= &iso8583_data_bit
[i
];
1299 hf_data
[i
].hfinfo
.name
= wmem_strdup_printf(wmem_epan_scope(), "Bit %d", i
+ 1);
1300 hf_data
[i
].hfinfo
.abbrev
= wmem_strdup_printf(wmem_epan_scope(), "iso8583.bit%d", i
+ 1);
1301 if(! i
%64 ) /* bit 1 and bit 65 */
1303 hf_data
[i
].hfinfo
.type
= FT_BOOLEAN
;
1304 hf_data
[i
].hfinfo
.display
= 8;
1308 hf_data
[i
].hfinfo
.type
= FT_STRING
;
1309 hf_data
[i
].hfinfo
.display
= BASE_NONE
;
1311 hf_data
[i
].hfinfo
.strings
= NULL
;
1312 hf_data
[i
].hfinfo
.bitmask
= 0;
1313 hf_data
[i
].hfinfo
.blurb
= hf_data_blurb
[i
];
1315 proto_register_field_array(proto_iso8583
, hf_data
, array_length(hf_data
));
1316 proto_register_subtree_array(ett
, array_length(ett
));
1318 expert_iso8583
= expert_register_protocol(proto_iso8583
);
1319 expert_register_field_array(expert_iso8583
, ei
, array_length(ei
));
1321 /* Register dissector handle */
1322 iso8583_handle
= register_dissector("iso8583", dissect_iso8583
, proto_iso8583
);
1324 /* Register preferences module */
1325 iso8583_module
= prefs_register_protocol(proto_iso8583
, NULL
);
1327 prefs_register_enum_preference(iso8583_module
, "len_endian",
1328 "Length field endian",
1329 "Endian of the length field. Big endian or Little endian",
1333 prefs_register_enum_preference(iso8583_module
, "charset",
1334 "Charset for numbers",
1335 " charset for numbers",
1336 &charset_pref
, enum_charset
, true);
1338 prefs_register_enum_preference(iso8583_module
, "binencode",
1340 " binary data representation",
1341 &bin_encode_pref
, enum_bin_encode
, true);
1344 void proto_reg_handoff_iso8583(void)
1346 dissector_add_for_decode_as_with_preference("tcp.port", iso8583_handle
);
1350 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1355 * indent-tabs-mode: nil
1358 * vi: set shiftwidth=2 tabstop=8 expandtab:
1359 * :indentSize=2:tabSize=8:noTabs=true: