$search
00001 /* 00002 * Wi-Fi Protected Setup - device attributes 00003 * Copyright (c) 2008, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "common.h" 00018 #include "wps_i.h" 00019 #include "wps_dev_attr.h" 00020 00021 00022 static int wps_build_manufacturer(struct wps_device_data *dev, 00023 struct wpabuf *msg) 00024 { 00025 size_t len; 00026 wpa_printf(MSG_DEBUG, "WPS: * Manufacturer"); 00027 wpabuf_put_be16(msg, ATTR_MANUFACTURER); 00028 len = dev->manufacturer ? os_strlen(dev->manufacturer) : 0; 00029 if (len == 0) { 00030 /* 00031 * Some deployed WPS implementations fail to parse zero-length 00032 * attributes. As a workaround, send a null character if the 00033 * device attribute string is empty. 00034 */ 00035 wpabuf_put_be16(msg, 1); 00036 wpabuf_put_u8(msg, '\0'); 00037 } else { 00038 wpabuf_put_be16(msg, len); 00039 wpabuf_put_data(msg, dev->manufacturer, len); 00040 } 00041 return 0; 00042 } 00043 00044 00045 static int wps_build_model_name(struct wps_device_data *dev, 00046 struct wpabuf *msg) 00047 { 00048 size_t len; 00049 wpa_printf(MSG_DEBUG, "WPS: * Model Name"); 00050 wpabuf_put_be16(msg, ATTR_MODEL_NAME); 00051 len = dev->model_name ? os_strlen(dev->model_name) : 0; 00052 if (len == 0) { 00053 /* 00054 * Some deployed WPS implementations fail to parse zero-length 00055 * attributes. As a workaround, send a null character if the 00056 * device attribute string is empty. 00057 */ 00058 wpabuf_put_be16(msg, 1); 00059 wpabuf_put_u8(msg, '\0'); 00060 } else { 00061 wpabuf_put_be16(msg, len); 00062 wpabuf_put_data(msg, dev->model_name, len); 00063 } 00064 return 0; 00065 } 00066 00067 00068 static int wps_build_model_number(struct wps_device_data *dev, 00069 struct wpabuf *msg) 00070 { 00071 size_t len; 00072 wpa_printf(MSG_DEBUG, "WPS: * Model Number"); 00073 wpabuf_put_be16(msg, ATTR_MODEL_NUMBER); 00074 len = dev->model_number ? os_strlen(dev->model_number) : 0; 00075 if (len == 0) { 00076 /* 00077 * Some deployed WPS implementations fail to parse zero-length 00078 * attributes. As a workaround, send a null character if the 00079 * device attribute string is empty. 00080 */ 00081 wpabuf_put_be16(msg, 1); 00082 wpabuf_put_u8(msg, '\0'); 00083 } else { 00084 wpabuf_put_be16(msg, len); 00085 wpabuf_put_data(msg, dev->model_number, len); 00086 } 00087 return 0; 00088 } 00089 00090 00091 static int wps_build_serial_number(struct wps_device_data *dev, 00092 struct wpabuf *msg) 00093 { 00094 size_t len; 00095 wpa_printf(MSG_DEBUG, "WPS: * Serial Number"); 00096 wpabuf_put_be16(msg, ATTR_SERIAL_NUMBER); 00097 len = dev->serial_number ? os_strlen(dev->serial_number) : 0; 00098 if (len == 0) { 00099 /* 00100 * Some deployed WPS implementations fail to parse zero-length 00101 * attributes. As a workaround, send a null character if the 00102 * device attribute string is empty. 00103 */ 00104 wpabuf_put_be16(msg, 1); 00105 wpabuf_put_u8(msg, '\0'); 00106 } else { 00107 wpabuf_put_be16(msg, len); 00108 wpabuf_put_data(msg, dev->serial_number, len); 00109 } 00110 return 0; 00111 } 00112 00113 00114 int wps_build_primary_dev_type(struct wps_device_data *dev, struct wpabuf *msg) 00115 { 00116 wpa_printf(MSG_DEBUG, "WPS: * Primary Device Type"); 00117 wpabuf_put_be16(msg, ATTR_PRIMARY_DEV_TYPE); 00118 wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN); 00119 wpabuf_put_data(msg, dev->pri_dev_type, WPS_DEV_TYPE_LEN); 00120 return 0; 00121 } 00122 00123 00124 static int wps_build_dev_name(struct wps_device_data *dev, struct wpabuf *msg) 00125 { 00126 size_t len; 00127 wpa_printf(MSG_DEBUG, "WPS: * Device Name"); 00128 wpabuf_put_be16(msg, ATTR_DEV_NAME); 00129 len = dev->device_name ? os_strlen(dev->device_name) : 0; 00130 if (len == 0) { 00131 /* 00132 * Some deployed WPS implementations fail to parse zero-length 00133 * attributes. As a workaround, send a null character if the 00134 * device attribute string is empty. 00135 */ 00136 wpabuf_put_be16(msg, 1); 00137 wpabuf_put_u8(msg, '\0'); 00138 } else { 00139 wpabuf_put_be16(msg, len); 00140 wpabuf_put_data(msg, dev->device_name, len); 00141 } 00142 return 0; 00143 } 00144 00145 00146 int wps_build_device_attrs(struct wps_device_data *dev, struct wpabuf *msg) 00147 { 00148 if (wps_build_manufacturer(dev, msg) || 00149 wps_build_model_name(dev, msg) || 00150 wps_build_model_number(dev, msg) || 00151 wps_build_serial_number(dev, msg) || 00152 wps_build_primary_dev_type(dev, msg) || 00153 wps_build_dev_name(dev, msg)) 00154 return -1; 00155 return 0; 00156 } 00157 00158 00159 int wps_build_os_version(struct wps_device_data *dev, struct wpabuf *msg) 00160 { 00161 wpa_printf(MSG_DEBUG, "WPS: * OS Version"); 00162 wpabuf_put_be16(msg, ATTR_OS_VERSION); 00163 wpabuf_put_be16(msg, 4); 00164 wpabuf_put_be32(msg, 0x80000000 | dev->os_version); 00165 return 0; 00166 } 00167 00168 00169 int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg) 00170 { 00171 wpa_printf(MSG_DEBUG, "WPS: * RF Bands (%x)", dev->rf_bands); 00172 wpabuf_put_be16(msg, ATTR_RF_BANDS); 00173 wpabuf_put_be16(msg, 1); 00174 wpabuf_put_u8(msg, dev->rf_bands); 00175 return 0; 00176 } 00177 00178 00179 static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str, 00180 size_t str_len) 00181 { 00182 if (str == NULL) { 00183 wpa_printf(MSG_DEBUG, "WPS: No Manufacturer received"); 00184 return -1; 00185 } 00186 00187 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer", str, str_len); 00188 00189 os_free(dev->manufacturer); 00190 dev->manufacturer = os_malloc(str_len + 1); 00191 if (dev->manufacturer == NULL) 00192 return -1; 00193 os_memcpy(dev->manufacturer, str, str_len); 00194 dev->manufacturer[str_len] = '\0'; 00195 00196 return 0; 00197 } 00198 00199 00200 static int wps_process_model_name(struct wps_device_data *dev, const u8 *str, 00201 size_t str_len) 00202 { 00203 if (str == NULL) { 00204 wpa_printf(MSG_DEBUG, "WPS: No Model Name received"); 00205 return -1; 00206 } 00207 00208 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name", str, str_len); 00209 00210 os_free(dev->model_name); 00211 dev->model_name = os_malloc(str_len + 1); 00212 if (dev->model_name == NULL) 00213 return -1; 00214 os_memcpy(dev->model_name, str, str_len); 00215 dev->model_name[str_len] = '\0'; 00216 00217 return 0; 00218 } 00219 00220 00221 static int wps_process_model_number(struct wps_device_data *dev, const u8 *str, 00222 size_t str_len) 00223 { 00224 if (str == NULL) { 00225 wpa_printf(MSG_DEBUG, "WPS: No Model Number received"); 00226 return -1; 00227 } 00228 00229 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number", str, str_len); 00230 00231 os_free(dev->model_number); 00232 dev->model_number = os_malloc(str_len + 1); 00233 if (dev->model_number == NULL) 00234 return -1; 00235 os_memcpy(dev->model_number, str, str_len); 00236 dev->model_number[str_len] = '\0'; 00237 00238 return 0; 00239 } 00240 00241 00242 static int wps_process_serial_number(struct wps_device_data *dev, 00243 const u8 *str, size_t str_len) 00244 { 00245 if (str == NULL) { 00246 wpa_printf(MSG_DEBUG, "WPS: No Serial Number received"); 00247 return -1; 00248 } 00249 00250 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", str, str_len); 00251 00252 os_free(dev->serial_number); 00253 dev->serial_number = os_malloc(str_len + 1); 00254 if (dev->serial_number == NULL) 00255 return -1; 00256 os_memcpy(dev->serial_number, str, str_len); 00257 dev->serial_number[str_len] = '\0'; 00258 00259 return 0; 00260 } 00261 00262 00263 static int wps_process_dev_name(struct wps_device_data *dev, const u8 *str, 00264 size_t str_len) 00265 { 00266 if (str == NULL) { 00267 wpa_printf(MSG_DEBUG, "WPS: No Device Name received"); 00268 return -1; 00269 } 00270 00271 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name", str, str_len); 00272 00273 os_free(dev->device_name); 00274 dev->device_name = os_malloc(str_len + 1); 00275 if (dev->device_name == NULL) 00276 return -1; 00277 os_memcpy(dev->device_name, str, str_len); 00278 dev->device_name[str_len] = '\0'; 00279 00280 return 0; 00281 } 00282 00283 00284 static int wps_process_primary_dev_type(struct wps_device_data *dev, 00285 const u8 *dev_type) 00286 { 00287 #ifndef CONFIG_NO_STDOUT_DEBUG 00288 char devtype[WPS_DEV_TYPE_BUFSIZE]; 00289 #endif /* CONFIG_NO_STDOUT_DEBUG */ 00290 00291 if (dev_type == NULL) { 00292 wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received"); 00293 return -1; 00294 } 00295 00296 os_memcpy(dev->pri_dev_type, dev_type, WPS_DEV_TYPE_LEN); 00297 wpa_printf(MSG_DEBUG, "WPS: Primary Device Type: %s", 00298 wps_dev_type_bin2str(dev->pri_dev_type, devtype, 00299 sizeof(devtype))); 00300 00301 return 0; 00302 } 00303 00304 00305 int wps_process_device_attrs(struct wps_device_data *dev, 00306 struct wps_parse_attr *attr) 00307 { 00308 if (wps_process_manufacturer(dev, attr->manufacturer, 00309 attr->manufacturer_len) || 00310 wps_process_model_name(dev, attr->model_name, 00311 attr->model_name_len) || 00312 wps_process_model_number(dev, attr->model_number, 00313 attr->model_number_len) || 00314 wps_process_serial_number(dev, attr->serial_number, 00315 attr->serial_number_len) || 00316 wps_process_primary_dev_type(dev, attr->primary_dev_type) || 00317 wps_process_dev_name(dev, attr->dev_name, attr->dev_name_len)) 00318 return -1; 00319 return 0; 00320 } 00321 00322 00323 int wps_process_os_version(struct wps_device_data *dev, const u8 *ver) 00324 { 00325 if (ver == NULL) { 00326 wpa_printf(MSG_DEBUG, "WPS: No OS Version received"); 00327 return -1; 00328 } 00329 00330 dev->os_version = WPA_GET_BE32(ver); 00331 wpa_printf(MSG_DEBUG, "WPS: OS Version %08x", dev->os_version); 00332 00333 return 0; 00334 } 00335 00336 00337 int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands) 00338 { 00339 if (bands == NULL) { 00340 wpa_printf(MSG_DEBUG, "WPS: No RF Bands received"); 00341 return -1; 00342 } 00343 00344 dev->rf_bands = *bands; 00345 wpa_printf(MSG_DEBUG, "WPS: Enrollee RF Bands 0x%x", dev->rf_bands); 00346 00347 return 0; 00348 } 00349 00350 00351 void wps_device_data_dup(struct wps_device_data *dst, 00352 const struct wps_device_data *src) 00353 { 00354 if (src->device_name) 00355 dst->device_name = os_strdup(src->device_name); 00356 if (src->manufacturer) 00357 dst->manufacturer = os_strdup(src->manufacturer); 00358 if (src->model_name) 00359 dst->model_name = os_strdup(src->model_name); 00360 if (src->model_number) 00361 dst->model_number = os_strdup(src->model_number); 00362 if (src->serial_number) 00363 dst->serial_number = os_strdup(src->serial_number); 00364 os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN); 00365 dst->os_version = src->os_version; 00366 dst->rf_bands = src->rf_bands; 00367 } 00368 00369 00370 void wps_device_data_free(struct wps_device_data *dev) 00371 { 00372 os_free(dev->device_name); 00373 dev->device_name = NULL; 00374 os_free(dev->manufacturer); 00375 dev->manufacturer = NULL; 00376 os_free(dev->model_name); 00377 dev->model_name = NULL; 00378 os_free(dev->model_number); 00379 dev->model_number = NULL; 00380 os_free(dev->serial_number); 00381 dev->serial_number = NULL; 00382 }