Пример #1
0
/* decode home realm query */
int bcm_decode_hspot_anqp_nai_home_realm_query(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_nai_home_realm_query_t *realm)
{
	int i;
	WL_PRPKT("packet for hotspot NAI home realm decoding",
		bcm_decode_current_ptr(pkt), bcm_decode_remaining(pkt));

	memset(realm, 0, sizeof(*realm));

	if (bcm_decode_is_zero_length(pkt))
		return TRUE;

	if (!bcm_decode_byte(pkt, &realm->count)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}

	if (realm->count > BCM_DECODE_HSPOT_ANQP_MAX_HOME_REALM) {
		WL_ERROR(("home realm count %d > %d\n", realm->count,
			BCM_DECODE_HSPOT_ANQP_MAX_HOME_REALM));
		return FALSE;
	}

	for (i = 0; i < realm->count; i++) {
		if (!pktDecodeHspotAnqpNaiHomeRealmQueryData(pkt,
			&realm->data[i])) {
			return FALSE;
		}
	}

	realm->isDecodeValid = TRUE;
	return TRUE;
}
Пример #2
0
/* decode operating class indication */
int bcm_decode_hspot_anqp_operating_class_indication(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_operating_class_indication_t *opClassList)
{
	int count;

	WL_PRPKT("packet for hotspot operating class indication decoding",
		bcm_decode_current_ptr(pkt), bcm_decode_remaining(pkt));

	memset(opClassList, 0, sizeof(*opClassList));

	if (bcm_decode_is_zero_length(pkt))
		return TRUE;

	count = bcm_decode_remaining(pkt);
	if (count > BCM_DECODE_HSPOT_ANQP_MAX_OPCLASS_LIST_SIZE) {
		WL_ERROR(("operating class indication list size is too large %d\n",
			BCM_DECODE_HSPOT_ANQP_MAX_OPCLASS_LIST_SIZE));
		return FALSE;
	}

	if (!bcm_decode_bytes(pkt, count, (uint8 *)opClassList->opClass)) {
		WL_ERROR(("bcm_decode_bytes failed"));
		return FALSE;
	}

	opClassList->opClassLen = count;
	opClassList->isDecodeValid = TRUE;
	return TRUE;
}
Пример #3
0
/* decode capability list */
int bcm_decode_hspot_anqp_capability_list(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_capability_list_t *capList)
{
	int count, i;

	WL_PRPKT("packet for hotspot capability list decoding",
		bcm_decode_current_ptr(pkt), bcm_decode_remaining(pkt));

	memset(capList, 0, sizeof(*capList));

	if (bcm_decode_is_zero_length(pkt))
		return TRUE;

	count =  bcm_decode_remaining(pkt);
	for (i = 0; i < count; i++) {
		if (i >= BCM_DECODE_ANQP_MAX_LIST_SIZE) {
			WL_ERROR(("truncating capability list to %d\n",
				BCM_DECODE_ANQP_MAX_LIST_SIZE));
			return FALSE;
		}
		(void)bcm_decode_byte(pkt, &capList->capId[capList->capLen++]);
	}

	capList->isDecodeValid = TRUE;
	return TRUE;
}
Пример #4
0
/* decode connection capability */
int bcm_decode_hspot_anqp_connection_capability(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_connection_capability_t *cap)
{
	WL_PRPKT("packet for hotspot connection capability decoding",
		bcm_decode_current_ptr(pkt), bcm_decode_remaining(pkt));

	memset(cap, 0, sizeof(*cap));

	if (bcm_decode_is_zero_length(pkt))
		return TRUE;

	while (bcm_decode_remaining(pkt) > 0 &&
		cap->numConnectCap < BCM_DECODE_HSPOT_ANQP_MAX_CONNECTION_CAPABILITY) {
		if (!pktDecodeHspotAnqpProtoPortTuple(pkt,
			&cap->tuple[cap->numConnectCap])) {
			return FALSE;
		}
		else {
			cap->numConnectCap++;
		}
	}

	cap->isDecodeValid = TRUE;
	return TRUE;
}
Пример #5
0
/* decode operator friendly name */
int bcm_decode_hspot_anqp_operator_friendly_name(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_operator_friendly_name_t *op)
{
	WL_PRPKT("packet for hotspot operator friendly name decoding",
		bcm_decode_current_ptr(pkt), bcm_decode_remaining(pkt));

	memset(op, 0, sizeof(*op));

	if (bcm_decode_is_zero_length(pkt))
		return TRUE;

	while (bcm_decode_remaining(pkt) > 0 &&
		op->numName < BCM_DECODE_HSPOT_ANQP_MAX_OPERATOR_NAME) {
		if (!pktDecodeHspotAnqpOperatorNameDuple(pkt,
			&op->duple[op->numName])) {
			return FALSE;
		}
		else {
			op->numName++;
		}
	}

	op->isDecodeValid = TRUE;
	return TRUE;
}
Пример #6
0
/* decode icon request */
int bcm_decode_hspot_anqp_icon_request(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_icon_request_t *request)
{
	WL_PRPKT("packet for hotspot icon request decoding",
		bcm_decode_current_ptr(pkt), bcm_decode_remaining(pkt));

	memset(request, 0, sizeof(*request));

	if (bcm_decode_is_zero_length(pkt))
		return TRUE;

	request->filenameLength = bcm_decode_remaining(pkt);
	if (request->filenameLength > BCM_DECODE_HSPOT_ANQP_MAX_ICON_FILENAME_LENGTH) {
		WL_ERROR(("icon filename exceeds buffer %d > %d\n",
			request->filenameLength, BCM_DECODE_HSPOT_ANQP_MAX_ICON_FILENAME_LENGTH));
		return FALSE;
	}
	if (!bcm_decode_bytes(pkt, request->filenameLength, (uint8 *)request->filename)) {
		WL_ERROR(("bcm_decode_bytes failed"));
		return FALSE;
	}
	request->filename[request->filenameLength] = 0;
	request->isDecodeValid = TRUE;
	return TRUE;

}
Пример #7
0
static void testEncode(void)
{
	uint8 adBuffer[BUFFER_SIZE];
	pktEncodeT ad;

	TEST(pktEncodeInit(&enc, sizeof(buffer), buffer), "pktEncodeInit failed");

	TEST(pktEncodeIeHotspotIndication2(&enc, TRUE, TRUE, HSPOT_RELEASE_2),
		"pktEncodeIeHotspotIndication2 failed");

	TEST(pktEncodeIeInterworking(&enc,
		IW_ANT_WILDCARD_NETWORK, FALSE, FALSE, FALSE, FALSE,
		TRUE, 0, 0, (struct ether_addr *)"\xff\xff\xff\xff\xff\xff"),
		"pktEncodeIeInterworking failed");

	TEST(pktEncodeInit(&ad, sizeof(adBuffer), adBuffer), "pktEncodeInit failed");
	TEST(pktEncodeIeAdvertisementProtocolTuple(&ad,
		ADVP_PAME_BI_DEPENDENT, 0xff, ADVP_ANQP_PROTOCOL_ID),
		"pktEncodeIeAdvertisementProtocolTuple failed");
	TEST(pktEncodeIeAdvertiseProtocol(&enc, pktEncodeLength(&ad), pktEncodeBuf(&ad)),
		"pktEncodeIeAdvertiseProtocol failed");

	TEST(pktEncodeIeRoamingConsortium(&enc, 0xff, 3, (uint8 *)"\x00\x11\x22",
		4, (uint8 *)"\x55\x66\x77\x88", 4, (uint8 *)"\xaa\xbb\xcc\xdd"),
		"pktEncodeIeRoamingConsortium failed");

	TEST(pktEncodeIeExtendedCapabilities(&enc, 0x80000000),
		"pktEncodeIeExtendedCapabilities failed");

	WL_PRPKT("encoded IEs",	pktEncodeBuf(&enc), pktEncodeLength(&enc));
}
Пример #8
0
/* decode WAN metrics */
int bcm_decode_hspot_anqp_wan_metrics(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_wan_metrics_t *wanMetrics)
{
	uint8 wanInfo;

	WL_PRPKT("packet for hotspot WAN metrics decoding",
		bcm_decode_current_ptr(pkt), bcm_decode_remaining(pkt));

	memset(wanMetrics, 0, sizeof(*wanMetrics));

	if (bcm_decode_is_zero_length(pkt))
		return TRUE;

	if (!bcm_decode_byte(pkt, &wanInfo)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}

	wanMetrics->linkStatus =
		(wanInfo & HSPOT_WAN_LINK_STATUS_MASK) >> HSPOT_WAN_LINK_STATUS_SHIFT;
	wanMetrics->symmetricLink =
		(wanInfo & HSPOT_WAN_SYMMETRIC_LINK_MASK) >> HSPOT_WAN_SYMMETRIC_LINK_SHIFT;
	wanMetrics->atCapacity =
		(wanInfo & HSPOT_WAN_AT_CAPACITY_MASK) >> HSPOT_WAN_AT_CAPACITY_SHIFT;

	if (!bcm_decode_le32(pkt, &wanMetrics->dlinkSpeed)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}

	if (!bcm_decode_le32(pkt, &wanMetrics->ulinkSpeed)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}

	if (!bcm_decode_byte(pkt, &wanMetrics->dlinkLoad)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}

	if (!bcm_decode_byte(pkt, &wanMetrics->ulinkLoad)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}

	if (!bcm_decode_le16(pkt, &wanMetrics->lmd)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}

	wanMetrics->dlinkAvailable = wanMetrics->dlinkSpeed -
		wanMetrics->dlinkSpeed * wanMetrics->dlinkLoad / 255;
	wanMetrics->ulinkAvailable = wanMetrics->ulinkSpeed -
		wanMetrics->ulinkSpeed * wanMetrics->ulinkLoad / 255;
	wanMetrics->isDecodeValid = TRUE;
	return TRUE;
}
Пример #9
0
/* decode icon binary file */
int bcm_decode_hspot_anqp_icon_binary_file(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_icon_binary_file_t *icon)
{
	WL_PRPKT("packet for hotspot icon binary file decoding",
		bcm_decode_current_ptr(pkt), bcm_decode_remaining(pkt));

	memset(icon, 0, sizeof(*icon));

	if (bcm_decode_is_zero_length(pkt))
		return TRUE;

	if (!bcm_decode_byte(pkt, &icon->status)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}

	if (!bcm_decode_byte(pkt, &icon->typeLength)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}
	if (icon->typeLength > bcm_decode_remaining(pkt)) {
		WL_ERROR(("icon type length exceeds packet %d > %d\n",
			icon->typeLength, bcm_decode_remaining(pkt)));
		return FALSE;
	}
	if (icon->typeLength > BCM_DECODE_HSPOT_ANQP_MAX_ICON_TYPE_LENGTH) {
		WL_ERROR(("icon type exceeds buffer %d > %d\n",
			icon->typeLength, BCM_DECODE_HSPOT_ANQP_MAX_ICON_TYPE_LENGTH));
		return FALSE;
	}
	if (icon->typeLength > 0 &&
		!bcm_decode_bytes(pkt, icon->typeLength, (uint8 *)icon->type)) {
		WL_ERROR(("bcm_decode_bytes failed"));
		return FALSE;
	}
	icon->type[icon->typeLength] = 0;

	if (!bcm_decode_le16(pkt, &icon->binaryLength)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}
	if (icon->binaryLength > bcm_decode_remaining(pkt)) {
		WL_ERROR(("icon binary length exceeds packet %d > %d\n",
			icon->binaryLength, bcm_decode_remaining(pkt)));
		return FALSE;
	}
	if (icon->binaryLength > 0 &&
		!bcm_decode_bytes(pkt, icon->binaryLength, (uint8 *)icon->binary)) {
		WL_ERROR(("bcm_decode_bytes failed"));
		return FALSE;
	}

	icon->isDecodeValid = TRUE;
	return TRUE;
}
Пример #10
0
static void testDecodeCorruptLength(void)
{
	pktDecodeT dec;
	pktIeT ie;
	uint8 *lenPtr;
	uint8 save;

	TEST(pktDecodeInit(&dec, pktEncodeLength(&enc),
		pktEncodeBuf(&enc)), "pktDecodeInit failed");
	WL_PRPKT("decode packet", pktDecodeBuf(&dec), pktDecodeBufLength(&dec));

	lenPtr = &pktDecodeBuf(&dec)[1];
	save = *lenPtr;
	*lenPtr += 1;
	TEST(pktDecodeIe(&dec, &ie) == 1, "pktDecodeIe failed");
	*lenPtr = 0xff;
	TEST(pktDecodeIe(&dec, &ie) == 0, "pktDecodeIe failed");
	*lenPtr = save;
}
Пример #11
0
/* decode anonymous NAI */
int bcm_decode_hspot_anqp_anonymous_nai(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_anonymous_nai_t *anonymous)
{
	WL_PRPKT("packet for hotspot anonymous NAI decoding",
		bcm_decode_current_ptr(pkt), bcm_decode_remaining(pkt));

	memset(anonymous, 0, sizeof(*anonymous));

	if (bcm_decode_is_zero_length(pkt))
		return TRUE;

	if (!bcm_decode_le16(pkt, &anonymous->naiLen)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}

	if (anonymous->naiLen > bcm_decode_remaining(pkt)) {
		WL_ERROR(("anonymous NAI length exceeds packet %d > %d\n",
			anonymous->naiLen, bcm_decode_remaining(pkt)));
		return FALSE;
	}

	if (anonymous->naiLen > BCM_DECODE_HSPOT_ANQP_MAX_NAI_SIZE) {
		WL_ERROR(("anonymous NAI exceeds buffer %d > %d\n",
			anonymous->naiLen, BCM_DECODE_HSPOT_ANQP_MAX_NAI_SIZE));
		return FALSE;
	}

	if (!bcm_decode_bytes(pkt, anonymous->naiLen, (uint8 *)anonymous->nai)) {
		WL_ERROR(("bcm_decode_bytes failed"));
		return FALSE;
	}

	anonymous->nai[anonymous->naiLen] = 0;
	anonymous->isDecodeValid = TRUE;
	return TRUE;
}
Пример #12
0
/* decode WNM-notification request for deauthentication imminent */
int bcm_decode_wnm_deauthentication_imminent(bcm_decode_t *pkt,
	bcm_decode_wnm_deauthentication_imminent_t *wnm)
{
	uint8 byte, len;
	uint8 oui[WFA_OUI_LEN];

	WL_PRPKT("packet for WNM deauthentication imminent decoding",
		bcm_decode_buf(pkt), bcm_decode_buf_length(pkt));

	memset(wnm, 0, sizeof(*wnm));

	if (!bcm_decode_byte(pkt, &byte) || byte != DOT11_ACTION_CAT_WNM) {
		WL_ERROR(("WNM action category\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &byte) || byte != DOT11_WNM_ACTION_NOTFCTN_REQ) {
		WL_ERROR(("WNM notifcation request\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &wnm->dialogToken)) {
		WL_ERROR(("dialog token\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &byte) || byte != HSPOT_WNM_TYPE) {
		WL_ERROR(("WNM type\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &byte) || byte != DOT11_MNG_VS_ID) {
		WL_ERROR(("vendor specific ID\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &len) || len < 8) {
		WL_ERROR(("length\n"));
		return FALSE;
	}
	if (len > bcm_decode_remaining(pkt)) {
		WL_ERROR(("length exceeds packet %d > %d\n",
			len, bcm_decode_remaining(pkt)));
		return FALSE;
	}
	if (!bcm_decode_bytes(pkt, WFA_OUI_LEN, oui) ||
		memcmp(oui, WFA_OUI, WFA_OUI_LEN) != 0) {
		WL_ERROR(("WFA OUI\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &byte) ||
		byte != HSPOT_WNM_DEAUTHENTICATION_IMMINENT) {
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &wnm->reason)) {
		WL_ERROR(("deauth reason\n"));
		return FALSE;
	}
	if (!bcm_decode_le16(pkt, &wnm->reauthDelay)) {
		WL_ERROR(("reauth delay\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &wnm->urlLength) ||
		wnm->urlLength > bcm_decode_remaining(pkt)) {
		WL_ERROR(("URL length\n"));
		return FALSE;
	}
	if (wnm->urlLength > 0) {
		bcm_decode_bytes(pkt, wnm->urlLength, (uint8 *)wnm->url);
	}
	wnm->url[wnm->urlLength] = 0;

	return TRUE;
}
Пример #13
0
/* decode WNM-notification request for subscription remediation */
int bcm_decode_wnm_subscription_remediation(
	bcm_decode_t *pkt, bcm_decode_wnm_subscription_remediation_t *wnm)
{
	uint8 byte, len;
	uint8 oui[WFA_OUI_LEN];

	WL_PRPKT("packet for WNM subscription remediation decoding",
		bcm_decode_buf(pkt), bcm_decode_buf_length(pkt));

	memset(wnm, 0, sizeof(*wnm));

	if (!bcm_decode_byte(pkt, &byte) || byte != DOT11_ACTION_CAT_WNM) {
		WL_ERROR(("WNM action category\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &byte) || byte != DOT11_WNM_ACTION_NOTFCTN_REQ) {
		WL_ERROR(("WNM notifcation request\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &wnm->dialogToken)) {
		WL_ERROR(("dialog token\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &byte) || byte != HSPOT_WNM_TYPE) {
		WL_ERROR(("WNM type\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &byte) || byte != DOT11_MNG_VS_ID) {
		WL_ERROR(("vendor specific ID\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &len) || len < 6) {
		WL_ERROR(("length\n"));
		return FALSE;
	}
	if (len > bcm_decode_remaining(pkt)) {
		WL_ERROR(("length exceeds packet %d > %d\n",
			len, bcm_decode_remaining(pkt)));
		return FALSE;
	}
	if (!bcm_decode_bytes(pkt, WFA_OUI_LEN, oui) ||
		memcmp(oui, WFA_OUI, WFA_OUI_LEN) != 0) {
		WL_ERROR(("WFA OUI\n"));
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &byte) ||
		byte != HSPOT_WNM_SUBSCRIPTION_REMEDIATION) {
		return FALSE;
	}
	if (!bcm_decode_byte(pkt, &wnm->urlLength) ||
		wnm->urlLength > bcm_decode_remaining(pkt)) {
		WL_ERROR(("URL length\n"));
		return FALSE;
	}
	if (wnm->urlLength > 0) {
		bcm_decode_bytes(pkt, wnm->urlLength, (uint8 *)wnm->url);
	}
	wnm->url[wnm->urlLength] = 0;
	if (bcm_decode_remaining(pkt) > 0 &&
		bcm_decode_byte(pkt, &wnm->serverMethod)) {
	}

	return TRUE;
}
Пример #14
0
static void testDecode(void)
{
	pktDecodeT dec;
	pktIeT ie;
	pktDecodeT dec1;
	pktHotspotIndicationT hotspot;
	pktInterworkingT interworking;
	pktAdvertisementProtocolT advertise;
	pktRoamingConsortiumT roam;
	uint32 cap;

	TEST(pktDecodeInit(&dec, pktEncodeLength(&enc),
		pktEncodeBuf(&enc)), "pktDecodeInit failed");
	WL_PRPKT("decode packet", pktDecodeBuf(&dec), pktDecodeBufLength(&dec));

	TEST(pktDecodeIe(&dec, &ie) == 5, "pktDecodeIe failed");

	TEST(pktDecodeInit(&dec1, ie.hotspotIndicationLength,
		ie.hotspotIndication), "pktDecodeInit failed");
	TEST(pktDecodeIeHotspotIndication2(&dec1, &hotspot),
		"pktDecodeIeHotspotIndication failed");
	TEST(hotspot.isDgafDisabled == TRUE, "invalid data");
	TEST(hotspot.isOsuBssid == TRUE, "invalid data");
	TEST(hotspot.releaseNumber == HSPOT_RELEASE_2, "invalid data");

	TEST(pktDecodeInit(&dec1, ie.interworkingLength,
		ie.interworking), "pktDecodeInit failed");
	TEST(pktDecodeIeInterworking(&dec1, &interworking), "pktDecodeIeInterworking failed");
	TEST(interworking.accessNetworkType == IW_ANT_WILDCARD_NETWORK, "invalid data");
	TEST(interworking.isInternet == FALSE, "invalid data");
	TEST(interworking.isAsra == FALSE, "invalid data");
	TEST(interworking.isEsr == FALSE, "invalid data");
	TEST(interworking.isUesa == FALSE, "invalid data");
	TEST(interworking.isVenue == TRUE, "invalid data");
	TEST(interworking.venueGroup == 0, "invalid data");
	TEST(interworking.venueType == 0, "invalid data");
	TEST(interworking.isHessid == TRUE, "invalid data");
	TEST(memcmp(&interworking.hessid, "\xff\xff\xff\xff\xff\xff",
		sizeof(interworking.hessid)) == 0, "invalid data");

	TEST(pktDecodeInit(&dec1, ie.advertisementProtocolLength,
		ie.advertisementProtocol), "pktDecodeInit failed");
	TEST(pktDecodeIeAdvertisementProtocol(&dec1, &advertise),
		"pktDecodeIeAdvertisementProtocol failed");
	TEST(advertise.count == 1, "invalid data");
	TEST(advertise.protocol[0].queryResponseLimit == 0x7f, "invalid data");
	TEST(advertise.protocol[0].isPamebi == FALSE, "invalid data");
	TEST(advertise.protocol[0].protocolId == ADVP_ANQP_PROTOCOL_ID, "invalid data");

	TEST(pktDecodeInit(&dec1, ie.roamingConsortiumLength,
		ie.roamingConsortium), "pktDecodeInit failed");
	TEST(pktDecodeIeRoamingConsortium(&dec1, &roam),
		"pktDecodeRoamingConsortium failed");
	TEST(roam.anqpOiCount == 0xff, "invalid data");
	TEST(roam.count == 3, "invalid data");
	TEST(memcmp(roam.oi[0].data, "\x00\x11\x22", roam.oi[0].length) == 0,
		"invalid data");
	TEST(memcmp(roam.oi[1].data, "\x55\x66\x77\x88", roam.oi[1].length) == 0,
		"invalid data");
	TEST(memcmp(roam.oi[2].data, "\xaa\xbb\xcc\xdd", roam.oi[2].length) == 0,
		"invalid data");

	TEST(pktDecodeInit(&dec1, ie.extendedCapabilityLength,
		ie.extendedCapability), "pktDecodeInit failed");
	TEST(pktDecodeIeExtendedCapabilities(&dec1, &cap),
		"pktDecodeIeExtendedCapabilities failed");
	TEST(cap == 0x80000000, "invalid data");
}
Пример #15
0
/* decode OSU provider list */
int bcm_decode_hspot_anqp_osu_provider_list(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_osu_provider_list_t *list)
{
	int len;
	int i;

	WL_PRPKT("packet for hotspot OSU provider list decoding",
		bcm_decode_current_ptr(pkt), bcm_decode_remaining(pkt));

	memset(list, 0, sizeof(*list));

	if (bcm_decode_is_zero_length(pkt))
		return TRUE;

	/* decode OSU SSID */
	if (!bcm_decode_byte(pkt, &list->osuSsidLength)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}
	len = list->osuSsidLength;
	if (len > BCM_DECODE_HSPOT_ANQP_MAX_OSU_SSID_LENGTH) {
		WL_ERROR(("length exceeds maximum %d > %d\n",
			list->osuSsidLength,
			BCM_DECODE_HSPOT_ANQP_MAX_OSU_SSID_LENGTH));
		return FALSE;
	}
	if (list->osuSsidLength > bcm_decode_remaining(pkt)) {
		WL_ERROR(("length exceeds packet %d > %d\n",
			list->osuSsidLength, bcm_decode_remaining(pkt)));
		return FALSE;
	}
	if (list->osuSsidLength > 0 &&
		!bcm_decode_bytes(pkt, list->osuSsidLength, list->osuSsid)) {
		WL_ERROR(("bcm_decode_bytes failed"));
		return FALSE;
	}
	list->osuSsid[list->osuSsidLength] = 0;

	/* decode number of OSU providers */
	if (!bcm_decode_byte(pkt, &list->osuProviderCount)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}
	if (list->osuProviderCount > BCM_DECODE_HSPOT_ANQP_MAX_OSU_PROVIDER) {
		WL_ERROR(("length exceeds maximum %d > %d\n",
			list->osuProviderCount,
			BCM_DECODE_HSPOT_ANQP_MAX_OSU_PROVIDER));
		return FALSE;
	}

	for (i = 0; i < list->osuProviderCount; i++) {
		bcm_decode_hspot_anqp_osu_provider_t *osu =
			&list->osuProvider[i];
		uint16 osuLength;
		uint16 nameLength;
		int remNameLength;
		uint16 iconLength;
		int remIconLength;
		uint16 descLength;
		int remDescLength;

		/* decode OSU provider length */
		if (!bcm_decode_le16(pkt, &osuLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (osuLength > bcm_decode_remaining(pkt)) {
			WL_ERROR(("OSU length exceeds packet %d > %d\n",
				osuLength, bcm_decode_remaining(pkt)));
			return FALSE;
		}

		/* decode OSU friendly name */
		if (!bcm_decode_le16(pkt, &nameLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (nameLength > bcm_decode_remaining(pkt)) {
			WL_ERROR(("name length exceeds packet %d > %d\n",
				nameLength, bcm_decode_remaining(pkt)));
			return FALSE;
		}
		remNameLength = nameLength;
		while (remNameLength > 0 &&
			osu->name.numName < BCM_DECODE_HSPOT_ANQP_MAX_OPERATOR_NAME) {
			int startOffset = bcm_decode_offset(pkt);

			if (!pktDecodeHspotAnqpOperatorNameDuple(pkt,
				&osu->name.duple[osu->name.numName])) {
				return FALSE;
			}
			else {
				osu->name.numName++;
			}

			/* update remaining name length */
			remNameLength -= bcm_decode_offset(pkt) - startOffset;
		}

		/* decode OSU server URI */
		if (!bcm_decode_byte(pkt, &osu->uriLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (osu->uriLength > BCM_DECODE_HSPOT_ANQP_MAX_URI_LENGTH) {
			WL_ERROR(("URI exceeds buffer %d > %d\n",
				osu->uriLength, BCM_DECODE_HSPOT_ANQP_MAX_URI_LENGTH));
			return FALSE;
		}
		if (osu->uriLength > 0 &&
			!bcm_decode_bytes(pkt, osu->uriLength, (uint8 *)osu->uri)) {
			WL_ERROR(("bcm_decode_bytes failed"));
			return FALSE;
		}
		osu->uri[osu->uriLength] = 0;

		/* decode OSU method */
		if (!bcm_decode_byte(pkt, &osu->methodLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (osu->methodLength > BCM_DECODE_HSPOT_ANQP_MAX_METHOD_LENGTH) {
			WL_ERROR(("method exceeds buffer %d > %d\n",
				osu->methodLength, BCM_DECODE_HSPOT_ANQP_MAX_METHOD_LENGTH));
			return FALSE;
		}
		if (!bcm_decode_bytes(pkt, osu->methodLength, (uint8 *)osu->method)) {
			WL_ERROR(("bcm_decode_bytes failed\n"));
			return FALSE;
		}

		/* decode icon metadata */
		if (!bcm_decode_le16(pkt, &iconLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		remIconLength = iconLength;
		while (remIconLength > 0 &&
			osu->iconMetadataCount < BCM_DECODE_HSPOT_ANQP_MAX_ICON_METADATA_LENGTH) {
			int startOffset = bcm_decode_offset(pkt);

			if (!pktDecodeHspotAnqpIconMetadata(pkt,
				&osu->iconMetadata[osu->iconMetadataCount])) {
				return FALSE;
			}
			else {
				osu->iconMetadataCount++;
			}

			/* update remaining name length */
			remIconLength -= bcm_decode_offset(pkt) - startOffset;
		}

		/* decode OSU NAI */
		if (!bcm_decode_byte(pkt, &osu->naiLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (osu->naiLength > BCM_DECODE_HSPOT_ANQP_MAX_NAI_LENGTH) {
			WL_ERROR(("NAI exceeds buffer %d > %d\n",
				osu->naiLength, BCM_DECODE_HSPOT_ANQP_MAX_NAI_LENGTH));
			return FALSE;
		}
		if (osu->naiLength > 0 &&
			!bcm_decode_bytes(pkt, osu->naiLength, (uint8 *)osu->nai)) {
			WL_ERROR(("bcm_decode_bytes failed"));
			return FALSE;
		}
		osu->nai[osu->naiLength] = 0;

		/* decode OSU service description */
		if (!bcm_decode_le16(pkt, &descLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (descLength > bcm_decode_remaining(pkt)) {
			WL_ERROR(("name length exceeds packet %d > %d\n",
				descLength, bcm_decode_remaining(pkt)));
			return FALSE;
		}
		remDescLength = descLength;
		while (remDescLength > 0 &&
			osu->desc.numName < BCM_DECODE_HSPOT_ANQP_MAX_OPERATOR_NAME) {
			int startOffset = bcm_decode_offset(pkt);

			if (!pktDecodeHspotAnqpOperatorNameDuple(pkt,
				&osu->desc.duple[osu->desc.numName])) {
				return FALSE;
			}
			else {
				osu->desc.numName++;
			}

			/* update remaining name length */
			remDescLength -= bcm_decode_offset(pkt) - startOffset;
		}
	}

	list->isDecodeValid = TRUE;
	return TRUE;
}
Пример #16
0
/* decode hotspot ANQP frame */
int bcm_decode_hspot_anqp(bcm_decode_t *pkt, int isReset, bcm_decode_hspot_anqp_t *hspot)
{
	int nextIeOffset = 0;
	int ieCount = 0;

	WL_PRPKT("packet for hotspot ANQP decoding",
		bcm_decode_buf(pkt), bcm_decode_buf_length(pkt));

	if (isReset)
		memset(hspot, 0, sizeof(*hspot));

	while (nextIeOffset < bcm_decode_buf_length(pkt)) {
		uint16 infoId;
		uint16 length;
		uint8 oui[WFA_OUI_LEN];
		uint8 type;
		uint8 subtype;
		uint8 reserved;
		int dataLength;
		uint8 *dataPtr;

		bcm_decode_offset_set(pkt, nextIeOffset);
		WL_P2PO(("decoding offset 0x%x\n", bcm_decode_offset(pkt)));

		/* minimum ID and length */
		if (bcm_decode_remaining(pkt) < 4) {
			WL_P2PO(("ID and length too short\n"));
			break;
		}

		bcm_decode_le16(pkt, &infoId);
		bcm_decode_le16(pkt, &length);

		/* check length */
		if (length > bcm_decode_remaining(pkt)) {
			WL_P2PO(("length exceeds packet %d > %d\n",
				length, bcm_decode_remaining(pkt)));
			break;
		}
		nextIeOffset = bcm_decode_offset(pkt) + length;

		/* check ID */
		if (infoId != ANQP_ID_VENDOR_SPECIFIC_LIST) {
			WL_P2PO(("invalid ID 0x%04x\n", infoId));
			continue;
		}

		if (length < HSPOT_LENGTH_OVERHEAD) {
			WL_P2PO(("length too short %d < %d\n",
				length, HSPOT_LENGTH_OVERHEAD));
			continue;
		}

		/* check OUI */
		if (!bcm_decode_bytes(pkt, WFA_OUI_LEN, oui) ||
			memcmp(oui, WFA_OUI, WFA_OUI_LEN) != 0)
			continue;

		/* check type */
		if (!bcm_decode_byte(pkt, &type) || type != HSPOT_ANQP_OUI_TYPE)
			continue;

		if (!bcm_decode_byte(pkt, &subtype))
			continue;

		if (!bcm_decode_byte(pkt, &reserved))
			continue;

		/* remaining data */
		dataLength = length - HSPOT_LENGTH_OVERHEAD;
		dataPtr = bcm_decode_current_ptr(pkt);

		switch (subtype)
		{
		case HSPOT_SUBTYPE_QUERY_LIST:
			hspot->queryListLength = dataLength;
			hspot->queryListBuffer = dataPtr;
			break;
		case HSPOT_SUBTYPE_CAPABILITY_LIST:
			hspot->capabilityListLength = dataLength;
			hspot->capabilityListBuffer = dataPtr;
			break;
		case HSPOT_SUBTYPE_OPERATOR_FRIENDLY_NAME:
			hspot->operatorFriendlyNameLength = dataLength;
			hspot->operatorFriendlyNameBuffer = dataPtr;
			break;
		case HSPOT_SUBTYPE_WAN_METRICS:
			hspot->wanMetricsLength = dataLength;
			hspot->wanMetricsBuffer = dataPtr;
			break;
		case HSPOT_SUBTYPE_CONNECTION_CAPABILITY:
			hspot->connectionCapabilityLength = dataLength;
			hspot->connectionCapabilityBuffer = dataPtr;
			break;
		case HSPOT_SUBTYPE_NAI_HOME_REALM_QUERY:
			hspot->naiHomeRealmQueryLength = dataLength;
			hspot->naiHomeRealmQueryBuffer = dataPtr;
			break;
		case HSPOT_SUBTYPE_OPERATING_CLASS_INDICATION:
			hspot->opClassIndicationLength = dataLength;
			hspot->opClassIndicationBuffer = dataPtr;
			break;
		case HSPOT_SUBTYPE_ONLINE_SIGNUP_PROVIDERS:
			hspot->onlineSignupProvidersLength = dataLength;
			hspot->onlineSignupProvidersBuffer = dataPtr;
			break;
		case HSPOT_SUBTYPE_ANONYMOUS_NAI:
			hspot->anonymousNaiLength = dataLength;
			hspot->anonymousNaiBuffer = dataPtr;
			break;
		case HSPOT_SUBTYPE_ICON_REQUEST:
			hspot->iconRequestLength = dataLength;
			hspot->iconRequestBuffer = dataPtr;
			break;
		case HSPOT_SUBTYPE_ICON_BINARY_FILE:
			hspot->iconBinaryFileLength = dataLength;
			hspot->iconBinaryFileBuffer = dataPtr;
			break;
		default:
			WL_P2PO(("invalid subtype %d\n", subtype));
			continue;
			break;
		}

		/* count IEs decoded */
		ieCount++;
	}


	return ieCount;
}
Пример #17
0
/* print decoded hotspot ANQP */
void bcm_decode_hspot_anqp_print(bcm_decode_hspot_anqp_t *hspot)
{
	WL_P2PO(("decoded hotspot ANQP frame:\n"));

	if (hspot->queryListBuffer) {
		WL_PRPKT("   query list",
			hspot->queryListBuffer, hspot->queryListLength);
	}
	if (hspot->capabilityListBuffer) {
		WL_PRPKT("   capability list",
			hspot->capabilityListBuffer, hspot->capabilityListLength);
	}
	if (hspot->operatorFriendlyNameBuffer) {
		WL_PRPKT("   operator friendly name",
			hspot->operatorFriendlyNameBuffer,
			hspot->operatorFriendlyNameLength);
	}
	if (hspot->wanMetricsBuffer) {
		WL_PRPKT("   wan metrics",
			hspot->wanMetricsBuffer, hspot->wanMetricsLength);
	}
	if (hspot->connectionCapabilityBuffer) {
		WL_PRPKT("   connection capability",
			hspot->connectionCapabilityBuffer,
			hspot->connectionCapabilityLength);
	}
	if (hspot->naiHomeRealmQueryBuffer) {
		WL_PRPKT("   NAI home realm query",
			hspot->naiHomeRealmQueryBuffer,
			hspot->naiHomeRealmQueryLength);
	}
	if (hspot->opClassIndicationBuffer) {
		WL_PRPKT("   operating class indication",
			hspot->opClassIndicationBuffer,
			hspot->opClassIndicationLength);
	}
	if (hspot->onlineSignupProvidersBuffer) {
		WL_PRPKT("   online sign-up providers",
			hspot->onlineSignupProvidersBuffer,
			hspot->onlineSignupProvidersLength);
	}
	if (hspot->anonymousNaiBuffer) {
		WL_PRPKT("   anonymous NAI",
			hspot->anonymousNaiBuffer,
			hspot->anonymousNaiLength);
	}
	if (hspot->iconRequestBuffer) {
		WL_PRPKT("   icon request",
			hspot->iconRequestBuffer,
			hspot->iconRequestLength);
	}
	if (hspot->iconBinaryFileBuffer) {
		WL_PRPKT("   icon binary file",
			hspot->iconBinaryFileBuffer,
			hspot->iconBinaryFileLength);
	}
}