WPS: Clean up Primary Device Type handling

Use shared functions for converting Primary Device Type between binary
and string formats. In addition, use array of eight octets instead of a
specific structure with multiple fields to reduce code complexity.
This commit is contained in:
Jouni Malinen 2009-11-26 11:39:29 +02:00 committed by Jouni Malinen
parent 8e2c104fa1
commit 96750ea5e5
8 changed files with 84 additions and 95 deletions

View file

@ -137,15 +137,17 @@ static void hostapd_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
struct hostapd_data *hapd = ctx; struct hostapd_data *hapd = ctx;
char uuid[40], txt[400]; char uuid[40], txt[400];
int len; int len;
char devtype[WPS_DEV_TYPE_BUFSIZE];
if (uuid_bin2str(uuid_e, uuid, sizeof(uuid))) if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
return; return;
wpa_printf(MSG_DEBUG, "WPS: PIN needed for E-UUID %s", uuid); wpa_printf(MSG_DEBUG, "WPS: PIN needed for E-UUID %s", uuid);
len = os_snprintf(txt, sizeof(txt), WPS_EVENT_PIN_NEEDED len = os_snprintf(txt, sizeof(txt), WPS_EVENT_PIN_NEEDED
"%s " MACSTR " [%s|%s|%s|%s|%s|%d-%08X-%d]", "%s " MACSTR " [%s|%s|%s|%s|%s|%s]",
uuid, MAC2STR(dev->mac_addr), dev->device_name, uuid, MAC2STR(dev->mac_addr), dev->device_name,
dev->manufacturer, dev->model_name, dev->manufacturer, dev->model_name,
dev->model_number, dev->serial_number, dev->model_number, dev->serial_number,
dev->categ, dev->oui, dev->sub_categ); wps_dev_type_bin2str(dev->pri_dev_type, devtype,
sizeof(devtype)));
if (len > 0 && len < (int) sizeof(txt)) if (len > 0 && len < (int) sizeof(txt))
wpa_msg(hapd->msg_ctx, MSG_INFO, "%s", txt); wpa_msg(hapd->msg_ctx, MSG_INFO, "%s", txt);
@ -157,11 +159,12 @@ static void hostapd_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
return; return;
os_get_time(&t); os_get_time(&t);
fprintf(f, "%ld\t%s\t" MACSTR "\t%s\t%s\t%s\t%s\t%s" fprintf(f, "%ld\t%s\t" MACSTR "\t%s\t%s\t%s\t%s\t%s"
"\t%d-%08X-%d\n", "\t%s\n",
t.sec, uuid, MAC2STR(dev->mac_addr), dev->device_name, t.sec, uuid, MAC2STR(dev->mac_addr), dev->device_name,
dev->manufacturer, dev->model_name, dev->model_number, dev->manufacturer, dev->model_name, dev->model_number,
dev->serial_number, dev->serial_number,
dev->categ, dev->oui, dev->sub_categ); wps_dev_type_bin2str(dev->pri_dev_type, devtype,
sizeof(devtype)));
fclose(f); fclose(f);
} }
} }
@ -537,32 +540,12 @@ int hostapd_init_wps(struct hostapd_data *hapd,
if (os_strstr(m, "keypad")) if (os_strstr(m, "keypad"))
wps->config_methods |= WPS_CONFIG_KEYPAD; wps->config_methods |= WPS_CONFIG_KEYPAD;
} }
if (hapd->conf->device_type) { if (hapd->conf->device_type &&
char *pos; wps_dev_type_str2bin(hapd->conf->device_type,
u8 oui[4]; wps->dev.pri_dev_type) < 0) {
/* <categ>-<OUI>-<subcateg> */ wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
wps->dev.categ = atoi(hapd->conf->device_type); os_free(wps);
pos = os_strchr(hapd->conf->device_type, '-'); return -1;
if (pos == NULL) {
wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
os_free(wps);
return -1;
}
pos++;
if (hexstr2bin(pos, oui, 4)) {
wpa_printf(MSG_ERROR, "WPS: Invalid device_type OUI");
os_free(wps);
return -1;
}
wps->dev.oui = WPA_GET_BE32(oui);
pos = os_strchr(pos, '-');
if (pos == NULL) {
wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
os_free(wps);
return -1;
}
pos++;
wps->dev.sub_categ = atoi(pos);
} }
wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version); wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);
wps->dev.rf_bands = hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ? wps->dev.rf_bands = hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ?

View file

@ -61,6 +61,9 @@ struct wps_credential {
size_t cred_attr_len; size_t cred_attr_len;
}; };
#define WPS_DEV_TYPE_LEN 8
#define WPS_DEV_TYPE_BUFSIZE 21
/** /**
* struct wps_device_data - WPS Device Data * struct wps_device_data - WPS Device Data
* @mac_addr: Device MAC address * @mac_addr: Device MAC address
@ -69,9 +72,7 @@ struct wps_credential {
* @model_name: Model Name (0..32 octets encoded in UTF-8) * @model_name: Model Name (0..32 octets encoded in UTF-8)
* @model_number: Model Number (0..32 octets encoded in UTF-8) * @model_number: Model Number (0..32 octets encoded in UTF-8)
* @serial_number: Serial Number (0..32 octets encoded in UTF-8) * @serial_number: Serial Number (0..32 octets encoded in UTF-8)
* @categ: Primary Device Category * @pri_dev_type: Primary Device Type
* @oui: Primary Device OUI
* @sub_categ: Primary Device Sub-Category
* @os_version: OS Version * @os_version: OS Version
* @rf_bands: RF bands (WPS_RF_24GHZ, WPS_RF_50GHZ flags) * @rf_bands: RF bands (WPS_RF_24GHZ, WPS_RF_50GHZ flags)
*/ */
@ -82,9 +83,7 @@ struct wps_device_data {
char *model_name; char *model_name;
char *model_number; char *model_number;
char *serial_number; char *serial_number;
u16 categ; u8 pri_dev_type[WPS_DEV_TYPE_LEN];
u32 oui;
u16 sub_categ;
u32 os_version; u32 os_version;
u8 rf_bands; u8 rf_bands;
}; };
@ -684,4 +683,8 @@ int wps_er_pbc(struct wps_er *er, const u8 *uuid);
int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin, int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
size_t pin_len); size_t pin_len);
int wps_dev_type_str2bin(const char *str, u8 dev_type[WPS_DEV_TYPE_LEN]);
char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf,
size_t buf_len);
#endif /* WPS_H */ #endif /* WPS_H */

View file

@ -111,7 +111,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
attr->sel_reg_config_methods = pos; attr->sel_reg_config_methods = pos;
break; break;
case ATTR_PRIMARY_DEV_TYPE: case ATTR_PRIMARY_DEV_TYPE:
if (len != sizeof(struct wps_dev_type)) { if (len != WPS_DEV_TYPE_LEN) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device " wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device "
"Type length %u", len); "Type length %u", len);
return -1; return -1;

View file

@ -528,3 +528,41 @@ int wps_get_oob_method(char *method)
} }
#endif /* CONFIG_WPS_OOB */ #endif /* CONFIG_WPS_OOB */
int wps_dev_type_str2bin(const char *str, u8 dev_type[WPS_DEV_TYPE_LEN])
{
const char *pos;
/* <categ>-<OUI>-<subcateg> */
WPA_PUT_BE16(dev_type, atoi(str));
pos = os_strchr(str, '-');
if (pos == NULL)
return -1;
pos++;
if (hexstr2bin(pos, &dev_type[2], 4))
return -1;
pos = os_strchr(pos, '-');
if (pos == NULL)
return -1;
pos++;
WPA_PUT_BE16(&dev_type[6], atoi(pos));
return 0;
}
char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf,
size_t buf_len)
{
int ret;
ret = os_snprintf(buf, buf_len, "%u-%08X-%u",
WPA_GET_BE16(dev_type), WPA_GET_BE32(&dev_type[2]),
WPA_GET_BE16(&dev_type[6]));
if (ret < 0 || (unsigned int) ret >= buf_len)
return NULL;
return buf;
}

View file

@ -232,13 +232,6 @@ enum wps_assoc_state {
}; };
/* Primary Device Type */
struct wps_dev_type {
u8 categ_id[2];
u8 oui[4];
u8 sub_categ_id[2];
};
#define WPS_DEV_OUI_WFA 0x0050f204 #define WPS_DEV_OUI_WFA 0x0050f204
enum wps_dev_categ { enum wps_dev_categ {

View file

@ -113,14 +113,10 @@ static int wps_build_serial_number(struct wps_device_data *dev,
int wps_build_primary_dev_type(struct wps_device_data *dev, struct wpabuf *msg) int wps_build_primary_dev_type(struct wps_device_data *dev, struct wpabuf *msg)
{ {
struct wps_dev_type *d;
wpa_printf(MSG_DEBUG, "WPS: * Primary Device Type"); wpa_printf(MSG_DEBUG, "WPS: * Primary Device Type");
wpabuf_put_be16(msg, ATTR_PRIMARY_DEV_TYPE); wpabuf_put_be16(msg, ATTR_PRIMARY_DEV_TYPE);
wpabuf_put_be16(msg, sizeof(*d)); wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN);
d = wpabuf_put(msg, sizeof(*d)); wpabuf_put_data(msg, dev->pri_dev_type, WPS_DEV_TYPE_LEN);
WPA_PUT_BE16(d->categ_id, dev->categ);
WPA_PUT_BE32(d->oui, dev->oui);
WPA_PUT_BE16(d->sub_categ_id, dev->sub_categ);
return 0; return 0;
} }
@ -288,21 +284,17 @@ static int wps_process_dev_name(struct wps_device_data *dev, const u8 *str,
static int wps_process_primary_dev_type(struct wps_device_data *dev, static int wps_process_primary_dev_type(struct wps_device_data *dev,
const u8 *dev_type) const u8 *dev_type)
{ {
struct wps_dev_type *d; char devtype[WPS_DEV_TYPE_BUFSIZE];
if (dev_type == NULL) { if (dev_type == NULL) {
wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received"); wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received");
return -1; return -1;
} }
d = (struct wps_dev_type *) dev_type; os_memcpy(dev->pri_dev_type, dev_type, WPS_DEV_TYPE_LEN);
dev->categ = WPA_GET_BE16(d->categ_id); wpa_printf(MSG_DEBUG, "WPS: Primary Device Type: %s",
dev->oui = WPA_GET_BE32(d->oui); wps_dev_type_bin2str(dev->pri_dev_type, devtype,
dev->sub_categ = WPA_GET_BE16(d->sub_categ_id); sizeof(devtype)));
wpa_printf(MSG_DEBUG, "WPS: Primary Device Type: category %d "
"OUI %08x sub-category %d",
dev->categ, dev->oui, dev->sub_categ);
return 0; return 0;
} }
@ -367,9 +359,7 @@ void wps_device_data_dup(struct wps_device_data *dst,
dst->model_number = os_strdup(src->model_number); dst->model_number = os_strdup(src->model_number);
if (src->serial_number) if (src->serial_number)
dst->serial_number = os_strdup(src->serial_number); dst->serial_number = os_strdup(src->serial_number);
dst->categ = src->categ; os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN);
dst->oui = src->oui;
dst->sub_categ = src->sub_categ;
dst->os_version = src->os_version; dst->os_version = src->os_version;
dst->rf_bands = src->rf_bands; dst->rf_bands = src->rf_bands;
} }

View file

@ -158,9 +158,7 @@ static void wps_device_clone_data(struct wps_device_data *dst,
struct wps_device_data *src) struct wps_device_data *src)
{ {
os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN); os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN);
dst->categ = src->categ; os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN);
dst->oui = src->oui;
dst->sub_categ = src->sub_categ;
#define WPS_STRDUP(n) \ #define WPS_STRDUP(n) \
os_free(dst->n); \ os_free(dst->n); \
@ -2800,6 +2798,7 @@ int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
struct wps_registrar_device *d; struct wps_registrar_device *d;
int len = 0, ret; int len = 0, ret;
char uuid[40]; char uuid[40];
char devtype[WPS_DEV_TYPE_BUFSIZE];
d = wps_device_get(reg, addr); d = wps_device_get(reg, addr);
if (d == NULL) if (d == NULL)
@ -2809,14 +2808,15 @@ int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
ret = os_snprintf(buf + len, buflen - len, ret = os_snprintf(buf + len, buflen - len,
"wpsUuid=%s\n" "wpsUuid=%s\n"
"wpsPrimaryDeviceType=%u-%08X-%u\n" "wpsPrimaryDeviceType=%s\n"
"wpsDeviceName=%s\n" "wpsDeviceName=%s\n"
"wpsManufacturer=%s\n" "wpsManufacturer=%s\n"
"wpsModelName=%s\n" "wpsModelName=%s\n"
"wpsModelNumber=%s\n" "wpsModelNumber=%s\n"
"wpsSerialNumber=%s\n", "wpsSerialNumber=%s\n",
uuid, uuid,
d->dev.categ, d->dev.oui, d->dev.sub_categ, wps_dev_type_bin2str(d->dev.pri_dev_type, devtype,
sizeof(devtype)),
d->dev.device_name ? d->dev.device_name : "", d->dev.device_name ? d->dev.device_name : "",
d->dev.manufacturer ? d->dev.manufacturer : "", d->dev.manufacturer ? d->dev.manufacturer : "",
d->dev.model_name ? d->dev.model_name : "", d->dev.model_name ? d->dev.model_name : "",

View file

@ -797,15 +797,17 @@ static void wpas_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
{ {
char uuid[40], txt[400]; char uuid[40], txt[400];
int len; int len;
char devtype[WPS_DEV_TYPE_BUFSIZE];
if (uuid_bin2str(uuid_e, uuid, sizeof(uuid))) if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
return; return;
wpa_printf(MSG_DEBUG, "WPS: PIN needed for UUID-E %s", uuid); wpa_printf(MSG_DEBUG, "WPS: PIN needed for UUID-E %s", uuid);
len = os_snprintf(txt, sizeof(txt), "WPS-EVENT-PIN-NEEDED %s " MACSTR len = os_snprintf(txt, sizeof(txt), "WPS-EVENT-PIN-NEEDED %s " MACSTR
" [%s|%s|%s|%s|%s|%d-%08X-%d]", " [%s|%s|%s|%s|%s|%s]",
uuid, MAC2STR(dev->mac_addr), dev->device_name, uuid, MAC2STR(dev->mac_addr), dev->device_name,
dev->manufacturer, dev->model_name, dev->manufacturer, dev->model_name,
dev->model_number, dev->serial_number, dev->model_number, dev->serial_number,
dev->categ, dev->oui, dev->sub_categ); wps_dev_type_bin2str(dev->pri_dev_type, devtype,
sizeof(devtype)));
if (len > 0 && len < (int) sizeof(txt)) if (len > 0 && len < (int) sizeof(txt))
wpa_printf(MSG_INFO, "%s", txt); wpa_printf(MSG_INFO, "%s", txt);
} }
@ -843,32 +845,12 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
wps->dev.model_name = wpa_s->conf->model_name; wps->dev.model_name = wpa_s->conf->model_name;
wps->dev.model_number = wpa_s->conf->model_number; wps->dev.model_number = wpa_s->conf->model_number;
wps->dev.serial_number = wpa_s->conf->serial_number; wps->dev.serial_number = wpa_s->conf->serial_number;
if (wpa_s->conf->device_type) { if (wpa_s->conf->device_type &&
char *pos; wps_dev_type_str2bin(wpa_s->conf->device_type,
u8 oui[4]; wps->dev.pri_dev_type) < 0) {
/* <categ>-<OUI>-<subcateg> */ wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
wps->dev.categ = atoi(wpa_s->conf->device_type); os_free(wps);
pos = os_strchr(wpa_s->conf->device_type, '-'); return -1;
if (pos == NULL) {
wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
os_free(wps);
return -1;
}
pos++;
if (hexstr2bin(pos, oui, 4)) {
wpa_printf(MSG_ERROR, "WPS: Invalid device_type OUI");
os_free(wps);
return -1;
}
wps->dev.oui = WPA_GET_BE32(oui);
pos = os_strchr(pos, '-');
if (pos == NULL) {
wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
os_free(wps);
return -1;
}
pos++;
wps->dev.sub_categ = atoi(pos);
} }
wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version); wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ; /* TODO: config */ wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ; /* TODO: config */