| 181 | static const char* |
| 182 | get_string(const char* val, const char* sep, u_int8_t* buf, int* lenp) |
| 183 | { |
| 184 | int len; |
| 185 | int hexstr; |
| 186 | u_int8_t* p; |
| 187 | |
| 188 | len = *lenp; |
| 189 | p = buf; |
| 190 | hexstr = (val[0] == '0' && tolower((u_char) val[1]) == 'x'); |
| 191 | if (hexstr) |
| 192 | val += 2; |
| 193 | for (;;) { |
| 194 | if (*val == '\0') |
| 195 | break; |
| 196 | if (sep != NULL && strchr(sep, *val) != NULL) { |
| 197 | val++; |
| 198 | break; |
| 199 | } |
| 200 | if (hexstr) { |
| 201 | if (!isxdigit((u_char) val[0])) { |
| 202 | printf("%s: bad hexadecimal digits", __func__); |
| 203 | return NULL; |
| 204 | } |
| 205 | if (!isxdigit((u_char) val[1])) { |
| 206 | printf("%s: odd count hexadecimal digits", |
| 207 | __func__); |
| 208 | return NULL; |
| 209 | } |
| 210 | } |
| 211 | if (p >= buf + len) { |
| 212 | if (hexstr) |
| 213 | printf("%s: hexadecimal digits too long", |
| 214 | __func__); |
| 215 | else |
| 216 | printf("string too long", __func__); |
| 217 | return NULL; |
| 218 | } |
| 219 | if (hexstr) { |
| 220 | #define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10) |
| 221 | *p++ = (tohex((u_char) val[0]) << 4) |
| 222 | | tohex((u_char) val[1]); |
| 223 | #undef tohex |
| 224 | val += 2; |
| 225 | } else |
| 226 | *p++ = *val++; |
| 227 | } |
| 228 | len = p - buf; |
| 229 | /* The string "-" is treated as the empty string. */ |
| 230 | if (!hexstr && len == 1 && buf[0] == '-') { |
| 231 | len = 0; |
| 232 | memset(buf, 0, *lenp); |
| 233 | } else if (len < *lenp) |
| 234 | memset(p, 0, *lenp - len); |
| 235 | *lenp = len; |
| 236 | return val; |
| 237 | } |
| 238 | |
| 239 | |
| 240 | static void |
| 241 | set80211(int s, const char* dev, int type, int val, int len, void* data) |
| 242 | { |
| 243 | struct ieee80211req ireq; |
| 244 | |
| 245 | (void)memset(&ireq, 0, sizeof(ireq)); |
| 246 | (void)strncpy(ireq.i_name, dev, sizeof(ireq.i_name)); |
| 247 | ireq.i_type = type; |
| 248 | ireq.i_val = val; |
| 249 | ireq.i_len = len; |
| 250 | ireq.i_data = data; |
| 251 | if (ioctl(s, SIOCS80211, &ireq, sizeof(struct ieee80211req)) < 0) |
| 252 | printf("%s: error in handling SIOCS80211\n", __func__); |
| 253 | } |
| 254 | |
| 255 | |
| 256 | static void |
| 257 | set80211ssid(const char* dev, const char* val, int s) |
| 258 | { |
| 259 | int ssid; |
| 260 | int len; |
| 261 | u_int8_t data[IEEE80211_NWID_LEN]; |
| 262 | |
| 263 | ssid = 0; |
| 264 | len = strlen(val); |
| 265 | if (len > 2 && isdigit((int)val[0]) && val[1] == ':') { |
| 266 | ssid = atoi(val) - 1; |
| 267 | val += 2; |
| 268 | } |
| 269 | bzero(data, sizeof(data)); |
| 270 | len = sizeof(data); |
| 271 | if (get_string(val, NULL, data, &len) == NULL) |
| 272 | exit(1); |
| 273 | |
| 274 | set80211(s, dev, IEEE80211_IOC_SSID, ssid, len, data); |
| 275 | } |
| 276 | |
| 277 | |
| 278 | static void |
| 279 | set80211nwkey(const char* dev, const char* val, int s) |
| 280 | { |
| 281 | int txkey; |
| 282 | int i, len; |
| 283 | u_int8_t data[IEEE80211_KEYBUF_SIZE]; |
| 284 | |
| 285 | set80211(s, dev, IEEE80211_IOC_WEP, IEEE80211_WEP_ON, 0, NULL); |
| 286 | |
| 287 | if (isdigit((int)val[0]) && val[1] == ':') { |
| 288 | txkey = val[0] - '0' - 1; |
| 289 | val += 2; |
| 290 | |
| 291 | for (i = 0; i < 4; i++) { |
| 292 | bzero(data, sizeof(data)); |
| 293 | len = sizeof(data); |
| 294 | val = get_string(val, ",", data, &len); |
| 295 | if (val == NULL) |
| 296 | exit(1); |
| 297 | |
| 298 | set80211(s, dev, IEEE80211_IOC_WEPKEY, i, len, data); |
| 299 | } |
| 300 | } else { |
| 301 | bzero(data, sizeof(data)); |
| 302 | len = sizeof(data); |
| 303 | get_string(val, NULL, data, &len); |
| 304 | txkey = 0; |
| 305 | |
| 306 | set80211(s, dev, IEEE80211_IOC_WEPKEY, 0, len, data); |
| 307 | |
| 308 | bzero(data, sizeof(data)); |
| 309 | for (i = 1; i < 4; i++) |
| 310 | set80211(s, dev, IEEE80211_IOC_WEPKEY, i, 0, data); |
| 311 | } |
| 312 | |
| 313 | set80211(s, dev, IEEE80211_IOC_WEPTXKEY, txkey, 0, NULL); |
| 314 | } |