--- /dev/null
+/** @file uapevent.c
+ *
+ * @brief Program to receive events from the driver/firmware of the uAP
+ * driver.
+ *
+ * Copyright (C) 2008-2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available along with the File in the gpl.txt file or by writing to
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ *
+ */
+/****************************************************************************
+Change log:
+ 03/18/08: Initial creation
+****************************************************************************/
+
+/****************************************************************************
+ Header files
+****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/time.h>
+#include <getopt.h>
+
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include "uapevent.h"
+
+/****************************************************************************
+ Definitions
+****************************************************************************/
+/** Enable or disable debug outputs */
+#define DEBUG 0
+
+/****************************************************************************
+ Global variables
+****************************************************************************/
+/** Termination flag */
+int terminate_flag = 0;
+
+/****************************************************************************
+ Local functions
+****************************************************************************/
+/**
+ * @brief Signal handler
+ *
+ * @param sig Received signal number
+ * @return N/A
+ */
+void
+sig_handler(int sig)
+{
+ printf("Stopping application.\n");
+#if DEBUG
+ printf("Process ID of process killed = %d\n", getpid());
+#endif
+ terminate_flag = 1;
+}
+
+/**
+ * @brief Dump hex data
+ *
+ * @param p A pointer to data buffer
+ * @param len The len of data buffer
+ * @param delim Deliminator character
+ * @return Hex integer
+ */
+static void
+hexdump(void *p, s32 len, s8 delim)
+{
+ s32 i;
+ u8 *s = p;
+ for (i = 0; i < len; i++) {
+ if (i != len - 1)
+ printf("%02x%c", *s++, delim);
+ else
+ printf("%02x\n", *s);
+ if ((i + 1) % 16 == 0)
+ printf("\n");
+ }
+}
+
+/**
+ * @brief Prints a MAC address in colon separated form from raw data
+ *
+ * @param raw A pointer to the hex data buffer
+ * @return N/A
+ */
+void
+print_mac(u8 * raw)
+{
+ printf("%02x:%02x:%02x:%02x:%02x:%02x", (unsigned int) raw[0],
+ (unsigned int) raw[1], (unsigned int) raw[2], (unsigned int) raw[3],
+ (unsigned int) raw[4], (unsigned int) raw[5]);
+ return;
+}
+
+/**
+ * @brief Print usage information
+ *
+ * @return N/A
+ */
+void
+print_usage(void)
+{
+ printf("\n");
+ printf("Usage : uapevent.exe [-v] [-h]\n");
+ printf(" -v : Print version information\n");
+ printf(" -h : Print help information\n");
+ printf("\n");
+}
+
+/**
+ * @brief Parse and print STA deauthentication event data
+ *
+ * @param buffer Pointer to received event buffer
+ * @param size Length of the received event data
+ * @return N/A
+ */
+void
+print_event_sta_deauth(u8 * buffer, u16 size)
+{
+ EVENTBUF_STA_DEAUTH *event_body = NULL;
+
+ if (size < sizeof(EVENTBUF_STA_DEAUTH)) {
+ printf("ERR:Event buffer too small!\n");
+ return;
+ }
+ event_body = (EVENTBUF_STA_DEAUTH *) buffer;
+ event_body->ReasonCode = uap_le16_to_cpu(event_body->ReasonCode);
+ printf("EVENT: STA_DEAUTH\n");
+ printf("Deauthenticated STA MAC: ");
+ print_mac(event_body->StaMacAddress);
+ printf("\nReason: ");
+ switch (event_body->ReasonCode) {
+ case 1:
+ printf("Unspecified reason.\n");
+ break;
+ case 2:
+ printf("Previous authentication no longer valid.\n");
+ break;
+ case 3:
+ printf("Deauthenticated because sending STA is leaving IBSS or ESS.\n");
+ break;
+ case 4:
+ printf("Disassociated due to inactivity.\n");
+ break;
+ case 5:
+ printf
+ ("Disassociated because AP is unable to handle all currently associated STAs.\n");
+ break;
+ case 6:
+ printf("Class 2 frame received from nonauthenticated STA.\n");
+ break;
+ case 7:
+ printf("Class 3 frame received from nonassociated STA.\n");
+ break;
+ case 8:
+ printf("Disassociated because sending STA is leaving BSS.\n");
+ break;
+ case 9:
+ printf
+ ("STA requesting (re)association is not authenticated with responding STA.\n");
+ break;
+ case 10:
+ printf
+ ("Disassociated because the information in the Power Capability element is unacceptable.\n");
+ break;
+ case 11:
+ printf
+ ("Disassociated because the information in the Supported Channels element is unacceptable.\n");
+ break;
+ case 13:
+ printf("Invalid information element.\n");
+ break;
+ case 14:
+ printf("Message integrity code (MIC) failure.\n");
+ break;
+ case 15:
+ printf("4-Way Handshake timeout.\n");
+ break;
+ case 16:
+ printf("Group Key Handshake timeout.\n");
+ break;
+ case 17:
+ printf("Information element in 4-Way Handshake different from\n");
+ printf(" (Re)Association Request/Probe Response/Beacon frame.\n");
+ break;
+ case 18:
+ printf("Invalid group cipher.\n");
+ break;
+ case 19:
+ printf("Invalid pairwise cipher.\n");
+ break;
+ case 20:
+ printf("Invalid AKMP.\n");
+ break;
+ case 21:
+ printf("Unsupported RSN information element version.\n");
+ break;
+ case 22:
+ printf("Invalid RSN information element capabilities.\n");
+ break;
+ case 23:
+ printf("IEEE 802.1X authentication failed.\n");
+ break;
+ case 24:
+ printf("Cipher suite rejected because of the security policy.\n");
+ break;
+ case 32:
+ printf("Disassociated for unspecified, QoS-related reason.\n");
+ break;
+ case 33:
+ printf
+ ("Disassociated because QoS AP lacks sufficient bandwidth for this QoS STA.\n");
+ break;
+ case 34:
+ printf
+ ("Disassociated because excessive number of frames need to be acknowledged\n");
+ printf
+ (" but are not acknowledged due to AP transmissions and or poor channel conditions.\n");
+ break;
+ case 35:
+ printf
+ ("Disassociated because STA is transmitting outside the limits of its TXOPs.\n");
+ break;
+ case 36:
+ printf
+ ("Requested from peer STA as the STA is leaving the BSS or resetting.\n");
+ break;
+ case 37:
+ printf
+ ("Requested from peer STA as it does not want to use the mechanism.\n");
+ break;
+ case 38:
+ printf("Requested from peer STA as the STA received frames using");
+ printf(" the mechanism for which a setup is required.\n");
+ break;
+ case 39:
+ printf("Requested from peer STA due to timeout.\n");
+ break;
+ case 45:
+ printf("Peer STA does not support the requested cipher suite.\n");
+ break;
+ default:
+ printf("Reserved or Unspecified\n");
+ break;
+ }
+ return;
+}
+
+/**
+ * @brief Prints mgmt frame
+ *
+ * @param mgmt_tlv A pointer to mgmt_tlv
+ * @param tlv_len Length of tlv payload
+ * @return N/A
+ */
+void
+print_mgmt_frame(MrvlIETypes_MgmtFrameSet_t * mgmt_tlv, int tlv_len)
+{
+ IEEEtypes_AssocRqst_t *assoc_req = NULL;
+ IEEEtypes_ReAssocRqst_t *reassoc_req = NULL;
+ IEEEtypes_AssocRsp_t *assoc_resp = NULL;
+ u16 frmctl = 0;
+ printf("\nMgmt Frame:\n");
+ memcpy(&frmctl, &mgmt_tlv->FrameControl, sizeof(u16));
+ printf("FrameControl: 0x%x\n", frmctl);
+ if (mgmt_tlv->FrameControl.Type != 0) {
+ printf("Frame type=%d subtype=%d:\n", mgmt_tlv->FrameControl.Type,
+ mgmt_tlv->FrameControl.Subtype);
+ hexdump(mgmt_tlv->FrameContents, tlv_len - sizeof(u16), ' ');
+ return;
+ }
+ switch (mgmt_tlv->FrameControl.Subtype) {
+ case SUBTYPE_ASSOC_REQUEST:
+ printf("Assoc Request:\n");
+ assoc_req = (IEEEtypes_AssocRqst_t *) mgmt_tlv->FrameContents;
+ printf("CapInfo: 0x%x ListenInterval: 0x%x \n",
+ uap_le16_to_cpu(assoc_req->CapInfo),
+ uap_le16_to_cpu(assoc_req->ListenInterval));
+ printf("AssocReqIE:\n");
+ hexdump(assoc_req->IEBuffer,
+ tlv_len - sizeof(IEEEtypes_AssocRqst_t) -
+ sizeof(IEEEtypes_FrameCtl_t), ' ');
+ break;
+ case SUBTYPE_REASSOC_REQUEST:
+ printf("ReAssoc Request:\n");
+ reassoc_req = (IEEEtypes_ReAssocRqst_t *) mgmt_tlv->FrameContents;
+ printf("CapInfo: 0x%x ListenInterval: 0x%x \n",
+ uap_le16_to_cpu(reassoc_req->CapInfo),
+ uap_le16_to_cpu(reassoc_req->ListenInterval));
+ printf("Current AP address: ");
+ print_mac(reassoc_req->CurrentApAddr);
+ printf("\nReAssocReqIE:\n");
+ hexdump(reassoc_req->IEBuffer,
+ tlv_len - sizeof(IEEEtypes_ReAssocRqst_t) -
+ sizeof(IEEEtypes_FrameCtl_t), ' ');
+ break;
+ case SUBTYPE_ASSOC_RESPONSE:
+ case SUBTYPE_REASSOC_RESPONSE:
+ if (mgmt_tlv->FrameControl.Subtype == SUBTYPE_ASSOC_RESPONSE)
+ printf("Assoc Response:\n");
+ else
+ printf("ReAssoc Response:\n");
+ assoc_resp = (IEEEtypes_AssocRsp_t *) mgmt_tlv->FrameContents;
+ printf("CapInfo: 0x%x StatusCode: %d AID: 0x%x \n",
+ uap_le16_to_cpu(assoc_resp->CapInfo),
+ (int) (uap_le16_to_cpu(assoc_resp->StatusCode)),
+ uap_le16_to_cpu(assoc_resp->AId) & 0x3fff);
+ break;
+ default:
+ printf("Frame subtype = %d:\n", mgmt_tlv->FrameControl.Subtype);
+ hexdump(mgmt_tlv->FrameContents, tlv_len - sizeof(u16), ' ');
+ break;
+ }
+ return;
+}
+
+/**
+ * @brief Parse and print STA associate event data
+ *
+ * @param buffer Pointer to received buffer
+ * @param size Length of the received event data
+ * @return N/A
+ */
+void
+print_event_sta_assoc(u8 * buffer, u16 size)
+{
+ int tlvBufLeft = size;
+ u16 tlvType, tlvLen;
+ tlvbuf_header *tlv = NULL;
+ MrvlIEtypes_WapiInfoSet_t *wapi_tlv = NULL;
+ MrvlIETypes_MgmtFrameSet_t *mgmt_tlv = NULL;
+ EVENTBUF_STA_ASSOC *event_body = NULL;
+ if (size < sizeof(EVENTBUF_STA_ASSOC)) {
+ printf("ERR:Event buffer too small!\n");
+ return;
+ }
+ event_body = (EVENTBUF_STA_ASSOC *) buffer;
+ printf("EVENT: STA_ASSOCIATE\n");
+ printf("Associated STA MAC: ");
+ print_mac(event_body->StaMacAddress);
+ printf("\n");
+ tlvBufLeft = size - sizeof(EVENTBUF_STA_ASSOC);
+ if (tlvBufLeft < (int) sizeof(tlvbuf_header))
+ return;
+ tlv = (tlvbuf_header *) (buffer + sizeof(EVENTBUF_STA_ASSOC));
+
+ while (tlvBufLeft >= (int) sizeof(tlvbuf_header)) {
+ tlvType = uap_le16_to_cpu(tlv->type);
+ tlvLen = uap_le16_to_cpu(tlv->len);
+ if ((sizeof(tlvbuf_header) + tlvLen) > tlvBufLeft) {
+ printf("wrong tlv: tlvLen=%d, tlvBufLeft=%d\n", tlvLen, tlvBufLeft);
+ break;
+ }
+ switch (tlvType) {
+ case MRVL_WAPI_INFO_TLV_ID:
+ wapi_tlv = (MrvlIEtypes_WapiInfoSet_t *) tlv;
+ printf("WAPI Multicast PN:\n");
+ hexdump(wapi_tlv->MulticastPN, tlvLen, ' ');
+ break;
+ case MRVL_MGMT_FRAME_TLV_ID:
+ mgmt_tlv = (MrvlIETypes_MgmtFrameSet_t *) tlv;
+ print_mgmt_frame(mgmt_tlv, tlvLen);
+ break;
+ default:
+ printf("unknown tlv: %d\n", tlvType);
+ break;
+ }
+ tlvBufLeft -= (sizeof(tlvbuf_header) + tlvLen);
+ tlv = (tlvbuf_header *) ((u8 *) tlv + tlvLen + sizeof(tlvbuf_header));
+ }
+ return;
+}
+
+/**
+ * @brief Parse and print BSS start event data
+ *
+ * @param buffer Pointer to received buffer
+ * @param size Length of the received event data
+ * @return N/A
+ */
+void
+print_event_bss_start(u8 * buffer, u16 size)
+{
+ EVENTBUF_BSS_START *event_body = NULL;
+
+ if (size < sizeof(EVENTBUF_BSS_START)) {
+ printf("ERR:Event buffer too small!\n");
+ return;
+ }
+ event_body = (EVENTBUF_BSS_START *) buffer;
+ printf("EVENT: BSS_START ");
+ printf("BSS MAC: ");
+ print_mac(event_body->apMacAddress);
+ printf("\n");
+ return;
+}
+
+/**
+ * @brief Prints station reject state
+ *
+ * @param state fail state
+ * @return N/A
+ */
+void
+print_reject_state(u8 state)
+{
+ switch (state) {
+ case REJECT_STATE_FAIL_EAPOL_2:
+ printf("Reject state: FAIL_EAPOL_2\n");
+ break;
+ case REJECT_STATE_FAIL_EAPOL_4:
+ printf("Reject state: FAIL_EAPOL_4:\n");
+ break;
+ case REJECT_STATE_FAIL_EAPOL_GROUP_2:
+ printf("Reject state: FAIL_EAPOL_GROUP_2\n");
+ break;
+ default:
+ printf("ERR: unknown reject state %d\n", state);
+ break;
+ }
+ return;
+}
+
+/**
+ * @brief Prints station reject reason
+ *
+ * @param reason reason code
+ * @return N/A
+ */
+void
+print_reject_reason(u16 reason)
+{
+ switch (reason) {
+ case IEEEtypes_REASON_INVALID_IE:
+ printf("Reject reason: Invalid IE\n");
+ break;
+ case IEEEtypes_REASON_MIC_FAILURE:
+ printf("Reject reason: Mic Failure\n");
+ break;
+ default:
+ printf("Reject reason: %d\n", reason);
+ break;
+ }
+ return;
+}
+
+/**
+ * @brief Prints EAPOL state
+ *
+ * @param state eapol state
+ * @return N/A
+ */
+void
+print_eapol_state(u8 state)
+{
+ switch (state) {
+ case EAPOL_START:
+ printf("Eapol state: EAPOL_START\n");
+ break;
+ case EAPOL_WAIT_PWK2:
+ printf("Eapol state: EAPOL_WAIT_PWK2\n");
+ break;
+ case EAPOL_WAIT_PWK4:
+ printf("Eapol state: EAPOL_WAIT_PWK4\n");
+ break;
+ case EAPOL_WAIT_GTK2:
+ printf("Eapol state: EAPOL_WAIT_GTK2\n");
+ break;
+ case EAPOL_END:
+ printf("Eapol state: EAPOL_END\n");
+ break;
+ default:
+ printf("ERR: unknow eapol state%d\n", state);
+ break;
+ }
+ return;
+}
+
+/**
+ * @brief Parse and print debug event data
+ *
+ * @param buffer Pointer to received buffer
+ * @param size Length of the received event data
+ * @return N/A
+ */
+void
+print_event_debug(u8 * buffer, u16 size)
+{
+ EVENTBUF_DEBUG *event_body = NULL;
+ if (size < sizeof(EVENTBUF_DEBUG)) {
+ printf("ERR:Event buffer too small!\n");
+ return;
+ }
+ event_body = (EVENTBUF_DEBUG *) buffer;
+ printf("Debug Event Type: %s\n",
+ (event_body->debugtype == 0) ? "EVENT" : "INFO");
+ printf("%s log:\n",
+ (uap_le32_to_cpu(event_body->debugIdMajor) ==
+ DEBUG_ID_MAJ_AUTHENTICATOR) ? "Authenticator" : "Assoc_agent");
+ if (uap_le32_to_cpu(event_body->debugIdMajor) == DEBUG_ID_MAJ_AUTHENTICATOR) {
+ switch (uap_le32_to_cpu(event_body->debugIdMinor)) {
+ case DEBUG_MAJ_AUTH_MIN_PWK1:
+ printf("EAPOL Key message 1 (PWK):\n");
+ hexdump((u8 *) & event_body->info.eapol_pwkMsg,
+ sizeof(EAPOL_KeyMsg_Debug_t), ' ');
+ break;
+ case DEBUG_MAJ_AUTH_MIN_PWK2:
+ printf("EAPOL Key message 2 (PWK):\n");
+ hexdump((u8 *) & event_body->info.eapol_pwkMsg,
+ sizeof(EAPOL_KeyMsg_Debug_t), ' ');
+ break;
+ case DEBUG_MAJ_AUTH_MIN_PWK3:
+ printf("EAPOL Key message 3 (PWK):\n");
+ hexdump((u8 *) & event_body->info.eapol_pwkMsg,
+ sizeof(EAPOL_KeyMsg_Debug_t), ' ');
+ break;
+ case DEBUG_MAJ_AUTH_MIN_PWK4:
+ printf("EAPOL Key message 4: (PWK)\n");
+ hexdump((u8 *) & event_body->info.eapol_pwkMsg,
+ sizeof(EAPOL_KeyMsg_Debug_t), ' ');
+ break;
+ case DEBUG_MAJ_AUTH_MIN_GWK1:
+ printf("EAPOL Key message 1: (GWK)\n");
+ hexdump((u8 *) & event_body->info.eapol_pwkMsg,
+ sizeof(EAPOL_KeyMsg_Debug_t), ' ');
+ break;
+ case DEBUG_MAJ_AUTH_MIN_GWK2:
+ printf("EAPOL Key message 2: (GWK)\n");
+ hexdump((u8 *) & event_body->info.eapol_pwkMsg,
+ sizeof(EAPOL_KeyMsg_Debug_t), ' ');
+ break;
+ case DEBUG_MAJ_AUTH_MIN_STA_REJ:
+ printf("Reject STA MAC: ");
+ print_mac(event_body->info.sta_reject.staMacAddr);
+ printf("\n");
+ print_reject_state(event_body->info.sta_reject.reject_state);
+ print_reject_reason(uap_le16_to_cpu
+ (event_body->info.sta_reject.reject_reason));
+ break;
+ case DEBUG_MAJ_AUTH_MIN_EAPOL_TR:
+ printf("STA MAC: ");
+ print_mac(event_body->info.eapol_state.staMacAddr);
+ printf("\n");
+ print_eapol_state(event_body->info.eapol_state.eapolState);
+ break;
+ default:
+ printf("ERR: unknow debugIdMinor: %d\n",
+ (int) uap_le32_to_cpu(event_body->debugIdMinor));
+ hexdump(buffer, size, ' ');
+ return;
+ }
+ } else if (uap_le32_to_cpu(event_body->debugIdMajor) ==
+ DEBUG_ID_MAJ_ASSOC_AGENT) {
+ switch (uap_le32_to_cpu(event_body->debugIdMinor)) {
+ case DEBUG_ID_MAJ_ASSOC_MIN_WPA_IE:
+ printf("STA MAC: ");
+ print_mac(event_body->info.wpaIe.staMacAddr);
+ printf("\n");
+ printf("wpa ie:\n");
+ hexdump(event_body->info.wpaIe.wpa_ie, MAX_WPA_IE_LEN, ' ');
+ break;
+ case DEBUG_ID_MAJ_ASSOC_MIN_STA_REJ:
+ printf("Reject STA MAC: ");
+ print_mac(event_body->info.sta_reject.staMacAddr);
+ printf("\n");
+ print_reject_state(event_body->info.sta_reject.reject_state);
+ print_reject_reason(uap_le16_to_cpu
+ (event_body->info.sta_reject.reject_reason));
+ break;
+ default:
+ printf("ERR: unknow debugIdMinor: %d\n",
+ (int) uap_le32_to_cpu(event_body->debugIdMinor));
+ hexdump(buffer, size, ' ');
+ return;
+ }
+ }
+ return;
+}
+
+/**
+ * @brief Parse and print received event information
+ *
+ * @param event Pointer to received event
+ * @param size Length of the received event
+ * @return N/A
+ */
+void
+print_event(EVENTHEADER * event, u16 size)
+{
+ u32 event_id = event->EventId & EVENT_ID_MASK;
+ switch (event_id) {
+ case MICRO_AP_EV_ID_STA_DEAUTH:
+ print_event_sta_deauth(event->EventData, size - EVENT_ID_LEN);
+ break;
+ case MICRO_AP_EV_ID_STA_ASSOC:
+ print_event_sta_assoc(event->EventData, size - EVENT_ID_LEN);
+ break;
+ case MICRO_AP_EV_ID_BSS_START:
+ print_event_bss_start(event->EventData, size - EVENT_ID_LEN);
+ break;
+ case MICRO_AP_EV_ID_DEBUG:
+ print_event_debug(event->EventData, size - EVENT_ID_LEN);
+ break;
+ case MICRO_AP_EV_BSS_IDLE:
+ printf("EVENT: BSS_IDLE\n");
+ break;
+ case MICRO_AP_EV_BSS_ACTIVE:
+ printf("EVENT: BSS_ACTIVE\n");
+ break;
+ default:
+ printf("ERR:Undefined event type (%X). Dumping event buffer:\n",
+ (unsigned int) event_id);
+ hexdump((void *) event, size, ' ');
+ break;
+ }
+ return;
+}
+
+/**
+ * @brief Read event data from netlink socket
+ *
+ * @param sk_fd Netlink socket handler
+ * @param buffer Pointer to the data buffer
+ * @param nlh Pointer to netlink message header
+ * @param msg Pointer to message header
+ * @return Number of bytes read or UAP_FAILURE
+ */
+int
+read_event_netlink_socket(int sk_fd, unsigned char *buffer,
+ struct nlmsghdr *nlh, struct msghdr *msg)
+{
+ int count = -1;
+ count = recvmsg(sk_fd, msg, 0);
+#if DEBUG
+ printf("DBG:Waiting for message from NETLINK.\n");
+#endif
+ if (count < 0) {
+ printf("ERR:NETLINK read failed!\n");
+ terminate_flag++;
+ return UAP_FAILURE;
+ }
+#if DEBUG
+ printf("DBG:Received message payload (%d)\n", count);
+#endif
+ if (count > NLMSG_SPACE(NL_MAX_PAYLOAD)) {
+ printf("ERR:Buffer overflow!\n");
+ return UAP_FAILURE;
+ }
+ bzero(buffer, NL_MAX_PAYLOAD);
+ memcpy(buffer, NLMSG_DATA(nlh), count - NLMSG_HDRLEN);
+#if DEBUG
+ hexdump(buffer, count - NLMSG_HDRLEN, ' ');
+#endif
+ return count - NLMSG_HDRLEN;
+}
+
+/**
+ * @brief Configure and read event data from netlink socket
+ *
+ * @param sk_fd Netlink socket handler
+ * @param buffer Pointer to the data buffer
+ * @param timeout Socket listen timeout value
+ * @param nlh Pointer to netlink message header
+ * @param msg Pointer to message header
+ * @return Number of bytes read or UAP_FAILURE
+ */
+int
+read_event(int sk_fd, unsigned char *buffer, int timeout, struct nlmsghdr *nlh,
+ struct msghdr *msg)
+{
+ struct timeval tv;
+ fd_set rfds;
+ int ret = UAP_FAILURE;
+
+ /* Setup read fds */
+ FD_ZERO(&rfds);
+ FD_SET(sk_fd, &rfds);
+
+ /* Initialize timeout value */
+ if (timeout != 0)
+ tv.tv_sec = timeout;
+ else
+ tv.tv_sec = UAP_RECV_WAIT_DEFAULT;
+ tv.tv_usec = 0;
+
+ /* Wait for reply */
+ ret = select(sk_fd + 1, &rfds, NULL, NULL, &tv);
+ if (ret == -1) {
+ /* Error */
+ terminate_flag++;
+ return UAP_FAILURE;
+ } else if (!ret) {
+ /* Timeout. Try again */
+ return UAP_FAILURE;
+ }
+ if (!FD_ISSET(sk_fd, &rfds)) {
+ /* Unexpected error. Try again */
+ return UAP_FAILURE;
+ }
+
+ /* Success */
+ ret = read_event_netlink_socket(sk_fd, buffer, nlh, msg);
+ return ret;
+}
+
+/* Command line options */
+static const struct option long_opts[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'v'},
+ {NULL, 0, NULL, 0}
+};
+
+/****************************************************************************
+ Global functions
+****************************************************************************/
+/**
+ * @brief The main function
+ *
+ * @param argc Number of arguments
+ * @param argv Pointer to the arguments
+ * @return 0 or 1
+ */
+int
+main(int argc, char *argv[])
+{
+ int opt;
+ int nl_sk = 0;
+ struct nlmsghdr *nlh = NULL;
+ struct sockaddr_nl src_addr, dest_addr;
+ struct msghdr msg;
+ struct iovec iov;
+ unsigned char *buffer = NULL;
+ struct timeval current_time;
+ struct tm *timeinfo;
+ int num_events = 0;
+ EVENTHEADER *event = NULL;
+ int ret = UAP_FAILURE;
+
+ /* Check command line options */
+ while ((opt = getopt_long(argc, argv, "hvt", long_opts, NULL)) > 0) {
+ switch (opt) {
+ case 'h':
+ print_usage();
+ return 0;
+ case 'v':
+ printf("uapevent version : %s\n", UAP_VERSION);
+ return 0;
+ break;
+ default:
+ print_usage();
+ return 1;
+ }
+ }
+ if (optind < argc) {
+ fputs("Too many arguments.\n", stderr);
+ print_usage();
+ return 1;
+ }
+
+ /* Open netlink socket */
+ nl_sk = socket(PF_NETLINK, SOCK_RAW, NETLINK_MARVELL);
+ if (nl_sk < 0) {
+ printf("ERR:Could not open netlink socket.\n");
+ ret = UAP_FAILURE;
+ goto done;
+ }
+
+ /* Set source address */
+ bzero((char *) &src_addr, sizeof(src_addr));
+ src_addr.nl_family = AF_NETLINK;
+ src_addr.nl_pid = getpid(); /* Our PID */
+ src_addr.nl_groups = NL_MULTICAST_GROUP;
+
+ /* Bind socket with source address */
+ if (bind(nl_sk, (struct sockaddr *) &src_addr, sizeof(src_addr)) < 0) {
+ printf("ERR:Could not bind socket!\n");
+ ret = UAP_FAILURE;
+ goto done;
+ }
+
+ /* Set destination address */
+ memset(&dest_addr, 0, sizeof(dest_addr));
+ dest_addr.nl_family = AF_NETLINK;
+ dest_addr.nl_pid = 0; /* Kernel */
+ dest_addr.nl_groups = NL_MULTICAST_GROUP;
+
+ /* Initialize netlink header */
+ nlh = (struct nlmsghdr *) malloc(NLMSG_SPACE(NL_MAX_PAYLOAD));
+ if (!nlh) {
+ printf("ERR: Could not alloc buffer\n");
+ ret = UAP_FAILURE;
+ goto done;
+ }
+ memset(nlh, 0, NLMSG_SPACE(NL_MAX_PAYLOAD));
+
+ /* Initialize I/O vector */
+ iov.iov_base = (void *) nlh;
+ iov.iov_len = NLMSG_SPACE(NL_MAX_PAYLOAD);
+
+ /* Initialize message header */
+ memset(&msg, 0, sizeof(struct msghdr));
+ msg.msg_name = (void *) &dest_addr;
+ msg.msg_namelen = sizeof(dest_addr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ /* Initialize receive buffer */
+ buffer = malloc(NL_MAX_PAYLOAD);
+ if (!buffer) {
+ printf("ERR: Could not alloc buffer\n");
+ ret = UAP_FAILURE;
+ goto done;
+ }
+ bzero(buffer, sizeof(buffer));
+
+ gettimeofday(¤t_time, NULL);
+
+ printf("\n");
+ printf("*********************************************\n");
+ if ((timeinfo = localtime(&(current_time.tv_sec))))
+ printf("uapevent start time : %s", asctime(timeinfo));
+ printf(" %u usecs\n",
+ (unsigned int) current_time.tv_usec);
+ printf("*********************************************\n");
+
+ signal(SIGTERM, sig_handler);
+ signal(SIGINT, sig_handler);
+ signal(SIGALRM, sig_handler);
+ while (1) {
+ if (terminate_flag) {
+ printf("Stopping!\n");
+ break;
+ }
+ ret = read_event(nl_sk, buffer, 0, nlh, &msg);
+
+ /* No result. Loop again */
+ if (ret == UAP_FAILURE) {
+ continue;
+ }
+ if (ret == 0) {
+ /* Zero bytes received */
+ printf("ERR:Received zero bytes!\n");
+ continue;
+ }
+ num_events++;
+ gettimeofday(¤t_time, NULL);
+ printf("\n");
+ printf("============================================\n");
+ printf("Received event");
+ if ((timeinfo = localtime(&(current_time.tv_sec))))
+ printf(": %s", asctime(timeinfo));
+ printf(" %u usecs\n",
+ (unsigned int) current_time.tv_usec);
+ printf("============================================\n");
+ event = (EVENTHEADER *) buffer;
+ event->EventId = uap_le32_to_cpu(event->EventId);
+#if DEBUG
+ printf("DBG:Received buffer =\n");
+ hexdump(buffer, ret, ' ');
+#endif
+ print_event(event, ret);
+ fflush(stdout);
+ }
+ gettimeofday(¤t_time, NULL);
+ printf("\n");
+ printf("********************************************\n");
+ if ((timeinfo = localtime(&(current_time.tv_sec))))
+ printf("uapevent end time : %s", asctime(timeinfo));
+ printf(" %u usecs\n",
+ (unsigned int) current_time.tv_usec);
+ printf("Total events : %u\n", num_events);
+ printf("********************************************\n");
+ done:
+ if (buffer)
+ free(buffer);
+ if (nl_sk)
+ close(nl_sk);
+ if (nlh)
+ free(nlh);
+ return 0;
+}
--- /dev/null
+/** @file uapevent.h
+ *
+ * @brief Header file for uapevent application
+ *
+ * Copyright (C) 2008-2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available along with the File in the gpl.txt file or by writing to
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ *
+ */
+/************************************************************************
+Change log:
+ 03/18/08: Initial creation
+************************************************************************/
+
+#ifndef _UAP_H
+#define _UAP_H
+
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+#undef BIG_ENDIAN
+#endif
+
+/** 16 bits byte swap */
+#define swap_byte_16(x) \
+ ((u16)((((u16)(x) & 0x00ffU) << 8) | \
+ (((u16)(x) & 0xff00U) >> 8)))
+
+/** 32 bits byte swap */
+#define swap_byte_32(x) \
+ ((u32)((((u32)(x) & 0x000000ffUL) << 24) | \
+ (((u32)(x) & 0x0000ff00UL) << 8) | \
+ (((u32)(x) & 0x00ff0000UL) >> 8) | \
+ (((u32)(x) & 0xff000000UL) >> 24)))
+
+/** 64 bits byte swap */
+#define swap_byte_64(x) \
+ ((u64)((u64)(((u64)(x) & 0x00000000000000ffULL) << 56) | \
+ (u64)(((u64)(x) & 0x000000000000ff00ULL) << 40) | \
+ (u64)(((u64)(x) & 0x0000000000ff0000ULL) << 24) | \
+ (u64)(((u64)(x) & 0x00000000ff000000ULL) << 8) | \
+ (u64)(((u64)(x) & 0x000000ff00000000ULL) >> 8) | \
+ (u64)(((u64)(x) & 0x0000ff0000000000ULL) >> 24) | \
+ (u64)(((u64)(x) & 0x00ff000000000000ULL) >> 40) | \
+ (u64)(((u64)(x) & 0xff00000000000000ULL) >> 56) ))
+
+#ifdef BIG_ENDIAN
+/** Convert from 16 bit little endian format to CPU format */
+#define uap_le16_to_cpu(x) swap_byte_16(x)
+/** Convert from 32 bit little endian format to CPU format */
+#define uap_le32_to_cpu(x) swap_byte_32(x)
+/** Convert from 64 bit little endian format to CPU format */
+#define uap_le64_to_cpu(x) swap_byte_64(x)
+/** Convert to 16 bit little endian format from CPU format */
+#define uap_cpu_to_le16(x) swap_byte_16(x)
+/** Convert to 32 bit little endian format from CPU format */
+#define uap_cpu_to_le32(x) swap_byte_32(x)
+/** Convert to 64 bit little endian format from CPU format */
+#define uap_cpu_to_le64(x) swap_byte_64(x)
+#else /* BIG_ENDIAN */
+/** Do nothing */
+#define uap_le16_to_cpu(x) x
+/** Do nothing */
+#define uap_le32_to_cpu(x) x
+/** Do nothing */
+#define uap_le64_to_cpu(x) x
+/** Do nothing */
+#define uap_cpu_to_le16(x) x
+/** Do nothing */
+#define uap_cpu_to_le32(x) x
+/** Do nothing */
+#define uap_cpu_to_le64(x) x
+#endif /* BIG_ENDIAN */
+
+/** uAP application version string */
+#define UAP_VERSION "uAP 1.4"
+
+/** Success */
+#define UAP_SUCCESS 1
+/** Failure */
+#define UAP_FAILURE -1
+
+#ifdef __GNUC__
+/** Structure packing begins */
+#define PACK_START
+/** Structure packeing end */
+#define PACK_END __attribute__ ((packed))
+#else
+/** Structure packing begins */
+#define PACK_START __packed
+/** Structure packeing end */
+#define PACK_END
+#endif
+
+#ifndef ETH_ALEN
+/** MAC address length */
+#define ETH_ALEN 6
+#endif
+
+/** Netlink protocol number */
+#define NETLINK_MARVELL (MAX_LINKS - 1)
+/** Netlink maximum payload size */
+#define NL_MAX_PAYLOAD 1024
+/** Netlink multicast group number */
+#define NL_MULTICAST_GROUP 1
+/** Default wait time in seconds for events */
+#define UAP_RECV_WAIT_DEFAULT 10
+
+/** Character, 1 byte */
+typedef char s8;
+/** Unsigned character, 1 byte */
+typedef unsigned char u8;
+
+/** Short integer */
+typedef signed short s16;
+/** Unsigned short integer */
+typedef unsigned short u16;
+
+/** Long integer */
+typedef signed long s32;
+/** Unsigned long integer */
+typedef unsigned long u32;
+
+/** event ID mask */
+#define EVENT_ID_MASK 0x0fff
+
+/** Event header */
+typedef PACK_START struct _EVENTHEADER
+{
+ /** Event ID */
+ u32 EventId;
+ /** Event data */
+ u8 EventData[0];
+} PACK_END EVENTHEADER;
+
+/** Event ID length */
+#define EVENT_ID_LEN 4
+
+/** Event ID: STA deauth */
+#define MICRO_AP_EV_ID_STA_DEAUTH 44
+
+/** Event ID: STA associated */
+#define MICRO_AP_EV_ID_STA_ASSOC 45
+
+/** Event ID: BSS started */
+#define MICRO_AP_EV_ID_BSS_START 46
+
+/** Event ID: Debug event */
+#define MICRO_AP_EV_ID_DEBUG 54
+
+/** Event ID: BSS idle event */
+#define MICRO_AP_EV_BSS_IDLE 67
+
+/** Event ID: BSS active event */
+#define MICRO_AP_EV_BSS_ACTIVE 68
+
+/** TLV buffer header*/
+typedef PACK_START struct _tlvbuf_header
+{
+ /** Header type */
+ u16 type;
+ /** Header length */
+ u16 len;
+} PACK_END tlvbuf_header;
+
+/** TLV ID : WAPI Information */
+#define MRVL_WAPI_INFO_TLV_ID 0x0167
+
+/** TLV ID : Management Frame */
+#define MRVL_MGMT_FRAME_TLV_ID 0x0168
+/** Assoc Request */
+#define SUBTYPE_ASSOC_REQUEST 0
+/** Assoc Response */
+#define SUBTYPE_ASSOC_RESPONSE 1
+/** ReAssoc Request */
+#define SUBTYPE_REASSOC_REQUEST 2
+/** ReAssoc Response */
+#define SUBTYPE_REASSOC_RESPONSE 3
+
+/** Event body : STA deauth */
+typedef PACK_START struct _EVENTBUF_STA_DEAUTH
+{
+ /** Deauthentication reason */
+ u16 ReasonCode;
+ /** MAC address of deauthenticated STA */
+ u8 StaMacAddress[ETH_ALEN];
+} PACK_END EVENTBUF_STA_DEAUTH;
+
+/** Event body : STA associated */
+typedef PACK_START struct _EVENTBUF_STA_ASSOC
+{
+ /** Reserved */
+ u8 Reserved[2];
+ /** MAC address of associated STA */
+ u8 StaMacAddress[ETH_ALEN];
+ /** Assoc request/response buffer */
+ u8 AssocPayload[0];
+} PACK_END EVENTBUF_STA_ASSOC;
+
+/** Event body : BSS started */
+typedef PACK_START struct _EVENTBUF_BSS_START
+{
+ /** Reserved */
+ u8 Reserved[2];
+ /** MAC address of BSS */
+ u8 apMacAddress[ETH_ALEN];
+} PACK_END EVENTBUF_BSS_START;
+
+/**
+ * IEEE 802.11 MAC Message Data Structures
+ *
+ * Each IEEE 802.11 MAC message includes a MAC header, a frame body (which
+ * can be empty), and a frame check sequence field. This section gives the
+ * structures that used for the MAC message headers and frame bodies that
+ * can exist in the three types of MAC messages - 1) Control messages,
+ * 2) Data messages, and 3) Management messages.
+ */
+#ifdef BIG_ENDIAN
+typedef PACK_START struct _IEEEtypes_FrameCtl_t
+{
+ /** Order */
+ u8 Order:1;
+ /** Wep */
+ u8 Wep:1;
+ /** MoreData */
+ u8 MoreData:1;
+ /** PwrMgmt */
+ u8 PwrMgmt:1;
+ /** Retry */
+ u8 Retry:1;
+ /** MoreFrag */
+ u8 MoreFrag:1;
+ /** FromDs */
+ u8 FromDs:1;
+ /** ToDs */
+ u8 ToDs:1;
+ /** Subtype */
+ u8 Subtype:4;
+ /** Type */
+ u8 Type:2;
+ /** Protocol Version */
+ u8 ProtocolVersion:2;
+} PACK_END IEEEtypes_FrameCtl_t;
+#else
+typedef PACK_START struct _IEEEtypes_FrameCtl_t
+{
+ /** Protocol Version */
+ u8 ProtocolVersion:2;
+ /** Type */
+ u8 Type:2;
+ /** Subtype */
+ u8 Subtype:4;
+ /** ToDs */
+ u8 ToDs:1;
+ /** FromDs */
+ u8 FromDs:1;
+ /** MoreFrag */
+ u8 MoreFrag:1;
+ /** Retry */
+ u8 Retry:1;
+ /** PwrMgmt */
+ u8 PwrMgmt:1;
+ /** MoreData */
+ u8 MoreData:1;
+ /** Wep */
+ u8 Wep:1;
+ /** Order */
+ u8 Order:1;
+} PACK_END IEEEtypes_FrameCtl_t;
+#endif
+
+/** IEEEtypes_AssocRqst_t */
+typedef PACK_START struct _IEEEtypes_AssocRqst_t
+{
+ /** CapInfo */
+ u16 CapInfo;
+ /** ListenInterval */
+ u16 ListenInterval;
+ /** IE Buffer */
+ u8 IEBuffer[0];
+} PACK_END IEEEtypes_AssocRqst_t;
+
+/** IEEEtypes_AssocRsp_t */
+typedef PACK_START struct _IEEEtypes_AssocRsp_t
+{
+ /** CapInfo */
+ u16 CapInfo;
+ /** StatusCode */
+ u16 StatusCode;
+ /** AID */
+ u16 AId;
+} PACK_END IEEEtypes_AssocRsp_t;
+
+/** IEEEtypes_ReAssocRqst_t */
+typedef PACK_START struct _IEEEtypes_ReAssocRqst_t
+{
+ /** CapInfo */
+ u16 CapInfo;
+ /** ListenInterval */
+ u16 ListenInterval;
+ /** Current APAddr */
+ u8 CurrentApAddr[ETH_ALEN];
+ /** IE Buffer */
+ u8 IEBuffer[0];
+} PACK_END IEEEtypes_ReAssocRqst_t;
+
+/** MrvlIEtypes_WapiInfoSet_t */
+typedef PACK_START struct _MrvlIEtypes_WapiInfoSet_t
+{
+ /** Type */
+ u16 Type;
+ /** Length */
+ u16 Len;
+ /** Multicast PN */
+ u8 MulticastPN[16];
+} PACK_END MrvlIEtypes_WapiInfoSet_t;
+
+/** MrvlIETypes_MgmtFrameSet_t */
+typedef PACK_START struct _MrvlIETypes_MgmtFrameSet_t
+{
+ /** Type */
+ u16 Type;
+ /** Length */
+ u16 Len;
+ /** Frame Control */
+ IEEEtypes_FrameCtl_t FrameControl;
+ /** Frame Contents */
+ u8 FrameContents[0];
+} PACK_END MrvlIETypes_MgmtFrameSet_t;
+
+/**Debug Type : Event */
+#define DEBUG_TYPE_EVENT 0
+/**Debug Type : Info */
+#define DEBUG_TYPE_INFO 1
+
+/** Major debug id: Authenticator */
+#define DEBUG_ID_MAJ_AUTHENTICATOR 1
+/** Minor debug id: PWK1 */
+#define DEBUG_MAJ_AUTH_MIN_PWK1 0
+/** Minor debug id: PWK2 */
+#define DEBUG_MAJ_AUTH_MIN_PWK2 1
+/** Minor debug id: PWK3 */
+#define DEBUG_MAJ_AUTH_MIN_PWK3 2
+/** Minor debug id: PWK4 */
+#define DEBUG_MAJ_AUTH_MIN_PWK4 3
+/** Minor debug id: GWK1 */
+#define DEBUG_MAJ_AUTH_MIN_GWK1 4
+/** Minor debug id: GWK2 */
+#define DEBUG_MAJ_AUTH_MIN_GWK2 5
+/** Minor debug id: station reject */
+#define DEBUG_MAJ_AUTH_MIN_STA_REJ 6
+/** Minor debug id: EAPOL_TR */
+#define DEBUG_MAJ_AUTH_MIN_EAPOL_TR 7
+
+/** Major debug id: Assoicate agent */
+#define DEBUG_ID_MAJ_ASSOC_AGENT 2
+/** Minor debug id: WPA IE*/
+#define DEBUG_ID_MAJ_ASSOC_MIN_WPA_IE 0
+/** Minor debug id: station reject */
+#define DEBUG_ID_MAJ_ASSOC_MIN_STA_REJ 1
+
+/** ether_hdr */
+typedef PACK_START struct
+{
+ /** dest address */
+ u8 da[ETH_ALEN];
+ /** src address */
+ u8 sa[ETH_ALEN];
+ /** header type */
+ u16 type;
+} PACK_END ether_hdr_t;
+
+/** 8021x header */
+typedef PACK_START struct
+{
+ /** protocol version*/
+ u8 protocol_ver;
+ /** packet type*/
+ u8 pckt_type;
+ /** packet len */
+ u8 pckt_body_len;
+} PACK_END Hdr_8021x_t;
+
+/** nonce size */
+#define NONCE_SIZE 32
+/** max wpa ie len */
+#define MAX_WPA_IE_LEN 64
+/** EAPOL mic size */
+#define EAPOL_MIC_SIZE 16
+
+/** EAPOL key message */
+typedef PACK_START struct
+{
+ /** Ether header */
+ ether_hdr_t Ether_Hdr;
+ /** 8021x header */
+ Hdr_8021x_t hdr_8021x;
+ /** desc_type */
+ u8 desc_type;
+ /** key info */
+ u16 k;
+ /** key length */
+ u16 key_length;
+ /** replay count */
+ u32 replay_cnt[2];
+ /** key nonce */
+ u8 key_nonce[NONCE_SIZE];
+ /** key IV */
+ u8 EAPOL_key_IV[16];
+ /** key RSC */
+ u8 key_RSC[8];
+ /** key ID */
+ u8 key_ID[8];
+ /** key MIC */
+ u8 key_MIC[EAPOL_MIC_SIZE];
+ /** key len */
+ u16 key_material_len;
+ /** key data */
+ u8 key_data[MAX_WPA_IE_LEN];
+} PACK_END EAPOL_KeyMsg_Debug_t;
+
+/** failure after receive EAPOL MSG2 PMK */
+#define REJECT_STATE_FAIL_EAPOL_2 1
+/** failure after receive EAPOL MSG4 PMK*/
+#define REJECT_STATE_FAIL_EAPOL_4 2
+/** failure after receive EAPOL Group MSG2 GWK */
+#define REJECT_STATE_FAIL_EAPOL_GROUP_2 3
+
+/** Fail reason: Invalid ie */
+#define IEEEtypes_REASON_INVALID_IE 13
+/** Fail reason: Mic failure */
+#define IEEEtypes_REASON_MIC_FAILURE 14
+
+/** station reject */
+typedef PACK_START struct
+{
+ /** reject state */
+ u8 reject_state;
+ /** reject reason */
+ u16 reject_reason;
+ /** station mac address */
+ u8 staMacAddr[ETH_ALEN];
+} PACK_END sta_reject_t;
+
+/** wpa_ie */
+typedef PACK_START struct
+{
+ /** station mac address */
+ u8 staMacAddr[ETH_ALEN];
+ /** wpa ie */
+ u8 wpa_ie[MAX_WPA_IE_LEN];
+} PACK_END wpaIe_t;
+
+/** initial state of the state machine */
+#define EAPOL_START 1
+/** sent eapol msg1, wait for msg2 from the client */
+#define EAPOL_WAIT_PWK2 2
+/** sent eapol msg3, wait for msg4 from the client */
+#define EAPOL_WAIT_PWK4 3
+/** sent eapol group key msg1, wait for group msg2 from the client */
+#define EAPOL_WAIT_GTK2 4
+/** eapol handshake complete */
+#define EAPOL_END 5
+
+/** eapol state */
+typedef PACK_START struct
+{
+ /** eapol state*/
+ u8 eapolState;
+ /** station address*/
+ u8 staMacAddr[ETH_ALEN];
+} PACK_END eapolState_t;
+
+/**debug Info */
+typedef PACK_START union
+{
+ /** eapol key message */
+ EAPOL_KeyMsg_Debug_t eapol_pwkMsg;
+ /** station reject*/
+ sta_reject_t sta_reject;
+ /** wpa ie */
+ wpaIe_t wpaIe;
+ /** eapol state */
+ eapolState_t eapol_state;
+} PACK_END dInfo;
+
+/** Event body : Debug */
+typedef PACK_START struct _EVENTBUF_DEBUG
+{
+ /** debug type */
+ u8 debugtype;
+ /** Major debug id */
+ u32 debugIdMajor;
+ /** Minor debug id */
+ u32 debugIdMinor;
+ /** debug Info */
+ dInfo info;
+} PACK_END EVENTBUF_DEBUG;
+#endif /* _UAP_H */