1 /* packet-sna.c
2  * Routines for SNA
3  * Gilbert Ramirez <gram@alumni.rice.edu>
4  * Jochen Friedrich <jochen@scram.de>
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 
13 #include "config.h"
14 
15 #include <epan/packet.h>
16 #include <epan/llcsaps.h>
17 #include <epan/ppptypes.h>
18 #include <epan/address_types.h>
19 #include <epan/prefs.h>
20 #include <epan/reassemble.h>
21 #include <epan/to_str.h>
22 #include "wsutil/pint.h"
23 
24 /*
25  * See:
26  *
27  * http://web.archive.org/web/20020206033700/http://www.wanresources.com/snacell.html
28  *
29  * http://web.archive.org/web/20150522015710/http://www.protocols.com/pbook/sna.htm
30  *
31  * Systems Network Architecture Formats, GA27-3136-20:
32  * https://publibz.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/D50A5007/CCONTENTS
33  *
34  * Systems Network Architecture Management Services Formats, GC31-8302-03:
35  * https://publibfp.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/d50x4002/CCONTENTS
36  */
37 void proto_register_sna(void);
38 void proto_reg_handoff_sna(void);
39 
40 static int proto_sna = -1;
41 static int proto_sna_xid = -1;
42 static int hf_sna_th = -1;
43 static int hf_sna_th_0 = -1;
44 static int hf_sna_th_fid = -1;
45 static int hf_sna_th_mpf = -1;
46 static int hf_sna_th_odai = -1;
47 static int hf_sna_th_efi = -1;
48 static int hf_sna_th_daf = -1;
49 static int hf_sna_th_oaf = -1;
50 static int hf_sna_th_snf = -1;
51 static int hf_sna_th_dcf = -1;
52 static int hf_sna_th_lsid = -1;
53 static int hf_sna_th_tg_sweep = -1;
54 static int hf_sna_th_er_vr_supp_ind = -1;
55 static int hf_sna_th_vr_pac_cnt_ind = -1;
56 static int hf_sna_th_ntwk_prty = -1;
57 static int hf_sna_th_tgsf = -1;
58 static int hf_sna_th_mft = -1;
59 static int hf_sna_th_piubf = -1;
60 static int hf_sna_th_iern = -1;
61 static int hf_sna_th_nlpoi = -1;
62 static int hf_sna_th_nlp_cp = -1;
63 static int hf_sna_th_ern = -1;
64 static int hf_sna_th_vrn = -1;
65 static int hf_sna_th_tpf = -1;
66 static int hf_sna_th_vr_cwi = -1;
67 static int hf_sna_th_tg_nonfifo_ind = -1;
68 static int hf_sna_th_vr_sqti = -1;
69 static int hf_sna_th_tg_snf = -1;
70 static int hf_sna_th_vrprq = -1;
71 static int hf_sna_th_vrprs = -1;
72 static int hf_sna_th_vr_cwri = -1;
73 static int hf_sna_th_vr_rwi = -1;
74 static int hf_sna_th_vr_snf_send = -1;
75 static int hf_sna_th_dsaf = -1;
76 static int hf_sna_th_osaf = -1;
77 static int hf_sna_th_snai = -1;
78 static int hf_sna_th_def = -1;
79 static int hf_sna_th_oef = -1;
80 static int hf_sna_th_sa = -1;
81 static int hf_sna_th_cmd_fmt = -1;
82 static int hf_sna_th_cmd_type = -1;
83 static int hf_sna_th_cmd_sn = -1;
84 static int hf_sna_th_byte1 = -1;
85 static int hf_sna_th_byte2 = -1;
86 static int hf_sna_th_byte3 = -1;
87 static int hf_sna_th_byte4 = -1;
88 static int hf_sna_th_byte6 = -1;
89 static int hf_sna_th_byte16 = -1;
90 
91 static int hf_sna_nlp_nhdr = -1;
92 static int hf_sna_nlp_nhdr_0 = -1;
93 static int hf_sna_nlp_sm = -1;
94 static int hf_sna_nlp_tpf = -1;
95 static int hf_sna_nlp_nhdr_1 = -1;
96 static int hf_sna_nlp_ft = -1;
97 static int hf_sna_nlp_tspi = -1;
98 static int hf_sna_nlp_slowdn1 = -1;
99 static int hf_sna_nlp_slowdn2 = -1;
100 static int hf_sna_nlp_fra = -1;
101 static int hf_sna_nlp_anr = -1;
102 static int hf_sna_nlp_frh = -1;
103 static int hf_sna_nlp_thdr = -1;
104 static int hf_sna_nlp_tcid = -1;
105 static int hf_sna_nlp_thdr_8 = -1;
106 static int hf_sna_nlp_setupi = -1;
107 static int hf_sna_nlp_somi = -1;
108 static int hf_sna_nlp_eomi = -1;
109 static int hf_sna_nlp_sri = -1;
110 static int hf_sna_nlp_rasapi = -1;
111 static int hf_sna_nlp_retryi = -1;
112 static int hf_sna_nlp_thdr_9 = -1;
113 static int hf_sna_nlp_lmi = -1;
114 static int hf_sna_nlp_cqfi = -1;
115 static int hf_sna_nlp_osi = -1;
116 static int hf_sna_nlp_offset = -1;
117 static int hf_sna_nlp_dlf = -1;
118 static int hf_sna_nlp_bsn = -1;
119 static int hf_sna_nlp_opti_len = -1;
120 static int hf_sna_nlp_opti_type = -1;
121 static int hf_sna_nlp_opti_0d_version = -1;
122 static int hf_sna_nlp_opti_0d_4 = -1;
123 static int hf_sna_nlp_opti_0d_target = -1;
124 static int hf_sna_nlp_opti_0d_arb = -1;
125 static int hf_sna_nlp_opti_0d_reliable = -1;
126 static int hf_sna_nlp_opti_0d_dedicated = -1;
127 static int hf_sna_nlp_opti_0e_stat = -1;
128 static int hf_sna_nlp_opti_0e_gap = -1;
129 static int hf_sna_nlp_opti_0e_idle = -1;
130 static int hf_sna_nlp_opti_0e_nabsp = -1;
131 static int hf_sna_nlp_opti_0e_sync = -1;
132 static int hf_sna_nlp_opti_0e_echo = -1;
133 static int hf_sna_nlp_opti_0e_rseq = -1;
134 /* static int hf_sna_nlp_opti_0e_abspbeg = -1; */
135 /* static int hf_sna_nlp_opti_0e_abspend = -1; */
136 static int hf_sna_nlp_opti_0f_bits = -1;
137 static int hf_sna_nlp_opti_10_tcid = -1;
138 static int hf_sna_nlp_opti_12_sense = -1;
139 static int hf_sna_nlp_opti_14_si_len = -1;
140 static int hf_sna_nlp_opti_14_si_key = -1;
141 static int hf_sna_nlp_opti_14_si_2 = -1;
142 static int hf_sna_nlp_opti_14_si_refifo = -1;
143 static int hf_sna_nlp_opti_14_si_mobility = -1;
144 static int hf_sna_nlp_opti_14_si_dirsearch = -1;
145 static int hf_sna_nlp_opti_14_si_limitres = -1;
146 static int hf_sna_nlp_opti_14_si_ncescope = -1;
147 static int hf_sna_nlp_opti_14_si_mnpsrscv = -1;
148 static int hf_sna_nlp_opti_14_si_maxpsize = -1;
149 static int hf_sna_nlp_opti_14_si_switch = -1;
150 static int hf_sna_nlp_opti_14_si_alive = -1;
151 static int hf_sna_nlp_opti_14_rr_len = -1;
152 static int hf_sna_nlp_opti_14_rr_key = -1;
153 static int hf_sna_nlp_opti_14_rr_2 = -1;
154 static int hf_sna_nlp_opti_14_rr_bfe = -1;
155 static int hf_sna_nlp_opti_14_rr_num = -1;
156 static int hf_sna_nlp_opti_22_2 = -1;
157 static int hf_sna_nlp_opti_22_type = -1;
158 static int hf_sna_nlp_opti_22_raa = -1;
159 static int hf_sna_nlp_opti_22_parity = -1;
160 static int hf_sna_nlp_opti_22_arb = -1;
161 static int hf_sna_nlp_opti_22_3 = -1;
162 static int hf_sna_nlp_opti_22_ratereq = -1;
163 static int hf_sna_nlp_opti_22_raterep = -1;
164 static int hf_sna_nlp_opti_22_field1 = -1;
165 static int hf_sna_nlp_opti_22_field2 = -1;
166 static int hf_sna_nlp_opti_22_field3 = -1;
167 static int hf_sna_nlp_opti_22_field4 = -1;
168 
169 static int hf_sna_rh = -1;
170 static int hf_sna_rh_0 = -1;
171 static int hf_sna_rh_1 = -1;
172 static int hf_sna_rh_2 = -1;
173 static int hf_sna_rh_rri = -1;
174 static int hf_sna_rh_ru_category = -1;
175 static int hf_sna_rh_fi = -1;
176 static int hf_sna_rh_sdi = -1;
177 static int hf_sna_rh_bci = -1;
178 static int hf_sna_rh_eci = -1;
179 static int hf_sna_rh_dr1 = -1;
180 static int hf_sna_rh_lcci = -1;
181 static int hf_sna_rh_dr2 = -1;
182 static int hf_sna_rh_eri = -1;
183 static int hf_sna_rh_rti = -1;
184 static int hf_sna_rh_rlwi = -1;
185 static int hf_sna_rh_qri = -1;
186 static int hf_sna_rh_pi = -1;
187 static int hf_sna_rh_bbi = -1;
188 static int hf_sna_rh_ebi = -1;
189 static int hf_sna_rh_cdi = -1;
190 static int hf_sna_rh_csi = -1;
191 static int hf_sna_rh_edi = -1;
192 static int hf_sna_rh_pdi = -1;
193 static int hf_sna_rh_cebi = -1;
194 /*static int hf_sna_ru = -1;*/
195 
196 static int hf_sna_gds = -1;
197 static int hf_sna_gds_len = -1;
198 static int hf_sna_gds_type = -1;
199 static int hf_sna_gds_cont = -1;
200 static int hf_sna_gds_info = -1;
201 
202 /* static int hf_sna_xid = -1; */
203 static int hf_sna_xid_0 = -1;
204 static int hf_sna_xid_id = -1;
205 static int hf_sna_xid_format = -1;
206 static int hf_sna_xid_type = -1;
207 static int hf_sna_xid_len = -1;
208 static int hf_sna_xid_idblock = -1;
209 static int hf_sna_xid_idnum = -1;
210 static int hf_sna_xid_3_8 = -1;
211 static int hf_sna_xid_3_init_self = -1;
212 static int hf_sna_xid_3_stand_bind = -1;
213 static int hf_sna_xid_3_gener_bind = -1;
214 static int hf_sna_xid_3_recve_bind = -1;
215 static int hf_sna_xid_3_actpu = -1;
216 static int hf_sna_xid_3_nwnode = -1;
217 static int hf_sna_xid_3_cp = -1;
218 static int hf_sna_xid_3_cpcp = -1;
219 static int hf_sna_xid_3_state = -1;
220 static int hf_sna_xid_3_nonact = -1;
221 static int hf_sna_xid_3_cpchange = -1;
222 static int hf_sna_xid_3_10 = -1;
223 static int hf_sna_xid_3_asend_bind = -1;
224 static int hf_sna_xid_3_arecv_bind = -1;
225 static int hf_sna_xid_3_quiesce = -1;
226 static int hf_sna_xid_3_pucap = -1;
227 static int hf_sna_xid_3_pbn = -1;
228 static int hf_sna_xid_3_pacing = -1;
229 static int hf_sna_xid_3_11 = -1;
230 static int hf_sna_xid_3_tgshare = -1;
231 static int hf_sna_xid_3_dedsvc = -1;
232 static int hf_sna_xid_3_12 = -1;
233 static int hf_sna_xid_3_negcsup = -1;
234 static int hf_sna_xid_3_negcomp = -1;
235 static int hf_sna_xid_3_15 = -1;
236 static int hf_sna_xid_3_partg = -1;
237 static int hf_sna_xid_3_dlur = -1;
238 static int hf_sna_xid_3_dlus = -1;
239 static int hf_sna_xid_3_exbn = -1;
240 static int hf_sna_xid_3_genodai = -1;
241 static int hf_sna_xid_3_branch = -1;
242 static int hf_sna_xid_3_brnn = -1;
243 static int hf_sna_xid_3_tg = -1;
244 static int hf_sna_xid_3_dlc = -1;
245 static int hf_sna_xid_3_dlen = -1;
246 
247 static int hf_sna_control_len = -1;
248 static int hf_sna_control_key = -1;
249 static int hf_sna_control_hprkey = -1;
250 static int hf_sna_control_05_delay = -1;
251 static int hf_sna_control_05_type = -1;
252 static int hf_sna_control_05_ptp = -1;
253 static int hf_sna_control_0e_type = -1;
254 static int hf_sna_control_0e_value = -1;
255 static int hf_sna_padding = -1;
256 static int hf_sna_reserved = -1;
257 static int hf_sna_biu_segment_data = -1;
258 
259 static gint ett_sna = -1;
260 static gint ett_sna_th = -1;
261 static gint ett_sna_th_fid = -1;
262 static gint ett_sna_nlp_nhdr = -1;
263 static gint ett_sna_nlp_nhdr_0 = -1;
264 static gint ett_sna_nlp_nhdr_1 = -1;
265 static gint ett_sna_nlp_thdr = -1;
266 static gint ett_sna_nlp_thdr_8 = -1;
267 static gint ett_sna_nlp_thdr_9 = -1;
268 static gint ett_sna_nlp_opti_un = -1;
269 static gint ett_sna_nlp_opti_0d = -1;
270 static gint ett_sna_nlp_opti_0d_4 = -1;
271 static gint ett_sna_nlp_opti_0e = -1;
272 static gint ett_sna_nlp_opti_0e_stat = -1;
273 static gint ett_sna_nlp_opti_0e_absp = -1;
274 static gint ett_sna_nlp_opti_0f = -1;
275 static gint ett_sna_nlp_opti_10 = -1;
276 static gint ett_sna_nlp_opti_12 = -1;
277 static gint ett_sna_nlp_opti_14 = -1;
278 static gint ett_sna_nlp_opti_14_si = -1;
279 static gint ett_sna_nlp_opti_14_si_2 = -1;
280 static gint ett_sna_nlp_opti_14_rr = -1;
281 static gint ett_sna_nlp_opti_14_rr_2 = -1;
282 static gint ett_sna_nlp_opti_22 = -1;
283 static gint ett_sna_nlp_opti_22_2 = -1;
284 static gint ett_sna_nlp_opti_22_3 = -1;
285 static gint ett_sna_rh = -1;
286 static gint ett_sna_rh_0 = -1;
287 static gint ett_sna_rh_1 = -1;
288 static gint ett_sna_rh_2 = -1;
289 static gint ett_sna_gds = -1;
290 static gint ett_sna_xid_0 = -1;
291 static gint ett_sna_xid_id = -1;
292 static gint ett_sna_xid_3_8 = -1;
293 static gint ett_sna_xid_3_10 = -1;
294 static gint ett_sna_xid_3_11 = -1;
295 static gint ett_sna_xid_3_12 = -1;
296 static gint ett_sna_xid_3_15 = -1;
297 static gint ett_sna_control_un = -1;
298 static gint ett_sna_control_05 = -1;
299 static gint ett_sna_control_05hpr = -1;
300 static gint ett_sna_control_05hpr_type = -1;
301 static gint ett_sna_control_0e = -1;
302 
303 static dissector_handle_t sna_handle;
304 static dissector_handle_t sna_xid_handle;
305 
306 static int sna_address_type = -1;
307 
308 /* Defragment fragmented SNA BIUs*/
309 static gboolean sna_defragment = TRUE;
310 static reassembly_table sna_reassembly_table;
311 
312 /* Format Identifier */
313 static const value_string sna_th_fid_vals[] = {
314 	{ 0x0,	"SNA device <--> Non-SNA Device" },
315 	{ 0x1,	"Subarea Nodes, without ER or VR" },
316 	{ 0x2,	"Subarea Node <--> PU2" },
317 	{ 0x3,	"Subarea Node or SNA host <--> Subarea Node" },
318 	{ 0x4,	"Subarea Nodes, supporting ER and VR" },
319 	{ 0x5,	"HPR RTP endpoint nodes" },
320 	{ 0xa,	"HPR NLP Frame Routing" },
321 	{ 0xb,	"HPR NLP Frame Routing" },
322 	{ 0xc,	"HPR NLP Automatic Network Routing" },
323 	{ 0xd,	"HPR NLP Automatic Network Routing" },
324 	{ 0xf,	"Adjacent Subarea Nodes, supporting ER and VR" },
325 	{ 0x0,	NULL }
326 };
327 
328 /* Mapping Field */
329 #define MPF_MIDDLE_SEGMENT  0
330 #define MPF_LAST_SEGMENT    1
331 #define MPF_FIRST_SEGMENT   2
332 #define MPF_WHOLE_BIU       3
333 
334 static const value_string sna_th_mpf_vals[] = {
335 	{ MPF_MIDDLE_SEGMENT,   "Middle segment of a BIU" },
336 	{ MPF_LAST_SEGMENT,     "Last segment of a BIU" },
337 	{ MPF_FIRST_SEGMENT,    "First segment of a BIU" },
338 	{ MPF_WHOLE_BIU,        "Whole BIU" },
339 	{ 0,   NULL }
340 };
341 
342 /* Expedited Flow Indicator */
343 static const value_string sna_th_efi_vals[] = {
344 	{ 0, "Normal Flow" },
345 	{ 1, "Expedited Flow" },
346 	{ 0x0,	NULL }
347 };
348 
349 /* Request/Response Indicator */
350 static const value_string sna_rh_rri_vals[] = {
351 	{ 0, "Request" },
352 	{ 1, "Response" },
353 	{ 0x0,	NULL }
354 };
355 
356 /* Request/Response Unit Category */
357 static const value_string sna_rh_ru_category_vals[] = {
358 	{ 0, "Function Management Data (FMD)" },
359 	{ 1, "Network Control (NC)" },
360 	{ 2, "Data Flow Control (DFC)" },
361 	{ 3, "Session Control (SC)" },
362 	{ 0x0,	NULL }
363 };
364 
365 /* Format Indicator */
366 static const true_false_string sna_rh_fi_truth =
367 	{ "FM Header", "No FM Header" };
368 
369 /* Begin Chain Indicator */
370 static const true_false_string sna_rh_bci_truth =
371 	{ "First in Chain", "Not First in Chain" };
372 
373 /* End Chain Indicator */
374 static const true_false_string sna_rh_eci_truth =
375 	{ "Last in Chain", "Not Last in Chain" };
376 
377 /* Lengith-Checked Compression Indicator */
378 static const true_false_string sna_rh_lcci_truth =
379 	{ "Compressed", "Not Compressed" };
380 
381 /* Response Type Indicator */
382 static const true_false_string sna_rh_rti_truth =
383 	{ "Negative", "Positive" };
384 
385 /* Queued Response Indicator */
386 static const true_false_string sna_rh_qri_truth =
387 	{ "Enqueue response in TC queues", "Response bypasses TC queues" };
388 
389 /* Code Selection Indicator */
390 static const value_string sna_rh_csi_vals[] = {
391 	{ 0, "EBCDIC" },
392 	{ 1, "ASCII" },
393 	{ 0x0,	NULL }
394 };
395 
396 /* TG Sweep */
397 static const value_string sna_th_tg_sweep_vals[] = {
398 	{ 0, "This PIU may overtake any PU ahead of it." },
399 	{ 1, "This PIU does not overtake any PIU ahead of it." },
400 	{ 0x0,	NULL }
401 };
402 
403 /* ER_VR_SUPP_IND */
404 static const value_string sna_th_er_vr_supp_ind_vals[] = {
405 	{ 0, "Each node supports ER and VR protocols" },
406 	{ 1, "Includes at least one node that does not support ER and VR"
407 	    " protocols"  },
408 	{ 0x0,	NULL }
409 };
410 
411 /* VR_PAC_CNT_IND */
412 static const value_string sna_th_vr_pac_cnt_ind_vals[] = {
413 	{ 0, "Pacing count on the VR has not reached 0" },
414 	{ 1, "Pacing count on the VR has reached 0" },
415 	{ 0x0,	NULL }
416 };
417 
418 /* NTWK_PRTY */
419 static const value_string sna_th_ntwk_prty_vals[] = {
420 	{ 0, "PIU flows at a lower priority" },
421 	{ 1, "PIU flows at network priority (highest transmission priority)" },
422 	{ 0x0,	NULL }
423 };
424 
425 /* TGSF */
426 static const value_string sna_th_tgsf_vals[] = {
427 	{ 0, "Not segmented" },
428 	{ 1, "Last segment" },
429 	{ 2, "First segment" },
430 	{ 3, "Middle segment" },
431 	{ 0x0,	NULL }
432 };
433 
434 /* PIUBF */
435 static const value_string sna_th_piubf_vals[] = {
436 	{ 0, "Single PIU frame" },
437 	{ 1, "Last PIU of a multiple PIU frame" },
438 	{ 2, "First PIU of a multiple PIU frame" },
439 	{ 3, "Middle PIU of a multiple PIU frame" },
440 	{ 0x0,	NULL }
441 };
442 
443 /* NLPOI */
444 static const value_string sna_th_nlpoi_vals[] = {
445 	{ 0, "NLP starts within this FID4 TH" },
446 	{ 1, "NLP byte 0 starts after RH byte 0 following NLP C/P pad" },
447 	{ 0x0,	NULL }
448 };
449 
450 /* TPF */
451 static const value_string sna_th_tpf_vals[] = {
452 	{ 0, "Low Priority" },
453 	{ 1, "Medium Priority" },
454 	{ 2, "High Priority" },
455 	{ 3, "Network Priority" },
456 	{ 0x0,	NULL }
457 };
458 
459 /* VR_CWI */
460 static const value_string sna_th_vr_cwi_vals[] = {
461 	{ 0, "Increment window size" },
462 	{ 1, "Decrement window size" },
463 	{ 0x0,	NULL }
464 };
465 
466 /* TG_NONFIFO_IND */
467 static const true_false_string sna_th_tg_nonfifo_ind_truth =
468 	{ "TG FIFO is not required", "TG FIFO is required" };
469 
470 /* VR_SQTI */
471 static const value_string sna_th_vr_sqti_vals[] = {
472 	{ 0, "Non-sequenced, Non-supervisory" },
473 	{ 1, "Non-sequenced, Supervisory" },
474 	{ 2, "Singly-sequenced" },
475 	{ 0x0,	NULL }
476 };
477 
478 /* VRPRQ */
479 static const true_false_string sna_th_vrprq_truth = {
480 	"VR pacing request is sent asking for a VR pacing response",
481 	"No VR pacing response is requested",
482 };
483 
484 /* VRPRS */
485 static const true_false_string sna_th_vrprs_truth = {
486 	"VR pacing response is sent in response to a VRPRQ bit set",
487 	"No pacing response sent",
488 };
489 
490 /* VR_CWRI */
491 static const value_string sna_th_vr_cwri_vals[] = {
492 	{ 0, "Increment window size by 1" },
493 	{ 1, "Decrement window size by 1" },
494 	{ 0x0,	NULL }
495 };
496 
497 /* VR_RWI */
498 static const true_false_string sna_th_vr_rwi_truth = {
499 	"Reset window size to the minimum specified in NC_ACTVR",
500 	"Do not reset window size",
501 };
502 
503 /* Switching Mode */
504 static const value_string sna_nlp_sm_vals[] = {
505 	{ 5, "Function routing" },
506 	{ 6, "Automatic network routing" },
507 	{ 0x0,	NULL }
508 };
509 
510 static const true_false_string sna_nlp_tspi_truth =
511 	{ "Time sensitive", "Not time sensitive" };
512 
513 static const true_false_string sna_nlp_slowdn1_truth =
514 	{ "Minor congestion", "No minor congestion" };
515 
516 static const true_false_string sna_nlp_slowdn2_truth =
517 	{ "Major congestion", "No major congestion" };
518 
519 /* Function Type */
520 static const value_string sna_nlp_ft_vals[] = {
521 	{ 0x10, "LDLC" },
522 	{ 0x0,	NULL }
523 };
524 
525 static const value_string sna_nlp_frh_vals[] = {
526 	{ 0x03, "XID complete request" },
527 	{ 0x04, "XID complete response" },
528 	{ 0x0,	NULL }
529 };
530 
531 static const true_false_string sna_nlp_setupi_truth =
532 	{ "Connection setup segment present", "Connection setup segment not"
533 	    " present" };
534 
535 static const true_false_string sna_nlp_somi_truth =
536 	{ "Start of message", "Not start of message" };
537 
538 static const true_false_string sna_nlp_eomi_truth =
539 	{ "End of message", "Not end of message" };
540 
541 static const true_false_string sna_nlp_sri_truth =
542 	{ "Status requested", "No status requested" };
543 
544 static const true_false_string sna_nlp_rasapi_truth =
545 	{ "Reply as soon as possible", "No need to reply as soon as possible" };
546 
547 static const true_false_string sna_nlp_retryi_truth =
548 	{ "Undefined", "Sender will retransmit" };
549 
550 static const true_false_string sna_nlp_lmi_truth =
551 	{ "Last message", "Not last message" };
552 
553 static const true_false_string sna_nlp_cqfi_truth =
554 	{ "CQFI included", "CQFI not included" };
555 
556 static const true_false_string sna_nlp_osi_truth =
557 	{ "Optional segments present", "No optional segments present" };
558 
559 static const value_string sna_xid_3_state_vals[] = {
560 	{ 0x00, "Exchange state indicators not supported" },
561 	{ 0x01, "Negotiation-proceeding exchange" },
562 	{ 0x02, "Prenegotiation exchange" },
563 	{ 0x03, "Nonactivation exchange" },
564 	{ 0x0, NULL }
565 };
566 
567 static const value_string sna_xid_3_branch_vals[] = {
568 	{ 0x00, "Sender does not support branch extender" },
569 	{ 0x01, "TG is branch uplink" },
570 	{ 0x02, "TG is branch downlink" },
571 	{ 0x03, "TG is neither uplink nor downlink" },
572 	{ 0x0, NULL }
573 };
574 
575 static const value_string sna_xid_type_vals[] = {
576 	{ 0x01, "T1 node" },
577 	{ 0x02, "T2.0 or T2.1 node" },
578 	{ 0x03, "Reserved" },
579 	{ 0x04, "T4 or T5 node" },
580 	{ 0x0, NULL }
581 };
582 
583 static const value_string sna_nlp_opti_vals[] = {
584 	{ 0x0d, "Connection Setup Segment" },
585 	{ 0x0e, "Status Segment" },
586 	{ 0x0f, "Client Out Of Band Bits Segment" },
587 	{ 0x10, "Connection Identifier Exchange Segment" },
588 	{ 0x12, "Connection Fault Segment" },
589 	{ 0x14, "Switching Information Segment" },
590 	{ 0x22, "Adaptive Rate-Based Segment" },
591 	{ 0x0, NULL }
592 };
593 
594 static const value_string sna_nlp_opti_0d_version_vals[] = {
595 	{ 0x0101, "Version 1.1" },
596 	{ 0x0, NULL }
597 };
598 
599 static const value_string sna_nlp_opti_0f_bits_vals[] = {
600 	{ 0x0001, "Request Deactivation" },
601 	{ 0x8000, "Reply - OK" },
602 	{ 0x8004, "Reply - Reject" },
603 	{ 0x0, NULL }
604 };
605 
606 static const value_string sna_nlp_opti_22_type_vals[] = {
607 	{ 0x00, "Setup" },
608 	{ 0x01, "Rate Reply" },
609 	{ 0x02, "Rate Request" },
610 	{ 0x03, "Rate Request/Rate Reply" },
611 	{ 0x0, NULL }
612 };
613 
614 static const value_string sna_nlp_opti_22_raa_vals[] = {
615 	{ 0x00, "Normal" },
616 	{ 0x01, "Restraint" },
617 	{ 0x02, "Slowdown1" },
618 	{ 0x03, "Slowdown2" },
619 	{ 0x04, "Critical" },
620 	{ 0x0, NULL }
621 };
622 
623 static const value_string sna_nlp_opti_22_arb_vals[] = {
624 	{ 0x00, "Base Mode ARB" },
625 	{ 0x01, "Responsive Mode ARB" },
626 	{ 0x0, NULL }
627 };
628 
629 /* GDS Variable Type */
630 static const value_string sna_gds_var_vals[] = {
631 	{ 0x1210, "Change Number Of Sessions" },
632 	{ 0x1211, "Exchange Log Name" },
633 	{ 0x1212, "Control Point Management Services Unit" },
634 	{ 0x1213, "Compare States" },
635 	{ 0x1214, "LU Names Position" },
636 	{ 0x1215, "LU Name" },
637 	{ 0x1217, "Do Know" },
638 	{ 0x1218, "Partner Restart" },
639 	{ 0x1219, "Don't Know" },
640 	{ 0x1220, "Sign-Off" },
641 	{ 0x1221, "Sign-On" },
642 	{ 0x1222, "SNMP-over-SNA" },
643 	{ 0x1223, "Node Address Service" },
644 	{ 0x12C1, "CP Capabilities" },
645 	{ 0x12C2, "Topology Database Update" },
646 	{ 0x12C3, "Register Resource" },
647 	{ 0x12C4, "Locate" },
648 	{ 0x12C5, "Cross-Domain Initiate" },
649 	{ 0x12C9, "Delete Resource" },
650 	{ 0x12CA, "Find Resource" },
651 	{ 0x12CB, "Found Resource" },
652 	{ 0x12CC, "Notify" },
653 	{ 0x12CD, "Initiate-Other Cross-Domain" },
654 	{ 0x12CE, "Route Setup" },
655 	{ 0x12E1, "Error Log" },
656 	{ 0x12F1, "Null Data" },
657 	{ 0x12F2, "User Control Date" },
658 	{ 0x12F3, "Map Name" },
659 	{ 0x12F4, "Error Data" },
660 	{ 0x12F6, "Authentication Token Data" },
661 	{ 0x12F8, "Service Flow Authentication Token Data" },
662 	{ 0x12FF, "Application Data" },
663 	{ 0x1310, "MDS Message Unit" },
664 	{ 0x1311, "MDS Routing Information" },
665 	{ 0x1500, "FID2 Encapsulation" },
666 	{ 0x0,    NULL }
667 };
668 
669 /* Control Vector Type */
670 static const value_string sna_control_vals[] = {
671 	{ 0x00,   "SSCP-LU Session Capabilities Control Vector" },
672 	{ 0x01,   "Date-Time Control Vector" },
673 	{ 0x02,   "Subarea Routing Control Vector" },
674 	{ 0x03,   "SDLC Secondary Station Control Vector" },
675 	{ 0x04,   "LU Control Vector" },
676 	{ 0x05,   "Channel Control Vector" },
677 	{ 0x06,   "Cross-Domain Resource Manager (CDRM) Control Vector" },
678 	{ 0x07,   "PU FMD-RU-Usage Control Vector" },
679 	{ 0x08,   "Intensive Mode Control Vector" },
680 	{ 0x09,   "Activation Request / Response Sequence Identifier Control"
681 	    " Vector" },
682 	{ 0x0a,   "User Request Correlator Control Vector" },
683 	{ 0x0b,   "SSCP-PU Session Capabilities Control Vector" },
684 	{ 0x0c,   "LU-LU Session Capabilities Control Vector" },
685 	{ 0x0d,   "Mode / Class-of-Service / Virtual-Route-Identifier List"
686 	    " Control Vector" },
687 	{ 0x0e,   "Network Name Control Vector" },
688 	{ 0x0f,   "Link Capabilities and Status Control Vector" },
689 	{ 0x10,   "Product Set ID Control Vector" },
690 	{ 0x11,   "Load Module Correlation Control Vector" },
691 	{ 0x12,   "Network Identifier Control Vector" },
692 	{ 0x13,   "Gateway Support Capabilities Control Vector" },
693 	{ 0x14,   "Session Initiation Control Vector" },
694 	{ 0x15,   "Network-Qualified Address Pair Control Vector" },
695 	{ 0x16,   "Names Substitution Control Vector" },
696 	{ 0x17,   "SSCP Identifier Control Vector" },
697 	{ 0x18,   "SSCP Name Control Vector" },
698 	{ 0x19,   "Resource Identifier Control Vector" },
699 	{ 0x1a,   "NAU Address Control Vector" },
700 	{ 0x1b,   "VRID List Control Vector" },
701 	{ 0x1c,   "Network-Qualified Name Pair Control Vector" },
702 	{ 0x1e,   "VR-ER Mapping Data Control Vector" },
703 	{ 0x1f,   "ER Configuration Control Vector" },
704 	{ 0x23,   "Local-Form Session Identifier Control Vector" },
705 	{ 0x24,   "IPL Load Module Request Control Vector" },
706 	{ 0x25,   "Security ID Control Control Vector" },
707 	{ 0x26,   "Network Connection Endpoint Identifier Control Vector" },
708 	{ 0x27,   "XRF Session Activation Control Vector" },
709 	{ 0x28,   "Related Session Identifier Control Vector" },
710 	{ 0x29,   "Session State Data Control Vector" },
711 	{ 0x2a,   "Session Information Control Vector" },
712 	{ 0x2b,   "Route Selection Control Vector" },
713 	{ 0x2c,   "COS/TPF Control Vector" },
714 	{ 0x2d,   "Mode Control Vector" },
715 	{ 0x2f,   "LU Definition Control Vector" },
716 	{ 0x30,   "Assign LU Characteristics Control Vector" },
717 	{ 0x31,   "BIND Image Control Vector" },
718 	{ 0x32,   "Short-Hold Mode Control Vector" },
719 	{ 0x33,   "ENCP Search Control Control Vector" },
720 	{ 0x34,   "LU Definition Override Control Vector" },
721 	{ 0x35,   "Extended Sense Data Control Vector" },
722 	{ 0x36,   "Directory Error Control Vector" },
723 	{ 0x37,   "Directory Entry Correlator Control Vector" },
724 	{ 0x38,   "Short-Hold Mode Emulation Control Vector" },
725 	{ 0x39,   "Network Connection Endpoint (NCE) Instance Identifier"
726 	    " Control Vector" },
727 	{ 0x3a,   "Route Status Data Control Vector" },
728 	{ 0x3b,   "VR Congestion Data Control Vector" },
729 	{ 0x3c,   "Associated Resource Entry Control Vector" },
730 	{ 0x3d,   "Directory Entry Control Vector" },
731 	{ 0x3e,   "Directory Entry Characteristic Control Vector" },
732 	{ 0x3f,   "SSCP (SLU) Capabilities Control Vector" },
733 	{ 0x40,   "Real Associated Resource Control Vector" },
734 	{ 0x41,   "Station Parameters Control Vector" },
735 	{ 0x42,   "Dynamic Path Update Data Control Vector" },
736 	{ 0x43,   "Extended SDLC Station Control Vector" },
737 	{ 0x44,   "Node Descriptor Control Vector" },
738 	{ 0x45,   "Node Characteristics Control Vector" },
739 	{ 0x46,   "TG Descriptor Control Vector" },
740 	{ 0x47,   "TG Characteristics Control Vector" },
741 	{ 0x48,   "Topology Resource Descriptor Control Vector" },
742 	{ 0x49,   "Multinode Persistent Sessions (MNPS) LU Names Control"
743 	    " Vector" },
744 	{ 0x4a,   "Real Owning Control Point Control Vector" },
745 	{ 0x4b,   "RTP Transport Connection Identifier Control Vector" },
746 	{ 0x51,   "DLUR/S Capabilities Control Vector" },
747 	{ 0x52,   "Primary Send Pacing Window Size Control Vector" },
748 	{ 0x56,   "Call Security Verification Control Vector" },
749 	{ 0x57,   "DLC Connection Data Control Vector" },
750 	{ 0x59,   "Installation-Defined CDINIT Data Control Vector" },
751 	{ 0x5a,   "Session Services Extension Support Control Vector" },
752 	{ 0x5b,   "Interchange Node Support Control Vector" },
753 	{ 0x5c,   "APPN Message Transport Control Vector" },
754 	{ 0x5d,   "Subarea Message Transport Control Vector" },
755 	{ 0x5e,   "Related Request Control Vector" },
756 	{ 0x5f,   "Extended Fully Qualified PCID Control Vector" },
757 	{ 0x60,   "Fully Qualified PCID Control Vector" },
758 	{ 0x61,   "HPR Capabilities Control Vector" },
759 	{ 0x62,   "Session Address Control Vector" },
760 	{ 0x63,   "Cryptographic Key Distribution Control Vector" },
761 	{ 0x64,   "TCP/IP Information Control Vector" },
762 	{ 0x65,   "Device Characteristics Control Vector" },
763 	{ 0x66,   "Length-Checked Compression Control Vector" },
764 	{ 0x67,   "Automatic Network Routing (ANR) Path Control Vector" },
765 	{ 0x68,   "XRF/Session Cryptography Control Vector" },
766 	{ 0x69,   "Switched Parameters Control Vector" },
767 	{ 0x6a,   "ER Congestion Data Control Vector" },
768 	{ 0x71,   "Triple DES Cryptography Key Continuation Control Vector" },
769 	{ 0xfe,   "Control Vector Keys Not Recognized" },
770 	{ 0x0,    NULL }
771 };
772 
773 static const value_string sna_control_hpr_vals[] = {
774 	{ 0x00,   "Node Identifier Control Vector" },
775 	{ 0x03,   "Network ID Control Vector" },
776 	{ 0x05,   "Network Address Control Vector" },
777 	{ 0x0,    NULL }
778 };
779 
780 static const value_string sna_control_0e_type_vals[] = {
781 	{ 0xF1,   "PU Name" },
782 	{ 0xF3,   "LU Name" },
783 	{ 0xF4,   "CP Name" },
784 	{ 0xF5,   "SSCP Name" },
785 	{ 0xF6,   "NNCP Name" },
786 	{ 0xF7,   "Link Station Name" },
787 	{ 0xF8,   "CP Name of CP(PLU)" },
788 	{ 0xF9,   "CP Name of CP(SLU)" },
789 	{ 0xFA,   "Generic Name" },
790 	{ 0x0,    NULL }
791 };
792 
793 /* Values to direct the top-most dissector what to dissect
794  * after the TH. */
795 enum next_dissection_enum {
796 	stop_here,
797 	rh_only,
798 	everything
799 };
800 
801 enum parse {
802 	LT,
803 	KL
804 };
805 
806 /*
807  * Structure used to represent an FID Type 4 address; gives the layout of the
808  * data pointed to by an AT_SNA "address" structure if the size is
809  * SNA_FID_TYPE_4_ADDR_LEN.
810  */
811 #define	SNA_FID_TYPE_4_ADDR_LEN	6
812 struct sna_fid_type_4_addr {
813 	guint32	saf;
814 	guint16	ef;
815 };
816 
817 typedef enum next_dissection_enum next_dissection_t;
818 
819 static void dissect_xid (tvbuff_t*, packet_info*, proto_tree*, proto_tree*);
820 static void dissect_fid (tvbuff_t*, packet_info*, proto_tree*, proto_tree*);
821 static void dissect_nlp (tvbuff_t*, packet_info*, proto_tree*, proto_tree*);
822 static void dissect_gds (tvbuff_t*, packet_info*, proto_tree*, proto_tree*);
823 static void dissect_rh (tvbuff_t*, int, proto_tree*);
824 static void dissect_sna_control(tvbuff_t* parent_tvb, int offset, int control_len, proto_tree* tree, int hpr, enum parse parse);
825 
sna_fid_to_str_buf(const address * addr,gchar * buf,int buf_len _U_)826 static int sna_fid_to_str_buf(const address *addr, gchar *buf, int buf_len _U_)
827 {
828 	const guint8 *addrdata;
829 	struct sna_fid_type_4_addr sna_fid_type_4_addr;
830 	gchar *bufp = buf;
831 
832 	switch (addr->len) {
833 
834 	case 1:
835 		addrdata = (const guint8 *)addr->data;
836 		word_to_hex(buf, addrdata[0]);
837 		buf[4] = '\0';
838 		break;
839 
840 	case 2:
841 		addrdata = (const guint8 *)addr->data;
842 		word_to_hex(buf, pntoh16(&addrdata[0]));
843 		buf[4] = '\0';
844 		break;
845 
846 	case SNA_FID_TYPE_4_ADDR_LEN:
847 		/* FID Type 4 */
848 		memcpy(&sna_fid_type_4_addr, addr->data, SNA_FID_TYPE_4_ADDR_LEN);
849 
850 		bufp = dword_to_hex(bufp, sna_fid_type_4_addr.saf);
851 		*bufp++ = '.';
852 		bufp = word_to_hex(bufp, sna_fid_type_4_addr.ef);
853 		*bufp++ = '\0'; /* NULL terminate */
854 		break;
855 	default:
856 		buf[0] = '\0';
857 		return 1;
858 	}
859 
860 	return (int)strlen(buf)+1;
861 }
862 
863 
sna_address_str_len(const address * addr _U_)864 static int sna_address_str_len(const address* addr _U_)
865 {
866 	/* We could do this based on address length, but 14 bytes isn't THAT much space */
867 	return 14;
868 }
869 
870 
871 /* --------------------------------------------------------------------
872  * Chapter 2 High-Performance Routing (HPR) Headers
873  * --------------------------------------------------------------------
874  */
875 
876 static void
dissect_optional_0d(tvbuff_t * tvb,proto_tree * tree)877 dissect_optional_0d(tvbuff_t *tvb, proto_tree *tree)
878 {
879 	int		offset, len, pad;
880 	static int * const fields[] = {
881 		&hf_sna_nlp_opti_0d_target,
882 		&hf_sna_nlp_opti_0d_arb,
883 		&hf_sna_nlp_opti_0d_reliable,
884 		&hf_sna_nlp_opti_0d_dedicated,
885 		NULL
886 	};
887 
888 	if (!tree)
889 		return;
890 
891 	proto_tree_add_item(tree, hf_sna_nlp_opti_0d_version, tvb, 2, 2, ENC_BIG_ENDIAN);
892 
893 	proto_tree_add_bitmask(tree, tvb, 4, hf_sna_nlp_opti_0d_4,
894 			       ett_sna_nlp_opti_0d_4, fields, ENC_NA);
895 
896 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 5, 3, ENC_NA);
897 
898 	offset = 8;
899 
900 	while (tvb_offset_exists(tvb, offset)) {
901 		len = tvb_get_guint8(tvb, offset+0);
902 		if (len) {
903 			dissect_sna_control(tvb, offset, len, tree, 1, LT);
904 			pad = (len+3) & 0xfffc;
905 			if (pad > len)
906 				proto_tree_add_item(tree, hf_sna_padding, tvb, offset+len, pad-len, ENC_NA);
907 			offset += pad;
908 		} else {
909 			/* Avoid endless loop */
910 			return;
911 		}
912 	}
913 }
914 
915 static void
dissect_optional_0e(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)916 dissect_optional_0e(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
917 {
918 	int		bits, offset;
919 	static int * const fields[] = {
920 		&hf_sna_nlp_opti_0e_gap,
921 		&hf_sna_nlp_opti_0e_idle,
922 		NULL
923 	};
924 
925 	bits = tvb_get_guint8(tvb, 2);
926 	offset = 20;
927 
928 	proto_tree_add_bitmask(tree, tvb, 2, hf_sna_nlp_opti_0e_stat,
929 			    ett_sna_nlp_opti_0e_stat, fields, ENC_NA);
930 
931 	proto_tree_add_item(tree, hf_sna_nlp_opti_0e_nabsp,
932 		tvb, 3, 1, ENC_BIG_ENDIAN);
933 	proto_tree_add_item(tree, hf_sna_nlp_opti_0e_sync,
934 		tvb, 4, 2, ENC_BIG_ENDIAN);
935 	proto_tree_add_item(tree, hf_sna_nlp_opti_0e_echo,
936 		tvb, 6, 2, ENC_BIG_ENDIAN);
937 	proto_tree_add_item(tree, hf_sna_nlp_opti_0e_rseq,
938 		tvb, 8, 4, ENC_BIG_ENDIAN);
939 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 12, 8, ENC_NA);
940 
941 	if (tvb_offset_exists(tvb, offset))
942 		call_data_dissector(tvb_new_subset_remaining(tvb, 4), pinfo, tree);
943 
944 	if (bits & 0x40) {
945 		col_set_str(pinfo->cinfo, COL_INFO, "HPR Idle Message");
946 	} else {
947 		col_set_str(pinfo->cinfo, COL_INFO, "HPR Status Message");
948 	}
949 }
950 
951 static void
dissect_optional_0f(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)952 dissect_optional_0f(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
953 {
954 	proto_tree_add_item(tree, hf_sna_nlp_opti_0f_bits, tvb, 2, 2, ENC_BIG_ENDIAN);
955 	if (tvb_offset_exists(tvb, 4))
956 		call_data_dissector(tvb_new_subset_remaining(tvb, 4), pinfo, tree);
957 }
958 
959 static void
dissect_optional_10(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)960 dissect_optional_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
961 {
962 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 2, 2, ENC_NA);
963 	proto_tree_add_item(tree, hf_sna_nlp_opti_10_tcid, tvb, 4, 8, ENC_NA);
964 	if (tvb_offset_exists(tvb, 12))
965 		call_data_dissector(tvb_new_subset_remaining(tvb, 12), pinfo, tree);
966 }
967 
968 static void
dissect_optional_12(tvbuff_t * tvb,proto_tree * tree)969 dissect_optional_12(tvbuff_t *tvb, proto_tree *tree)
970 {
971 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 2, 2, ENC_NA);
972 	proto_tree_add_item(tree, hf_sna_nlp_opti_12_sense, tvb, 4, -1, ENC_NA);
973 }
974 
975 static void
dissect_optional_14(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)976 dissect_optional_14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
977 {
978 	proto_tree	*sub_tree;
979 	int		len, pad, type, offset, num, sublen;
980 	static int * const opti_14_si_fields[] = {
981 		&hf_sna_nlp_opti_14_si_refifo,
982 		&hf_sna_nlp_opti_14_si_mobility,
983 		&hf_sna_nlp_opti_14_si_dirsearch,
984 		&hf_sna_nlp_opti_14_si_limitres,
985 		&hf_sna_nlp_opti_14_si_ncescope,
986 		&hf_sna_nlp_opti_14_si_mnpsrscv,
987 		NULL
988 	};
989 	static int * const opti_14_rr_fields[] = {
990 		&hf_sna_nlp_opti_14_rr_bfe,
991 		NULL
992 	};
993 
994 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 2, 2, ENC_NA);
995 
996 	offset = 4;
997 
998 	len = tvb_get_guint8(tvb, offset);
999 	type = tvb_get_guint8(tvb, offset+1);
1000 
1001 	if ((type != 0x83) || (len <= 16)) {
1002 		/* Invalid */
1003 		call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1004 		return;
1005 	}
1006 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, len,
1007 	    ett_sna_nlp_opti_14_si, NULL, "Switching Information Control Vector");
1008 
1009 	proto_tree_add_uint(sub_tree, hf_sna_nlp_opti_14_si_len,
1010 	    tvb, offset, 1, len);
1011 	proto_tree_add_uint(sub_tree, hf_sna_nlp_opti_14_si_key,
1012 	    tvb, offset+1, 1, type);
1013 
1014 	proto_tree_add_bitmask(tree, tvb, offset+2, hf_sna_nlp_opti_14_si_2,
1015 			       ett_sna_nlp_opti_14_si_2, opti_14_si_fields, ENC_NA);
1016 
1017 	proto_tree_add_item(sub_tree, hf_sna_reserved, tvb, offset+3, 1, ENC_NA);
1018 	proto_tree_add_item(sub_tree, hf_sna_nlp_opti_14_si_maxpsize,
1019 	    tvb, offset+4, 4, ENC_BIG_ENDIAN);
1020 	proto_tree_add_item(sub_tree, hf_sna_nlp_opti_14_si_switch,
1021 	    tvb, offset+8, 4, ENC_BIG_ENDIAN);
1022 	proto_tree_add_item(sub_tree, hf_sna_nlp_opti_14_si_alive,
1023 	    tvb, offset+12, 4, ENC_BIG_ENDIAN);
1024 
1025 	dissect_sna_control(tvb, offset+16, len-16, sub_tree, 1, LT);
1026 
1027 	pad = (len+3) & 0xfffc;
1028 	if (pad > len)
1029 		proto_tree_add_item(sub_tree, hf_sna_padding, tvb, offset+len, pad-len, ENC_NA);
1030 	offset += pad;
1031 
1032 	len = tvb_get_guint8(tvb, offset);
1033 	type = tvb_get_guint8(tvb, offset+1);
1034 
1035 	if ((type != 0x85) || ( len < 4))  {
1036 		/* Invalid */
1037 		call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1038 		return;
1039 	}
1040 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, len,
1041 	    ett_sna_nlp_opti_14_rr, NULL, "Return Route TG Descriptor Control Vector");
1042 
1043 	proto_tree_add_uint(sub_tree, hf_sna_nlp_opti_14_rr_len,
1044 	    tvb, offset, 1, len);
1045 	proto_tree_add_uint(sub_tree, hf_sna_nlp_opti_14_rr_key,
1046 	    tvb, offset+1, 1, type);
1047 
1048 	proto_tree_add_bitmask(tree, tvb, offset+2, hf_sna_nlp_opti_14_rr_2,
1049 			       ett_sna_nlp_opti_14_rr_2, opti_14_rr_fields, ENC_NA);
1050 
1051 	num = tvb_get_guint8(tvb, offset+3);
1052 
1053 	proto_tree_add_uint(sub_tree, hf_sna_nlp_opti_14_rr_num,
1054 	    tvb, offset+3, 1, num);
1055 
1056 	offset += 4;
1057 
1058 	while (num) {
1059 		sublen = tvb_get_guint8(tvb, offset);
1060 		if (sublen) {
1061 			dissect_sna_control(tvb, offset, sublen, sub_tree, 1, LT);
1062 		} else {
1063 			/* Invalid */
1064 			call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1065 			return;
1066 		}
1067 		/* No padding here */
1068 		offset += sublen;
1069 		num--;
1070 	}
1071 }
1072 
1073 static void
dissect_optional_22(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)1074 dissect_optional_22(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1075 {
1076 	int		bits, type;
1077 	static int * const opti_22_2_fields[] = {
1078 		&hf_sna_nlp_opti_22_type,
1079 		&hf_sna_nlp_opti_22_raa,
1080 		&hf_sna_nlp_opti_22_parity,
1081 		&hf_sna_nlp_opti_22_arb,
1082 		NULL
1083 	};
1084 	static int * const opti_22_3_fields[] = {
1085 		&hf_sna_nlp_opti_22_ratereq,
1086 		&hf_sna_nlp_opti_22_raterep,
1087 		NULL
1088 	};
1089 
1090 	bits = tvb_get_guint8(tvb, 2);
1091 	type = (bits & 0xc0) >> 6;
1092 
1093 	proto_tree_add_bitmask(tree, tvb, 2, hf_sna_nlp_opti_22_2,
1094 			       ett_sna_nlp_opti_22_2, opti_22_2_fields, ENC_NA);
1095 
1096 	proto_tree_add_bitmask(tree, tvb, 3, hf_sna_nlp_opti_22_3,
1097 			       ett_sna_nlp_opti_22_3, opti_22_3_fields, ENC_NA);
1098 
1099 	proto_tree_add_item(tree, hf_sna_nlp_opti_22_field1,
1100 	    tvb, 4, 4, ENC_BIG_ENDIAN);
1101 	proto_tree_add_item(tree, hf_sna_nlp_opti_22_field2,
1102 	    tvb, 8, 4, ENC_BIG_ENDIAN);
1103 
1104 	if (type == 0) {
1105 		proto_tree_add_item(tree, hf_sna_nlp_opti_22_field3,
1106 		    tvb, 12, 4, ENC_BIG_ENDIAN);
1107 		proto_tree_add_item(tree, hf_sna_nlp_opti_22_field4,
1108 		    tvb, 16, 4, ENC_BIG_ENDIAN);
1109 
1110 		if (tvb_offset_exists(tvb, 20))
1111 			call_data_dissector(tvb_new_subset_remaining(tvb, 20), pinfo, tree);
1112 	} else {
1113 		if (tvb_offset_exists(tvb, 12))
1114 			call_data_dissector(tvb_new_subset_remaining(tvb, 12), pinfo, tree);
1115 	}
1116 }
1117 
1118 static void
dissect_optional(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)1119 dissect_optional(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1120 {
1121 	proto_tree	*sub_tree;
1122 	int		offset, type, len;
1123 	gint		ett;
1124 
1125 	sub_tree = NULL;
1126 
1127 	offset = 0;
1128 
1129 	while (tvb_offset_exists(tvb, offset)) {
1130 		len = tvb_get_guint8(tvb, offset);
1131 		type = tvb_get_guint8(tvb, offset+1);
1132 
1133 		/* Prevent loop for invalid crap in packet */
1134 		if (len == 0) {
1135 			call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1136 			return;
1137 		}
1138 
1139 		ett = ett_sna_nlp_opti_un;
1140 		if(type == 0x0d) ett = ett_sna_nlp_opti_0d;
1141 		if(type == 0x0e) ett = ett_sna_nlp_opti_0e;
1142 		if(type == 0x0f) ett = ett_sna_nlp_opti_0f;
1143 		if(type == 0x10) ett = ett_sna_nlp_opti_10;
1144 		if(type == 0x12) ett = ett_sna_nlp_opti_12;
1145 		if(type == 0x14) ett = ett_sna_nlp_opti_14;
1146 		if(type == 0x22) ett = ett_sna_nlp_opti_22;
1147 		if (tree) {
1148 			sub_tree = proto_tree_add_subtree(tree, tvb,
1149 			    offset, len << 2, ett, NULL,
1150 			    val_to_str(type, sna_nlp_opti_vals,
1151 			    "Unknown Segment Type"));
1152 			proto_tree_add_uint(sub_tree, hf_sna_nlp_opti_len,
1153 			    tvb, offset, 1, len);
1154 			proto_tree_add_uint(sub_tree, hf_sna_nlp_opti_type,
1155 			    tvb, offset+1, 1, type);
1156 		}
1157 		switch(type) {
1158 			case 0x0d:
1159 				dissect_optional_0d(tvb_new_subset_length_caplen(tvb, offset,
1160 				    len << 2, -1), sub_tree);
1161 				break;
1162 			case 0x0e:
1163 				dissect_optional_0e(tvb_new_subset_length_caplen(tvb, offset,
1164 				    len << 2, -1), pinfo, sub_tree);
1165 				break;
1166 			case 0x0f:
1167 				dissect_optional_0f(tvb_new_subset_length_caplen(tvb, offset,
1168 				    len << 2, -1), pinfo, sub_tree);
1169 				break;
1170 			case 0x10:
1171 				dissect_optional_10(tvb_new_subset_length_caplen(tvb, offset,
1172 				    len << 2, -1), pinfo, sub_tree);
1173 				break;
1174 			case 0x12:
1175 				dissect_optional_12(tvb_new_subset_length_caplen(tvb, offset,
1176 				    len << 2, -1), sub_tree);
1177 				break;
1178 			case 0x14:
1179 				dissect_optional_14(tvb_new_subset_length_caplen(tvb, offset,
1180 				    len << 2, -1), pinfo, sub_tree);
1181 				break;
1182 			case 0x22:
1183 				dissect_optional_22(tvb_new_subset_length_caplen(tvb, offset,
1184 				    len << 2, -1), pinfo, sub_tree);
1185 				break;
1186 			default:
1187 				call_data_dissector(tvb_new_subset_length_caplen(tvb, offset,
1188 				    len << 2, -1), pinfo, sub_tree);
1189 		}
1190 		offset += (len << 2);
1191 	}
1192 }
1193 
1194 static void
dissect_nlp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_tree * parent_tree)1195 dissect_nlp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1196 	    proto_tree *parent_tree)
1197 {
1198 	proto_tree	*nlp_tree;
1199 	proto_item	*nlp_item;
1200 	guint8		nhdr_0, nhdr_1, nhdr_x, thdr_8, thdr_9, fid;
1201 	guint32		thdr_len, thdr_dlf;
1202 	guint16		subindx;
1203 	static int * const nlp_nhdr_0_fields[] = {
1204 		&hf_sna_nlp_sm,
1205 		&hf_sna_nlp_tpf,
1206 		NULL
1207 	};
1208 	static int * const nlp_nhdr_1_fields[] = {
1209 		&hf_sna_nlp_ft,
1210 		&hf_sna_nlp_tspi,
1211 		&hf_sna_nlp_slowdn1,
1212 		&hf_sna_nlp_slowdn2,
1213 		NULL
1214 	};
1215 	static int * const nlp_nhdr_8_fields[] = {
1216 		&hf_sna_nlp_setupi,
1217 		&hf_sna_nlp_somi,
1218 		&hf_sna_nlp_eomi,
1219 		&hf_sna_nlp_sri,
1220 		&hf_sna_nlp_rasapi,
1221 		&hf_sna_nlp_retryi,
1222 		NULL
1223 	};
1224 	static int * const nlp_nhdr_9_fields[] = {
1225 		&hf_sna_nlp_lmi,
1226 		&hf_sna_nlp_cqfi,
1227 		&hf_sna_nlp_osi,
1228 		NULL
1229 	};
1230 
1231 	int indx = 0, counter = 0;
1232 
1233 	nlp_tree = NULL;
1234 	nlp_item = NULL;
1235 
1236 	nhdr_0 = tvb_get_guint8(tvb, indx);
1237 	nhdr_1 = tvb_get_guint8(tvb, indx+1);
1238 
1239 	col_set_str(pinfo->cinfo, COL_INFO, "HPR NLP Packet");
1240 
1241 	if (tree) {
1242 		/* Don't bother setting length. We'll set it later after we
1243 		 * find the lengths of NHDR */
1244 		nlp_item = proto_tree_add_item(tree, hf_sna_nlp_nhdr, tvb,
1245 		    indx, -1, ENC_NA);
1246 		nlp_tree = proto_item_add_subtree(nlp_item, ett_sna_nlp_nhdr);
1247 
1248 		proto_tree_add_bitmask(nlp_tree, tvb, indx, hf_sna_nlp_nhdr_0,
1249 			       ett_sna_nlp_nhdr_0, nlp_nhdr_0_fields, ENC_NA);
1250 
1251 		proto_tree_add_bitmask(nlp_tree, tvb, indx+1, hf_sna_nlp_nhdr_1,
1252 			       ett_sna_nlp_nhdr_1, nlp_nhdr_1_fields, ENC_NA);
1253 	}
1254 	/* ANR or FR lists */
1255 
1256 	indx += 2;
1257 	counter = 0;
1258 
1259 	if ((nhdr_0 & 0xe0) == 0xa0) {
1260 		do {
1261 			nhdr_x = tvb_get_guint8(tvb, indx + counter);
1262 			counter ++;
1263 		} while (nhdr_x != 0xff);
1264 		proto_tree_add_item(nlp_tree,
1265 			    hf_sna_nlp_fra, tvb, indx, counter, ENC_NA);
1266 		indx += counter;
1267 		proto_tree_add_item(nlp_tree, hf_sna_reserved, tvb, indx, 1, ENC_NA);
1268 		indx++;
1269 
1270 		if (tree)
1271 			proto_item_set_len(nlp_item, indx);
1272 
1273 		if ((nhdr_1 & 0xf0) == 0x10) {
1274 			proto_tree_add_item(tree, hf_sna_nlp_frh,
1275 				    tvb, indx, 1, ENC_BIG_ENDIAN);
1276 			indx ++;
1277 
1278 			if (tvb_offset_exists(tvb, indx))
1279 				call_data_dissector(tvb_new_subset_remaining(tvb, indx),
1280 					pinfo, parent_tree);
1281 			return;
1282 		}
1283 	}
1284 	if ((nhdr_0 & 0xe0) == 0xc0) {
1285 		do {
1286 			nhdr_x = tvb_get_guint8(tvb, indx + counter);
1287 			counter ++;
1288 		} while (nhdr_x != 0xff);
1289 		proto_tree_add_item(nlp_tree, hf_sna_nlp_anr,
1290 			    tvb, indx, counter, ENC_NA);
1291 		indx += counter;
1292 
1293 		proto_tree_add_item(nlp_tree, hf_sna_reserved, tvb, indx, 1, ENC_NA);
1294 		indx++;
1295 
1296 		if (tree)
1297 			proto_item_set_len(nlp_item, indx);
1298 	}
1299 
1300 	thdr_8 = tvb_get_guint8(tvb, indx+8);
1301 	thdr_9 = tvb_get_guint8(tvb, indx+9);
1302 	thdr_len = tvb_get_ntohs(tvb, indx+10);
1303 	thdr_dlf = tvb_get_ntohl(tvb, indx+12);
1304 
1305 	if (tree) {
1306 		nlp_item = proto_tree_add_item(tree, hf_sna_nlp_thdr, tvb,
1307 		    indx, thdr_len << 2, ENC_NA);
1308 		nlp_tree = proto_item_add_subtree(nlp_item, ett_sna_nlp_thdr);
1309 
1310 		proto_tree_add_item(nlp_tree, hf_sna_nlp_tcid, tvb,
1311 		    indx, 8, ENC_NA);
1312 
1313 		proto_tree_add_bitmask(nlp_tree, tvb, indx+8, hf_sna_nlp_thdr_8,
1314 			       ett_sna_nlp_thdr_8, nlp_nhdr_8_fields, ENC_NA);
1315 
1316 		proto_tree_add_bitmask(nlp_tree, tvb, indx+9, hf_sna_nlp_thdr_9,
1317 			       ett_sna_nlp_thdr_9, nlp_nhdr_9_fields, ENC_NA);
1318 
1319 		proto_tree_add_uint(nlp_tree, hf_sna_nlp_offset, tvb, indx+10,
1320 		    2, thdr_len);
1321 		proto_tree_add_uint(nlp_tree, hf_sna_nlp_dlf, tvb, indx+12,
1322 		    4, thdr_dlf);
1323 		proto_tree_add_item(nlp_tree, hf_sna_nlp_bsn, tvb, indx+16,
1324 		    4, ENC_BIG_ENDIAN);
1325 	}
1326 	subindx = 20;
1327 
1328 	if (((thdr_9 & 0x18) == 0x08) && ((thdr_len << 2) > subindx)) {
1329 		counter = tvb_get_guint8(tvb, indx + subindx);
1330 		if (tvb_get_guint8(tvb, indx+subindx+1) == 5)
1331 			dissect_sna_control(tvb, indx + subindx, counter+2, nlp_tree, 1, LT);
1332 		else
1333 			call_data_dissector(tvb_new_subset_length_caplen(tvb, indx + subindx, counter+2,
1334 			    -1), pinfo, nlp_tree);
1335 
1336 		subindx += (counter+2);
1337 	}
1338 	if ((thdr_9 & 0x04) && ((thdr_len << 2) > subindx))
1339 		dissect_optional(
1340 		    tvb_new_subset_length_caplen(tvb, indx + subindx,
1341 		    (thdr_len << 2) - subindx, -1),
1342 		    pinfo, nlp_tree);
1343 
1344 	indx += (thdr_len << 2);
1345 	if (((thdr_8 & 0x20) == 0) && thdr_dlf) {
1346 		col_set_str(pinfo->cinfo, COL_INFO, "HPR Fragment");
1347 		if (tvb_offset_exists(tvb, indx)) {
1348 			call_data_dissector(tvb_new_subset_remaining(tvb, indx), pinfo,
1349 			    parent_tree);
1350 		}
1351 		return;
1352 	}
1353 	if (tvb_offset_exists(tvb, indx)) {
1354 		/* Transmission Header Format Identifier */
1355 		fid = hi_nibble(tvb_get_guint8(tvb, indx));
1356 		if (fid == 5) /* Only FID5 allowed for HPR */
1357 			dissect_fid(tvb_new_subset_remaining(tvb, indx), pinfo,
1358 			    tree, parent_tree);
1359 		else {
1360 			if (tvb_get_ntohs(tvb, indx+2) == 0x12ce) {
1361 				/* Route Setup */
1362 				col_set_str(pinfo->cinfo, COL_INFO, "HPR Route Setup");
1363 				dissect_gds(tvb_new_subset_remaining(tvb, indx),
1364 				    pinfo, tree, parent_tree);
1365 			} else
1366 				call_data_dissector(tvb_new_subset_remaining(tvb, indx),
1367 				    pinfo, parent_tree);
1368 		}
1369 	}
1370 }
1371 
1372 /* --------------------------------------------------------------------
1373  * Chapter 3 Exchange Identification (XID) Information Fields
1374  * --------------------------------------------------------------------
1375  */
1376 
1377 static void
dissect_xid1(tvbuff_t * tvb,proto_tree * tree)1378 dissect_xid1(tvbuff_t *tvb, proto_tree *tree)
1379 {
1380 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 0, 2, ENC_NA);
1381 
1382 }
1383 
1384 static void
dissect_xid2(tvbuff_t * tvb,proto_tree * tree)1385 dissect_xid2(tvbuff_t *tvb, proto_tree *tree)
1386 {
1387 	guint		dlen, offset;
1388 
1389 	if (!tree)
1390 		return;
1391 
1392 	dlen = tvb_get_guint8(tvb, 0);
1393 
1394 	offset = dlen;
1395 
1396 	while (tvb_offset_exists(tvb, offset)) {
1397 		dlen = tvb_get_guint8(tvb, offset+1);
1398 		dissect_sna_control(tvb, offset, dlen+2, tree, 0, KL);
1399 		offset += (dlen + 2);
1400 	}
1401 }
1402 
1403 static void
dissect_xid3(tvbuff_t * tvb,proto_tree * tree)1404 dissect_xid3(tvbuff_t *tvb, proto_tree *tree)
1405 {
1406 	guint		dlen, offset;
1407 	static int * const sna_xid_3_fields[] = {
1408 		&hf_sna_xid_3_init_self,
1409 		&hf_sna_xid_3_stand_bind,
1410 		&hf_sna_xid_3_gener_bind,
1411 		&hf_sna_xid_3_recve_bind,
1412 		&hf_sna_xid_3_actpu,
1413 		&hf_sna_xid_3_nwnode,
1414 		&hf_sna_xid_3_cp,
1415 		&hf_sna_xid_3_cpcp,
1416 		&hf_sna_xid_3_state,
1417 		&hf_sna_xid_3_nonact,
1418 		&hf_sna_xid_3_cpchange,
1419 		NULL
1420 	};
1421 	static int * const sna_xid_10_fields[] = {
1422 		&hf_sna_xid_3_asend_bind,
1423 		&hf_sna_xid_3_arecv_bind,
1424 		&hf_sna_xid_3_quiesce,
1425 		&hf_sna_xid_3_pucap,
1426 		&hf_sna_xid_3_pbn,
1427 		&hf_sna_xid_3_pacing,
1428 		NULL
1429 	};
1430 	static int * const sna_xid_11_fields[] = {
1431 		&hf_sna_xid_3_tgshare,
1432 		&hf_sna_xid_3_dedsvc,
1433 		NULL
1434 	};
1435 	static int * const sna_xid_12_fields[] = {
1436 		&hf_sna_xid_3_negcsup,
1437 		&hf_sna_xid_3_negcomp,
1438 		NULL
1439 	};
1440 	static int * const sna_xid_15_fields[] = {
1441 		&hf_sna_xid_3_partg,
1442 		&hf_sna_xid_3_dlur,
1443 		&hf_sna_xid_3_dlus,
1444 		&hf_sna_xid_3_exbn,
1445 		&hf_sna_xid_3_genodai,
1446 		&hf_sna_xid_3_branch,
1447 		&hf_sna_xid_3_brnn,
1448 		NULL
1449 	};
1450 
1451 	if (!tree)
1452 		return;
1453 
1454 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 0, 2, ENC_NA);
1455 
1456 	proto_tree_add_bitmask(tree, tvb, 2, hf_sna_xid_3_8,
1457 			       ett_sna_xid_3_8, sna_xid_3_fields, ENC_BIG_ENDIAN);
1458 
1459 	proto_tree_add_bitmask(tree, tvb, 4, hf_sna_xid_3_10,
1460 			       ett_sna_xid_3_10, sna_xid_10_fields, ENC_BIG_ENDIAN);
1461 
1462 	proto_tree_add_bitmask(tree, tvb, 5, hf_sna_xid_3_11,
1463 			       ett_sna_xid_3_11, sna_xid_11_fields, ENC_BIG_ENDIAN);
1464 
1465 	proto_tree_add_bitmask(tree, tvb, 6, hf_sna_xid_3_12,
1466 			       ett_sna_xid_3_12, sna_xid_12_fields, ENC_BIG_ENDIAN);
1467 
1468 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 7, 2, ENC_NA);
1469 
1470 	proto_tree_add_bitmask(tree, tvb, 9, hf_sna_xid_3_15,
1471 			       ett_sna_xid_3_15, sna_xid_15_fields, ENC_BIG_ENDIAN);
1472 
1473 	proto_tree_add_item(tree, hf_sna_xid_3_tg, tvb, 10, 1, ENC_BIG_ENDIAN);
1474 	proto_tree_add_item(tree, hf_sna_xid_3_dlc, tvb, 11, 1, ENC_BIG_ENDIAN);
1475 
1476 	dlen = tvb_get_guint8(tvb, 12);
1477 
1478 	proto_tree_add_uint(tree, hf_sna_xid_3_dlen, tvb, 12, 1, dlen);
1479 
1480 	/* FIXME: DLC Dependent Data Go Here */
1481 
1482 	offset = 12 + dlen;
1483 
1484 	while (tvb_offset_exists(tvb, offset)) {
1485 		dlen = tvb_get_guint8(tvb, offset+1);
1486 		dissect_sna_control(tvb, offset, dlen+2, tree, 0, KL);
1487 		offset += (dlen+2);
1488 	}
1489 }
1490 
1491 static void
dissect_xid(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_tree * parent_tree)1492 dissect_xid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1493 	    proto_tree *parent_tree)
1494 {
1495 	proto_tree	*sub_tree;
1496 	proto_item	*sub_ti = NULL;
1497 	int		format, type, len;
1498 	guint32		id;
1499 
1500 	len = tvb_get_guint8(tvb, 1);
1501 	type = tvb_get_guint8(tvb, 0);
1502 	id = tvb_get_ntohl(tvb, 2);
1503 	format = hi_nibble(type);
1504 
1505 	/* Summary information */
1506 	col_add_fstr(pinfo->cinfo, COL_INFO,
1507 		    "SNA XID Format:%d Type:%s", format,
1508 		    val_to_str_const(lo_nibble(type), sna_xid_type_vals,
1509 		    "Unknown Type"));
1510 
1511 	if (tree) {
1512 		sub_ti = proto_tree_add_item(tree, hf_sna_xid_0, tvb,
1513 		    0, 1, ENC_BIG_ENDIAN);
1514 		sub_tree = proto_item_add_subtree(sub_ti, ett_sna_xid_0);
1515 
1516 		proto_tree_add_uint(sub_tree, hf_sna_xid_format, tvb, 0, 1,
1517 		    type);
1518 		proto_tree_add_uint(sub_tree, hf_sna_xid_type, tvb, 0, 1,
1519 		    type);
1520 
1521 		proto_tree_add_uint(tree, hf_sna_xid_len, tvb, 1, 1, len);
1522 
1523 		sub_ti = proto_tree_add_item(tree, hf_sna_xid_id, tvb,
1524 		    2, 4, ENC_BIG_ENDIAN);
1525 		sub_tree = proto_item_add_subtree(sub_ti, ett_sna_xid_id);
1526 
1527 		proto_tree_add_uint(sub_tree, hf_sna_xid_idblock, tvb, 2, 4,
1528 		    id);
1529 		proto_tree_add_uint(sub_tree, hf_sna_xid_idnum, tvb, 2, 4,
1530 		    id);
1531 
1532 		switch(format) {
1533 			case 0:
1534 				break;
1535 			case 1:
1536 				dissect_xid1(tvb_new_subset_length_caplen(tvb, 6, len-6, -1),
1537 				    tree);
1538 				break;
1539 			case 2:
1540 				dissect_xid2(tvb_new_subset_length_caplen(tvb, 6, len-6, -1),
1541 				    tree);
1542 				break;
1543 			case 3:
1544 				dissect_xid3(tvb_new_subset_length_caplen(tvb, 6, len-6, -1),
1545 				    tree);
1546 				break;
1547 			default:
1548 				/* external standards organizations */
1549 				call_data_dissector(tvb_new_subset_length_caplen(tvb, 6, len-6, -1),
1550 				    pinfo, tree);
1551 		}
1552 	}
1553 
1554 	if (format == 0)
1555 		len = 6;
1556 
1557 	if (tvb_offset_exists(tvb, len))
1558 		call_data_dissector(tvb_new_subset_remaining(tvb, len), pinfo, parent_tree);
1559 }
1560 
1561 /* --------------------------------------------------------------------
1562  * Chapter 4 Transmission Headers (THs)
1563  * --------------------------------------------------------------------
1564  */
1565 
1566 #define RH_LEN	3
1567 
1568 static unsigned int
mpf_value(guint8 th_byte)1569 mpf_value(guint8 th_byte)
1570 {
1571 	return (th_byte & 0x0c) >> 2;
1572 }
1573 
1574 #define FIRST_FRAG_NUMBER	0
1575 #define MIDDLE_FRAG_NUMBER	1
1576 #define LAST_FRAG_NUMBER	2
1577 
1578 /* FID2 is defragged by sequence. The weird thing is that we have neither
1579  * absolute sequence numbers, nor byte offets. Other FIDs have byte offsets
1580  * (the DCF field), but not FID2. The only thing we have to go with is "FIRST",
1581  * "MIDDLE", or "LAST". If the BIU is split into 3 frames, then everything is
1582  * fine, * "FIRST", "MIDDLE", and "LAST" map nicely onto frag-number 0, 1,
1583  * and 2. However, if the BIU is split into 2 frames, then we only have
1584  * "FIRST" and "LAST", and the mapping *should* be frag-number 0 and 1,
1585  * *NOT* 0 and 2.
1586  *
1587  * The SNA docs say "FID2 PIUs cannot be blocked because there is no DCF in the
1588  * TH format for deblocking" (note on Figure 4-2 in the IBM SNA documention,
1589  * see the FTP URL in the comment near the top of this file). I *think*
1590  * this means that the fragmented frames cannot arrive out of order.
1591  * Well, I *want* it to mean this, because w/o this limitation, if you
1592  * get a "FIRST" frame and a "LAST" frame, how long should you wait to
1593  * see if a "MIDDLE" frame every arrives????? Thus, if frames *have* to
1594  * arrive in order, then we're saved.
1595  *
1596  * The problem then boils down to figuring out if "LAST" means frag-number 1
1597  * (in the case of a BIU split into 2 frames) or frag-number 2
1598  * (in the case of a BIU split into 3 frames).
1599  *
1600  * Assuming fragmented FID2 BIU frames *do* arrive in order, the obvious
1601  * way to handle the mapping of "LAST" to either frag-number 1 or
1602  * frag-number 2 is to keep a hash which tracks the frames seen, etc.
1603  * This consumes resources. A trickier way, but a way which works, is to
1604  * always map the "LAST" BIU segment to frag-number 2. Here's the trickery:
1605  * if we add frag-number 2, which we know to be the "LAST" BIU segment,
1606  * and the reassembly code tells us that the the BIU is still not reassmebled,
1607  * then, owing to the, ahem, /fact/, that fragmented BIU segments arrive
1608  * in order :), we know that 1) "FIRST" did come, and 2) there's no "MIDDLE",
1609  * because this BIU was fragmented into 2 frames, not 3. So, we'll be
1610  * tricky and add a zero-length "MIDDLE" BIU frame (i.e, frag-number 1)
1611  * to complete the reassembly.
1612  */
1613 static tvbuff_t*
defragment_by_sequence(packet_info * pinfo,tvbuff_t * tvb,int offset,int mpf,int id)1614 defragment_by_sequence(packet_info *pinfo, tvbuff_t *tvb, int offset, int mpf,
1615 		       int id)
1616 {
1617 	fragment_head *fd_head;
1618 	int frag_number = -1;
1619 	int more_frags = TRUE;
1620 	tvbuff_t *rh_tvb = NULL;
1621 	gint frag_len;
1622 
1623 	/* Determine frag_number and more_frags */
1624 	switch(mpf) {
1625 		case MPF_WHOLE_BIU:
1626 			/* nothing */
1627 			break;
1628 		case MPF_FIRST_SEGMENT:
1629 			frag_number = FIRST_FRAG_NUMBER;
1630 			break;
1631 		case MPF_MIDDLE_SEGMENT:
1632 			frag_number = MIDDLE_FRAG_NUMBER;
1633 			break;
1634 		case MPF_LAST_SEGMENT:
1635 			frag_number = LAST_FRAG_NUMBER;
1636 			more_frags = FALSE;
1637 			break;
1638 		default:
1639 			DISSECTOR_ASSERT_NOT_REACHED();
1640 	}
1641 
1642 	/* If sna_defragment is on, and this is a fragment.. */
1643 	if (frag_number > -1) {
1644 		/* XXX - check length ??? */
1645 		frag_len = tvb_reported_length_remaining(tvb, offset);
1646 		if (tvb_bytes_exist(tvb, offset, frag_len)) {
1647 			fd_head = fragment_add_seq(&sna_reassembly_table,
1648 			    tvb, offset, pinfo, id, NULL,
1649 			    frag_number, frag_len, more_frags, 0);
1650 
1651 			/* We added the LAST segment and reassembly didn't
1652 			 * complete. Insert a zero-length MIDDLE segment to
1653 			 * turn a 2-frame BIU-fragmentation into a 3-frame
1654 			 * BIU-fragmentation (empty middle frag).
1655 		         * See above long comment about this trickery. */
1656 
1657 			if (mpf == MPF_LAST_SEGMENT && !fd_head) {
1658 				fd_head = fragment_add_seq(&sna_reassembly_table,
1659 				    tvb, offset, pinfo, id, NULL,
1660 				    MIDDLE_FRAG_NUMBER, 0, TRUE, 0);
1661 			}
1662 
1663 			if (fd_head != NULL) {
1664 				/* We have the complete reassembled payload. */
1665 				rh_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
1666 
1667 				/* Add the defragmented data to the data
1668 				 * source list. */
1669 				add_new_data_source(pinfo, rh_tvb,
1670 				    "Reassembled SNA BIU");
1671 			}
1672 		}
1673 	}
1674 	return rh_tvb;
1675 }
1676 
1677 #define SNA_FID01_ADDR_LEN	2
1678 
1679 /* FID Types 0 and 1 */
1680 static int
dissect_fid0_1(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)1681 dissect_fid0_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1682 {
1683 	proto_tree	*bf_tree;
1684 	proto_item	*bf_item;
1685 	guint8		th_0;
1686 
1687 	const int bytes_in_header = 10;
1688 
1689 	if (tree) {
1690 		/* Byte 0 */
1691 		th_0 = tvb_get_guint8(tvb, 0);
1692 		bf_item = proto_tree_add_uint(tree, hf_sna_th_0, tvb, 0, 1,
1693 		    th_0);
1694 		bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
1695 
1696 		proto_tree_add_uint(bf_tree, hf_sna_th_fid, tvb, 0, 1, th_0);
1697 		proto_tree_add_uint(bf_tree, hf_sna_th_mpf, tvb, 0, 1, th_0);
1698 		proto_tree_add_uint(bf_tree, hf_sna_th_efi, tvb, 0, 1, th_0);
1699 
1700 		/* Byte 1 */
1701 		proto_tree_add_item(tree, hf_sna_reserved, tvb, 1, 1, ENC_NA);
1702 
1703 		/* Bytes 2-3 */
1704 		proto_tree_add_item(tree, hf_sna_th_daf, tvb, 2, 2, ENC_BIG_ENDIAN);
1705 	}
1706 
1707 	/* Set DST addr */
1708 	set_address_tvb(&pinfo->net_dst, sna_address_type, SNA_FID01_ADDR_LEN, tvb, 2);
1709 	copy_address_shallow(&pinfo->dst, &pinfo->net_dst);
1710 
1711 	proto_tree_add_item(tree, hf_sna_th_oaf, tvb, 4, 2, ENC_BIG_ENDIAN);
1712 
1713 	/* Set SRC addr */
1714 	set_address_tvb(&pinfo->net_src, sna_address_type, SNA_FID01_ADDR_LEN, tvb, 4);
1715 	copy_address_shallow(&pinfo->src, &pinfo->net_src);
1716 
1717 	proto_tree_add_item(tree, hf_sna_th_snf, tvb, 6, 2, ENC_BIG_ENDIAN);
1718 	proto_tree_add_item(tree, hf_sna_th_dcf, tvb, 8, 2, ENC_BIG_ENDIAN);
1719 
1720 	return bytes_in_header;
1721 }
1722 
1723 #define SNA_FID2_ADDR_LEN	1
1724 
1725 /* FID Type 2 */
1726 static int
dissect_fid2(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,tvbuff_t ** rh_tvb_ptr,next_dissection_t * continue_dissecting)1727 dissect_fid2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1728 	     tvbuff_t **rh_tvb_ptr, next_dissection_t *continue_dissecting)
1729 {
1730 	proto_tree	*bf_tree;
1731 	proto_item	*bf_item;
1732 	guint8		th_0;
1733 	unsigned int	mpf, id;
1734 
1735 	const int bytes_in_header = 6;
1736 
1737 	th_0 = tvb_get_guint8(tvb, 0);
1738 	mpf = mpf_value(th_0);
1739 
1740 	if (tree) {
1741 
1742 		/* Byte 0 */
1743 		bf_item = proto_tree_add_item(tree, hf_sna_th_0, tvb, 0, 1, ENC_BIG_ENDIAN);
1744 		bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
1745 
1746 		proto_tree_add_item(bf_tree, hf_sna_th_fid, tvb, 0, 1, ENC_BIG_ENDIAN);
1747 		proto_tree_add_item(bf_tree, hf_sna_th_mpf, tvb, 0, 1, ENC_BIG_ENDIAN);
1748 		proto_tree_add_item(bf_tree, hf_sna_th_odai,tvb, 0, 1, ENC_BIG_ENDIAN);
1749 		proto_tree_add_item(bf_tree, hf_sna_th_efi, tvb, 0, 1, ENC_BIG_ENDIAN);
1750 
1751 
1752 		/* Byte 1 */
1753 		proto_tree_add_item(tree, hf_sna_reserved, tvb, 1, 1, ENC_NA);
1754 
1755 		/* Byte 2 */
1756 		proto_tree_add_item(tree, hf_sna_th_daf, tvb, 2, 1, ENC_BIG_ENDIAN);
1757 	}
1758 
1759 	/* Set DST addr */
1760 	set_address_tvb(&pinfo->net_dst, sna_address_type, SNA_FID2_ADDR_LEN, tvb, 2);
1761 	copy_address_shallow(&pinfo->dst, &pinfo->net_dst);
1762 
1763 	/* Byte 3 */
1764 	proto_tree_add_item(tree, hf_sna_th_oaf, tvb, 3, 1, ENC_BIG_ENDIAN);
1765 
1766 	/* Set SRC addr */
1767 	set_address_tvb(&pinfo->net_src, sna_address_type, SNA_FID2_ADDR_LEN, tvb, 3);
1768 	copy_address_shallow(&pinfo->src, &pinfo->net_src);
1769 
1770 	id = tvb_get_ntohs(tvb, 4);
1771 	proto_tree_add_item(tree, hf_sna_th_snf, tvb, 4, 2, ENC_BIG_ENDIAN);
1772 
1773 	if (mpf != MPF_WHOLE_BIU && !sna_defragment) {
1774 		if (mpf == MPF_FIRST_SEGMENT) {
1775 			*continue_dissecting = rh_only;
1776 			} else {
1777 			*continue_dissecting = stop_here;
1778 			}
1779 
1780 		}
1781 	else if (sna_defragment) {
1782 		*rh_tvb_ptr = defragment_by_sequence(pinfo, tvb,
1783 		    bytes_in_header, mpf, id);
1784 	}
1785 
1786 	return bytes_in_header;
1787 }
1788 
1789 /* FID Type 3 */
1790 static int
dissect_fid3(tvbuff_t * tvb,proto_tree * tree)1791 dissect_fid3(tvbuff_t *tvb, proto_tree *tree)
1792 {
1793 	proto_tree	*bf_tree;
1794 	proto_item	*bf_item;
1795 	guint8		th_0;
1796 
1797 	const int bytes_in_header = 2;
1798 
1799 	/* If we're not filling a proto_tree, return now */
1800 	if (!tree)
1801 		return bytes_in_header;
1802 
1803 	th_0 = tvb_get_guint8(tvb, 0);
1804 
1805 	/* Create the bitfield tree */
1806 	bf_item = proto_tree_add_uint(tree, hf_sna_th_0, tvb, 0, 1, th_0);
1807 	bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
1808 
1809 	proto_tree_add_uint(bf_tree, hf_sna_th_fid, tvb, 0, 1, th_0);
1810 	proto_tree_add_uint(bf_tree, hf_sna_th_mpf, tvb, 0, 1, th_0);
1811 	proto_tree_add_uint(bf_tree, hf_sna_th_efi, tvb, 0, 1, th_0);
1812 
1813 	proto_tree_add_item(tree, hf_sna_th_lsid, tvb, 1, 1, ENC_BIG_ENDIAN);
1814 
1815 	return bytes_in_header;
1816 }
1817 
1818 static int
dissect_fid4(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)1819 dissect_fid4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1820 {
1821 	int		offset = 0;
1822 	guint8		th_byte, mft;
1823 	guint16		def, oef;
1824 	guint32		dsaf, osaf;
1825 	static int * const byte0_fields[] = {
1826 		&hf_sna_th_fid,
1827 		&hf_sna_th_tg_sweep,
1828 		&hf_sna_th_er_vr_supp_ind,
1829 		&hf_sna_th_vr_pac_cnt_ind,
1830 		&hf_sna_th_ntwk_prty,
1831 		NULL
1832 	};
1833 	static int * const byte1_fields[] = {
1834 		&hf_sna_th_tgsf,
1835 		&hf_sna_th_mft,
1836 		&hf_sna_th_piubf,
1837 		NULL
1838 	};
1839 	static int * const byte2_mft_fields[] = {
1840 		&hf_sna_th_nlpoi,
1841 		&hf_sna_th_nlp_cp,
1842 		&hf_sna_th_ern,
1843 		NULL
1844 	};
1845 	static int * const byte2_fields[] = {
1846 		&hf_sna_th_iern,
1847 		&hf_sna_th_ern,
1848 		NULL
1849 	};
1850 	static int * const byte3_fields[] = {
1851 		&hf_sna_th_vrn,
1852 		&hf_sna_th_tpf,
1853 		NULL
1854 	};
1855 	static int * const byte4_fields[] = {
1856 		&hf_sna_th_vr_cwi,
1857 		&hf_sna_th_tg_nonfifo_ind,
1858 		&hf_sna_th_vr_sqti,
1859 	    /* I'm not sure about byte-order on this one... */
1860 		&hf_sna_th_tg_snf,
1861 		NULL
1862 	};
1863 	static int * const byte6_fields[] = {
1864 		&hf_sna_th_vrprq,
1865 		&hf_sna_th_vrprs,
1866 		&hf_sna_th_vr_cwri,
1867 		&hf_sna_th_vr_rwi,
1868 	    /* I'm not sure about byte-order on this one... */
1869 		&hf_sna_th_vr_snf_send,
1870 		NULL
1871 	};
1872 	static int * const byte16_fields[] = {
1873 		&hf_sna_th_snai,
1874 	/* We luck out here because in their infinite wisdom the SNA
1875 	 * architects placed the MPF and EFI fields in the same bitfield
1876 	 * locations, even though for FID4 they're not in byte 0.
1877 	 * Thank you IBM! */
1878 		&hf_sna_th_mpf,
1879 		&hf_sna_th_efi,
1880 		NULL
1881 	};
1882 
1883 	struct sna_fid_type_4_addr *src, *dst;
1884 
1885 	const int bytes_in_header = 26;
1886 
1887 	/* If we're not filling a proto_tree, return now */
1888 	if (!tree)
1889 		return bytes_in_header;
1890 
1891 	/* Byte 0 */
1892 	proto_tree_add_bitmask(tree, tvb, offset, hf_sna_th_0,
1893 			       ett_sna_th_fid, byte0_fields, ENC_NA);
1894 
1895 	offset += 1;
1896 	th_byte = tvb_get_guint8(tvb, offset);
1897 
1898 	/* Byte 1 */
1899 	proto_tree_add_bitmask(tree, tvb, offset, hf_sna_th_byte1,
1900 			       ett_sna_th_fid, byte1_fields, ENC_NA);
1901 
1902 	mft = th_byte & 0x04;
1903 	offset += 1;
1904 
1905 	/* Byte 2 */
1906 	if (mft) {
1907 		proto_tree_add_bitmask(tree, tvb, offset, hf_sna_th_byte2,
1908 			       ett_sna_th_fid, byte2_mft_fields, ENC_NA);
1909 	} else {
1910 		proto_tree_add_bitmask(tree, tvb, offset, hf_sna_th_byte2,
1911 			       ett_sna_th_fid, byte2_fields, ENC_NA);
1912 	}
1913 
1914 	offset += 1;
1915 
1916 	/* Byte 3 */
1917 	proto_tree_add_bitmask(tree, tvb, offset, hf_sna_th_byte3,
1918 			       ett_sna_th_fid, byte3_fields, ENC_NA);
1919 	offset += 1;
1920 
1921 	/* Bytes 4-5 */
1922 	proto_tree_add_bitmask(tree, tvb, offset, hf_sna_th_byte4,
1923 			       ett_sna_th_fid, byte4_fields, ENC_BIG_ENDIAN);
1924 	offset += 2;
1925 
1926 	/* Create the bitfield tree */
1927 	proto_tree_add_bitmask(tree, tvb, offset, hf_sna_th_byte6,
1928 			       ett_sna_th_fid, byte6_fields, ENC_BIG_ENDIAN);
1929 	offset += 2;
1930 
1931 	dsaf = tvb_get_ntohl(tvb, 8);
1932 	/* Bytes 8-11 */
1933 	proto_tree_add_uint(tree, hf_sna_th_dsaf, tvb, offset, 4, dsaf);
1934 
1935 	offset += 4;
1936 
1937 	osaf = tvb_get_ntohl(tvb, 12);
1938 	/* Bytes 12-15 */
1939 	proto_tree_add_uint(tree, hf_sna_th_osaf, tvb, offset, 4, osaf);
1940 
1941 	offset += 4;
1942 
1943 	/* Byte 16 */
1944 	proto_tree_add_bitmask(tree, tvb, offset, hf_sna_th_byte16,
1945 			       ett_sna_th_fid, byte16_fields, ENC_NA);
1946 
1947 	/* 1 for byte 16, 1 for byte 17 which is reserved */
1948 	offset += 2;
1949 
1950 	def = tvb_get_ntohs(tvb, 18);
1951 	/* Bytes 18-25 */
1952 	proto_tree_add_uint(tree, hf_sna_th_def, tvb, offset, 2, def);
1953 
1954 	/* Addresses in FID 4 are discontiguous, sigh */
1955 	dst = wmem_new0(pinfo->pool, struct sna_fid_type_4_addr);
1956 	dst->saf = dsaf;
1957 	dst->ef = def;
1958 	set_address(&pinfo->net_dst, sna_address_type, SNA_FID_TYPE_4_ADDR_LEN, dst);
1959 	copy_address_shallow(&pinfo->dst, &pinfo->net_dst);
1960 
1961 	oef = tvb_get_ntohs(tvb, 20);
1962 	proto_tree_add_uint(tree, hf_sna_th_oef, tvb, offset+2, 2, oef);
1963 
1964 	/* Addresses in FID 4 are discontiguous, sigh */
1965 	src = wmem_new0(pinfo->pool, struct sna_fid_type_4_addr);
1966 	src->saf = osaf;
1967 	src->ef = oef;
1968 	set_address(&pinfo->net_src, sna_address_type, SNA_FID_TYPE_4_ADDR_LEN, src);
1969 	copy_address_shallow(&pinfo->src, &pinfo->net_src);
1970 
1971 	proto_tree_add_item(tree, hf_sna_th_snf, tvb, offset+4, 2, ENC_BIG_ENDIAN);
1972 	proto_tree_add_item(tree, hf_sna_th_dcf, tvb, offset+6, 2, ENC_BIG_ENDIAN);
1973 
1974 	return bytes_in_header;
1975 }
1976 
1977 /* FID Type 5 */
1978 static int
dissect_fid5(tvbuff_t * tvb,proto_tree * tree)1979 dissect_fid5(tvbuff_t *tvb, proto_tree *tree)
1980 {
1981 	proto_tree	*bf_tree;
1982 	proto_item	*bf_item;
1983 	guint8		th_0;
1984 
1985 	const int bytes_in_header = 12;
1986 
1987 	/* If we're not filling a proto_tree, return now */
1988 	if (!tree)
1989 		return bytes_in_header;
1990 
1991 	th_0 = tvb_get_guint8(tvb, 0);
1992 
1993 	/* Create the bitfield tree */
1994 	bf_item = proto_tree_add_uint(tree, hf_sna_th_0, tvb, 0, 1, th_0);
1995 	bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
1996 
1997 	proto_tree_add_uint(bf_tree, hf_sna_th_fid, tvb, 0, 1, th_0);
1998 	proto_tree_add_uint(bf_tree, hf_sna_th_mpf, tvb, 0, 1, th_0);
1999 	proto_tree_add_uint(bf_tree, hf_sna_th_efi, tvb, 0, 1, th_0);
2000 
2001 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 1, 1, ENC_NA);
2002 	proto_tree_add_item(tree, hf_sna_th_snf, tvb, 2, 2, ENC_BIG_ENDIAN);
2003 
2004 	proto_tree_add_item(tree, hf_sna_th_sa, tvb, 4, 8, ENC_NA);
2005 
2006 	return bytes_in_header;
2007 
2008 }
2009 
2010 /* FID Type f */
2011 static int
dissect_fidf(tvbuff_t * tvb,proto_tree * tree)2012 dissect_fidf(tvbuff_t *tvb, proto_tree *tree)
2013 {
2014 	proto_tree	*bf_tree;
2015 	proto_item	*bf_item;
2016 	guint8		th_0;
2017 
2018 	const int bytes_in_header = 26;
2019 
2020 	/* If we're not filling a proto_tree, return now */
2021 	if (!tree)
2022 		return bytes_in_header;
2023 
2024 	th_0 = tvb_get_guint8(tvb, 0);
2025 
2026 	/* Create the bitfield tree */
2027 	bf_item = proto_tree_add_uint(tree, hf_sna_th_0, tvb, 0, 1, th_0);
2028 	bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
2029 
2030 	proto_tree_add_uint(bf_tree, hf_sna_th_fid, tvb, 0, 1, th_0);
2031 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 1, 1, ENC_NA);
2032 
2033 	proto_tree_add_item(tree, hf_sna_th_cmd_fmt, tvb,  2, 1, ENC_BIG_ENDIAN);
2034 	proto_tree_add_item(tree, hf_sna_th_cmd_type, tvb, 3, 1, ENC_BIG_ENDIAN);
2035 	proto_tree_add_item(tree, hf_sna_th_cmd_sn, tvb,   4, 2, ENC_BIG_ENDIAN);
2036 
2037 	/* Yup, bytes 6-23 are reserved! */
2038 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 6, 18, ENC_NA);
2039 
2040 	proto_tree_add_item(tree, hf_sna_th_dcf, tvb, 24, 2, ENC_BIG_ENDIAN);
2041 
2042 	return bytes_in_header;
2043 }
2044 
2045 static void
dissect_fid(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_tree * parent_tree)2046 dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2047 	    proto_tree *parent_tree)
2048 {
2049 
2050 	proto_tree	*th_tree = NULL, *rh_tree = NULL;
2051 	proto_item	*th_ti = NULL, *rh_ti = NULL;
2052 	guint8		th_fid;
2053 	int		th_header_len = 0;
2054 	int		offset, rh_offset;
2055 	tvbuff_t	*rh_tvb = NULL;
2056 	next_dissection_t continue_dissecting = everything;
2057 
2058 	/* Transmission Header Format Identifier */
2059 	th_fid = hi_nibble(tvb_get_guint8(tvb, 0));
2060 
2061 	/* Summary information */
2062 	col_add_str(pinfo->cinfo, COL_INFO,
2063 		    val_to_str(th_fid, sna_th_fid_vals, "Unknown FID: %01x"));
2064 
2065 	if (tree) {
2066 		/* --- TH --- */
2067 		/* Don't bother setting length. We'll set it later after we
2068 		 * find the length of TH */
2069 		th_ti = proto_tree_add_item(tree, hf_sna_th, tvb,  0, -1,
2070 		    ENC_NA);
2071 		th_tree = proto_item_add_subtree(th_ti, ett_sna_th);
2072 	}
2073 
2074 	/* Get size of TH */
2075 	switch(th_fid) {
2076 		case 0x0:
2077 		case 0x1:
2078 			th_header_len = dissect_fid0_1(tvb, pinfo, th_tree);
2079 			break;
2080 		case 0x2:
2081 			th_header_len = dissect_fid2(tvb, pinfo, th_tree,
2082 			    &rh_tvb, &continue_dissecting);
2083 			break;
2084 		case 0x3:
2085 			th_header_len = dissect_fid3(tvb, th_tree);
2086 			break;
2087 		case 0x4:
2088 			th_header_len = dissect_fid4(tvb, pinfo, th_tree);
2089 			break;
2090 		case 0x5:
2091 			th_header_len = dissect_fid5(tvb, th_tree);
2092 			break;
2093 		case 0xf:
2094 			th_header_len = dissect_fidf(tvb, th_tree);
2095 			break;
2096 		default:
2097 			call_data_dissector(tvb_new_subset_remaining(tvb, 1), pinfo, parent_tree);
2098 			return;
2099 	}
2100 
2101 	offset = th_header_len;
2102 
2103 	/* Short-circuit ? */
2104 	if (continue_dissecting == stop_here) {
2105 		proto_tree_add_item(tree, hf_sna_biu_segment_data, tvb, offset, -1, ENC_NA);
2106 		return;
2107 	}
2108 
2109 	/* If the FID dissector function didn't create an rh_tvb, then we just
2110 	 * use the rest of our tvbuff as the rh_tvb. */
2111 	if (!rh_tvb)
2112 		rh_tvb = tvb_new_subset_remaining(tvb, offset);
2113 	rh_offset = 0;
2114 
2115 	/* Process the rest of the SNA packet, starting with RH */
2116 	if (tree) {
2117 		proto_item_set_len(th_ti, th_header_len);
2118 
2119 		/* --- RH --- */
2120 		rh_ti = proto_tree_add_item(tree, hf_sna_rh, rh_tvb, rh_offset,
2121 		    RH_LEN, ENC_NA);
2122 		rh_tree = proto_item_add_subtree(rh_ti, ett_sna_rh);
2123 		dissect_rh(rh_tvb, rh_offset, rh_tree);
2124 	}
2125 
2126 	rh_offset += RH_LEN;
2127 
2128 	if (tvb_offset_exists(rh_tvb, rh_offset)) {
2129 		/* Short-circuit ? */
2130 		if (continue_dissecting == rh_only) {
2131 			proto_tree_add_item(tree, hf_sna_biu_segment_data, rh_tvb, rh_offset, -1, ENC_NA);
2132 			return;
2133 		}
2134 
2135 		call_data_dissector(tvb_new_subset_remaining(rh_tvb, rh_offset),
2136 		    pinfo, parent_tree);
2137 	}
2138 }
2139 
2140 /* --------------------------------------------------------------------
2141  * Chapter 5 Request/Response Headers (RHs)
2142  * --------------------------------------------------------------------
2143  */
2144 
2145 static void
dissect_rh(tvbuff_t * tvb,int offset,proto_tree * tree)2146 dissect_rh(tvbuff_t *tvb, int offset, proto_tree *tree)
2147 {
2148 	gboolean	is_response;
2149 	guint8		rh_0;
2150 	static int * const sna_rh_fields[] = {
2151 		&hf_sna_rh_rri,
2152 		&hf_sna_rh_ru_category,
2153 		&hf_sna_rh_fi,
2154 		&hf_sna_rh_sdi,
2155 		&hf_sna_rh_bci,
2156 		&hf_sna_rh_eci,
2157 		NULL
2158 	};
2159 	static int * const sna_rh_1_req_fields[] = {
2160 		&hf_sna_rh_dr1,
2161 		&hf_sna_rh_lcci,
2162 		&hf_sna_rh_dr2,
2163 		&hf_sna_rh_eri,
2164 		&hf_sna_rh_rlwi,
2165 		&hf_sna_rh_qri,
2166 		&hf_sna_rh_pi,
2167 		NULL
2168 	};
2169 	static int * const sna_rh_1_rsp_fields[] = {
2170 		&hf_sna_rh_dr1,
2171 		&hf_sna_rh_dr2,
2172 		&hf_sna_rh_rti,
2173 		&hf_sna_rh_qri,
2174 		&hf_sna_rh_pi,
2175 		NULL
2176 	};
2177 	static int * const sna_rh_2_req_fields[] = {
2178 		&hf_sna_rh_bbi,
2179 		&hf_sna_rh_ebi,
2180 		&hf_sna_rh_cdi,
2181 		&hf_sna_rh_csi,
2182 		&hf_sna_rh_edi,
2183 		&hf_sna_rh_pdi,
2184 		&hf_sna_rh_cebi,
2185 		NULL
2186 	};
2187 
2188 	if (!tree)
2189 		return;
2190 
2191 	/* Create the bitfield tree for byte 0*/
2192 	rh_0 = tvb_get_guint8(tvb, offset);
2193 	is_response = (rh_0 & 0x80);
2194 
2195 	proto_tree_add_bitmask(tree, tvb, offset, hf_sna_rh_0,
2196 			       ett_sna_rh_0, sna_rh_fields, ENC_BIG_ENDIAN);
2197 	offset += 1;
2198 
2199 	/* Create the bitfield tree for byte 1*/
2200 	if (is_response) {
2201 		proto_tree_add_bitmask(tree, tvb, offset, hf_sna_rh_1,
2202 			       ett_sna_rh_1, sna_rh_1_rsp_fields, ENC_BIG_ENDIAN);
2203 	} else {
2204 		proto_tree_add_bitmask(tree, tvb, offset, hf_sna_rh_1,
2205 			       ett_sna_rh_1, sna_rh_1_req_fields, ENC_BIG_ENDIAN);
2206 	}
2207 	offset += 1;
2208 
2209 	/* Create the bitfield tree for byte 2*/
2210 	if (!is_response) {
2211 		proto_tree_add_bitmask(tree, tvb, offset, hf_sna_rh_2,
2212 			       ett_sna_rh_2, sna_rh_2_req_fields, ENC_BIG_ENDIAN);
2213 	} else {
2214 		proto_tree_add_item(tree, hf_sna_rh_2, tvb, offset, 1, ENC_BIG_ENDIAN);
2215 	}
2216 
2217 	/* XXX - check for sdi. If TRUE, the next 4 bytes will be sense data */
2218 }
2219 
2220 /* --------------------------------------------------------------------
2221  * Chapter 6 Request/Response Units (RUs)
2222  * --------------------------------------------------------------------
2223  */
2224 
2225 /* --------------------------------------------------------------------
2226  * Chapter 9 Common Fields
2227  * --------------------------------------------------------------------
2228  */
2229 
2230 static void
dissect_control_05hpr(tvbuff_t * tvb,proto_tree * tree,int hpr,enum parse parse)2231 dissect_control_05hpr(tvbuff_t *tvb, proto_tree *tree, int hpr,
2232 		      enum parse parse)
2233 {
2234 	guint16		offset, len, pad;
2235 	static int * const sna_control_05hpr_fields[] = {
2236 		&hf_sna_control_05_ptp,
2237 		NULL
2238 	};
2239 
2240 	if (!tree)
2241 		return;
2242 
2243 	proto_tree_add_bitmask(tree, tvb, 2, hf_sna_control_05_type,
2244 			       ett_sna_control_05hpr_type, sna_control_05hpr_fields, ENC_BIG_ENDIAN);
2245 
2246 	proto_tree_add_item(tree, hf_sna_reserved, tvb, 3, 1, ENC_NA);
2247 
2248 	offset = 4;
2249 
2250 	while (tvb_offset_exists(tvb, offset)) {
2251 		if (parse == LT) {
2252 			len = tvb_get_guint8(tvb, offset+0);
2253 		} else {
2254 			len = tvb_get_guint8(tvb, offset+1);
2255 		}
2256 		if (len) {
2257 			dissect_sna_control(tvb, offset, len, tree, hpr, parse);
2258 			pad = (len+3) & 0xfffc;
2259 			if (pad > len) {
2260 				proto_tree_add_item(tree, hf_sna_padding, tvb, offset+len, pad-len, ENC_NA);
2261 			}
2262 			offset += pad;
2263 		} else {
2264 			return;
2265 		}
2266 	}
2267 }
2268 
2269 static void
dissect_control_05(tvbuff_t * tvb,proto_tree * tree)2270 dissect_control_05(tvbuff_t *tvb, proto_tree *tree)
2271 {
2272 	if(!tree)
2273 		return;
2274 
2275 	proto_tree_add_item(tree, hf_sna_control_05_delay, tvb, 2, 2, ENC_BIG_ENDIAN);
2276 }
2277 
2278 static void
dissect_control_0e(tvbuff_t * tvb,proto_tree * tree)2279 dissect_control_0e(tvbuff_t *tvb, proto_tree *tree)
2280 {
2281 	gint	len;
2282 
2283 	if (!tree)
2284 		return;
2285 
2286 	proto_tree_add_item(tree, hf_sna_control_0e_type, tvb, 2, 1, ENC_BIG_ENDIAN);
2287 
2288 	len = tvb_reported_length_remaining(tvb, 3);
2289 	if (len <= 0)
2290 		return;
2291 
2292 	proto_tree_add_item(tree, hf_sna_control_0e_value, tvb, 3, len, ENC_EBCDIC|ENC_NA);
2293 }
2294 
2295 static void
dissect_sna_control(tvbuff_t * parent_tvb,int offset,int control_len,proto_tree * tree,int hpr,enum parse parse)2296 dissect_sna_control(tvbuff_t *parent_tvb, int offset, int control_len,
2297 		proto_tree *tree, int hpr, enum parse parse)
2298 {
2299 	tvbuff_t	*tvb;
2300 	gint		length, reported_length;
2301 	proto_tree	*sub_tree;
2302 	int		len, key;
2303 	gint		ett;
2304 
2305 	length = tvb_captured_length_remaining(parent_tvb, offset);
2306 	reported_length = tvb_reported_length_remaining(parent_tvb, offset);
2307 	if (control_len < length)
2308 		length = control_len;
2309 	if (control_len < reported_length)
2310 		reported_length = control_len;
2311 	tvb = tvb_new_subset_length_caplen(parent_tvb, offset, length, reported_length);
2312 
2313 	sub_tree = NULL;
2314 
2315 	if (parse == LT) {
2316 		len = tvb_get_guint8(tvb, 0);
2317 		key = tvb_get_guint8(tvb, 1);
2318 	} else {
2319 		key = tvb_get_guint8(tvb, 0);
2320 		len = tvb_get_guint8(tvb, 1);
2321 	}
2322 	ett = ett_sna_control_un;
2323 
2324 	if (tree) {
2325 		if (key == 5) {
2326 			 if (hpr) ett = ett_sna_control_05hpr;
2327 			 else ett = ett_sna_control_05;
2328 		}
2329 		if (key == 0x0e) ett = ett_sna_control_0e;
2330 
2331 		if (((key == 0) || (key == 3) || (key == 5)) && hpr)
2332 			sub_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett, NULL,
2333 			    val_to_str_const(key, sna_control_hpr_vals,
2334 			    "Unknown Control Vector"));
2335 		else
2336 			sub_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett, NULL,
2337 			    val_to_str_const(key, sna_control_vals,
2338 			    "Unknown Control Vector"));
2339 		if (parse == LT) {
2340 			proto_tree_add_uint(sub_tree, hf_sna_control_len,
2341 			    tvb, 0, 1, len);
2342 			if (((key == 0) || (key == 3) || (key == 5)) && hpr)
2343 				proto_tree_add_uint(sub_tree,
2344 				    hf_sna_control_hprkey, tvb, 1, 1, key);
2345 			else
2346 				proto_tree_add_uint(sub_tree,
2347 				    hf_sna_control_key, tvb, 1, 1, key);
2348 		} else {
2349 			if (((key == 0) || (key == 3) || (key == 5)) && hpr)
2350 				proto_tree_add_uint(sub_tree,
2351 				    hf_sna_control_hprkey, tvb, 0, 1, key);
2352 			else
2353 				proto_tree_add_uint(sub_tree,
2354 				    hf_sna_control_key, tvb, 0, 1, key);
2355 			proto_tree_add_uint(sub_tree, hf_sna_control_len,
2356 			    tvb, 1, 1, len);
2357 		}
2358 	}
2359 	switch(key) {
2360 		case 0x05:
2361 			if (hpr)
2362 				dissect_control_05hpr(tvb, sub_tree, hpr,
2363 				    parse);
2364 			else
2365 				dissect_control_05(tvb, sub_tree);
2366 			break;
2367 		case 0x0e:
2368 			dissect_control_0e(tvb, sub_tree);
2369 			break;
2370 	}
2371 }
2372 
2373 /* --------------------------------------------------------------------
2374  * Chapter 11 Function Management (FM) Headers
2375  * --------------------------------------------------------------------
2376  */
2377 
2378 /* --------------------------------------------------------------------
2379  * Chapter 12 Presentation Services (PS) Headers
2380  * --------------------------------------------------------------------
2381  */
2382 
2383 /* --------------------------------------------------------------------
2384  * Chapter 13 GDS Variables
2385  * --------------------------------------------------------------------
2386  */
2387 
2388 static void
dissect_gds(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_tree * parent_tree)2389 dissect_gds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2390 	    proto_tree *parent_tree)
2391 {
2392 	guint16		length;
2393 	int		cont;
2394 	int		offset = 0;
2395 	proto_item	*pi;
2396 	proto_tree	*subtree;
2397 	gboolean	first_ll = TRUE;
2398 
2399 	do {
2400 		length = tvb_get_ntohs(tvb, offset) & 0x7fff;
2401 		cont   = (tvb_get_ntohs(tvb, offset) & 0x8000) ? 1 : 0;
2402 
2403 		pi = proto_tree_add_item(tree, hf_sna_gds, tvb, offset, -1, ENC_NA);
2404 		subtree = proto_item_add_subtree(pi, ett_sna_gds);
2405 		proto_tree_add_item(subtree, hf_sna_gds_len, tvb, offset, 2, ENC_BIG_ENDIAN);
2406 		proto_tree_add_item(subtree, hf_sna_gds_cont, tvb, offset, 2, ENC_BIG_ENDIAN);
2407 		if (length < 2 ) /* escape sequence */
2408 			return;
2409 		offset += 2;
2410 		length -= 2;
2411 		if (first_ll) {
2412 			proto_tree_add_item(subtree, hf_sna_gds_type, tvb, offset, 2, ENC_BIG_ENDIAN);
2413 			offset += 2;
2414 			length -= 2;
2415 			first_ll = FALSE;
2416 		}
2417 		if (length > 0) {
2418 			proto_tree_add_item(subtree, hf_sna_gds_info, tvb, offset, length, ENC_NA);
2419 			offset += length;
2420 		}
2421 	} while(cont);
2422 	proto_item_set_len(pi, offset);
2423 	if (tvb_offset_exists(tvb, offset))
2424 		call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, parent_tree);
2425 }
2426 
2427 /* --------------------------------------------------------------------
2428  * General stuff
2429  * --------------------------------------------------------------------
2430  */
2431 
2432 static int
dissect_sna(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2433 dissect_sna(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2434 {
2435 	guint8		fid;
2436 	proto_tree	*sna_tree = NULL;
2437 	proto_item	*sna_ti = NULL;
2438 
2439 	col_set_str(pinfo->cinfo, COL_PROTOCOL, "SNA");
2440 	col_clear(pinfo->cinfo, COL_INFO);
2441 
2442 	/* SNA data should be printed in EBCDIC, not ASCII */
2443 	pinfo->fd->encoding = PACKET_CHAR_ENC_CHAR_EBCDIC;
2444 
2445 	if (tree) {
2446 
2447 		/* Don't bother setting length. We'll set it later after we find
2448 		 * the lengths of TH/RH/RU */
2449 		sna_ti = proto_tree_add_item(tree, proto_sna, tvb, 0, -1,
2450 		    ENC_NA);
2451 		sna_tree = proto_item_add_subtree(sna_ti, ett_sna);
2452 	}
2453 
2454 	/* Transmission Header Format Identifier */
2455 	fid = hi_nibble(tvb_get_guint8(tvb, 0));
2456 	switch(fid) {
2457 		case 0xa:	/* HPR Network Layer Packet */
2458 		case 0xb:
2459 		case 0xc:
2460 		case 0xd:
2461 			dissect_nlp(tvb, pinfo, sna_tree, tree);
2462 			break;
2463 		default:
2464 			dissect_fid(tvb, pinfo, sna_tree, tree);
2465 	}
2466 	return tvb_captured_length(tvb);
2467 }
2468 
2469 static int
dissect_sna_xid(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2470 dissect_sna_xid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2471 {
2472 	proto_tree	*sna_tree = NULL;
2473 	proto_item	*sna_ti = NULL;
2474 
2475 	col_set_str(pinfo->cinfo, COL_PROTOCOL, "SNA");
2476 	col_clear(pinfo->cinfo, COL_INFO);
2477 
2478 	/* SNA data should be printed in EBCDIC, not ASCII */
2479 	pinfo->fd->encoding = PACKET_CHAR_ENC_CHAR_EBCDIC;
2480 
2481 	if (tree) {
2482 
2483 		/* Don't bother setting length. We'll set it later after we find
2484 		 * the lengths of XID */
2485 		sna_ti = proto_tree_add_item(tree, proto_sna_xid, tvb, 0, -1,
2486 		    ENC_NA);
2487 		sna_tree = proto_item_add_subtree(sna_ti, ett_sna);
2488 	}
2489 	dissect_xid(tvb, pinfo, sna_tree, tree);
2490 	return tvb_captured_length(tvb);
2491 }
2492 
2493 
2494 void
proto_register_sna(void)2495 proto_register_sna(void)
2496 {
2497 	static hf_register_info hf[] = {
2498 		{ &hf_sna_th,
2499 		  { "Transmission Header", "sna.th", FT_NONE, BASE_NONE,
2500 		    NULL, 0x0, NULL, HFILL }},
2501 
2502 		{ &hf_sna_th_0,
2503 		  { "Transmission Header Byte 0", "sna.th.0", FT_UINT8, BASE_HEX,
2504 		    NULL, 0x0,
2505 		    "TH Byte 0", HFILL }},
2506 
2507 		{ &hf_sna_th_fid,
2508 		  { "Format Identifier", "sna.th.fid", FT_UINT8, BASE_HEX,
2509 		    VALS(sna_th_fid_vals), 0xf0, NULL, HFILL }},
2510 
2511 		{ &hf_sna_th_mpf,
2512 		  { "Mapping Field", "sna.th.mpf", FT_UINT8,
2513 		    BASE_DEC, VALS(sna_th_mpf_vals), 0x0c, NULL, HFILL }},
2514 
2515 		{ &hf_sna_th_odai,
2516 		  { "ODAI Assignment Indicator", "sna.th.odai", FT_UINT8,
2517 		    BASE_DEC, NULL, 0x02, NULL, HFILL }},
2518 
2519 		{ &hf_sna_th_efi,
2520 		  { "Expedited Flow Indicator", "sna.th.efi", FT_UINT8,
2521 		    BASE_DEC, VALS(sna_th_efi_vals), 0x01, NULL, HFILL }},
2522 
2523 		{ &hf_sna_th_daf,
2524 		  { "Destination Address Field", "sna.th.daf", FT_UINT16,
2525 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
2526 
2527 		{ &hf_sna_th_oaf,
2528 		  { "Origin Address Field", "sna.th.oaf", FT_UINT16, BASE_HEX,
2529 		    NULL, 0x0, NULL, HFILL }},
2530 
2531 		{ &hf_sna_th_snf,
2532 		  { "Sequence Number Field", "sna.th.snf", FT_UINT16, BASE_DEC,
2533 		    NULL, 0x0, NULL, HFILL }},
2534 
2535 		{ &hf_sna_th_dcf,
2536 		  { "Data Count Field", "sna.th.dcf", FT_UINT16, BASE_DEC,
2537 		    NULL, 0x0, NULL, HFILL }},
2538 
2539 		{ &hf_sna_th_lsid,
2540 		  { "Local Session Identification", "sna.th.lsid", FT_UINT8,
2541 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
2542 
2543 		{ &hf_sna_th_tg_sweep,
2544 		  { "Transmission Group Sweep", "sna.th.tg_sweep", FT_UINT8,
2545 		    BASE_DEC, VALS(sna_th_tg_sweep_vals), 0x08, NULL, HFILL }},
2546 
2547 		{ &hf_sna_th_er_vr_supp_ind,
2548 		  { "ER and VR Support Indicator", "sna.th.er_vr_supp_ind",
2549 		    FT_UINT8, BASE_DEC, VALS(sna_th_er_vr_supp_ind_vals),
2550 		    0x04, NULL, HFILL }},
2551 
2552 		{ &hf_sna_th_vr_pac_cnt_ind,
2553 		  { "Virtual Route Pacing Count Indicator",
2554 		    "sna.th.vr_pac_cnt_ind", FT_UINT8, BASE_DEC,
2555 		    VALS(sna_th_vr_pac_cnt_ind_vals), 0x02, NULL, HFILL }},
2556 
2557 		{ &hf_sna_th_ntwk_prty,
2558 		  { "Network Priority", "sna.th.ntwk_prty", FT_UINT8, BASE_DEC,
2559 		    VALS(sna_th_ntwk_prty_vals), 0x01, NULL, HFILL }},
2560 
2561 		{ &hf_sna_th_tgsf,
2562 		  { "Transmission Group Segmenting Field", "sna.th.tgsf",
2563 		    FT_UINT8, BASE_HEX, VALS(sna_th_tgsf_vals), 0xc0,
2564 		    NULL, HFILL }},
2565 
2566 		{ &hf_sna_th_mft,
2567 		  { "MPR FID4 Type", "sna.th.mft", FT_BOOLEAN, 8,
2568 		    NULL, 0x04, NULL, HFILL }},
2569 
2570 		{ &hf_sna_th_piubf,
2571 		  { "PIU Blocking Field", "sna.th.piubf", FT_UINT8, BASE_HEX,
2572 		    VALS(sna_th_piubf_vals), 0x03, NULL, HFILL }},
2573 
2574 		{ &hf_sna_th_iern,
2575 		  { "Initial Explicit Route Number", "sna.th.iern", FT_UINT8,
2576 		    BASE_DEC, NULL, 0xf0, NULL, HFILL }},
2577 
2578 		{ &hf_sna_th_nlpoi,
2579 		  { "NLP Offset Indicator", "sna.th.nlpoi", FT_UINT8, BASE_DEC,
2580 		    VALS(sna_th_nlpoi_vals), 0x80, NULL, HFILL }},
2581 
2582 		{ &hf_sna_th_nlp_cp,
2583 		  { "NLP Count or Padding", "sna.th.nlp_cp", FT_UINT8, BASE_DEC,
2584 		    NULL, 0x70, NULL, HFILL }},
2585 
2586 		{ &hf_sna_th_ern,
2587 		  { "Explicit Route Number", "sna.th.ern", FT_UINT8, BASE_DEC,
2588 		    NULL, 0x0f, NULL, HFILL }},
2589 
2590 		{ &hf_sna_th_vrn,
2591 		  { "Virtual Route Number", "sna.th.vrn", FT_UINT8, BASE_DEC,
2592 		    NULL, 0xf0, NULL, HFILL }},
2593 
2594 		{ &hf_sna_th_tpf,
2595 		  { "Transmission Priority Field", "sna.th.tpf", FT_UINT8,
2596 		    BASE_HEX, VALS(sna_th_tpf_vals), 0x03, NULL, HFILL }},
2597 
2598 		{ &hf_sna_th_vr_cwi,
2599 		  { "Virtual Route Change Window Indicator", "sna.th.vr_cwi",
2600 		    FT_UINT16, BASE_DEC, VALS(sna_th_vr_cwi_vals), 0x8000,
2601 		    "Change Window Indicator", HFILL }},
2602 
2603 		{ &hf_sna_th_tg_nonfifo_ind,
2604 		  { "Transmission Group Non-FIFO Indicator",
2605 		    "sna.th.tg_nonfifo_ind", FT_BOOLEAN, 16,
2606 		    TFS(&sna_th_tg_nonfifo_ind_truth), 0x4000, NULL, HFILL }},
2607 
2608 		{ &hf_sna_th_vr_sqti,
2609 		  { "Virtual Route Sequence and Type Indicator", "sna.th.vr_sqti",
2610 		    FT_UINT16, BASE_HEX, VALS(sna_th_vr_sqti_vals), 0x3000,
2611 		    "Route Sequence and Type", HFILL }},
2612 
2613 		{ &hf_sna_th_tg_snf,
2614 		  { "Transmission Group Sequence Number Field", "sna.th.tg_snf",
2615 		    FT_UINT16, BASE_DEC, NULL, 0x0fff, NULL, HFILL }},
2616 
2617 		{ &hf_sna_th_vrprq,
2618 		  { "Virtual Route Pacing Request", "sna.th.vrprq", FT_BOOLEAN,
2619 		    16, TFS(&sna_th_vrprq_truth), 0x8000, NULL, HFILL }},
2620 
2621 		{ &hf_sna_th_vrprs,
2622 		  { "Virtual Route Pacing Response", "sna.th.vrprs", FT_BOOLEAN,
2623 		    16, TFS(&sna_th_vrprs_truth), 0x4000, NULL, HFILL }},
2624 
2625 		{ &hf_sna_th_vr_cwri,
2626 		  { "Virtual Route Change Window Reply Indicator",
2627 		    "sna.th.vr_cwri", FT_UINT16, BASE_DEC,
2628 		    VALS(sna_th_vr_cwri_vals), 0x2000, NULL, HFILL }},
2629 
2630 		{ &hf_sna_th_vr_rwi,
2631 		  { "Virtual Route Reset Window Indicator", "sna.th.vr_rwi",
2632 		    FT_BOOLEAN, 16, TFS(&sna_th_vr_rwi_truth), 0x1000,
2633 		    NULL, HFILL }},
2634 
2635 		{ &hf_sna_th_vr_snf_send,
2636 		  { "Virtual Route Send Sequence Number Field",
2637 		    "sna.th.vr_snf_send", FT_UINT16, BASE_DEC, NULL, 0x0fff,
2638 		    "Send Sequence Number Field", HFILL }},
2639 
2640 		{ &hf_sna_th_dsaf,
2641 		  { "Destination Subarea Address Field", "sna.th.dsaf",
2642 		    FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2643 
2644 		{ &hf_sna_th_osaf,
2645 		  { "Origin Subarea Address Field", "sna.th.osaf", FT_UINT32,
2646 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
2647 
2648 		{ &hf_sna_th_snai,
2649 		  { "SNA Indicator", "sna.th.snai", FT_BOOLEAN, 8, NULL, 0x10,
2650 		    "Used to identify whether the PIU originated or is destined for an SNA or non-SNA device.", HFILL }},
2651 
2652 		{ &hf_sna_th_def,
2653 		  { "Destination Element Field", "sna.th.def", FT_UINT16,
2654 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
2655 
2656 		{ &hf_sna_th_oef,
2657 		  { "Origin Element Field", "sna.th.oef", FT_UINT16, BASE_HEX,
2658 		    NULL, 0x0, NULL, HFILL }},
2659 
2660 		{ &hf_sna_th_sa,
2661 		  { "Session Address", "sna.th.sa", FT_BYTES, BASE_NONE,
2662 		    NULL, 0x0, NULL, HFILL }},
2663 
2664 		{ &hf_sna_th_cmd_fmt,
2665 		  { "Command Format", "sna.th.cmd_fmt", FT_UINT8, BASE_HEX,
2666 		    NULL, 0x0, NULL, HFILL }},
2667 
2668 		{ &hf_sna_th_cmd_type,
2669 		  { "Command Type", "sna.th.cmd_type", FT_UINT8, BASE_HEX,
2670 		    NULL, 0x0, NULL, HFILL }},
2671 
2672 		{ &hf_sna_th_cmd_sn,
2673 		  { "Command Sequence Number", "sna.th.cmd_sn", FT_UINT16,
2674 		    BASE_DEC, NULL, 0x0, NULL, HFILL }},
2675 
2676 		{ &hf_sna_th_byte1,
2677 		  { "Transmission Header Bytes 1", "sna.th.byte1", FT_UINT8,
2678 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
2679 
2680 		{ &hf_sna_th_byte2,
2681 		  { "Transmission Header Bytes 2", "sna.th.byte2", FT_UINT8,
2682 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
2683 
2684 		{ &hf_sna_th_byte3,
2685 		  { "Transmission Header Bytes 3", "sna.th.byte3", FT_UINT8,
2686 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
2687 
2688 		{ &hf_sna_th_byte4,
2689 		  { "Transmission Header Bytes 4-5", "sna.th.byte4", FT_UINT16,
2690 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
2691 
2692 		{ &hf_sna_th_byte6,
2693 		  { "Transmission Header Bytes 6-7", "sna.th.byte6", FT_UINT16,
2694 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
2695 
2696 		{ &hf_sna_th_byte16,
2697 		  { "Transmission Header Bytes 16", "sna.th.byte16", FT_UINT8,
2698 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
2699 
2700 		{ &hf_sna_nlp_nhdr,
2701 		  { "Network Layer Packet Header", "sna.nlp.nhdr", FT_NONE,
2702 		    BASE_NONE, NULL, 0x0, "NHDR", HFILL }},
2703 
2704 		{ &hf_sna_nlp_nhdr_0,
2705 		  { "Network Layer Packet Header Byte 0",	"sna.nlp.nhdr.0",
2706 		    FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2707 
2708 		{ &hf_sna_nlp_nhdr_1,
2709 		  { "Network Layer Packet Header Byte 1", "sna.nlp.nhdr.1",
2710 		    FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2711 
2712 		{ &hf_sna_nlp_sm,
2713 		  { "Switching Mode Field", "sna.nlp.nhdr.sm", FT_UINT8,
2714 		    BASE_HEX, VALS(sna_nlp_sm_vals), 0xe0, NULL, HFILL }},
2715 
2716 		{ &hf_sna_nlp_tpf,
2717 		  { "Transmission Priority Field", "sna.nlp.nhdr.tpf", FT_UINT8,
2718 		    BASE_HEX, VALS(sna_th_tpf_vals), 0x06, NULL, HFILL }},
2719 
2720 		{ &hf_sna_nlp_ft,
2721 		  { "Function Type", "sna.nlp.nhdr.ft", FT_UINT8, BASE_HEX,
2722 		    VALS(sna_nlp_ft_vals), 0xF0, NULL, HFILL }},
2723 
2724 		{ &hf_sna_nlp_tspi,
2725 		  { "Time Sensitive Packet Indicator", "sna.nlp.nhdr.tspi",
2726 		    FT_BOOLEAN, 8, TFS(&sna_nlp_tspi_truth), 0x08, NULL, HFILL }},
2727 
2728 		{ &hf_sna_nlp_slowdn1,
2729 		  { "Slowdown 1", "sna.nlp.nhdr.slowdn1", FT_BOOLEAN, 8,
2730 		    TFS(&sna_nlp_slowdn1_truth), 0x04, NULL, HFILL }},
2731 
2732 		{ &hf_sna_nlp_slowdn2,
2733 		  { "Slowdown 2", "sna.nlp.nhdr.slowdn2", FT_BOOLEAN, 8,
2734 		    TFS(&sna_nlp_slowdn2_truth), 0x02, NULL, HFILL }},
2735 
2736 		{ &hf_sna_nlp_fra,
2737 		  { "Function Routing Address Entry", "sna.nlp.nhdr.fra",
2738 		    FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
2739 
2740 		{ &hf_sna_nlp_anr,
2741 		  { "Automatic Network Routing Entry", "sna.nlp.nhdr.anr",
2742 		    FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
2743 
2744 		{ &hf_sna_nlp_frh,
2745 		  { "Transmission Priority Field", "sna.nlp.frh", FT_UINT8,
2746 		    BASE_HEX, VALS(sna_nlp_frh_vals), 0, NULL, HFILL }},
2747 
2748 		{ &hf_sna_nlp_thdr,
2749 		  { "RTP Transport Header", "sna.nlp.thdr", FT_NONE, BASE_NONE,
2750 		    NULL, 0x0, "THDR", HFILL }},
2751 
2752 		{ &hf_sna_nlp_tcid,
2753 		  { "Transport Connection Identifier", "sna.nlp.thdr.tcid",
2754 		    FT_BYTES, BASE_NONE, NULL, 0x0, "TCID", HFILL }},
2755 
2756 		{ &hf_sna_nlp_thdr_8,
2757 		  { "RTP Transport Packet Header Byte 8", "sna.nlp.thdr.8",
2758 		    FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2759 
2760 		{ &hf_sna_nlp_setupi,
2761 		  { "Setup Indicator", "sna.nlp.thdr.setupi", FT_BOOLEAN, 8,
2762 		    TFS(&sna_nlp_setupi_truth), 0x40, NULL, HFILL }},
2763 
2764 		{ &hf_sna_nlp_somi,
2765 		  { "Start Of Message Indicator", "sna.nlp.thdr.somi",
2766 		    FT_BOOLEAN, 8, TFS(&sna_nlp_somi_truth), 0x20, NULL, HFILL }},
2767 
2768 		{ &hf_sna_nlp_eomi,
2769 		  { "End Of Message Indicator", "sna.nlp.thdr.eomi", FT_BOOLEAN,
2770 		    8, TFS(&sna_nlp_eomi_truth), 0x10, NULL, HFILL }},
2771 
2772 		{ &hf_sna_nlp_sri,
2773 		  { "Session Request Indicator", "sna.nlp.thdr.sri", FT_BOOLEAN,
2774 		    8, TFS(&sna_nlp_sri_truth), 0x08, NULL, HFILL }},
2775 
2776 		{ &hf_sna_nlp_rasapi,
2777 		  { "Reply ASAP Indicator", "sna.nlp.thdr.rasapi", FT_BOOLEAN,
2778 		    8, TFS(&sna_nlp_rasapi_truth), 0x04, NULL, HFILL }},
2779 
2780 		{ &hf_sna_nlp_retryi,
2781 		  { "Retry Indicator", "sna.nlp.thdr.retryi", FT_BOOLEAN,
2782 		    8, TFS(&sna_nlp_retryi_truth), 0x02, NULL, HFILL }},
2783 
2784 		{ &hf_sna_nlp_thdr_9,
2785 		  { "RTP Transport Packet Header Byte 9", "sna.nlp.thdr.9",
2786 		    FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2787 
2788 		{ &hf_sna_nlp_lmi,
2789 		  { "Last Message Indicator", "sna.nlp.thdr.lmi", FT_BOOLEAN,
2790 		    8, TFS(&sna_nlp_lmi_truth), 0x80, NULL, HFILL }},
2791 
2792 		{ &hf_sna_nlp_cqfi,
2793 		  { "Connection Qualifier Field Indicator", "sna.nlp.thdr.cqfi",
2794 		    FT_BOOLEAN, 8, TFS(&sna_nlp_cqfi_truth), 0x08, NULL, HFILL }},
2795 
2796 		{ &hf_sna_nlp_osi,
2797 		  { "Optional Segments Present Indicator", "sna.nlp.thdr.osi",
2798 		    FT_BOOLEAN, 8, TFS(&sna_nlp_osi_truth), 0x04, NULL, HFILL }},
2799 
2800 		{ &hf_sna_nlp_offset,
2801 		  { "Data Offset/4", "sna.nlp.thdr.offset", FT_UINT16, BASE_HEX,
2802 		    NULL, 0x0, "Data Offset in Words", HFILL }},
2803 
2804 		{ &hf_sna_nlp_dlf,
2805 		  { "Data Length Field", "sna.nlp.thdr.dlf", FT_UINT32, BASE_HEX,
2806 		    NULL, 0x0, NULL, HFILL }},
2807 
2808 		{ &hf_sna_nlp_bsn,
2809 		  { "Byte Sequence Number", "sna.nlp.thdr.bsn", FT_UINT32,
2810 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
2811 
2812 		{ &hf_sna_nlp_opti_len,
2813 		  { "Optional Segment Length/4", "sna.nlp.thdr.optional.len",
2814 		    FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2815 
2816 		{ &hf_sna_nlp_opti_type,
2817 		  { "Optional Segment Type", "sna.nlp.thdr.optional.type",
2818 		    FT_UINT8, BASE_HEX, VALS(sna_nlp_opti_vals), 0x0, NULL,
2819 		    HFILL }},
2820 
2821 		{ &hf_sna_nlp_opti_0d_version,
2822 		  { "Version", "sna.nlp.thdr.optional.0d.version",
2823 		    FT_UINT16, BASE_HEX, VALS(sna_nlp_opti_0d_version_vals),
2824 		    0, NULL, HFILL }},
2825 
2826 		{ &hf_sna_nlp_opti_0d_4,
2827 		  { "Connection Setup Byte 4", "sna.nlp.thdr.optional.0e.4",
2828 		    FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
2829 
2830 		{ &hf_sna_nlp_opti_0d_target,
2831 		  { "Target Resource ID Present",
2832 		    "sna.nlp.thdr.optional.0d.target",
2833 		    FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
2834 
2835 		{ &hf_sna_nlp_opti_0d_arb,
2836 		  { "ARB Flow Control", "sna.nlp.thdr.optional.0d.arb",
2837 		    FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
2838 
2839 		{ &hf_sna_nlp_opti_0d_reliable,
2840 		  { "Reliable Connection", "sna.nlp.thdr.optional.0d.reliable",
2841 		    FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
2842 
2843 		{ &hf_sna_nlp_opti_0d_dedicated,
2844 		  { "Dedicated RTP Connection",
2845 		    "sna.nlp.thdr.optional.0d.dedicated",
2846 		    FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
2847 
2848 		{ &hf_sna_nlp_opti_0e_stat,
2849 		  { "Status", "sna.nlp.thdr.optional.0e.stat",
2850 		    FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
2851 
2852 		{ &hf_sna_nlp_opti_0e_gap,
2853 		  { "Gap Detected", "sna.nlp.thdr.optional.0e.gap",
2854 		    FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
2855 
2856 		{ &hf_sna_nlp_opti_0e_idle,
2857 		  { "RTP Idle Packet", "sna.nlp.thdr.optional.0e.idle",
2858 		    FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }},
2859 
2860 		{ &hf_sna_nlp_opti_0e_nabsp,
2861 		  { "Number Of ABSP", "sna.nlp.thdr.optional.0e.nabsp",
2862 		    FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2863 
2864 		{ &hf_sna_nlp_opti_0e_sync,
2865 		  { "Status Report Number", "sna.nlp.thdr.optional.0e.sync",
2866 		    FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2867 
2868 		{ &hf_sna_nlp_opti_0e_echo,
2869 		  { "Status Acknowledge Number", "sna.nlp.thdr.optional.0e.echo",
2870 		    FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2871 
2872 		{ &hf_sna_nlp_opti_0e_rseq,
2873 		  { "Received Sequence Number", "sna.nlp.thdr.optional.0e.rseq",
2874 		    FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2875 
2876 #if 0
2877 		{ &hf_sna_nlp_opti_0e_abspbeg,
2878 		  { "ABSP Begin", "sna.nlp.thdr.optional.0e.abspbeg",
2879 		    FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2880 #endif
2881 
2882 #if 0
2883 		{ &hf_sna_nlp_opti_0e_abspend,
2884 		  { "ABSP End", "sna.nlp.thdr.optional.0e.abspend",
2885 		    FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2886 #endif
2887 
2888 		{ &hf_sna_nlp_opti_0f_bits,
2889 		  { "Client Bits", "sna.nlp.thdr.optional.0f.bits",
2890 		    FT_UINT8, BASE_HEX, VALS(sna_nlp_opti_0f_bits_vals),
2891 		    0x0, NULL, HFILL }},
2892 
2893 		{ &hf_sna_nlp_opti_10_tcid,
2894 		  { "Transport Connection Identifier",
2895 		    "sna.nlp.thdr.optional.10.tcid",
2896 		    FT_BYTES, BASE_NONE, NULL, 0x0, "TCID", HFILL }},
2897 
2898 		{ &hf_sna_nlp_opti_12_sense,
2899 		  { "Sense Data", "sna.nlp.thdr.optional.12.sense",
2900 		    FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2901 
2902 		{ &hf_sna_nlp_opti_14_si_len,
2903 		  { "Length", "sna.nlp.thdr.optional.14.si.len",
2904 		    FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2905 
2906 		{ &hf_sna_nlp_opti_14_si_key,
2907 		  { "Key", "sna.nlp.thdr.optional.14.si.key",
2908 		    FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2909 
2910 		{ &hf_sna_nlp_opti_14_si_2,
2911 		  { "Switching Information Byte 2",
2912 		    "sna.nlp.thdr.optional.14.si.2",
2913 		    FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2914 
2915 		{ &hf_sna_nlp_opti_14_si_refifo,
2916 		  { "Resequencing (REFIFO) Indicator",
2917 		    "sna.nlp.thdr.optional.14.si.refifo",
2918 		    FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
2919 
2920 		{ &hf_sna_nlp_opti_14_si_mobility,
2921 		  { "Mobility Indicator",
2922 		    "sna.nlp.thdr.optional.14.si.mobility",
2923 		    FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }},
2924 
2925 		{ &hf_sna_nlp_opti_14_si_dirsearch,
2926 		  { "Directory Search Required on Path Switch Indicator",
2927 		    "sna.nlp.thdr.optional.14.si.dirsearch",
2928 		    FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }},
2929 
2930 		{ &hf_sna_nlp_opti_14_si_limitres,
2931 		  { "Limited Resource Link Indicator",
2932 		    "sna.nlp.thdr.optional.14.si.limitres",
2933 		    FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
2934 
2935 		{ &hf_sna_nlp_opti_14_si_ncescope,
2936 		  { "NCE Scope Indicator",
2937 		    "sna.nlp.thdr.optional.14.si.ncescope",
2938 		    FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
2939 
2940 		{ &hf_sna_nlp_opti_14_si_mnpsrscv,
2941 		  { "MNPS RSCV Retention Indicator",
2942 		    "sna.nlp.thdr.optional.14.si.mnpsrscv",
2943 		    FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
2944 
2945 		{ &hf_sna_nlp_opti_14_si_maxpsize,
2946 		  { "Maximum Packet Size On Return Path",
2947 		    "sna.nlp.thdr.optional.14.si.maxpsize",
2948 		    FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2949 
2950 		{ &hf_sna_nlp_opti_14_si_switch,
2951 		  { "Path Switch Time", "sna.nlp.thdr.optional.14.si.switch",
2952 		    FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2953 
2954 		{ &hf_sna_nlp_opti_14_si_alive,
2955 		  { "RTP Alive Timer", "sna.nlp.thdr.optional.14.si.alive",
2956 		    FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2957 
2958 		{ &hf_sna_nlp_opti_14_rr_len,
2959 		  { "Length", "sna.nlp.thdr.optional.14.rr.len",
2960 		    FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2961 
2962 		{ &hf_sna_nlp_opti_14_rr_key,
2963 		  { "Key", "sna.nlp.thdr.optional.14.rr.key",
2964 		    FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2965 
2966 		{ &hf_sna_nlp_opti_14_rr_2,
2967 		  { "Return Route TG Descriptor Byte 2",
2968 		    "sna.nlp.thdr.optional.14.rr.2",
2969 		    FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2970 
2971 		{ &hf_sna_nlp_opti_14_rr_bfe,
2972 		  { "BF Entry Indicator",
2973 		    "sna.nlp.thdr.optional.14.rr.bfe",
2974 		    FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
2975 
2976 		{ &hf_sna_nlp_opti_14_rr_num,
2977 		  { "Number Of TG Control Vectors",
2978 		    "sna.nlp.thdr.optional.14.rr.num",
2979 		    FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2980 
2981 		{ &hf_sna_nlp_opti_22_2,
2982 		  { "Adaptive Rate Based Segment Byte 2",
2983 		    "sna.nlp.thdr.optional.22.2",
2984 		    FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2985 
2986 		{ &hf_sna_nlp_opti_22_type,
2987 		  { "Message Type",
2988 		    "sna.nlp.thdr.optional.22.type",
2989 		    FT_UINT8, BASE_HEX,
2990 		    VALS(sna_nlp_opti_22_type_vals), 0xc0, NULL, HFILL }},
2991 
2992 		{ &hf_sna_nlp_opti_22_raa,
2993 		  { "Rate Adjustment Action",
2994 		    "sna.nlp.thdr.optional.22.raa",
2995 		    FT_UINT8, BASE_HEX,
2996 		    VALS(sna_nlp_opti_22_raa_vals), 0x38, NULL, HFILL }},
2997 
2998 		{ &hf_sna_nlp_opti_22_parity,
2999 		  { "Parity Indicator",
3000 		    "sna.nlp.thdr.optional.22.parity",
3001 		    FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
3002 
3003 		{ &hf_sna_nlp_opti_22_arb,
3004 		  { "ARB Mode",
3005 		    "sna.nlp.thdr.optional.22.arb",
3006 		    FT_UINT8, BASE_HEX,
3007 		    VALS(sna_nlp_opti_22_arb_vals), 0x03, NULL, HFILL }},
3008 
3009 		{ &hf_sna_nlp_opti_22_3,
3010 		  { "Adaptive Rate Based Segment Byte 3",
3011 		    "sna.nlp.thdr.optional.22.3",
3012 		    FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3013 
3014 		{ &hf_sna_nlp_opti_22_ratereq,
3015 		  { "Rate Request Correlator",
3016 		    "sna.nlp.thdr.optional.22.ratereq",
3017 		    FT_UINT8, BASE_DEC, NULL, 0xf0, NULL, HFILL }},
3018 
3019 		{ &hf_sna_nlp_opti_22_raterep,
3020 		  { "Rate Reply Correlator",
3021 		    "sna.nlp.thdr.optional.22.raterep",
3022 		    FT_UINT8, BASE_DEC, NULL, 0x0f, NULL, HFILL }},
3023 
3024 		{ &hf_sna_nlp_opti_22_field1,
3025 		  { "Field 1", "sna.nlp.thdr.optional.22.field1",
3026 		    FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3027 
3028 		{ &hf_sna_nlp_opti_22_field2,
3029 		  { "Field 2", "sna.nlp.thdr.optional.22.field2",
3030 		    FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3031 
3032 		{ &hf_sna_nlp_opti_22_field3,
3033 		  { "Field 3", "sna.nlp.thdr.optional.22.field3",
3034 		    FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3035 
3036 		{ &hf_sna_nlp_opti_22_field4,
3037 		  { "Field 4", "sna.nlp.thdr.optional.22.field4",
3038 		    FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3039 
3040 		{ &hf_sna_rh,
3041 		  { "Request/Response Header", "sna.rh", FT_NONE, BASE_NONE,
3042 		    NULL, 0x0, NULL, HFILL }},
3043 
3044 		{ &hf_sna_rh_0,
3045 		  { "Request/Response Header Byte 0", "sna.rh.0", FT_UINT8,
3046 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
3047 
3048 		{ &hf_sna_rh_1,
3049 		  { "Request/Response Header Byte 1", "sna.rh.1", FT_UINT8,
3050 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
3051 
3052 		{ &hf_sna_rh_2,
3053 		  { "Request/Response Header Byte 2", "sna.rh.2", FT_UINT8,
3054 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
3055 
3056 		{ &hf_sna_rh_rri,
3057 		  { "Request/Response Indicator", "sna.rh.rri", FT_UINT8,
3058 		    BASE_DEC, VALS(sna_rh_rri_vals), 0x80, NULL, HFILL }},
3059 
3060 		{ &hf_sna_rh_ru_category,
3061 		  { "Request/Response Unit Category", "sna.rh.ru_category",
3062 		    FT_UINT8, BASE_HEX, VALS(sna_rh_ru_category_vals), 0x60,
3063 		    NULL, HFILL }},
3064 
3065 		{ &hf_sna_rh_fi,
3066 		  { "Format Indicator", "sna.rh.fi", FT_BOOLEAN, 8,
3067 		    TFS(&sna_rh_fi_truth), 0x08, NULL, HFILL }},
3068 
3069 		{ &hf_sna_rh_sdi,
3070 		  { "Sense Data Included", "sna.rh.sdi", FT_BOOLEAN, 8,
3071 		    TFS(&tfs_included_not_included), 0x04, NULL, HFILL }},
3072 
3073 		{ &hf_sna_rh_bci,
3074 		  { "Begin Chain Indicator", "sna.rh.bci", FT_BOOLEAN, 8,
3075 		    TFS(&sna_rh_bci_truth), 0x02, NULL, HFILL }},
3076 
3077 		{ &hf_sna_rh_eci,
3078 		  { "End Chain Indicator", "sna.rh.eci", FT_BOOLEAN, 8,
3079 		    TFS(&sna_rh_eci_truth), 0x01, NULL, HFILL }},
3080 
3081 		{ &hf_sna_rh_dr1,
3082 		  { "Definite Response 1 Indicator", "sna.rh.dr1", FT_BOOLEAN,
3083 		    8, NULL, 0x80, NULL, HFILL }},
3084 
3085 		{ &hf_sna_rh_lcci,
3086 		  { "Length-Checked Compression Indicator", "sna.rh.lcci",
3087 		    FT_BOOLEAN, 8, TFS(&sna_rh_lcci_truth), 0x40, NULL, HFILL }},
3088 
3089 		{ &hf_sna_rh_dr2,
3090 		  { "Definite Response 2 Indicator", "sna.rh.dr2", FT_BOOLEAN,
3091 		    8, NULL, 0x20, NULL, HFILL }},
3092 
3093 		{ &hf_sna_rh_eri,
3094 		  { "Exception Response Indicator", "sna.rh.eri", FT_BOOLEAN,
3095 		    8, NULL, 0x10, NULL, HFILL }},
3096 
3097 		{ &hf_sna_rh_rti,
3098 		  { "Response Type Indicator", "sna.rh.rti", FT_BOOLEAN,
3099 		    8, TFS(&sna_rh_rti_truth), 0x10, NULL, HFILL }},
3100 
3101 		{ &hf_sna_rh_rlwi,
3102 		  { "Request Larger Window Indicator", "sna.rh.rlwi", FT_BOOLEAN,
3103 		    8, NULL, 0x04, NULL, HFILL }},
3104 
3105 		{ &hf_sna_rh_qri,
3106 		  { "Queued Response Indicator", "sna.rh.qri", FT_BOOLEAN,
3107 		    8, TFS(&sna_rh_qri_truth), 0x02, NULL, HFILL }},
3108 
3109 		{ &hf_sna_rh_pi,
3110 		  { "Pacing Indicator", "sna.rh.pi", FT_BOOLEAN,
3111 		    8, NULL, 0x01, NULL, HFILL }},
3112 
3113 		{ &hf_sna_rh_bbi,
3114 		  { "Begin Bracket Indicator", "sna.rh.bbi", FT_BOOLEAN,
3115 		    8, NULL, 0x80, NULL, HFILL }},
3116 
3117 		{ &hf_sna_rh_ebi,
3118 		  { "End Bracket Indicator", "sna.rh.ebi", FT_BOOLEAN,
3119 		    8, NULL, 0x40, NULL, HFILL }},
3120 
3121 		{ &hf_sna_rh_cdi,
3122 		  { "Change Direction Indicator", "sna.rh.cdi", FT_BOOLEAN,
3123 		    8, NULL, 0x20, NULL, HFILL }},
3124 
3125 		{ &hf_sna_rh_csi,
3126 		  { "Code Selection Indicator", "sna.rh.csi", FT_UINT8, BASE_DEC,
3127 		    VALS(sna_rh_csi_vals), 0x08, NULL, HFILL }},
3128 
3129 		{ &hf_sna_rh_edi,
3130 		  { "Enciphered Data Indicator", "sna.rh.edi", FT_BOOLEAN, 8,
3131 		    NULL, 0x04, NULL, HFILL }},
3132 
3133 		{ &hf_sna_rh_pdi,
3134 		  { "Padded Data Indicator", "sna.rh.pdi", FT_BOOLEAN, 8, NULL,
3135 		    0x02, NULL, HFILL }},
3136 
3137 		{ &hf_sna_rh_cebi,
3138 		  { "Conditional End Bracket Indicator", "sna.rh.cebi",
3139 		    FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
3140 
3141 /*		{ &hf_sna_ru,
3142 		{ "Request/Response Unit", "sna.ru", FT_NONE, BASE_NONE,
3143 		NULL, 0x0, NULL, HFILL }},*/
3144 
3145 		{ &hf_sna_gds,
3146 		  { "GDS Variable", "sna.gds", FT_NONE, BASE_NONE, NULL, 0x0,
3147 		    NULL, HFILL }},
3148 
3149 		{ &hf_sna_gds_len,
3150 		  { "GDS Variable Length", "sna.gds.len", FT_UINT16, BASE_DEC,
3151 		    NULL, 0x7fff, NULL, HFILL }},
3152 
3153 		{ &hf_sna_gds_cont,
3154 		  { "Continuation Flag", "sna.gds.cont", FT_BOOLEAN, 16, NULL,
3155 		    0x8000, NULL, HFILL }},
3156 
3157 		{ &hf_sna_gds_type,
3158 		  { "Type of Variable", "sna.gds.type", FT_UINT16, BASE_HEX,
3159 		    VALS(sna_gds_var_vals), 0x0, NULL, HFILL }},
3160 
3161 		{ &hf_sna_gds_info,
3162 		  { "Information", "sna.gds.info", FT_BYTES, BASE_NONE,
3163 		    NULL, 0x0, NULL, HFILL }},
3164 
3165 #if 0
3166 		{ &hf_sna_xid,
3167 		  { "XID", "sna.xid", FT_NONE, BASE_NONE, NULL, 0x0,
3168 		    "XID Frame", HFILL }},
3169 #endif
3170 
3171 		{ &hf_sna_xid_0,
3172 		  { "XID Byte 0", "sna.xid.0", FT_UINT8, BASE_HEX, NULL, 0x0,
3173 		    NULL, HFILL }},
3174 
3175 		{ &hf_sna_xid_format,
3176 		  { "XID Format", "sna.xid.format", FT_UINT8, BASE_DEC, NULL,
3177 		    0xf0, NULL, HFILL }},
3178 
3179 		{ &hf_sna_xid_type,
3180 		  { "XID Type", "sna.xid.type", FT_UINT8, BASE_DEC,
3181 		    VALS(sna_xid_type_vals), 0x0f, NULL, HFILL }},
3182 
3183 		{ &hf_sna_xid_len,
3184 		  { "XID Length", "sna.xid.len", FT_UINT8, BASE_DEC, NULL, 0x0,
3185 		    NULL, HFILL }},
3186 
3187 		{ &hf_sna_xid_id,
3188 		  { "Node Identification", "sna.xid.id", FT_UINT32, BASE_HEX,
3189 		    NULL, 0x0, NULL, HFILL }},
3190 
3191 		{ &hf_sna_xid_idblock,
3192 		  { "ID Block", "sna.xid.idblock", FT_UINT32, BASE_HEX, NULL,
3193 		    0xfff00000, NULL, HFILL }},
3194 
3195 		{ &hf_sna_xid_idnum,
3196 		  { "ID Number", "sna.xid.idnum", FT_UINT32, BASE_HEX, NULL,
3197 		    0x0fffff, NULL, HFILL }},
3198 
3199 		{ &hf_sna_xid_3_8,
3200 		  { "Characteristics of XID sender", "sna.xid.type3.8", FT_UINT16,
3201 		    BASE_HEX, NULL, 0x0, NULL, HFILL }},
3202 
3203 		{ &hf_sna_xid_3_init_self,
3204 		  { "INIT-SELF support", "sna.xid.type3.initself",
3205 		    FT_BOOLEAN, 16, NULL, 0x8000, NULL, HFILL }},
3206 
3207 		{ &hf_sna_xid_3_stand_bind,
3208 		  { "Stand-Alone BIND Support", "sna.xid.type3.stand_bind",
3209 		    FT_BOOLEAN, 16, NULL, 0x4000, NULL, HFILL }},
3210 
3211 		{ &hf_sna_xid_3_gener_bind,
3212 		  { "Whole BIND PIU generated indicator",
3213 		    "sna.xid.type3.gener_bind", FT_BOOLEAN, 16, NULL, 0x2000,
3214 		    "Whole BIND PIU generated", HFILL }},
3215 
3216 		{ &hf_sna_xid_3_recve_bind,
3217 		  { "Whole BIND PIU required indicator",
3218 		    "sna.xid.type3.recve_bind", FT_BOOLEAN, 16, NULL, 0x1000,
3219 		    "Whole BIND PIU required", HFILL }},
3220 
3221 		{ &hf_sna_xid_3_actpu,
3222 		  { "ACTPU suppression indicator", "sna.xid.type3.actpu",
3223 		    FT_BOOLEAN, 16, NULL, 0x0080, NULL, HFILL }},
3224 
3225 		{ &hf_sna_xid_3_nwnode,
3226 		  { "Sender is network node", "sna.xid.type3.nwnode",
3227 		    FT_BOOLEAN, 16, NULL, 0x0040, NULL, HFILL }},
3228 
3229 		{ &hf_sna_xid_3_cp,
3230 		  { "Control Point Services", "sna.xid.type3.cp",
3231 		    FT_BOOLEAN, 16, NULL, 0x0020, NULL, HFILL }},
3232 
3233 		{ &hf_sna_xid_3_cpcp,
3234 		  { "CP-CP session support", "sna.xid.type3.cpcp",
3235 		    FT_BOOLEAN, 16, NULL, 0x0010, NULL, HFILL }},
3236 
3237 		{ &hf_sna_xid_3_state,
3238 		  { "XID exchange state indicator", "sna.xid.type3.state",
3239 		    FT_UINT16, BASE_HEX, VALS(sna_xid_3_state_vals),
3240 		    0x000c, NULL, HFILL }},
3241 
3242 		{ &hf_sna_xid_3_nonact,
3243 		  { "Nonactivation Exchange", "sna.xid.type3.nonact",
3244 		    FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL }},
3245 
3246 		{ &hf_sna_xid_3_cpchange,
3247 		  { "CP name change support", "sna.xid.type3.cpchange",
3248 		    FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL }},
3249 
3250 		{ &hf_sna_xid_3_10,
3251 		  { "XID Type 3 Byte 10", "sna.xid.type3.10", FT_UINT8, BASE_HEX,
3252 		    NULL, 0x0, NULL, HFILL }},
3253 
3254 		{ &hf_sna_xid_3_asend_bind,
3255 		  { "Adaptive BIND pacing support as sender",
3256 		    "sna.xid.type3.asend_bind", FT_BOOLEAN, 8, NULL, 0x80,
3257 		    "Pacing support as sender", HFILL }},
3258 
3259 		{ &hf_sna_xid_3_arecv_bind,
3260 		  { "Adaptive BIND pacing support as receiver",
3261 		    "sna.xid.type3.asend_recv", FT_BOOLEAN, 8, NULL, 0x40,
3262 		    "Pacing support as receive", HFILL }},
3263 
3264 		{ &hf_sna_xid_3_quiesce,
3265 		  { "Quiesce TG Request",
3266 		    "sna.xid.type3.quiesce", FT_BOOLEAN, 8, NULL, 0x20,
3267 		    NULL, HFILL }},
3268 
3269 		{ &hf_sna_xid_3_pucap,
3270 		  { "PU Capabilities",
3271 		    "sna.xid.type3.pucap", FT_BOOLEAN, 8, NULL, 0x10,
3272 		    NULL, HFILL }},
3273 
3274 		{ &hf_sna_xid_3_pbn,
3275 		  { "Peripheral Border Node",
3276 		    "sna.xid.type3.pbn", FT_BOOLEAN, 8, NULL, 0x08,
3277 		    NULL, HFILL }},
3278 
3279 		{ &hf_sna_xid_3_pacing,
3280 		  { "Qualifier for adaptive BIND pacing support",
3281 		    "sna.xid.type3.pacing", FT_UINT8, BASE_HEX, NULL, 0x03,
3282 		    NULL, HFILL }},
3283 
3284 		{ &hf_sna_xid_3_11,
3285 		  { "XID Type 3 Byte 11", "sna.xid.type3.11", FT_UINT8, BASE_HEX,
3286 		    NULL, 0x0, NULL, HFILL }},
3287 
3288 		{ &hf_sna_xid_3_tgshare,
3289 		  { "TG Sharing Prohibited Indicator",
3290 		    "sna.xid.type3.tgshare", FT_BOOLEAN, 8, NULL, 0x40,
3291 		    NULL, HFILL }},
3292 
3293 		{ &hf_sna_xid_3_dedsvc,
3294 		  { "Dedicated SVC Indicator",
3295 		    "sna.xid.type3.dedsvc", FT_BOOLEAN, 8, NULL, 0x20,
3296 		    NULL, HFILL }},
3297 
3298 		{ &hf_sna_xid_3_12,
3299 		  { "XID Type 3 Byte 12", "sna.xid.type3.12", FT_UINT8, BASE_HEX,
3300 		    NULL, 0x0, NULL, HFILL }},
3301 
3302 		{ &hf_sna_xid_3_negcsup,
3303 		  { "Negotiation Complete Supported",
3304 		    "sna.xid.type3.negcsup", FT_BOOLEAN, 8, NULL, 0x80,
3305 		    NULL, HFILL }},
3306 
3307 		{ &hf_sna_xid_3_negcomp,
3308 		  { "Negotiation Complete",
3309 		    "sna.xid.type3.negcomp", FT_BOOLEAN, 8, NULL, 0x40,
3310 		    NULL, HFILL }},
3311 
3312 		{ &hf_sna_xid_3_15,
3313 		  { "XID Type 3 Byte 15", "sna.xid.type3.15", FT_UINT8, BASE_HEX,
3314 		    NULL, 0x0, NULL, HFILL }},
3315 
3316 		{ &hf_sna_xid_3_partg,
3317 		  { "Parallel TG Support",
3318 		    "sna.xid.type3.partg", FT_BOOLEAN, 8, NULL, 0x80,
3319 		    NULL, HFILL }},
3320 
3321 		{ &hf_sna_xid_3_dlur,
3322 		  { "Dependent LU Requester Indicator",
3323 		    "sna.xid.type3.dlur", FT_BOOLEAN, 8, NULL, 0x40,
3324 		    NULL, HFILL }},
3325 
3326 		{ &hf_sna_xid_3_dlus,
3327 		  { "DLUS Served LU Registration Indicator",
3328 		    "sna.xid.type3.dlus", FT_BOOLEAN, 8, NULL, 0x20,
3329 		    NULL, HFILL }},
3330 
3331 		{ &hf_sna_xid_3_exbn,
3332 		  { "Extended HPR Border Node",
3333 		    "sna.xid.type3.exbn", FT_BOOLEAN, 8, NULL, 0x10,
3334 		    NULL, HFILL }},
3335 
3336 		{ &hf_sna_xid_3_genodai,
3337 		  { "Generalized ODAI Usage Option",
3338 		    "sna.xid.type3.genodai", FT_BOOLEAN, 8, NULL, 0x08,
3339 		    NULL, HFILL }},
3340 
3341 		{ &hf_sna_xid_3_branch,
3342 		  { "Branch Indicator", "sna.xid.type3.branch",
3343 		    FT_UINT8, BASE_HEX, VALS(sna_xid_3_branch_vals),
3344 		    0x06, NULL, HFILL }},
3345 
3346 		{ &hf_sna_xid_3_brnn,
3347 		  { "Option Set 1123 Indicator",
3348 		    "sna.xid.type3.brnn", FT_BOOLEAN, 8, NULL, 0x01,
3349 		    NULL, HFILL }},
3350 
3351 		{ &hf_sna_xid_3_tg,
3352 		  { "XID TG", "sna.xid.type3.tg", FT_UINT8, BASE_HEX, NULL, 0x0,
3353 		    NULL, HFILL }},
3354 
3355 		{ &hf_sna_xid_3_dlc,
3356 		  { "XID DLC", "sna.xid.type3.dlc", FT_UINT8, BASE_HEX, NULL, 0x0,
3357 		    NULL, HFILL }},
3358 
3359 		{ &hf_sna_xid_3_dlen,
3360 		  { "DLC Dependent Section Length", "sna.xid.type3.dlen",
3361 		    FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3362 
3363 		{ &hf_sna_control_len,
3364 		  { "Control Vector Length", "sna.control.len",
3365 		    FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3366 
3367 		{ &hf_sna_control_key,
3368 		  { "Control Vector Key", "sna.control.key",
3369 		    FT_UINT8, BASE_HEX, VALS(sna_control_vals), 0x0, NULL,
3370 		    HFILL }},
3371 
3372 		{ &hf_sna_control_hprkey,
3373 		  { "Control Vector HPR Key", "sna.control.hprkey",
3374 		    FT_UINT8, BASE_HEX, VALS(sna_control_hpr_vals), 0x0, NULL,
3375 		    HFILL }},
3376 
3377 		{ &hf_sna_control_05_delay,
3378 		  { "Channel Delay", "sna.control.05.delay",
3379 		    FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3380 
3381 		{ &hf_sna_control_05_type,
3382 		  { "Network Address Type", "sna.control.05.type",
3383 		    FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3384 
3385 		{ &hf_sna_control_05_ptp,
3386 		  { "Point-to-point", "sna.control.05.ptp",
3387 		    FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
3388 
3389 		{ &hf_sna_control_0e_type,
3390 		  { "Type", "sna.control.0e.type",
3391 		    FT_UINT8, BASE_HEX, VALS(sna_control_0e_type_vals),
3392 		    0, NULL, HFILL }},
3393 
3394 		{ &hf_sna_control_0e_value,
3395 		  { "Value", "sna.control.0e.value",
3396 		    FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3397 
3398 		{ &hf_sna_padding,
3399 		  { "Padding", "sna.padding",
3400 		    FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
3401 
3402 		{ &hf_sna_reserved,
3403 		  { "Reserved", "sna.reserved",
3404 		    FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
3405 
3406 		{ &hf_sna_biu_segment_data,
3407 		  { "BIU segment data", "sna.biu_segment_data",
3408 		    FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
3409 
3410 	};
3411 	static gint *ett[] = {
3412 		&ett_sna,
3413 		&ett_sna_th,
3414 		&ett_sna_th_fid,
3415 		&ett_sna_nlp_nhdr,
3416 		&ett_sna_nlp_nhdr_0,
3417 		&ett_sna_nlp_nhdr_1,
3418 		&ett_sna_nlp_thdr,
3419 		&ett_sna_nlp_thdr_8,
3420 		&ett_sna_nlp_thdr_9,
3421 		&ett_sna_nlp_opti_un,
3422 		&ett_sna_nlp_opti_0d,
3423 		&ett_sna_nlp_opti_0d_4,
3424 		&ett_sna_nlp_opti_0e,
3425 		&ett_sna_nlp_opti_0e_stat,
3426 		&ett_sna_nlp_opti_0e_absp,
3427 		&ett_sna_nlp_opti_0f,
3428 		&ett_sna_nlp_opti_10,
3429 		&ett_sna_nlp_opti_12,
3430 		&ett_sna_nlp_opti_14,
3431 		&ett_sna_nlp_opti_14_si,
3432 		&ett_sna_nlp_opti_14_si_2,
3433 		&ett_sna_nlp_opti_14_rr,
3434 		&ett_sna_nlp_opti_14_rr_2,
3435 		&ett_sna_nlp_opti_22,
3436 		&ett_sna_nlp_opti_22_2,
3437 		&ett_sna_nlp_opti_22_3,
3438 		&ett_sna_rh,
3439 		&ett_sna_rh_0,
3440 		&ett_sna_rh_1,
3441 		&ett_sna_rh_2,
3442 		&ett_sna_gds,
3443 		&ett_sna_xid_0,
3444 		&ett_sna_xid_id,
3445 		&ett_sna_xid_3_8,
3446 		&ett_sna_xid_3_10,
3447 		&ett_sna_xid_3_11,
3448 		&ett_sna_xid_3_12,
3449 		&ett_sna_xid_3_15,
3450 		&ett_sna_control_un,
3451 		&ett_sna_control_05,
3452 		&ett_sna_control_05hpr,
3453 		&ett_sna_control_05hpr_type,
3454 		&ett_sna_control_0e,
3455 	};
3456 	module_t *sna_module;
3457 
3458 	proto_sna = proto_register_protocol("Systems Network Architecture",
3459 	    "SNA", "sna");
3460 	proto_register_field_array(proto_sna, hf, array_length(hf));
3461 	proto_register_subtree_array(ett, array_length(ett));
3462 	sna_handle = register_dissector("sna", dissect_sna, proto_sna);
3463 
3464 	proto_sna_xid = proto_register_protocol(
3465 	    "Systems Network Architecture XID", "SNA XID", "sna_xid");
3466 	sna_xid_handle = register_dissector("sna_xid", dissect_sna_xid, proto_sna_xid);
3467 
3468 	sna_address_type = address_type_dissector_register("AT_SNA", "SNA Address", sna_fid_to_str_buf, sna_address_str_len, NULL, NULL, NULL, NULL, NULL);
3469 
3470 	/* Register configuration options */
3471 	sna_module = prefs_register_protocol(proto_sna, NULL);
3472 	prefs_register_bool_preference(sna_module, "defragment",
3473 		"Reassemble fragmented BIUs",
3474 		"Whether fragmented BIUs should be reassembled",
3475 		&sna_defragment);
3476 
3477 	reassembly_table_register(&sna_reassembly_table,
3478 	    &addresses_reassembly_table_functions);
3479 }
3480 
3481 void
proto_reg_handoff_sna(void)3482 proto_reg_handoff_sna(void)
3483 {
3484 	dissector_add_uint("llc.dsap", SAP_SNA_PATHCTRL, sna_handle);
3485 	dissector_add_uint("llc.dsap", SAP_SNA1, sna_handle);
3486 	dissector_add_uint("llc.dsap", SAP_SNA2, sna_handle);
3487 	dissector_add_uint("llc.dsap", SAP_SNA3, sna_handle);
3488 	dissector_add_uint("llc.dsap", SAP_SNA4, sna_handle);
3489 	dissector_add_uint("llc.xid_dsap", SAP_SNA_PATHCTRL, sna_xid_handle);
3490 	dissector_add_uint("llc.xid_dsap", SAP_SNA1, sna_xid_handle);
3491 	dissector_add_uint("llc.xid_dsap", SAP_SNA2, sna_xid_handle);
3492 	dissector_add_uint("llc.xid_dsap", SAP_SNA3, sna_xid_handle);
3493 	/* RFC 2043 */
3494 	dissector_add_uint("ppp.protocol", PPP_SNA, sna_handle);
3495 }
3496 
3497 /*
3498  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
3499  *
3500  * Local variables:
3501  * c-basic-offset: 8
3502  * tab-width: 8
3503  * indent-tabs-mode: t
3504  * End:
3505  *
3506  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3507  * :indentSize=8:tabSize=8:noTabs=false:
3508  */
3509