/**************************************************************************** ** 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 */ }