704ec552007096ff443718a43596e36d3a751ed9
[obnox/wireshark/wip.git] / packet-sna.c
1 /* packet-sna.c
2  * Routines for SNA
3  * Gilbert Ramirez <gram@alumni.rice.edu>
4  *
5  * $Id: packet-sna.c,v 1.40 2002/05/29 08:55:28 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  * 
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
32 #endif
33
34 #include <glib.h>
35 #include <epan/packet.h>
36 #include "llcsaps.h"
37 #include "ppptypes.h"
38 #include <epan/sna-utils.h>
39
40 /*
41  * http://www.wanresources.com/snacell.html
42  * ftp://ftp.software.ibm.com/networking/pub/standards/aiw/formats/
43  *
44  */
45
46 static int proto_sna = -1;
47 static int hf_sna_th = -1;
48 static int hf_sna_th_0 = -1;
49 static int hf_sna_th_fid = -1;
50 static int hf_sna_th_mpf = -1;
51 static int hf_sna_th_odai = -1;
52 static int hf_sna_th_efi = -1;
53 static int hf_sna_th_daf = -1;
54 static int hf_sna_th_oaf = -1;
55 static int hf_sna_th_snf = -1;
56 static int hf_sna_th_dcf = -1;
57 static int hf_sna_th_lsid = -1;
58 static int hf_sna_th_tg_sweep = -1;
59 static int hf_sna_th_er_vr_supp_ind = -1;
60 static int hf_sna_th_vr_pac_cnt_ind = -1;
61 static int hf_sna_th_ntwk_prty = -1;
62 static int hf_sna_th_tgsf = -1;
63 static int hf_sna_th_mft = -1;
64 static int hf_sna_th_piubf = -1;
65 static int hf_sna_th_iern = -1;
66 static int hf_sna_th_nlpoi = -1;
67 static int hf_sna_th_nlp_cp = -1;
68 static int hf_sna_th_ern = -1;
69 static int hf_sna_th_vrn = -1;
70 static int hf_sna_th_tpf = -1;
71 static int hf_sna_th_vr_cwi = -1;
72 static int hf_sna_th_tg_nonfifo_ind = -1;
73 static int hf_sna_th_vr_sqti = -1;
74 static int hf_sna_th_tg_snf = -1;
75 static int hf_sna_th_vrprq = -1;
76 static int hf_sna_th_vrprs = -1;
77 static int hf_sna_th_vr_cwri = -1;
78 static int hf_sna_th_vr_rwi = -1;
79 static int hf_sna_th_vr_snf_send = -1;
80 static int hf_sna_th_dsaf = -1;
81 static int hf_sna_th_osaf = -1;
82 static int hf_sna_th_snai = -1;
83 static int hf_sna_th_def = -1;
84 static int hf_sna_th_oef = -1;
85 static int hf_sna_th_sa = -1;
86 static int hf_sna_th_cmd_fmt = -1;
87 static int hf_sna_th_cmd_type = -1;
88 static int hf_sna_th_cmd_sn = -1;
89
90 static int hf_sna_nlp_nhdr = -1;
91 static int hf_sna_nlp_nhdr_0 = -1;
92 static int hf_sna_nlp_sm = -1;
93 static int hf_sna_nlp_tpf = -1;
94 static int hf_sna_nlp_nhdr_1 = -1;
95 static int hf_sna_nlp_ft = -1;
96 static int hf_sna_nlp_tspi = -1;
97 static int hf_sna_nlp_slowdn1 = -1;
98 static int hf_sna_nlp_slowdn2 = -1;
99 static int hf_sna_nlp_fra = -1;
100 static int hf_sna_nlp_anr = -1;
101 static int hf_sna_nlp_frh = -1;
102 static int hf_sna_nlp_thdr = -1;
103 static int hf_sna_nlp_tcid = -1;
104 static int hf_sna_nlp_thdr_8 = -1;
105 static int hf_sna_nlp_setupi = -1;
106 static int hf_sna_nlp_somi = -1;
107 static int hf_sna_nlp_eomi = -1;
108 static int hf_sna_nlp_sri = -1;
109 static int hf_sna_nlp_rasapi = -1;
110 static int hf_sna_nlp_retryi = -1;
111 static int hf_sna_nlp_thdr_9 = -1;
112 static int hf_sna_nlp_lmi = -1;
113 static int hf_sna_nlp_cqfi = -1;
114 static int hf_sna_nlp_osi = -1;
115 static int hf_sna_nlp_offset = -1;
116 static int hf_sna_nlp_dlf = -1;
117 static int hf_sna_nlp_bsn = -1;
118
119 static int hf_sna_rh = -1;
120 static int hf_sna_rh_0 = -1;
121 static int hf_sna_rh_1 = -1;
122 static int hf_sna_rh_2 = -1;
123 static int hf_sna_rh_rri = -1;
124 static int hf_sna_rh_ru_category = -1;
125 static int hf_sna_rh_fi = -1;
126 static int hf_sna_rh_sdi = -1;
127 static int hf_sna_rh_bci = -1;
128 static int hf_sna_rh_eci = -1;
129 static int hf_sna_rh_dr1 = -1;
130 static int hf_sna_rh_lcci = -1;
131 static int hf_sna_rh_dr2 = -1;
132 static int hf_sna_rh_eri = -1;
133 static int hf_sna_rh_rti = -1;
134 static int hf_sna_rh_rlwi = -1;
135 static int hf_sna_rh_qri = -1;
136 static int hf_sna_rh_pi = -1;
137 static int hf_sna_rh_bbi = -1;
138 static int hf_sna_rh_ebi = -1;
139 static int hf_sna_rh_cdi = -1;
140 static int hf_sna_rh_csi = -1;
141 static int hf_sna_rh_edi = -1;
142 static int hf_sna_rh_pdi = -1;
143 static int hf_sna_rh_cebi = -1;
144 /*static int hf_sna_ru = -1;*/
145
146 static gint ett_sna = -1;
147 static gint ett_sna_th = -1;
148 static gint ett_sna_th_fid = -1;
149 static gint ett_sna_nlp_nhdr = -1;
150 static gint ett_sna_nlp_nhdr_0 = -1;
151 static gint ett_sna_nlp_nhdr_1 = -1;
152 static gint ett_sna_nlp_thdr = -1;
153 static gint ett_sna_nlp_thdr_8 = -1;
154 static gint ett_sna_nlp_thdr_9 = -1;
155 static gint ett_sna_rh = -1;
156 static gint ett_sna_rh_0 = -1;
157 static gint ett_sna_rh_1 = -1;
158 static gint ett_sna_rh_2 = -1;
159
160 static dissector_handle_t data_handle;
161
162 /* Format Identifier */
163 static const value_string sna_th_fid_vals[] = {
164         { 0x0,  "SNA device <--> Non-SNA Device" },
165         { 0x1,  "Subarea Nodes, without ER or VR" },
166         { 0x2,  "Subarea Node <--> PU2" },
167         { 0x3,  "Subarea Node or SNA host <--> Subarea Node" },
168         { 0x4,  "Subarea Nodes, supporting ER and VR" },
169         { 0x5,  "HPR RTP endpoint nodes" },
170         { 0xa,  "HPR NLP Frame Routing" },
171         { 0xb,  "HPR NLP Frame Routing" },
172         { 0xc,  "HPR NLP Automatic Network Routing" },
173         { 0xd,  "HPR NLP Automatic Network Routing" },
174         { 0xf,  "Adjaced Subarea Nodes, supporting ER and VR" },
175         { 0x0,  NULL }
176 };
177
178 /* Mapping Field */
179 static const value_string sna_th_mpf_vals[] = {
180         { 0, "Middle segment of a BIU" },
181         { 1, "Last segment of a BIU" },
182         { 2, "First segment of a BIU" },
183         { 3 , "Whole BIU" },
184         { 0,   NULL }
185 };
186
187 /* Expedited Flow Indicator */
188 static const value_string sna_th_efi_vals[] = {
189         { 0, "Normal Flow" },
190         { 1, "Expedited Flow" },
191         { 0x0,  NULL }
192 };
193
194 /* Request/Response Indicator */
195 static const value_string sna_rh_rri_vals[] = {
196         { 0, "Request" },
197         { 1, "Response" },
198         { 0x0,  NULL }
199 };
200
201 /* Request/Response Unit Category */
202 static const value_string sna_rh_ru_category_vals[] = {
203         { 0, "Function Management Data (FMD)" },
204         { 1, "Network Control (NC)" },
205         { 2, "Data Flow Control (DFC)" },
206         { 3, "Session Control (SC)" },
207         { 0x0,  NULL }
208 };
209
210 /* Format Indicator */
211 static const true_false_string sna_rh_fi_truth =
212         { "FM Header", "No FM Header" };
213
214 /* Sense Data Included */
215 static const true_false_string sna_rh_sdi_truth =
216         { "Included", "Not Included" };
217
218 /* Begin Chain Indicator */
219 static const true_false_string sna_rh_bci_truth =
220         { "First in Chain", "Not First in Chain" };
221
222 /* End Chain Indicator */
223 static const true_false_string sna_rh_eci_truth =
224         { "Last in Chain", "Not Last in Chain" };
225
226 /* Lengith-Checked Compression Indicator */
227 static const true_false_string sna_rh_lcci_truth =
228         { "Compressed", "Not Compressed" };
229
230 /* Response Type Indicator */
231 static const true_false_string sna_rh_rti_truth =
232         { "Negative", "Positive" };
233
234 /* Exception Response Indicator */
235 static const true_false_string sna_rh_eri_truth =
236         { "Exception", "Definite" };
237
238 /* Queued Response Indicator */
239 static const true_false_string sna_rh_qri_truth =
240         { "Enqueue response in TC queues", "Response bypasses TC queues" };
241
242 /* Code Selection Indicator */
243 static const value_string sna_rh_csi_vals[] = {
244         { 0, "EBCDIC" },
245         { 1, "ASCII" },
246         { 0x0,  NULL }
247 };
248
249 /* TG Sweep */
250 static const value_string sna_th_tg_sweep_vals[] = {
251         { 0, "This PIU may overtake any PU ahead of it." },
252         { 1, "This PIU does not ovetake any PIU ahead of it." },
253         { 0x0,  NULL }
254 };
255
256 /* ER_VR_SUPP_IND */
257 static const value_string sna_th_er_vr_supp_ind_vals[] = {
258         { 0, "Each node supports ER and VR protocols" },
259         { 1, "Includes at least one node that does not support ER and VR protocols"  },
260         { 0x0,  NULL }
261 };
262
263 /* VR_PAC_CNT_IND */
264 static const value_string sna_th_vr_pac_cnt_ind_vals[] = {
265         { 0, "Pacing count on the VR has not reached 0" },
266         { 1, "Pacing count on the VR has reached 0" },
267         { 0x0,  NULL }
268 };
269
270 /* NTWK_PRTY */
271 static const value_string sna_th_ntwk_prty_vals[] = {
272         { 0, "PIU flows at a lower priority" },
273         { 1, "PIU flows at network priority (highest transmission priority)" },
274         { 0x0,  NULL }
275 };
276
277 /* TGSF */
278 static const value_string sna_th_tgsf_vals[] = {
279         { 0, "Not segmented" },
280         { 1, "Last segment" },
281         { 2, "First segment" },
282         { 3, "Middle segment" },
283         { 0x0,  NULL }
284 };
285
286 /* PIUBF */
287 static const value_string sna_th_piubf_vals[] = {
288         { 0, "Single PIU frame" },
289         { 1, "Last PIU of a multiple PIU frame" },
290         { 2, "First PIU of a multiple PIU frame" },
291         { 3, "Middle PIU of a multiple PIU frame" },
292         { 0x0,  NULL }
293 };
294
295 /* NLPOI */
296 static const value_string sna_th_nlpoi_vals[] = {
297         { 0, "NLP starts within this FID4 TH" },
298         { 1, "NLP byte 0 starts after RH byte 0 following NLP C/P pad" },
299         { 0x0,  NULL }
300 };
301
302 /* TPF */
303 static const value_string sna_th_tpf_vals[] = {
304         { 0, "Low Priority" },
305         { 1, "Medium Priority" },
306         { 2, "High Priority" },
307         { 3, "Network Priority" },
308         { 0x0,  NULL }
309 };
310
311 /* VR_CWI */
312 static const value_string sna_th_vr_cwi_vals[] = {
313         { 0, "Increment window size" },
314         { 1, "Decrement window size" },
315         { 0x0,  NULL }
316 };
317
318 /* TG_NONFIFO_IND */
319 static const true_false_string sna_th_tg_nonfifo_ind_truth =
320         { "TG FIFO is not required", "TG FIFO is required" };
321
322 /* VR_SQTI */
323 static const value_string sna_th_vr_sqti_vals[] = {
324         { 0, "Non-sequenced, Non-supervisory" },
325         { 1, "Non-sequenced, Supervisory" },
326         { 2, "Singly-sequenced" },
327         { 0x0,  NULL }
328 };
329
330 /* VRPRQ */
331 static const true_false_string sna_th_vrprq_truth = {
332         "VR pacing request is sent asking for a VR pacing response",
333         "No VR pacing response is requested",
334 };
335
336 /* VRPRS */
337 static const true_false_string sna_th_vrprs_truth = {
338         "VR pacing response is sent in response to a VRPRQ bit set",
339         "No pacing response sent",
340 };
341
342 /* VR_CWRI */
343 static const value_string sna_th_vr_cwri_vals[] = {
344         { 0, "Increment window size by 1" },
345         { 1, "Decrement window size by 1" },
346         { 0x0,  NULL }
347 };
348
349 /* VR_RWI */
350 static const true_false_string sna_th_vr_rwi_truth = {
351         "Reset window size to the minimum specified in NC_ACTVR",
352         "Do not reset window size",
353 };
354
355 /* Switching Mode */
356 static const value_string sna_nlp_sm_vals[] = {
357         { 5, "Function routing" },
358         { 6, "Automatic network routing" },
359         { 0x0,  NULL }
360 };
361
362 static const true_false_string sna_nlp_tspi_truth =
363         { "Time sensitive", "Not time sensitive" };
364
365 static const true_false_string sna_nlp_slowdn1_truth =
366         { "Minor congestion", "No minor congestion" };
367
368 static const true_false_string sna_nlp_slowdn2_truth =
369         { "Major congestion", "No major congestion" };
370
371 /* Function Type */
372 static const value_string sna_nlp_ft_vals[] = {
373         { 0x10, "LDLC" },
374         { 0x0,  NULL }
375 };
376
377 static const value_string sna_nlp_frh_vals[] = {
378         { 0x03, "XID complete request" },
379         { 0x04, "XID complete response" },
380         { 0x0,  NULL }
381 };
382
383 static const true_false_string sna_nlp_setupi_truth =
384         { "Connection setup segment present", "Connection setup segment not present" };
385
386 static const true_false_string sna_nlp_somi_truth =
387         { "Start of message", "Not start of message" };
388
389 static const true_false_string sna_nlp_eomi_truth =
390         { "End of message", "Not end of message" };
391
392 static const true_false_string sna_nlp_sri_truth =
393         { "Status requested", "No status requested" };
394
395 static const true_false_string sna_nlp_rasapi_truth =
396         { "Reply as soon as possible", "No need to reply as soon as possible" };
397
398 static const true_false_string sna_nlp_retryi_truth =
399         { "Undefined", "Sender will retransmit" };
400
401 static const true_false_string sna_nlp_lmi_truth =
402         { "Last message", "Not last message" };
403
404 static const true_false_string sna_nlp_cqfi_truth =
405         { "CQFI included", "CQFI not included" };
406
407 static const true_false_string sna_nlp_osi_truth =
408         { "Optional segments present", "No optional segments present" };
409
410
411 static int  dissect_fid0_1 (tvbuff_t*, packet_info*, proto_tree*);
412 static int  dissect_fid2 (tvbuff_t*, packet_info*, proto_tree*);
413 static int  dissect_fid3 (tvbuff_t*, proto_tree*);
414 static int  dissect_fid4 (tvbuff_t*, packet_info*, proto_tree*);
415 static int  dissect_fid5 (tvbuff_t*, proto_tree*);
416 static int  dissect_fidf (tvbuff_t*, proto_tree*);
417 static void dissect_fid (tvbuff_t*, packet_info*, proto_tree*, proto_tree*);
418 static void dissect_nlp (tvbuff_t*, packet_info*, proto_tree*, proto_tree*);
419 static void dissect_rh (tvbuff_t*, int, proto_tree*);
420
421 static void
422 dissect_sna(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
423 {
424         guint8          fid;
425         proto_tree      *sna_tree = NULL;
426         proto_item      *sna_ti = NULL;
427
428         if (check_col(pinfo->cinfo, COL_PROTOCOL))
429                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SNA");
430         if (check_col(pinfo->cinfo, COL_INFO))
431                 col_clear(pinfo->cinfo, COL_INFO);
432
433         /* SNA data should be printed in EBCDIC, not ASCII */
434         pinfo->fd->flags.encoding = CHAR_EBCDIC;
435
436         if (tree) {
437
438                 /* Don't bother setting length. We'll set it later after we find
439                  * the lengths of TH/RH/RU */
440                 sna_ti = proto_tree_add_item(tree, proto_sna, tvb, 0, -1, FALSE);
441                 sna_tree = proto_item_add_subtree(sna_ti, ett_sna);
442         }
443
444         /* Transmission Header Format Identifier */
445         fid = hi_nibble(tvb_get_guint8(tvb, 0));
446         switch(fid) {
447                 case 0xa:       /* HPR Network Layer Packet */
448                 case 0xb:
449                 case 0xc:
450                 case 0xd:
451                         dissect_nlp(tvb, pinfo, sna_tree, tree);
452                         break;
453                 default:
454                         dissect_fid(tvb, pinfo, sna_tree, tree);
455         }
456 }
457
458 static void
459 dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
460     proto_tree *parent_tree)
461 {
462
463         proto_tree      *th_tree = NULL, *rh_tree = NULL;
464         proto_item      *th_ti = NULL, *rh_ti = NULL;
465         guint8          th_fid;
466         int             sna_header_len = 0, th_header_len = 0;
467         int             offset;
468
469         /* Transmission Header Format Identifier */
470         th_fid = hi_nibble(tvb_get_guint8(tvb, 0));
471
472         /* Summary information */
473         if (check_col(pinfo->cinfo, COL_INFO))
474                 col_add_str(pinfo->cinfo, COL_INFO,
475                                 val_to_str(th_fid, sna_th_fid_vals, "Unknown FID: %01x"));
476
477         if (tree) {
478
479                 /* --- TH --- */
480                 /* Don't bother setting length. We'll set it later after we find
481                  * the length of TH */
482                 th_ti = proto_tree_add_item(tree, hf_sna_th, tvb,  0, -1, FALSE);
483                 th_tree = proto_item_add_subtree(th_ti, ett_sna_th);
484         }
485
486         /* Get size of TH */
487         switch(th_fid) {
488                 case 0x0:
489                 case 0x1:
490                         th_header_len = dissect_fid0_1(tvb, pinfo, th_tree);
491                         break;
492                 case 0x2:
493                         th_header_len = dissect_fid2(tvb, pinfo, th_tree);
494                         break;
495                 case 0x3:
496                         th_header_len = dissect_fid3(tvb, th_tree);
497                         break;
498                 case 0x4:
499                         th_header_len = dissect_fid4(tvb, pinfo, th_tree);
500                         break;
501                 case 0x5:
502                         th_header_len = dissect_fid5(tvb, th_tree);
503                         break;
504                 case 0xf:
505                         th_header_len = dissect_fidf(tvb, th_tree);
506                         break;
507                 default:
508                         call_dissector(data_handle,
509                             tvb_new_subset(tvb, 1, -1, -1), pinfo, parent_tree);
510                         return;
511         }
512
513         sna_header_len += th_header_len;
514         offset = th_header_len;
515
516         if (tree) {
517                 proto_item_set_len(th_ti, th_header_len);
518
519                 /* --- RH --- */
520                 rh_ti = proto_tree_add_item(tree, hf_sna_rh, tvb, offset, 3, FALSE);
521                 rh_tree = proto_item_add_subtree(rh_ti, ett_sna_rh);
522                 dissect_rh(tvb, offset, rh_tree);
523
524                 sna_header_len += 3;
525                 offset += 3;
526         }
527         else {
528                 sna_header_len += 3;
529                 offset += 3;
530         }
531
532         if (tvb_offset_exists(tvb, offset+1)) {
533                 call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1),
534                     pinfo, parent_tree);
535         }
536 }
537
538 #define SNA_FID01_ADDR_LEN      2
539
540 /* FID Types 0 and 1 */
541 static int
542 dissect_fid0_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
543 {
544         proto_tree      *bf_tree;
545         proto_item      *bf_item;
546         guint8          th_0;
547         const guint8    *ptr;
548
549         const int bytes_in_header = 10;
550
551         if (tree) {
552                 /* Byte 0 */
553                 th_0 = tvb_get_guint8(tvb, 0);
554                 bf_item = proto_tree_add_uint(tree, hf_sna_th_0, tvb, 0, 1, th_0);
555                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
556
557                 proto_tree_add_uint(bf_tree, hf_sna_th_fid, tvb, 0, 1, th_0);
558                 proto_tree_add_uint(bf_tree, hf_sna_th_mpf, tvb, 0, 1, th_0);
559                 proto_tree_add_uint(bf_tree, hf_sna_th_efi, tvb, 0, 1, th_0);
560
561                 /* Byte 1 */
562                 proto_tree_add_text(tree, tvb, 1, 1, "Reserved");
563
564                 /* Bytes 2-3 */
565                 proto_tree_add_item(tree, hf_sna_th_daf, tvb, 2, 2, FALSE);
566         }
567
568         /* Set DST addr */
569         ptr = tvb_get_ptr(tvb, 2, SNA_FID01_ADDR_LEN);
570         SET_ADDRESS(&pinfo->net_dst, AT_SNA, SNA_FID01_ADDR_LEN, ptr);
571         SET_ADDRESS(&pinfo->dst, AT_SNA, SNA_FID01_ADDR_LEN, ptr);
572
573         if (tree) {
574                 proto_tree_add_item(tree, hf_sna_th_oaf, tvb, 4, 2, FALSE);
575         }
576
577         /* Set SRC addr */
578         ptr = tvb_get_ptr(tvb, 4, SNA_FID01_ADDR_LEN);
579         SET_ADDRESS(&pinfo->net_src, AT_SNA, SNA_FID01_ADDR_LEN, ptr);
580         SET_ADDRESS(&pinfo->src, AT_SNA, SNA_FID01_ADDR_LEN, ptr);
581
582         /* If we're not filling a proto_tree, return now */
583         if (tree) {
584                 return bytes_in_header;
585         }
586
587         proto_tree_add_item(tree, hf_sna_th_snf, tvb, 6, 2, FALSE);
588         proto_tree_add_item(tree, hf_sna_th_dcf, tvb, 8, 2, FALSE);
589
590         return bytes_in_header;
591 }
592
593 #define SNA_FID2_ADDR_LEN       1
594
595 /* FID Type 2 */
596 static int
597 dissect_fid2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
598 {
599         proto_tree      *bf_tree;
600         proto_item      *bf_item;
601         guint8          th_0=0, daf=0, oaf=0;
602         const guint8    *ptr;
603
604         const int bytes_in_header = 6;
605
606         if (tree) {
607                 th_0 = tvb_get_guint8(tvb, 0);
608                 daf = tvb_get_guint8(tvb, 2);
609                 oaf = tvb_get_guint8(tvb, 3);
610
611                 /* Byte 0 */
612                 bf_item = proto_tree_add_uint(tree, hf_sna_th_0, tvb, 0, 1, th_0);
613                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
614
615                 proto_tree_add_uint(bf_tree, hf_sna_th_fid, tvb, 0, 1, th_0);
616                 proto_tree_add_uint(bf_tree, hf_sna_th_mpf, tvb, 0, 1, th_0);
617                 proto_tree_add_uint(bf_tree, hf_sna_th_odai,tvb, 0, 1, th_0);
618                 proto_tree_add_uint(bf_tree, hf_sna_th_efi, tvb, 0, 1, th_0);
619
620                 /* Byte 1 */
621                 proto_tree_add_text(tree, tvb, 1, 1, "Reserved");
622
623                 /* Byte 2 */
624                 proto_tree_add_uint_format(tree, hf_sna_th_daf, tvb, 2, 1, daf,
625                                 "Destination Address Field: 0x%02x", daf);
626         }
627
628         /* Set DST addr */
629         ptr = tvb_get_ptr(tvb, 2, SNA_FID2_ADDR_LEN);
630         SET_ADDRESS(&pinfo->net_dst, AT_SNA, SNA_FID2_ADDR_LEN, ptr);
631         SET_ADDRESS(&pinfo->dst, AT_SNA, SNA_FID2_ADDR_LEN, ptr);
632
633         if (tree) {
634                 /* Byte 3 */
635                 proto_tree_add_uint_format(tree, hf_sna_th_oaf, tvb, 3, 1, oaf,
636                                 "Origin Address Field: 0x%02x", oaf);
637         }
638
639         /* Set SRC addr */
640         ptr = tvb_get_ptr(tvb, 3, SNA_FID2_ADDR_LEN);
641         SET_ADDRESS(&pinfo->net_src, AT_SNA, SNA_FID2_ADDR_LEN, ptr);
642         SET_ADDRESS(&pinfo->src, AT_SNA, SNA_FID2_ADDR_LEN, ptr);
643
644         if (tree) {
645                 proto_tree_add_item(tree, hf_sna_th_snf, tvb, 4, 2, FALSE);
646         }
647
648         return bytes_in_header;
649 }
650
651 /* FID Type 3 */
652 static int
653 dissect_fid3(tvbuff_t *tvb, proto_tree *tree)
654 {
655         proto_tree      *bf_tree;
656         proto_item      *bf_item;
657         guint8          th_0;
658
659         const int bytes_in_header = 2;
660
661         /* If we're not filling a proto_tree, return now */
662         if (!tree) {
663                 return bytes_in_header;
664         }
665
666         th_0 = tvb_get_guint8(tvb, 0);
667
668         /* Create the bitfield tree */
669         bf_item = proto_tree_add_uint(tree, hf_sna_th_0, tvb, 0, 1, th_0);
670         bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
671
672         proto_tree_add_uint(bf_tree, hf_sna_th_fid, tvb, 0, 1, th_0);
673         proto_tree_add_uint(bf_tree, hf_sna_th_mpf, tvb, 0, 1, th_0);
674         proto_tree_add_uint(bf_tree, hf_sna_th_efi, tvb, 0, 1, th_0);
675
676         proto_tree_add_item(tree, hf_sna_th_lsid, tvb, 1, 1, FALSE);
677
678         return bytes_in_header;
679 }
680
681
682 static int
683 dissect_fid4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
684 {
685         proto_tree      *bf_tree;
686         proto_item      *bf_item;
687         int             offset = 0;
688         guint8          th_byte, mft;
689         guint16         th_word;
690         guint16         def, oef;
691         guint32         dsaf, osaf;
692         static struct sna_fid_type_4_addr src, dst;
693
694         const int bytes_in_header = 26;
695
696         /* If we're not filling a proto_tree, return now */
697         if (!tree) {
698                 return bytes_in_header;
699         }
700
701         if (tree) {
702                 th_byte = tvb_get_guint8(tvb, offset);
703
704                 /* Create the bitfield tree */
705                 bf_item = proto_tree_add_uint(tree, hf_sna_th_0, tvb, offset, 1, th_byte);
706                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
707
708                 /* Byte 0 */
709                 proto_tree_add_uint(bf_tree, hf_sna_th_fid, tvb, offset, 1, th_byte);
710                 proto_tree_add_uint(bf_tree, hf_sna_th_tg_sweep, tvb, offset, 1, th_byte);
711                 proto_tree_add_uint(bf_tree, hf_sna_th_er_vr_supp_ind, tvb, offset, 1, th_byte);
712                 proto_tree_add_uint(bf_tree, hf_sna_th_vr_pac_cnt_ind, tvb, offset, 1, th_byte);
713                 proto_tree_add_uint(bf_tree, hf_sna_th_ntwk_prty, tvb, offset, 1, th_byte);
714
715                 offset += 1;
716                 th_byte = tvb_get_guint8(tvb, offset);
717
718                 /* Create the bitfield tree */
719                 bf_item = proto_tree_add_text(tree, tvb, offset, 1, "Transmision Header Byte 1");
720                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
721
722                 /* Byte 1 */
723                 proto_tree_add_uint(bf_tree, hf_sna_th_tgsf, tvb, offset, 1, th_byte);
724                 proto_tree_add_boolean(bf_tree, hf_sna_th_mft, tvb, offset, 1, th_byte);
725                 proto_tree_add_uint(bf_tree, hf_sna_th_piubf, tvb, offset, 1, th_byte);
726
727                 mft = th_byte & 0x04;
728                 offset += 1;
729                 th_byte = tvb_get_guint8(tvb, offset);
730
731                 /* Create the bitfield tree */
732                 bf_item = proto_tree_add_text(tree, tvb, offset, 1, "Transmision Header Byte 2");
733                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
734
735                 /* Byte 2 */
736                 if (mft) {
737                         proto_tree_add_uint(bf_tree, hf_sna_th_nlpoi, tvb, offset, 1, th_byte);
738                         proto_tree_add_uint(bf_tree, hf_sna_th_nlp_cp, tvb, offset, 1, th_byte);
739                 }
740                 else {
741                         proto_tree_add_uint(bf_tree, hf_sna_th_iern, tvb, offset, 1, th_byte);
742                 }
743                 proto_tree_add_uint(bf_tree, hf_sna_th_ern, tvb, offset, 1, th_byte);
744
745                 offset += 1;
746                 th_byte = tvb_get_guint8(tvb, offset);
747
748                 /* Create the bitfield tree */
749                 bf_item = proto_tree_add_text(tree, tvb, offset, 1, "Transmision Header Byte 3");
750                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
751
752                 /* Byte 3 */
753                 proto_tree_add_uint(bf_tree, hf_sna_th_vrn, tvb, offset, 1, th_byte);
754                 proto_tree_add_uint(bf_tree, hf_sna_th_tpf, tvb, offset, 1, th_byte);
755
756                 offset += 1;
757                 th_word = tvb_get_ntohs(tvb, offset);
758
759                 /* Create the bitfield tree */
760                 bf_item = proto_tree_add_text(tree, tvb, offset, 2, "Transmision Header Bytes 4-5");
761                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
762
763                 /* Bytes 4-5 */
764                 proto_tree_add_uint(bf_tree, hf_sna_th_vr_cwi, tvb, offset, 2, th_word);
765                 proto_tree_add_boolean(bf_tree, hf_sna_th_tg_nonfifo_ind, tvb, offset, 2, th_word);
766                 proto_tree_add_uint(bf_tree, hf_sna_th_vr_sqti, tvb, offset, 2, th_word);
767
768                 /* I'm not sure about byte-order on this one... */
769                 proto_tree_add_uint(bf_tree, hf_sna_th_tg_snf, tvb, offset, 2, th_word);
770
771                 offset += 2;
772                 th_word = tvb_get_ntohs(tvb, offset);
773
774                 /* Create the bitfield tree */
775                 bf_item = proto_tree_add_text(tree, tvb, offset, 2, "Transmision Header Bytes 6-7");
776                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
777
778                 /* Bytes 6-7 */
779                 proto_tree_add_boolean(bf_tree, hf_sna_th_vrprq, tvb, offset, 2, th_word);
780                 proto_tree_add_boolean(bf_tree, hf_sna_th_vrprs, tvb, offset, 2, th_word);
781                 proto_tree_add_uint(bf_tree, hf_sna_th_vr_cwri, tvb, offset, 2, th_word);
782                 proto_tree_add_boolean(bf_tree, hf_sna_th_vr_rwi, tvb, offset, 2, th_word);
783
784                 /* I'm not sure about byte-order on this one... */
785                 proto_tree_add_uint(bf_tree, hf_sna_th_vr_snf_send, tvb, offset, 2, th_word);
786
787                 offset += 2;
788         }
789
790         dsaf = tvb_get_ntohl(tvb, 8);
791         if (tree) {
792                 /* Bytes 8-11 */
793                 proto_tree_add_uint(tree, hf_sna_th_dsaf, tvb, offset, 4, dsaf);
794
795                 offset += 4;
796         }
797
798         osaf = tvb_get_ntohl(tvb, 12);
799         if (tree) {
800                 /* Bytes 12-15 */
801                 proto_tree_add_uint(tree, hf_sna_th_osaf, tvb, offset, 4, osaf);
802
803                 offset += 4;
804                 th_byte = tvb_get_guint8(tvb, offset);
805
806                 /* Create the bitfield tree */
807                 bf_item = proto_tree_add_text(tree, tvb, offset, 2, "Transmision Header Byte 16");
808                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
809
810                 /* Byte 16 */
811                 proto_tree_add_boolean(tree, hf_sna_th_snai, tvb, offset, 1, th_byte);
812
813                 /* We luck out here because in their infinite wisdom the SNA
814                  * architects placed the MPF and EFI fields in the same bitfield
815                  * locations, even though for FID4 they're not in byte 0.
816                  * Thank you IBM! */
817                 proto_tree_add_uint(tree, hf_sna_th_mpf, tvb, offset, 1, th_byte);
818                 proto_tree_add_uint(tree, hf_sna_th_efi, tvb, offset, 1, th_byte);
819
820                 offset += 2; /* 1 for byte 16, 1 for byte 17 which is reserved */
821         }
822
823
824         def = tvb_get_ntohs(tvb, 18);
825         if (tree) {
826                 /* Bytes 18-25 */
827                 proto_tree_add_uint(tree, hf_sna_th_def, tvb, offset, 2, def);
828         }
829
830         /* Addresses in FID 4 are discontiguous, sigh */
831         dst.saf = dsaf;
832         dst.ef = def;
833         SET_ADDRESS(&pinfo->net_dst, AT_SNA, SNA_FID_TYPE_4_ADDR_LEN, (guint8* )&dst);
834         SET_ADDRESS(&pinfo->dst, AT_SNA, SNA_FID_TYPE_4_ADDR_LEN, (guint8 *)&dst);
835
836
837         oef = tvb_get_ntohs(tvb, 20);
838         if (tree) {
839                 proto_tree_add_uint(tree, hf_sna_th_oef, tvb, offset+2, 2, oef);
840         }
841
842         /* Addresses in FID 4 are discontiguous, sigh */
843         src.saf = osaf;
844         src.ef = oef;
845         SET_ADDRESS(&pinfo->net_src, AT_SNA, SNA_FID_TYPE_4_ADDR_LEN, (guint8 *)&src);
846         SET_ADDRESS(&pinfo->src, AT_SNA, SNA_FID_TYPE_4_ADDR_LEN, (guint8 *)&src);
847
848         if (tree) {
849                 proto_tree_add_item(tree, hf_sna_th_snf, tvb, offset+4, 2, FALSE);
850                 proto_tree_add_item(tree, hf_sna_th_dcf, tvb, offset+6, 2, FALSE);
851         }
852
853         return bytes_in_header;
854 }
855
856 /* FID Type 5 */
857 static int
858 dissect_fid5(tvbuff_t *tvb, proto_tree *tree)
859 {
860         proto_tree      *bf_tree;
861         proto_item      *bf_item;
862         guint8          th_0;
863
864         const int bytes_in_header = 12;
865
866         /* If we're not filling a proto_tree, return now */
867         if (!tree) {
868                 return bytes_in_header;
869         }
870
871         th_0 = tvb_get_guint8(tvb, 0);
872
873         /* Create the bitfield tree */
874         bf_item = proto_tree_add_uint(tree, hf_sna_th_0, tvb, 0, 1, th_0);
875         bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
876
877         proto_tree_add_uint(bf_tree, hf_sna_th_fid, tvb, 0, 1, th_0);
878         proto_tree_add_uint(bf_tree, hf_sna_th_mpf, tvb, 0, 1, th_0);
879         proto_tree_add_uint(bf_tree, hf_sna_th_efi, tvb, 0, 1, th_0);
880
881         proto_tree_add_text(tree, tvb, 1, 1, "Reserved");
882         proto_tree_add_item(tree, hf_sna_th_snf, tvb, 2, 2, FALSE);
883
884         proto_tree_add_item(tree, hf_sna_th_sa, tvb, 4, 8, FALSE);
885
886         return bytes_in_header;
887
888 }
889
890 /* FID Type f */
891 static int
892 dissect_fidf(tvbuff_t *tvb, proto_tree *tree)
893 {
894         proto_tree      *bf_tree;
895         proto_item      *bf_item;
896         guint8          th_0;
897         
898         const int bytes_in_header = 26;
899
900         /* If we're not filling a proto_tree, return now */
901         if (!tree) {
902                 return bytes_in_header;
903         }
904
905         th_0 = tvb_get_guint8(tvb, 0);
906
907         /* Create the bitfield tree */
908         bf_item = proto_tree_add_uint(tree, hf_sna_th_0, tvb, 0, 1, th_0);
909         bf_tree = proto_item_add_subtree(bf_item, ett_sna_th_fid);
910
911         proto_tree_add_uint(bf_tree, hf_sna_th_fid, tvb, 0, 1, th_0);
912         proto_tree_add_text(tree, tvb, 1, 1, "Reserved");
913
914         proto_tree_add_item(tree, hf_sna_th_cmd_fmt, tvb,  2, 1, FALSE);
915         proto_tree_add_item(tree, hf_sna_th_cmd_type, tvb, 3, 1, FALSE);
916         proto_tree_add_item(tree, hf_sna_th_cmd_sn, tvb,   4, 2, FALSE);
917
918         /* Yup, bytes 6-23 are reserved! */
919         proto_tree_add_text(tree, tvb, 6, 18, "Reserved");
920
921         proto_tree_add_item(tree, hf_sna_th_dcf, tvb, 24, 2, FALSE);
922
923         return bytes_in_header;
924 }
925
926 /* HPR Network Layer Packet */
927 static void
928 dissect_nlp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
929     proto_tree *parent_tree)
930 {
931         proto_tree      *nlp_tree, *bf_tree;
932         proto_item      *nlp_item, *bf_item, *h_item;
933         guint8          nhdr_0, nhdr_1, nhdr_x, thdr_8, thdr_9;
934         guint32         thdr_len, thdr_dlf, thdr_bsn;
935
936         int index = 0, counter = 0;
937
938         nlp_tree = NULL;
939         nlp_item = NULL;
940
941         nhdr_0 = tvb_get_guint8(tvb, index);
942         nhdr_1 = tvb_get_guint8(tvb, index+1);
943
944         if (check_col(pinfo->cinfo, COL_INFO))
945                 col_add_str(pinfo->cinfo, COL_INFO, "HPR NLP Packet");
946
947         if (tree) {
948                 /* Don't bother setting length. We'll set it later after we find
949                  * the lengths of NHDR */
950                 nlp_item = proto_tree_add_item(tree, hf_sna_nlp_nhdr, tvb, index, -1, FALSE);
951                 nlp_tree = proto_item_add_subtree(nlp_item, ett_sna_nlp_nhdr);
952
953                 bf_item = proto_tree_add_uint(nlp_tree, hf_sna_nlp_nhdr_0, tvb, index, 1, nhdr_0);
954                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_nlp_nhdr_0);
955
956                 proto_tree_add_uint(bf_tree, hf_sna_nlp_sm, tvb, index, 1, nhdr_0);
957                 proto_tree_add_uint(bf_tree, hf_sna_nlp_tpf, tvb, index, 1, nhdr_0);
958
959                 bf_item = proto_tree_add_uint(nlp_tree, hf_sna_nlp_nhdr_1, tvb, index+1, 1, nhdr_1);
960                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_nlp_nhdr_1);
961
962                 proto_tree_add_uint(bf_tree, hf_sna_nlp_ft, tvb, index+1, 1, nhdr_1);
963                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_tspi, tvb, index+1, 1, nhdr_1);
964                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_slowdn1, tvb, index+1, 1, nhdr_1);
965                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_slowdn2, tvb, index+1, 1, nhdr_1);
966         }
967         /* ANR or FR lists */
968
969         index += 2;
970         counter = 0;
971
972         if ((nhdr_0 & 0xe0) == 0xa0) {
973                 do {
974                         nhdr_x = tvb_get_guint8(tvb, index + counter);
975                         counter ++;
976                 } while (nhdr_x != 0xff);
977                 if (tree)
978                         h_item = proto_tree_add_item(nlp_tree, hf_sna_nlp_fra, tvb, index, counter, FALSE);
979                 index += counter;
980
981                 index++; /* 1 Byte Reserved */
982
983                 if (tree) {
984                         proto_item_set_len(nlp_item, index);
985                 }
986                 if ((nhdr_1 & 0x80) == 0x10) {
987                         nhdr_x = tvb_get_guint8(tvb, index);
988                         if (tree) {
989                                 proto_tree_add_uint(tree, hf_sna_nlp_frh, tvb, index, 1, nhdr_x);
990                         }
991                         index ++;
992
993                         if (tvb_offset_exists(tvb, index+1)) {
994                                 call_dissector(data_handle,
995                                         tvb_new_subset(tvb, index, -1, -1),
996                                         pinfo, parent_tree);
997                         }
998                         return;
999                 }
1000         }
1001         if ((nhdr_0 & 0xe0) == 0xc0) {
1002                 do {
1003                         nhdr_x = tvb_get_guint8(tvb, index + counter);
1004                         counter ++;
1005                 } while (nhdr_x != 0xff);
1006                 if (tree)
1007                         h_item = proto_tree_add_item(nlp_tree, hf_sna_nlp_anr, tvb, index, counter, FALSE);
1008                 index += counter;
1009
1010                 index++; /* 1 Byte Reserved */
1011
1012                 if (tree) {
1013                         proto_item_set_len(nlp_item, index);
1014                 }
1015
1016         }
1017
1018         thdr_8 = tvb_get_guint8(tvb, index+8);
1019         thdr_9 = tvb_get_guint8(tvb, index+9);
1020         thdr_len = tvb_get_ntohs(tvb, index+10);
1021         thdr_dlf = tvb_get_ntohl(tvb, index+12);
1022         thdr_bsn = tvb_get_ntohl(tvb, index+16);
1023
1024         if (tree) {
1025                 /* Don't bother setting length. We'll set it later after we find
1026                  * the lengths of NHDR */
1027                 nlp_item = proto_tree_add_item(tree, hf_sna_nlp_thdr, tvb, index, -1, FALSE);
1028                 nlp_tree = proto_item_add_subtree(nlp_item, ett_sna_nlp_thdr);
1029
1030                 bf_item = proto_tree_add_item(nlp_tree, hf_sna_nlp_tcid, tvb, index, 8, FALSE);
1031
1032                 bf_item = proto_tree_add_uint(nlp_tree, hf_sna_nlp_thdr_8, tvb, index+8, 1, thdr_8);
1033                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_nlp_thdr_8);
1034
1035                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_setupi, tvb, index+8, 1, thdr_8);
1036                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_somi, tvb, index+8, 1, thdr_8);
1037                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_eomi, tvb, index+8, 1, thdr_8);
1038                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_sri, tvb, index+8, 1, thdr_8);
1039                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_rasapi, tvb, index+8, 1, thdr_8);
1040                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_retryi, tvb, index+8, 1, thdr_8);
1041
1042                 bf_item = proto_tree_add_uint(nlp_tree, hf_sna_nlp_thdr_9, tvb, index+9, 1, thdr_9);
1043                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_nlp_thdr_9);
1044
1045                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_lmi, tvb, index+9, 1, thdr_9);
1046                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_cqfi, tvb, index+9, 1, thdr_9);
1047                 proto_tree_add_boolean(bf_tree, hf_sna_nlp_osi, tvb, index+9, 1, thdr_9);
1048
1049                 proto_tree_add_uint(nlp_tree, hf_sna_nlp_offset, tvb, index+10, 2, thdr_len);
1050                 proto_tree_add_uint(nlp_tree, hf_sna_nlp_dlf, tvb, index+12, 4, thdr_dlf);
1051                 proto_tree_add_uint(nlp_tree, hf_sna_nlp_bsn, tvb, index+16, 4, thdr_bsn);
1052
1053                 proto_item_set_len(nlp_item, thdr_len);
1054         }
1055         index += (thdr_len << 2);
1056         if (((thdr_8 & 0x20) == 0) && thdr_dlf) {
1057                 if (check_col(pinfo->cinfo, COL_INFO))
1058                         col_add_str(pinfo->cinfo, COL_INFO, "HPR Fragment");
1059                 if (tvb_offset_exists(tvb, index+1)) {
1060                         call_dissector(data_handle,
1061                                 tvb_new_subset(tvb, index, -1, -1), pinfo,
1062                                 parent_tree);
1063                 }
1064                 return;
1065         }
1066         if (tvb_offset_exists(tvb, index+1)) {
1067                 dissect_fid(tvb_new_subset(tvb, index, -1, -1), pinfo, tree,
1068                         parent_tree);
1069         }
1070 }
1071
1072 /* RH */
1073 static void
1074 dissect_rh(tvbuff_t *tvb, int offset, proto_tree *tree)
1075 {
1076         proto_tree      *bf_tree;
1077         proto_item      *bf_item;
1078         gboolean        is_response;
1079         guint8          rh_0, rh_1, rh_2;
1080
1081
1082         /* Create the bitfield tree for byte 0*/
1083         rh_0 = tvb_get_guint8(tvb, offset);
1084         is_response = (rh_0 & 0x80);
1085
1086         bf_item = proto_tree_add_uint(tree, hf_sna_rh_0, tvb, offset, 1, rh_0);
1087         bf_tree = proto_item_add_subtree(bf_item, ett_sna_rh_0);
1088
1089         proto_tree_add_uint(bf_tree, hf_sna_rh_rri, tvb, offset, 1, rh_0);
1090         proto_tree_add_uint(bf_tree, hf_sna_rh_ru_category, tvb, offset, 1, rh_0);
1091         proto_tree_add_boolean(bf_tree, hf_sna_rh_fi, tvb, offset, 1, rh_0);
1092         proto_tree_add_boolean(bf_tree, hf_sna_rh_sdi, tvb, offset, 1, rh_0);
1093         proto_tree_add_boolean(bf_tree, hf_sna_rh_bci, tvb, offset, 1, rh_0);
1094         proto_tree_add_boolean(bf_tree, hf_sna_rh_eci, tvb, offset, 1, rh_0);
1095
1096         offset += 1;
1097         rh_1 = tvb_get_guint8(tvb, offset);
1098
1099         /* Create the bitfield tree for byte 1*/
1100         bf_item = proto_tree_add_uint(tree, hf_sna_rh_1, tvb, offset, 1, rh_1);
1101         bf_tree = proto_item_add_subtree(bf_item, ett_sna_rh_1);
1102
1103         proto_tree_add_boolean(bf_tree, hf_sna_rh_dr1, tvb,  offset, 1, rh_1);
1104
1105         if (!is_response) {
1106                 proto_tree_add_boolean(bf_tree, hf_sna_rh_lcci, tvb, offset, 1, rh_1);
1107         }
1108
1109         proto_tree_add_boolean(bf_tree, hf_sna_rh_dr2, tvb,  offset, 1, rh_1);
1110
1111         if (is_response) {
1112                 proto_tree_add_boolean(bf_tree, hf_sna_rh_rti, tvb,  offset, 1, rh_1);
1113         }
1114         else {
1115                 proto_tree_add_boolean(bf_tree, hf_sna_rh_eri, tvb,  offset, 1, rh_1);
1116                 proto_tree_add_boolean(bf_tree, hf_sna_rh_rlwi, tvb, offset, 1, rh_1);
1117         }
1118
1119         proto_tree_add_boolean(bf_tree, hf_sna_rh_qri, tvb, offset, 1, rh_1);
1120         proto_tree_add_boolean(bf_tree, hf_sna_rh_pi, tvb,  offset, 1, rh_1);
1121
1122         offset += 1;
1123         rh_2 = tvb_get_guint8(tvb, offset);
1124
1125         /* Create the bitfield tree for byte 2*/
1126         bf_item = proto_tree_add_uint(tree, hf_sna_rh_2, tvb, offset, 1, rh_2);
1127
1128         if (!is_response) {
1129                 bf_tree = proto_item_add_subtree(bf_item, ett_sna_rh_2);
1130
1131                 proto_tree_add_boolean(bf_tree, hf_sna_rh_bbi, tvb,  offset, 1, rh_2);
1132                 proto_tree_add_boolean(bf_tree, hf_sna_rh_ebi, tvb,  offset, 1, rh_2);
1133                 proto_tree_add_boolean(bf_tree, hf_sna_rh_cdi, tvb,  offset, 1, rh_2);
1134                 proto_tree_add_uint(bf_tree, hf_sna_rh_csi, tvb,  offset, 1, rh_2);
1135                 proto_tree_add_boolean(bf_tree, hf_sna_rh_edi, tvb,  offset, 1, rh_2);
1136                 proto_tree_add_boolean(bf_tree, hf_sna_rh_pdi, tvb,  offset, 1, rh_2);
1137                 proto_tree_add_boolean(bf_tree, hf_sna_rh_cebi, tvb, offset, 1, rh_2);
1138         }
1139
1140         /* XXX - check for sdi. If TRUE, the next 4 bytes will be sense data */
1141 }
1142
1143 void
1144 proto_register_sna(void)
1145 {
1146         static hf_register_info hf[] = {
1147                 { &hf_sna_th,
1148                 { "Transmission Header",        "sna.th", FT_NONE, BASE_NONE, NULL, 0x0,
1149                         "", HFILL }},
1150
1151                 { &hf_sna_th_0,
1152                 { "Transmission Header Byte 0", "sna.th.0", FT_UINT8, BASE_HEX, NULL, 0x0,
1153                         "Byte 0 of Tranmission Header contains FID, MPF, ODAI,"
1154                         " and EFI as bitfields.", HFILL }},
1155
1156                 { &hf_sna_th_fid,
1157                 { "Format Identifer",           "sna.th.fid", FT_UINT8, BASE_HEX, VALS(sna_th_fid_vals), 0xf0,
1158                         "Format Identification", HFILL }},
1159
1160                 { &hf_sna_th_mpf,
1161                 { "Mapping Field",              "sna.th.mpf", FT_UINT8, BASE_DEC, VALS(sna_th_mpf_vals), 0x0c,
1162                         "The Mapping Field specifies whether the information field"
1163                         " associated with the TH is a complete or partial BIU.", HFILL }},
1164
1165                 { &hf_sna_th_odai,
1166                 { "ODAI Assignment Indicator",  "sna.th.odai", FT_UINT8, BASE_DEC, NULL, 0x02,
1167                         "The ODAI indicates which node assigned the OAF'-DAF' values"
1168                         " carried in the TH.", HFILL }},
1169
1170                 { &hf_sna_th_efi,
1171                 { "Expedited Flow Indicator",   "sna.th.efi", FT_UINT8, BASE_DEC, VALS(sna_th_efi_vals), 0x01,
1172                         "The EFI designates whether the PIU belongs to the normal"
1173                         " or expedited flow.", HFILL }},
1174
1175                 { &hf_sna_th_daf,
1176                 { "Destination Address Field",  "sna.th.daf", FT_UINT16, BASE_HEX, NULL, 0x0,
1177                         "", HFILL }},
1178
1179                 { &hf_sna_th_oaf,
1180                 { "Origin Address Field",       "sna.th.oaf", FT_UINT16, BASE_HEX, NULL, 0x0,
1181                         "", HFILL }},
1182
1183                 { &hf_sna_th_snf,
1184                 { "Sequence Number Field",      "sna.th.snf", FT_UINT16, BASE_DEC, NULL, 0x0,
1185                         "The Sequence Number Field contains a numerical identifier for"
1186                         " the associated BIU.", HFILL }},
1187
1188                 { &hf_sna_th_dcf,
1189                 { "Data Count Field",   "sna.th.dcf", FT_UINT16, BASE_DEC, NULL, 0x0,
1190                         "A binary count of the number of bytes in the BIU or BIU segment associated "
1191                         "with the tranmission header. The count does not include any of the bytes "
1192                         "in the transmission header.", HFILL }},
1193
1194                 { &hf_sna_th_lsid,
1195                 { "Local Session Identification",       "sna.th.lsid", FT_UINT8, BASE_HEX, NULL, 0x0,
1196                         "", HFILL }},
1197
1198                 { &hf_sna_th_tg_sweep,
1199                 { "Transmission Group Sweep",           "sna.th.tg_sweep", FT_UINT8, BASE_DEC,
1200                         VALS(sna_th_tg_sweep_vals), 0x08,
1201                         "", HFILL }},
1202
1203                 { &hf_sna_th_er_vr_supp_ind,
1204                 { "ER and VR Support Indicator",        "sna.th.er_vr_supp_ind", FT_UINT8, BASE_DEC,
1205                         VALS(sna_th_er_vr_supp_ind_vals), 0x04,
1206                         "", HFILL }},
1207
1208                 { &hf_sna_th_vr_pac_cnt_ind,
1209                 { "Virtual Route Pacing Count Indicator",       "sna.th.vr_pac_cnt_ind",
1210                         FT_UINT8, BASE_DEC, VALS(sna_th_vr_pac_cnt_ind_vals), 0x02,
1211                         "", HFILL }},
1212
1213                 { &hf_sna_th_ntwk_prty,
1214                 { "Network Priority",   "sna.th.ntwk_prty",
1215                         FT_UINT8, BASE_DEC, VALS(sna_th_ntwk_prty_vals), 0x01,
1216                         "", HFILL }},
1217
1218                 { &hf_sna_th_tgsf,
1219                 { "Transmission Group Segmenting Field",        "sna.th.tgsf",
1220                         FT_UINT8, BASE_HEX, VALS(sna_th_tgsf_vals), 0xc0,
1221                         "", HFILL }},
1222
1223                 { &hf_sna_th_mft,
1224                 { "MPR FID4 Type",      "sna.th.mft", FT_BOOLEAN, BASE_NONE, NULL, 0x04,
1225                         "", HFILL }},
1226
1227                 { &hf_sna_th_piubf,
1228                 { "PIU Blocking Field", "sna.th.piubf", FT_UINT8, BASE_HEX,
1229                         VALS(sna_th_piubf_vals), 0x03,
1230                         "Specifies whether this frame contains a single PIU or multiple PIUs.", HFILL }},
1231
1232                 { &hf_sna_th_iern,
1233                 { "Initial Explicit Route Number",      "sna.th.iern", FT_UINT8, BASE_DEC, NULL, 0xf0,
1234                         "", HFILL }},
1235
1236                 { &hf_sna_th_nlpoi,
1237                 { "NLP Offset Indicator",       "sna.th.nlpoi", FT_UINT8, BASE_DEC,
1238                         VALS(sna_th_nlpoi_vals), 0x80,
1239                         "", HFILL }},
1240
1241                 { &hf_sna_th_nlp_cp,
1242                 { "NLP Count or Padding",       "sna.th.nlp_cp", FT_UINT8, BASE_DEC, NULL, 0x70,
1243                         "", HFILL }},
1244
1245                 { &hf_sna_th_ern,
1246                 { "Explicit Route Number",      "sna.th.ern", FT_UINT8, BASE_DEC, NULL, 0x0f,
1247                         "The ERN in a TH identifies an explicit route direction of flow.", HFILL }},
1248
1249                 { &hf_sna_th_vrn,
1250                 { "Virtual Route Number",       "sna.th.vrn", FT_UINT8, BASE_DEC, NULL, 0xf0,
1251                         "", HFILL }},
1252
1253                 { &hf_sna_th_tpf,
1254                 { "Transmission Priority Field",        "sna.th.tpf", FT_UINT8, BASE_HEX,
1255                         VALS(sna_th_tpf_vals), 0x03,
1256                         "", HFILL }},
1257
1258                 { &hf_sna_th_vr_cwi,
1259                 { "Virtual Route Change Window Indicator",      "sna.th.vr_cwi", FT_UINT16, BASE_DEC,
1260                         VALS(sna_th_vr_cwi_vals), 0x8000,
1261                         "Used to change the window size of the virtual route by 1.", HFILL }},
1262
1263                 { &hf_sna_th_tg_nonfifo_ind,
1264                 { "Transmission Group Non-FIFO Indicator",      "sna.th.tg_nonfifo_ind", FT_BOOLEAN, 16,
1265                         TFS(&sna_th_tg_nonfifo_ind_truth), 0x4000,
1266                         "Indicates whether or not FIFO discipline is to enforced in "
1267                         "transmitting PIUs through the tranmission groups to prevent the PIUs "
1268                         "getting out of sequence during transmission over the TGs.", HFILL }},
1269
1270                 { &hf_sna_th_vr_sqti,
1271                 { "Virtual Route Sequence and Type Indicator",  "sna.th.vr_sqti", FT_UINT16, BASE_HEX,
1272                         VALS(sna_th_vr_sqti_vals), 0x3000,
1273                         "Specifies the PIU type.", HFILL }},
1274
1275                 { &hf_sna_th_tg_snf,
1276                 { "Transmission Group Sequence Number Field",   "sna.th.tg_snf", FT_UINT16, BASE_DEC,
1277                         NULL, 0x0fff,
1278                         "", HFILL }},
1279
1280                 { &hf_sna_th_vrprq,
1281                 { "Virtual Route Pacing Request",       "sna.th.vrprq", FT_BOOLEAN, 16,
1282                         TFS(&sna_th_vrprq_truth), 0x8000,
1283                         "", HFILL }},
1284
1285                 { &hf_sna_th_vrprs,
1286                 { "Virtual Route Pacing Response",      "sna.th.vrprs", FT_BOOLEAN, 16,
1287                         TFS(&sna_th_vrprs_truth), 0x4000,
1288                         "", HFILL }},
1289
1290                 { &hf_sna_th_vr_cwri,
1291                 { "Virtual Route Change Window Reply Indicator",        "sna.th.vr_cwri", FT_UINT16, BASE_DEC,
1292                         VALS(sna_th_vr_cwri_vals), 0x2000,
1293                         "Permits changing of the window size by 1 for PIUs received by the "
1294                         "sender of this bit.", HFILL }},
1295
1296                 { &hf_sna_th_vr_rwi,
1297                 { "Virtual Route Reset Window Indicator",       "sna.th.vr_rwi", FT_BOOLEAN, 16,
1298                         TFS(&sna_th_vr_rwi_truth), 0x1000,
1299                         "Indicates severe congestion in a node on the virtual route.", HFILL }},
1300
1301                 { &hf_sna_th_vr_snf_send,
1302                 { "Virtual Route Send Sequence Number Field",   "sna.th.vr_snf_send", FT_UINT16, BASE_DEC,
1303                         NULL, 0x0fff,
1304                         "", HFILL }},
1305
1306                 { &hf_sna_th_dsaf,
1307                 { "Destination Subarea Address Field",  "sna.th.dsaf", FT_UINT32, BASE_HEX, NULL, 0x0,
1308                         "", HFILL }},
1309
1310                 { &hf_sna_th_osaf,
1311                 { "Origin Subarea Address Field",       "sna.th.osaf", FT_UINT32, BASE_HEX, NULL, 0x0,
1312                         "", HFILL }},
1313
1314                 { &hf_sna_th_snai,
1315                 { "SNA Indicator",      "sna.th.snai", FT_BOOLEAN, 8, NULL, 0x10,
1316                         "Used to identify whether the PIU originated or is destined for "
1317                         "an SNA or non-SNA device.", HFILL }},
1318
1319                 { &hf_sna_th_def,
1320                 { "Destination Element Field",  "sna.th.def", FT_UINT16, BASE_HEX, NULL, 0x0,
1321                         "", HFILL }},
1322
1323                 { &hf_sna_th_oef,
1324                 { "Origin Element Field",       "sna.th.oef", FT_UINT16, BASE_HEX, NULL, 0x0,
1325                         "", HFILL }},
1326
1327                 { &hf_sna_th_sa,
1328                 { "Session Address",    "sna.th.sa", FT_BYTES, BASE_HEX, NULL, 0x0,
1329                         "", HFILL }},
1330
1331                 { &hf_sna_th_cmd_fmt,
1332                 { "Command Format",     "sna.th.cmd_fmt", FT_UINT8, BASE_HEX, NULL, 0x0,
1333                         "", HFILL }},
1334
1335                 { &hf_sna_th_cmd_type,
1336                 { "Command Type",       "sna.th.cmd_type", FT_UINT8, BASE_HEX, NULL, 0x0,
1337                         "", HFILL }},
1338
1339                 { &hf_sna_th_cmd_sn,
1340                 { "Command Sequence Number",    "sna.th.cmd_sn", FT_UINT16, BASE_DEC, NULL, 0x0,
1341                         "", HFILL }},
1342
1343                 { &hf_sna_nlp_nhdr,
1344                 { "Network Layer Packet Header",        "sna.nlp.nhdr", FT_NONE, BASE_NONE, NULL, 0x0,
1345                         "Network Layer Packet Header (NHDR)", HFILL }},
1346
1347                 { &hf_sna_nlp_nhdr_0,
1348                 { "Network Layer Packet Header Byte 0", "sna.nlp.nhdr.0", FT_UINT8, BASE_HEX, NULL, 0x0,
1349                         "Byte 0 of Network Layer Packet contains SM and TPF", HFILL }},
1350
1351                 { &hf_sna_nlp_nhdr_1,
1352                 { "Network Layer Packet Header Bype 1", "sna.nlp.nhdr.1", FT_UINT8, BASE_HEX, NULL, 0x0,
1353                         "Byte 1 of Network Layer Packet contains FT,"
1354                         " Time Sensitive Packet Indicator and Congestion Indicator", HFILL }},
1355
1356                 { &hf_sna_nlp_sm,
1357                 { "Switching Mode Field",       "sna.nlp.nhdr.sm", FT_UINT8, BASE_HEX,
1358                         VALS(sna_nlp_sm_vals), 0xe0,
1359                         "", HFILL }},
1360
1361                 { &hf_sna_nlp_tpf,
1362                 { "Transmission Priority Field",        "sna.nlp.nhdr.tpf", FT_UINT8, BASE_HEX,
1363                         VALS(sna_th_tpf_vals), 0x06,
1364                         "", HFILL }},
1365
1366                 { &hf_sna_nlp_ft,
1367                 { "Function Type",      "sna.nlp.nhdr.ft", FT_UINT8, BASE_HEX,
1368                         VALS(sna_nlp_ft_vals), 0xF0,
1369                         "", HFILL }},
1370
1371                 { &hf_sna_nlp_tspi,
1372                 { "Time Sensitive Packet Indicator",    "sna.nlp.nhdr.tspi", FT_BOOLEAN, 8,
1373                         TFS(&sna_nlp_tspi_truth), 0x08,
1374                         "", HFILL }},
1375
1376                 { &hf_sna_nlp_slowdn1,
1377                 { "Slowdown 1", "sna.nlp.nhdr.slowdn1", FT_BOOLEAN, 8,
1378                         TFS(&sna_nlp_slowdn1_truth), 0x04,
1379                         "", HFILL }},
1380
1381                 { &hf_sna_nlp_slowdn2,
1382                 { "Slowdown 2", "sna.nlp.nhdr.slowdn2", FT_BOOLEAN, 8,
1383                         TFS(&sna_nlp_slowdn2_truth), 0x02,
1384                         "", HFILL }},
1385
1386                 { &hf_sna_nlp_fra,
1387                 { "Function Routing Address Entry",     "sna.nlp.nhdr.fra", FT_BYTES, BASE_NONE, NULL, 0,
1388                         "", HFILL }},
1389
1390                 { &hf_sna_nlp_anr,
1391                 { "Automatic Network Routing Entry",    "sna.nlp.nhdr.anr", FT_BYTES, BASE_HEX, NULL, 0,
1392                         "", HFILL }},
1393
1394                 { &hf_sna_nlp_frh,
1395                 { "Transmission Priority Field",        "sna.nlp.frh", FT_UINT8, BASE_HEX,
1396                         VALS(sna_nlp_frh_vals), 0, "", HFILL }},
1397
1398                 { &hf_sna_nlp_thdr,
1399                 { "RTP Transport Header",       "sna.nlp.thdr", FT_NONE, BASE_NONE, NULL, 0x0,
1400                         "RTP Transport Header (THDR)", HFILL }},
1401
1402                 { &hf_sna_nlp_tcid,
1403                 { "Transport Connection Identifier",    "sna.nlp.thdr.tcid", FT_BYTES, BASE_HEX, NULL, 0x0,
1404                         "Transport Connection Identifier (TCID)", HFILL }},
1405
1406                 { &hf_sna_nlp_thdr_8,
1407                 { "RTP Transport Packet Header Bype 8", "sna.nlp.thdr.8", FT_UINT8, BASE_HEX, NULL, 0x0,
1408                         "Byte 8 of RTP Transport Packet Header", HFILL }},
1409
1410                 { &hf_sna_nlp_setupi,
1411                 { "Setup Indicator",    "sna.nlp.thdr.setupi", FT_BOOLEAN, 8,
1412                         TFS(&sna_nlp_setupi_truth), 0x40,
1413                         "", HFILL }},
1414
1415                 { &hf_sna_nlp_somi,
1416                 { "Start Of Message Indicator", "sna.nlp.thdr.somi", FT_BOOLEAN, 8,
1417                         TFS(&sna_nlp_somi_truth), 0x20,
1418                         "", HFILL }},
1419
1420                 { &hf_sna_nlp_eomi,
1421                 { "End Of Message Indicator",   "sna.nlp.thdr.eomi", FT_BOOLEAN, 8,
1422                         TFS(&sna_nlp_eomi_truth), 0x10,
1423                         "", HFILL }},
1424
1425                 { &hf_sna_nlp_sri,
1426                 { "Session Request Indicator",  "sna.nlp.thdr.sri", FT_BOOLEAN, 8,
1427                         TFS(&sna_nlp_sri_truth), 0x08,
1428                         "", HFILL }},
1429
1430                 { &hf_sna_nlp_rasapi,
1431                 { "Reply ASAP Indicator",       "sna.nlp.thdr.rasapi", FT_BOOLEAN, 8,
1432                         TFS(&sna_nlp_rasapi_truth), 0x04,
1433                         "", HFILL }},
1434
1435                 { &hf_sna_nlp_retryi,
1436                 { "Retry Indicator",    "sna.nlp.thdr.retryi", FT_BOOLEAN, 8,
1437                         TFS(&sna_nlp_retryi_truth), 0x02,
1438                         "", HFILL }},
1439
1440                 { &hf_sna_nlp_thdr_9,
1441                 { "RTP Transport Packet Header Bype 9", "sna.nlp.thdr.9", FT_UINT8, BASE_HEX, NULL, 0x0,
1442                         "Byte 9 of RTP Transport Packet Header", HFILL }},
1443
1444                 { &hf_sna_nlp_lmi,
1445                 { "Last Message Indicator",     "sna.nlp.thdr.lmi", FT_BOOLEAN, 8,
1446                         TFS(&sna_nlp_lmi_truth), 0x80,
1447                         "", HFILL }},
1448
1449                 { &hf_sna_nlp_cqfi,
1450                 { "Connection Qualifyer Field Indicator",       "sna.nlp.thdr.cqfi", FT_BOOLEAN, 8,
1451                         TFS(&sna_nlp_cqfi_truth), 0x08,
1452                         "", HFILL }},
1453
1454                 { &hf_sna_nlp_osi,
1455                 { "Optional Segments Present Indicator",        "sna.nlp.thdr.osi", FT_BOOLEAN, 8,
1456                         TFS(&sna_nlp_osi_truth), 0x04,
1457                         "", HFILL }},
1458
1459                 { &hf_sna_nlp_offset,
1460                 { "Data Offset/4",      "sna.nlp.thdr.offset", FT_UINT16, BASE_HEX, NULL, 0x0,
1461                         "Data Offset in words", HFILL }},
1462
1463                 { &hf_sna_nlp_dlf,
1464                 { "Data Length Field",  "sna.nlp.thdr.dlf", FT_UINT32, BASE_HEX, NULL, 0x0,
1465                         "Data Length Field", HFILL }},
1466
1467                 { &hf_sna_nlp_bsn,
1468                 { "Byte Sequence Number",       "sna.nlp.thdr.bsn", FT_UINT32, BASE_HEX, NULL, 0x0,
1469                         "Byte Sequence Number", HFILL }},
1470
1471
1472                 { &hf_sna_rh,
1473                 { "Request/Response Header",    "sna.rh", FT_NONE, BASE_NONE, NULL, 0x0,
1474                         "", HFILL }},
1475
1476                 { &hf_sna_rh_0,
1477                 { "Request/Response Header Byte 0",     "sna.rh.0", FT_UINT8, BASE_HEX, NULL, 0x0,
1478                         "", HFILL }},
1479
1480                 { &hf_sna_rh_1,
1481                 { "Request/Response Header Byte 1",     "sna.rh.1", FT_UINT8, BASE_HEX, NULL, 0x0,
1482                         "", HFILL }},
1483
1484                 { &hf_sna_rh_2,
1485                 { "Request/Response Header Byte 2",     "sna.rh.2", FT_UINT8, BASE_HEX, NULL, 0x0,
1486                         "", HFILL }},
1487
1488                 { &hf_sna_rh_rri,
1489                 { "Request/Response Indicator", "sna.rh.rri", FT_UINT8, BASE_DEC, VALS(sna_rh_rri_vals), 0x80,
1490                         "Denotes whether this is a request or a response.", HFILL }},
1491
1492                 { &hf_sna_rh_ru_category,
1493                 { "Request/Response Unit Category",     "sna.rh.ru_category", FT_UINT8, BASE_HEX,
1494                         VALS(sna_rh_ru_category_vals), 0x60,
1495                         "", HFILL }},
1496
1497                 { &hf_sna_rh_fi,
1498                 { "Format Indicator",           "sna.rh.fi", FT_BOOLEAN, 8, TFS(&sna_rh_fi_truth), 0x08,
1499                         "", HFILL }},
1500
1501                 { &hf_sna_rh_sdi,
1502                 { "Sense Data Included",        "sna.rh.sdi", FT_BOOLEAN, 8, TFS(&sna_rh_sdi_truth), 0x04,
1503                         "Indicates that a 4-byte sense data field is included in the associated RU.", HFILL }},
1504
1505                 { &hf_sna_rh_bci,
1506                 { "Begin Chain Indicator",      "sna.rh.bci", FT_BOOLEAN, 8, TFS(&sna_rh_bci_truth), 0x02,
1507                         "", HFILL }},
1508
1509                 { &hf_sna_rh_eci,
1510                 { "End Chain Indicator",        "sna.rh.eci", FT_BOOLEAN, 8, TFS(&sna_rh_eci_truth), 0x01,
1511                         "", HFILL }},
1512
1513                 { &hf_sna_rh_dr1,
1514                 { "Definite Response 1 Indicator",      "sna.rh.dr1", FT_BOOLEAN, 8, NULL, 0x80,
1515                         "", HFILL }},
1516
1517                 { &hf_sna_rh_lcci,
1518                 { "Length-Checked Compression Indicator",       "sna.rh.lcci", FT_BOOLEAN, 8,
1519                         TFS(&sna_rh_lcci_truth), 0x40,
1520                         "", HFILL }},
1521
1522                 { &hf_sna_rh_dr2,
1523                 { "Definite Response 2 Indicator",      "sna.rh.dr2", FT_BOOLEAN, 8, NULL, 0x20,
1524                         "", HFILL }},
1525
1526                 { &hf_sna_rh_eri,
1527                 { "Exception Response Indicator",       "sna.rh.eri", FT_BOOLEAN, 8, NULL, 0x10,
1528                         "Used in conjunction with DR1I and DR2I to indicate, in a request, "
1529                         "the form of response requested.", HFILL }},
1530
1531                 { &hf_sna_rh_rti,
1532                 { "Response Type Indicator",    "sna.rh.rti", FT_BOOLEAN, 8, TFS(&sna_rh_rti_truth), 0x10,
1533                         "", HFILL }},
1534
1535                 { &hf_sna_rh_rlwi,
1536                 { "Request Larger Window Indicator",    "sna.rh.rlwi", FT_BOOLEAN, 8, NULL, 0x04,
1537                         "Indicates whether a larger pacing window was requested.", HFILL }},
1538
1539                 { &hf_sna_rh_qri,
1540                 { "Queued Response Indicator",  "sna.rh.qri", FT_BOOLEAN, 8, TFS(&sna_rh_qri_truth), 0x02,
1541                         "", HFILL }},
1542
1543                 { &hf_sna_rh_pi,
1544                 { "Pacing Indicator",   "sna.rh.pi", FT_BOOLEAN, 8, NULL, 0x01,
1545                         "", HFILL }},
1546
1547                 { &hf_sna_rh_bbi,
1548                 { "Begin Bracket Indicator",    "sna.rh.bbi", FT_BOOLEAN, 8, NULL, 0x80,
1549                         "", HFILL }},
1550
1551                 { &hf_sna_rh_ebi,
1552                 { "End Bracket Indicator",      "sna.rh.ebi", FT_BOOLEAN, 8, NULL, 0x40,
1553                         "", HFILL }},
1554
1555                 { &hf_sna_rh_cdi,
1556                 { "Change Direction Indicator", "sna.rh.cdi", FT_BOOLEAN, 8, NULL, 0x20,
1557                         "", HFILL }},
1558
1559                 { &hf_sna_rh_csi,
1560                 { "Code Selection Indicator",   "sna.rh.csi", FT_UINT8, BASE_DEC, VALS(sna_rh_csi_vals), 0x08,
1561                         "Specifies the encoding used for the associated FMD RU.", HFILL }},
1562
1563                 { &hf_sna_rh_edi,
1564                 { "Enciphered Data Indicator",  "sna.rh.edi", FT_BOOLEAN, 8, NULL, 0x04,
1565                         "Indicates that information in the associated RU is enciphered under "
1566                         "session-level cryptography protocols.", HFILL }},
1567
1568                 { &hf_sna_rh_pdi,
1569                 { "Padded Data Indicator",      "sna.rh.pdi", FT_BOOLEAN, 8, NULL, 0x02,
1570                         "Indicates that the RU was padded at the end, before encipherment, to the next "
1571                         "integral multiple of 8 bytes.", HFILL }},
1572
1573                 { &hf_sna_rh_cebi,
1574                 { "Conditional End Bracket Indicator",  "sna.rh.cebi", FT_BOOLEAN, 8, NULL, 0x01,
1575                         "Used to indicate the beginning or end of a group of exchanged "
1576                         "requests and responses called a bracket. Only used on LU-LU sessions.", HFILL }},
1577
1578 /*                { &hf_sna_ru,
1579                 { "Request/Response Unit",      "sna.ru", FT_NONE, BASE_NONE, NULL, 0x0,
1580                         "", HFILL }},*/
1581         };
1582         static gint *ett[] = {
1583                 &ett_sna,
1584                 &ett_sna_th,
1585                 &ett_sna_th_fid,
1586                 &ett_sna_nlp_nhdr,
1587                 &ett_sna_nlp_nhdr_0,
1588                 &ett_sna_nlp_nhdr_1,
1589                 &ett_sna_nlp_thdr,
1590                 &ett_sna_nlp_thdr_8,
1591                 &ett_sna_nlp_thdr_9,
1592                 &ett_sna_rh,
1593                 &ett_sna_rh_0,
1594                 &ett_sna_rh_1,
1595                 &ett_sna_rh_2,
1596         };
1597
1598         proto_sna = proto_register_protocol("Systems Network Architecture",
1599             "SNA", "sna");
1600         proto_register_field_array(proto_sna, hf, array_length(hf));
1601         proto_register_subtree_array(ett, array_length(ett));
1602         register_dissector("sna", dissect_sna, proto_sna);
1603 }
1604
1605 void
1606 proto_reg_handoff_sna(void)
1607 {
1608         dissector_handle_t sna_handle;
1609
1610         sna_handle = find_dissector("sna");
1611         dissector_add("llc.dsap", SAP_SNA_PATHCTRL, sna_handle);
1612         /* RFC 2043 */
1613         dissector_add("ppp.protocol", PPP_SNA, sna_handle);
1614         data_handle = find_dissector("data");
1615 }