/* ipwps_private_api.c - WSC Private API implementation */ /* * Copyright (c) 2008 Wind River Systems, Inc. * * The right to copy, distribute, modify, or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. * */ /* modification history -------------------- 01a,13Jan09,mry Created */ /* DESCRIPTION: * =========== * Implements the IPWPS private APIs used by IPWPS related modules. */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipwps_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include "ipwps_debug.h" #include "ipwps_public.h" #include "ipwps_private_api.h" /* **************************************************************************** * 4 DEFINES **************************************************************************** */ /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* * **************************************************************************** * 8 DATA **************************************************************************** */ /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipwps_send_timeout_event *=========================================================================== * Description: . * Parameters: * Returns: * */ IP_PUBLIC Ip_err ipwps_send_timeout_event(Ipwps_msg_type_wpstimeout tmo_evtype) { Ipwps_ipd_msg *request, *response; Ip_err rc = IPCOM_SUCCESS; if (!IPWPS_ISVALID_TIMEOUT_EVENT_TYPE(tmo_evtype)) { IPCOM_LOG1(ERR, "ipwps_send_timeout_event :: Invalid tmo_evtype %d", tmo_evtype); return IPCOM_ERR_INVALID_ARG; } request = ipcom_calloc(1, sizeof(Ipwps_ipd_msg)); response = ipcom_calloc(1, sizeof(Ipwps_ipd_msg)); if (!request || !response ) { rc = IPCOM_ERR_NO_MEMORY; goto done_timeout_event; } IPWPS_PREPARE_IPD_MSG(request, IPWPS_IPD_EVENT_WPSTIMEOUT, IPCOM_SUCCESS, tmo_evtype); rc = ipcom_ipd_datamsg(IPWPS_PROCESS_NAME,request,sizeof(Ipwps_ipd_msg),response,sizeof(Ipwps_ipd_msg)); if (rc != IPCOM_SUCCESS) { IPCOM_LOG1(ERR, "ipwps_send_timeout_event :: ipcom_ipd_datamsg() failed, rc = %d", rc); goto done_timeout_event; } rc = response->ipd_msg.msgerr; if (rc < 0) { IPCOM_LOG2(ERR, "ipwps_send_timeout_event :: failure response msgerr = %d (%s)", rc, ipcom_err_string(rc)); } done_timeout_event: if (response) ipcom_free(response); if (request) ipcom_free(request); return rc; } /* *=========================================================================== * ipwps_notify_eapol_start *=========================================================================== * Description: . * Parameters: * Returns: * */ IP_GLOBAL Ip_err ipwps_notify_eapol_start(char* wls_if, Ip_u32 ip8021x_instance, Ip_u8* peer_eth_addr) { Ipwps_ipd_msg *request, *response; Ip_err rc = IPCOM_SUCCESS; if (!wls_if || !peer_eth_addr) return IPCOM_ERR_INVALID_ARG; IPCOM_LOG9(DEBUG2, "%s: wls_if : %s, ip8021x_inst: %d, peer_addr: %.2x %.2x %.2x %.2x %.2x %.2x\n", __FUNCTION__, wls_if, ip8021x_instance, peer_eth_addr[0], peer_eth_addr[1], peer_eth_addr[2], peer_eth_addr[3], peer_eth_addr[4], peer_eth_addr[5]); request = ipcom_calloc(1, sizeof(Ipwps_ipd_msg)); response = ipcom_calloc(1, sizeof(Ipwps_ipd_msg)); if (!request || !response ) { rc = IPCOM_ERR_NO_MEMORY; goto done_eapol_event; } IPWPS_PREPARE_IPD_MSG(request, IPWPS_IPD_EVENT_WPSPROTO, IPCOM_SUCCESS, IPWPS_MSG_TYPE_WPSPROTO_EAPOL_NOTIFY); request->wps_msg_data.wps_eapol_notify.eapol_event = IPWPS_EAPOL_EVENT_RCV_START; ipcom_memcpy(request->wps_msg_data.wps_eapol_notify.if_name, wls_if, IPWPS_MAX_IFNAME); request->wps_msg_data.wps_eapol_notify.ip8021x_inst = ip8021x_instance; ipcom_memcpy(request->wps_msg_data.wps_eapol_notify.peeraddr, peer_eth_addr, 6); rc = ipcom_ipd_datamsg(IPWPS_PROCESS_NAME,request,sizeof(Ipwps_ipd_msg),response,sizeof(Ipwps_ipd_msg)); if (rc != IPCOM_SUCCESS) { IPCOM_LOG2(ERR, "ipwps_handle_wsc_event :: ipcom_ipd_datamsg() failed, rc = %d (%s)", rc, ipcom_err_string(rc)); goto done_eapol_event; } rc = response->ipd_msg.msgerr; if (rc < 0) { IPCOM_LOG2(ERR, "ipwps_handle_wsc_event :: failure response msgerr = %d (%s)", rc, ipcom_err_string(rc)); } done_eapol_event: if (response) ipcom_free(response); if (request) ipcom_free(request); return rc; } /* *=========================================================================== * ipwps_create_proto_msg_data *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL Ipwps_wsc_proto_msg *ipwps_create_proto_msg_data(int event_or_rc, Ip_u32 datasize, Ip_u8 *data) { Ipwps_wsc_proto_msg *msg_data; if (datasize > IPWPS_PROTO_MSG_DATALEN_MAX) { IPCOM_LOG2(CRIT, "ipwps_create_proto_msg_data :: requested datasize %d > max len %d", datasize, IPWPS_PROTO_MSG_DATALEN_MAX); return IP_NULL; } if (datasize && !data) { IPCOM_LOG1(ERR, "ipwps_create_proto_msg_data :: null data for non zero datasize %d", datasize); return IP_NULL; } msg_data = ipcom_calloc(1, sizeof(Ipwps_wsc_proto_msg)); if (msg_data) { msg_data->event_or_rc = event_or_rc; msg_data->proto_data.len = datasize; if (datasize) ipcom_memcpy(msg_data->proto_data.data, data, datasize); } return msg_data; } /* *=========================================================================== * ipwps_wsc_event_name *=========================================================================== * Description: . * Parameters: * Returns: * */ IP_GLOBAL char * ipwps_wsc_event_name(Ipwps_wsc_event wsc_event) { char *name = "UNKNOWN"; switch (wsc_event) { case IPWPS_WSC_EVENT_RCV_ID_RESP: name = "IPWPS_WSC_EVENT_RCV_ID_RESP"; break; case IPWPS_WSC_EVENT_RCV_WSC_START: name = "IPWPS_WSC_EVENT_RCV_WSC_START"; break; case IPWPS_WSC_EVENT_RCV_WSC_ACK: name = "IPWPS_WSC_EVENT_RCV_WSC_ACK"; break; case IPWPS_WSC_EVENT_RCV_WSC_NACK: name = "IPWPS_WSC_EVENT_RCV_WSC_NACK"; break; case IPWPS_WSC_EVENT_RCV_WSC_MSG: name = "IPWPS_WSC_EVENT_RCV_WSC_MSG"; break; case IPWPS_WSC_EVENT_RCV_WSC_DONE: name = "IPWPS_WSC_EVENT_RCV_WSC_DONE"; break; case IPWPS_WSC_EVENT_RCV_EAP_FAIL: name = "IPWPS_WSC_EVENT_RCV_EAP_FAIL"; break; default: IP_PANIC(); break; } return name; } /* *=========================================================================== * ipwps_handle_wsc_event *=========================================================================== * Description: . * Parameters: * Returns: * return code from ipd message or IPCOM_ERR_TIMEOUT in case of response timeout * or error indication. * */ IP_GLOBAL Ip_err ipwps_handle_wsc_event ( Ipwps_wsc_proto_msg *wsc_rcvd_msg, Ipwps_wsc_rc *wsc_rc, Ipwps_proto_data **wsc_resp_data ) { Ipwps_ipd_msg *request, *response; Ipwps_proto_data *resp_data = IP_NULL; Ip_err rc = IPCOM_SUCCESS; ip_assert(wsc_rcvd_msg); #ifdef IPWPS_DEBUG_WSC_EVENTS IPCOM_LOG2(DEBUG2, "ipwps_handle_wsc_event :: Received event %s with datasize %d", ipwps_wsc_event_name((Ipwps_wsc_event)wsc_rcvd_msg->event_or_rc), wsc_rcvd_msg->proto_data.len); ipwps_dump_data("ipwps_handle_wsc_event :: data:", wsc_rcvd_msg->proto_data.data, wsc_rcvd_msg->proto_data.len); #endif ip_assert(wsc_rc); ip_assert(wsc_resp_data); request = ipcom_calloc(1, sizeof(Ipwps_ipd_msg)); response = ipcom_calloc(1, sizeof(Ipwps_ipd_msg)); if (!request || !response ) { rc = IPCOM_ERR_NO_MEMORY; goto done_wsc_event; } IPWPS_PREPARE_IPD_MSG(request, IPWPS_IPD_EVENT_WPSPROTO, IPCOM_SUCCESS, IPWPS_MSG_TYPE_WPSPROTO_WSCNOTIFY); ipcom_memcpy(&request->wps_msg_data.wps_proto_msg, wsc_rcvd_msg, sizeof(Ipwps_wsc_proto_msg)); rc = ipcom_ipd_datamsg(IPWPS_PROCESS_NAME,request,sizeof(Ipwps_ipd_msg),response,sizeof(Ipwps_ipd_msg)); if (rc != IPCOM_SUCCESS) { IPCOM_LOG1(ERR, "ipwps_handle_wsc_event :: ipcom_ipd_datamsg() failed, rc = %d", rc); goto done_wsc_event; } rc = response->ipd_msg.msgerr; if (rc < 0) { IPCOM_LOG1(ERR, "ipwps_handle_wsc_event :: failure response msgerr = %d", rc); goto done_wsc_event; } if (response->wps_msg_type.wpsproto != IPWPS_MSG_TYPE_WPSPROTO_WSCRESPONSE) { IPCOM_LOG1(ERR, "ipwps_handle_wsc_event :: unexpected response wps_msg_type = %d", (response->wps_msg_type.overlay)); rc = IPCOM_ERR_FAILED; goto done_wsc_event; } *wsc_rc = (Ipwps_wsc_rc)response->wps_msg_data.wps_proto_msg.event_or_rc; if (response->wps_msg_data.wps_proto_msg.proto_data.len == 0) goto done_wsc_event; #ifdef IPWPS_DEBUG_WSC_EVENTS IPCOM_LOG3(DEBUG2, "ipwps_handle_wsc_event :: response rc = %d (%s), wsc_rc = %d", rc, ipcom_err_string(rc), *wsc_rc); #endif resp_data = ipcom_calloc(1, sizeof(Ipwps_proto_data)); if (!resp_data) { IPCOM_LOG0(CRIT, "ipwps_handle_wsc_event :: failed to alloc resp_data"); rc = IPCOM_ERR_NO_MEMORY; goto done_wsc_event; } ipcom_memcpy(resp_data, &response->wps_msg_data.wps_proto_msg.proto_data, sizeof(Ipwps_proto_data)); done_wsc_event: if (response) ipcom_free(response); if (request) ipcom_free(request); *wsc_resp_data = resp_data; return rc; } /* *=========================================================================== * ipwps_dump_data *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL void ipwps_dump_data(char *prefix_str, Ip_u8* buf, int len) { char* str; int i; if (!buf) { IPCOM_LOG1(DEBUG2, "ipwps_dump_data :: null buffer, len = %d", len); return; } str = ipcom_calloc(1, len*2+1); if (str) { for(i=0; i