forked from osmocom/wireshark
From Flavio Poletti: handle 3GPP QoS in RADIUS messages.
svn path=/trunk/; revision=6091
This commit is contained in:
parent
7a12fa1373
commit
320621f2f4
1
AUTHORS
1
AUTHORS
|
@ -1386,6 +1386,7 @@ Brian Bruns <camber[AT]ais.org> {
|
|||
Flavio Poletti <Flavio.Poletti[AT]tei.ericsson.se> {
|
||||
Fix bug in decoding of maximum uplink and downlink rate in GTP
|
||||
v1
|
||||
Handle 3GPP QoS in RADIUS messages
|
||||
}
|
||||
|
||||
Marcus Haebler <haeblerm[AT]yahoo.com> {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Makefile.am
|
||||
# Automake file for Ethereal
|
||||
#
|
||||
# $Id: Makefile.am,v 1.457 2002/08/21 21:00:32 tpot Exp $
|
||||
# $Id: Makefile.am,v 1.458 2002/08/26 20:22:23 guy Exp $
|
||||
#
|
||||
# Ethereal - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -464,6 +464,7 @@ noinst_HEADERS = \
|
|||
packet-giop.h \
|
||||
packet-gnutella.h \
|
||||
packet-gssapi.h \
|
||||
packet-gtp.h \
|
||||
packet-hclnfsd.h \
|
||||
packet-http.h \
|
||||
packet-ieee80211.h \
|
||||
|
|
196
packet-gtp.c
196
packet-gtp.c
|
@ -4,7 +4,7 @@
|
|||
* Copyright 2001, Michal Melerowicz <michal.melerowicz@nokia.com>
|
||||
* Nicolas Balkota <balkota@mac.com>
|
||||
*
|
||||
* $Id: packet-gtp.c,v 1.34 2002/08/24 10:12:42 guy Exp $
|
||||
* $Id: packet-gtp.c,v 1.35 2002/08/26 20:22:27 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -36,9 +36,11 @@
|
|||
#include <glib.h>
|
||||
|
||||
#include <epan/packet.h>
|
||||
#include "packet-gtp.h"
|
||||
#include "packet-ipv6.h"
|
||||
#include "ppptypes.h"
|
||||
#include "prefs.h"
|
||||
|
||||
/*
|
||||
* All data related to GTP v0 (GPRS) uses "gtpv0" or "GTPv0",
|
||||
* all data related to GTP v1 (UMTS) uses "gtpv1" or "GTPv1",
|
||||
|
@ -3330,10 +3332,42 @@ decode_gtp_mm_cntxt(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tre
|
|||
return 3+length;
|
||||
}
|
||||
|
||||
/* Function to extract the value of an hexadecimal octet. Only the lower
|
||||
* nybble will be non-zero in the output.
|
||||
* */
|
||||
static guint8 hex2dec (guint8 x)
|
||||
{
|
||||
if ((x >= 'a') && (x <= 'f'))
|
||||
x = x - 'a' + 10;
|
||||
else if ((x >= 'A') && (x <= 'F'))
|
||||
x = x - 'A' + 10;
|
||||
else if ((x >= '0') && (x <= '9'))
|
||||
x = x - '0';
|
||||
else
|
||||
x = 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Wrapper function to add UTF-8 decoding for QoS attributes in
|
||||
* RADIUS messages.
|
||||
* */
|
||||
static guint8 wrapped_tvb_get_guint8(
|
||||
tvbuff_t *tvb, int offset, int type)
|
||||
{
|
||||
if (type == 2)
|
||||
return (hex2dec(tvb_get_guint8(tvb, offset)) << 4
|
||||
| hex2dec(tvb_get_guint8(tvb, offset + 1)));
|
||||
else
|
||||
return tvb_get_guint8(tvb, offset);
|
||||
}
|
||||
|
||||
/* WARNING : actually length is coded on 2 octets for QoS profile but on 1 octet for PDP Context!
|
||||
* so type means length of length :-)
|
||||
*
|
||||
* WARNING :) type does not mean length of length any more... see below for
|
||||
* type = 3!
|
||||
*/
|
||||
static int
|
||||
int
|
||||
decode_qos_umts(tvbuff_t *tvb, int offset, proto_tree *tree, gchar* qos_str, guint8 type) {
|
||||
|
||||
guint8 length;
|
||||
|
@ -3348,6 +3382,18 @@ decode_qos_umts(tvbuff_t *tvb, int offset, proto_tree *tree, gchar* qos_str, gui
|
|||
proto_item *te;
|
||||
int mss, mu, md, gu, gd;
|
||||
|
||||
/* Will keep if the input is UTF-8 encoded (as in RADIUS messages).
|
||||
* If 1, input is *not* UTF-8 encoded (i.e. each input octet corresponds
|
||||
* to one byte to be dissected).
|
||||
* If 2, input is UTF-8 encoded (i.e. each *couple* of input octets
|
||||
* corresponds to one byte to be dissected)
|
||||
* */
|
||||
guint8 utf8_type = 1;
|
||||
|
||||
/* In RADIUS messages the QoS has a version field of two octets prepended.
|
||||
* */
|
||||
guint8 version_buffer[2];
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
length = tvb_get_guint8 (tvb, offset);
|
||||
|
@ -3362,6 +3408,23 @@ decode_qos_umts(tvbuff_t *tvb, int offset, proto_tree *tree, gchar* qos_str, gui
|
|||
proto_tree_add_text (ext_tree_qos, tvb, offset + 1, 2, "Length: %u", length);
|
||||
type++; /* +1 because of first 0x86 byte for UMTS QoS */
|
||||
break;
|
||||
case 3:
|
||||
/* For QoS inside RADIUS Client messages from GGSN */
|
||||
utf8_type = 2;
|
||||
|
||||
/* The field in the RADIUS message starts one byte before :) */
|
||||
length = tvb_get_guint8 (tvb, offset);
|
||||
te = proto_tree_add_text (tree, tvb, offset - 1, length, "%s", qos_str);
|
||||
|
||||
ext_tree_qos = proto_item_add_subtree (te, ett_gtp_qos);
|
||||
version_buffer[0] = tvb_get_guint8(tvb, offset + 1);
|
||||
version_buffer[1] = tvb_get_guint8(tvb, offset + 2);
|
||||
proto_tree_add_text (ext_tree_qos, tvb, offset + 1, 2, "Version: %c%c", version_buffer[0], version_buffer[1]);
|
||||
|
||||
/* Now, we modify offset here and in order to use type later
|
||||
* effectively.*/
|
||||
offset--;
|
||||
break;
|
||||
default:
|
||||
/* XXX - what should we do with the length here? */
|
||||
length = 0;
|
||||
|
@ -3371,108 +3434,129 @@ decode_qos_umts(tvbuff_t *tvb, int offset, proto_tree *tree, gchar* qos_str, gui
|
|||
|
||||
offset += type;
|
||||
|
||||
/* In RADIUS messages there is no allocation-retention priority
|
||||
* so I don't need to wrap the following call to tvb_get_guint8
|
||||
* */
|
||||
al_ret_priority = tvb_get_guint8 (tvb, offset);
|
||||
|
||||
spare1 = tvb_get_guint8(tvb, offset+1) & 0xC0;
|
||||
delay = tvb_get_guint8(tvb, offset+1) & 0x38;
|
||||
reliability = tvb_get_guint8(tvb, offset+1) & 0x07;
|
||||
peak = tvb_get_guint8(tvb, offset+2) & 0xF0;
|
||||
spare2 = tvb_get_guint8(tvb, offset+2) & 0x08;
|
||||
precedence = tvb_get_guint8(tvb, offset+2) & 0x07;
|
||||
spare3 = tvb_get_guint8(tvb, offset+3) & 0xE0;
|
||||
mean = tvb_get_guint8(tvb, offset+3) & 0x1F;
|
||||
/* All calls are wrapped to take into account the possibility that the
|
||||
* input is UTF-8 encoded. If utf8_type is equal to 1, the final value
|
||||
* of the offset will be the same as in the previous version of this
|
||||
* dissector, and the wrapped function will serve as a dumb wrapper;
|
||||
* otherwise, if utf_8_type is 2, the offset is correctly shifted by
|
||||
* two bytes for needed shift, and the wrapped function will unencode
|
||||
* two values from the input.
|
||||
* */
|
||||
spare1 = wrapped_tvb_get_guint8(tvb, offset+(1 - 1) * utf8_type + 1, utf8_type) & 0xC0;
|
||||
delay = wrapped_tvb_get_guint8(tvb, offset+(1 - 1) * utf8_type + 1, utf8_type) & 0x38;
|
||||
reliability = wrapped_tvb_get_guint8(tvb, offset+(1 - 1) * utf8_type + 1, utf8_type) & 0x07;
|
||||
peak = wrapped_tvb_get_guint8(tvb, offset+(2 - 1) * utf8_type + 1, utf8_type) & 0xF0;
|
||||
spare2 = wrapped_tvb_get_guint8(tvb, offset+(2 - 1) * utf8_type + 1, utf8_type) & 0x08;
|
||||
precedence = wrapped_tvb_get_guint8(tvb, offset+(2 - 1) * utf8_type + 1, utf8_type) & 0x07;
|
||||
spare3 = wrapped_tvb_get_guint8(tvb, offset+(3 - 1) * utf8_type + 1, utf8_type) & 0xE0;
|
||||
mean = wrapped_tvb_get_guint8(tvb, offset+(3 - 1) * utf8_type + 1, utf8_type) & 0x1F;
|
||||
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_al_ret_priority, tvb, offset, 1, al_ret_priority);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_spare1, tvb, offset+1, 1, spare1);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_delay, tvb, offset+1, 1, delay);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_reliability, tvb, offset+1, 1, reliability);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_peak, tvb, offset+2, 1, peak);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_spare2, tvb, offset+2, 1, spare2);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_precedence, tvb, offset+2, 1, precedence);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_spare3, tvb, offset+3, 1, spare3);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_mean, tvb, offset+3, 1, mean);
|
||||
/* In RADIUS messages there is no allocation-retention priority */
|
||||
if (type != 3)
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_al_ret_priority, tvb, offset, 1, al_ret_priority);
|
||||
|
||||
/* All additions must take care of the fact that QoS fields in RADIUS
|
||||
* messages are UTF-8 encoded, so we have to use the same trick as above.
|
||||
* */
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_spare1, tvb, offset+(1 - 1) * utf8_type + 1, utf8_type, spare1);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_delay, tvb, offset+(1 - 1) * utf8_type + 1, utf8_type, delay);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_reliability, tvb, offset+(1 - 1) * utf8_type + 1, utf8_type, reliability);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_peak, tvb, offset+(2 - 1) * utf8_type + 1, utf8_type, peak);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_spare2, tvb, offset+(2 - 1) * utf8_type + 1, utf8_type, spare2);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_precedence, tvb, offset+(2 - 1) * utf8_type + 1, utf8_type, precedence);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_spare3, tvb, offset+(3 - 1) * utf8_type + 1, utf8_type, spare3);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_mean, tvb, offset+(3 - 1) * utf8_type + 1, utf8_type, mean);
|
||||
|
||||
if (length > 4) {
|
||||
|
||||
traf_class = tvb_get_guint8(tvb, offset+4) & 0xE0;
|
||||
del_order = tvb_get_guint8(tvb, offset+4) & 0x18;
|
||||
del_err_sdu = tvb_get_guint8(tvb, offset+4) & 0x07;
|
||||
max_sdu_size = tvb_get_guint8(tvb, offset+5);
|
||||
max_ul = tvb_get_guint8(tvb, offset+6);
|
||||
max_dl = tvb_get_guint8(tvb, offset+7);
|
||||
res_ber = tvb_get_guint8(tvb, offset+8) & 0xF0;
|
||||
sdu_err_ratio = tvb_get_guint8(tvb, offset+8) & 0x0F;
|
||||
trans_delay = tvb_get_guint8(tvb, offset+9) & 0xFC;
|
||||
traf_handl_prio = tvb_get_guint8(tvb, offset+9) & 0x03;
|
||||
guar_ul = tvb_get_guint8(tvb, offset+10);
|
||||
guar_dl = tvb_get_guint8(tvb, offset+11);
|
||||
/* See above for the need of wrapping
|
||||
* */
|
||||
traf_class = wrapped_tvb_get_guint8(tvb, offset+(4 - 1) * utf8_type + 1, utf8_type) & 0xE0;
|
||||
del_order = wrapped_tvb_get_guint8(tvb, offset+(4 - 1) * utf8_type + 1, utf8_type) & 0x18;
|
||||
del_err_sdu = wrapped_tvb_get_guint8(tvb, offset+(4 - 1) * utf8_type + 1, utf8_type) & 0x07;
|
||||
max_sdu_size = wrapped_tvb_get_guint8(tvb, offset+(5 - 1) * utf8_type + 1, utf8_type);
|
||||
max_ul = wrapped_tvb_get_guint8(tvb, offset+(6 - 1) * utf8_type + 1, utf8_type);
|
||||
max_dl = wrapped_tvb_get_guint8(tvb, offset+(7 - 1) * utf8_type + 1, utf8_type);
|
||||
res_ber = wrapped_tvb_get_guint8(tvb, offset+(8 - 1) * utf8_type + 1, utf8_type) & 0xF0;
|
||||
sdu_err_ratio = wrapped_tvb_get_guint8(tvb, offset+(8 - 1) * utf8_type + 1, utf8_type) & 0x0F;
|
||||
trans_delay = wrapped_tvb_get_guint8(tvb, offset+(9 - 1) * utf8_type + 1, utf8_type) & 0xFC;
|
||||
traf_handl_prio = wrapped_tvb_get_guint8(tvb, offset+(9 - 1) * utf8_type + 1, utf8_type) & 0x03;
|
||||
guar_ul = wrapped_tvb_get_guint8(tvb, offset+(10 - 1) * utf8_type + 1, utf8_type);
|
||||
guar_dl = wrapped_tvb_get_guint8(tvb, offset+(11 - 1) * utf8_type + 1, utf8_type);
|
||||
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_traf_class, tvb, offset+4, 1, traf_class);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_del_order, tvb, offset+4, 1, del_order);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_del_err_sdu, tvb, offset+4, 1, del_err_sdu);
|
||||
/* See above comments for the changes
|
||||
* */
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_traf_class, tvb, offset+(4 - 1) * utf8_type + 1, utf8_type, traf_class);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_del_order, tvb, offset+(4 - 1) * utf8_type + 1, utf8_type, del_order);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_del_err_sdu, tvb, offset+(4 - 1) * utf8_type + 1, utf8_type, del_err_sdu);
|
||||
if (max_sdu_size == 0 || max_sdu_size > 150)
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_max_sdu_size, tvb, offset+5, 1, max_sdu_size);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_max_sdu_size, tvb, offset+(5 - 1) * utf8_type + 1, utf8_type, max_sdu_size);
|
||||
if (max_sdu_size > 0 && max_sdu_size <= 150) {
|
||||
mss = max_sdu_size*10;
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_sdu_size, tvb, offset+5, 1, mss, "Maximum SDU size : %u octets", mss);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_sdu_size, tvb, offset+(5 - 1) * utf8_type + 1, utf8_type, mss, "Maximum SDU size : %u octets", mss);
|
||||
}
|
||||
|
||||
if(max_ul == 0 || max_ul == 255)
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_max_ul, tvb, offset+6, 1, max_ul);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_max_ul, tvb, offset+(6 - 1) * utf8_type + 1, utf8_type, max_ul);
|
||||
if(max_ul > 0 && max_ul <= 63)
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_ul, tvb, offset+6, 1, max_ul, "Maximum bit rate for uplink : %u kbps", max_ul);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_ul, tvb, offset+(6 - 1) * utf8_type + 1, utf8_type, max_ul, "Maximum bit rate for uplink : %u kbps", max_ul);
|
||||
if(max_ul > 63 && max_ul <=127) {
|
||||
mu = 64 + ( max_ul - 64 ) * 8;
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_ul, tvb, offset+6, 1, mu, "Maximum bit rate for uplink : %u kbps", mu);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_ul, tvb, offset+(6 - 1) * utf8_type + 1, utf8_type, mu, "Maximum bit rate for uplink : %u kbps", mu);
|
||||
}
|
||||
|
||||
if(max_ul > 127 && max_ul <=254) {
|
||||
mu = 576 + ( max_ul - 128 ) * 64;
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_ul, tvb, offset+6, 1, mu, "Maximum bit rate for uplink : %u kbps", mu);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_ul, tvb, offset+(6 - 1) * utf8_type + 1, utf8_type, mu, "Maximum bit rate for uplink : %u kbps", mu);
|
||||
}
|
||||
|
||||
if(max_dl == 0 || max_dl == 255)
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_max_dl, tvb, offset+7, 1, max_dl);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_max_dl, tvb, offset+(7 - 1) * utf8_type + 1, utf8_type, max_dl);
|
||||
if(max_dl > 0 && max_dl <= 63)
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_dl, tvb, offset+7, 1, max_dl, "Maximum bit rate for downlink : %u kbps", max_dl);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_dl, tvb, offset+(7 - 1) * utf8_type + 1, utf8_type, max_dl, "Maximum bit rate for downlink : %u kbps", max_dl);
|
||||
if(max_dl > 63 && max_dl <=127) {
|
||||
md = 64 + ( max_dl - 64 ) * 8;
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_dl, tvb, offset+7, 1, md, "Maximum bit rate for downlink : %u kbps", md);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_dl, tvb, offset+(7 - 1) * utf8_type + 1, utf8_type, md, "Maximum bit rate for downlink : %u kbps", md);
|
||||
}
|
||||
if(max_dl > 127 && max_dl <=254) {
|
||||
md = 576 + ( max_dl - 128 ) * 64;
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_dl, tvb, offset+7, 1, md, "Maximum bit rate for downlink : %u kbps", md);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_max_dl, tvb, offset+(7 - 1) * utf8_type + 1, utf8_type, md, "Maximum bit rate for downlink : %u kbps", md);
|
||||
}
|
||||
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_res_ber, tvb, offset+8, 1, res_ber);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_sdu_err_ratio, tvb, offset+8, 1, sdu_err_ratio);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_trans_delay, tvb, offset+9, 1, trans_delay);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_traf_handl_prio, tvb, offset+9, 1, traf_handl_prio);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_res_ber, tvb, offset+(8 - 1) * utf8_type + 1, utf8_type, res_ber);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_sdu_err_ratio, tvb, offset+(8 - 1) * utf8_type + 1, utf8_type, sdu_err_ratio);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_trans_delay, tvb, offset+(9 - 1) * utf8_type + 1, utf8_type, trans_delay);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_traf_handl_prio, tvb, offset+(9 - 1) * utf8_type + 1, utf8_type, traf_handl_prio);
|
||||
|
||||
if(guar_ul == 0 || guar_ul == 255)
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_guar_ul, tvb, offset+10, 1, guar_ul);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_guar_ul, tvb, offset+(10 - 1) * utf8_type + 1, utf8_type, guar_ul);
|
||||
if(guar_ul > 0 && guar_ul <= 63)
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_ul, tvb, offset+10, 1, guar_ul, "Guaranteed bit rate for uplink : %u kbps", guar_ul);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_ul, tvb, offset+(10 - 1) * utf8_type + 1, utf8_type, guar_ul, "Guaranteed bit rate for uplink : %u kbps", guar_ul);
|
||||
if(guar_ul > 63 && guar_ul <=127) {
|
||||
gu = 64 + ( guar_ul - 64 ) * 8;
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_ul, tvb, offset+10, 1, gu, "Guaranteed bit rate for uplink : %u kbps", gu);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_ul, tvb, offset+(10 - 1) * utf8_type + 1, utf8_type, gu, "Guaranteed bit rate for uplink : %u kbps", gu);
|
||||
}
|
||||
if(guar_ul > 127 && guar_ul <=254) {
|
||||
gu = 576 + ( guar_ul - 128 ) * 64;
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_ul, tvb, offset+10, 1, gu, "Guaranteed bit rate for uplink : %u kbps", gu);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_ul, tvb, offset+(10 - 1) * utf8_type + 1, utf8_type, gu, "Guaranteed bit rate for uplink : %u kbps", gu);
|
||||
}
|
||||
|
||||
if(guar_dl == 0 || guar_dl == 255)
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_guar_dl, tvb, offset+11, 1, guar_dl);
|
||||
proto_tree_add_uint(ext_tree_qos, hf_gtpv1_qos_guar_dl, tvb, offset+(11 - 1) * utf8_type + 1, utf8_type, guar_dl);
|
||||
if(guar_dl > 0 && guar_dl <= 63)
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_dl, tvb, offset+11, 1, guar_dl, "Guaranteed bit rate for downlink : %u kbps", guar_dl);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_dl, tvb, offset+(11 - 1) * utf8_type + 1, utf8_type, guar_dl, "Guaranteed bit rate for downlink : %u kbps", guar_dl);
|
||||
if(guar_dl > 63 && guar_dl <=127) {
|
||||
gd = 64 + ( guar_dl - 64 ) * 8;
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_dl, tvb, offset+11, 1, gd, "Guaranteed bit rate for downlink : %u kbps", gd);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_dl, tvb, offset+(11 - 1) * utf8_type + 1, utf8_type, gd, "Guaranteed bit rate for downlink : %u kbps", gd);
|
||||
}
|
||||
if(guar_dl > 127 && guar_dl <=254) {
|
||||
gd = 576 + ( guar_dl - 128 ) * 64;
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_dl, tvb, offset+11, 1, gd, "Guaranteed bit rate for downlink : %u kbps", gd);
|
||||
proto_tree_add_uint_format(ext_tree_qos, hf_gtpv1_qos_guar_dl, tvb, offset+(11 - 1) * utf8_type + 1, utf8_type, gd, "Guaranteed bit rate for downlink : %u kbps", gd);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* packet-gtp.h
|
||||
*
|
||||
* Declarations of exported routines from GTP dissector
|
||||
* Copyright 2001, Michal Melerowicz <michal.melerowicz@nokia.com>
|
||||
* Nicolas Balkota <balkota@mac.com>
|
||||
*
|
||||
* $Id: packet-gtp.h,v 1.1 2002/08/26 20:22:31 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PACKET_GTP_H__
|
||||
#define __PACKET_GTP_H__
|
||||
|
||||
extern int decode_qos_umts(
|
||||
tvbuff_t *tvb, int offset, proto_tree *tree, gchar* qos_str, guint8 type);
|
||||
|
||||
#endif
|
121
packet-radius.c
121
packet-radius.c
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* RFC 2865, RFC 2866, RFC 2867, RFC 2868, RFC 2869
|
||||
*
|
||||
* $Id: packet-radius.c,v 1.66 2002/08/02 23:35:57 jmayer Exp $
|
||||
* $Id: packet-radius.c,v 1.67 2002/08/26 20:22:31 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -39,6 +39,7 @@
|
|||
#include <epan/resolv.h>
|
||||
|
||||
#include "packet-q931.h"
|
||||
#include "packet-gtp.h"
|
||||
|
||||
static int proto_radius = -1;
|
||||
static int hf_radius_length = -1;
|
||||
|
@ -212,7 +213,9 @@ enum {
|
|||
|
||||
SHASTA_USER_PRIVILEGE,
|
||||
|
||||
COLUMBIA_UNIVERSITY_SIP_METHOD
|
||||
COLUMBIA_UNIVERSITY_SIP_METHOD,
|
||||
|
||||
THE3GPP_QOS
|
||||
};
|
||||
|
||||
static value_string radius_vals[] =
|
||||
|
@ -278,6 +281,7 @@ static value_string radius_vals[] =
|
|||
#define VENDOR_QUINTUM 6618
|
||||
#define VENDOR_COLUBRIS 8744
|
||||
#define VENDOR_COLUMBIA_UNIVERSITY 11862
|
||||
#define VENDOR_THE3GPP 10415
|
||||
|
||||
static value_string radius_vendor_specific_vendors[] =
|
||||
{
|
||||
|
@ -302,6 +306,7 @@ static value_string radius_vendor_specific_vendors[] =
|
|||
{VENDOR_QUINTUM, "Quintum"},
|
||||
{VENDOR_COLUBRIS, "Colubris"},
|
||||
{VENDOR_COLUMBIA_UNIVERSITY, "Columbia University"},
|
||||
{VENDOR_THE3GPP, "3GPP"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
@ -2178,6 +2183,12 @@ static value_string radius_vendor_columbia_university_sip_method_vals[] =
|
|||
{0, NULL}
|
||||
};
|
||||
|
||||
static value_value_string radius_vendor_3gpp_attrib[] =
|
||||
{
|
||||
{5, THE3GPP_QOS, "QoS Profile"},
|
||||
{0, 0, NULL},
|
||||
};
|
||||
|
||||
static rd_vsa_table radius_vsa_table[] =
|
||||
{
|
||||
{VENDOR_ACC, radius_vendor_acc_attrib},
|
||||
|
@ -2200,6 +2211,7 @@ static rd_vsa_table radius_vsa_table[] =
|
|||
{VENDOR_QUINTUM, radius_vendor_quintum_attrib},
|
||||
{VENDOR_COLUBRIS, radius_vendor_colubris_attrib},
|
||||
{VENDOR_COLUMBIA_UNIVERSITY, radius_vendor_columbia_university_attrib},
|
||||
{VENDOR_THE3GPP, radius_vendor_3gpp_attrib},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
|
@ -2400,10 +2412,34 @@ static gchar *rdconvertinttostr(gchar *dest, int print_type, guint32 val)
|
|||
return dest;
|
||||
}
|
||||
|
||||
/* NOTE: This function's signature has been changed with the addition of the
|
||||
* tree parameter at the end.
|
||||
*
|
||||
* The function behaves EXACTLY AS BEFORE for parameters which do not
|
||||
* imply THE3GPP_QOS; I had to change the signature because the function
|
||||
* decode_qos_umts() wants to write on the protocol tree :)
|
||||
*
|
||||
* If you think it is better to DUPLICATE the code copying decode_qos_umts
|
||||
* here, and adapting it, feel free; only keep in mind that changes will have
|
||||
* to be doubled if any bug is found.
|
||||
*
|
||||
* At last, forgive me if I've messed up some indentation...
|
||||
* */
|
||||
static gchar *rd_value_to_str_2(gchar *dest, e_avphdr *avph, tvbuff_t *tvb,
|
||||
int offset, const value_value_string *vvs)
|
||||
int offset, const value_value_string *vvs, proto_tree *tree)
|
||||
{
|
||||
int print_type;
|
||||
|
||||
/* Variable to peek which will be the next print_type for VENDOR-SPECIFIC
|
||||
* RADIUS attributes
|
||||
* */
|
||||
int next_print_type;
|
||||
|
||||
/* Temporary variable to perform some trick on the cont variable; again, this
|
||||
* is needed only when THE3GPP_QOS in involved.
|
||||
* */
|
||||
gchar *tmp_punt;
|
||||
|
||||
gchar *cont;
|
||||
value_string *valstrarr;
|
||||
guint32 intval;
|
||||
|
@ -2492,19 +2528,34 @@ static gchar *rd_value_to_str_2(gchar *dest, e_avphdr *avph, tvbuff_t *tvb,
|
|||
vsa_rvt = get_vsa_table(intval);
|
||||
do
|
||||
{
|
||||
vsa_avph = (e_avphdr*)tvb_get_ptr(tvb, offset+vsa_len, avph->avp_length-vsa_len);
|
||||
cont = &cont[strlen(cont)+1];
|
||||
vsabuffer[vsa_index].str = cont;
|
||||
vsabuffer[vsa_index].offset = offset+vsa_len;
|
||||
vsabuffer[vsa_index].length = vsa_avph->avp_length;
|
||||
sprintf(cont, "t:%s(%u) l:%u, ",
|
||||
(vsa_rvt ? rd_match_strval_attrib(vsa_avph->avp_type, vsa_rvt->attrib) : "Unknown Type"),
|
||||
vsa_avph->avp_type, vsa_avph->avp_length);
|
||||
cont = &cont[strlen(cont)];
|
||||
rd_value_to_str_2(cont, vsa_avph, tvb, offset+vsa_len,
|
||||
(vsa_rvt ? vsa_rvt->attrib : NULL));
|
||||
vsa_len += vsa_avph->avp_length;
|
||||
vsa_index++;
|
||||
vsa_avph = (e_avphdr*)tvb_get_ptr(tvb, offset+vsa_len,
|
||||
avph->avp_length-vsa_len);
|
||||
if (vsa_rvt)
|
||||
next_print_type = match_numval(vsa_avph->avp_type,
|
||||
vsa_rvt->attrib);
|
||||
else
|
||||
next_print_type = 0;
|
||||
cont = &cont[strlen(cont)+1];
|
||||
tmp_punt = cont;
|
||||
vsabuffer[vsa_index].str = cont;
|
||||
vsabuffer[vsa_index].offset = offset+vsa_len;
|
||||
vsabuffer[vsa_index].length = vsa_avph->avp_length;
|
||||
sprintf(cont, "t:%s(%u) l:%u, ",
|
||||
(vsa_rvt
|
||||
? rd_match_strval_attrib(vsa_avph->avp_type,vsa_rvt->attrib)
|
||||
: "Unknown Type"),
|
||||
vsa_avph->avp_type, vsa_avph->avp_length);
|
||||
cont = &cont[strlen(cont)];
|
||||
rd_value_to_str_2(cont, vsa_avph, tvb, offset+vsa_len,
|
||||
(vsa_rvt ? vsa_rvt->attrib : NULL), tree);
|
||||
vsa_index++;
|
||||
vsa_len += vsa_avph->avp_length;
|
||||
if (next_print_type == THE3GPP_QOS )
|
||||
{
|
||||
cont = tmp_punt;
|
||||
vsa_index--;
|
||||
vsabuffer[vsa_index].str = 0;
|
||||
}
|
||||
} while (vsa_length > vsa_len && vsa_index < VSABUFFER);
|
||||
break;
|
||||
case( RADIUS_SERVICE_TYPE ):
|
||||
|
@ -2580,6 +2631,20 @@ static gchar *rd_value_to_str_2(gchar *dest, e_avphdr *avph, tvbuff_t *tvb,
|
|||
tvb_get_ntohs(tvb,offset+2),
|
||||
tvb_get_ntohs(tvb,offset+4));
|
||||
break;
|
||||
|
||||
case( THE3GPP_QOS ):
|
||||
/* Find the ponter to the already-built label
|
||||
* */
|
||||
tmp_punt = dest - 2;
|
||||
while (*tmp_punt)
|
||||
tmp_punt--;
|
||||
tmp_punt++;
|
||||
|
||||
/* Call decode_qos_umts from packet-gtp package
|
||||
* */
|
||||
decode_qos_umts(tvb, offset + 1, tree, tmp_punt, 3);
|
||||
break;
|
||||
|
||||
case( RADIUS_TIMESTAMP ):
|
||||
intval=tvb_get_ntohl(tvb,offset+2);
|
||||
rtimestamp=ctime((time_t*)&intval);
|
||||
|
@ -2609,13 +2674,18 @@ static gchar *rd_value_to_str_2(gchar *dest, e_avphdr *avph, tvbuff_t *tvb,
|
|||
return dest;
|
||||
}
|
||||
|
||||
static gchar *rd_value_to_str(e_avphdr *avph, tvbuff_t *tvb, int offset)
|
||||
/* NOTE: This function's signature has been changed with the addition of the
|
||||
* tree parameter at the end. This is needed for 3GPP QoS handling; previous
|
||||
* behaviour has not been changed.
|
||||
* */
|
||||
static gchar *rd_value_to_str(
|
||||
e_avphdr *avph, tvbuff_t *tvb, int offset, proto_tree *tree)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < VSABUFFER; i++)
|
||||
vsabuffer[i].str = NULL;
|
||||
rd_value_to_str_2(textbuffer, avph, tvb, offset, radius_attrib);
|
||||
rd_value_to_str_2(textbuffer, avph, tvb, offset, radius_attrib, tree);
|
||||
return textbuffer;
|
||||
}
|
||||
|
||||
|
@ -2777,15 +2847,18 @@ dissect_attribute_value_pairs(tvbuff_t *tvb, int offset,proto_tree *tree,
|
|||
proto_item *ti;
|
||||
proto_tree *vsa_tree = NULL;
|
||||
int i;
|
||||
valstr = rd_value_to_str(&avph, tvb, offset);
|
||||
/* We pre-add a text and a subtree to allow 3GPP QoS decoding
|
||||
* to access the protocol tree.
|
||||
* */
|
||||
ti = proto_tree_add_text(tree, tvb, offset, avph.avp_length,
|
||||
"t:%s(%u) l:%u, %s",
|
||||
avptpstrval, avph.avp_type, avph.avp_length,
|
||||
valstr);
|
||||
"t:%s(%u) l:%u",
|
||||
avptpstrval, avph.avp_type, avph.avp_length);
|
||||
vsa_tree = proto_item_add_subtree(ti, ett_radius_vsa);
|
||||
valstr = rd_value_to_str(&avph, tvb, offset, vsa_tree);
|
||||
proto_item_append_text(ti, ", %s", valstr);
|
||||
for (i = 0; vsabuffer[i].str && i < VSABUFFER; i++)
|
||||
proto_tree_add_text(vsa_tree, tvb, vsabuffer[i].offset, vsabuffer[i].length,
|
||||
"%s", vsabuffer[i].str);
|
||||
proto_tree_add_text(vsa_tree, tvb, vsabuffer[i].offset,
|
||||
vsabuffer[i].length, "%s", vsabuffer[i].str);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue