示例#1
0
/* pretty hex print a pkt buffer chain */
void prpkt(char *msg, void *drv, void *p0)
{
	void *p;

	if (msg && (msg[0] != '\0'))
		printf("%s: ", msg);

	for (p = p0; p; p = PKTNEXT(drv, p))
		prhex(NULL, PKTDATA(drv, p), PKTLEN(drv, p));
}
示例#2
0
/* pretty hex print a pkt buffer chain */
void prpkt(const char *msg, struct osl_info *osh, struct sk_buff *p0)
{
	struct sk_buff *p;

	if (msg && (msg[0] != '\0'))
		printf("%s:\n", msg);

	for (p = p0; p; p = p->next)
		prhex(NULL, p->data, p->len);
}
示例#3
0
void
wpa_calc_tpk(struct ether_addr *init_ea, struct ether_addr *resp_ea,
	struct ether_addr *bssid, uint8 *anonce, uint8* snonce,
                       uint8 *tpk, uint tpk_len)
{
	uchar key_input[SHA256_DIGEST_LENGTH];
	uchar data[128], tpk_buff[160];	/* TK_bits + 128, where TK_bits is 16 bytes for CCMP */
	char prefix[] = "TDLS PMK";
	uint data_len = 0;

	/* Generate TPK-Key-Input = SHA-256(min(SN, AN) || max(SN, AN)) first */
	bcopy(wpa_array_cmp(MIN_ARRAY, snonce, anonce,
	                    EAPOL_WPA_KEY_NONCE_LEN),
	      (char *)&data[0], EAPOL_WPA_KEY_NONCE_LEN);
	prhex("min(sn,an):", data, EAPOL_WPA_KEY_NONCE_LEN);
	data_len += EAPOL_WPA_KEY_NONCE_LEN;
	bcopy(wpa_array_cmp(MAX_ARRAY, snonce, anonce,
	                    EAPOL_WPA_KEY_NONCE_LEN),
	      (char *)&data[data_len], EAPOL_WPA_KEY_NONCE_LEN);
	prhex("max(sn,an):", &data[data_len], EAPOL_WPA_KEY_NONCE_LEN);
	data_len += EAPOL_WPA_KEY_NONCE_LEN;
	prhex("data:", &data[data_len], 2*EAPOL_WPA_KEY_NONCE_LEN);
	sha256(data, data_len, key_input, SHA256_DIGEST_LENGTH);
	prhex("input_key", key_input, SHA256_DIGEST_LENGTH);

	/* Create the the data portion:
	 * the lesser of the EAs, followed by the greater of the EAs,
	 * followed by BSSID
	 */
	data_len = 0;
	bcopy(prefix, data, strlen(prefix));
	prhex("prefix:", data, strlen(prefix));
	data_len  += strlen(prefix);

	bcopy(wpa_array_cmp(MIN_ARRAY, (uint8 *)init_ea, (uint8 *)resp_ea,
	                    ETHER_ADDR_LEN),
	      (char *)&data[data_len], ETHER_ADDR_LEN);
	prhex("min(init_ea, resp_ea:", &data[data_len], ETHER_ADDR_LEN);
	data_len += ETHER_ADDR_LEN;
	bcopy(wpa_array_cmp(MAX_ARRAY, (uint8 *)init_ea, (uint8 *)resp_ea,
	                    ETHER_ADDR_LEN),
	      (char *)&data[data_len], ETHER_ADDR_LEN);
	prhex("min(init_ea, resp_ea:", &data[data_len], ETHER_ADDR_LEN);
	data_len += ETHER_ADDR_LEN;
	bcopy((char*)bssid, (char *)&data[data_len], ETHER_ADDR_LEN);
	data_len += ETHER_ADDR_LEN;
	prhex("data", data, data_len);

	/* generate the TPK */
	hmac_sha256_n(key_input, SHA256_DIGEST_LENGTH, data, data_len, tpk_buff, tpk_len);
	bcopy(tpk_buff, (char*)tpk, tpk_len);
}
示例#4
0
int
wl_cfgnan_status_handler(struct net_device *ndev,
	struct bcm_cfg80211 *cfg, char *cmd, nan_cmd_data_t *cmd_data)
{
	wl_nan_ioc_t *nanioc = NULL;
	void *pxtlv;
	char *ptr = cmd;
	wl_nan_tlv_data_t tlv_data;
	s32 ret = BCME_OK;
	u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
	uint16 nanioc_size = sizeof(wl_nan_ioc_t) + NAN_IOCTL_BUF_SIZE;

	nanioc = kzalloc(nanioc_size, kflags);
	if (!nanioc) {
		WL_ERR((" memory allocation failed \n"));
		return -ENOMEM;
	}

	/*
	 * command to test
	 *
	 * wl: wl nan status
	 *
	 * wpa_cli: DRIVER NAN_STATUS
	 */

	/* nan status */
	nanioc->version = htod16(WL_NAN_IOCTL_VERSION);
	nanioc->id = htod16(WL_NAN_CMD_STATUS);
	pxtlv = nanioc->data;
	nanioc->len = NAN_IOCTL_BUF_SIZE;
	nanioc_size = sizeof(wl_nan_ioc_t) + sizeof(bcm_xtlv_t);
	ret = wldev_iovar_getbuf(ndev, "nan", nanioc, nanioc_size,
		cfg->ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
	if (unlikely(ret)) {
		WL_ERR((" nan status failed, error = %d \n", ret));
		goto fail;
	} else {
		WL_DBG((" nan status successful \n"));
	}

	/* unpack the tlvs */
	memset(&tlv_data, 0, sizeof(tlv_data));
	nanioc = (wl_nan_ioc_t *)cfg->ioctl_buf;
	if (g_nan_debug) {
		prhex(" nanioc->data: ", (uint8 *)nanioc->data, nanioc->len);
	}
	bcm_unpack_xtlv_buf(&tlv_data, nanioc->data, nanioc->len,
		wl_cfgnan_set_vars_cbfn);

	ptr += sprintf(ptr, CLUS_ID_PREFIX MACF, ETHER_TO_MACF(tlv_data.clus_id));
	ptr += sprintf(ptr, " " ROLE_PREFIX"%d", tlv_data.dev_role);
	ptr += sprintf(ptr, " " AMR_PREFIX);
	ptr += bcm_format_hex(ptr, tlv_data.amr, NAN_MASTER_RANK_LEN);
	ptr += sprintf(ptr, " " AMBTT_PREFIX"0x%x", tlv_data.ambtt);
	ptr += sprintf(ptr, " " HOP_COUNT_PREFIX"%d", tlv_data.hop_count);

	WL_DBG((" formatted string for userspace: %s, len: %zu \n",
		cmd, strlen(cmd)));

fail:
	if (nanioc) {
		kfree(nanioc);
	}
	if (tlv_data.svc_info.data) {
		kfree(tlv_data.svc_info.data);
		tlv_data.svc_info.data = NULL;
		tlv_data.svc_info.dlen = 0;
	}
	if (tlv_data.vend_info.data) {
		kfree(tlv_data.vend_info.data);
		tlv_data.vend_info.data = NULL;
		tlv_data.vend_info.dlen = 0;
	}

	return ret;
}
示例#5
0
s32
wl_cfgnan_notify_nan_status(struct bcm_cfg80211 *cfg,
	bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *event, void *data)
{
	s32 ret = BCME_OK;
	u16 data_len;
	u32 event_num;
	s32 event_type;
	nan_event_hdr_t nan_hdr;
	wl_nan_tlv_data_t tlv_data;
	u8 *buf = NULL;
	u32 buf_len;
	u8 *ptr;
	u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;

	if (!event || !data) {
		WL_ERR((" event data is NULL \n"));
		return -EINVAL;
	}

	event_type = ntoh32(event->event_type);
	event_num = ntoh32(event->reason);
	data_len = ntoh32(event->datalen);
	memset(&nan_hdr, 0, sizeof(nan_event_hdr_t));
	nan_hdr.event_subtype = event_num;

	WL_DBG((" nan event: type: %d num: %d len: %d \n",
		event_type, event_num, data_len));

	if (INVALID_NAN_EVENT(event_num)) {
		WL_ERR((" unsupported event, num: %d \n", event_num));
		return -EINVAL;
	}

	if (g_nan_debug) {
		WL_DBG((" event name: %s \n", nan_event_name[event_num]));
		WL_DBG((" event data: \n"));
		prhex(NULL, data, data_len);
	}

	/* unpack the tlvs */
	memset(&tlv_data, 0, sizeof(wl_nan_tlv_data_t));
	bcm_unpack_xtlv_buf(&tlv_data, data, data_len,
		wl_cfgnan_set_vars_cbfn);

	/*
	 * send as preformatted hex string
	 *
	 * EVENT_NAN <event_type> <tlv_hex_string>
	 */

	buf_len = NAN_IOCTL_BUF_SIZE;
	buf = ptr = kzalloc(buf_len, kflags);
	if (!buf) {
		WL_ERR((" memory allocation failed \n"));
		ret = -ENOMEM;
		goto fail;
	}

	switch (event_num) {
	case WL_NAN_EVENT_START:
	case WL_NAN_EVENT_JOIN:
	case WL_NAN_EVENT_STOP:
		ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " CLUS_ID_PREFIX MACF,
			nan_event_str[event_num], ETHER_TO_MACF(tlv_data.nstatus.cid));
		break;
	case WL_NAN_EVENT_ROLE:
		ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s "ROLE_PREFIX "%d "
			CLUS_ID_PREFIX MACF, nan_event_str[event_num],
			tlv_data.nstatus.role, ETHER_TO_MACF(tlv_data.nstatus.cid));
		break;
	case WL_NAN_EVENT_DISCOVERY_RESULT:
		ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " PUB_ID_PREFIX"%d "
			SUB_ID_PREFIX"%d " MAC_ADDR_PREFIX MACF,
			nan_event_str[event_num], tlv_data.pub_id, tlv_data.sub_id,
			ETHER_TO_MACF(tlv_data.mac_addr));
		if (tlv_data.svc_info.data && tlv_data.svc_info.dlen) {
			WL_DBG((" service info present \n"));
			if ((strlen(ptr) + tlv_data.svc_info.dlen) >= buf_len) {
				WL_ERR((" service info length = %d\n",
					tlv_data.svc_info.dlen));
				WL_ERR((" insufficent buffer to copy service info \n"));
				ret = -EOVERFLOW;
				goto fail;
			}
			ptr += sprintf(ptr, " %s", SVC_INFO_PREFIX);
			ptr += bcm_format_hex(ptr, tlv_data.svc_info.data,
				tlv_data.svc_info.dlen);
		} else {
			WL_DBG((" service info not present \n"));
		}

		if (tlv_data.vend_info.data && tlv_data.vend_info.dlen) {
			struct ether_addr *ea;
			u8 *data = tlv_data.vend_info.data;
			uint32 bitmap;
			u16 dlen = tlv_data.vend_info.dlen;
			chanspec_t chanspec;
			uint8 mapcontrol;
			uint8 proto;

			WL_DBG((" vendor info present \n"));
			if ((*data != NAN_ATTR_VENDOR_SPECIFIC) ||
				(dlen < NAN_VENDOR_HDR_SIZE)) {
				WL_ERR((" error in vendor info attribute \n"));
				ret = -EINVAL;
				goto fail;
			} else {
				WL_DBG((" vendor info not present \n"));
			}

			if (*(data + 6) == NAN_VENDOR_TYPE_RTT) {
				data += NAN_VENDOR_HDR_SIZE;
				ea = (struct ether_addr *)data;
				data += ETHER_ADDR_LEN;
				mapcontrol = *data++;
				proto = *data++;
				bitmap = *(uint32 *)data;
				data += 4;
				chanspec = *(chanspec_t *)data;
				ptr += sprintf(ptr, " "BITMAP_PREFIX"0x%x "CHAN_PREFIX"%d/%s",
					bitmap, wf_chspec_ctlchan(chanspec),
					wf_chspec_to_bw_str(chanspec));
				WL_DBG((" bitmap: 0x%x channel: %d bandwidth: %s \n", bitmap,
					wf_chspec_ctlchan(chanspec),
					wf_chspec_to_bw_str(chanspec)));
			}
		}
		break;
	case WL_NAN_EVENT_REPLIED:
		ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " PUB_ID_PREFIX"%d "
				MAC_ADDR_PREFIX MACF, nan_event_str[event_num],
				tlv_data.pub_id, ETHER_TO_MACF(tlv_data.mac_addr));
		break;
	case WL_NAN_EVENT_TERMINATED:
		ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " PUB_ID_PREFIX"%d ",
			nan_event_str[event_num], tlv_data.pub_id);
		break;
	case WL_NAN_EVENT_RECEIVE:
		ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " PUB_ID_PREFIX"%d "
				MAC_ADDR_PREFIX MACF, nan_event_str[event_num],
				tlv_data.pub_id, ETHER_TO_MACF(tlv_data.mac_addr));
		if (tlv_data.svc_info.data && tlv_data.svc_info.dlen) {
			WL_DBG((" service info present \n"));
			if ((strlen(ptr) + tlv_data.svc_info.dlen) >= buf_len) {
				WL_ERR((" service info length = %d\n",
					tlv_data.svc_info.dlen));
				WL_ERR((" insufficent buffer to copy service info \n"));
				ret = -EOVERFLOW;
				goto fail;
			}
			ptr += sprintf(ptr, " %s", SVC_INFO_PREFIX);
			ptr += bcm_format_hex(ptr, tlv_data.svc_info.data,
				tlv_data.svc_info.dlen);
		} else {
			WL_DBG((" service info not present \n"));
		}
		break;
	case WL_NAN_EVENT_SCAN_COMPLETE:
		ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " CLUS_ID_PREFIX MACF,
			nan_event_str[event_num], ETHER_TO_MACF(tlv_data.nstatus.cid));
		break;
	case WL_NAN_EVENT_STATUS_CHG:
		ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " CLUS_ID_PREFIX MACF,
			nan_event_str[event_num], ETHER_TO_MACF(tlv_data.nstatus.cid));
		break;
	case WL_NAN_EVENT_MERGE:
		ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " CLUS_ID_PREFIX MACF,
			nan_event_str[event_num], ETHER_TO_MACF(tlv_data.nstatus.cid));
		break;
	default:
		WL_ERR((" unknown event \n"));
		break;
	}

#ifdef WL_GENL
	/* send the preformatted string to the upper layer as event */
	WL_DBG((" formatted string for userspace: %s, len: %zu \n",
		buf, strlen(buf)));
	wl_genl_send_msg(bcmcfg_to_prmry_ndev(cfg), 0, buf, strlen(buf), 0, 0);
#endif /* WL_GENL */

fail:
	if (buf) {
		kfree(buf);
	}
	if (tlv_data.svc_info.data) {
		kfree(tlv_data.svc_info.data);
		tlv_data.svc_info.data = NULL;
		tlv_data.svc_info.dlen = 0;
	}
	if (tlv_data.vend_info.data) {
		kfree(tlv_data.vend_info.data);
		tlv_data.vend_info.data = NULL;
		tlv_data.vend_info.dlen = 0;
	}

	return ret;
}
示例#6
0
s32
wl_cfgnan_notify_proxd_status(struct bcm_cfg80211 *cfg,
	bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *event, void *data)
{
	s32 ret = BCME_OK;
	wl_nan_ranging_event_data_t *rdata;
	s32 status;
	u16 data_len;
	s32 event_type;
	s32 event_num;
	u8 *buf = NULL;
	u32 buf_len;
	u8 *ptr;
	u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
	s32 i;

	if (!event || !data) {
		WL_ERR((" event data is NULL \n"));
		return -EINVAL;
	}

	status = ntoh32(event->reason);
	event_type = ntoh32(event->event_type);
	event_num = ntoh32(event->reason);
	data_len = ntoh32(event->datalen);

	WL_DBG((" proxd event: type: %d num: %d len: %d \n",
		event_type, event_num, data_len));

	if (INVALID_PROXD_EVENT(event_num)) {
		WL_ERR((" unsupported event, num: %d \n", event_num));
		return -EINVAL;
	}

	if (g_nan_debug) {
		WL_DBG((" event name: WLC_E_PROXD_NAN_EVENT \n"));
		WL_DBG((" event data: \n"));
		prhex(NULL, data, data_len);
	}

	if (data_len < sizeof(wl_nan_ranging_event_data_t)) {
		WL_ERR((" wrong data len \n"));
		return -EINVAL;
	}

	rdata = (wl_nan_ranging_event_data_t *)data;

	WL_DBG((" proxd event: count:%d success_count:%d mode:%d \n",
		rdata->count, rdata->success_count, rdata->mode));

	if (g_nan_debug) {
		prhex(" event data: ", data, data_len);
	}

	buf_len = NAN_IOCTL_BUF_SIZE;
	buf = kzalloc(buf_len, kflags);
	if (!buf) {
		WL_ERR((" memory allocation failed \n"));
		return -ENOMEM;
	}

	for (i = 0; i < rdata->count; i++) {
		if (&rdata->rr[i] == NULL) {
			ret = -EINVAL;
			goto fail;
		}

		ptr = buf;
		WL_DBG((" ranging data for mac:"MACDBG" \n",
			MAC2STRDBG(rdata->rr[i].ea.octet)));
		ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " MAC_ADDR_PREFIX MACF
			" "STATUS_PREFIX"%s", EVENT_RTT_STATUS_STR,
			ETHER_TO_MACF(rdata->rr[i].ea), (rdata->rr[i].status == 1) ?
			"success" : "fail");

		if (rdata->rr[i].status == 1) {
			/* add tsf and distance only if status is success */
			ptr += sprintf(ptr, " "TIMESTAMP_PREFIX"0x%x "
				DISTANCE_PREFIX"%d.%04d", rdata->rr[i].timestamp,
				rdata->rr[i].distance >> 4,
				((rdata->rr[i].distance & 0x0f) * 625));
		}

#ifdef WL_GENL
		/* send the preformatted string to the upper layer as event */
		WL_DBG((" formatted string for userspace: %s, len: %zu \n",
			buf, strlen(buf)));
		wl_genl_send_msg(bcmcfg_to_prmry_ndev(cfg), 0, buf, strlen(buf), 0, 0);
#endif /* WL_GENL */
	}