/****************************************************************************
** File: radius_3gpp2.c
**
** Author: Mike Borella
**
** Comments: Support for decoding 3GPP2 RADIUS attributes.
**
** $Id: radius_3gpp2.c,v 1.2 2001/11/29 00:20:30 mborella Exp $
**
** 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 Library 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.
**
*****************************************************************************/
#include "radius_3gpp2.h"
#include "iana.h"
/*
* 3GPP2 vendor specific attributes
*/
#define RADIUS_ATTR_3GPP2_IKEPSKREQUEST 1
#define RADIUS_ATTR_3GPP2_SECURITYLEVEL 2
#define RADIUS_ATTR_3GPP2_IKEPSK 3
#define RADIUS_ATTR_3GPP2_REVERSETUNNEL 4
#define RADIUS_ATTR_3GPP2_DIFFSERVCLASS 5
#define RADIUS_ATTR_3GPP2_HAADDR 7
#define RADIUS_ATTR_3GPP2_SERVINGPCFADDR 9
#define RADIUS_ATTR_3GPP2_BSID 10
#define RADIUS_ATTR_3GPP2_USERZONE 11
#define RADIUS_ATTR_3GPP2_FORWARDMUX 12
#define RADIUS_ATTR_3GPP2_REVERSEMUX 13
#define RADIUS_ATTR_3GPP2_MNHAKEY 14
#define RADIUS_ATTR_3GPP2_MNHAKEYREQUEST 15
#define RADIUS_ATTR_3GPP2_SERVICEOPTION 16
#define RADIUS_ATTR_3GPP2_FORTRAFFICTYPE 17
#define RADIUS_ATTR_3GPP2_REVTRAFFICTYPE 18
#define RADIUS_ATTR_3GPP2_FUNDFRAMESIZE 19
#define RADIUS_ATTR_3GPP2_FORFUNDRC 20
#define RADIUS_ATTR_3GPP2_REVFUNDRC 21
#define RADIUS_ATTR_3GPP2_IPTECHNOLOGY 22
#define RADIUS_ATTR_3GPP2_COMPTUNNELIND 23
#define RADIUS_ATTR_3GPP2_RELEASEINDICATOR 24
#define RADIUS_ATTR_3GPP2_BADPPPFRAMECOUNT 25
#define RADIUS_ATTR_3GPP2_NUMACTIVETRANS 30
#define RADIUS_ATTR_3GPP2_SDBOCTETCNTTERM 31
#define RADIUS_ATTR_3GPP2_SDBOCTETCNTORIG 32
#define RADIUS_ATTR_3GPP2_NUMSDBTERM 33
#define RADIUS_ATTR_3GPP2_NUMSDBORIG 34
#define RADIUS_ATTR_3GPP2_IPQOS 36
#define RADIUS_ATTR_3GPP2_AIRLINKQOS 39
#define RADIUS_ATTR_3GPP2_AIRLINKRECTYPE 40
#define RADIUS_ATTR_3GPP2_RPSESSIONID 41
#define RADIUS_ATTR_3GPP2_AIRLINKSEQNO 42
#define RADIUS_ATTR_3GPP2_NUMHDLCBYTESRECVD 43
#define RADIUS_ATTR_3GPP2_CORRELATIONID 44
#define RADIUS_ATTR_3GPP2_MOBILEORIGTERMIND 45
#define RADIUS_ATTR_3GPP2_INBMIPOCTETCNT 46
#define RADIUS_ATTR_3GPP2_OUTMIPOCTETCNT 47
#define RADIUS_ATTR_3GPP2_SESSIONCONTINUE 48
#define RADIUS_ATTR_3GPP2_ACTIVETIME 49
#define RADIUS_ATTR_3GPP2_DCCHFRAMEFORMAT 50
#define RADIUS_ATTR_3GPP2_SESSIONBEGIN 51
#define RADIUS_ATTR_3GPP2_SOURCEIPV6ADDR 52
#define RADIUS_ATTR_3GPP2_ESN 52
#define RADIUS_ATTR_3GPP2_IPV6PDSNADDR 53
#define RADIUS_ATTR_3GPP2_DNSUPDATEREQD 54
/*
* 3GPP2 vendor specific attribute map
*/
strmap_t radius_attr_3gpp2_map[] =
{
{ RADIUS_ATTR_3GPP2_IKEPSKREQUEST, "IKE preshared key request" },
{ RADIUS_ATTR_3GPP2_SECURITYLEVEL, "security level" },
{ RADIUS_ATTR_3GPP2_IKEPSK, "IKE preshared key" },
{ RADIUS_ATTR_3GPP2_REVERSETUNNEL, "reverse tunnel" },
{ RADIUS_ATTR_3GPP2_HAADDR, "home agent address" },
{ RADIUS_ATTR_3GPP2_SERVINGPCFADDR, "serving PCF address" },
{ RADIUS_ATTR_3GPP2_BSID, "BSID" },
{ RADIUS_ATTR_3GPP2_USERZONE, "user zone" },
{ RADIUS_ATTR_3GPP2_FORWARDMUX, "forward MUX option" },
{ RADIUS_ATTR_3GPP2_REVERSEMUX, "reverse MUX option" },
{ RADIUS_ATTR_3GPP2_MNHAKEY, "MN-HA key" },
{ RADIUS_ATTR_3GPP2_MNHAKEYREQUEST, "MN-HA key request" },
{ RADIUS_ATTR_3GPP2_SERVICEOPTION, "service option" },
{ RADIUS_ATTR_3GPP2_FORTRAFFICTYPE, "forward fundamental traffic type" },
{ RADIUS_ATTR_3GPP2_REVTRAFFICTYPE, "reverse fundamental traffic type" },
{ RADIUS_ATTR_3GPP2_FUNDFRAMESIZE, "fundamental frame size" },
{ RADIUS_ATTR_3GPP2_FORFUNDRC, "forward fundamental RC" },
{ RADIUS_ATTR_3GPP2_REVFUNDRC, "reverse fundamental RC" },
{ RADIUS_ATTR_3GPP2_IPTECHNOLOGY, "IP technology" },
{ RADIUS_ATTR_3GPP2_COMPTUNNELIND, "compulsory tunnel indicator" },
{ RADIUS_ATTR_3GPP2_RELEASEINDICATOR, "release indicator" },
{ RADIUS_ATTR_3GPP2_BADPPPFRAMECOUNT, "bad PPP frame count" },
{ RADIUS_ATTR_3GPP2_NUMACTIVETRANS, "number of active transitions" },
{ RADIUS_ATTR_3GPP2_SDBOCTETCNTTERM, "SDB octet count terminating" },
{ RADIUS_ATTR_3GPP2_SDBOCTETCNTORIG, "SDB octet count originating" },
{ RADIUS_ATTR_3GPP2_NUMSDBTERM, "number of SDBs terminating" },
{ RADIUS_ATTR_3GPP2_NUMSDBORIG, "number of SDBs originating" },
{ RADIUS_ATTR_3GPP2_IPQOS, "IP QoS" },
{ RADIUS_ATTR_3GPP2_AIRLINKQOS, "airlink QoS" },
{ RADIUS_ATTR_3GPP2_AIRLINKRECTYPE, "airlink record type" },
{ RADIUS_ATTR_3GPP2_RPSESSIONID, "RP session ID" },
{ RADIUS_ATTR_3GPP2_AIRLINKSEQNO, "airlink sequence number" },
{ RADIUS_ATTR_3GPP2_NUMHDLCBYTESRECVD,"number of HDLC bytes received" },
{ RADIUS_ATTR_3GPP2_CORRELATIONID, "correlation ID" },
{ RADIUS_ATTR_3GPP2_MOBILEORIGTERMIND,"mobile orig/term indicator" },
{ RADIUS_ATTR_3GPP2_INBMIPOCTETCNT, "inbound mobile IP octet count" },
{ RADIUS_ATTR_3GPP2_OUTMIPOCTETCNT, "outbound mobile IP octet count" },
{ RADIUS_ATTR_3GPP2_SESSIONCONTINUE, "session continue" },
{ RADIUS_ATTR_3GPP2_SOURCEIPV6ADDR, "source IPv6 address" },
{ RADIUS_ATTR_3GPP2_ESN, "ESN" },
{ RADIUS_ATTR_3GPP2_IPV6PDSNADDR, "IPv6 DNS address" },
{ RADIUS_ATTR_3GPP2_DNSUPDATEREQD, "DNS update required" },
{ 0, ""}
};
extern struct arg_t * my_args;
extern strmap_t iana_enterprise_map[];
extern strmap_t radius_attr_map[];
/*----------------------------------------------------------------------------
**
** dump_radius_3gpp2()
**
** Parse and dump a vendor specific RADIUS attribute.
** Returns the number of bytes read or -1 on error.
**
**----------------------------------------------------------------------------
*/
void dump_radius_3gpp2(packet_t * pkt, u_int8_t type, u_int8_t length)
{
u_int8_t vendortype;
u_int8_t vendorlength;
/* Get the vendor type and length */
if (get_packet_bytes((u_int8_t *) &vendortype, pkt, 1) == 0)
return;
if (get_packet_bytes((u_int8_t *) &vendorlength, pkt, 1) == 0)
return;
/* Display everything so far */
if (my_args->m)
{
display_minimal_string(map2str(radius_attr_map, type));
display_minimal_string("[");
display_minimal_string(map2str(iana_enterprise_map,
IANA_ENTERPRISE_3GPP2));
display_minimal_string("]: ");
display_minimal_string(map2str(radius_attr_3gpp2_map, vendortype));
display_minimal_string(" ");
}
else
{
display_strmap("Attribute type", type, radius_attr_map);
display(" Length", &length, 1, DISP_DEC);
display_strmap(" Vendor", IANA_ENTERPRISE_3GPP2, iana_enterprise_map);
display_strmap(" Type", vendortype, radius_attr_3gpp2_map);
display(" Length", &vendorlength, 1, DISP_DEC);
}
/* Based on the vendor type, decode the data field */
switch(vendortype)
{
/* This is for attributes that are 4 byte integers */
case RADIUS_ATTR_3GPP2_IKEPSKREQUEST:
case RADIUS_ATTR_3GPP2_SECURITYLEVEL:
case RADIUS_ATTR_3GPP2_REVERSETUNNEL:
case RADIUS_ATTR_3GPP2_USERZONE:
case RADIUS_ATTR_3GPP2_FORWARDMUX:
case RADIUS_ATTR_3GPP2_REVERSEMUX:
case RADIUS_ATTR_3GPP2_MNHAKEYREQUEST:
case RADIUS_ATTR_3GPP2_SERVICEOPTION:
case RADIUS_ATTR_3GPP2_FORTRAFFICTYPE:
case RADIUS_ATTR_3GPP2_REVTRAFFICTYPE:
case RADIUS_ATTR_3GPP2_FUNDFRAMESIZE:
case RADIUS_ATTR_3GPP2_FORFUNDRC:
case RADIUS_ATTR_3GPP2_REVFUNDRC:
case RADIUS_ATTR_3GPP2_IPTECHNOLOGY:
case RADIUS_ATTR_3GPP2_COMPTUNNELIND:
case RADIUS_ATTR_3GPP2_BADPPPFRAMECOUNT:
{
u_int32_t value;
/* Get the value */
if (get_packet_bytes((u_int8_t *) &value, pkt, 4) == 0)
return;
/* Conversion */
value = ntohl(value);
/* Display it */
if (my_args->m)
display_minimal((u_int8_t *) &value, 4, DISP_DEC);
else
display(" Value", (u_int8_t *) &value, 4, DISP_DEC);
}
break;
case RADIUS_ATTR_3GPP2_HAADDR:
case RADIUS_ATTR_3GPP2_SERVINGPCFADDR:
{
u_int32_t addr;
if (get_packet_bytes((u_int8_t *) &addr, pkt, 4) == 0)
return;
/* Display */
if (my_args->m)
display_minimal((u_int8_t *) &addr, 4, DISP_DOTTEDDEC);
else
display(" Address", (u_int8_t *) &addr, 4, DISP_DOTTEDDEC);
}
break;
/* This is for attributes that are hex strings */
case RADIUS_ATTR_3GPP2_IKEPSK:
default:
{
u_int8_t * generic_value;
/* Allocate memory for the value then get it */
generic_value = my_malloc(vendorlength-2);
if (get_packet_bytes(generic_value, pkt, vendorlength-2) == 0)
return;
/* Display */
if (my_args->m)
display_minimal(generic_value, vendorlength-2, DISP_HEX);
else
display(" Value", generic_value, vendorlength-2,
DISP_HEX_MULTILINE);
/* Free the memory of the value */
my_free(generic_value);
}
break;
} /* switch */
}
syntax highlighted by Code2HTML, v. 0.9.1