From Andreas Sikkema:
[metze/wireshark/wip.git] / packet-isns.c
1 /* packet-isns.c
2  * Routines for iSNS dissection
3  * Copyright 2003, Elipsan, Gareth Bushell <gbushell@elipsan.com>
4  *
5  * Ethereal - Network traffic analyzer
6  * By Gerald Combs <gerald@ethereal.com>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  * 
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
34 #endif
35
36 #ifdef HAVE_NETINET_IN_H
37 # include <netinet/in.h>
38 #endif
39
40 #include <glib.h>
41
42 #ifdef NEED_SNPRINTF_H
43 # include "snprintf.h"
44 #endif
45
46 #include <epan/packet.h>
47
48 #define ISNS_PROTO_VER 0x1
49 #define ISNS_HEADER_SIZE 12
50
51 #define ISNS_TCP_PORT 3205
52 #define ISNS_UDP_PORT 3205
53
54 static gint ett_isns_flags = -1;
55 static gint ett_isns_payload = -1;
56 static gint ett_isns_port = -1;
57 static gint ett_isns_psb = -1;
58 static gint ett_isns_isnt = -1;
59 static gint ett_scn_bitmap = -1;
60
61 static guint AddAttribute(tvbuff_t *tvb, proto_tree *tree,guint offset );
62
63 /* Initialize the protocol and registered fields */
64 static int proto_isns = -1;
65
66
67 /* Header Stuff */
68 static int hf_isns_version = -1;
69 static int hf_isns_function_id = -1;
70 static int hf_isns_pdu_length = -1;
71 static int hf_isns_flags = -1;
72 static int hf_isns_transaction_id = -1;
73 static int hf_isns_sequence_id = -1;
74 static int hf_isns_payload = -1;
75 static int hf_isns_first_pdu = -1;
76 static int hf_isns_last_pdu = -1;
77 static int hf_isns_replace = -1;
78 static int hf_isns_server = -1;
79 static int hf_isns_client = -1;
80
81 /* Payload stuff */
82 static int hf_isns_scn_bitmap                                      = -1;
83 static int hf_isns_scn_bitmap_initiator_and_self_information_only  = -1;
84 static int hf_isns_scn_bitmap_target_and_self_information_only     = -1;
85 static int hf_isns_scn_bitmap_management_registration_scn          = -1;
86 static int hf_isns_scn_bitmap_object_removed                       = -1;
87 static int hf_isns_scn_bitmap_object_added                         = -1;
88 static int hf_isns_scn_bitmap_object_updated                       = -1;
89 static int hf_isns_scn_bitmap_dd_dds_member_removed                = -1;
90 static int hf_isns_scn_bitmap_dd_dds_member_added                  = -1;
91 static int hf_isns_isnt = -1;
92 static int hf_isns_isnt_control = -1;
93 static int hf_isns_isnt_initiator = -1;
94 static int hf_isns_isnt_target = -1;
95
96 static int hf_isns_psb = -1;
97 static int hf_isns_psb_tunnel_mode = -1;
98 static int hf_isns_psb_transport_mode = -1;
99 static int hf_isns_psb_pfs = -1;
100 static int hf_isns_psb_aggressive_mode = -1;
101 static int hf_isns_psb_main_mode = -1;
102 static int hf_isns_psb_ike_ipsec = -1;
103 static int hf_isns_psb_bitmap = -1;
104
105 static int hf_isns_port = -1;
106 static int hf_isns_port_port = -1;
107 static int hf_isns_port_type = -1;
108
109 static int hf_isns_entity_protocol = -1;
110 static int hf_isns_resp_errorcode = -1;
111 static int hf_isns_attr_tag = -1;
112 static int hf_isns_attr_len = -1;
113 static int hf_isns_attr_payload = -1;
114 static int hf_isns_heartbeat_ipv6_addr = -1;
115 static int hf_isns_heartbeat_udp_port = -1;
116 static int hf_isns_heartbeat_tcp_port = -1;
117 static int hf_isns_heartbeat_interval = -1;
118 static int hf_isns_heartbeat_counter = -1;
119
120 static int hf_isns_attr_string = -1;
121 static int hf_isns_attr_ipaddr = -1;
122 static int hf_isns_attr_index = -1;
123 static int hf_isns_attr_seconds = -1;
124
125 /* Function Id's */
126 #define ISNS_FUNC_DEVATTRREG     0x0001
127 #define ISNS_FUNC_DEVATTRQRY     0x0002
128 #define ISNS_FUNC_DEVGETNEXT     0x0003
129 #define ISNS_FUNC_DEREGDEV       0x0004
130 #define ISNS_FUNC_SCNREG         0x0005
131 #define ISNS_FUNC_SCNDEREG       0x0006
132 #define ISNS_FUNC_SCNEVENT       0x0007
133 #define ISNS_FUNC_SCN            0x0008
134 #define ISNS_FUNC_DDREG          0x0009
135 #define ISNS_FUNC_DDDEREG        0x000a
136 #define ISNS_FUNC_DDSREG         0x000b
137 #define ISNS_FUNC_DDSDEREG       0x000c
138 #define ISNS_FUNC_ESI            0x000d
139 #define ISNS_FUNC_HEARTBEAT      0x000e
140
141 #define ISNS_FUNC_RSP_DEVATTRREG 0x8001
142 #define ISNS_FUNC_RSP_DEVATTRQRY 0x8002
143 #define ISNS_FUNC_RSP_DEVGETNEXT 0x8003
144 #define ISNS_FUNC_RSP_DEREGDEV   0x8004
145 #define ISNS_FUNC_RSP_SCNREG     0x8005
146 #define ISNS_FUNC_RSP_SCNDEREG   0x8006
147 #define ISNS_FUNC_RSP_SCNEVENT   0x8007
148 #define ISNS_FUNC_RSP_SCN        0x8008
149 #define ISNS_FUNC_RSP_DDREG      0x8009
150 #define ISNS_FUNC_RSP_DDDEREG    0x800a
151 #define ISNS_FUNC_RSP_DDSREG     0x800b
152 #define ISNS_FUNC_RSP_DDSDEREG   0x800c
153 #define ISNS_FUNC_RSP_ESI        0x800d
154
155 static const value_string isns_function_ids[] = {
156 /* Requests*/
157     {ISNS_FUNC_DEVATTRREG,     "DevAttrReg"},
158     {ISNS_FUNC_DEVATTRQRY,     "DevAttrQry"},
159     {ISNS_FUNC_DEVGETNEXT,     "DevGetNext"},
160     {ISNS_FUNC_DEREGDEV,       "DeregDev"},
161     {ISNS_FUNC_SCNREG,         "SCNReg"},
162     {ISNS_FUNC_SCNDEREG,       "SCNDereg"},
163     {ISNS_FUNC_SCNEVENT,       "SCNEvent"},
164     {ISNS_FUNC_SCN,            "SCN"},
165     {ISNS_FUNC_DDREG,          "DDReg"},
166     {ISNS_FUNC_DDDEREG,        "DDDereg"},
167     {ISNS_FUNC_DDSREG,         "DDSReg"},
168     {ISNS_FUNC_DDSDEREG,       "DDSDereg"},
169     {ISNS_FUNC_ESI,            "ESI"},
170     {ISNS_FUNC_HEARTBEAT,      "Heartbeat"},
171
172 /* Responses */
173     {ISNS_FUNC_RSP_DEVATTRREG, "DevAttrRegRsp"},
174     {ISNS_FUNC_RSP_DEVATTRQRY, "DevAttrQryRsp"},
175     {ISNS_FUNC_RSP_DEVGETNEXT, "DevGetNextRsp"},
176     {ISNS_FUNC_RSP_DEREGDEV,   "DeregDevRsp"},
177     {ISNS_FUNC_RSP_SCNREG,     "SCNRegRsp"},
178     {ISNS_FUNC_RSP_SCNDEREG,   "SCNDeregRsp"},
179     {ISNS_FUNC_RSP_SCNEVENT,   "SCNEventRsp"},
180     {ISNS_FUNC_RSP_SCN,        "SCNRsp"},
181     {ISNS_FUNC_RSP_DDREG,      "DDRegRsp"},
182     {ISNS_FUNC_RSP_DDDEREG,    "DDDeregRsp"},
183     {ISNS_FUNC_RSP_DDSREG,     "DDSRegRsp"},
184     {ISNS_FUNC_RSP_DDSDEREG,   "DDSDeregRsp"},
185     {ISNS_FUNC_RSP_ESI,        "ESIRsp"},
186
187     {0x0,NULL},
188 };
189
190 #define ISNS_ENTITY_PROTOCOL_NO_PROTOCOL 1
191 #define ISNS_ENTITY_PROTOCOL_ISCSI       2
192 #define ISNS_ENTITY_PROTOCOL_IFCP        3
193
194
195 static const value_string isns_entity_protocol[] = {
196     {ISNS_ENTITY_PROTOCOL_NO_PROTOCOL, "No Protocol"},
197     {ISNS_ENTITY_PROTOCOL_ISCSI,       "iSCSI"},
198     {ISNS_ENTITY_PROTOCOL_IFCP,        "iFCP"}, 
199
200     {0x0,NULL},
201 };
202
203 static const value_string isns_errorcode[] = {
204     { 0,"No Error"},
205     { 1,"Unknown Error"},
206     { 2,"Message Format Error"},
207     { 3,"Invalid Registration"},
208     { 4,"Requested ESI Period Too short"},
209     { 5,"Invalid Query"},
210     { 6,"Authentication Unknown"},
211     { 7,"Authentication Absent"},
212     { 8,"Authentication Failed"},
213     { 9,"No such Entry"},
214     {10,"Version Not Supported"},
215     {11,"Internal Bus Error"},
216     {12,"Busy Now"},
217     {13,"Option Not Understood"},
218     {14,"Invalid Update"},
219     {15,"Message Not supported"},
220     {16,"SCN Event Rejected"},
221     {17,"SCN Registration Rejected"},
222     {18,"Attribute Not Implemented"},
223     {19,"SWITCH_ID Not available"},
224     {20,"SWITCH_ID not allocated"},
225     {21,"ESI Not Available"},
226
227     {0x0,NULL}
228 };
229
230
231 #define ISNS_ATTR_TAG_DELIMITER                     0
232 #define ISNS_ATTR_TAG_ENTITY_IDENTIFIER             1
233 #define ISNS_ATTR_TAG_ENTITY_PROTOCOL               2
234 #define ISNS_ATTR_TAG_MGMT_IP_ADDRESS               3
235 #define ISNS_ATTR_TAG_TIMESTAMP                     4
236 #define ISNS_ATTR_TAG_PROTOCOL_VERSION_RANGE        5
237 #define ISNS_ATTR_TAG_REGISTRATION_PERIOD           6
238 #define ISNS_ATTR_TAG_ENTITY_INDEX                  7
239 #define ISNS_ATTR_TAG_ENTITY_NEXT_INDEX             8
240 #define ISNS_ATTR_TAG_ENTITY_ISAKMP_PHASE_1         11
241 #define ISNS_ATTR_TAG_ENTITY_CERTIFICATE            12
242 #define ISNS_ATTR_TAG_PORTAL_IP_ADDRESS             16
243 #define ISNS_ATTR_TAG_PORTAL_PORT                   17
244 #define ISNS_ATTR_TAG_PORTAL_SYMBOLIC_NAME          18
245 #define ISNS_ATTR_TAG_ESI_INTERVAL                  19
246 #define ISNS_ATTR_TAG_ESI_PORT                      20
247 #define ISNS_ATTR_TAG_PORTAL_GROUP                  21
248 #define ISNS_ATTR_TAG_PORTAL_INDEX                  22
249 #define ISNS_ATTR_TAG_SCN_PORT                      23
250 #define ISNS_ATTR_TAG_PORTAL_NEXT_INDEX             24
251 #define ISNS_ATTR_TAG_PORTAL_SECURITY_BITMAP        27
252 #define ISNS_ATTR_TAG_PORTAL_ISAKMP_PHASE_1         28
253 #define ISNS_ATTR_TAG_PORTAL_ISAKMP_PHASE_2         29
254 #define ISNS_ATTR_TAG_PORTAL_CERTIFICATE            31
255 #define ISNS_ATTR_TAG_ISCSI_NAME                    32
256 #define ISNS_ATTR_TAG_ISCSI_NODE_TYPE               33
257 #define ISNS_ATTR_TAG_ISCSI_ALIAS                   34
258 #define ISNS_ATTR_TAG_ISCSI_SCN_BITMAP              35
259 #define ISNS_ATTR_TAG_ISCSI_NODE_INDEX              36
260 #define ISNS_ATTR_TAG_WWNN_TOKEN                    37
261 #define ISNS_ATTR_TAG_ISCSI_NODE_NEXT_INDEX         38
262 #define ISNS_ATTR_TAG_ISCSI_AUTH_METHOD             42
263 #define ISNS_ATTR_TAG_ISCSI_NODE_CERTIFICATE        43
264 #define ISNS_ATTR_TAG_FC_PORT_NAME_WWPN             64
265 #define ISNS_ATTR_TAG_PORT_ID                       65
266 #define ISNS_ATTR_TAG_FC_PORT_TYPE                  66
267 #define ISNS_ATTR_TAG_SYMBOLIC_PORT_NAME            67
268 #define ISNS_ATTR_TAG_FABRIC_PORT_NAME              68
269 #define ISNS_ATTR_TAG_HARD_ADDRESS                  69
270 #define ISNS_ATTR_TAG_PORT_IP_ADDRESS               70
271 #define ISNS_ATTR_TAG_CLASS_OF_SERVICE              71
272 #define ISNS_ATTR_TAG_FC4_TYPES                     72
273 #define ISNS_ATTR_TAG_FC4_DESCRIPTOR                73
274 #define ISNS_ATTR_TAG_FC4_FEATURES                  74
275 #define ISNS_ATTR_TAG_IFCP_SCN_BITMAP               75
276 #define ISNS_ATTR_TAG_PORT_ROLE                     76
277 #define ISNS_ATTR_TAG_PERMANENT_PORT_NAME           77
278 #define ISNS_ATTR_TAG_PORT_CERTIFICATE              83
279 #define ISNS_ATTR_TAG_FC4_TYPE_CODE                 95
280 #define ISNS_ATTR_TAG_FC_NODE_NAME_WWNN             96
281 #define ISNS_ATTR_TAG_SYMBOLIC_NODE_NAME            97
282 #define ISNS_ATTR_TAG_NODE_IP_ADDRESS               98
283 #define ISNS_ATTR_TAG_NODE_IPA                      99
284 #define ISNS_ATTR_TAG_NODE_CERTIFICATE              100
285 #define ISNS_ATTR_TAG_PROXY_ISCSI_NAME              101
286 #define ISNS_ATTR_TAG_SWITCH_NAME                   128
287 #define ISNS_ATTR_TAG_PREFERRED_ID                  129
288 #define ISNS_ATTR_TAG_ASSIGNED_ID                   130
289 #define ISNS_ATTR_TAG_VIRTUAL_FABRIC_ID             131
290 #define ISNS_ATTR_TAG_VENDOR_OUI                    256
291 #define ISNS_ATTR_TAG_DD_SET_ID                     2049
292 #define ISNS_ATTR_TAG_DD_SET_SYMBOLIC_NAME          2050
293 #define ISNS_ATTR_TAG_DD_SET_STATUS                 2051
294 #define ISNS_ATTR_TAG_DD_SET_NEXT_ID                2052
295 #define ISNS_ATTR_TAG_DD_ID                         2065
296 #define ISNS_ATTR_TAG_DD_SYMBOLIC_NAME              2066
297 #define ISNS_ATTR_TAG_DD_MEMBER_ISCSI_INDEX         2067
298 #define ISNS_ATTR_TAG_DD_MEMBER_ISCSI_NAME          2068
299 #define ISNS_ATTR_TAG_DD_MEMBER_IFCP_NODE           2069
300 #define ISNS_ATTR_TAG_DD_MEMBER_PORTAL_INDEX        2070
301 #define ISNS_ATTR_TAG_DD_MEMBER_PORTAL_IP_ADDRESS   2071
302 #define ISNS_ATTR_TAG_DD_MEMBER_PORTAL_PORT         2072
303 #define ISNS_ATTR_TAG_DD_FEATURES                   2078
304 #define ISNS_ATTR_TAG_DD_ID_NEXT_ID                 2079
305
306
307 static const value_string isns_attribute_tags[] = {
308     {ISNS_ATTR_TAG_DELIMITER,                   "Delimiter"},
309     {ISNS_ATTR_TAG_ENTITY_IDENTIFIER,           "Entity Identifier (EID)"},
310     {ISNS_ATTR_TAG_ENTITY_PROTOCOL,             "Entity Protocol"},
311     {ISNS_ATTR_TAG_MGMT_IP_ADDRESS,             "Management IP Address"},
312     {ISNS_ATTR_TAG_TIMESTAMP,                   "Timestamp"},
313     {ISNS_ATTR_TAG_PROTOCOL_VERSION_RANGE,      "Protocol Version Range"},
314     {ISNS_ATTR_TAG_REGISTRATION_PERIOD,         "Registration Period"},
315     {ISNS_ATTR_TAG_ENTITY_INDEX,                "Entity Index"},
316     {ISNS_ATTR_TAG_ENTITY_NEXT_INDEX,           "Entity Next Index"},
317     {ISNS_ATTR_TAG_ENTITY_ISAKMP_PHASE_1,       "Entity ISAKMP Phase-1"},
318     {ISNS_ATTR_TAG_ENTITY_CERTIFICATE,          "Entity Certificate"},
319     {ISNS_ATTR_TAG_PORTAL_IP_ADDRESS,           "Portal IP Address"},
320     {ISNS_ATTR_TAG_PORTAL_PORT,                 "Portal TCP/UDP Port"},
321     {ISNS_ATTR_TAG_PORTAL_SYMBOLIC_NAME,        "Portal Symbolic Name"},
322     {ISNS_ATTR_TAG_ESI_INTERVAL,                "ESI Interval"},
323     {ISNS_ATTR_TAG_ESI_PORT,                    "ESI Port"},
324     {ISNS_ATTR_TAG_PORTAL_GROUP,                "Portal Group Tag"},
325     {ISNS_ATTR_TAG_PORTAL_INDEX,                "Portal Index"},
326     {ISNS_ATTR_TAG_SCN_PORT,                    "SCN Port"},
327     {ISNS_ATTR_TAG_PORTAL_NEXT_INDEX,           "Portal Next Index"},
328     {ISNS_ATTR_TAG_PORTAL_SECURITY_BITMAP,      "Portal Security Bitmap"},
329     {ISNS_ATTR_TAG_PORTAL_ISAKMP_PHASE_1,       "Portal ISAKMP Phase-1"},
330     {ISNS_ATTR_TAG_PORTAL_ISAKMP_PHASE_2,       "Portal ISAKMP Phase-2"},
331     {ISNS_ATTR_TAG_PORTAL_CERTIFICATE,          "Portal Certificate"},
332     {ISNS_ATTR_TAG_ISCSI_NAME,                  "iSCSI Name"},
333     {ISNS_ATTR_TAG_ISCSI_NODE_TYPE,             "iSCSI Node Type"},
334     {ISNS_ATTR_TAG_ISCSI_ALIAS,                 "iSCSI Alias"},
335     {ISNS_ATTR_TAG_ISCSI_SCN_BITMAP,            "iSCSI SCN Bitmap"},
336     {ISNS_ATTR_TAG_ISCSI_NODE_INDEX,            "iSCSI Node Index"},
337     {ISNS_ATTR_TAG_WWNN_TOKEN,                  "WWNN Token"},
338     {ISNS_ATTR_TAG_ISCSI_NODE_NEXT_INDEX,       "iSCSI Node Next Index"},
339     {ISNS_ATTR_TAG_ISCSI_AUTH_METHOD,           "iSCSI AuthMethod"},
340     {ISNS_ATTR_TAG_ISCSI_NODE_CERTIFICATE,      "iSCSI Node Certificate"},
341     {ISNS_ATTR_TAG_FC_PORT_NAME_WWPN,           "FC Port Name WWPN"},
342     {ISNS_ATTR_TAG_PORT_ID,                     "Port ID"},
343     {ISNS_ATTR_TAG_FC_PORT_TYPE,                "FC Port Type"},
344     {ISNS_ATTR_TAG_SYMBOLIC_PORT_NAME,          "Symbolic Port Name"},
345     {ISNS_ATTR_TAG_FABRIC_PORT_NAME,            "Fabric Port Name"},
346     {ISNS_ATTR_TAG_HARD_ADDRESS,                "Hard Address"},
347     {ISNS_ATTR_TAG_PORT_IP_ADDRESS,             "Port IP-Address"},
348     {ISNS_ATTR_TAG_CLASS_OF_SERVICE,            "Class of Service"},
349     {ISNS_ATTR_TAG_FC4_TYPES,                   "FC-4 Types"},
350     {ISNS_ATTR_TAG_FC4_DESCRIPTOR,              "FC-4 Descriptor"},
351     {ISNS_ATTR_TAG_FC4_FEATURES,                "FC-4 Features"},
352     {ISNS_ATTR_TAG_IFCP_SCN_BITMAP,             "iFCP SCN bitmap"},
353     {ISNS_ATTR_TAG_PORT_ROLE,                   "Port Role"},
354     {ISNS_ATTR_TAG_PERMANENT_PORT_NAME,         "Permanent Port Name"},
355     {ISNS_ATTR_TAG_PORT_CERTIFICATE,            "Port Certificate"},
356     {ISNS_ATTR_TAG_FC4_TYPE_CODE,               "FC-4 Type Code"},
357     {ISNS_ATTR_TAG_FC_NODE_NAME_WWNN,           "FC Node Name WWNN"},
358     {ISNS_ATTR_TAG_SYMBOLIC_NODE_NAME,          "Symbolic Node Name"},
359     {ISNS_ATTR_TAG_NODE_IP_ADDRESS,             "Node IP-Address"},
360     {ISNS_ATTR_TAG_NODE_IPA,                    "Node IPA"},
361     {ISNS_ATTR_TAG_NODE_CERTIFICATE,            "Node Certificate"},
362     {ISNS_ATTR_TAG_PROXY_ISCSI_NAME,            "Proxy iSCSI Name"},
363     {ISNS_ATTR_TAG_SWITCH_NAME,                 "Switch Name"},
364     {ISNS_ATTR_TAG_PREFERRED_ID,                "Preferred ID"},
365     {ISNS_ATTR_TAG_ASSIGNED_ID,                 "Assigned ID"},
366     {ISNS_ATTR_TAG_VIRTUAL_FABRIC_ID,           "Virtual_Fabric_ID"},
367     {ISNS_ATTR_TAG_VENDOR_OUI,                  "iSNS Server Vendor OUI"},
368     {ISNS_ATTR_TAG_DD_SET_ID,                   "DD_Set ID"},
369     {ISNS_ATTR_TAG_DD_SET_SYMBOLIC_NAME,        "DD_Set Sym Name"},
370     {ISNS_ATTR_TAG_DD_SET_STATUS,               "DD_Set Status"},
371     {ISNS_ATTR_TAG_DD_SET_NEXT_ID,              "DD_Set_Next_ID"},
372     {ISNS_ATTR_TAG_DD_ID,                       "DD_ID"},
373     {ISNS_ATTR_TAG_DD_SYMBOLIC_NAME,            "DD_Symbolic Name"},
374     {ISNS_ATTR_TAG_DD_MEMBER_ISCSI_INDEX,       "DD_Member iSCSI Index"},
375     {ISNS_ATTR_TAG_DD_MEMBER_ISCSI_NAME,        "DD_Member iSCSI Name"},
376     {ISNS_ATTR_TAG_DD_MEMBER_IFCP_NODE,         "DD_Member iFCP Node"},
377     {ISNS_ATTR_TAG_DD_MEMBER_PORTAL_INDEX,      "DD Member Portal Index"},
378     {ISNS_ATTR_TAG_DD_MEMBER_PORTAL_IP_ADDRESS, "DD_Member Portal IP Addr"},
379     {ISNS_ATTR_TAG_DD_MEMBER_PORTAL_PORT,       "DD Member Portal TCP/UDP"},
380     {ISNS_ATTR_TAG_DD_FEATURES,                 "DD_Features"},
381     {ISNS_ATTR_TAG_DD_ID_NEXT_ID,               "DD_ID Next ID"},
382
383     {0,NULL}
384 };
385
386
387
388
389 static const true_false_string isns_scn_bitmap_initiator_and_self_information_only = {
390     "True",
391     "False"
392 };
393 static const true_false_string isns_scn_bitmap_target_and_self_information_only    = {
394     "True",
395     "False"
396 };
397 static const true_false_string isns_scn_bitmap_management_registration_scn         = {
398     "True",
399     "False"
400 };
401 static const true_false_string isns_scn_bitmap_object_removed                      = {
402     "True",
403     "False"
404 };
405 static const true_false_string isns_scn_bitmap_object_added                        = {
406     "True",
407     "False"
408 };
409 static const true_false_string isns_scn_bitmap_object_updated                      = {
410     "True",
411     "False"
412 };
413 static const true_false_string isns_scn_bitmap_dd_dds_member_removed               = {
414     "True",
415     "False"
416 };
417 static const true_false_string isns_scn_bitmap_dd_dds_member_added                 = {
418     "True",
419     "False"
420 };
421
422 static const true_false_string isns_psb_tunnel_mode = {
423     "Preferred",
424     "No Preference"
425 };
426 static const true_false_string isns_psb_transport_mode = {
427     "Preferred",
428     "No Preference"
429 };
430 static const true_false_string isns_psb_pfs = {
431     "Enabled",
432     "Disabled"
433 };
434 static const true_false_string isns_psb_aggressive_mode = {
435     "Enabled",
436     "Disabled"
437 };
438 static const true_false_string isns_psb_main_mode = {
439     "Enabled",
440     "Disabled"
441 };
442 static const true_false_string isns_psb_ike_ipsec = {
443     "Enabled",
444     "Disabled"
445 };
446 static const true_false_string isns_psb_bitmap = {
447     "VALID",
448     "INVALID"
449 };
450
451 static const true_false_string isns_isnt_control = {
452     "Yes",
453     "No"
454 };
455 static const true_false_string isns_isnt_initiator = {
456     "Yes",
457     "No"
458 };
459 static const true_false_string isns_isnt_target = {
460     "Yes",
461     "No"
462 };
463
464 static const true_false_string isns_port_type = {
465     "UDP",
466     "TCP"
467 };
468
469 static const true_false_string isns_flag_first_pdu = {
470     "First PDU of iSNS Message",
471     "Not the first PDU of iSNS Message"
472 };
473
474 static const true_false_string isns_flag_last_pdu = {
475     "Last PDU of iSNS Message",
476     "Not the Last PDU of iSNS Message"
477 };
478
479 static const true_false_string isns_flag_replace = {
480     "Replace",
481     "Don't replace"
482 };
483
484 static const true_false_string isns_flag_server = {
485     "Sender is iSNS server",
486     "Sender is not iSNS server"
487 };
488
489 static const true_false_string isns_flag_client = {
490     "Sender is iSNS client",
491     "Sender is not iSNS client"
492 };
493
494
495 /* Initialize the subtree pointers */
496 static gint ett_isns = -1;
497
498
499 /* Code to actually dissect the packets */
500 static int
501 dissect_isns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
502 {
503     guint offset = 0;
504     guint16 function_id;
505     guint16 isns_protocol_version;
506     guint32 packet_len = tvb_length_remaining(tvb, offset);
507     char * function_id_str;
508     /* Set up structures needed to add the protocol subtree and manage it */
509     proto_item *ti = NULL;
510     proto_tree *isns_tree = NULL;
511     
512     if( packet_len < 12 )
513         return 0;
514
515     /* Make entries in Protocol column and Info column on summary display */
516     if (check_col(pinfo->cinfo, COL_PROTOCOL)) 
517         col_set_str(pinfo->cinfo, COL_PROTOCOL, "isns");
518     if (check_col(pinfo->cinfo, COL_INFO)) 
519         col_clear(pinfo->cinfo, COL_INFO);
520
521     /* Get the function id from the packet */
522     function_id =  tvb_get_ntohs(tvb, offset + 2);
523     function_id_str = match_strval(function_id, isns_function_ids);
524     
525     /* Get the protocol version - only version one at the moment*/ 
526     isns_protocol_version = tvb_get_ntohs(tvb, offset + 0);
527     if( (function_id_str == NULL) || (isns_protocol_version != ISNS_PROTO_VER) )
528         return 0;
529     
530     /* Add the function name in the info col */
531     if (check_col(pinfo->cinfo, COL_INFO)) 
532         col_add_str(pinfo->cinfo, COL_INFO, function_id_str);
533     
534     /* In the interest of speed, if "tree" is NULL, don't do any work not
535      * necessary to generate protocol tree items. 
536      */
537     if (tree) {
538         guint16 b;      
539         proto_tree *tt;
540         proto_item *tflags;
541         proto_item *tpayload;
542
543         /* NOTE: The offset and length values in the call to
544          * "proto_tree_add_item()" define what data bytes to highlight in the hex
545          * display window when the line in the protocol tree display
546          * corresponding to that item is selected.
547          *  tvb_length(tvb) is a handy way to highlight all data from the offset to
548          *  the end of the packet. 
549          */
550
551         /* create display subtree for the protocol */
552         ti = proto_tree_add_item(tree, proto_isns, tvb, 0, -1, FALSE);
553         isns_tree = proto_item_add_subtree(ti, ett_isns);
554
555         /* OK... Sort out the header */
556         b = tvb_get_ntohs(tvb, offset);
557         proto_tree_add_uint(isns_tree, hf_isns_version, tvb, offset, 2, b);
558
559         b = tvb_get_ntohs(tvb, offset + 2);
560         proto_tree_add_uint(isns_tree, hf_isns_function_id, tvb, offset+2, 2, b);
561
562         b = tvb_get_ntohs(tvb, offset + 4);
563         proto_tree_add_uint(isns_tree, hf_isns_pdu_length, tvb, offset+4, 2, b);
564
565         /*FLAGS*/
566         b = tvb_get_ntohs(tvb, offset + 6);
567         tflags = proto_tree_add_uint(isns_tree, hf_isns_flags, tvb, offset+6, 2, b);
568         tt = proto_item_add_subtree(tflags, ett_isns_flags);
569
570         proto_tree_add_boolean(tt, hf_isns_first_pdu, tvb, offset+6, 2, b); 
571         proto_tree_add_boolean(tt, hf_isns_last_pdu, tvb, offset+6, 2, b); 
572         proto_tree_add_boolean(tt, hf_isns_replace, tvb, offset+6, 2, b); 
573         proto_tree_add_boolean(tt, hf_isns_server, tvb, offset+6, 2, b); 
574         proto_tree_add_boolean(tt, hf_isns_client, tvb, offset+6, 2, b); 
575
576         b = tvb_get_ntohs(tvb, offset + 8);
577         proto_tree_add_uint(isns_tree, hf_isns_transaction_id, tvb, offset+8, 2, b);
578
579         b = tvb_get_ntohs(tvb, offset + 10);
580         proto_tree_add_uint(isns_tree, hf_isns_sequence_id, tvb, offset+10, 2, b);
581
582         tpayload = proto_tree_add_item(isns_tree, hf_isns_payload, tvb, offset+12, packet_len - 12 , FALSE);
583         tt = proto_item_add_subtree(tpayload, ett_isns_payload);
584
585         /* Now set the offset to the start of the payload */
586         offset += ISNS_HEADER_SIZE;
587
588         /* Decode those attributes baby - Yeah!*/
589         switch (function_id)
590         {
591         case ISNS_FUNC_HEARTBEAT:
592         {
593             guint8 hb_ipv6[16];
594             guint16 port;
595             guint32 c;
596             tvb_memcpy(tvb,hb_ipv6,offset,16);
597             proto_tree_add_ipv6(tt,hf_isns_heartbeat_ipv6_addr, tvb, offset, 16, hb_ipv6);
598             offset += 16;
599
600             port = tvb_get_ntohs(tvb, offset);
601             proto_tree_add_uint(tt,hf_isns_heartbeat_tcp_port, tvb, offset, 2, port);
602             offset += 2;
603
604             port = tvb_get_ntohs(tvb, offset);
605             proto_tree_add_uint(tt,hf_isns_heartbeat_udp_port, tvb, offset, 2, port);
606             offset += 2;
607
608             c = tvb_get_ntohl(tvb, offset);
609             proto_tree_add_uint(tt,hf_isns_heartbeat_interval, tvb, offset, 4, c);
610             offset += 4;
611
612             c = tvb_get_ntohl(tvb, offset);
613             proto_tree_add_uint(tt,hf_isns_heartbeat_counter, tvb, offset, 4, c);
614             offset += 4;
615             break;
616         }
617         /* Responses */
618         case ISNS_FUNC_RSP_DEVATTRREG:
619         case ISNS_FUNC_RSP_DEVATTRQRY:
620         case ISNS_FUNC_RSP_DEVGETNEXT:
621         case ISNS_FUNC_RSP_DEREGDEV:
622         case ISNS_FUNC_RSP_SCNREG:
623         case ISNS_FUNC_RSP_SCNDEREG:
624         case ISNS_FUNC_RSP_SCNEVENT:
625         case ISNS_FUNC_RSP_SCN:
626         case ISNS_FUNC_RSP_DDREG:
627         case ISNS_FUNC_RSP_DDDEREG:
628         case ISNS_FUNC_RSP_DDSREG:
629         case ISNS_FUNC_RSP_DDSDEREG:
630         case ISNS_FUNC_RSP_ESI:
631         {
632             /* Get the Error message of the response */
633             guint32 errorcode =  tvb_get_ntohl(tvb, offset);
634             proto_tree_add_uint(tt,hf_isns_resp_errorcode, tvb, offset, 4, errorcode);
635             offset += 4;
636             /* Messages */
637         }
638         case ISNS_FUNC_DEVATTRREG:
639         case ISNS_FUNC_DEVATTRQRY:
640         case ISNS_FUNC_DEVGETNEXT: 
641         case ISNS_FUNC_DEREGDEV:
642         case ISNS_FUNC_SCNREG:
643         case ISNS_FUNC_SCNDEREG:
644         case ISNS_FUNC_SCNEVENT:
645         case ISNS_FUNC_SCN:
646         case ISNS_FUNC_DDREG:
647         case ISNS_FUNC_DDDEREG:
648         case ISNS_FUNC_DDSREG:
649         case ISNS_FUNC_DDSDEREG:
650         case ISNS_FUNC_ESI:
651         default:
652             while( offset < packet_len )
653             {
654                 offset += AddAttribute(tvb,tt,offset);
655             }
656         }
657     }
658
659     return tvb_length(tvb);
660 }
661
662 static guint
663 AddAttribute(tvbuff_t *tvb, proto_tree *tree,guint offset )
664 {
665     proto_tree *tt;
666     proto_item *attribute;
667     guint32 tag,len;
668
669     /* Get the Tag */
670     tag = tvb_get_ntohl(tvb, offset);
671
672     /* Now the Length */
673     len = tvb_get_ntohl(tvb, offset + 4);
674     
675     attribute = proto_tree_add_item(tree, hf_isns_attr_payload, tvb, offset , len + 8 , FALSE);
676     tt = proto_item_add_subtree(attribute, ett_isns_payload);
677     proto_tree_add_uint(tt,hf_isns_attr_tag, tvb, offset, 4, tag);
678     proto_tree_add_uint(tt,hf_isns_attr_len, tvb, offset + 4, 4, len);
679 #if 0    
680     fprintf(stderr,"packet_len=%i\noffset=%i\n(len <= (packet_len - (offset + 8))))=%i\n",
681             packet_len,
682             offset,
683             (len <= (packet_len - (offset + 8))));
684
685     if( (len > 0) && (len <= (packet_len - (offset + 8))))
686     {
687         fprintf(stderr,"Payload");
688         
689     }
690 #endif
691
692     if( len == 0 ) return 8;
693
694     switch( tag )
695     {
696     case ISNS_ATTR_TAG_DELIMITER:                    goto none;
697     case ISNS_ATTR_TAG_ENTITY_IDENTIFIER:            goto string;
698     case ISNS_ATTR_TAG_ENTITY_PROTOCOL:              goto entity_protocol;
699     case ISNS_ATTR_TAG_MGMT_IP_ADDRESS:              goto ip;
700     case ISNS_ATTR_TAG_TIMESTAMP:                    goto seconds;
701     case ISNS_ATTR_TAG_PROTOCOL_VERSION_RANGE:       goto version_range;
702     case ISNS_ATTR_TAG_REGISTRATION_PERIOD:          goto seconds;
703     case ISNS_ATTR_TAG_ENTITY_INDEX:                 goto identifier32;
704     case ISNS_ATTR_TAG_ENTITY_NEXT_INDEX:            goto identifier32;
705     case ISNS_ATTR_TAG_ENTITY_ISAKMP_PHASE_1:        goto will_not_decode;
706     case ISNS_ATTR_TAG_ENTITY_CERTIFICATE:           goto will_not_decode;
707     case ISNS_ATTR_TAG_PORTAL_IP_ADDRESS:            goto ip;
708     case ISNS_ATTR_TAG_PORTAL_PORT:                  goto port;
709     case ISNS_ATTR_TAG_PORTAL_SYMBOLIC_NAME:         goto string;
710     case ISNS_ATTR_TAG_ESI_INTERVAL:                 goto seconds;
711     case ISNS_ATTR_TAG_ESI_PORT:                     goto port;
712     case ISNS_ATTR_TAG_PORTAL_GROUP:                 goto portal_group;
713     case ISNS_ATTR_TAG_PORTAL_INDEX:                 goto identifier32;
714     case ISNS_ATTR_TAG_SCN_PORT:                     goto port;
715     case ISNS_ATTR_TAG_PORTAL_NEXT_INDEX:            goto identifier32;
716     case ISNS_ATTR_TAG_PORTAL_SECURITY_BITMAP:       goto portal_security_bitmap;
717     case ISNS_ATTR_TAG_PORTAL_ISAKMP_PHASE_1:        goto will_not_decode;
718     case ISNS_ATTR_TAG_PORTAL_ISAKMP_PHASE_2:        goto will_not_decode;
719     case ISNS_ATTR_TAG_PORTAL_CERTIFICATE:           goto will_not_decode;
720     case ISNS_ATTR_TAG_ISCSI_NAME:                   goto string;
721     case ISNS_ATTR_TAG_ISCSI_NODE_TYPE:              goto iscsi_node_type;
722     case ISNS_ATTR_TAG_ISCSI_ALIAS:                  goto string;
723     case ISNS_ATTR_TAG_ISCSI_SCN_BITMAP:             goto iscsi_scn_bitmap;
724     case ISNS_ATTR_TAG_ISCSI_NODE_INDEX:             goto identifier32;
725     case ISNS_ATTR_TAG_WWNN_TOKEN:                   goto identifier64;
726     case ISNS_ATTR_TAG_ISCSI_NODE_NEXT_INDEX:        goto identifier32;
727     case ISNS_ATTR_TAG_ISCSI_AUTH_METHOD:            goto string;
728     case ISNS_ATTR_TAG_ISCSI_NODE_CERTIFICATE:       goto will_not_decode;
729     case ISNS_ATTR_TAG_FC_PORT_NAME_WWPN:            goto identifier64;
730     case ISNS_ATTR_TAG_PORT_ID:                      goto identifier24;
731     case ISNS_ATTR_TAG_FC_PORT_TYPE:                 goto will_not_decode;
732         /*
733           0x0000           Unidentified/Null Entry 
734           0x0001           Fibre Channel N_Port 
735           0x0002           Fibre Channel NL_Port 
736           0x0003           Fibre Channel F/NL_Port 
737           0x0081           Fibre Channel F_Port 
738           0x0082           Fibre Channel FL_Port 
739           0x0084           Fibre Channel E_Port 
740           0xFF12           iFCP Port 
741         */
742     case ISNS_ATTR_TAG_SYMBOLIC_PORT_NAME:           goto string;
743     case ISNS_ATTR_TAG_FABRIC_PORT_NAME:             goto identifier64;
744     case ISNS_ATTR_TAG_HARD_ADDRESS:                 goto identifier24;
745     case ISNS_ATTR_TAG_PORT_IP_ADDRESS:              goto ip;
746     case ISNS_ATTR_TAG_CLASS_OF_SERVICE:             goto will_not_decode;
747         /*
748           bit 29             Fibre Channel Class 2 Supported
749           bit 28             Fibre Channel Class 3 Supported
750         */
751     case ISNS_ATTR_TAG_FC4_TYPES:                    goto will_not_decode;
752     case ISNS_ATTR_TAG_FC4_DESCRIPTOR:               goto string;
753     case ISNS_ATTR_TAG_FC4_FEATURES:                 goto will_not_decode;
754     case ISNS_ATTR_TAG_IFCP_SCN_BITMAP:              goto will_not_decode;
755         /*
756           bit 24              INITIATOR AND SELF INFORMATION ONLY
757           bit 25              TARGET AND SELF INFORMATION ONLY
758           bit 26              MANAGEMENT REGISTRATION/SCN
759           bit 27              OBJECT REMOVED
760           bit 28              OBJECT ADDED
761           bit 29              OBJECT UPDATED
762           bit 30              DD/DDS MEMBER REMOVED (Mgmt Reg/SCN only)
763           bit 31 (Lsb)        DD/DDS MEMBER ADDED (Mgmt Reg/SCN only)
764         */
765     case ISNS_ATTR_TAG_PORT_ROLE:                    goto will_not_decode;
766         /*
767           bit 29              Control 
768           bit 30              FCP Initiator 
769           bit 31 (Lsb)        FCP Target 
770         */
771     case ISNS_ATTR_TAG_PERMANENT_PORT_NAME:          goto identifier64;
772     case ISNS_ATTR_TAG_PORT_CERTIFICATE:             goto will_not_decode;
773     case ISNS_ATTR_TAG_FC4_TYPE_CODE:                goto will_not_decode;
774         /* 8bit type code in byte0 */
775     case ISNS_ATTR_TAG_FC_NODE_NAME_WWNN:            goto identifier64;
776     case ISNS_ATTR_TAG_SYMBOLIC_NODE_NAME:           goto string;
777     case ISNS_ATTR_TAG_NODE_IP_ADDRESS:              goto ip;
778     case ISNS_ATTR_TAG_NODE_IPA:                     goto identifier64;
779     case ISNS_ATTR_TAG_NODE_CERTIFICATE:             goto will_not_decode;
780     case ISNS_ATTR_TAG_PROXY_ISCSI_NAME:             goto string;
781     case ISNS_ATTR_TAG_SWITCH_NAME:                  goto identifier64;
782     case ISNS_ATTR_TAG_PREFERRED_ID:                 goto identifier32;
783     case ISNS_ATTR_TAG_ASSIGNED_ID:                  goto identifier32;
784     case ISNS_ATTR_TAG_VIRTUAL_FABRIC_ID:            goto string;
785     case ISNS_ATTR_TAG_VENDOR_OUI:                   goto identifier32;
786     case ISNS_ATTR_TAG_DD_SET_ID:                    goto identifier32;
787     case ISNS_ATTR_TAG_DD_SET_SYMBOLIC_NAME:         goto string;
788     case ISNS_ATTR_TAG_DD_SET_STATUS:                goto dd_set_status;
789     case ISNS_ATTR_TAG_DD_SET_NEXT_ID:               goto identifier32;
790     case ISNS_ATTR_TAG_DD_ID:                        goto identifier32;
791     case ISNS_ATTR_TAG_DD_SYMBOLIC_NAME:             goto string;
792     case ISNS_ATTR_TAG_DD_MEMBER_ISCSI_INDEX:        goto identifier32;
793     case ISNS_ATTR_TAG_DD_MEMBER_ISCSI_NAME:         goto string;
794     case ISNS_ATTR_TAG_DD_MEMBER_IFCP_NODE:          goto identifier32;
795     case ISNS_ATTR_TAG_DD_MEMBER_PORTAL_INDEX:       goto identifier32;
796     case ISNS_ATTR_TAG_DD_MEMBER_PORTAL_IP_ADDRESS:  goto ip;
797     case ISNS_ATTR_TAG_DD_MEMBER_PORTAL_PORT:        goto port;
798     case ISNS_ATTR_TAG_DD_FEATURES:                  goto dd_features;
799     case ISNS_ATTR_TAG_DD_ID_NEXT_ID:                goto identifier32;
800     }
801
802 identifier24:
803     /* 24-bit identifier (least significant 3 bytes) */
804 identifier64:
805 none:
806     goto end;
807
808 identifier32:
809     {
810         guint32 i = tvb_get_ntohl(tvb, offset + 8);
811         proto_tree_add_uint(tt, hf_isns_attr_index, tvb, offset + 8, len, i);
812         goto end;
813     }
814     goto end;
815
816 dd_features:
817     /*
818       31 (Lsb)      Boot List Enabled (1)/Boot List Disabled (0) 
819     */
820     goto end;
821
822 dd_set_status:
823     /*
824       31 (Lsb)      DDS Enabled (1) / DDS Disabled (0) 
825     */
826     goto end;
827
828 iscsi_scn_bitmap:
829     /*
830       24              INITIATOR AND SELF INFORMATION ONLY 
831       25              TARGET AND SELF INFORMATION ONLY  
832       26              MANAGEMENT REGISTRATION/SCN 
833       27              OBJECT REMOVED 
834       28              OBJECT ADDED 
835       29              OBJECT UPDATED 
836       30              DD/DDS MEMBER REMOVED (Mgmt Reg/SCN only) 
837       31 (Lsb)        DD/DDS MEMBER ADDED (Mgmt Reg/SCN only) 
838     */
839     {
840         /*FLAGS*/
841         proto_item *tscn_bitmap;
842         proto_item *scn_bitmap_item;
843         guint32 scn_bitmap = tvb_get_ntohl(tvb, offset + 8);
844
845         scn_bitmap_item = proto_tree_add_uint(tt, hf_isns_scn_bitmap, tvb, offset+8, 4, scn_bitmap);
846         tscn_bitmap = proto_item_add_subtree(scn_bitmap_item, ett_scn_bitmap);
847
848         proto_tree_add_boolean(tt, hf_isns_scn_bitmap_initiator_and_self_information_only, tvb, offset+8, 4, scn_bitmap);
849         proto_tree_add_boolean(tt, hf_isns_scn_bitmap_target_and_self_information_only,    tvb, offset+8, 4, scn_bitmap);
850         proto_tree_add_boolean(tt, hf_isns_scn_bitmap_management_registration_scn,         tvb, offset+8, 4, scn_bitmap);
851         proto_tree_add_boolean(tt, hf_isns_scn_bitmap_object_removed,                      tvb, offset+8, 4, scn_bitmap);
852         proto_tree_add_boolean(tt, hf_isns_scn_bitmap_object_added,                        tvb, offset+8, 4, scn_bitmap);
853         proto_tree_add_boolean(tt, hf_isns_scn_bitmap_object_updated,                      tvb, offset+8, 4, scn_bitmap);
854         proto_tree_add_boolean(tt, hf_isns_scn_bitmap_dd_dds_member_removed,               tvb, offset+8, 4, scn_bitmap);
855         proto_tree_add_boolean(tt, hf_isns_scn_bitmap_dd_dds_member_added,                 tvb, offset+8, 4, scn_bitmap);
856     }
857     goto end;
858
859 iscsi_node_type:
860     {
861         proto_item *tisnt;
862         proto_item *isnt_item;
863         guint32 isnt = tvb_get_ntohl(tvb, offset + 8);
864
865         isnt_item = proto_tree_add_uint(tt, hf_isns_isnt, tvb, offset+8, 4, isnt);
866         tisnt = proto_item_add_subtree(isnt_item, ett_isns_isnt);
867
868         proto_tree_add_boolean(tisnt, hf_isns_isnt_control,   tvb, offset+8, 4, isnt);
869         proto_tree_add_boolean(tisnt, hf_isns_isnt_initiator, tvb, offset+8, 4, isnt);
870         proto_tree_add_boolean(tisnt, hf_isns_isnt_target,    tvb, offset+8, 4, isnt);
871     }
872     goto end;
873
874 portal_security_bitmap:
875     {
876         proto_item *tpsb;
877         proto_item *psb_item;
878         guint32 psb = tvb_get_ntohl(tvb, offset + 8);
879
880         psb_item = proto_tree_add_uint(tt, hf_isns_psb, tvb, offset+8, 4, psb);
881         tpsb = proto_item_add_subtree(psb_item, ett_isns_psb);
882
883         proto_tree_add_boolean(tpsb, hf_isns_psb_tunnel_mode,     tvb, offset+8, 4, psb);
884         proto_tree_add_boolean(tpsb, hf_isns_psb_transport_mode,  tvb, offset+8, 4, psb);
885         proto_tree_add_boolean(tpsb, hf_isns_psb_pfs,             tvb, offset+8, 4, psb);
886         proto_tree_add_boolean(tpsb, hf_isns_psb_aggressive_mode, tvb, offset+8, 4, psb);
887         proto_tree_add_boolean(tpsb, hf_isns_psb_main_mode,       tvb, offset+8, 4, psb);
888         proto_tree_add_boolean(tpsb, hf_isns_psb_ike_ipsec,       tvb, offset+8, 4, psb);
889         proto_tree_add_boolean(tpsb, hf_isns_psb_bitmap,          tvb, offset+8, 4, psb);
890     }
891     goto end;
892
893 portal_group:
894     /*
895       16bit portal group identifier - least significant
896     */
897     goto end;
898
899 version_range:
900     /*
901       16bit minimum protocol supported - least significant
902       16bit maximum protocol supported - most significant
903     */
904     goto end;
905
906 entity_protocol:
907     proto_tree_add_uint(tt,hf_isns_entity_protocol, tvb, offset + 8, len, tag);
908     goto end;
909
910 string:
911     proto_tree_add_item(tt,hf_isns_attr_string, tvb, offset + 8, len, FALSE);
912     goto end;
913
914 ip:
915     proto_tree_add_item(tt,hf_isns_attr_ipaddr, tvb, offset + 8, len, FALSE);
916     goto end;
917
918 seconds:
919     {
920         guint32 i = tvb_get_ntohl(tvb, offset + 8);
921
922         proto_tree_add_uint(tt, hf_isns_attr_seconds, tvb, offset + 8, 4, i);
923         goto end;
924     }
925
926 port:
927     {
928         proto_item *tport;
929         proto_item *port_item;
930         guint32 port = tvb_get_ntohl(tvb, offset + 8);
931         guint16 port_type = tvb_get_ntohl(tvb, offset + 8);
932         guint16 port_port = tvb_get_ntohl(tvb, offset + 10);
933
934         port_item = proto_tree_add_uint(tt, hf_isns_port, tvb, offset+8, 4, port);
935         tport = proto_item_add_subtree(port_item, ett_isns_port);
936
937         proto_tree_add_boolean(tport, hf_isns_port_type, tvb, offset+8, 2, port_port);
938         proto_tree_add_uint(tport,hf_isns_port_port, tvb, offset+10, 2, port_type);
939     }
940     goto end;
941
942 will_not_decode:
943     goto end;
944
945 end:
946
947
948
949     
950     /* move on the offset to next attribute */
951     
952
953     return (8 + len);    
954 }
955
956
957
958 /* Register the protocol with Ethereal */
959
960 /* this format is require because a script is used to build the C function
961    that calls all the protocol registration.
962 */
963
964 void proto_register_isns(void)
965 {
966     /* Setup list of header fields  See Section 1.6.1 for details*/
967     static hf_register_info hf[] = {
968         /* The Header Stuff */
969         { &hf_isns_version,
970           { "iSNSP Version","isns.PVer",
971             FT_UINT16, BASE_DEC, NULL, 0,          
972             "iSNS Protocol Version" ,HFILL}
973         },
974         { &hf_isns_function_id,
975           { "Function ID","isns.functionid",        
976             FT_UINT16, BASE_DEC,VALS(&isns_function_ids),0,          
977             "iSNS Function ID" ,HFILL}
978         },
979         { &hf_isns_pdu_length,
980           { "PDU Length","isns.pdulength",
981             FT_UINT16, BASE_DEC,NULL,0,
982             "iSNS PDU Length" ,HFILL}
983         },
984
985         { &hf_isns_flags,
986           { "Flags","isns.flags",
987             FT_UINT16, BASE_HEX,NULL,0,
988             "iSNS Flags" ,HFILL}
989         },
990         { &hf_isns_client,
991           { "Client    ","isns.flags.client",
992             FT_BOOLEAN, 16, TFS(&isns_flag_client), 0x8000, /* bit 16 */
993             "iSNS Client" ,HFILL}
994         },
995         { &hf_isns_server,
996           { "Server    ","isns.flags.server",
997             FT_BOOLEAN, 16, TFS(&isns_flag_server), 0x4000, /* bit 17 */
998             "iSNS Server" ,HFILL}
999         },
1000         { &hf_isns_replace,
1001           { "Replace   ","isns.flags.replace",
1002             FT_BOOLEAN, 16, TFS(&isns_flag_replace), 0x1000, /* bit 19 */
1003             "iSNS Replace" ,HFILL}
1004         },
1005         { &hf_isns_last_pdu,
1006           { "Last PDU  ","isns.flags.lastpdu",
1007             FT_BOOLEAN, 16, TFS(&isns_flag_last_pdu), 0x0800, /* bit 20 */
1008             "iSNS Last PDU" ,HFILL}
1009         },
1010         { &hf_isns_first_pdu,
1011           { "First PDU ","isns.flags.firstpdu",
1012             FT_BOOLEAN, 16, TFS(&isns_flag_first_pdu), 0x0400, /* bit 21 */
1013             "iSNS First PDU",HFILL }
1014         },
1015
1016
1017         { &hf_isns_transaction_id,
1018           { "Transaction ID","isns.transactionid",
1019             FT_UINT16, BASE_DEC,NULL,0,
1020             "iSNS transaction ID" ,HFILL}
1021         },
1022         { &hf_isns_sequence_id,
1023           { "Sequence ID","isns.sequenceid",
1024             FT_UINT16, BASE_DEC,NULL,0,
1025             "iSNS sequence ID" ,HFILL}
1026         },
1027
1028         { &hf_isns_entity_protocol,
1029           { "Entity Protocol","isns.entity_protocol",
1030             FT_UINT32, BASE_DEC,TFS(isns_entity_protocol),0,
1031             "iSNS Entity Protocol" ,HFILL}
1032         },
1033         /* The Payload stuff */
1034
1035         { &hf_isns_port,
1036           { "Port","isns.port",
1037             FT_UINT32, BASE_HEX, NULL, 0,
1038             "Port", HFILL }
1039         },
1040
1041         { &hf_isns_port_type,
1042           { "Port Type","isns.port.port_type",
1043             FT_BOOLEAN, 16, TFS(&isns_port_type), 0x01, /* bit 15 (or bit 1 of a 16bit word) */
1044             "Port Type",HFILL }
1045         },
1046
1047         { &hf_isns_port_port,
1048           { "Port","isns.port.port",
1049             FT_UINT16, BASE_DEC, NULL, 0,
1050             "Port", HFILL }
1051         },
1052
1053
1054         { &hf_isns_psb,
1055           { "Portal Security Bitmap","isns.psb",
1056             FT_UINT32, BASE_HEX, NULL, 0,
1057             "Portal Security Bitmap", HFILL }
1058         },
1059         { &hf_isns_psb_tunnel_mode,
1060           { "Tunnel Mode     ","isns.psb.tunnel",
1061             FT_BOOLEAN, 32, TFS(&isns_psb_tunnel_mode),     0x0040, /* bit 25 */
1062             "Tunnel Mode Preferred",HFILL }
1063         },
1064         { &hf_isns_psb_transport_mode,
1065           { "Transport Mode  ","isns.psb.transport",
1066             FT_BOOLEAN, 32, TFS(&isns_psb_transport_mode),  0x0020, /* bit 26 */
1067             "Transport Mode",HFILL }
1068         },
1069         { &hf_isns_psb_pfs,
1070           { "PFS             ","isns.psb.pfs",
1071             FT_BOOLEAN, 32, TFS(&isns_psb_pfs),        0x0010, /* bit 27 */
1072             "PFS",HFILL }
1073         },
1074         { &hf_isns_psb_aggressive_mode,
1075           { "Aggressive Mode ","isns.psb.aggressive_mode",
1076             FT_BOOLEAN, 32, TFS(&isns_psb_aggressive_mode), 0x0008, /* bit 28 */
1077             "Aggressive Mode",HFILL }
1078         },
1079         { &hf_isns_psb_main_mode,
1080           { "Main Mode       ","isns.psb.main_mode",
1081             FT_BOOLEAN, 32, TFS(&isns_psb_main_mode),  0x0004, /* bit 29 */
1082             "Main Mode",HFILL }
1083         },
1084         { &hf_isns_psb_ike_ipsec,
1085           { "IKE/IPSec       ","isns.psb.ike_ipsec",
1086             FT_BOOLEAN, 32, TFS(&isns_psb_ike_ipsec),  0x0002, /* bit 30 */
1087             "IKE/IPSec",HFILL }
1088         },
1089         { &hf_isns_psb_bitmap,
1090           { "Bitmap          ","isns.psb.bitmap",
1091             FT_BOOLEAN, 32, TFS(&isns_psb_bitmap),     0x0001, /* bit 31 */
1092             "Bitmap",HFILL }
1093         },
1094
1095
1096
1097         { &hf_isns_scn_bitmap,
1098           { "iSCSI SCN Bitmap","isns.scn_bitmap",
1099             FT_UINT32, BASE_HEX, NULL, 0,
1100             "iSCSI SCN Bitmap", HFILL }
1101         },
1102         { &hf_isns_scn_bitmap_initiator_and_self_information_only,
1103           { "Initiator And Self Information Only","isns.scn_bitmap.initiator_and_self_information_only",
1104             FT_BOOLEAN, 32, TFS(&isns_scn_bitmap_initiator_and_self_information_only),     0x0080, /* bit 24 */
1105             "Initiator And Self Information Only",HFILL }
1106         },
1107         { &hf_isns_scn_bitmap_target_and_self_information_only,
1108           { "Target And Self Information Only","isns.scn_bitmap.target_and_self_information_only",
1109             FT_BOOLEAN, 32, TFS(&isns_scn_bitmap_target_and_self_information_only),     0x0040, /* bit 25 */
1110             "Target And Self Information Only",HFILL }
1111         },
1112         { &hf_isns_scn_bitmap_management_registration_scn,
1113           { "Management Registration/SCN","isns.scn_bitmap.management_registration_scn",
1114             FT_BOOLEAN, 32, TFS(&isns_scn_bitmap_management_registration_scn),     0x0020, /* bit 26 */
1115             "Management Registration/SCN",HFILL }
1116         },
1117         { &hf_isns_scn_bitmap_object_removed,
1118           { "Object Removed","isns.scn_bitmap.object_removed",
1119             FT_BOOLEAN, 32, TFS(&isns_scn_bitmap_object_removed),     0x0010, /* bit 27 */
1120             "Object Removed",HFILL }
1121         },
1122         { &hf_isns_scn_bitmap_object_added,
1123           { "Object Added","isns.scn_bitmap.object_added",
1124             FT_BOOLEAN, 32, TFS(&isns_scn_bitmap_object_added),     0x0008, /* bit 28 */
1125             "Object Added",HFILL }
1126         },
1127         { &hf_isns_scn_bitmap_object_updated,
1128           { "Object Updated","isns.scn_bitmap.object_updated",
1129             FT_BOOLEAN, 32, TFS(&isns_scn_bitmap_object_updated),     0x0004, /* bit 29 */
1130             "Object Updated",HFILL }
1131         },
1132         { &hf_isns_scn_bitmap_dd_dds_member_removed,
1133           { "DD/DDS Member Removed (Mgmt Reg/SCN only)","isns.scn_bitmap.dd_dds_member_removed",
1134             FT_BOOLEAN, 32, TFS(&isns_scn_bitmap_dd_dds_member_removed),     0x0002, /* bit 30 */
1135             "DD/DDS Member Removed (Mgmt Reg/SCN only)",HFILL }
1136         },
1137         { &hf_isns_scn_bitmap_dd_dds_member_added,
1138           { "DD/DDS Member Added (Mgmt Reg/SCN only)","isns.scn_bitmap.dd_dds_member_added",
1139             FT_BOOLEAN, 32, TFS(&isns_scn_bitmap_dd_dds_member_added),     0x0001, /* bit 31 */
1140             "DD/DDS Member Added (Mgmt Reg/SCN only)",HFILL }
1141         },
1142
1143
1144         { &hf_isns_isnt,
1145           { "iSCSI Node Type","isns.isnt",
1146             FT_UINT32, BASE_HEX, NULL, 0,
1147             "iSCSI Node Type", HFILL }
1148         },
1149         { &hf_isns_isnt_control,
1150           { "Control   ","isns.isnt.control",
1151             FT_BOOLEAN, 32, TFS(&isns_isnt_control),  0x0004, /* bit 29 */
1152             "Control",HFILL }
1153         },
1154         { &hf_isns_isnt_initiator,
1155           { "Initiator ","isns.isnt.initiator",
1156             FT_BOOLEAN, 32, TFS(&isns_isnt_initiator),  0x0002, /* bit 30 */
1157             "Initiator",HFILL }
1158         },
1159         { &hf_isns_isnt_target,
1160           { "Target    ","isns.isnt.target",
1161             FT_BOOLEAN, 32, TFS(&isns_isnt_target),     0x0001, /* bit 31 */
1162             "Target",HFILL }
1163         },
1164
1165
1166         { &hf_isns_resp_errorcode,
1167           { "ErrorCode","isns.errorcode",
1168             FT_UINT32, BASE_DEC,TFS(isns_errorcode),0,
1169             "iSNS Response Error Code" ,HFILL}
1170         },
1171
1172         { &hf_isns_attr_tag,
1173           { "Attribute Tag","isns.attr.tag",
1174             FT_UINT32, BASE_DEC,TFS(isns_attribute_tags),0,
1175             "iSNS Attribute Tag" ,HFILL}
1176         },
1177
1178         { &hf_isns_attr_len,
1179           { "Attribute Length","isns.attr.len",
1180             FT_UINT32, BASE_DEC,NULL,0,
1181             "iSNS Attribute Length" ,HFILL}
1182         },
1183
1184         { &hf_isns_attr_payload,
1185           { "Attribute Payload","isns.attr.payload",
1186             FT_BYTES, BASE_HEX,NULL,0,
1187             "iSNS Attribute Payload" ,HFILL}
1188         },
1189
1190         { &hf_isns_heartbeat_ipv6_addr,
1191           { "Heartbeat Address (ipv6)","isns.heartbeat.address",
1192             FT_IPv6, BASE_NONE, NULL, 0x0,
1193             "Server IPv6 Address", HFILL }},
1194
1195         { &hf_isns_heartbeat_tcp_port,
1196           { "Heartbeat TCP Port","isns.heartbeat.tcpport",
1197             FT_UINT16, BASE_DEC, NULL, 0x0,
1198             "Server TCP Port", HFILL }},
1199
1200         { &hf_isns_heartbeat_udp_port,
1201           { "Heartbeat UDP Port","isns.heartbeat.udpport",
1202             FT_UINT16, BASE_DEC, NULL, 0x0,
1203             "Server UDP Port", HFILL }},
1204
1205
1206         { &hf_isns_heartbeat_interval,
1207           { "Heartbeat Interval (secs)","isns.heartbeat.interval",
1208             FT_UINT32, BASE_DEC, NULL, 0x0,
1209             "Server Heartbeat interval", HFILL }},
1210
1211         { &hf_isns_heartbeat_counter,
1212           { "Heartbeat counter","isns.heartbeat.counter",
1213             FT_UINT32, BASE_DEC, NULL, 0x0,
1214             "Server Heartbeat Counter", HFILL }},
1215
1216         { &hf_isns_attr_string,
1217           { "Attribute String","isns.attrstring",
1218             FT_STRING, BASE_NONE, NULL, 0x0,
1219             "String", HFILL }},
1220
1221         { &hf_isns_attr_ipaddr,
1222           { "Attribute IP Address","isns.ipv4",
1223             FT_IPv6, BASE_NONE, NULL, 0x0,
1224             "IPv6 Address", HFILL }},
1225
1226         { &hf_isns_attr_index,
1227           { "Index","isns.index",
1228             FT_UINT32, BASE_DEC, NULL, 0x0,
1229             "Index", HFILL }},
1230
1231         { &hf_isns_attr_seconds,
1232           { "Seconds","isns.seconds",
1233             FT_UINT32, BASE_DEC, NULL, 0x0,
1234             "Seconds", HFILL }},
1235
1236         
1237         { &hf_isns_payload,
1238           { "Payload", "isns.payload",
1239             FT_BYTES, BASE_HEX, NULL, 0,
1240             "Payload" ,HFILL}
1241         }
1242     };
1243
1244 /* Setup protocol subtree array */
1245     static gint *ett[] = {
1246         &ett_isns,
1247         &ett_isns_flags,
1248         &ett_isns_payload,
1249         &ett_isns_port,
1250         &ett_isns_psb,
1251         &ett_isns_isnt,
1252         &ett_scn_bitmap
1253     };
1254
1255 /* Register the protocol name and description */
1256     proto_isns = proto_register_protocol("iSNS",
1257                                          "iSNS", "isns");
1258
1259     proto_register_field_array(proto_isns, hf, array_length(hf));
1260
1261     proto_register_subtree_array(ett, array_length(ett));
1262
1263 }
1264
1265 /* If this dissector uses sub-dissector registration add a registration routine.
1266    This format is required because a script is used to find these routines and
1267    create the code that calls these routines.
1268 */
1269
1270 void
1271 proto_reg_handoff_isns(void)
1272 {
1273     dissector_handle_t isns_handle;
1274     isns_handle = new_create_dissector_handle(dissect_isns,proto_isns);
1275     dissector_add("udp.port",ISNS_UDP_PORT,isns_handle);
1276     dissector_add("tcp.port",ISNS_TCP_PORT,isns_handle);
1277 }