Mercurial > hg > freeDiameter
view extensions/app_diameap/diameap_eappacket.c @ 1515:8430dabbc637
Add 3GPP TS 29.109 V15.0.0 (2017-06)
Add AVPs:
- GBA-UserSecSettings, OctetString, code 400, section 6.3.1.1
- Transaction-Identifier, OctetString, code 401, section 6.3.1.2
- NAF-Id, OctetString, code 402, section 6.3.1.3
- GAA-Service-Identifier, OctetString, code 403, section 6.3.1.4
- Key-ExpiryTime, Time, code 404, section 6.3.1.5
- ME-Key-Material, OctetString, code 405, section 6.3.1.6
- UICC-Key-Material, OctetString, code 406, section 6.3.1.7
- GBA-U-Awareness-Indicator, Enumerated, code 407, section 6.3.1.8
- BootstrapInfoCreationTime, Time, code 408, section 6.3.1.9
- GUSS-Timestamp, Time, code 409, section 6.3.1.10
- GBA-Type, Enumerated, code 410, section 6.3.1.11
- UE-Id, OctetString, code 411, section 6.3.1.12
- UE-Id-Type, Enumerated, code 412, section 6.3.1.13
- UICC-App-Label, OctetString, code 413, section 6.3.1.14
- UICC-ME, Enumerated, code 414, section 6.3.1.15
- Requested-Key-Lifetime, Time, code 415, section 6.3.1.16
- Private-Identity-Request, Enumerated, code 416, section 6.3.1.17
- GBA-Push-Info, OctetString, code 417, section 6.3.1.18
- NAF-SA-Identifier, OctetString, code 418, section 6.3.1.19
- Security-Feature-Request, OctetString, code 419, section 6.3.1.20
- Security-Feature-Response, OctetString, code 420, section 6.3.1.21
Note: 3GPP TS 29.109 table 6.1 row GBA_U-Awareness-Indicator (407)
has an underscore in the name (contrary to RFC 6733 section 4.1).
Fix: GBA_U-Awareness-Indicator (407) renamed to GBA-U-Awareness-Indicator (407).
author | Luke Mewburn <luke@mewburn.net> |
---|---|
date | Thu, 09 Apr 2020 00:34:15 +1000 |
parents | 0117a7746b21 |
children |
line wrap: on
line source
/***************************************************************************************************** * Software License Agreement (BSD License) * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp> * * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project * All rights reserved. * * Redistribution and use of this software in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>. * * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************************************/ #include "libdiameap.h" int diameap_eap_get_code(struct eap_packet *eappacket, eap_code * eapcode) { TRACE_ENTRY("%p %p",eappacket,eapcode); if (eappacket->data == NULL) { *eapcode = ERROR; TRACE_DEBUG(INFO,"%sEmpty data in EAP packet: no EAP Code to return.",DIAMEAP_EXTENSION); return EINVAL; } if (eappacket->length < 1) { *eapcode = ERROR; TRACE_DEBUG(INFO,"%sEAP packet length %d : no EAP Code to return.",DIAMEAP_EXTENSION, eappacket->length); return EINVAL; } *eapcode = G8(eappacket->data); return 0; } int diameap_eap_get_identifier(struct eap_packet *eappacket, u8 * identifier) { TRACE_ENTRY("%p %p",eappacket,identifier); *identifier = 0; if (eappacket->data == NULL) { TRACE_DEBUG(INFO,"%sEmpty data in EAP packet: no Identifier field to return.",DIAMEAP_EXTENSION); return EINVAL; } if (eappacket->length < 2) { TRACE_DEBUG(INFO,"%sEAP packet length %d : no Identifier field to return.",DIAMEAP_EXTENSION, eappacket->length); return EINVAL; } *identifier = G8(eappacket->data + 1); return 0; } int diameap_eap_get_length(struct eap_packet *eappacket, u16 *length) { TRACE_ENTRY("%p %p",eappacket,length); *length = 0; if (eappacket->data == NULL) { TRACE_DEBUG(INFO,"%sEmpty data in EAP packet: no Length field to return.",DIAMEAP_EXTENSION); return EINVAL; } if (eappacket->ulength < 4) { TRACE_DEBUG(INFO,"%sEAP packet length %d : no Length field to return.",DIAMEAP_EXTENSION, eappacket->length); return EINVAL; } *length = (u16) G16BIGE((eappacket->data + 2)); return 0; } int diameap_eap_get_packetlength(struct eap_packet *eappacket, u16 *length) { TRACE_ENTRY("%p %p",eappacket,length); if (eappacket->data == NULL) { TRACE_DEBUG(INFO,"%sEmpty data in EAP packet: no Length field to return.",DIAMEAP_EXTENSION); return EINVAL; } *length = eappacket->ulength; return 0; } int diameap_eap_get_type(struct eap_packet *eappacket, eap_type * eaptype) { TRACE_ENTRY("%p %p",eappacket,eaptype); *eaptype = 0; if (eappacket->data == NULL) { TRACE_DEBUG(INFO,"%sEmpty data in EAP packet: no EAP Type field to return.",DIAMEAP_EXTENSION); return EINVAL; } if (eappacket->length < 5) { TRACE_DEBUG(INFO,"%sEAP packet length %d : no EAP Type field to return.",DIAMEAP_EXTENSION, eappacket->length); return EINVAL; } *eaptype = (u32) G8(eappacket->data + 4); return 0; } boolean diameap_eap_check_code(eap_code code) { TRACE_ENTRY("%d",code); if (code != EAP_REQUEST && code != EAP_RESPONSE && code != EAP_SUCCESS && code != EAP_FAILURE) { TRACE_DEBUG(FULL,"%sIncorrect EAP Code (%d).",DIAMEAP_EXTENSION,code); return FALSE; } return TRUE; } int diameap_eap_get_packetdata(struct eap_packet *eappacket, u8 ** data, int *len) { TRACE_ENTRY("%p %p",eappacket,data); if (eappacket->length > 0) { *data = malloc(sizeof(u8) * eappacket->length); U8COPY(*data,0,eappacket->length,eappacket->data); *len = eappacket->length; return 0; } TRACE_DEBUG(INFO,"%sEAP packet length=%d: empty or wrong EAP Packet.",DIAMEAP_EXTENSION, eappacket->length); *data = NULL; *len = 0; return EINVAL; } int diameap_eap_get_data(struct eap_packet *eappacket, u8 ** data, int * len) { TRACE_ENTRY("%p %p",eappacket,data); if (eappacket->length > 5) { CHECK_MALLOC( *data = malloc(sizeof(u8) * (eappacket->length - 5)) ); U8COPY(*data,0,(eappacket->length-5),(eappacket->data+5)); *len = eappacket->length - 5; return 0; } TRACE_DEBUG(INFO,"%sEAP packet length=%d: empty or wrong EAP Packet.",DIAMEAP_EXTENSION, eappacket->length); *data = NULL; *len = 0; return EINVAL; } void diameap_eap_dump(int level, struct eap_packet *eappacket) { TRACE_ENTRY("%d %p",level,eappacket); if (!TRACE_BOOL(level)) return; if (eappacket->data == NULL) return; if (eappacket->length < 5) return; if (eappacket->ulength < 5) return; fd_log_debug("------------- Dump EAP Packet-------------"); int i; fd_log_debug("\t -Code : "); eap_code code; CHECK_FCT_DO(diameap_eap_get_code(eappacket,&code),return); switch (code) { case 1: fd_log_debug("Request"); break; case 2: fd_log_debug("Response"); break; case 3: fd_log_debug("Success"); break; case 4: fd_log_debug("Failure"); break; default: fd_log_debug("Error (EAP Code value [%d] not allowed)",code); break; } u8 id; CHECK_FCT_DO(diameap_eap_get_identifier(eappacket,&id),return); fd_log_debug("\t -Identifier : %x ", id); u16 length; CHECK_FCT_DO(diameap_eap_get_length(eappacket,&length),return); fd_log_debug("\t -Length : %d ", (unsigned int)length); if (eappacket->length > 4) { eap_type type; CHECK_FCT_DO(diameap_eap_get_type(eappacket,&type),return); fd_log_debug("\t -Type : %d ", type); } if (eappacket->length > 5) { char buf[1024]; snprintf(buf, sizeof(buf), "\t -Data : "); for (i = 5; i < eappacket->length && i < 30; i++) { snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%02x ", G8(eappacket->data + i)); } if(i+1<eappacket->length) snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "[...] (len=%d)",(unsigned int) length); fd_log_debug("%s", buf); } fd_log_debug("-------------End Dump EAP Packet-------------"); } int diameap_eap_new(eap_code code, u8 id, eap_type type, u8 * data, u16 dataLength, struct eap_packet *eappacket) { TRACE_ENTRY("%d %hhu %d %p %hu %p", code, id, type, data, dataLength,eappacket); int length = 0; //Initialize EAP Packet eappacket->length = 0; eappacket->ulength = 0; eappacket->data = NULL; if (diameap_eap_check_code(code) == FALSE) { TRACE_DEBUG( INFO, "%sWrong EAP Code. Only Request, Response, Success or Failure are permitted.",DIAMEAP_EXTENSION); return EINVAL; } length += EAP_HEADER; if (code == EAP_REQUEST || code == EAP_RESPONSE) { // EAP Packet code is either Request or Response if (type == TYPE_NONE) { TRACE_DEBUG(INFO, "%sUnable to create a new EAP Packet (Request or Response) without EAP Type field.",DIAMEAP_EXTENSION); return EINVAL; } length += EAP_TYPE; // EAP Packet code if (data != NULL) { length += dataLength; if (length > (int) MAX_EAP_PACKET) { TRACE_DEBUG(INFO, "%sUnable to add Data to EAP Packet. Data field length exceed allowed data size.", DIAMEAP_EXTENSION); return EINVAL; } else { CHECK_MALLOC(eappacket->data=malloc(sizeof(u8)*length)); memset(eappacket->data, 0, sizeof(u8) * length); U8COPY(eappacket->data, 5, dataLength, data); } } else { CHECK_MALLOC(eappacket->data=malloc(sizeof(u8)*length)); memset(eappacket->data, 0, sizeof(u8) * length); } P8(eappacket->data + 4, type); } else { //EAP Packet code is SUCCESS or FAILURE CHECK_MALLOC(eappacket->data=malloc(sizeof(u8)*length)); memset(eappacket->data, 0, sizeof(u8) * length); //No Data filed //No Type field } //Add Code and Identifier fields P8(eappacket->data, code); P8(eappacket->data + 1, id); //Add length field P16BIGE(eappacket->data + 2, length); eappacket->length = length; eappacket->ulength = length; return 0; }