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;
char uuid[40], txt[400];
int len;
char devtype[WPS_DEV_TYPE_BUFSIZE];
if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
return;
wpa_printf(MSG_DEBUG, "WPS: PIN needed for E-UUID %s", uuid);
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,
dev->manufacturer, dev->model_name,
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))
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;
os_get_time(&t);
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,
dev->manufacturer, dev->model_name, dev->model_number,
dev->serial_number,
dev->categ, dev->oui, dev->sub_categ);
wps_dev_type_bin2str(dev->pri_dev_type, devtype,
sizeof(devtype)));
fclose(f);
}
}
@ -537,32 +540,12 @@ int hostapd_init_wps(struct hostapd_data *hapd,
if (os_strstr(m, "keypad"))
wps->config_methods |= WPS_CONFIG_KEYPAD;
}
if (hapd->conf->device_type) {
char *pos;
u8 oui[4];
/* <categ>-<OUI>-<subcateg> */
wps->dev.categ = atoi(hapd->conf->device_type);
pos = os_strchr(hapd->conf->device_type, '-');
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);
if (hapd->conf->device_type &&
wps_dev_type_str2bin(hapd->conf->device_type,
wps->dev.pri_dev_type) < 0) {
wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
os_free(wps);
return -1;
}
wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);
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;
};
#define WPS_DEV_TYPE_LEN 8
#define WPS_DEV_TYPE_BUFSIZE 21
/**
* struct wps_device_data - WPS Device Data
* @mac_addr: Device MAC address
@ -69,9 +72,7 @@ struct wps_credential {
* @model_name: Model Name (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)
* @categ: Primary Device Category
* @oui: Primary Device OUI
* @sub_categ: Primary Device Sub-Category
* @pri_dev_type: Primary Device Type
* @os_version: OS Version
* @rf_bands: RF bands (WPS_RF_24GHZ, WPS_RF_50GHZ flags)
*/
@ -82,9 +83,7 @@ struct wps_device_data {
char *model_name;
char *model_number;
char *serial_number;
u16 categ;
u32 oui;
u16 sub_categ;
u8 pri_dev_type[WPS_DEV_TYPE_LEN];
u32 os_version;
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,
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 */

View file

@ -111,7 +111,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
attr->sel_reg_config_methods = pos;
break;
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 "
"Type length %u", len);
return -1;

View file

@ -528,3 +528,41 @@ int wps_get_oob_method(char *method)
}
#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
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)
{
struct wps_dev_type *d;
wpa_printf(MSG_DEBUG, "WPS: * Primary Device Type");
wpabuf_put_be16(msg, ATTR_PRIMARY_DEV_TYPE);
wpabuf_put_be16(msg, sizeof(*d));
d = wpabuf_put(msg, sizeof(*d));
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);
wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN);
wpabuf_put_data(msg, dev->pri_dev_type, WPS_DEV_TYPE_LEN);
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,
const u8 *dev_type)
{
struct wps_dev_type *d;
char devtype[WPS_DEV_TYPE_BUFSIZE];
if (dev_type == NULL) {
wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received");
return -1;
}
d = (struct wps_dev_type *) dev_type;
dev->categ = WPA_GET_BE16(d->categ_id);
dev->oui = WPA_GET_BE32(d->oui);
dev->sub_categ = WPA_GET_BE16(d->sub_categ_id);
wpa_printf(MSG_DEBUG, "WPS: Primary Device Type: category %d "
"OUI %08x sub-category %d",
dev->categ, dev->oui, dev->sub_categ);
os_memcpy(dev->pri_dev_type, dev_type, WPS_DEV_TYPE_LEN);
wpa_printf(MSG_DEBUG, "WPS: Primary Device Type: %s",
wps_dev_type_bin2str(dev->pri_dev_type, devtype,
sizeof(devtype)));
return 0;
}
@ -367,9 +359,7 @@ void wps_device_data_dup(struct wps_device_data *dst,
dst->model_number = os_strdup(src->model_number);
if (src->serial_number)
dst->serial_number = os_strdup(src->serial_number);
dst->categ = src->categ;
dst->oui = src->oui;
dst->sub_categ = src->sub_categ;
os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN);
dst->os_version = src->os_version;
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)
{
os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN);
dst->categ = src->categ;
dst->oui = src->oui;
dst->sub_categ = src->sub_categ;
os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN);
#define WPS_STRDUP(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;
int len = 0, ret;
char uuid[40];
char devtype[WPS_DEV_TYPE_BUFSIZE];
d = wps_device_get(reg, addr);
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,
"wpsUuid=%s\n"
"wpsPrimaryDeviceType=%u-%08X-%u\n"
"wpsPrimaryDeviceType=%s\n"
"wpsDeviceName=%s\n"
"wpsManufacturer=%s\n"
"wpsModelName=%s\n"
"wpsModelNumber=%s\n"
"wpsSerialNumber=%s\n",
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.manufacturer ? d->dev.manufacturer : "",
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];
int len;
char devtype[WPS_DEV_TYPE_BUFSIZE];
if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
return;
wpa_printf(MSG_DEBUG, "WPS: PIN needed for UUID-E %s", uuid);
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,
dev->manufacturer, dev->model_name,
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))
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_number = wpa_s->conf->model_number;
wps->dev.serial_number = wpa_s->conf->serial_number;
if (wpa_s->conf->device_type) {
char *pos;
u8 oui[4];
/* <categ>-<OUI>-<subcateg> */
wps->dev.categ = atoi(wpa_s->conf->device_type);
pos = os_strchr(wpa_s->conf->device_type, '-');
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);
if (wpa_s->conf->device_type &&
wps_dev_type_str2bin(wpa_s->conf->device_type,
wps->dev.pri_dev_type) < 0) {
wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
os_free(wps);
return -1;
}
wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ; /* TODO: config */