2 * Routines for Protocol for carrying Authentication for Network Access dissection
3 * Copyright 2006, Peter Racz <racz@ifi.unizh.ch>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
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.
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.
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.
25 /* This protocol implements PANA as of the IETF RFC 5191.
26 * (Note: This dissector was udated to reflect
27 * draft-ietf-pana-pana-18 which is a workitem of the ietf workgroup
28 * internet area/pana. I believe draft-18 then became RFC 5191).
37 #include <epan/packet.h>
38 #include <epan/value_string.h>
39 #include <epan/conversation.h>
40 #include <epan/emem.h>
43 #define PANA_UDP_PORT 3001
46 #define MIN_AVP_SIZE 8
48 #define PANA_FLAG_R 0x8000
49 #define PANA_FLAG_S 0x4000
50 #define PANA_FLAG_C 0x2000
51 #define PANA_FLAG_A 0x1000
52 #define PANA_FLAG_P 0x0800
53 #define PANA_FLAG_I 0x0400
55 #define PANA_FLAG_RES6 0x0200
56 #define PANA_FLAG_RES7 0x0100
57 #define PANA_FLAG_RES8 0x0080
58 #define PANA_FLAG_RES9 0x0040
59 #define PANA_FLAG_RES10 0x0020
60 #define PANA_FLAG_RES11 0x0010
61 #define PANA_FLAG_RES12 0x0008
62 #define PANA_FLAG_RES13 0x0004
63 #define PANA_FLAG_RES14 0x0002
64 #define PANA_FLAG_RES15 0x0001
66 #define PANA_FLAG_RESERVED 0x03ff
68 #define PANA_AVP_FLAG_V 0x8000
70 #define PANA_AVP_FLAG_RES1 0x4000
71 #define PANA_AVP_FLAG_RES2 0x2000
72 #define PANA_AVP_FLAG_RES3 0x1000
73 #define PANA_AVP_FLAG_RES4 0x0800
74 #define PANA_AVP_FLAG_RES5 0x0400
75 #define PANA_AVP_FLAG_RES6 0x0200
76 #define PANA_AVP_FLAG_RES7 0x0100
77 #define PANA_AVP_FLAG_RES8 0x0080
78 #define PANA_AVP_FLAG_RES9 0x0040
79 #define PANA_AVP_FLAG_RES10 0x0020
80 #define PANA_AVP_FLAG_RES11 0x0010
81 #define PANA_AVP_FLAG_RES12 0x0008
82 #define PANA_AVP_FLAG_RES13 0x0004
83 #define PANA_AVP_FLAG_RES14 0x0002
84 #define PANA_AVP_FLAG_RES15 0x0001
86 #define PANA_AVP_FLAG_RESERVED 0x7fff
88 static dissector_handle_t eap_handle;
90 /* Initialize the protocol and registered fields */
91 static int proto_pana = -1;
92 static int hf_pana_reserved_type = -1;
93 static int hf_pana_length_type = -1;
94 static int hf_pana_msg_type = -1;
95 static int hf_pana_session_id = -1;
96 static int hf_pana_seqnumber = -1;
97 static int hf_pana_response_in = -1;
98 static int hf_pana_response_to = -1;
99 static int hf_pana_response_time = -1;
101 static int hf_pana_flags = -1;
102 static int hf_pana_flag_r = -1;
103 static int hf_pana_flag_s = -1;
104 static int hf_pana_flag_c = -1;
105 static int hf_pana_flag_a = -1;
106 static int hf_pana_flag_p = -1;
107 static int hf_pana_flag_i = -1;
108 static int hf_pana_avp_code = -1;
109 static int hf_pana_avp_data_length = -1;
110 static int hf_pana_avp_flags = -1;
111 static int hf_pana_avp_flag_v = -1;
112 static int hf_pana_avp_reserved = -1;
113 static int hf_pana_avp_vendorid = -1;
115 static int hf_pana_avp_data_uint64 = -1;
116 static int hf_pana_avp_data_int64 = -1;
117 static int hf_pana_avp_data_uint32 = -1;
118 static int hf_pana_avp_data_int32 = -1;
119 static int hf_pana_avp_data_bytes = -1;
120 static int hf_pana_avp_data_string = -1;
121 static int hf_pana_avp_data_enumerated = -1;
123 #define MSG_TYPE_MAX 4
124 static const value_string msg_type_names[] = {
125 { 1, "PANA-Client-Initiation" },
127 { 3, "PANA-Termination" },
128 { 4, "PANA-Notification" },
132 static const value_string msg_subtype_names[] = {
133 { 0x0000, "Answer" },
134 { 0x8000, "Request" },
138 #define AVP_CODE_MAX 9
139 static const value_string avp_code_names[] = {
141 { 2, "EAP-Payload AVP" },
142 { 3, "Integrity-Algorithm AVP" },
145 { 6, "PRF-Algorithm AVP" },
146 { 7, "Result-Code" },
147 { 8, "Session-Lifetime" },
148 { 9, "Termination-Cause" },
152 static const value_string avp_resultcode_names[] = {
153 { 0, "PANA_SUCCESS" },
154 { 1, "PANA_AUTHENTICATION_REJECTED" },
155 { 2, "PANA_AUTHORIZATION_REJECTED" },
160 PANA_OCTET_STRING = 1,
175 static const value_string avp_type_names[]={
176 { PANA_OCTET_STRING, "OctetString" },
177 { PANA_INTEGER32, "Integer32" },
178 { PANA_INTEGER64, "Integer64" },
179 { PANA_UNSIGNED32, "Unsigned32" },
180 { PANA_UNSIGNED64, "Unsigned64" },
181 { PANA_FLOAT32, "Float32" },
182 { PANA_FLOAT64, "Float64" },
183 { PANA_FLOAT128, "Float128" },
184 { PANA_GROUPED, "Grouped" },
185 { PANA_ENUMERATED, "Enumerated" },
186 { PANA_UTF8STRING, "UTF8String" },
187 { PANA_EAP, "OctetString" },
188 { PANA_RESULT_CODE, "Unsigned32" },
193 /* Initialize the subtree pointers */
194 static gint ett_pana = -1;
195 static gint ett_pana_flags = -1;
196 static gint ett_pana_avp = -1;
197 static gint ett_pana_avp_info = -1;
198 static gint ett_pana_avp_flags = -1;
201 typedef struct _pana_transaction_t {
205 } pana_transaction_t;
207 typedef struct _pana_conv_info_t {
213 * Function for the PANA flags dissector.
216 dissect_pana_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint16 flags)
219 proto_item *flags_item;
220 proto_tree *flags_tree;
222 if(parent_tree == NULL)
225 flags_item = proto_tree_add_uint(parent_tree, hf_pana_flags, tvb,
227 flags_tree = proto_item_add_subtree(flags_item, ett_pana_flags);
229 proto_tree_add_boolean(flags_tree, hf_pana_flag_r, tvb, offset, 2, flags);
230 if (flags & PANA_FLAG_R)
231 proto_item_append_text(flags_item, ", Request");
233 proto_item_append_text(flags_item, ", Answer");
234 proto_tree_add_boolean(flags_tree, hf_pana_flag_s, tvb, offset, 2, flags);
235 if (flags & PANA_FLAG_S)
236 proto_item_append_text(flags_item, ", S flag set");
237 proto_tree_add_boolean(flags_tree, hf_pana_flag_c, tvb, offset, 2, flags);
238 if (flags & PANA_FLAG_C)
239 proto_item_append_text(flags_item, ", C flag set");
240 proto_tree_add_boolean(flags_tree, hf_pana_flag_a, tvb, offset, 2, flags);
241 if (flags & PANA_FLAG_A)
242 proto_item_append_text(flags_item, ", A flag set");
243 proto_tree_add_boolean(flags_tree, hf_pana_flag_p, tvb, offset, 2, flags);
244 if (flags & PANA_FLAG_P)
245 proto_item_append_text(flags_item, ", P flag set");
246 proto_tree_add_boolean(flags_tree, hf_pana_flag_i, tvb, offset, 2, flags);
247 if (flags & PANA_FLAG_I)
248 proto_item_append_text(flags_item, ", I flag set");
254 * Function for AVP flags dissector.
257 dissect_pana_avp_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint16 flags)
260 proto_item *avp_flags_item;
261 proto_tree *avp_flags_tree;
263 if(parent_tree == NULL) {
266 avp_flags_item = proto_tree_add_uint(parent_tree, hf_pana_avp_flags, tvb,
268 avp_flags_tree = proto_item_add_subtree(avp_flags_item, ett_pana_avp_flags);
270 proto_tree_add_boolean(avp_flags_tree, hf_pana_avp_flag_v, tvb, offset, 2, flags);
271 if (flags & PANA_AVP_FLAG_V) {
272 proto_item_append_text(avp_flags_item, ", Vendor");
279 * Map AVP code to AVP type
281 static pana_avp_types
282 pana_avp_get_type(guint16 avp_code, guint32 vendor_id)
287 case 1: return PANA_OCTET_STRING; /* AUTH AVP */
288 case 2: return PANA_EAP; /* EAP-Payload AVP */
289 case 3: return PANA_UNSIGNED32; /* Integrity-Algorithm AVP */
290 case 4: return PANA_INTEGER32; /* Key-Id AVP */
291 case 5: return PANA_OCTET_STRING; /* Nonce AVP */
292 case 6: return PANA_UNSIGNED32; /* PRF-Algorithm AVP */
293 case 7: return PANA_RESULT_CODE; /* Result-Code AVP */
294 case 8: return PANA_UNSIGNED32; /* Session-Lifetime AVP */
295 case 9: return PANA_ENUMERATED; /* Termination-Cause AVP */
296 default: return PANA_OCTET_STRING;
299 return PANA_OCTET_STRING;
306 * Function for AVP dissector.
309 dissect_avps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *avp_tree)
318 guint32 avp_hdr_length;
319 guint32 avp_data_length;
322 gint32 buffer_length;
326 proto_item *single_avp_item;
327 proto_tree *single_avp_tree;
328 proto_item *avp_eap_item;
329 proto_tree *avp_eap_tree;
332 buffer_length = tvb_reported_length(tvb);
334 /* Go through all AVPs */
335 while (buffer_length > 0) {
336 avp_code = tvb_get_ntohs(tvb, offset);
337 avp_flags = tvb_get_ntohs(tvb, offset + 2);
338 avp_data_length = tvb_get_ntohs(tvb, offset + 4);
340 /* Check AVP flags for vendor specific AVP */
341 if (avp_flags & PANA_AVP_FLAG_V) {
342 vendor_id = tvb_get_ntohl(tvb, 8);
349 avp_length = avp_hdr_length + avp_data_length;
352 avp_type = pana_avp_get_type(avp_code, vendor_id);
356 padding = (4 - (avp_length % 4)) % 4;
358 single_avp_item = proto_tree_add_text(avp_tree, tvb, offset, avp_length + padding,
359 "%s (%s) length: %d bytes (%d padded bytes)",
360 val_to_str(avp_code, avp_code_names, "Unknown (%d)"),
361 val_to_str(avp_type, avp_type_names, "Unknown (%d)"),
363 avp_length + padding);
365 single_avp_tree = proto_item_add_subtree(single_avp_item, ett_pana_avp_info);
368 proto_tree_add_uint_format_value(single_avp_tree, hf_pana_avp_code, tvb,
369 offset, 2, avp_code, "%s (%u)",
370 val_to_str(avp_code, avp_code_names, "Unknown (%d)"),
375 dissect_pana_avp_flags(single_avp_tree, tvb, offset, avp_flags);
379 proto_tree_add_item(single_avp_tree, hf_pana_avp_data_length, tvb, offset, 2, ENC_BIG_ENDIAN);
383 proto_tree_add_item(single_avp_tree, hf_pana_avp_reserved, tvb, offset, 2, ENC_NA);
386 if (avp_flags & PANA_AVP_FLAG_V) {
388 proto_tree_add_item(single_avp_tree, hf_pana_avp_vendorid, tvb, offset, 4, ENC_BIG_ENDIAN);
391 if (! (avp_flags & PANA_AVP_FLAG_V)) {
395 proto_item *avp_group_item;
396 proto_tree *avp_group_tree;
397 avp_group_item = proto_tree_add_text(single_avp_tree,
398 tvb, offset, avp_data_length,
400 avp_group_tree = proto_item_add_subtree(avp_group_item, ett_pana_avp);
401 group_tvb = tvb_new_subset(tvb, offset,
402 MIN(avp_data_length, tvb_reported_length(tvb)-offset),
404 dissect_avps(group_tvb, pinfo, avp_group_tree);
407 case PANA_UTF8STRING: {
409 data = tvb_get_ptr(tvb, offset, avp_data_length);
410 proto_tree_add_string_format(single_avp_tree, hf_pana_avp_data_string, tvb,
411 offset, avp_data_length, data,
413 avp_data_length, avp_data_length, data);
416 case PANA_OCTET_STRING: {
417 proto_tree_add_item(single_avp_tree, hf_pana_avp_data_bytes, tvb,
418 offset, avp_data_length, ENC_NA);
421 case PANA_INTEGER32: {
422 proto_tree_add_item(single_avp_tree, hf_pana_avp_data_int32, tvb,
423 offset, 4, ENC_BIG_ENDIAN);
426 case PANA_UNSIGNED32: {
427 proto_tree_add_item(single_avp_tree, hf_pana_avp_data_uint32, tvb,
428 offset, 4, ENC_BIG_ENDIAN);
431 case PANA_INTEGER64: {
432 proto_tree_add_item(single_avp_tree, hf_pana_avp_data_int64, tvb,
433 offset, 8, ENC_BIG_ENDIAN);
436 case PANA_UNSIGNED64: {
437 proto_tree_add_item(single_avp_tree, hf_pana_avp_data_uint64, tvb,
438 offset, 8, ENC_BIG_ENDIAN);
441 case PANA_ENUMERATED: {
442 proto_tree_add_item(single_avp_tree, hf_pana_avp_data_enumerated, tvb,
443 offset, 4, ENC_BIG_ENDIAN);
446 case PANA_RESULT_CODE: {
447 proto_tree_add_text(single_avp_tree, tvb, offset, avp_data_length,
449 tvb_get_ntohl(tvb, offset),
450 val_to_str(tvb_get_ntohs(tvb, offset), avp_code_names, "Unknown (%d)"));
454 avp_eap_item = proto_tree_add_text(single_avp_tree,
455 tvb, offset, avp_data_length,
456 "AVP Value (EAP packet)");
457 avp_eap_tree = proto_item_add_subtree(avp_eap_item, ett_pana_avp);
458 eap_tvb = tvb_new_subset(tvb, offset, avp_data_length, avp_data_length);
459 if (eap_handle != NULL) {
460 call_dissector(eap_handle, eap_tvb, pinfo, avp_eap_tree);
466 offset += avp_data_length + padding;
468 /* Update the buffer length */
469 buffer_length -= avp_length + padding;
476 * Function for the PANA PDU dissector.
479 dissect_pana_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
482 proto_tree *pana_tree = NULL;
488 conversation_t *conversation;
489 pana_conv_info_t *pana_info;
490 pana_transaction_t *pana_trans;
493 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PANA");
494 col_clear(pinfo->cinfo, COL_INFO);
496 /* Get message length, type and flags */
497 msg_length = tvb_get_ntohs(tvb, 2);
498 flags = tvb_get_ntohs(tvb, 4);
499 msg_type = tvb_get_ntohs(tvb, 6);
500 seq_num = tvb_get_ntohl(tvb, 12);
501 avp_length = msg_length - 16;
503 if (check_col(pinfo->cinfo, COL_INFO)) {
504 col_add_fstr(pinfo->cinfo, COL_INFO, "Type %s-%s",
505 val_to_str(msg_type, msg_type_names, "Unknown (%d)"),
506 val_to_str(flags & PANA_FLAG_R, msg_subtype_names, "Unknown (%d)"));
509 /* Make the protocol tree */
512 ti = proto_tree_add_item(tree, proto_pana, tvb, 0, -1, ENC_NA);
513 pana_tree = proto_item_add_subtree(ti, ett_pana);
518 * We need to track some state for this protocol on a per conversation
519 * basis so we can do neat things like request/response tracking
521 conversation = find_or_create_conversation(pinfo);
524 * Do we already have a state structure for this conv
526 pana_info = conversation_get_proto_data(conversation, proto_pana);
528 /* No. Attach that information to the conversation, and add
529 * it to the list of information structures.
531 pana_info = se_alloc(sizeof(pana_conv_info_t));
532 pana_info->pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "pana_pdus");
534 conversation_add_proto_data(conversation, proto_pana, pana_info);
537 if(!pinfo->fd->flags.visited){
538 if(flags&PANA_FLAG_R){
539 /* This is a request */
540 pana_trans=se_alloc(sizeof(pana_transaction_t));
541 pana_trans->req_frame=pinfo->fd->num;
542 pana_trans->rep_frame=0;
543 pana_trans->req_time=pinfo->fd->abs_ts;
544 se_tree_insert32(pana_info->pdus, seq_num, (void *)pana_trans);
546 pana_trans=se_tree_lookup32(pana_info->pdus, seq_num);
548 pana_trans->rep_frame=pinfo->fd->num;
552 pana_trans=se_tree_lookup32(pana_info->pdus, seq_num);
556 /* create a "fake" pana_trans structure */
557 pana_trans=ep_alloc(sizeof(pana_transaction_t));
558 pana_trans->req_frame=0;
559 pana_trans->rep_frame=0;
560 pana_trans->req_time=pinfo->fd->abs_ts;
563 /* print state tracking in the tree */
564 if(flags&PANA_FLAG_R){
565 /* This is a request */
566 if(pana_trans->rep_frame){
569 it=proto_tree_add_uint(pana_tree, hf_pana_response_in, tvb, 0, 0, pana_trans->rep_frame);
570 PROTO_ITEM_SET_GENERATED(it);
573 /* This is a reply */
574 if(pana_trans->req_frame){
578 it=proto_tree_add_uint(pana_tree, hf_pana_response_to, tvb, 0, 0, pana_trans->req_frame);
579 PROTO_ITEM_SET_GENERATED(it);
581 nstime_delta(&ns, &pinfo->fd->abs_ts, &pana_trans->req_time);
582 it=proto_tree_add_time(pana_tree, hf_pana_response_time, tvb, 0, 0, &ns);
583 PROTO_ITEM_SET_GENERATED(it);
588 proto_tree_add_item(pana_tree, hf_pana_reserved_type, tvb, offset, 2, ENC_NA);
592 proto_tree_add_item(pana_tree, hf_pana_length_type, tvb, offset, 2, ENC_BIG_ENDIAN);
596 dissect_pana_flags(pana_tree, tvb, offset, flags);
600 proto_tree_add_uint_format_value(pana_tree, hf_pana_msg_type, tvb,
601 offset, 2, msg_type, "%s-%s (%d)",
602 val_to_str(msg_type, msg_type_names, "Unknown (%d)"),
603 val_to_str(flags & PANA_FLAG_R, msg_subtype_names, "Unknown (%d)"),
608 proto_tree_add_item(pana_tree, hf_pana_session_id, tvb, offset, 4, ENC_BIG_ENDIAN);
611 /* Sequence Number */
612 proto_tree_add_item(pana_tree, hf_pana_seqnumber, tvb, offset, 4, ENC_BIG_ENDIAN);
618 proto_tree *avp_tree;
619 proto_item *avp_item;
620 avp_tvb = tvb_new_subset(tvb, offset, avp_length, avp_length);
621 avp_item = proto_tree_add_text(pana_tree, tvb, offset, avp_length, "Attribute Value Pairs");
622 avp_tree = proto_item_add_subtree(avp_item, ett_pana_avp);
624 if (avp_tree != NULL) {
625 dissect_avps(avp_tvb, pinfo, avp_tree);
633 * Function for the PANA dissector.
635 /* Called either as a "new-style" or a heuristic dissector */
637 dissect_pana(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
643 guint32 buffer_length;
647 /* Get actual buffer length */
648 buffer_length = tvb_length(tvb);
650 /* Check minimum buffer length */
651 if(buffer_length < 12) {
655 /* Get header fields */
656 pana_res = tvb_get_ntohs(tvb, 0);
657 msg_length = tvb_get_ntohs(tvb, 2);
658 flags = tvb_get_ntohs(tvb, 4);
659 msg_type = tvb_get_ntohs(tvb, 6);
661 /* Check minimum packet length */
662 if(msg_length < 16) {
666 /* Check the packet length */
667 if(msg_length != tvb_reported_length(tvb)) {
671 /* check that the reserved field is zero */
676 /* verify that none of the reserved bits are set */
677 if (flags & PANA_FLAG_RESERVED) {
681 /* verify that we recognize the message type */
682 if ((msg_type > MSG_TYPE_MAX) || (msg_type == 0)) {
686 avp_length = msg_length - 16;
688 /* For bug 1908: check the length of the first AVP, too */
690 if (avp_length != 0) {
693 guint32 first_avp_length;
696 if (avp_length < MIN_AVP_SIZE) {
700 /* Make sure no exceptions since we're just doing a preliminary heuristic check */
701 if ((avp_offset + 8) > buffer_length ) {
704 avp_code = tvb_get_ntohs(tvb, avp_offset);
705 if ((avp_code == 0) || (avp_code > AVP_CODE_MAX)) {
708 avp_flags = tvb_get_ntohs(tvb, avp_offset + 2);
709 if (avp_flags & PANA_AVP_FLAG_RESERVED) {
712 /* check whether is the V (vendor) flag on or not */
713 if (avp_flags & PANA_AVP_FLAG_V) {
714 first_avp_length = 12;
716 first_avp_length = 8;
719 first_avp_length += tvb_get_ntohs(tvb, avp_offset + 4);
721 if (first_avp_length > avp_length) {
726 dissect_pana_pdu(tvb, pinfo, tree);
728 return tvb_reported_length(tvb);
734 * Register the protocol with Wireshark
737 proto_register_pana(void)
740 static hf_register_info hf[] = {
741 { &hf_pana_response_in,
742 { "Response In", "pana.response_in",
743 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
744 "The response to this PANA request is in this frame", HFILL }
746 { &hf_pana_response_to,
747 { "Request In", "pana.response_to",
748 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
749 "This is a response to the PANA request in this frame", HFILL }
751 { &hf_pana_response_time,
752 { "Response Time", "pana.response_time",
753 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
754 "The time between the Call and the Reply", HFILL }
756 { &hf_pana_reserved_type,
757 { "PANA Reserved", "pana.reserved",
758 FT_BYTES, BASE_NONE, NULL, 0x0,
761 { &hf_pana_length_type,
762 { "PANA Message Length", "pana.length",
763 FT_UINT16, BASE_DEC, NULL, 0x0,
769 { "Flags", "pana.flags",
770 FT_UINT8, BASE_HEX, NULL, 0x0,
774 { "Request", "pana.flags.r",
775 FT_BOOLEAN, 16, TFS(&tfs_set_notset), PANA_FLAG_R,
779 { "Start", "pana.flags.s",
780 FT_BOOLEAN, 16, TFS(&tfs_set_notset), PANA_FLAG_S,
784 { "Complete","pana.flags.c",
785 FT_BOOLEAN, 16, TFS(&tfs_set_notset), PANA_FLAG_C,
789 { "Auth","pana.flags.a",
790 FT_BOOLEAN, 16, TFS(&tfs_set_notset), PANA_FLAG_A,
794 { "Ping","pana.flags.p",
795 FT_BOOLEAN, 16, TFS(&tfs_set_notset), PANA_FLAG_P,
799 { "IP Reconfig","pana.flags.i",
800 FT_BOOLEAN, 16, TFS(&tfs_set_notset), PANA_FLAG_I,
805 { "PANA Message Type", "pana.type",
806 FT_UINT16, BASE_DEC, NULL, 0x0,
809 { &hf_pana_session_id,
810 { "PANA Session ID", "pana.sid",
811 FT_UINT32, BASE_HEX, NULL, 0x0,
814 { &hf_pana_seqnumber,
815 { "PANA Sequence Number", "pana.seq",
816 FT_UINT32, BASE_HEX, NULL, 0x0,
822 { "AVP Code", "pana.avp.code",
823 FT_UINT16, BASE_DEC, NULL, 0x0,
826 { &hf_pana_avp_data_length,
827 { "AVP Data Length", "pana.avp.data_length",
828 FT_UINT16, BASE_DEC, NULL, 0x0,
831 { &hf_pana_avp_flags,
832 { "AVP Flags", "pana.avp.flags",
833 FT_UINT16, BASE_HEX, NULL, 0x0,
836 { &hf_pana_avp_flag_v,
837 { "Vendor", "pana.avp.flags.v",
838 FT_BOOLEAN, 16, TFS(&tfs_set_notset), PANA_AVP_FLAG_V,
841 { &hf_pana_avp_reserved,
842 { "AVP Reserved", "pana.avp.reserved",
843 FT_BYTES, BASE_NONE, NULL, 0x0,
846 { &hf_pana_avp_vendorid,
847 { "AVP Vendor ID", "pana.avp.vendorid",
848 FT_UINT32, BASE_HEX, NULL, 0x0,
853 { &hf_pana_avp_data_uint64,
854 { "Value", "pana.avp.data.uint64",
855 FT_UINT64, BASE_HEX, NULL, 0x0,
858 { &hf_pana_avp_data_int64,
859 { "Value", "pana.avp.data.int64",
860 FT_INT64, BASE_DEC, NULL, 0x0,
863 { &hf_pana_avp_data_uint32,
864 { "Value", "pana.avp.data.uint32",
865 FT_UINT32, BASE_HEX, NULL, 0x0,
868 { &hf_pana_avp_data_int32,
869 { "Value", "pana.avp.data.int32",
870 FT_INT32, BASE_DEC, NULL, 0x0,
873 { &hf_pana_avp_data_bytes,
874 { "Value", "pana.avp.data.bytes",
875 FT_BYTES, BASE_NONE, NULL, 0x0,
878 { &hf_pana_avp_data_string,
879 { "Value", "pana.avp.data.string",
880 FT_STRING, BASE_NONE, NULL, 0x0,
883 { &hf_pana_avp_data_enumerated,
884 { "Value", "pana.avp.data.enum",
885 FT_INT32, BASE_DEC, NULL, 0x0,
891 /* Setup protocol subtree array */
892 static gint *ett[] = {
900 /* Register the protocol name and description */
901 proto_pana = proto_register_protocol("Protocol for carrying Authentication for Network Access",
904 /* Required function calls to register the header fields and subtrees used */
905 proto_register_field_array(proto_pana, hf, array_length(hf));
906 proto_register_subtree_array(ett, array_length(ett));
912 proto_reg_handoff_pana(void)
915 dissector_handle_t pana_handle;
917 heur_dissector_add("udp", dissect_pana, proto_pana);
919 pana_handle = new_create_dissector_handle(dissect_pana, proto_pana);
920 dissector_add_handle("udp.port", pana_handle);
922 eap_handle = find_dissector("eap");
923 /** if(!eap_handle) fprintf(stderr,"PANA warning: EAP dissector not found\n"); **/