uapevent/0000700000000000000000000000000011450031471011365 5ustar rootrootuapevent/uapevent.c0000600000000000000000000006640711450031217013375 0ustar rootroot/** @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 #include #include #include #include #include #include #include #include #include #include #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; } uapevent/uapevent.h0000600000000000000000000003217211450031217013372 0ustar rootroot/** @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 */ uapevent/Makefile0000700000000000000000000000177211450031267013042 0ustar rootroot# File : uapevent/Makefile # # Copyright (C) 2008, Marvell International Ltd. # All Rights Reserved # Path to the top directory of the wlan distribution PATH_TO_TOP = ../.. # Determine how we should copy things to the install directory ABSPATH := $(filter /%, $(INSTALLDIR)) RELPATH := $(filter-out /%, $(INSTALLDIR)) INSTALLPATH := $(ABSPATH) ifeq ($(strip $(INSTALLPATH)),) INSTALLPATH := $(PATH_TO_TOP)/$(RELPATH) endif # Override CFLAGS for application sources, remove __ kernel namespace defines CFLAGS := $(filter-out -D__%, $(EXTRA_CFLAGS)) #CFLAGS += -DAP22 -fshort-enums CFLAGS += -Wall #ECHO = @ LIBS = -lrt .PHONY: default tags all OBJECTS = uapevent.o HEADERS = uapevent.h TARGET = uapevent build default: $(TARGET) @cp -f $(TARGET) $(INSTALLPATH) all : tags default $(TARGET): $(OBJECTS) $(HEADERS) $(ECHO)$(CC) $(LIBS) -o $@ $(OBJECTS) %.o: %.c $(HEADERS) $(ECHO)$(CC) $(CFLAGS) -c -o $@ $< tags: ctags -R -f tags.txt clean: $(ECHO)$(RM) $(OBJECTS) $(TARGET) $(ECHO)$(RM) tags.txt