Print this page
10125 smatch fixes for cmd-inet
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/cmd-inet/usr.sbin/wificonfig/wificonfig.c
+++ new/usr/src/cmd/cmd-inet/usr.sbin/wificonfig/wificonfig.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 -#pragma ident "%Z%%M% %I% %E% SMI"
26 +/*
27 + * Copyright (c) 2018, Joyent, Inc.
28 + */
27 29
28 30 #include <stdio.h>
29 31 #include <stdlib.h>
30 32 #include <stddef.h>
31 33 #include <errno.h>
32 34 #include <ctype.h>
33 35 #include <stdarg.h>
34 36 #include <fcntl.h>
35 37 #include <unistd.h>
36 38 #include <net/if.h>
37 39 #include <sys/types.h>
38 40 #include <sys/stat.h>
39 41 #include <sys/wait.h>
40 42 #include <sys/ipc.h>
41 43 #include <sys/ddi.h>
42 44 #include <stropts.h>
43 45 #include <assert.h>
44 46 #include <termios.h>
45 47 #include <time.h>
46 48 #include <string.h>
47 49 #include <strings.h>
48 50 #include <auth_attr.h>
49 51 #include <auth_list.h>
50 52 #include <libdevinfo.h>
51 53 #include <secdb.h>
52 54 #include <priv.h>
53 55 #include <pwd.h>
54 56 #include <umem.h>
55 57 #include <locale.h>
56 58 #include <libintl.h>
57 59 #include <dirent.h>
58 60 #include <inet/wifi_ioctl.h>
59 61
60 62 /*
61 63 * Debug information
62 64 */
63 65 #ifdef DEBUG
64 66 int wifi_debug = 0;
65 67 void wifi_dbgprintf(char *fmt, ...);
66 68 #define PRTDBG(msg) if (wifi_debug > 1) wifi_dbgprintf msg
67 69 #else /* DEBUG */
68 70 #define PRTDBG(msg)
69 71 #endif /* DEBUG */
70 72
71 73 #define MAX_HISTORY_NUM 10
72 74 #define MAX_PREFERENCE_NUM 10
73 75 #define MAX_SCANBUF_LEN 256
74 76 #define MAX_CONFIG_FILE_LENGTH 256
75 77 #define MAX_LOADPF_LENGTH 256
76 78 #define LOADPROFILE_TIMEOUT 10
77 79 #define RECORD_ADD 0
78 80 #define RECORD_DEL 1
79 81 /*
80 82 * Wificonfig exit status
81 83 */
82 84 #define WIFI_EXIT_DEF 0
83 85 #define WIFI_FATAL_ERR 1
84 86 #define WIFI_IMPROPER_USE 2
85 87 #define WIFI_MINOR_ERR 3
86 88
87 89 #define WIFI_LOCKF "/var/run/lockf_wifi"
88 90
89 91 typedef enum {
90 92 PREFERENCE,
91 93 HISTORY,
92 94 ACTIVEP,
93 95 PROFILE,
94 96 OTHER
95 97 } list_type_t;
96 98
97 99 #define WIFI_PREFER "{preference}"
98 100 #define WIFI_HISTORY "{history}"
99 101 #define WIFI_ACTIVEP "{active_profile}"
100 102
101 103 typedef enum {
102 104 LINKSTATUS = 0,
103 105 BSSID,
104 106 ESSID,
105 107 BSSTYPE,
106 108 CREATEIBSS,
107 109 CHANNEL,
108 110 RATES,
109 111 POWERMODE,
110 112 AUTHMODE,
111 113 ENCRYPTION,
112 114 WEPKEYID,
113 115 WEPKEY,
114 116 SIGNAL,
115 117 RADIOON,
116 118 WLANLIST,
117 119 CONFIG_ITEM_END /* 15 */
118 120 } config_item_t;
119 121 typedef struct ae {
120 122 struct ae *ae_next;
121 123 char *ae_arg;
122 124 }ae_t;
123 125 typedef struct aelist {
124 126 int ael_argc;
125 127 ae_t *ael_head, *ael_tail;
126 128 list_type_t type;
127 129 }aelist_t;
128 130 typedef struct section {
129 131 struct section *section_next;
130 132 aelist_t *list;
131 133 char *section_id;
132 134 }section_t;
133 135
134 136 /*
135 137 * config_file_t is an abstract of configration file,
136 138 * either/etc/inet/wifi/wifi.<interface> or /etc/inet/secret/
137 139 * wifi/wifiwepkey.<interface>
138 140 */
139 141 typedef struct config_file {
140 142 int section_argc;
141 143 section_t *section_head, *section_tail;
142 144 }config_file_t;
143 145
144 146 static config_file_t *gp_config_file = NULL;
145 147 static config_file_t *gp_wepkey_file = NULL;
146 148 static char *p_file_wifi = "/etc/inet/wifi";
147 149 static char *p_file_wifiwepkey = "/etc/inet/secret/wifiwepkey";
148 150
149 151 typedef enum {
150 152 AUTH_WEP = 0,
151 153 AUTH_OTHER = 1
152 154 } wifi_auth_t;
153 155
154 156 static char *p_auth_string[] = {
155 157 WIFI_WEP_AUTH,
156 158 WIFI_CONFIG_AUTH
157 159 };
158 160
159 161 /*
160 162 * gbuf: is a global buf, which is used to communicate between the user and
161 163 * the driver
162 164 */
163 165 static wldp_t *gbuf = NULL;
164 166 static char *gExecName = NULL;
165 167
166 168 static void print_error(uint32_t);
167 169 static void *safe_malloc(size_t);
168 170 static void *safe_calloc(size_t, size_t);
169 171 static char *safe_strdup(const char *s1);
170 172 static void safe_snprintf(char *s, size_t n,
171 173 const char *format, ...);
172 174 static void safe_fclose(FILE *stream);
173 175 static void new_ae(aelist_t *ael, const char *arg);
174 176 static aelist_t *new_ael(list_type_t type);
175 177 static config_file_t *new_config_file();
176 178 static void new_section(config_file_t *p_config_file, aelist_t *p_list,
177 179 const char *section_id);
178 180 static void destroy_config(config_file_t *p_config_file);
179 181 static config_file_t *parse_file(const char *pfile);
180 182 static char **aeltoargv(aelist_t *ael, int *ael_num);
181 183 static boolean_t fprint_config_file(config_file_t *p_config_file,
182 184 const char *file_name);
183 185 static char *append_pa(const char *arg);
184 186 static section_t *find_section(config_file_t *p_config_file,
185 187 const char *section_id);
186 188 static ae_t *find_ae(aelist_t *plist, const char *arg);
187 189 static void update_aelist(aelist_t *plist, const char *arg);
188 190 static const char *get_value(const char *arg);
189 191 static char *find_active_profile(int);
190 192 static const char *essid_of_profile(const char *profile);
191 193 static boolean_t search_interface(char *interface);
192 194 static int open_dev(char *devname);
193 195 static boolean_t call_ioctl(int, int, uint32_t, uint32_t);
194 196 static boolean_t del_prefer(config_file_t *p_config_file, const char *prefer,
195 197 boolean_t rflag);
196 198 static boolean_t del_section(config_file_t *p_config_file, char *section_id);
197 199 static boolean_t set_prefer(config_file_t *p_config_file, const char *prefer,
198 200 int rank);
199 201 static void add_to_history(config_file_t *p_config_file,
200 202 int argc, char **argv);
201 203 static boolean_t check_authority(wifi_auth_t type);
202 204 static void heuristic_load(int fd, uint32_t ess_num, wl_ess_conf_t **);
203 205 static char *select_profile(int fd, int readonly, int timeout);
204 206 static char *construct_format(uint32_t nt);
205 207 static void print_gbuf(config_item_t index);
206 208 static boolean_t items_in_profile(aelist_t *, aelist_t *, int, char **);
207 209 static char *get_commit_key(int, int, char **);
208 210 static void print_wepkey_info(const char *id, const char *wepkeyn);
209 211 static void do_print_usage();
210 212 static boolean_t do_print_support_params(int fd);
211 213 static boolean_t do_autoconf(int fd, int argc, char **argv);
212 214 static boolean_t do_startconf(int fd, int argc, char **argv);
213 215 static boolean_t do_loadpf(int fd, int argc, char **argv);
214 216 static boolean_t do_disconnect(int fd, int argc, char **argv);
215 217 static boolean_t do_printpf(int fd, int argc, char **argv);
216 218 static boolean_t do_restoredef(int fd, int argc, char **argv);
217 219 static boolean_t do_history(int fd, int argc, char **argv);
218 220 static boolean_t do_deletepf(int fd, int argc, char **argv);
219 221 static boolean_t do_wepkey(int fd, int argc, char **argv);
220 222 static boolean_t do_setprefer(int fd, int argc, char **arg);
221 223 static boolean_t do_rmprefer(int fd, int argc, char **argv);
222 224 static boolean_t do_lsprefer(int fd, int argc, char **argv);
223 225 static boolean_t do_wlanlist(int fd, int argc, char **argv);
224 226 static boolean_t do_showstatus(int fd, int argc, char **argv);
225 227 static boolean_t do_getprofparam(int fd, int argc, char **argv);
226 228 static boolean_t do_setprofparam(int fd, int argc, char **argv);
227 229 static boolean_t do_setprofwepkey(int fd, int argc, char **argv);
228 230 static boolean_t is_rates_support(int fd, int num, uint8_t *rates);
229 231 static boolean_t do_set_bsstype(int fd, const char *arg);
230 232 static boolean_t do_set_essid(int fd, const char *arg);
231 233 static boolean_t do_set_powermode(int fd, const char *arg);
232 234 static boolean_t do_set_rates(int fd, const char *arg);
233 235 static boolean_t do_set_channel(int fd, const char *arg);
234 236 static boolean_t do_set_createibss(int fd, const char *arg);
235 237 static boolean_t do_set_radioon(int fd, const char *arg);
236 238 static boolean_t do_set_wepkeyid(int fd, const char *arg);
237 239 static boolean_t do_set_encryption(int fd, const char *arg);
238 240 static boolean_t do_set_authmode(int fd, const char *arg);
239 241 static boolean_t do_set_wepkey(int fd, const char *pbuf);
240 242 static boolean_t do_get_createibss(int fd);
241 243 static boolean_t do_get_bsstype(int fd);
242 244 static boolean_t do_get_essid(int fd);
243 245 static boolean_t do_get_bssid(int fd);
244 246 static boolean_t do_get_radioon(int fd);
245 247 static boolean_t do_get_signal(int fd);
246 248 static boolean_t do_get_wepkeyid(int fd);
247 249 static boolean_t do_get_encryption(int fd);
248 250 static boolean_t do_get_authmode(int fd);
249 251 static boolean_t do_get_powermode(int fd);
250 252 static boolean_t do_get_rates(int fd);
251 253 static boolean_t do_get_wlanlist(int fd);
252 254 static boolean_t do_get_linkstatus(int fd);
253 255 static boolean_t do_get_channel(int fd);
254 256 static boolean_t do_get(int fd, int argc, char **argv);
255 257 static boolean_t do_set(int fd, int argc, char **argv);
256 258 static boolean_t do_createprofile(int fd, int argc, char **argv);
257 259 static boolean_t value_is_valid(config_item_t item, const char *value);
258 260
259 261 typedef struct cmd_ops {
260 262 char cmd[32];
261 263 boolean_t (*p_do_func)(int fd, int argc, char **argv);
262 264 boolean_t b_auth;
263 265 boolean_t b_fileonly; /* operation only on the config file */
264 266 boolean_t b_readonly; /* only read from the card or config file */
265 267 } cmd_ops_t;
266 268 static cmd_ops_t do_func[] = {
267 269 {
268 270 "autoconf",
269 271 do_autoconf,
270 272 B_TRUE,
271 273 B_FALSE,
272 274 B_FALSE
273 275 },
274 276 {
275 277 "startconf",
276 278 do_startconf,
277 279 B_TRUE,
278 280 B_FALSE,
279 281 B_TRUE
280 282 },
281 283 {
282 284 "connect",
283 285 do_loadpf,
284 286 B_TRUE,
285 287 B_FALSE,
286 288 B_FALSE
287 289 },
288 290 {
289 291 "disconnect",
290 292 do_disconnect,
291 293 B_TRUE,
292 294 B_FALSE,
293 295 B_FALSE
294 296 },
295 297 {
296 298 "showprofile",
297 299 do_printpf,
298 300 B_FALSE,
299 301 B_TRUE,
300 302 B_TRUE
301 303 },
302 304 {
303 305 "deleteprofile",
304 306 do_deletepf,
305 307 B_TRUE,
306 308 B_TRUE,
307 309 B_FALSE
308 310 },
309 311 {
310 312 "history",
311 313 do_history,
312 314 B_FALSE,
313 315 B_TRUE,
314 316 B_TRUE
315 317 },
316 318 {
317 319 "listprefer",
318 320 do_lsprefer,
319 321 B_FALSE,
320 322 B_TRUE,
321 323 B_TRUE
322 324 },
323 325 {
324 326 "removeprefer",
325 327 do_rmprefer,
326 328 B_TRUE,
327 329 B_TRUE,
328 330 B_FALSE
329 331 },
330 332 {
331 333 "setprefer",
332 334 do_setprefer,
333 335 B_TRUE,
334 336 B_TRUE,
335 337 B_FALSE
336 338 },
337 339 {
338 340 "setwepkey",
339 341 do_wepkey,
340 342 B_TRUE,
341 343 B_FALSE,
342 344 B_FALSE
343 345 },
344 346 {
345 347 "restoredef",
346 348 do_restoredef,
347 349 B_TRUE,
348 350 B_FALSE,
349 351 B_FALSE
350 352 },
351 353 {
352 354 "getparam",
353 355 do_get,
354 356 B_FALSE,
355 357 B_FALSE,
356 358 B_TRUE
357 359 },
358 360 {
359 361 "setparam",
360 362 do_set,
361 363 B_TRUE,
362 364 B_FALSE,
363 365 B_FALSE
364 366 },
365 367 {
366 368 "createprofile",
367 369 do_createprofile,
368 370 B_TRUE,
369 371 B_TRUE,
370 372 B_FALSE
371 373 },
372 374 {
373 375 "scan",
374 376 do_wlanlist,
375 377 B_FALSE,
376 378 B_FALSE,
377 379 B_FALSE
378 380 },
379 381 {
380 382 "showstatus",
381 383 do_showstatus,
382 384 B_FALSE,
383 385 B_FALSE,
384 386 B_TRUE
385 387 },
386 388 {
387 389 "setprofileparam",
388 390 do_setprofparam,
389 391 B_TRUE,
390 392 B_TRUE,
391 393 B_FALSE
392 394 },
393 395 {
394 396 "getprofileparam",
395 397 do_getprofparam,
396 398 B_FALSE,
397 399 B_TRUE,
398 400 B_TRUE
399 401 },
400 402 {
401 403 "setprofilewepkey",
402 404 do_setprofwepkey,
403 405 B_TRUE,
404 406 B_TRUE,
405 407 B_FALSE
406 408 }
407 409 };
408 410
409 411
410 412 typedef enum {RW, RO, WO} rw_property_t;
411 413 typedef struct gs_ops {
412 414 config_item_t index;
413 415 char cmd[32];
414 416 boolean_t (*p_do_get_func)(int fd);
415 417 boolean_t (*p_do_set_func)(int fd, const char *arg);
416 418 rw_property_t rw;
417 419 } gs_ops_t;
418 420 static gs_ops_t do_gs_func[] = {
419 421 {LINKSTATUS, "linkstatus", NULL, NULL, RO},
420 422 {BSSID, "bssid", do_get_bssid, NULL, RO},
421 423 {ESSID, "essid", do_get_essid, do_set_essid, RW},
422 424 {BSSTYPE, "bsstype", do_get_bsstype, do_set_bsstype, RW},
423 425 {CREATEIBSS, "createibss", do_get_createibss, do_set_createibss, RW},
424 426 {CHANNEL, "channel", do_get_channel, do_set_channel, RW},
425 427 {RATES, "rates", do_get_rates, do_set_rates, RW},
426 428 {POWERMODE, "powermode", do_get_powermode, do_set_powermode, RW},
427 429 {AUTHMODE, "authmode", do_get_authmode, do_set_authmode, RW},
428 430 {ENCRYPTION, "encryption", do_get_encryption, do_set_encryption, RW},
429 431 {WEPKEYID, "wepkeyindex", do_get_wepkeyid, do_set_wepkeyid, RW},
430 432 {WEPKEY, "wepkey|1-4", NULL, do_set_wepkey, WO},
431 433 {SIGNAL, "signal", do_get_signal, NULL, RO},
432 434 {RADIOON, "radio", do_get_radioon, do_set_radioon, RW},
433 435 };
434 436
435 437 #define N_FUNC sizeof (do_func) / sizeof (cmd_ops_t)
436 438 #define N_GS_FUNC sizeof (do_gs_func) / sizeof (gs_ops_t)
437 439
438 440 /*
439 441 * valid rate value
440 442 */
441 443 typedef struct wifi_rates_tab {
442 444 char *rates_s;
443 445 uint8_t rates_i;
444 446 uint8_t rates_reserve0;
445 447 uint8_t rates_reserve1;
446 448 uint8_t rates_reserve2;
447 449 } wifi_rates_tab_t;
448 450
449 451 /*
450 452 * the rates value is in increments of 500kb/s.
451 453 * according to the 802.11 a/b/g specs(IEEE):
452 454 * 802.11b(IEEE Std 802.11b-1999) page35, rates should be:
453 455 * X02, X04, X0b, X16
454 456 * 802.11a(IEEE Std 802.11a-1999) page47, rates should be:
455 457 * 6,9,12,18,24,36,48,54 Mb/s
456 458 * 802.11g(IEEE Std 802.11g-2003) page44, rates should be:
457 459 * 1,2,5.5,11,6,9,12,18,22,24,33,36,48,54 Mb/s
458 460 */
459 461 #define WIFI_RATES_NUM 14
460 462 static wifi_rates_tab_t wifi_rates_s[WIFI_RATES_NUM] = {
461 463 {"1", WL_RATE_1M, 0, 0, 0},
462 464 {"2", WL_RATE_2M, 0, 0, 0},
463 465 {"5.5", WL_RATE_5_5M, 0, 0, 0},
464 466 {"6", WL_RATE_6M, 0, 0, 0},
465 467 {"9", WL_RATE_9M, 0, 0, 0},
466 468 {"11", WL_RATE_11M, 0, 0, 0},
467 469 {"12", WL_RATE_12M, 0, 0, 0},
468 470 {"18", WL_RATE_18M, 0, 0, 0},
469 471 {"22", WL_RATE_22M, 0, 0, 0},
470 472 {"24", WL_RATE_24M, 0, 0, 0},
471 473 {"33", WL_RATE_33M, 0, 0, 0},
472 474 {"36", WL_RATE_36M, 0, 0, 0},
473 475 {"48", WL_RATE_48M, 0, 0, 0},
474 476 {"54", WL_RATE_54M, 0, 0, 0}
475 477 };
476 478 /* print the error message on why set or get ioctl command failed. */
477 479 static void
478 480 print_error(uint32_t errorno)
479 481 {
480 482 char *buf;
481 483
482 484 switch (errorno) {
483 485 case WL_SUCCESS:
484 486 buf = gettext("command succeeded");
485 487 break;
486 488 case WL_NOTSUPPORTED:
487 489 case WL_LACK_FEATURE:
488 490 case WL_HW_ERROR:
489 491 case WL_ACCESS_DENIED:
490 492 buf = strerror(errorno);
491 493 break;
492 494 case WL_READONLY:
493 495 buf = gettext("parameter read-only");
494 496 break;
495 497 case WL_WRITEONLY:
496 498 buf = gettext("parameter write-only");
497 499 break;
498 500 case WL_NOAP:
499 501 buf = gettext("no access point available");
500 502 break;
501 503 default:
502 504 buf = gettext("unknown error");
503 505 break;
504 506 }
505 507 (void) fprintf(stderr, "%s\n", buf);
506 508 }
507 509
508 510 static void *
509 511 safe_malloc(size_t size)
510 512 {
511 513 void *buf;
512 514
513 515 buf = malloc(size);
514 516 if (buf == NULL) {
515 517 (void) fprintf(stderr, gettext("%s: malloc: %s\n"),
516 518 gExecName, strerror(errno));
517 519 exit(WIFI_FATAL_ERR);
518 520 }
519 521 return (buf);
520 522 }
521 523
522 524 static void *
523 525 safe_calloc(size_t nelem, size_t elsize)
524 526 {
525 527 void *buf;
526 528
527 529 buf = calloc(nelem, elsize);
528 530 if (buf == NULL) {
529 531 (void) fprintf(stderr, gettext("%s: calloc: %s\n"),
530 532 gExecName, strerror(errno));
531 533 exit(WIFI_FATAL_ERR);
532 534 }
533 535 return (buf);
534 536 }
535 537
536 538 static char *
537 539 safe_strdup(const char *s1)
538 540 {
539 541 char *p;
540 542
541 543 p = strdup(s1);
542 544 if (p == NULL) {
543 545 (void) fprintf(stderr, gettext("%s: strdup: %s\n"),
544 546 gExecName, strerror(errno));
545 547 exit(WIFI_FATAL_ERR);
546 548 }
547 549 return (p);
548 550 }
549 551
550 552 static void
551 553 safe_snprintf(char *s, size_t n, const char *format, ...)
552 554 {
553 555 int len;
554 556 va_list ap;
555 557 va_start(ap, format);
556 558
557 559 len = vsnprintf(s, n, format, ap);
558 560 if ((len <= 0) || (len > n - 1)) {
559 561 (void) fprintf(stderr,
560 562 gettext("%s: snprintf: %s\n"),
561 563 gExecName, strerror(errno));
562 564 exit(WIFI_FATAL_ERR);
563 565 }
564 566 va_end(ap);
565 567 }
566 568
567 569 static void
568 570 safe_fclose(FILE *stream)
569 571 {
570 572 int err;
571 573
572 574 err = fclose(stream);
573 575 if (err == EOF) {
574 576 (void) fprintf(stderr, gettext("%s: fclose: %s\n"),
575 577 gExecName, strerror(errno));
576 578 exit(WIFI_FATAL_ERR);
577 579 }
578 580 }
579 581 /*
580 582 * new_ae: Add an element with content pointed by arg to the list *ael.
581 583 */
582 584 static void
583 585 new_ae(aelist_t *ael, const char *arg)
584 586 {
585 587 ae_t *pae = NULL;
586 588
587 589 PRTDBG(("new_ae(0x%x, \"%s\")\n", ael, arg));
588 590 assert((ael != NULL) && (arg != NULL));
589 591
590 592 pae = safe_calloc(sizeof (*pae), 1);
591 593 pae->ae_arg = safe_strdup(arg);
592 594 pae->ae_next = NULL;
593 595
594 596 if (ael->ael_tail == NULL) {
595 597 ael->ael_head = pae;
596 598 } else {
597 599 ael->ael_tail->ae_next = pae;
598 600 }
599 601 ael->ael_tail = pae;
600 602 ael->ael_argc++;
601 603 }
602 604 /*
603 605 * new_ael: Create a new aelist with list_type "type"
604 606 * and return the list pointer.
605 607 */
606 608 static aelist_t *
607 609 new_ael(list_type_t type)
608 610 {
609 611 aelist_t *plist;
610 612
611 613 plist = safe_calloc(sizeof (*plist), 1);
612 614 plist->type = type;
613 615 plist->ael_argc = 0;
614 616 plist->ael_head = plist->ael_tail = NULL;
615 617
616 618 PRTDBG(("new_ael(%d) = 0x%x\n", type, plist));
617 619 return (plist);
618 620 }
619 621
620 622 /*
621 623 * new_config_file: Creates a new config_file_t struct which is counterpart of
622 624 * of the configration file, and return the pointer.
623 625 */
624 626 static config_file_t *
625 627 new_config_file()
626 628 {
627 629 config_file_t *p_config_file;
628 630
629 631 p_config_file = safe_calloc(sizeof (config_file_t), 1);
630 632 p_config_file->section_argc = 0;
631 633 p_config_file->section_head = p_config_file->section_tail = NULL;
632 634
633 635 PRTDBG(("new_config_file() = 0x%x\n", p_config_file));
634 636 return (p_config_file);
635 637 }
636 638
637 639 /*
638 640 * new_section: Add a list pointed by "p_list", with identity "section_id" to
639 641 * the config_file_t struct pointed by "p_config_file"
640 642 */
641 643 static void
642 644 new_section(config_file_t *p_config_file, aelist_t *p_list,
643 645 const char *section_id)
644 646 {
645 647 section_t *p_section = NULL;
646 648
647 649 PRTDBG(("new_section(0x%x, 0x%x, \"%s\")\n", p_config_file, p_list,
648 650 section_id));
649 651 assert((p_config_file != NULL) && (p_list != NULL) &&
650 652 (section_id != NULL));
651 653
652 654 p_section = safe_calloc(sizeof (*p_section), 1);
653 655 p_section->list = p_list;
654 656 p_section->section_next = NULL;
655 657 p_section->section_id = safe_strdup(section_id);
656 658
657 659 if (p_config_file->section_tail == NULL) {
658 660 p_config_file->section_head = p_section;
659 661 } else {
660 662 p_config_file->section_tail->section_next = p_section;
661 663 }
662 664 p_config_file->section_tail = p_section;
663 665 p_config_file->section_argc++;
664 666 }
665 667
666 668 /*
667 669 * destroy_config:Destroy the config_file struct
668 670 */
669 671 static void
670 672 destroy_config(config_file_t *p_config_file)
671 673 {
672 674 section_t *p_section = NULL;
673 675 aelist_t *p_list = NULL;
674 676 ae_t *pae = NULL;
675 677
676 678 PRTDBG(("destory_config(0x%x)\n", p_config_file));
677 679 assert(p_config_file != NULL);
678 680
679 681 p_section = p_config_file->section_head;
680 682 while (p_section != NULL) {
681 683 p_list = p_section->list;
682 684 if (p_list != NULL) {
683 685 pae = p_list->ael_head;
684 686 while (pae != NULL) {
685 687 if (pae->ae_arg != NULL)
686 688 free(pae->ae_arg);
687 689 pae->ae_arg = NULL;
688 690 pae = pae->ae_next;
689 691 free(p_list->ael_head);
690 692 p_list->ael_head = pae;
691 693 }
692 694 free(p_list);
693 695 p_list = NULL;
694 696 }
695 697 if (p_section->section_id != NULL)
696 698 free(p_section->section_id);
697 699 p_section->section_id = NULL;
698 700 p_section = p_section->section_next;
699 701 free(p_config_file->section_head);
700 702 p_config_file->section_head = p_section;
701 703 }
702 704 free(p_config_file);
703 705 p_config_file = NULL;
704 706 }
705 707
706 708 /*
707 709 * parse_file: Parse each section of the configration file
708 710 * and construct the config_file_t structure.
709 711 * Example:
710 712 * A config file has contents below:
711 713 *
712 714 * {preferrence}
713 715 * essid=ap7-3
714 716 * essid=linksys
715 717 *
716 718 * {history}
717 719 * essid=ap7-3
718 720 * essid=ap7-2
719 721 *
720 722 * [ap7-3]
721 723 * essid=ap7-3
722 724 * wepkeyid=3
723 725 * channel=11
724 726 * rates=1,2
725 727 *
726 728 * [linksys]
727 729 * essid=linksys
728 730 * createibss=BSS
729 731 * authmode=OPENSYSTEM
730 732 * wepkeyid=1
731 733 *
732 734 * then its config_file_t structure will be:
733 735 *
734 736 * config_file_t
735 737 * |~~~~~~~~~~~~~~~~~~~~~~~~~~|
736 738 * | section_argc=5 |
737 739 * |~~~~~~~~~~~~T~~~~~~~~~~~~~|
738 740 * /| *head | *tail |\
739 741 * / ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \
740 742 * / \
741 743 * / \
742 744 * / \
743 745 * / \
744 746 * / \
745 747 * section_t V section_t V section_t
746 748 * |~~~~~~~~~~~~~~~|~~| |~~~~~~~~~~~~~~~|~~| |~~~~~~~~~~~~~~|~~|
747 749 * |"{preferrence}"| | | "{history}" | | | "[linksys]" | |
748 750 * |~~~~~~~~~~~~~~~| -+---->|~~~~~~~~~~~~~~~| -+->..->|~~~~~~~~~~~~~~| -+->NULL
749 751 * | *list | | | *list | | | *list | |
750 752 * ~~T~~~~~~~~~~~~~~~~~ ~~~T~~~~~~~~~~~~~~~~ ~~~T~~~~~~~~~~~~~~~
751 753 * | | |
752 754 * | | |
753 755 * V aelist_t V aelist_t V aelist_t
754 756 * |~~~~~~~~~~~~~| |~~~~~~~~~~~~~| |~~~~~~~~~~~~~|
755 757 * | argc=2 | | argc=3 | | argc=4 |
756 758 * |~~~~~~~~~~~~~| |~~~~~~~~~~~~~| |~~~~~~~~~~~~~|
757 759 * |PREFFERRENCE | | HISTORY | | PROFILE |
758 760 * |~~~~~~T~~~~~~| |~~~~~~T~~~~~~| |~~~~~~T~~~~~~|
759 761 * |*head |*tail |\ |*head |*tail |\ |*head |*tail |
760 762 * ~~T~~~~~~~~~~~~ \ ~~T~~~~~~~~~~~~ \ /~~~~~~~~~~~~~~~\
761 763 * | \ V V / \
762 764 * | \ ... ... / \
763 765 * V ae_t V ae_t ae_t V ae_t V
764 766 * |~~~~~~~~~T~~| |~~~~~~~~~T~~| |~~~~~~~~~T~~| |~~~~~~~~~T~~|
765 767 * |"essid= | -+->|"essid= | -+->NULL |"essid= | -+->..->|"wepkeyid| -+->NULL
766 768 * | ap7-3" | | | linksys"| | | linksys"| | | =1" | |
767 769 * ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
768 770 *
769 771 */
770 772
771 773 static config_file_t *
772 774 parse_file(const char *pfile)
773 775 {
774 776 FILE *file = NULL;
775 777 int fd = 0;
776 778 char buf_line[256];
777 779 config_file_t *p_config_file;
778 780 list_type_t cur_list = OTHER;
779 781 aelist_t *prefer_list = NULL;
780 782 aelist_t *history_list = NULL;
781 783 aelist_t *profile_list = NULL;
782 784 aelist_t *activep_list = NULL;
783 785
784 786 assert(pfile != NULL);
785 787 /*
786 788 * The files /etc/inet/wifi and /etc/inet/secret/wifiwepkey should
787 789 * be opened with "r" attribute. If these two files do not exist,
788 790 * create them here.
789 791 */
790 792 file = fopen(pfile, "r");
791 793
792 794 if (file == NULL) {
793 795 fd = open(pfile, O_CREAT|O_EXCL|O_RDWR, 0600);
794 796 if (fd < 0) {
795 797 (void) fprintf(stderr, gettext("%s: failed to open %s"
796 798 "\n"), gExecName, pfile);
797 799 goto error1;
798 800 }
799 801 file = fdopen(fd, "w");
800 802 (void) chmod(pfile, S_IRUSR);
801 803 }
802 804
803 805 p_config_file = new_config_file();
804 806
805 807 while (fgets(buf_line, sizeof (buf_line), file) != NULL) {
806 808 if ((buf_line[0] == '\n') || (buf_line[0] == ' '))
807 809 continue;
808 810 /* replace the old '\n' to '\0' */
809 811 buf_line[strlen(buf_line) - 1] = '\0';
810 812 if (strstr(buf_line, WIFI_PREFER) == buf_line) {
811 813 if (prefer_list == NULL) {
812 814 cur_list = PREFERENCE;
813 815 prefer_list = new_ael(PREFERENCE);
814 816 new_section(p_config_file, prefer_list,
815 817 WIFI_PREFER);
816 818 } else {
817 819 (void) fprintf(stderr, gettext("%s: "
818 820 "%s : duplicated %s section\n"),
819 821 gExecName, pfile, WIFI_PREFER);
820 822 goto error;
821 823 }
822 824 } else if (strstr(buf_line, WIFI_HISTORY) == buf_line) {
823 825 if (history_list == NULL) {
824 826 cur_list = HISTORY;
825 827 history_list = new_ael(HISTORY);
826 828 new_section(p_config_file, history_list,
827 829 WIFI_HISTORY);
828 830 } else {
829 831 (void) fprintf(stderr, gettext("%s: "
830 832 "%s : duplicated %s section\n"),
831 833 gExecName, pfile, WIFI_HISTORY);
832 834 goto error;
833 835 }
834 836 } else if (strstr(buf_line, WIFI_ACTIVEP) == buf_line) {
835 837 if (activep_list == NULL) {
836 838 cur_list = ACTIVEP;
837 839 activep_list = new_ael(ACTIVEP);
838 840 new_section(p_config_file, activep_list,
839 841 WIFI_ACTIVEP);
840 842 } else {
841 843 (void) fprintf(stderr, gettext("%s: "
842 844 "%s : duplicated %s section\n"),
843 845 gExecName, pfile, WIFI_ACTIVEP);
844 846 goto error;
845 847 }
846 848 } else if ((strchr(buf_line, '[') == buf_line) &&
847 849 (buf_line[strlen(buf_line) - 1] == ']')) {
848 850 cur_list = PROFILE;
849 851 profile_list = new_ael(PROFILE);
850 852 new_section(p_config_file, profile_list,
851 853 buf_line);
852 854 } else {
853 855 switch (cur_list) {
854 856 case PREFERENCE:
855 857 if (prefer_list->ael_argc <=
856 858 MAX_PREFERENCE_NUM)
857 859 new_ae(prefer_list, buf_line);
858 860 break;
859 861 case HISTORY:
860 862 if (history_list->ael_argc <=
861 863 MAX_HISTORY_NUM)
862 864 new_ae(history_list, buf_line);
863 865 break;
864 866 case ACTIVEP:
865 867 if ((activep_list->ael_argc <= 1) &&
866 868 (strpbrk(buf_line, "=") != NULL))
867 869 new_ae(activep_list, buf_line);
868 870 break;
869 871 case PROFILE:
870 872 if (strpbrk(buf_line, "=") != NULL)
871 873 new_ae(profile_list, buf_line);
872 874 break;
873 875 default:
874 876 (void) fprintf(stderr,
875 877 gettext("%s: %s: file format error\n"),
876 878 gExecName, pfile);
877 879 goto error;
878 880 }
879 881 }
880 882 }
881 883 PRTDBG(("parse_file(\"%s\")=0x%x\n", pfile, p_config_file));
882 884 (void) fclose(file);
883 885 return (p_config_file);
884 886 error:
885 887 destroy_config(p_config_file);
886 888 (void) fclose(file);
887 889 error1:
888 890 return (NULL);
889 891 }
890 892 /*
891 893 * construct an argument vector from an aelist
892 894 */
893 895 static char **
894 896 aeltoargv(aelist_t *ael, int *ael_num)
895 897 {
896 898 ae_t *ae = NULL;
897 899 char **argv = NULL;
898 900 int argc = 0;
899 901
900 902 PRTDBG(("aeltoargv(%x)\n", ael));
901 903 assert(ael != NULL);
902 904
903 905 argv = safe_calloc(sizeof (*argv), ael->ael_argc);
904 906
905 907 for (argc = 0, ae = ael->ael_head; ae; ae = ae->ae_next) {
906 908 /* skip bssid since it can not be set */
907 909 if (strncmp(ae->ae_arg, "bssid=", strlen("bssid=")) == 0)
908 910 continue;
909 911 argv[argc] = safe_strdup(ae->ae_arg);
910 912 argc++;
911 913 if (ae == ael->ael_tail)
912 914 break;
913 915 }
914 916
915 917 PRTDBG(("aeltoargv(0x%x) = 0x%x\n\n", ael, argv));
916 918 *ael_num = argc;
917 919 return (argv);
918 920 }
919 921
920 922 /*
921 923 * archived contents into a file
922 924 */
923 925 static boolean_t
924 926 fprint_config_file(config_file_t *p_config_file, const char *file_name)
925 927 {
926 928 FILE *file = NULL;
927 929 int fd = 0;
928 930 int len;
929 931 section_t *p_section = NULL;
930 932 aelist_t *p_list = NULL;
931 933 ae_t *pae = NULL;
932 934 char temp_file[256];
933 935 struct stat buf;
934 936
935 937 PRTDBG(("fprint_config_file(0x%x, \"%s\")\n", p_config_file,
936 938 file_name));
937 939 assert((p_config_file != NULL)&&(strcmp(file_name, "") != 0));
938 940
939 941 safe_snprintf(temp_file, sizeof (temp_file),
940 942 "%s.tmp", file_name);
941 943 fd = open(temp_file, O_CREAT|O_WRONLY|O_TRUNC, 0600);
942 944 if (fd < 0) {
943 945 (void) fprintf(stderr, gettext("%s: failed to open %s\n"),
944 946 gExecName, temp_file);
945 947 return (B_FALSE);
946 948 }
947 949 file = fdopen(fd, "w");
948 950
949 951 p_section = p_config_file->section_head;
950 952 while (p_section != NULL) {
951 953 p_list = p_section->list;
952 954 if (p_list != NULL) {
953 955 PRTDBG(("fprint_config_file: section_id=%s\n",
954 956 p_section->section_id));
955 957 len = fprintf(file, "\n%s\n", p_section->section_id);
956 958 if (len < 0) {
957 959 (void) fprintf(stderr, gettext("%s: "
958 960 "failed to update %s: %s\n"),
959 961 gExecName, file_name, strerror(errno));
960 962 safe_fclose(file);
961 963 return (B_FALSE);
962 964 }
963 965 pae = p_list->ael_head;
964 966 while (pae != NULL) {
965 967 if (pae->ae_arg != NULL) {
966 968 len = fprintf(file, "%s\n",
967 969 pae->ae_arg);
968 970 if (len < 0) {
969 971 (void) fprintf(stderr,
970 972 gettext("%s: failed to "
971 973 "update %s: %s\n"),
972 974 gExecName, file_name,
973 975 strerror(errno));
974 976 safe_fclose(file);
975 977 return (B_FALSE);
976 978 }
977 979 }
978 980 pae = pae->ae_next;
979 981 }
980 982 }
981 983 p_section = p_section->section_next;
982 984 }
983 985 safe_fclose(file);
984 986 /*
985 987 * The attribute of the file /etc/inet/wifi and
986 988 * /etc/inet/security/wifiwepkey should be retained.
987 989 * if those file do not exist, set default file mode.
988 990 */
989 991 if (stat(file_name, &buf) != 0) {
990 992 if (errno == ENOENT) {
991 993 buf.st_mode = 0600;
992 994 } else {
993 995 (void) fprintf(stderr, gettext("%s: failed to get "
994 996 "file %s stat: %s\n"),
995 997 gExecName, file_name, strerror(errno));
996 998 return (B_FALSE);
997 999 }
998 1000 }
999 1001 if (rename(temp_file, file_name) != 0) {
1000 1002 (void) fprintf(stderr, gettext("%s: failed to update %s: %s"
1001 1003 "\n"), gExecName, file_name, strerror(errno));
1002 1004 return (B_FALSE);
1003 1005 }
1004 1006 (void) chmod(file_name, buf.st_mode);
1005 1007 return (B_TRUE);
1006 1008 }
1007 1009 /*
1008 1010 * append_pa: Each section holds a section_id which identifies a section
1009 1011 * a profile uses its essid appending "[]" to denote its section_id.
1010 1012 * note: new memory is allocated, remember to free.
1011 1013 */
1012 1014 static char *
1013 1015 append_pa(const char *arg)
1014 1016 {
1015 1017 char *pbuf = NULL;
1016 1018 int len;
1017 1019
1018 1020 assert(arg != NULL);
1019 1021
1020 1022 len = strlen(arg) + 3;
1021 1023 pbuf = safe_malloc(len);
1022 1024 safe_snprintf(pbuf, len, "[%s]", arg);
1023 1025 PRTDBG(("append_pa(\"%s\") = \"%s\"\n", arg, pbuf));
1024 1026 return (pbuf);
1025 1027 }
1026 1028 /*
1027 1029 * find a section by section_id from p_config_file,
1028 1030 * return the section pointer.
1029 1031 */
1030 1032 static section_t *
1031 1033 find_section(config_file_t *p_config_file, const char *section_id)
1032 1034 {
1033 1035 section_t *p_section = NULL;
1034 1036
1035 1037 PRTDBG(("find_section(0x%x, \"%s\")\n", p_config_file, section_id));
1036 1038 assert((section_id != NULL)&&(p_config_file != NULL));
1037 1039
1038 1040 p_section = p_config_file->section_head;
1039 1041
1040 1042 while (p_section != NULL) {
1041 1043 if ((p_section->section_id != NULL) &&
1042 1044 (strcmp(p_section->section_id, section_id) == 0))
1043 1045 return (p_section);
1044 1046 p_section = p_section->section_next;
1045 1047 }
1046 1048 return (NULL);
1047 1049 }
1048 1050
1049 1051 /*
1050 1052 * get_value: Get rid of "parameter=" from a "parameter=value", for example:
1051 1053 * when we read an line from file, we gets "essid=ap7-2", this function
1052 1054 * returns the pointer to string "ap7-2";
1053 1055 */
1054 1056
1055 1057 static const char *
1056 1058 get_value(const char *arg)
1057 1059 {
1058 1060 char *p;
1059 1061 assert(arg != NULL);
1060 1062
1061 1063 p = strchr(arg, '=');
1062 1064 PRTDBG(("get_value(\"%s\") = \"%s\"\n", arg, p + 1));
1063 1065 if (p != NULL)
1064 1066 return (p + 1);
1065 1067 else
1066 1068 return (NULL);
1067 1069 }
1068 1070
1069 1071 /*
1070 1072 * search /dev/wifi to see which interface is available
1071 1073 */
1072 1074 static boolean_t
1073 1075 search_interface(char *interface)
1074 1076 {
1075 1077 DIR *dirp;
1076 1078 struct dirent *dp;
1077 1079 char buf[256];
1078 1080 int fd;
1079 1081
1080 1082 PRTDBG(("search interface\n"));
1081 1083 assert(interface != NULL);
1082 1084
1083 1085 /*
1084 1086 * Try to return the first found wifi interface.
1085 1087 * If no wifi interface is available, return B_FALSE
1086 1088 */
1087 1089
1088 1090 if ((dirp = opendir("/dev/wifi")) == NULL) {
1089 1091 PRTDBG(("failed to open '/dev/wifi'\n"));
1090 1092 return (B_FALSE);
1091 1093 }
1092 1094 while ((dp = readdir(dirp)) != NULL) {
1093 1095 if (strcmp(dp->d_name, ".") == 0 ||
1094 1096 strcmp(dp->d_name, "..") == 0)
1095 1097 continue;
1096 1098 if (dp->d_name[strlen(dp->d_name) - 1] < '0' ||
1097 1099 dp->d_name[strlen(dp->d_name) - 1] > '9')
1098 1100 continue;
1099 1101 safe_snprintf(buf, sizeof (buf), "%s%s",
1100 1102 "/dev/wifi/", dp->d_name);
1101 1103 fd = open(buf, O_RDWR);
1102 1104 if (fd == -1) {
1103 1105 PRTDBG(("interface %s doesn't exist\n", dp->d_name));
1104 1106 continue;
1105 1107 } else {
1106 1108 PRTDBG(("interface %s is the first found interface\n",
1107 1109 dp->d_name));
1108 1110 (void) strlcpy(interface, buf, LIFNAMSIZ);
1109 1111 (void) close(fd);
1110 1112 (void) closedir(dirp);
1111 1113 return (B_TRUE);
1112 1114 }
1113 1115 }
1114 1116
1115 1117 PRTDBG(("failed to find available wireless interface\n"));
1116 1118 (void) closedir(dirp);
1117 1119 return (B_FALSE);
1118 1120
1119 1121 }
1120 1122 /*
1121 1123 * open_dev: Open the driver.
1122 1124 * if the 'devname' has format like 'ath0', we should add the path to that
1123 1125 * device(/dev/ath0) and open it; if the 'devname' has format like
1124 1126 * '/dev/wifi/ath0', we open it directly.
1125 1127 */
1126 1128 static int
1127 1129 open_dev(char *devname)
1128 1130 {
1129 1131 int fd;
1130 1132 int len;
1131 1133 char *pbuf = NULL;
1132 1134
1133 1135 PRTDBG(("open_dev(\"%s\")\n", devname));
1134 1136 assert(devname != NULL);
1135 1137 /*
1136 1138 * If the devname is got from the user input, we
1137 1139 * add '/dev/' to that relative devname. If it
1138 1140 * is got from the 'search interface', it is an
1139 1141 * absolute path.
1140 1142 */
1141 1143 if (strncmp(devname, "/dev/wifi/", strlen("/dev/wifi/")) == 0) {
1142 1144 pbuf = safe_strdup(devname);
1143 1145 } else {
1144 1146 len = strlen(devname) + strlen("/dev/") + 1;
1145 1147 pbuf = safe_malloc(len);
1146 1148 safe_snprintf(pbuf, len, "/dev/%s", devname);
1147 1149 }
1148 1150 fd = open(pbuf, O_RDWR);
1149 1151 free(pbuf);
1150 1152
1151 1153 if (fd == -1) {
1152 1154 (void) fprintf(stderr, gettext("%s: failed to open '%s': %s"
1153 1155 "\n"), gExecName, devname, strerror(errno));
1154 1156 return (-1);
1155 1157 }
1156 1158 if (!isastream(fd)) {
1157 1159 (void) fprintf(stderr, gettext("%s: %s is "
1158 1160 "not a stream device\n"),
1159 1161 gExecName, devname);
1160 1162 (void) close(fd);
1161 1163 return (-1);
1162 1164 }
1163 1165 return (fd);
1164 1166 }
1165 1167 /*
1166 1168 * call_ioctl: Fill strioctl structure and issue an ioctl system call
1167 1169 */
1168 1170 static boolean_t
1169 1171 call_ioctl(int fd, int cmd, uint32_t params, uint32_t buf_len)
1170 1172 {
1171 1173 struct strioctl stri;
1172 1174
1173 1175 PRTDBG(("call_ioctl_gs(%d, 0x%x, 0x%x, 0x%x)\n",
1174 1176 fd, cmd, params, buf_len));
1175 1177
1176 1178 switch (cmd) {
1177 1179 case WLAN_GET_PARAM:
1178 1180 (void) memset(gbuf, 0, MAX_BUF_LEN);
1179 1181 stri.ic_len = MAX_BUF_LEN;
1180 1182 break;
1181 1183 case WLAN_SET_PARAM:
1182 1184 gbuf->wldp_length = buf_len + WIFI_BUF_OFFSET;
1183 1185 stri.ic_len = gbuf->wldp_length;
1184 1186 break;
1185 1187 case WLAN_COMMAND:
1186 1188 gbuf->wldp_length = sizeof (wldp_t);
1187 1189 stri.ic_len = gbuf->wldp_length;
1188 1190 break;
1189 1191 default:
1190 1192 (void) fprintf(stderr, gettext("%s: ioctl : "
1191 1193 "unsupported ioctl command\n"), gExecName);
1192 1194 return (B_FALSE);
1193 1195 }
1194 1196 gbuf->wldp_type = NET_802_11;
1195 1197 gbuf->wldp_id = params;
1196 1198
1197 1199 stri.ic_cmd = cmd;
1198 1200 stri.ic_timout = 0;
1199 1201 stri.ic_dp = (char *)gbuf;
1200 1202
1201 1203 if (ioctl(fd, I_STR, &stri) == -1) {
1202 1204 gbuf->wldp_result = 0xffff;
1203 1205 return (B_FALSE);
1204 1206 }
1205 1207 if (cmd == WLAN_COMMAND) {
1206 1208 return (B_TRUE);
1207 1209 } else {
1208 1210 return (gbuf->wldp_result != WL_SUCCESS ?
1209 1211 B_FALSE:B_TRUE);
1210 1212 }
1211 1213 }
1212 1214
1213 1215 /*
1214 1216 * del_prefer: Delete an item from the {preferrence} list, the idea is
1215 1217 * simply free the ae_t element, and set ae_arg to NULL, then when archive
1216 1218 * the config_file_t struct to the file, it will be delete.
1217 1219 * The last flag is used to identify whether this function is invoked due to
1218 1220 * the 'removeprefer' subcommand or due to 'deleteprofile' subcommand.
1219 1221 */
1220 1222 static boolean_t
1221 1223 del_prefer(config_file_t *p_config_file, const char *prefer, boolean_t rflag)
1222 1224 {
1223 1225 section_t *p_section = NULL;
1224 1226 aelist_t *plist = NULL;
1225 1227 ae_t *pae = NULL;
1226 1228 int i = 0, position = 0;
1227 1229 int number;
1228 1230 ae_t *prm_ae = NULL;
1229 1231
1230 1232 PRTDBG(("del_prefer(0x%x, \"%s\")\n", p_config_file, prefer));
1231 1233 assert((prefer != NULL)&&(p_config_file != NULL));
1232 1234
1233 1235 p_section = find_section(p_config_file, WIFI_PREFER);
1234 1236 if (p_section != NULL)
1235 1237 plist = p_section->list;
1236 1238
1237 1239 if ((p_section == NULL) || (plist == NULL))
1238 1240 return (B_FALSE);
1239 1241
1240 1242 number = plist->ael_argc;
1241 1243 pae = plist->ael_head;
1242 1244 prm_ae = plist->ael_head;
1243 1245 while (pae != NULL) {
1244 1246 if (strcmp(prefer, pae->ae_arg) == 0) {
1245 1247 free(pae->ae_arg);
1246 1248 pae->ae_arg = NULL; /* mark */
1247 1249 if (!position) {
1248 1250 plist->ael_head = pae->ae_next;
1249 1251 if (pae->ae_next == NULL)
1250 1252 plist->ael_tail = NULL;
1251 1253 } else {
1252 1254 for (i = 0; i < position - 1; i++)
1253 1255 prm_ae = prm_ae->ae_next;
1254 1256 prm_ae->ae_next = pae->ae_next;
1255 1257 if (pae->ae_next == NULL)
1256 1258 plist->ael_tail = prm_ae;
1257 1259 }
1258 1260 free(pae);
1259 1261 pae = NULL;
1260 1262 plist->ael_argc--;
1261 1263 break;
1262 1264 }
1263 1265 position++;
1264 1266 pae = pae->ae_next;
1265 1267 }
1266 1268 if ((number == plist->ael_argc) && (rflag == B_TRUE)) {
1267 1269 (void) fprintf(stderr, gettext("%s: removeprefer : "
1268 1270 "no such profile: '%s' in the preference list\n"),
1269 1271 gExecName, prefer);
1270 1272 return (B_FALSE);
1271 1273 }
1272 1274 return (B_TRUE);
1273 1275 }
1274 1276
1275 1277 /*
1276 1278 * del_section: Delete an section from p_config_file, the idea is
1277 1279 * simply free the aelist_t struct and set it to NULL, when archiving
1278 1280 * config_file_t struct to the file, we will find section list is NULL,
1279 1281 * and will not write it to file, so it will be deleted.
1280 1282 */
1281 1283 static boolean_t
1282 1284 del_section(config_file_t *p_config_file, char *section_id)
1283 1285 {
1284 1286 section_t *p_section = NULL;
1285 1287 section_t *prm_section = NULL;
1286 1288 aelist_t *plist = NULL;
1287 1289 ae_t *pae = NULL;
1288 1290 int i = 0, position = 0;
1289 1291
1290 1292 PRTDBG(("del_section(0x%x, \"%s\")\n", p_config_file, section_id));
1291 1293 PRTDBG(("del_section: %d section(s) in config file\n",
1292 1294 p_config_file->section_argc));
1293 1295 assert((section_id != NULL)&&(p_config_file != NULL));
1294 1296
1295 1297 if (find_section(p_config_file, section_id) == NULL) {
1296 1298 return (B_FALSE);
1297 1299 }
1298 1300 p_section = p_config_file->section_head;
1299 1301 prm_section = p_config_file->section_head;
1300 1302 while (p_section != NULL) {
1301 1303 if (p_section->section_id != NULL) {
1302 1304 if (strcmp(p_section->section_id, section_id) == 0) {
1303 1305 plist = p_section->list;
1304 1306 pae = plist->ael_head;
1305 1307 while (pae != NULL) {
1306 1308 free(pae->ae_arg);
1307 1309 pae->ae_arg = NULL;
1308 1310 pae = pae->ae_next;
1309 1311 free(plist->ael_head);
1310 1312 plist->ael_head = pae;
1311 1313 }
1312 1314 free(plist);
1313 1315 p_section->list = NULL;
1314 1316 free(p_section->section_id);
1315 1317 p_section->section_id = NULL;
1316 1318
1317 1319 if (!position) {
1318 1320 p_config_file->section_head =
1319 1321 p_section->section_next;
1320 1322 if (p_section->section_next == NULL)
1321 1323 p_config_file->section_tail =
1322 1324 NULL;
1323 1325 } else {
1324 1326 for (i = 0; i < position - 1; i++) {
1325 1327 prm_section =
1326 1328 prm_section->section_next;
1327 1329 }
1328 1330 prm_section->section_next =
1329 1331 p_section->section_next;
1330 1332 if (p_section->section_next == NULL)
1331 1333 p_config_file->section_tail =
1332 1334 prm_section;
1333 1335 }
1334 1336 free(p_section);
1335 1337 p_config_file->section_argc--;
1336 1338 break;
1337 1339 }
1338 1340 position++;
1339 1341 }
1340 1342 p_section = p_section->section_next;
1341 1343 }
1342 1344 return (B_TRUE);
1343 1345 }
1344 1346
1345 1347 /*
1346 1348 * set_prefer: Reorder the preferrence list.
1347 1349 */
1348 1350 static boolean_t
1349 1351 set_prefer(config_file_t *p_config_file, const char *prefer, int rank)
1350 1352 {
1351 1353 char *pbuf = NULL;
1352 1354 aelist_t *plist = NULL;
1353 1355 section_t *p_section = NULL;
1354 1356 ae_t *pae = NULL;
1355 1357 int i = 0, position = 0;
1356 1358 ae_t *pae_move = NULL;
1357 1359
1358 1360 assert(prefer != NULL);
1359 1361 PRTDBG(("set_prefer(0x%x, \"%s\", %d)\n", p_config_file, prefer, rank));
1360 1362
1361 1363 pbuf = append_pa(prefer);
1362 1364 if (find_section(p_config_file, pbuf) == NULL) {
1363 1365 (void) fprintf(stderr, gettext("%s: setprefer: "
1364 1366 "no such profile: '%s'\n"),
1365 1367 gExecName, prefer);
1366 1368 free(pbuf);
1367 1369 return (B_FALSE);
1368 1370 }
1369 1371 free(pbuf);
1370 1372
1371 1373 p_section = find_section(p_config_file, WIFI_PREFER);
1372 1374
1373 1375 if (p_section == NULL) {
1374 1376 plist = new_ael(PREFERENCE);
1375 1377 new_section(p_config_file, plist, WIFI_PREFER);
1376 1378 new_ae(plist, prefer);
1377 1379 return (B_TRUE);
1378 1380 } else {
1379 1381 plist = p_section->list;
1380 1382 }
1381 1383
1382 1384 pae = plist->ael_head;
1383 1385 pae_move = plist->ael_head;
1384 1386 while (pae != NULL) {
1385 1387 if (strcmp(prefer, pae->ae_arg) == 0) {
1386 1388 free(pae->ae_arg);
1387 1389 pae->ae_arg = NULL;
1388 1390 if (!position) {
1389 1391 plist->ael_head = pae->ae_next;
1390 1392 if (pae->ae_next == NULL)
1391 1393 plist->ael_tail = NULL;
1392 1394 } else {
1393 1395 for (i = 0; i < position - 1; i++)
1394 1396 pae_move = pae_move->ae_next;
1395 1397 pae_move->ae_next = pae->ae_next;
1396 1398 if (pae->ae_next == NULL)
1397 1399 plist->ael_tail = pae_move;
1398 1400 }
1399 1401 free(pae);
1400 1402 plist->ael_argc--;
1401 1403 break;
1402 1404 }
1403 1405 position++;
1404 1406 pae = pae->ae_next;
1405 1407 }
1406 1408 PRTDBG(("set_prefer: %d Profiles in prefer list\n", plist->ael_argc));
1407 1409 if (rank > plist->ael_argc) {
1408 1410 new_ae(plist, prefer);
1409 1411 } else if (rank <= 1) {
1410 1412 pae = safe_calloc(sizeof (ae_t), 1);
1411 1413 pae->ae_arg = safe_strdup(prefer);
1412 1414 pae->ae_next = plist->ael_head;
1413 1415 plist->ael_head = pae;
1414 1416 plist->ael_argc++;
1415 1417 } else {
1416 1418 pae_move = plist->ael_head;
1417 1419 for (i = 1; i < rank-1; i++) {
1418 1420 pae_move = pae_move->ae_next;
1419 1421 }
1420 1422 pae = safe_calloc(sizeof (ae_t), 1);
1421 1423 pae->ae_arg = safe_strdup(prefer);
1422 1424 pae->ae_next = pae_move->ae_next;
1423 1425 pae_move->ae_next = pae;
1424 1426 plist->ael_argc++;
1425 1427 }
1426 1428 /*
1427 1429 * If number of prefer list items is larger than the MAX_PREFERENCE_NUM
1428 1430 * delete those items whose No is larger than MAX_PREFERENCE_NUM.
1429 1431 */
1430 1432 if (plist->ael_argc > MAX_PREFERENCE_NUM) {
1431 1433 pae = plist->ael_head;
1432 1434 while (pae->ae_next != plist->ael_tail)
1433 1435 pae = pae->ae_next;
1434 1436 free(plist->ael_tail->ae_arg);
1435 1437 plist->ael_tail->ae_arg = NULL;
1436 1438 free(plist->ael_tail);
1437 1439 plist->ael_tail = pae;
1438 1440 plist->ael_tail->ae_next = NULL;
1439 1441 plist->ael_argc--;
1440 1442 }
1441 1443 PRTDBG(("set_prefer: %d Profiles in prefer list\n", plist->ael_argc));
1442 1444 return (B_TRUE);
1443 1445 }
1444 1446 /*
1445 1447 * add_to_history: Save the scanlist argv into history section
1446 1448 */
1447 1449 static void
1448 1450 add_to_history(config_file_t *p_config_file, int argc, char **argv)
1449 1451 {
1450 1452 int i = 0, j = 0, pos = 0;
1451 1453 aelist_t *plist = NULL;
1452 1454 section_t *p_section = NULL;
1453 1455 ae_t *pae = NULL;
1454 1456 ae_t *pae_m = NULL;
1455 1457 char item[256];
1456 1458 time_t cltime;
1457 1459
1458 1460 PRTDBG(("add_to_history(0x%x, %d, 0x%x)\n", p_config_file, argc, argv));
1459 1461 assert(p_config_file != NULL);
1460 1462
1461 1463 p_section = find_section(p_config_file, WIFI_HISTORY);
1462 1464
1463 1465 if (p_section == NULL) {
1464 1466 plist = new_ael(HISTORY);
1465 1467 new_section(p_config_file, plist, WIFI_HISTORY);
1466 1468 } else {
1467 1469 plist = p_section->list;
1468 1470 }
1469 1471
1470 1472 if (plist != NULL) {
1471 1473 for (i = 0; i < argc; i++) {
1472 1474 if (!strlen(argv[i]))
1473 1475 continue;
1474 1476 pos = 0;
1475 1477 pae = plist->ael_head;
1476 1478 pae_m = plist->ael_head;
1477 1479 /*
1478 1480 * add time stamp to the history record
1479 1481 */
1480 1482 cltime = time(&cltime);
1481 1483 (void) snprintf(item, sizeof (item), "%s%c%ld",
1482 1484 argv[i], ',', cltime);
1483 1485 while (pae != NULL) {
1484 1486 if (strncmp(item, pae->ae_arg,
1485 1487 strlen(argv[i])) == 0) {
1486 1488 free(pae->ae_arg);
1487 1489 pae->ae_arg = NULL;
1488 1490 if (!pos) {
1489 1491 plist->ael_head = pae->ae_next;
1490 1492 if (pae->ae_next == NULL)
1491 1493 plist->ael_tail = NULL;
1492 1494 } else {
1493 1495 for (j = 0; j < pos - 1; j++)
1494 1496 pae_m = pae_m->ae_next;
1495 1497 pae_m->ae_next = pae->ae_next;
1496 1498 if (pae->ae_next == NULL)
1497 1499 plist->ael_tail = pae_m;
1498 1500 }
1499 1501 free(pae);
1500 1502 plist->ael_argc--;
1501 1503 break;
1502 1504 }
1503 1505 pos++;
1504 1506 pae = pae->ae_next;
1505 1507 }
1506 1508 new_ae(plist, item);
1507 1509 }
1508 1510
1509 1511 if (plist->ael_argc > MAX_HISTORY_NUM) {
1510 1512 for (i = 0; i < plist->ael_argc - MAX_HISTORY_NUM;
1511 1513 i++) {
1512 1514 pae = plist->ael_head;
1513 1515 free(pae->ae_arg);
1514 1516 plist->ael_head = pae->ae_next;
1515 1517 free(pae);
1516 1518 }
1517 1519 plist->ael_argc = MAX_HISTORY_NUM;
1518 1520 }
1519 1521 }
1520 1522 }
1521 1523
1522 1524 static void
1523 1525 do_print_usage()
1524 1526 {
1525 1527 (void) fprintf(stderr, gettext("\t%s [-R root_path][-i interface]"
1526 1528 " autoconf [wait={n|forever}]\n"), gExecName);
1527 1529 (void) fprintf(stderr, gettext("\t%s [-R root_path][-i interface]"
1528 1530 " connect profile [wait={n|forever}]\n"), gExecName);
1529 1531 (void) fprintf(stderr, gettext("\t%s [-R root_path][-i interface]"
1530 1532 " connect essid [wait={n|forever}]\n"), gExecName);
1531 1533 (void) fprintf(stderr, gettext("\t%s [-R root_path][-i interface]"
1532 1534 " disconnect\n"), gExecName);
1533 1535 (void) fprintf(stderr, gettext("\t%s [-R root_path][-i interface]"
1534 1536 " getparam [parameter [...]]\n"), gExecName);
1535 1537 (void) fprintf(stderr, gettext("\t%s [-R root_path][-i interface]"
1536 1538 " setparam [parameter=value [...]]\n"), gExecName);
1537 1539 (void) fprintf(stderr, gettext(
1538 1540 "\tparameters:\n"
1539 1541 "\t\tbssid\t\t - read only: 6 byte mac address of "
1540 1542 "base station\n"
1541 1543 "\t\tessid\t\t - name of the network, a string of up "
1542 1544 "to 32 chars\n"
1543 1545 "\t\tbsstype\t\t - bss(ap, infrastructure), ibss(ad-hoc)"
1544 1546 " or auto\n"
1545 1547 "\t\tcreateibss\t - flag to identify whether a ibss is to be\n"
1546 1548 "\t\t\t\t created when the network to connect is\n"
1547 1549 "\t\t\t\t not available, yes or no\n"
1548 1550 "\t\tchannel\t\t - channel(used only when creating an ibss)\n"
1549 1551 "\t\t\t\t valid value:\n"
1550 1552 "\t\t\t\t\t 802.11a: 0-99\n"
1551 1553 "\t\t\t\t\t 802.11b: 1-14\n"
1552 1554 "\t\t\t\t\t 802.11g: 1-14\n"
1553 1555 "\t\trates\t\t - set of rates, seperated by ',' valid rates:\n"
1554 1556 "\t\t\t\t 1,2,5.5,6,9,11,12,18,22,24,33,36,48 and 54\n"
1555 1557 "\t\tpowermode\t - off, mps or fast\n"
1556 1558 "\t\tauthmode\t - opensystem or shared_key\n"
1557 1559 "\t\tencryption\t - none or wep\n"
1558 1560 "\t\twepkey|1-4\t - write only:\n"
1559 1561 "\t\t\t\t 5 chars or 10 hex digits for 40bit wepkey;\n"
1560 1562 "\t\t\t\t 13 chars or 26 hex digits for 128bit wepkey\n"
1561 1563 "\t\twepkeyindex\t - an integer within the range 1-4\n"
1562 1564 "\t\tsignal\t\t - read only: signal strength from 0 to 15\n"
1563 1565 "\t\tradio\t\t - on or off\n"));
1564 1566 (void) fprintf(stderr, gettext("\t%s [-R root_path][-i interface]"
1565 1567 " restoredef\n"), gExecName);
1566 1568 (void) fprintf(stderr, gettext("\t%s [-R root_path][-i interface]"
1567 1569 " scan\n"), gExecName);
1568 1570 (void) fprintf(stderr, gettext("\t%s [-R root_path][-i interface]"
1569 1571 " showstatus\n"), gExecName);
1570 1572 (void) fprintf(stderr, gettext("\t%s [-R root_path][-i interface]"
1571 1573 " setwepkey 1|2|3|4\n"), gExecName);
1572 1574
1573 1575 (void) fprintf(stderr, "\n");
1574 1576
1575 1577 (void) fprintf(stderr, gettext("\t%s [-R root_path]"
1576 1578 " createprofile profile parameter=value [...]\n"), gExecName);
1577 1579 (void) fprintf(stderr, gettext("\t%s [-R root_path]"
1578 1580 " deleteprofile profile1 [profile2 [...]]\n"), gExecName);
1579 1581 (void) fprintf(stderr, gettext("\t%s [-R root_path]"
1580 1582 " showprofile profile1 [profile2 [...]]\n"), gExecName);
1581 1583 (void) fprintf(stderr, gettext("\t%s [-R root_path]"
1582 1584 " setprofilewepkey profile 1|2|3|4\n"), gExecName);
1583 1585 (void) fprintf(stderr, gettext("\t%s [-R root_path]"
1584 1586 " getprofileparam profile [parameter [...]]\n"), gExecName);
1585 1587 (void) fprintf(stderr, gettext("\t%s [-R root_path]"
1586 1588 " setprofileparam profile [parameter=value [...]]\n"), gExecName);
1587 1589
1588 1590 (void) fprintf(stderr, "\n");
1589 1591
1590 1592 (void) fprintf(stderr, gettext("\t%s [-R root_path]"
1591 1593 " history\n"), gExecName);
1592 1594 (void) fprintf(stderr, gettext("\t%s [-R root_path]"
1593 1595 " listprefer\n"), gExecName);
1594 1596 (void) fprintf(stderr, gettext("\t%s [-R root_path]"
1595 1597 " removeprefer profile\n"), gExecName);
1596 1598 (void) fprintf(stderr, gettext("\t%s [-R root_path]"
1597 1599 " setprefer profile [n]\n"), gExecName);
1598 1600 }
1599 1601
1600 1602 /*
1601 1603 * do_print_support_params: Query interface which cmd is supported
1602 1604 */
1603 1605 static boolean_t
1604 1606 do_print_support_params(int fd)
1605 1607 {
1606 1608 int i = 0, n = 0;
1607 1609
1608 1610 PRTDBG(("do_print_support_params(\"%d\")\n", fd));
1609 1611 assert(fd != -1);
1610 1612
1611 1613 (void) printf(gettext("\t parameter\tproperty\n"));
1612 1614 for (i = 0; i < N_GS_FUNC; i++) {
1613 1615 gbuf->wldp_result = WL_LACK_FEATURE;
1614 1616 if ((do_gs_func[i].p_do_get_func != NULL) &&
1615 1617 (do_gs_func[i].p_do_get_func(fd) != B_TRUE)) {
1616 1618 continue;
1617 1619 }
1618 1620 if (gbuf->wldp_result == WL_SUCCESS) {
1619 1621 (void) printf("\t%11s", do_gs_func[i].cmd);
1620 1622 if (do_gs_func[i].rw == RO)
1621 1623 (void) printf(gettext("\tread only\n"));
1622 1624 else
1623 1625 (void) printf(gettext("\tread/write\n"));
1624 1626 n++;
1625 1627 }
1626 1628 }
1627 1629
1628 1630 return (n ? B_TRUE : B_FALSE);
1629 1631 }
1630 1632
1631 1633 /*
1632 1634 * check_authority: Check if command is permitted.
1633 1635 */
1634 1636 static boolean_t
1635 1637 check_authority(wifi_auth_t type)
1636 1638 {
1637 1639 struct passwd *pw = NULL;
1638 1640
1639 1641 PRTDBG(("check_authority()\n"));
1640 1642
1641 1643 pw = getpwuid(getuid());
1642 1644 if (pw == NULL)
1643 1645 return (B_FALSE);
1644 1646 if (chkauthattr(p_auth_string[type], pw->pw_name) == 0) {
1645 1647 if (type == AUTH_WEP)
1646 1648 (void) fprintf(stderr, gettext("%s: "
1647 1649 "privilege '%s' is required for setting "
1648 1650 "wepkey.\n"), gExecName, WIFI_WEP_AUTH);
1649 1651 else
1650 1652 (void) fprintf(stderr, gettext("%s: "
1651 1653 "privilege '%s' is required.\n"),
1652 1654 gExecName, WIFI_CONFIG_AUTH);
1653 1655 return (B_FALSE);
1654 1656 } else {
1655 1657 return (B_TRUE);
1656 1658 }
1657 1659 }
1658 1660
1659 1661 /*
1660 1662 * construct the 'history' and 'scan' output format
1661 1663 * memory allocated. need to free after the function is invoked.
1662 1664 */
1663 1665 static char *
1664 1666 construct_format(uint32_t nt)
1665 1667 {
1666 1668 char *format;
1667 1669 int len = 0, i;
1668 1670
1669 1671 #define FORMAT_LEN 256
1670 1672 assert((nt >= 1) && (nt <= 4));
1671 1673 format = safe_malloc(FORMAT_LEN);
1672 1674
1673 1675 for (i = 0; i < nt; i++)
1674 1676 len += snprintf(format + len, FORMAT_LEN - len, "\t");
1675 1677 if ((len <= 0) || (len > FORMAT_LEN - 1)) {
1676 1678 return ("\t\t\t\t");
1677 1679 }
1678 1680 return (format);
1679 1681 }
1680 1682
1681 1683 /*
1682 1684 * find the essid of the named profile.
1683 1685 * gp_config_file is golable, so the return is gloable too.
1684 1686 */
1685 1687 static const char *
1686 1688 essid_of_profile(const char *profile)
1687 1689 {
1688 1690 section_t *p_section = NULL;
1689 1691 aelist_t *plist = NULL;
1690 1692 ae_t *pae = NULL;
1691 1693 char *pbuf;
1692 1694
1693 1695 PRTDBG(("essid_of_profile: profile = %s\n", profile));
1694 1696 pbuf = append_pa(profile);
1695 1697 p_section = find_section(gp_config_file, pbuf);
1696 1698 free(pbuf);
1697 1699
1698 1700 if (p_section == NULL) {
1699 1701 return (NULL);
1700 1702 } else {
1701 1703 plist = p_section->list;
1702 1704 }
1703 1705 pae = plist->ael_head;
1704 1706 while (pae != NULL) {
1705 1707 if (strncmp(pae->ae_arg, "essid=", strlen("essid=")) == 0) {
1706 1708 PRTDBG(("essid_of_profile: essid = %s\n",
1707 1709 pae->ae_arg));
1708 1710 return (get_value(pae->ae_arg));
1709 1711 }
1710 1712 pae = pae->ae_next;
1711 1713 }
1712 1714 return (NULL);
1713 1715 }
1714 1716
1715 1717 /*
1716 1718 * If we don't know which profile is our favorate in 'autoconf',
1717 1719 * we select the wifi network based on the following heuristic
1718 1720 * 1. the network without wep.
1719 1721 * 2. the network with the strongst signal.
1720 1722 * 3. the network with the faster speed(not implemented since signal affects
1721 1723 * the speed in some degree).
1722 1724 */
1723 1725 static void
1724 1726 heuristic_load(int fd, uint32_t ess_num, wl_ess_conf_t **p_ess_conf)
1725 1727 {
1726 1728 int i = 0;
1727 1729 char *flag = NULL;
1728 1730 int have_nowep_wlan = 0;
1729 1731 wl_rssi_t maxsignal = 0;
1730 1732 char essid[34];
1731 1733 int timeout = LOADPROFILE_TIMEOUT;
1732 1734
1733 1735 PRTDBG(("heuristic_load: enter\n"));
1734 1736 (void) call_ioctl(fd, WLAN_COMMAND, WL_LOAD_DEFAULTS, 0);
1735 1737 flag = calloc(sizeof (char), ess_num);
1736 1738 for (i = 0; i < ess_num; i++) { /* extract none-wep network */
1737 1739 if (p_ess_conf[i]->wl_ess_conf_wepenabled == B_FALSE) {
1738 1740 flag[i] = 1;
1739 1741 have_nowep_wlan = 1;
1740 1742 }
1741 1743 }
1742 1744 /*
1743 1745 * if all the wlans are weped, we select the one with strongest signal
1744 1746 * in all of them, otherwise we just select in the none weped ones.
1745 1747 */
1746 1748 if (!have_nowep_wlan)
1747 1749 (void) memset(flag, 1, ess_num);
1748 1750 for (i = 0; i < ess_num; i++) { /* extract the strongest signal ones */
1749 1751 if (flag[i] == 1) {
1750 1752 if (p_ess_conf[i]->wl_ess_conf_sl > maxsignal) {
1751 1753 maxsignal = p_ess_conf[i]->wl_ess_conf_sl;
1752 1754 (void) memset(flag, 0, i);
1753 1755 } else if (p_ess_conf[i]->wl_ess_conf_sl == maxsignal)
1754 1756 continue;
1755 1757 else
1756 1758 flag[i] = 0;
1757 1759 }
1758 1760 }
1759 1761 for (i = 0; i < ess_num; i++) {
1760 1762 if (flag[i] == 1)
1761 1763 break;
1762 1764 }
1763 1765 free(flag);
1764 1766 PRTDBG(("heuristic_load: %s is selected\n",
1765 1767 p_ess_conf[i]->wl_ess_conf_essid.wl_essid_essid));
1766 1768 /* select one in all the networks which meet the preceding stardands */
1767 1769 if (i == ess_num)
1768 1770 (void) do_set_essid(fd, "");
1769 1771 else
1770 1772 (void) do_set_essid(fd,
1771 1773 p_ess_conf[i]->wl_ess_conf_essid.wl_essid_essid);
1772 1774
1773 1775 if ((ess_num == 0) || (do_get_essid(fd) == B_FALSE)) {
1774 1776 (void) fprintf(stderr, gettext("%s: autoconf:"
1775 1777 " failed to connect to any essid\n"),
1776 1778 gExecName);
1777 1779 exit(WIFI_MINOR_ERR);
1778 1780 }
1779 1781 (void) strlcpy(essid, ((wl_essid_t *)(gbuf->wldp_buf))->wl_essid_essid,
1780 1782 sizeof (essid));
1781 1783 (void) printf(gettext("%s: autoconf: essid '%s' is selected%s\n"),
1782 1784 gExecName, essid,
1783 1785 have_nowep_wlan ? "" : ": this is a WEPed "
1784 1786 "access point");
1785 1787
1786 1788 if (!have_nowep_wlan)
1787 1789 exit(WIFI_FATAL_ERR);
1788 1790
1789 1791 while (timeout > 0) {
1790 1792 if ((do_get_linkstatus(fd) == B_TRUE) &&
1791 1793 (*(wl_linkstatus_t *)(gbuf->wldp_buf) == WL_CONNECTED)) {
1792 1794 (void) printf(gettext("%s: connecting to "
1793 1795 "essid '%s'\n"), gExecName, essid);
1794 1796 return;
1795 1797 }
1796 1798 (void) sleep(1);
1797 1799 timeout--;
1798 1800 }
1799 1801 (void) fprintf(stderr, gettext("%s: failed to connect to "
1800 1802 "essid '%s'\n"), gExecName, essid);
1801 1803 exit(WIFI_FATAL_ERR);
1802 1804 }
1803 1805
1804 1806 /*
1805 1807 * Called in autoconf and startconf to find which 'profile' is selected.
1806 1808 * The process is: check profile names in the prefer list item by item,
1807 1809 * if the essid of the profile is in the scan list, then it is the wanted.
1808 1810 * readonly: 1 for startconf
1809 1811 * 0 for autoconf
1810 1812 * for autoconf, the scan result will be recorded in the history list.
1811 1813 */
1812 1814 static char *
1813 1815 select_profile(int fd, int readonly, int timeout)
1814 1816 {
1815 1817 uint32_t ess_num = 0;
1816 1818 int nprefer = 1;
1817 1819 char **ess_argv;
1818 1820 char **hisess_argv;
1819 1821 wl_ess_conf_t **p_ess_conf;
1820 1822 section_t *p_section = NULL;
1821 1823 aelist_t *plist = NULL;
1822 1824 ae_t *pae = NULL;
1823 1825 int i;
1824 1826 const char *parg;
1825 1827 char *selected = NULL;
1826 1828 boolean_t flag = B_FALSE;
1827 1829
1828 1830 if ((call_ioctl(fd, WLAN_COMMAND, WL_SCAN, 0) == B_FALSE) ||
1829 1831 (do_get_wlanlist(fd) == B_FALSE)) {
1830 1832 (void) fprintf(stderr, gettext("%s: "
1831 1833 "autoconf : failed to scan\n"), gExecName);
1832 1834 exit(WIFI_FATAL_ERR);
1833 1835 }
1834 1836 ess_num = ((wl_ess_list_t *)(gbuf->wldp_buf))->wl_ess_list_num;
1835 1837 ess_argv = safe_calloc(sizeof (char *), ess_num);
1836 1838 hisess_argv = safe_calloc(sizeof (char *), ess_num);
1837 1839 p_ess_conf = safe_calloc(sizeof (wl_ess_list_t *), ess_num);
1838 1840 for (i = 0; i < ess_num; i++) {
1839 1841 p_ess_conf[i] = ((wl_ess_list_t *)gbuf->wldp_buf)
1840 1842 ->wl_ess_list_ess + i;
1841 1843 ess_argv[i] = safe_malloc(MAX_SCANBUF_LEN);
1842 1844 if (readonly == 0) {
1843 1845 hisess_argv[i] = safe_malloc(MAX_SCANBUF_LEN);
1844 1846 (void) snprintf(hisess_argv[i], MAX_SCANBUF_LEN,
1845 1847 "%s%c%02x:%02x:%02x:%02x:%02x:%02x%c%s",
1846 1848 p_ess_conf[i]->wl_ess_conf_essid.wl_essid_essid,
1847 1849 ',',
1848 1850 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[0]),
1849 1851 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[1]),
1850 1852 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[2]),
1851 1853 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[3]),
1852 1854 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[4]),
1853 1855 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[5]), ',',
1854 1856 (p_ess_conf[i]->wl_ess_conf_wepenabled == B_TRUE
1855 1857 ? "wep":"none"));
1856 1858 }
1857 1859 (void) snprintf(ess_argv[i], MAX_SCANBUF_LEN, "%s",
1858 1860 p_ess_conf[i]->wl_ess_conf_essid.wl_essid_essid);
1859 1861 }
1860 1862 if (readonly == 0) {
1861 1863 add_to_history(gp_config_file, ess_num, hisess_argv);
1862 1864 for (i = 0; i < ess_num; i++) {
1863 1865 free(hisess_argv[i]);
1864 1866 }
1865 1867 free(hisess_argv);
1866 1868 }
1867 1869
1868 1870 p_section = find_section(gp_config_file, WIFI_PREFER);
1869 1871 if (p_section == NULL) {
1870 1872 if (ess_num > 0) {
1871 1873 heuristic_load(fd, ess_num, p_ess_conf);
1872 1874 exit(WIFI_EXIT_DEF);
1873 1875 }
1874 1876 goto done;
1875 1877 }
1876 1878 plist = p_section->list;
1877 1879 assert(plist != NULL);
1878 1880 if (plist != NULL) {
1879 1881 nprefer = plist->ael_argc;
1880 1882 if (nprefer == 0) {
1881 1883 if (ess_num > 0) {
1882 1884 heuristic_load(fd, ess_num, p_ess_conf);
1883 1885 exit(WIFI_EXIT_DEF);
1884 1886 }
1885 1887 goto done;
1886 1888 }
1887 1889 }
1888 1890 pae = plist->ael_head;
1889 1891 while ((pae != NULL) && (flag != B_TRUE)) {
1890 1892 parg = essid_of_profile(pae->ae_arg);
1891 1893 if (parg != NULL) {
1892 1894 for (i = 0; i < ess_num; i++) {
1893 1895 if (strcmp(parg, ess_argv[i]) == 0) {
1894 1896 selected = pae->ae_arg;
1895 1897 flag = B_TRUE;
1896 1898 break;
1897 1899 }
1898 1900 }
1899 1901 }
1900 1902 pae = pae->ae_next;
1901 1903 }
1902 1904 done:
1903 1905 if ((selected == NULL) && (timeout == 0)) {
1904 1906 heuristic_load(fd, ess_num, p_ess_conf);
1905 1907 }
1906 1908 for (i = 0; i < ess_num; i++) {
1907 1909 free(ess_argv[i]);
1908 1910 }
1909 1911 free(ess_argv);
1910 1912 free(p_ess_conf);
1911 1913 return (selected);
1912 1914 }
1913 1915
1914 1916 static boolean_t
1915 1917 is_waittime_valid(char *pbuf)
1916 1918 {
1917 1919 int i;
1918 1920
1919 1921 i = atoi(pbuf);
1920 1922 if (i == -1)
1921 1923 return (B_TRUE);
1922 1924 for (i = 0; i < strlen(pbuf); i++) {
1923 1925 if (isdigit(pbuf[i]) == 0) {
1924 1926 return (B_FALSE);
1925 1927 }
1926 1928 }
1927 1929 return (B_TRUE);
1928 1930 }
1929 1931 /*
1930 1932 * do_autoconf: First scan the wlanlist, and select one essid from scan result
1931 1933 * by the order in {preferrence} list. If no match, then heuristic_load;
1932 1934 */
1933 1935 /*ARGSUSED*/
1934 1936 static boolean_t
1935 1937 do_autoconf(int fd, int argc, char **argv)
1936 1938 {
1937 1939 const char *selected = NULL;
1938 1940 int timeout = LOADPROFILE_TIMEOUT, forever = 0, len = 0;
1939 1941 char *pequal, *param;
1940 1942 char **ld_argv = NULL;
1941 1943 boolean_t ret = B_TRUE;
1942 1944
1943 1945 PRTDBG(("do_autoconf(%d, 0x%x)\n", argc, argv));
1944 1946 assert(fd > 0);
1945 1947 if (argc > 0) {
1946 1948 param = safe_strdup(argv[0]);
1947 1949 pequal = strchr(param, '=');
1948 1950 if (pequal != NULL) {
1949 1951 *pequal++ = '\0';
1950 1952 } else {
1951 1953 do_print_usage();
1952 1954 exit(WIFI_IMPROPER_USE);
1953 1955 }
1954 1956 if (strcmp(param, "wait") != 0) {
1955 1957 do_print_usage();
1956 1958 exit(WIFI_IMPROPER_USE);
1957 1959 } else {
1958 1960 if (strcmp(pequal, "forever") == 0) {
1959 1961 forever = 1;
1960 1962 } else {
1961 1963 if (is_waittime_valid(pequal) == B_FALSE) {
1962 1964 (void) fprintf(stderr, gettext("%s: "
1963 1965 "invalid value %s for 'wait'\n"),
1964 1966 gExecName, pequal);
1965 1967 exit(WIFI_FATAL_ERR);
1966 1968 }
1967 1969 if (sscanf(pequal, "%d", &timeout) != 1) {
1968 1970 do_print_usage();
1969 1971 exit(WIFI_IMPROPER_USE);
1970 1972 }
1971 1973 if (timeout == -1) {
1972 1974 forever = 1;
1973 1975 }
1974 1976 }
1975 1977 }
1976 1978 free(param);
1977 1979 if (argc > 1) {
1978 1980 (void) fprintf(stderr, gettext("%s: trailing "
1979 1981 "useless tokens after '%s'\n"),
1980 1982 gExecName, argv[0]);
1981 1983 }
1982 1984 }
1983 1985
1984 1986 while ((forever == 1) || (timeout > 0)) {
1985 1987 timeout--;
1986 1988 selected = select_profile(fd, 0, max(timeout, forever));
1987 1989 if (selected != NULL)
1988 1990 break;
1989 1991 (void) sleep(1);
1990 1992 }
1991 1993 if (selected == NULL) {
1992 1994 return (B_TRUE);
1993 1995 }
1994 1996 (void) printf(gettext("%s: autoconf: profile [%s]"
1995 1997 " is selected\n"), gExecName, selected);
1996 1998 ld_argv = safe_calloc(sizeof (char *), argc+1);
1997 1999 ld_argv[0] = safe_strdup(selected);
1998 2000 if (argc > 0) {
1999 2001 len = max(strlen(argv[0]), strlen("wait=forever"));
2000 2002 ld_argv[1] = safe_malloc(len);
2001 2003 safe_snprintf(ld_argv[1], len + 1, forever == 1 ?
2002 2004 "wait=forever" : "wait=%d", timeout);
2003 2005 }
2004 2006 ret = do_loadpf(fd, argc+1, ld_argv);
2005 2007 free(ld_argv[0]);
2006 2008 if (argc > 0) {
2007 2009 free(ld_argv[1]);
2008 2010 }
2009 2011 free(ld_argv);
2010 2012 return (ret);
2011 2013 }
2012 2014
2013 2015 /*
2014 2016 * do_startconf: almost the same as the do_autoconf, except that doesn't
2015 2017 * write file.
2016 2018 */
2017 2019 /*ARGSUSED*/
2018 2020 static boolean_t
2019 2021 do_startconf(int fd, int argc, char **argv)
2020 2022 {
2021 2023 int i = 0, ael_num = 0;
2022 2024 section_t *p_section = NULL;
2023 2025 section_t *p_wep_section = NULL;
2024 2026 aelist_t *plist = NULL;
2025 2027 const char *selected = NULL;
2026 2028 ae_t *pae = NULL;
2027 2029 char *pbuf = NULL;
2028 2030 char **argvnew = NULL;
2029 2031
2030 2032 PRTDBG(("do_startconf(%d, 0x%x)\n", argc, argv));
2031 2033 assert(fd > 0);
2032 2034
2033 2035 selected = select_profile(fd, 1, 0);
2034 2036 if (selected == NULL) {
2035 2037 return (B_TRUE);
2036 2038 }
2037 2039
2038 2040 (void) call_ioctl(fd, WLAN_COMMAND, WL_LOAD_DEFAULTS, 0);
2039 2041
2040 2042 pbuf = append_pa(selected);
2041 2043 p_wep_section = find_section(gp_wepkey_file, pbuf);
2042 2044 p_section = find_section(gp_config_file, pbuf);
2043 2045 free(pbuf);
2044 2046
2045 2047 if (p_wep_section != NULL) {
2046 2048 plist = p_wep_section->list;
2047 2049 pae = plist->ael_head;
2048 2050 while (pae != NULL) {
2049 2051 if (pae->ae_arg != NULL)
2050 2052 (void) do_set_wepkey(fd, pae->ae_arg);
2051 2053 pae = pae->ae_next;
2052 2054 }
2053 2055 }
2054 2056
2055 2057 if (p_section != NULL) {
2056 2058 plist = p_section->list;
2057 2059 if (plist->ael_argc == 0) {
2058 2060 return (B_TRUE);
2059 2061 }
2060 2062 argvnew = aeltoargv(plist, &ael_num);
2061 2063 (void) do_set(fd, ael_num, argvnew);
2062 2064
2063 2065 for (i = 0; i < ael_num; i++)
2064 2066 free(argvnew[i]);
2065 2067 free(argvnew);
2066 2068 }
2067 2069 return (B_TRUE);
2068 2070 }
2069 2071
2070 2072 static char *
2071 2073 find_active_profile(int fd)
2072 2074 {
2073 2075 section_t *p_section = NULL, *activep_section = NULL;
2074 2076 aelist_t *plist = NULL;
2075 2077 ae_t *pae = NULL;
2076 2078 const char *pessid = NULL, *pbssid = NULL;
2077 2079 char essid[34], bssid[32];
2078 2080 const char *activeprofile = NULL;
2079 2081
2080 2082 PRTDBG(("find_active_profile: %d\n", fd));
2081 2083 if (do_get_essid(fd) == B_FALSE) {
2082 2084 return (NULL);
2083 2085 }
2084 2086 (void) strlcpy(essid, ((wl_essid_t *)(gbuf->wldp_buf))->wl_essid_essid,
2085 2087 sizeof (essid));
2086 2088 if (do_get_bssid(fd) == B_FALSE) {
2087 2089 return (NULL);
2088 2090 }
2089 2091 safe_snprintf(bssid, sizeof (bssid), "%02x:%02x:%02x:%02x:%02x:%02x",
2090 2092 ((uint8_t *)gbuf->wldp_buf)[0],
2091 2093 ((uint8_t *)gbuf->wldp_buf)[1],
2092 2094 ((uint8_t *)gbuf->wldp_buf)[2],
2093 2095 ((uint8_t *)gbuf->wldp_buf)[3],
2094 2096 ((uint8_t *)gbuf->wldp_buf)[4],
2095 2097 ((uint8_t *)gbuf->wldp_buf)[5]);
2096 2098 activep_section = find_section(gp_config_file, WIFI_ACTIVEP);
2097 2099 if (activep_section == NULL)
2098 2100 return (NULL);
2099 2101 activeprofile = get_value(activep_section->list->
2100 2102 ael_head->ae_arg);
2101 2103 if (activeprofile == NULL)
2102 2104 return (NULL);
2103 2105 p_section = gp_config_file->section_head;
2104 2106 while (p_section != NULL) {
2105 2107 if (((plist = p_section->list) != NULL) &&
2106 2108 (plist->type == PROFILE) &&
2107 2109 (strcmp(p_section->section_id, activeprofile) == 0)) {
2108 2110 pae = plist->ael_head;
2109 2111 while (pae != NULL) {
2110 2112 if (strncmp(pae->ae_arg, "essid=",
2111 2113 strlen("essid=")) == 0) {
2112 2114 pessid = get_value(pae->ae_arg);
2113 2115 }
2114 2116 if (strncmp(pae->ae_arg, "bssid=",
2115 2117 strlen("bssid=")) == 0) {
2116 2118 pbssid = get_value(pae->ae_arg);
2117 2119 }
2118 2120 pae = pae->ae_next;
2119 2121 }
2120 2122 if (pessid && pbssid &&
2121 2123 (strcmp(essid, pessid) == 0) &&
2122 2124 (strcmp(bssid, pbssid) == 0)) {
2123 2125 return (p_section->section_id);
2124 2126 }
2125 2127 }
2126 2128 p_section = p_section->section_next;
2127 2129 }
2128 2130 return (NULL);
2129 2131 }
2130 2132
2131 2133 static void
2132 2134 record_active_profile(char *pname, int action)
2133 2135 {
2134 2136 section_t *p_section = NULL;
2135 2137 aelist_t *plist = NULL;
2136 2138 char pbuf[256];
2137 2139
2138 2140 p_section = find_section(gp_config_file, WIFI_ACTIVEP);
2139 2141 if (p_section == NULL) {
2140 2142 plist = new_ael(ACTIVEP);
2141 2143 new_section(gp_config_file, plist, WIFI_ACTIVEP);
2142 2144 } else {
2143 2145 plist = p_section->list;
2144 2146 }
2145 2147
2146 2148 if (action == RECORD_ADD) {
2147 2149 assert(pname != NULL);
2148 2150 safe_snprintf(pbuf, sizeof (pbuf), "activep=%s", pname);
2149 2151 update_aelist(plist, pbuf);
2150 2152 } else if (action == RECORD_DEL) {
2151 2153 assert(pname == NULL);
2152 2154 update_aelist(plist, "activep= ");
2153 2155 }
2154 2156 }
2155 2157
2156 2158 /*
2157 2159 * do_loadpf: load a profile, set related parameters both in wifi
2158 2160 * and in wifiwepkey, if network name is not exist in the
2159 2161 * configration files, then we clean all parameters and set essid only
2160 2162 */
2161 2163 static boolean_t
2162 2164 do_loadpf(int fd, int argc, char ** argv)
2163 2165 {
2164 2166 int i = 0, ael_num = 0;
2165 2167 int timeout = LOADPROFILE_TIMEOUT, forever = 0;
2166 2168 section_t *p_section = NULL;
2167 2169 section_t *p_wep_section = NULL;
2168 2170 aelist_t *plist = NULL;
2169 2171 ae_t *pae = NULL;
2170 2172 char *pbuf = NULL;
2171 2173 char **argvnew = NULL;
2172 2174 char *connect;
2173 2175 char *pequal, *param;
2174 2176
2175 2177 PRTDBG(("do_loadpf(%d, %x)\n", argc, argv));
2176 2178 assert(fd > 0);
2177 2179 if (argc == 0) {
2178 2180 (void) fprintf(stderr, gettext("%s: connect: "
2179 2181 "profile name missing\n"), gExecName);
2180 2182 return (B_FALSE);
2181 2183 }
2182 2184 if (argc > 1) {
2183 2185 param = safe_strdup(argv[1]);
2184 2186 pequal = strchr(param, '=');
2185 2187 if (pequal != NULL) {
2186 2188 *pequal++ = '\0';
2187 2189 } else {
2188 2190 do_print_usage();
2189 2191 exit(WIFI_IMPROPER_USE);
2190 2192 }
2191 2193 if (strcmp(param, "wait") != 0) {
2192 2194 do_print_usage();
2193 2195 exit(WIFI_IMPROPER_USE);
2194 2196 } else {
2195 2197 if (strcmp(pequal, "forever") == 0) {
2196 2198 forever = 1;
2197 2199 } else {
2198 2200 if (is_waittime_valid(pequal) == B_FALSE) {
2199 2201 (void) fprintf(stderr, gettext("%s: "
2200 2202 "invalid value %s for 'wait'\n"),
2201 2203 gExecName, pequal);
2202 2204 exit(WIFI_FATAL_ERR);
2203 2205 }
2204 2206 if (sscanf(pequal, "%d", &timeout) != 1) {
2205 2207 do_print_usage();
2206 2208 exit(WIFI_IMPROPER_USE);
2207 2209 }
2208 2210 if (timeout == -1) {
2209 2211 forever = 1;
2210 2212 }
2211 2213 }
2212 2214 }
2213 2215 free(param);
2214 2216 if (argc > 2) {
2215 2217 (void) fprintf(stderr, gettext("%s: trailing "
2216 2218 "useless tokens after '%s'\n"),
2217 2219 gExecName, argv[1]);
2218 2220 }
2219 2221 }
2220 2222 (void) call_ioctl(fd, WLAN_COMMAND, WL_LOAD_DEFAULTS, 0);
2221 2223
2222 2224 pbuf = append_pa(argv[0]);
2223 2225 p_wep_section = find_section(gp_wepkey_file, pbuf);
2224 2226 p_section = find_section(gp_config_file, pbuf);
2225 2227
2226 2228 if (p_wep_section != NULL) {
2227 2229 (void) set_prefer(gp_config_file, argv[0], 1);
2228 2230 plist = p_wep_section->list;
2229 2231 pae = plist->ael_head;
2230 2232 while (pae != NULL) {
2231 2233 if (pae->ae_arg != NULL) {
2232 2234 (void) do_set_wepkey(fd, pae->ae_arg);
2233 2235 }
2234 2236 pae = pae->ae_next;
2235 2237 }
2236 2238 }
2237 2239
2238 2240 if (p_section != NULL) {
2239 2241 connect = "profile";
2240 2242
2241 2243 (void) set_prefer(gp_config_file, argv[0], 1);
2242 2244 plist = p_section->list;
2243 2245 if (plist->ael_argc == 0) {
2244 2246 free(pbuf);
2245 2247 return (B_TRUE);
2246 2248 }
2247 2249 argvnew = aeltoargv(plist, &ael_num);
2248 2250 /*
2249 2251 * if there is no 'essid' item in argvnew, the profile
2250 2252 * name(argv[0]) is treated as essid.
2251 2253 */
2252 2254 for (i = 0; i < ael_num; i++) {
2253 2255 if (strncmp(argvnew[i], "essid=", strlen("essid="))
2254 2256 == 0)
2255 2257 break;
2256 2258 }
2257 2259 if (i == ael_num)
2258 2260 (void) do_set_essid(fd, argv[0]);
2259 2261
2260 2262 (void) do_set(fd, ael_num, argvnew);
2261 2263
2262 2264 for (i = 0; i < ael_num; i++)
2263 2265 free(argvnew[i]);
2264 2266 free(argvnew);
2265 2267
2266 2268 /*
2267 2269 * set flag in {active_profile} so that showprofile knows
2268 2270 * which profile is active when more than one profiles are
2269 2271 * created for the same WLAN.
2270 2272 */
2271 2273 record_active_profile(pbuf, RECORD_ADD);
2272 2274 } else {
2273 2275 (void) do_set_essid(fd, argv[0]);
2274 2276 connect = "essid";
2275 2277 }
2276 2278
2277 2279 while ((forever == 1) || (timeout > 0)) {
2278 2280 if ((do_get_linkstatus(fd) == B_TRUE) &&
2279 2281 (*(wl_linkstatus_t *)(gbuf->wldp_buf) == WL_CONNECTED)) {
2280 2282 section_t *p_section = NULL;
2281 2283 aelist_t *plist = NULL;
2282 2284 char bssid[32];
2283 2285 /* record bssid in the profile */
2284 2286 if (do_get_bssid(fd) == B_FALSE) {
2285 2287 free(pbuf);
2286 2288 return (B_TRUE);
2287 2289 }
2288 2290 safe_snprintf(bssid, sizeof (bssid),
2289 2291 "bssid=%02x:%02x:%02x:%02x:%02x:%02x",
2290 2292 ((uint8_t *)gbuf->wldp_buf)[0],
2291 2293 ((uint8_t *)gbuf->wldp_buf)[1],
2292 2294 ((uint8_t *)gbuf->wldp_buf)[2],
2293 2295 ((uint8_t *)gbuf->wldp_buf)[3],
2294 2296 ((uint8_t *)gbuf->wldp_buf)[4],
2295 2297 ((uint8_t *)gbuf->wldp_buf)[5]);
2296 2298
2297 2299 p_section = find_section(gp_config_file, pbuf);
2298 2300 if (p_section != NULL) {
2299 2301 plist = p_section->list;
2300 2302 update_aelist(plist, bssid);
2301 2303 }
2302 2304 free(pbuf);
2303 2305 (void) printf(gettext("%s: connecting to "
2304 2306 "%s '%s'\n"), gExecName, connect, argv[0]);
2305 2307 return (B_TRUE);
2306 2308 }
2307 2309 (void) sleep(1);
2308 2310 timeout--;
2309 2311 PRTDBG(("connect counting:......%d\n", timeout));
2310 2312 }
2311 2313 (void) fprintf(stderr, gettext("%s: failed to connect to "
2312 2314 "%s '%s'\n"), gExecName, connect, argv[0]);
2313 2315 free(pbuf);
2314 2316 return (B_FALSE);
2315 2317 }
2316 2318
2317 2319 /*
2318 2320 * if wepkey is set in the profile, display wepkey|n=*****
2319 2321 * when showprofile and getprofilewepkey.
2320 2322 * if wepkeyn is NULL, all the wepkeys will be display,
2321 2323 * otherwise, just display the matching one.
2322 2324 */
2323 2325 static void
2324 2326 print_wepkey_info(const char *id, const char *wepkeyn)
2325 2327 {
2326 2328 char *pequal, *param;
2327 2329 section_t *p_section = NULL;
2328 2330 aelist_t *plist = NULL;
2329 2331 ae_t *pae = NULL;
2330 2332
2331 2333 p_section = find_section(gp_wepkey_file, id);
2332 2334 if (p_section != NULL) {
2333 2335 plist = p_section->list;
2334 2336 pae = plist->ael_head;
2335 2337 while (pae != NULL) {
2336 2338 if (pae->ae_arg != NULL) {
2337 2339 param = safe_strdup(pae->ae_arg);
2338 2340 pequal = strchr(param, '=');
2339 2341 if (pequal == NULL)
2340 2342 return;
2341 2343 *pequal = '\0';
2342 2344 if (wepkeyn != NULL) {
2343 2345 if (strcmp(wepkeyn, param) == 0)
2344 2346 (void) printf("\t%s=*****\n",
2345 2347 param);
2346 2348 free(param);
2347 2349 return;
2348 2350 } else {
2349 2351 (void) printf("\t%s=*****\n", param);
2350 2352 free(param);
2351 2353 }
2352 2354 }
2353 2355 pae = pae->ae_next;
2354 2356 }
2355 2357 }
2356 2358 }
2357 2359
2358 2360 /*
2359 2361 * do_printpf: print each parameters of the profile, if no network name
2360 2362 * assigned, then print all profile saved in configration file.
2361 2363 */
2362 2364 /*ARGSUSED*/
2363 2365 static boolean_t
2364 2366 do_printpf(int fd, int argc, char ** argv)
2365 2367 {
2366 2368 section_t *p_section = NULL;
2367 2369 aelist_t *plist = NULL;
2368 2370 ae_t *pae = NULL;
2369 2371 char *pbuf = NULL;
2370 2372 int i;
2371 2373
2372 2374 PRTDBG(("do_printpf(%d, %x)\n", argc, argv));
2373 2375
2374 2376 /*
2375 2377 * if no profile name is inputted, all the profiles will be displayed.
2376 2378 */
2377 2379 if (argc == 0) {
2378 2380 p_section = gp_config_file->section_head;
2379 2381 while (p_section != NULL) {
2380 2382 plist = p_section->list;
2381 2383 if (plist->type == PROFILE) {
2382 2384 (void) printf("%s\n", p_section->section_id);
2383 2385 pae = plist->ael_head;
2384 2386 while (pae != NULL) {
2385 2387 if (pae->ae_arg != NULL) {
2386 2388 (void) printf("\t%s\n",
2387 2389 pae->ae_arg);
2388 2390 }
2389 2391 pae = pae->ae_next;
2390 2392 }
2391 2393 /*
2392 2394 * identify whether wepkey is set
2393 2395 * in the profile
2394 2396 */
2395 2397 print_wepkey_info(p_section->section_id, NULL);
2396 2398 }
2397 2399 p_section = p_section->section_next;
2398 2400 }
2399 2401 return (B_TRUE);
2400 2402 }
2401 2403
2402 2404 for (i = 0; i < argc; i++) {
2403 2405 pbuf = append_pa(argv[i]);
2404 2406 p_section = find_section(gp_config_file, pbuf);
2405 2407 free(pbuf);
2406 2408 if (p_section != NULL) {
2407 2409 (void) printf("%s\n", p_section->section_id);
2408 2410 plist = p_section->list;
2409 2411 if (plist != NULL) {
2410 2412 pae = plist->ael_head;
2411 2413 while (pae != NULL) {
2412 2414 if (pae->ae_arg != NULL) {
2413 2415 (void) printf("\t%s\n",
2414 2416 pae->ae_arg);
2415 2417 }
2416 2418 pae = pae->ae_next;
2417 2419 }
2418 2420 /*
2419 2421 * identify whether wepkey is set
2420 2422 * in the profile
2421 2423 */
2422 2424 print_wepkey_info(p_section->section_id, NULL);
2423 2425 }
2424 2426 } else {
2425 2427 (void) fprintf(stderr,
2426 2428 gettext("%s: showprofile : "
2427 2429 "no such profile: '%s'\n"),
2428 2430 gExecName, argv[i]);
2429 2431 return (B_FALSE);
2430 2432 }
2431 2433 }
2432 2434 return (B_TRUE);
2433 2435 }
2434 2436 /*
2435 2437 * find_ae: Find an ae by its contents, return its pointer.
2436 2438 */
2437 2439 static ae_t *
2438 2440 find_ae(aelist_t *plist, const char *arg)
2439 2441 {
2440 2442 char *param = NULL;
2441 2443 char *pnext = NULL;
2442 2444 ae_t *pae = NULL;
2443 2445
2444 2446 if ((arg == NULL) || (plist == NULL)) {
2445 2447 PRTDBG(("find_ae: arg= NULL or plist=NULL\n"));
2446 2448 return (NULL);
2447 2449 }
2448 2450 PRTDBG(("find_ae(0x%x, \"%s\")\n", plist, arg));
2449 2451 param = safe_strdup(arg);
2450 2452 pnext = strchr(param, '=');
2451 2453 if (pnext != NULL) {
2452 2454 *pnext = '\0';
2453 2455 } else {
2454 2456 PRTDBG(("find_ae: param = \"%s\"\n", param));
2455 2457 free(param);
2456 2458 return (NULL);
2457 2459 }
2458 2460
2459 2461 pae = plist->ael_head;
2460 2462 while (pae != NULL) {
2461 2463 if ((pae->ae_arg != NULL) &&
2462 2464 (strncmp(pae->ae_arg, param, strlen(param)) == 0)) {
2463 2465 PRTDBG(("find_ae: param = \"%s\"\n", param));
2464 2466 free(param);
2465 2467 return (pae);
2466 2468 }
2467 2469 pae = pae->ae_next;
2468 2470 }
2469 2471 free(param);
2470 2472 return (NULL);
2471 2473 }
2472 2474
2473 2475 /*
2474 2476 * update_aelist: Update an aelist by arg, for example:
2475 2477 * there are an item with content"essid=ap7-2",
2476 2478 * update_aelist(0x..., "essid=myssid2") will update it as "essid=myssid2"
2477 2479 */
2478 2480 static void
2479 2481 update_aelist(aelist_t *plist, const char *arg)
2480 2482 {
2481 2483 ae_t *pae = NULL;
2482 2484
2483 2485 assert((arg != NULL)&&(plist != NULL));
2484 2486 PRTDBG(("update_aelist(0x%x, \"%s\")\n", plist, arg));
2485 2487 pae = find_ae(plist, arg);
2486 2488 if (pae == NULL) {
2487 2489 new_ae(plist, arg);
2488 2490 } else {
2489 2491 free(pae->ae_arg);
2490 2492 pae->ae_arg = safe_strdup(arg);
2491 2493 }
2492 2494 }
2493 2495
2494 2496 /*
2495 2497 * do_deletepf: delete a profile in configration files.
2496 2498 */
2497 2499 /*ARGSUSED*/
2498 2500 static boolean_t
2499 2501 do_deletepf(int fd, int argc, char **argv)
2500 2502 {
2501 2503 int i = 0;
2502 2504 char *section_id;
2503 2505 char *prefer;
2504 2506 section_t *p_section = NULL, *p_sectionbak = NULL;
2505 2507 aelist_t *plist = NULL;
2506 2508
2507 2509 PRTDBG(("do_deletepf(%d, \"%s\")\n", argc, argv));
2508 2510 if (argc <= 0) {
2509 2511 do_print_usage();
2510 2512 exit(WIFI_IMPROPER_USE);
2511 2513 }
2512 2514
2513 2515 /*
2514 2516 * if a "all" is inputted, all the profiles will be deleted.
2515 2517 */
2516 2518 if (strcasecmp(argv[0], "all") == 0) {
2517 2519 p_section = gp_config_file->section_head;
2518 2520 while ((p_section != NULL) &&
2519 2521 ((plist = p_section->list) != NULL)) {
2520 2522 if (plist->type == PROFILE) {
2521 2523 p_sectionbak = p_section->section_next;
2522 2524 section_id = safe_strdup(p_section->section_id);
2523 2525 (void) del_section(gp_config_file, section_id);
↓ open down ↓ |
2487 lines elided |
↑ open up ↑ |
2524 2526 (void) del_section(gp_wepkey_file, section_id);
2525 2527 /*
2526 2528 * remove the '[]' of the [section_id]
2527 2529 */
2528 2530 prefer = section_id + 1;
2529 2531 *(prefer + strlen(section_id) - 2) = '\0';
2530 2532 (void) del_prefer(gp_config_file, prefer,
2531 2533 B_FALSE);
2532 2534 free(section_id);
2533 2535 p_section = p_sectionbak;
2534 - continue;
2536 + continue;
2535 2537 }
2536 2538 p_section = p_section->section_next;
2537 2539 }
2538 2540 return (B_TRUE);
2539 2541 }
2540 2542 if (gp_config_file != NULL) {
2541 2543 for (i = 0; i < argc; i++) {
2542 2544 section_id = append_pa(argv[i]);
2543 2545 if (del_section(gp_config_file, section_id)
2544 2546 == B_FALSE) {
2545 2547 if (del_section(gp_wepkey_file, section_id)
2546 2548 == B_TRUE) {
2547 2549 (void) del_prefer(gp_config_file,
2548 2550 argv[i], B_FALSE);
2549 2551 free(section_id);
2550 2552 return (B_TRUE);
2551 2553 } else {
2552 2554 (void) fprintf(stderr,
2553 2555 gettext("%s: deleteprofile"
2554 2556 ": no such profile: '%s'\n"),
2555 2557 gExecName, argv[i]);
2556 2558 free(section_id);
2557 2559 return (B_FALSE);
2558 2560 }
2559 2561 }
2560 2562 (void) del_prefer(gp_config_file, argv[i], B_FALSE);
2561 2563 (void) del_section(gp_wepkey_file, section_id);
2562 2564 free(section_id);
2563 2565 }
2564 2566 }
2565 2567 return (B_TRUE);
2566 2568 }
2567 2569
2568 2570 /*
2569 2571 * do_history: Print the list in {history} section.
2570 2572 */
2571 2573 /*ARGSUSED*/
2572 2574 static boolean_t
2573 2575 do_history(int fd, int argc, char **argv)
2574 2576 {
2575 2577 section_t *p_section = NULL;
2576 2578 aelist_t *plist = NULL;
2577 2579 ae_t *pae = NULL;
2578 2580 char *param, *param_bak, *pcomma;
2579 2581 uint32_t maxessidlen = 0, ulen;
2580 2582 char format[256], *ntstr;
2581 2583 uint32_t nt = 0, cnt = 0;
2582 2584 int len;
2583 2585 time_t cltime;
2584 2586
2585 2587 PRTDBG(("do_history(%d, 0x%x)\n", argc, argv));
2586 2588 if (argc > 0) {
2587 2589 (void) fprintf(stderr, gettext("%s: trailing useless tokens "
2588 2590 "after 'history'\n"), gExecName);
2589 2591 }
2590 2592 p_section = find_section(gp_config_file, WIFI_HISTORY);
2591 2593 if (p_section == NULL) {
2592 2594 PRTDBG(("no history section\n"));
2593 2595 return (B_FALSE);
2594 2596 }
2595 2597 plist = p_section->list;
2596 2598
2597 2599 /*
2598 2600 * If history section is empty, directly return.
2599 2601 */
2600 2602 if (plist == NULL)
2601 2603 return (B_TRUE);
2602 2604 /*
2603 2605 * construct the output format in terms of the
2604 2606 * maxmium essid length
2605 2607 */
2606 2608 pae = NULL;
2607 2609 pae = plist->ael_head;
2608 2610 while (pae != NULL) {
2609 2611 if (pae->ae_arg != NULL) {
2610 2612 param = safe_strdup(pae->ae_arg);
2611 2613 pcomma = strchr(param, ',');
2612 2614 if (pcomma == NULL) {
2613 2615 (void) fprintf(stderr,
2614 2616 gettext("%s: history : "
2615 2617 "data format error\n"),
2616 2618 gExecName);
2617 2619 free(param);
2618 2620 return (B_FALSE);
2619 2621 }
2620 2622 *pcomma = '\0';
2621 2623 ulen = strlen(param);
2622 2624 maxessidlen = (maxessidlen > ulen
2623 2625 ? maxessidlen:ulen);
2624 2626 free(param);
2625 2627 }
2626 2628 pae = pae->ae_next;
2627 2629 }
2628 2630 if ((nt = (maxessidlen / 8 + 1)) > 4)
2629 2631 nt = 4;
2630 2632 len = snprintf(format, sizeof (format), gettext("essid"));
2631 2633 ntstr = construct_format(nt);
2632 2634 assert((ntstr != NULL) && (strlen(ntstr) <= 4));
2633 2635 len += snprintf(format + len, sizeof (format) - len, "%s", ntstr);
2634 2636 len += snprintf(format + len, sizeof (format) - len,
2635 2637 gettext("bssid\t\t encryption\tlast seen\n"));
2636 2638
2637 2639 if ((len <= 0) || (len > sizeof (format) - 1)) {
2638 2640 (void) printf(gettext("essid\t\t\t\tbssid\t\t encryption"
2639 2641 "\tlast seen\n"));
2640 2642 } else {
2641 2643 (void) printf("%s", format);
2642 2644 }
2643 2645 /*
2644 2646 * output the contents of the history section.
2645 2647 */
2646 2648 pae = plist->ael_head;
2647 2649 while (pae != NULL) {
2648 2650 if (pae->ae_arg != NULL) {
2649 2651 param = safe_strdup(pae->ae_arg);
2650 2652 param_bak = param;
2651 2653 if ((pcomma = strchr(param, ',')) != NULL) {
2652 2654 *pcomma = '\0';
2653 2655 cnt = nt - (min((strlen(param)/8 + 1), 4) - 1);
2654 2656 ntstr = construct_format(cnt);
2655 2657 assert(ntstr != NULL);
2656 2658 /* display essid */
2657 2659 (void) printf("%s%s", param, ntstr);
2658 2660 free(ntstr);
2659 2661 }
2660 2662 param = pcomma + 1;
2661 2663 if ((pcomma = strchr(param, ',')) != NULL) {
2662 2664 *pcomma = '\0';
2663 2665 /* display bssid */
2664 2666 (void) printf("%s ", param);
2665 2667 }
2666 2668 param = pcomma + 1;
2667 2669 if ((pcomma = strchr(param, ',')) != NULL) {
2668 2670 *pcomma = '\0';
2669 2671 /* display wep */
2670 2672 (void) printf("%s\t\t", param);
2671 2673 }
2672 2674 param = pcomma + 1;
2673 2675 /* display time stamp */
2674 2676 cltime = (time_t)atol(param);
2675 2677 (void) printf("%s", ctime(&cltime));
2676 2678 free(param_bak);
2677 2679 }
2678 2680 pae = pae->ae_next;
2679 2681 }
2680 2682
2681 2683 return (B_TRUE);
2682 2684 }
2683 2685
2684 2686 /*
2685 2687 * do_lsprefer: Print the list in {preferrence} section
2686 2688 */
2687 2689 /*ARGSUSED*/
2688 2690 static boolean_t
2689 2691 do_lsprefer(int fd, int argc, char **argv)
2690 2692 {
2691 2693 int i = 0;
2692 2694 section_t *p_section = NULL;
2693 2695 aelist_t *plist = NULL;
2694 2696 ae_t *pae = NULL;
2695 2697 char *pbuf;
2696 2698
2697 2699 PRTDBG(("do_lsprefer(%d, 0x%x)\n", argc, argv));
2698 2700 if (argc > 0) {
2699 2701 (void) fprintf(stderr, gettext("%s: trailing useless tokens "
2700 2702 "after 'listprefer'\n"), gExecName);
2701 2703 }
2702 2704 p_section = find_section(gp_config_file, WIFI_PREFER);
2703 2705 if (p_section != NULL) {
2704 2706 plist = p_section->list;
2705 2707 if (plist != NULL) {
2706 2708 pae = NULL;
2707 2709 pae = plist->ael_head;
2708 2710 while (pae != NULL) {
2709 2711 if (pae->ae_arg != NULL) {
2710 2712 pbuf = append_pa(pae->ae_arg);
2711 2713 (void) printf("%d\t%s\n", ++i, pbuf);
2712 2714 }
2713 2715 pae = pae->ae_next;
2714 2716 }
2715 2717 }
2716 2718 return (B_TRUE);
2717 2719 } else {
2718 2720 PRTDBG(("no preference section\n"));
2719 2721 return (B_FALSE);
2720 2722 }
2721 2723 }
2722 2724
2723 2725 /*
2724 2726 * do_rmprefer: Remove an item in {preferrence} list
2725 2727 */
2726 2728 /*ARGSUSED*/
2727 2729 static boolean_t
2728 2730 do_rmprefer(int fd, int argc, char **argv)
2729 2731 {
2730 2732 int i = 0;
2731 2733 section_t *p_section = NULL;
2732 2734 aelist_t *plist = NULL;
2733 2735 ae_t *pae = NULL;
2734 2736
2735 2737 PRTDBG(("do_rmprefer(%d, 0x%x)\n", argc, argv));
2736 2738 if (argc <= 0) {
2737 2739 do_print_usage();
2738 2740 exit(WIFI_IMPROPER_USE);
2739 2741 }
2740 2742
2741 2743 /*
2742 2744 * if a "all" is inputted, all the items in the preference
2743 2745 * list will be deleted.
↓ open down ↓ |
199 lines elided |
↑ open up ↑ |
2744 2746 */
2745 2747 if (strcasecmp(argv[0], "all") == 0) {
2746 2748 p_section = find_section(gp_config_file, WIFI_PREFER);
2747 2749 if (p_section != NULL)
2748 2750 plist = p_section->list;
2749 2751
2750 2752 if ((p_section == NULL) || (plist == NULL))
2751 2753 return (B_FALSE);
2752 2754 pae = plist->ael_head;
2753 2755 while (pae != NULL) {
2756 + ae_t *next = pae->ae_next;
2754 2757 free(pae);
2755 - pae = pae->ae_next;
2758 + pae = next;
2756 2759 }
2757 2760 plist->ael_head = plist->ael_tail = NULL;
2758 2761 plist->ael_argc = 0;
2759 2762 } else if (gp_config_file != NULL) {
2760 2763 for (i = 0; i < argc; i++) {
2761 2764 if (del_prefer(gp_config_file, argv[i], B_TRUE)
2762 2765 == B_FALSE) {
2763 2766 return (B_FALSE);
2764 2767 }
2765 2768 }
2766 2769 }
2767 2770 return (B_TRUE);
2768 2771 }
2769 2772
2770 2773 static boolean_t
2771 2774 is_prefer_rank_valid(const char *pbuf)
2772 2775 {
2773 2776 int i;
2774 2777 boolean_t ret = B_FALSE;
2775 2778
2776 2779 for (i = 0; i < strlen(pbuf); i++) {
2777 2780 if (isdigit(pbuf[i]) == 0) {
2778 2781 ret = B_FALSE;
2779 2782 goto exit0;
2780 2783 }
2781 2784 }
2782 2785 i = atoi(pbuf);
2783 2786 if ((i >= 1) && (i <= MAX_PREFERENCE_NUM))
2784 2787 ret = B_TRUE;
2785 2788 exit0:
2786 2789 return (ret);
2787 2790 }
2788 2791
2789 2792 /*
2790 2793 * do_setprefer: Set network preferrence
2791 2794 */
2792 2795 /*ARGSUSED*/
2793 2796 static boolean_t
2794 2797 do_setprefer(int fd, int argc, char **argv)
2795 2798 {
2796 2799 int rank = 0;
2797 2800
2798 2801 PRTDBG(("do_setprefer(%d, 0x%x)\n", argc, argv));
2799 2802 if (argc <= 0) {
2800 2803 do_print_usage();
2801 2804 exit(WIFI_IMPROPER_USE);
2802 2805 }
2803 2806 if (argc == 1) {
2804 2807 rank = 1;
2805 2808 } else {
2806 2809 if (is_prefer_rank_valid(argv[1]) == B_FALSE) {
2807 2810 (void) fprintf(stderr, gettext("%s: preference rank "
2808 2811 "should be an integer within 1-10\n"), gExecName);
2809 2812 return (B_FALSE);
2810 2813 }
2811 2814 rank = atoi(argv[1]);
2812 2815 }
2813 2816 return (set_prefer(gp_config_file, argv[0], rank));
2814 2817 }
2815 2818
2816 2819 static boolean_t
2817 2820 is_wepkeyindex_valid(const char *pbuf)
2818 2821 {
2819 2822 int i;
2820 2823 boolean_t ret = B_FALSE;
2821 2824
2822 2825 for (i = 0; i < strlen(pbuf); i++) {
2823 2826 if (isdigit(pbuf[i]) == 0) {
2824 2827 ret = B_FALSE;
2825 2828 goto exit0;
2826 2829 }
2827 2830 }
2828 2831 i = atoi(pbuf);
2829 2832 if ((i >= 1) && (i <= MAX_NWEPKEYS))
2830 2833 ret = B_TRUE;
2831 2834 exit0:
2832 2835 return (ret);
2833 2836 }
2834 2837
2835 2838 static boolean_t
2836 2839 is_channel_valid(const char *pbuf)
2837 2840 {
2838 2841 int i;
2839 2842 boolean_t ret = B_FALSE;
2840 2843
2841 2844 for (i = 0; i < strlen(pbuf); i++) {
2842 2845 if (isdigit(pbuf[i]) == 0) {
2843 2846 ret = B_FALSE;
2844 2847 goto exit0;
2845 2848 }
2846 2849 }
2847 2850 i = atoi(pbuf);
2848 2851 if ((i >= 0) && (i <= MAX_CHANNEL_NUM))
2849 2852 ret = B_TRUE;
2850 2853 exit0:
2851 2854 return (ret);
2852 2855 }
2853 2856
2854 2857 static boolean_t
2855 2858 is_wepkey_valid(const char *pbuf, uint32_t length)
2856 2859 {
2857 2860 int i;
2858 2861 boolean_t ret = B_FALSE;
2859 2862
2860 2863 switch (length) {
2861 2864 case 10:
2862 2865 case 26:
2863 2866 for (i = 0; i < length; i++) {
2864 2867 if (isxdigit(pbuf[i]) == 0) {
2865 2868 ret = B_FALSE;
2866 2869 goto exit0;
2867 2870 }
2868 2871 }
2869 2872 ret = B_TRUE;
2870 2873 break;
2871 2874 case 5:
2872 2875 case 13:
2873 2876 ret = B_TRUE;
2874 2877 break;
2875 2878 default:
2876 2879 ret = B_FALSE;
2877 2880 break;
2878 2881 }
2879 2882 exit0:
2880 2883 if (ret == B_FALSE) {
2881 2884 (void) fprintf(stderr, gettext("%s: "
2882 2885 "wepkey should be:\n"
2883 2886 "\t 40bits: 5 char or 10 hex digits.\n"
2884 2887 "\t 128bits: 13 char or 26 hex digits.\n"),
2885 2888 gExecName);
2886 2889 }
2887 2890 return (ret);
2888 2891 }
2889 2892
2890 2893 /*
2891 2894 * get_valid_wepkey: get an valid wepkey from stdin
2892 2895 */
2893 2896 static char *
2894 2897 get_valid_wepkey()
2895 2898 {
2896 2899 int i = 0;
2897 2900 char *buf = NULL;
2898 2901 uint8_t length = 0;
2899 2902 struct termios stored_settings;
2900 2903 struct termios new_settings;
2901 2904
2902 2905 PRTDBG(("get_valid_wepkey()\n"));
2903 2906 buf = safe_calloc(sizeof (char), MAX_KEY_LENGTH + 2);
2904 2907 /*
2905 2908 * Because we need to get single char from terminal, so we need to
2906 2909 * disable canonical mode and set buffer size to 1 tyte. And because
2907 2910 * wepkey should not be see by others, so we disable echo too.
2908 2911 */
2909 2912 (void) fflush(stdin);
2910 2913 (void) tcgetattr(0, &stored_settings);
2911 2914 new_settings = stored_settings;
2912 2915 new_settings.c_lflag &= (~ICANON);
2913 2916 new_settings.c_lflag &= (~ECHO);
2914 2917 new_settings.c_cc[VTIME] = 0;
2915 2918 new_settings.c_cc[VMIN] = 1;
2916 2919 /* Set new terminal attributes */
2917 2920 (void) tcsetattr(0, TCSANOW, &new_settings);
2918 2921 while (((buf[i++] = getchar()) != '\n') && (i < MAX_KEY_LENGTH + 1)) {
2919 2922 (void) putchar('*');
2920 2923 }
2921 2924 (void) putchar('\n');
2922 2925 /* Restore terminal attributes */
2923 2926 (void) tcsetattr(0, TCSANOW, &stored_settings);
2924 2927 (void) fflush(stdin);
2925 2928
2926 2929 if (buf[--i] != '\n') {
2927 2930 (void) fprintf(stderr, gettext("%s: wepkey length "
2928 2931 "exceeds 26 hex digits\n"), gExecName);
2929 2932 free(buf);
2930 2933 return (NULL);
2931 2934 }
2932 2935 /* Replace last char '\n' with '\0' */
2933 2936 buf[i] = '\0';
2934 2937 length = (uint8_t)i;
2935 2938 return ((is_wepkey_valid(buf, length) == B_TRUE)?
2936 2939 buf : NULL);
2937 2940 }
2938 2941
2939 2942 /*
2940 2943 * do_set_wepkey: Set parameters in wepkey, and call ioctl
2941 2944 */
2942 2945 static boolean_t
2943 2946 do_set_wepkey(int fd, const char *pbuf)
2944 2947 {
2945 2948 int id = 0;
2946 2949 char i = 0;
2947 2950 uint8_t len = 0;
2948 2951 uint8_t length;
2949 2952 const char *wepkey = NULL;
2950 2953 char key[MAX_KEY_LENGTH] = {0};
2951 2954 unsigned int keytmp;
2952 2955 wl_wep_key_tab_t wepkey_tab;
2953 2956
2954 2957 PRTDBG(("do_set_wepkey(%d, \"%s\")\n", fd, pbuf));
2955 2958 if (!check_authority(AUTH_WEP)) {
2956 2959 exit(WIFI_FATAL_ERR);
2957 2960 }
2958 2961 id = pbuf[strlen("wepkeyn") - 1] - '0';
2959 2962 wepkey = get_value(pbuf);
2960 2963 length = strlen(wepkey);
2961 2964 switch (length) {
2962 2965 case 10:
2963 2966 case 26:
2964 2967 for (i = 0; i < length / 2; i++) {
2965 2968 (void) sscanf(wepkey + i * 2, "%2x", &keytmp);
2966 2969 key[i] = (char)keytmp;
2967 2970 }
2968 2971 len = length / 2;
2969 2972 break;
2970 2973 case 5:
2971 2974 case 13:
2972 2975 (void) strlcpy(key, wepkey, MAX_KEY_LENGTH);
2973 2976 len = length;
2974 2977 break;
2975 2978 default:
2976 2979 PRTDBG(("do_set_wepkey: error pbuf size\n"));
2977 2980 (void) fprintf(stderr, gettext("%s: "
2978 2981 "wepkey should be:\n"
2979 2982 "\t 40bits: 5 char or 10 hex digits.\n"
2980 2983 "\t 128bits: 13 char or 26 hex digits.\n"),
2981 2984 gExecName);
2982 2985 exit(WIFI_FATAL_ERR);
2983 2986 }
2984 2987
2985 2988 (void) memset(wepkey_tab, 0, sizeof (wepkey_tab));
2986 2989 for (i = 0; i < MAX_NWEPKEYS; i++) {
2987 2990 wepkey_tab[i].wl_wep_operation = WL_NUL;
2988 2991 }
2989 2992
2990 2993 if (id > 0 && id <= MAX_NWEPKEYS) {
2991 2994 wepkey_tab[id-1].wl_wep_operation = WL_ADD;
2992 2995 wepkey_tab[id-1].wl_wep_length = len;
2993 2996 (void) memcpy(wepkey_tab[id-1].wl_wep_key, key, len);
2994 2997 } else {
2995 2998 (void) fprintf(stderr, gettext("%s: wepkeyindex "
2996 2999 "should be an integer within the range 1-4\n"), gExecName);
2997 3000 exit(WIFI_FATAL_ERR);
2998 3001 }
2999 3002 (void) memmove(gbuf->wldp_buf, &wepkey_tab, sizeof (wl_wep_key_tab_t));
3000 3003 return (call_ioctl(fd, WLAN_SET_PARAM, WL_WEP_KEY_TAB,
3001 3004 sizeof (wl_wep_key_tab_t)));
3002 3005 }
3003 3006
3004 3007 /*
3005 3008 * get the committed wepkey. the return form is like wepkey1=*****;
3006 3009 */
3007 3010 /*ARGSUSED*/
3008 3011 static char *
3009 3012 get_commit_key(int fd, int argc, char **argv)
3010 3013 {
3011 3014 int key;
3012 3015 int len;
3013 3016 char *wepkey = NULL;
3014 3017 char *wepkey_confirm = NULL;
3015 3018 char *pbuf = NULL;
3016 3019
3017 3020 key = atoi(argv[0]);
3018 3021 if (key <= 0 || key > MAX_NWEPKEYS) {
3019 3022 (void) fprintf(stderr, gettext("%s: wepkeyindex "
3020 3023 "should be an integer within the range 1-4\n"), gExecName);
3021 3024 goto exit0;
3022 3025 }
3023 3026 (void) printf(gettext("input wepkey%d:"), key);
3024 3027 wepkey = get_valid_wepkey();
3025 3028 if (wepkey == NULL) {
3026 3029 goto exit0;
3027 3030 }
3028 3031 (void) printf(gettext("confirm wepkey%d:"), key);
3029 3032 wepkey_confirm = get_valid_wepkey();
3030 3033 if (wepkey_confirm == NULL) {
3031 3034 free(wepkey);
3032 3035 goto exit0;
3033 3036 }
3034 3037 if (strcmp(wepkey, wepkey_confirm) != 0) {
3035 3038 free(wepkey);
3036 3039 free(wepkey_confirm);
3037 3040 (void) fprintf(stderr,
3038 3041 gettext("%s: wepkey: "
3039 3042 "two inputs are not identical\n"), gExecName);
3040 3043 goto exit0;
3041 3044 }
3042 3045 free(wepkey_confirm); /* wepkey_confirm is no longer used */
3043 3046
3044 3047 len = MAX_KEY_LENGTH + strlen("wepkey1=\n") + 1;
3045 3048 pbuf = safe_malloc(len);
3046 3049 safe_snprintf(pbuf, len, "%s%d=%s", "wepkey", key, wepkey);
3047 3050
3048 3051 free(wepkey); /* wepkey is no longer used */
3049 3052 return (pbuf);
3050 3053 exit0:
3051 3054 return (NULL);
3052 3055 }
3053 3056
3054 3057 /*
3055 3058 * do_wepkey: Get input from user, call do_set_wepkey
3056 3059 */
3057 3060 /*ARGSUSED*/
3058 3061 static boolean_t
3059 3062 do_wepkey(int fd, int argc, char **argv)
3060 3063 {
3061 3064 char *pbuf;
3062 3065
3063 3066 PRTDBG(("do_wepkey(%d, 0x%x)\n", argc, argv));
3064 3067 assert(fd > 0);
3065 3068 if (argc <= 0) {
3066 3069 do_print_usage();
3067 3070 exit(WIFI_IMPROPER_USE);
3068 3071 }
3069 3072 if (argc > 1) {
3070 3073 (void) fprintf(stderr, gettext("%s: trailing useless tokens "
3071 3074 "after 'setwepkey'\n"), gExecName);
3072 3075 }
3073 3076 pbuf = get_commit_key(fd, argc, argv);
3074 3077 if ((pbuf != NULL) && (do_set_wepkey(fd, pbuf) == B_TRUE)) {
3075 3078 free(pbuf);
3076 3079 return (B_TRUE);
3077 3080 }
3078 3081 free(pbuf);
3079 3082 return (B_FALSE);
3080 3083 }
3081 3084
3082 3085 /*ARGSUSED*/
3083 3086 static boolean_t
3084 3087 do_setprofwepkey(int fd, int argc, char **argv)
3085 3088 {
3086 3089 char *pbuf;
3087 3090 char *section_id = NULL;
3088 3091 section_t *p_section = NULL;
3089 3092 aelist_t *plist = NULL;
3090 3093
3091 3094 PRTDBG(("do_setprofwepkey(%d, 0x%x)\n", argc, argv));
3092 3095 if (argc < 2) {
3093 3096 do_print_usage();
3094 3097 exit(WIFI_IMPROPER_USE);
3095 3098 }
3096 3099 if (argc > 2) {
3097 3100 (void) fprintf(stderr, gettext("%s: trailing useless tokens "
3098 3101 "after 'setprofwepkey'\n"), gExecName);
3099 3102 }
3100 3103
3101 3104 section_id = append_pa(argv[0]);
3102 3105 p_section = find_section(gp_wepkey_file, section_id);
3103 3106 free(section_id);
3104 3107 if (p_section == NULL) {
3105 3108 (void) fprintf(stderr, gettext("%s: "
3106 3109 "no such profile: '%s'\n"),
3107 3110 gExecName, argv[0]);
3108 3111 return (B_FALSE);
3109 3112 }
3110 3113
3111 3114 argc--;
3112 3115 argv++;
3113 3116 pbuf = get_commit_key(fd, argc, argv);
3114 3117 if (pbuf == NULL)
3115 3118 return (B_FALSE);
3116 3119 plist = p_section->list;
3117 3120 update_aelist(plist, pbuf);
3118 3121
3119 3122 return (B_TRUE);
3120 3123 }
3121 3124
3122 3125 /*
3123 3126 * do_wlanlist: Scan for wlanlist
3124 3127 */
3125 3128 /*ARGSUSED*/
3126 3129 static boolean_t
3127 3130 do_wlanlist(int fd, int argc, char **argv)
3128 3131 {
3129 3132 PRTDBG(("do_wlanlist(%d, 0x%x)\n", argc, argv));
3130 3133 assert(fd > 0);
3131 3134 if (argc > 0) {
3132 3135 (void) fprintf(stderr, gettext("%s: trailing useless tokens "
3133 3136 "after 'scan'\n"), gExecName);
3134 3137 }
3135 3138 if (call_ioctl(fd, WLAN_COMMAND, WL_SCAN, 0) == B_FALSE) {
3136 3139 (void) fprintf(stderr, gettext("%s: failed to scan\n"),
3137 3140 gExecName);
3138 3141 return (B_FALSE);
3139 3142 }
3140 3143 if (do_get_wlanlist(fd) == B_TRUE) {
3141 3144 print_gbuf(WLANLIST);
3142 3145 }
3143 3146 return (B_TRUE);
3144 3147 }
3145 3148
3146 3149 /*
3147 3150 * do_showstatus: show the basic status of the interface, including
3148 3151 * linkstauts, essid, encryption and signal strength.
3149 3152 */
3150 3153 /*ARGSUSED*/
3151 3154 static boolean_t
3152 3155 do_showstatus(int fd, int argc, char **argv)
3153 3156 {
3154 3157 wl_rssi_t signal;
3155 3158 char *active_profile = NULL;
3156 3159
3157 3160 PRTDBG(("do_showstatus(%d, 0x%x)\n", argc, argv));
3158 3161 assert(fd > 0);
3159 3162
3160 3163 if (argc > 0) {
3161 3164 (void) fprintf(stderr, gettext("%s: trailing useless tokens "
3162 3165 "after 'showstatus'\n"), gExecName);
3163 3166 }
3164 3167 if (do_get_linkstatus(fd) == B_TRUE) {
3165 3168 print_gbuf(LINKSTATUS);
3166 3169 if (*(wl_linkstatus_t *)(gbuf->wldp_buf) == WL_NOTCONNECTED) {
3167 3170 return (B_TRUE);
3168 3171 }
3169 3172 }
3170 3173 active_profile = find_active_profile(fd);
3171 3174 (void) printf("\tactive profile: %s\n",
3172 3175 active_profile ? active_profile : "none");
3173 3176 if (do_get_essid(fd) == B_TRUE) {
3174 3177 print_gbuf(ESSID);
3175 3178 }
3176 3179 if (do_get_bssid(fd) == B_TRUE) {
3177 3180 print_gbuf(BSSID);
3178 3181 }
3179 3182 if (do_get_encryption(fd) == B_TRUE) {
3180 3183 print_gbuf(ENCRYPTION);
3181 3184 }
3182 3185 if (do_get_signal(fd) == B_TRUE) {
3183 3186 signal = *(wl_rssi_t *)(gbuf->wldp_buf);
3184 3187 if (signal < 4) {
3185 3188 (void) printf("\tsignal strength: weak(%d)\n",
3186 3189 signal);
3187 3190 } else if ((signal >= 4) && (signal <= 11)) {
3188 3191 (void) printf("\tsignal strength: medium(%d)\n",
3189 3192 signal);
3190 3193 } else {
3191 3194 (void) printf("\tsignal strength: strong(%d)\n",
3192 3195 signal);
3193 3196 }
3194 3197 }
3195 3198
3196 3199 return (B_TRUE);
3197 3200 }
3198 3201
3199 3202
3200 3203 /*
3201 3204 * do_restoredef: Ask driver for loading default parameters
3202 3205 */
3203 3206 /*ARGSUSED*/
3204 3207 static boolean_t
3205 3208 do_restoredef(int fd, int argc, char **argv)
3206 3209 {
3207 3210 PRTDBG(("do_restoredef(%d, 0x%x)\n", argc, argv));
3208 3211 assert(fd > 0);
3209 3212
3210 3213 if (argc > 0) {
3211 3214 (void) fprintf(stderr, gettext("%s: trailing useless tokens "
3212 3215 "after 'restoredef'\n"), gExecName);
3213 3216 }
3214 3217 record_active_profile(NULL, RECORD_DEL);
3215 3218 if (call_ioctl(fd, WLAN_COMMAND, WL_LOAD_DEFAULTS, 0) == B_FALSE) {
3216 3219 return (B_FALSE);
3217 3220 } else {
3218 3221 return (B_TRUE);
3219 3222 }
3220 3223 }
3221 3224
3222 3225 /*
3223 3226 * do_disconnect: disconnect from the current connectted network
3224 3227 */
3225 3228 /*ARGSUSED*/
3226 3229 static boolean_t
3227 3230 do_disconnect(int fd, int argc, char **argv)
3228 3231 {
3229 3232 PRTDBG(("do_disconnect(%d, 0x%x)\n", argc, argv));
3230 3233 assert(fd > 0);
3231 3234
3232 3235 if (argc > 0) {
3233 3236 (void) fprintf(stderr, gettext("%s: trailing useless tokens "
3234 3237 "after 'disconnect'\n"), gExecName);
3235 3238 }
3236 3239 record_active_profile(NULL, RECORD_DEL);
3237 3240 if (call_ioctl(fd, WLAN_COMMAND, WL_DISASSOCIATE, 0) == B_FALSE) {
3238 3241 return (B_FALSE);
3239 3242 } else {
3240 3243 return (B_TRUE);
3241 3244 }
3242 3245 }
3243 3246
3244 3247 static boolean_t
3245 3248 do_set_essid(int fd, const char *arg)
3246 3249 {
3247 3250 wl_essid_t essid;
3248 3251
3249 3252 PRTDBG(("do_set_essid(%d, \"%s\")\n", fd, arg));
3250 3253
3251 3254 /*
3252 3255 * a trick here: clean the active_profile flag
3253 3256 * in section{active_profile}
3254 3257 */
3255 3258 record_active_profile(NULL, RECORD_DEL);
3256 3259
3257 3260 (void) memset(&essid, 0x0, sizeof (essid));
3258 3261
3259 3262 if (arg == NULL || strcmp(arg, "") == 0) {
3260 3263 essid.wl_essid_length = 0;
3261 3264 essid.wl_essid_essid[0] = '\0';
3262 3265 } else {
3263 3266 essid.wl_essid_length = strlen(arg);
3264 3267 if (essid.wl_essid_length > MAX_ESSID_LENGTH - 1) {
3265 3268 (void) fprintf(stderr, gettext("%s: "
3266 3269 "essid exceeds 32 bytes\n"), gExecName);
3267 3270 exit(WIFI_FATAL_ERR);
3268 3271 }
3269 3272 (void) strcpy(essid.wl_essid_essid, arg);
3270 3273 }
3271 3274 (void) memmove(gbuf->wldp_buf, &essid, sizeof (wl_essid_t));
3272 3275 return (call_ioctl(fd, WLAN_SET_PARAM, WL_ESSID, sizeof (wl_essid_t)));
3273 3276 }
3274 3277
3275 3278 static boolean_t
3276 3279 do_set_bsstype(int fd, const char *arg)
3277 3280 {
3278 3281 wl_bss_type_t bsstype;
3279 3282
3280 3283 assert(arg != NULL);
3281 3284
3282 3285 PRTDBG(("do_set_bsstype(%d, \"%s\")\n", fd, arg));
3283 3286
3284 3287 (void) memset(&bsstype, 0xff, sizeof (bsstype));
3285 3288
3286 3289 if ((strcasecmp(arg, "BSS") == 0) ||
3287 3290 (strcasecmp(arg, "AP") == 0) ||
3288 3291 (strcasecmp(arg, "INFRASTRUCTURE") == 0)) {
3289 3292 bsstype = WL_BSS_BSS;
3290 3293 } else if ((strcasecmp(arg, "IBSS") == 0) ||
3291 3294 (strcasecmp(arg, "AD-HOC") == 0)) {
3292 3295 bsstype = WL_BSS_IBSS;
3293 3296 } else if (strcasecmp(arg, "AUTO") == 0) {
3294 3297 bsstype = WL_BSS_ANY;
3295 3298 } else {
3296 3299 (void) fprintf(stderr, gettext("%s: bsstype: "
3297 3300 "bss(ap,infrastructure) ibss(ad-hoc) or auto\n"),
3298 3301 gExecName);
3299 3302 exit(WIFI_FATAL_ERR);
3300 3303 }
3301 3304
3302 3305 (void) memmove(gbuf->wldp_buf, &bsstype, sizeof (wl_bss_type_t));
3303 3306 return (call_ioctl(fd, WLAN_SET_PARAM, WL_BSS_TYPE,
3304 3307 sizeof (wl_bss_type_t)));
3305 3308 }
3306 3309
3307 3310 static boolean_t
3308 3311 do_set_createibss(int fd, const char *arg)
3309 3312 {
3310 3313 wl_create_ibss_t create_ibss;
3311 3314
3312 3315 assert(arg != NULL);
3313 3316
3314 3317 PRTDBG(("do_set_createibss(%d, \"%s\")\n", fd, arg));
3315 3318
3316 3319 (void) memset(&create_ibss, 0x0, sizeof (create_ibss));
3317 3320
3318 3321 if (strcasecmp(arg, "YES") == 0) {
3319 3322 create_ibss = B_TRUE;
3320 3323 } else if (strcasecmp(arg, "NO") == 0) {
3321 3324 create_ibss = B_FALSE;
3322 3325 } else {
3323 3326 (void) fprintf(stderr, gettext("%s: "
3324 3327 "createibss: yes or no\n"), gExecName);
3325 3328 exit(WIFI_FATAL_ERR);
3326 3329 }
3327 3330
3328 3331 (void) memmove(gbuf->wldp_buf, &create_ibss,
3329 3332 sizeof (wl_create_ibss_t));
3330 3333 return (call_ioctl(fd, WLAN_SET_PARAM, WL_CREATE_IBSS,
3331 3334 sizeof (wl_create_ibss_t)));
3332 3335 }
3333 3336
3334 3337 static boolean_t
3335 3338 do_set_channel(int fd, const char *arg)
3336 3339 {
3337 3340 wl_phy_conf_t phy_conf;
3338 3341
3339 3342 assert(arg != NULL);
3340 3343 PRTDBG(("do_set_channel(%d, \"%s\")\n", fd, arg));
3341 3344
3342 3345 (void) memset(&phy_conf, 0xff, sizeof (phy_conf));
3343 3346
3344 3347 if (is_channel_valid(arg) == B_FALSE) {
3345 3348 (void) fprintf(stderr, gettext("%s: channel No. "
3346 3349 "should be:\n"
3347 3350 "\t802.11a: 0-99\n"
3348 3351 "\t802.11b: 1-14\n"
3349 3352 "\t802.11g: 1-14\n"), gExecName);
3350 3353 exit(WIFI_FATAL_ERR);
3351 3354 }
3352 3355 phy_conf.wl_phy_dsss_conf.wl_dsss_channel = atoi(arg);
3353 3356 PRTDBG(("channel=%d\n", phy_conf.wl_phy_dsss_conf.wl_dsss_channel));
3354 3357
3355 3358 (void) memmove(gbuf->wldp_buf, &phy_conf, sizeof (wl_phy_conf_t));
3356 3359 return (call_ioctl(fd, WLAN_SET_PARAM, WL_PHY_CONFIG,
3357 3360 sizeof (wl_phy_conf_t)));
3358 3361 }
3359 3362 /*
3360 3363 * is_rates_support: Querying driver about supported rates.
3361 3364 */
3362 3365 static boolean_t
3363 3366 is_rates_support(int fd, int num, uint8_t *rates)
3364 3367 {
3365 3368 int rates_num = 0;
3366 3369 int i = 0, j = 0;
3367 3370 uint8_t value = 0;
3368 3371
3369 3372 assert((rates != NULL)&&(num != 0));
3370 3373 PRTDBG(("is_rates_support(%d, %d, 0x%x)\n", fd, num, rates));
3371 3374
3372 3375 if (call_ioctl(fd, WLAN_GET_PARAM, WL_SUPPORTED_RATES, 0)
3373 3376 == B_TRUE) {
3374 3377 rates_num = ((wl_rates_t *)(gbuf->wldp_buf))->wl_rates_num;
3375 3378
3376 3379 for (i = 0; i < num; i++) {
3377 3380 PRTDBG(("rates[%d] = %d\n", i, rates[i]));
3378 3381 for (j = 0; j < rates_num; j++) {
3379 3382 value = ((wl_rates_t *)gbuf->wldp_buf)
3380 3383 ->wl_rates_rates[j];
3381 3384 PRTDBG(("supported rates[%d]=%d\n", j, value));
3382 3385 if (value == rates[i]) {
3383 3386 break;
3384 3387 }
3385 3388 }
3386 3389 if (j == rates_num) {
3387 3390 if (rates[i] == 11) {
3388 3391 (void) fprintf(stderr,
3389 3392 gettext("%s: "
3390 3393 "rate 5.5M is not supported\n"),
3391 3394 gExecName);
3392 3395 } else {
3393 3396 (void) fprintf(stderr,
3394 3397 gettext("%s: "
3395 3398 "rate %dM is not supported\n"),
3396 3399 gExecName, rates[i]/2);
3397 3400 }
3398 3401 return (B_FALSE);
3399 3402 }
3400 3403 }
3401 3404 return (B_TRUE);
3402 3405 }
3403 3406 return (B_FALSE);
3404 3407 }
3405 3408
3406 3409 /*
3407 3410 *
3408 3411 */
3409 3412 static uint8_t
3410 3413 rates_convert(const char *rates)
3411 3414 {
3412 3415 int i;
3413 3416 uint8_t ret;
3414 3417
3415 3418 for (i = 0; i < WIFI_RATES_NUM; i++) {
3416 3419 if (strcmp(rates, wifi_rates_s[i].rates_s) == 0) {
3417 3420 ret = wifi_rates_s[i].rates_i;
3418 3421 break;
3419 3422 }
3420 3423 }
3421 3424 if (i == WIFI_RATES_NUM) {
3422 3425 (void) fprintf(stderr, gettext("%s: "
3423 3426 "invalid rates '%s'\n"), gExecName, rates);
3424 3427 exit(WIFI_FATAL_ERR);
3425 3428 }
3426 3429 return (ret);
3427 3430 }
3428 3431
3429 3432 /*
3430 3433 * get_rates: convert string value arg into uint8_t array,
3431 3434 * array length will be save into *len[i].
3432 3435 * for example:
3433 3436 * arg = "1,2,5.5,11"
3434 3437 * then after call, rates[] = {2,4,11,22} will be returned.
3435 3438 * and *len will equal to 4
3436 3439 */
3437 3440 static uint8_t *
3438 3441 get_rates(const char *arg, uint32_t *len)
3439 3442 {
3440 3443 int i = 1, j = 0;
3441 3444 uint8_t *rates = NULL;
3442 3445 char *pnext = NULL;
3443 3446 char *token;
3444 3447 char *pstart;
3445 3448 char *pstart_bak;
3446 3449
3447 3450 assert(arg != NULL);
3448 3451
3449 3452 if (strlen(arg) == 0) {
3450 3453 PRTDBG(("get_rates: empty rates string\n"));
3451 3454 return (NULL);
3452 3455 }
3453 3456 PRTDBG(("get_rates(\"%s\", 0x%x)\n", arg, len));
3454 3457 pstart = safe_strdup(arg);
3455 3458 pstart_bak = pstart;
3456 3459 while ((pnext = strchr(pstart, ',')) != NULL) {
3457 3460 pstart = pnext + 1;
3458 3461 i++;
3459 3462 }
3460 3463 *len = i;
3461 3464 rates = safe_calloc(sizeof (uint8_t), i);
3462 3465
3463 3466 pstart = pstart_bak;
3464 3467 if ((token = strtok(pstart, ",")) != NULL) {
3465 3468 PRTDBG(("rates[0]: %s\n", token));
3466 3469 rates[0] = rates_convert(token);
3467 3470 i = 1;
3468 3471 while ((token = strtok(NULL, ",")) != NULL) {
3469 3472 PRTDBG(("rates[%d]: %s\n", i, token));
3470 3473 rates[i++] = rates_convert(token);
3471 3474 }
3472 3475 }
3473 3476 free(pstart_bak);
3474 3477 for (i = 0; i < *len; i++) {
3475 3478 for (j = 0; j < i; j++)
3476 3479 if (rates[j] == rates[i]) {
3477 3480 (void) fprintf(stderr,
3478 3481 gettext("%s: rates duplicated\n"),
3479 3482 gExecName);
3480 3483 free(rates);
3481 3484 return (NULL);
3482 3485 }
3483 3486 }
3484 3487
3485 3488 return (rates);
3486 3489 }
3487 3490
3488 3491 static boolean_t
3489 3492 do_set_rates(int fd, const char *arg)
3490 3493 {
3491 3494 int i = 0;
3492 3495 uint32_t num = 0;
3493 3496 uint8_t *rates;
3494 3497
3495 3498 assert(arg != NULL);
3496 3499
3497 3500 PRTDBG(("do_set_rates(%d, \"%s\")\n", fd, arg));
3498 3501
3499 3502 rates = get_rates(arg, &num);
3500 3503 if ((rates == NULL) ||
3501 3504 is_rates_support(fd, num, rates) == B_FALSE) {
3502 3505 exit(WIFI_FATAL_ERR);
3503 3506 }
3504 3507
3505 3508 ((wl_rates_t *)(gbuf->wldp_buf))->wl_rates_num = num;
3506 3509 for (i = 0; i < num; i++) {
3507 3510 ((wl_rates_t *)gbuf->wldp_buf)->wl_rates_rates[i]
3508 3511 = rates[i];
3509 3512 }
3510 3513 free(rates);
3511 3514 return (call_ioctl(fd, WLAN_SET_PARAM, WL_DESIRED_RATES,
3512 3515 offsetof(wl_rates_t, wl_rates_rates) +
3513 3516 num*sizeof (char)));
3514 3517 }
3515 3518
3516 3519 static boolean_t
3517 3520 do_set_powermode(int fd, const char *arg)
3518 3521 {
3519 3522 wl_ps_mode_t ps_mode;
3520 3523
3521 3524 assert(arg != NULL);
3522 3525
3523 3526 PRTDBG(("do_set_powermode(%d, \"%s\")\n", fd, arg));
3524 3527
3525 3528 (void) memset(&ps_mode, 0xff, sizeof (ps_mode));
3526 3529
3527 3530 if ((strcasecmp(arg, "OFF") == 0) ||
3528 3531 (strcasecmp(arg, "MPS") == 0) ||
3529 3532 (strcasecmp(arg, "FAST") == 0)) {
3530 3533 switch (arg[0]) {
3531 3534 case 'O':
3532 3535 case 'o':
3533 3536 ps_mode.wl_ps_mode = WL_PM_AM;
3534 3537 break;
3535 3538 case 'M':
3536 3539 case 'm':
3537 3540 ps_mode.wl_ps_mode = WL_PM_MPS;
3538 3541 break;
3539 3542 case 'F':
3540 3543 case 'f':
3541 3544 ps_mode.wl_ps_mode = WL_PM_FAST;
3542 3545 break;
3543 3546 default:
3544 3547 break;
3545 3548 }
3546 3549 } else {
3547 3550 (void) fprintf(stderr,
3548 3551 gettext("%s: powermode: off mps or fast\n"), gExecName);
3549 3552 exit(WIFI_FATAL_ERR);
3550 3553 }
3551 3554
3552 3555 (void) memmove(gbuf->wldp_buf, &ps_mode, sizeof (wl_ps_mode_t));
3553 3556 return (call_ioctl(fd, WLAN_SET_PARAM, WL_POWER_MODE,
3554 3557 sizeof (wl_ps_mode_t)));
3555 3558 }
3556 3559
3557 3560 static boolean_t
3558 3561 do_set_authmode(int fd, const char *arg)
3559 3562 {
3560 3563 wl_authmode_t auth_mode;
3561 3564
3562 3565 assert(arg != NULL);
3563 3566 PRTDBG(("do_set_authmode(%d, \"%s\")\n", fd, arg));
3564 3567
3565 3568 (void) memset(&auth_mode, 0xff, sizeof (auth_mode));
3566 3569 /* Mark */
3567 3570 if (strcasecmp(arg, "OPENSYSTEM") == 0) {
3568 3571 auth_mode = WL_OPENSYSTEM;
3569 3572 } else if (strcasecmp(arg, "SHARED_KEY") == 0) {
3570 3573 auth_mode = WL_SHAREDKEY;
3571 3574 } else {
3572 3575 (void) fprintf(stderr,
3573 3576 gettext("%s: authmode: "
3574 3577 "opensystem or shared_key\n"), gExecName);
3575 3578 exit(WIFI_FATAL_ERR);
3576 3579 }
3577 3580
3578 3581 (void) memmove(gbuf->wldp_buf, &auth_mode, sizeof (wl_authmode_t));
3579 3582 return (call_ioctl(fd, WLAN_SET_PARAM, WL_AUTH_MODE,
3580 3583 sizeof (wl_authmode_t)));
3581 3584 }
3582 3585
3583 3586 static boolean_t
3584 3587 do_set_encryption(int fd, const char *arg)
3585 3588 {
3586 3589 wl_encryption_t encryption;
3587 3590
3588 3591 assert(arg != NULL);
3589 3592 PRTDBG(("do_set_encryption(%d, \"%s\")\n", fd, arg));
3590 3593
3591 3594 (void) memset(&encryption, 0xff, sizeof (encryption));
3592 3595
3593 3596 if (strcasecmp(arg, "NONE") == 0) {
3594 3597 encryption = WL_NOENCRYPTION;
3595 3598 } else if (strcasecmp(arg, "WEP") == 0) {
3596 3599 encryption = WL_ENC_WEP;
3597 3600 } else {
3598 3601 (void) fprintf(stderr, gettext("%s: encryption: "
3599 3602 "none or wep\n"), gExecName);
3600 3603 exit(WIFI_FATAL_ERR);
3601 3604 }
3602 3605
3603 3606 (void) memmove(gbuf->wldp_buf, &encryption, sizeof (wl_encryption_t));
3604 3607 return (call_ioctl(fd, WLAN_SET_PARAM, WL_ENCRYPTION,
3605 3608 sizeof (wl_encryption_t)));
3606 3609 }
3607 3610
3608 3611 static boolean_t
3609 3612 do_set_wepkeyid(int fd, const char *arg)
3610 3613 {
3611 3614 wl_wep_key_id_t wep_key_id;
3612 3615
3613 3616 assert(arg != NULL);
3614 3617 PRTDBG(("do_set_wepkeyid(%d, \"%s\")\n", fd, arg));
3615 3618
3616 3619 (void) memset(&wep_key_id, 0xff, sizeof (wep_key_id));
3617 3620 if (is_wepkeyindex_valid(arg) == B_FALSE) {
3618 3621 (void) fprintf(stderr, gettext("%s: wepkeyindex "
3619 3622 "should be an integer within the range 1-4\n"), gExecName);
3620 3623 exit(WIFI_FATAL_ERR);
3621 3624 }
3622 3625 wep_key_id = atoi(arg) - 1;
3623 3626
3624 3627 (void) memmove(gbuf->wldp_buf, &wep_key_id, sizeof (wl_wep_key_id_t));
3625 3628 return (call_ioctl(fd, WLAN_SET_PARAM, WL_WEP_KEY_ID,
3626 3629 sizeof (wl_wep_key_id_t)));
3627 3630 }
3628 3631
3629 3632 static boolean_t
3630 3633 do_set_radioon(int fd, const char *arg)
3631 3634 {
3632 3635 wl_radio_t radio;
3633 3636
3634 3637 assert(arg != NULL);
3635 3638 PRTDBG(("do_set_radioon(%d, \"%s\")\n", fd, arg));
3636 3639
3637 3640 (void) memset(&radio, 0xff, sizeof (radio));
3638 3641
3639 3642 if (strcasecmp(arg, "ON") == 0) {
3640 3643 radio = B_TRUE;
3641 3644 } else if (strcasecmp(arg, "OFF") == 0) {
3642 3645 radio = B_FALSE;
3643 3646 } else {
3644 3647 (void) fprintf(stderr,
3645 3648 gettext("%s: radio : on or off\n"), gExecName);
3646 3649 exit(WIFI_FATAL_ERR);
3647 3650 }
3648 3651
3649 3652 (void) memmove(gbuf->wldp_buf, &radio, sizeof (wl_radio_t));
3650 3653 return (call_ioctl(fd, WLAN_SET_PARAM, WL_RADIO, sizeof (wl_radio_t)));
3651 3654 }
3652 3655 /*
3653 3656 * print_gbuf: After each ioctl system call, gbuf will contain result, gbuf
3654 3657 * contents's format varies from each kind of ioctl system call.
3655 3658 */
3656 3659 static void
3657 3660 print_gbuf(config_item_t index)
3658 3661 {
3659 3662 int i = 0, j = 0;
3660 3663 uint32_t ess_num;
3661 3664 char **ess_argv;
3662 3665 uint32_t rates_num;
3663 3666 uint32_t subtype;
3664 3667 wl_bss_type_t bsstype;
3665 3668 wl_create_ibss_t createibss;
3666 3669 wl_ps_mode_t *ps_mode;
3667 3670 wl_authmode_t authmode;
3668 3671 wl_encryption_t encryption;
3669 3672 wl_wep_key_id_t wepkeyid;
3670 3673 wl_rssi_t signal;
3671 3674 wl_radio_t radioon;
3672 3675 wl_ess_conf_t **p_ess_conf;
3673 3676 wl_linkstatus_t linkstatus;
3674 3677 char format[256], *ntstr;
3675 3678 uint32_t maxessidlen = 0, nt = 0, cnt = 0;
3676 3679 int len;
3677 3680 uint8_t bssid[6];
3678 3681
3679 3682 PRTDBG(("print_gbuf(%d)\n", index));
3680 3683 assert(gbuf->wldp_length < MAX_BUF_LEN);
3681 3684
3682 3685 switch (index) {
3683 3686 case BSSID:
3684 3687 (void) printf("\tbssid: ");
3685 3688 (void) memset(bssid, 0, sizeof (bssid));
3686 3689 if (memcmp((uint8_t *)gbuf->wldp_buf, bssid, sizeof (bssid))
3687 3690 == 0) {
3688 3691 (void) printf("none\n");
3689 3692 break;
3690 3693 }
3691 3694 (void) memset(bssid, 0xff, sizeof (bssid));
3692 3695 if (memcmp((uint8_t *)gbuf->wldp_buf, bssid, sizeof (bssid))
3693 3696 == 0) {
3694 3697 (void) printf("none\n");
3695 3698 break;
3696 3699 }
3697 3700 for (i = 0; i < 5; i++)
3698 3701 (void) printf("%02x:", ((uint8_t *)gbuf->wldp_buf)[i]);
3699 3702 (void) printf("%02x\n", ((uint8_t *)gbuf->wldp_buf)[i]);
3700 3703 break;
3701 3704 case ESSID:
3702 3705 (void) printf("\tessid: %s\n", ((wl_essid_t *)(gbuf->wldp_buf))
3703 3706 ->wl_essid_essid);
3704 3707 break;
3705 3708 case BSSTYPE:
3706 3709 bsstype = *(wl_bss_type_t *)(gbuf->wldp_buf);
3707 3710 switch (bsstype) {
3708 3711 case WL_BSS_BSS:
3709 3712 (void) printf("\tbsstype: bss(ap, infrastructure)\n");
3710 3713 break;
3711 3714 case WL_BSS_IBSS:
3712 3715 (void) printf("\tbsstype: ibss(ad-hoc)\n");
3713 3716 break;
3714 3717 case WL_BSS_ANY:
3715 3718 (void) printf("\tbsstype: auto\n");
3716 3719 break;
3717 3720 default:
3718 3721 (void) fprintf(stderr,
3719 3722 gettext("%s: "
3720 3723 "invalid bsstype value\n"), gExecName);
3721 3724 }
3722 3725 break;
3723 3726 case CREATEIBSS:
3724 3727 createibss = *(wl_create_ibss_t *)(gbuf->wldp_buf);
3725 3728 switch (createibss) {
3726 3729 case B_TRUE:
3727 3730 (void) printf("\tcreateibss: yes\n");
3728 3731 break;
3729 3732 case B_FALSE:
3730 3733 (void) printf("\tcreateibss: no\n");
3731 3734 break;
3732 3735 default:
3733 3736 (void) fprintf(stderr,
3734 3737 gettext("%s: "
3735 3738 "invalid createibss value\n"), gExecName);
3736 3739 }
3737 3740 break;
3738 3741 case CHANNEL:
3739 3742 subtype = ((wl_fhss_t *)(gbuf->wldp_buf))->wl_fhss_subtype;
3740 3743 switch (subtype) {
3741 3744 case WL_FHSS:
3742 3745 case WL_DSSS:
3743 3746 case WL_IRBASE:
3744 3747 case WL_HRDS:
3745 3748 case WL_ERP:
3746 3749 (void) printf("\tchannel: %d\n", ((wl_fhss_t *)
3747 3750 (gbuf->wldp_buf))->wl_fhss_channel);
3748 3751 break;
3749 3752 case WL_OFDM:
3750 3753 (void) printf("\tchannel: %d\n", ((wl_ofdm_t *)
3751 3754 (gbuf->wldp_buf))
3752 3755 ->wl_ofdm_frequency);
3753 3756 break;
3754 3757 default:
3755 3758 (void) fprintf(stderr, gettext("%s: "
3756 3759 "invalid subtype\n"), gExecName);
3757 3760 break;
3758 3761 }
3759 3762 break;
3760 3763 case RATES:
3761 3764 rates_num = ((wl_rates_t *)(gbuf->wldp_buf))->wl_rates_num;
3762 3765 (void) printf("\trates: ");
3763 3766 for (i = 0; i < rates_num; i++) {
3764 3767 char rate;
3765 3768 rate = ((wl_rates_t *)gbuf->wldp_buf)
3766 3769 ->wl_rates_rates[i];
3767 3770 if (rate == WL_RATE_5_5M)
3768 3771 (void) printf("5.5");
3769 3772 else
3770 3773 (void) printf("%d", (uint8_t)(rate / 2));
3771 3774
3772 3775 if (i == (rates_num - 1))
3773 3776 (void) printf("\n");
3774 3777 else
3775 3778 (void) printf(",");
3776 3779 }
3777 3780 break;
3778 3781 case POWERMODE:
3779 3782 ps_mode = (wl_ps_mode_t *)(gbuf->wldp_buf);
3780 3783 switch (ps_mode->wl_ps_mode) {
3781 3784 case WL_PM_AM:
3782 3785 (void) printf("\tpowermode: off\n");
3783 3786 break;
3784 3787 case WL_PM_MPS:
3785 3788 (void) printf("\tpowermode: mps\n");
3786 3789 break;
3787 3790 case WL_PM_FAST:
3788 3791 (void) printf("\tpowermode: fast\n");
3789 3792 break;
3790 3793 default:
3791 3794 (void) fprintf(stderr,
3792 3795 gettext("%s: "
3793 3796 "invalid powermode value\n"), gExecName);
3794 3797 break;
3795 3798 }
3796 3799 break;
3797 3800 case AUTHMODE:
3798 3801 authmode = *(wl_authmode_t *)(gbuf->wldp_buf);
3799 3802 switch (authmode) {
3800 3803 case WL_OPENSYSTEM:
3801 3804 (void) printf("\tauthmode: opensystem\n");
3802 3805 break;
3803 3806 case WL_SHAREDKEY:
3804 3807 (void) printf("\tauthmode: shared_key\n");
3805 3808 break;
3806 3809 default:
3807 3810 (void) fprintf(stderr,
3808 3811 gettext("%s: "
3809 3812 "invalid authmode value\n"), gExecName);
3810 3813 break;
3811 3814 }
3812 3815 break;
3813 3816 case ENCRYPTION:
3814 3817 encryption = *(wl_encryption_t *)(gbuf->wldp_buf);
3815 3818 switch (encryption) {
3816 3819 case WL_NOENCRYPTION:
3817 3820 (void) printf("\tencryption: none\n");
3818 3821 break;
3819 3822 case WL_ENC_WEP:
3820 3823 (void) printf("\tencryption: wep\n");
3821 3824 break;
3822 3825 default:
3823 3826 (void) fprintf(stderr,
3824 3827 gettext("%s: "
3825 3828 "invalid encryption value\n"), gExecName);
3826 3829 break;
3827 3830 }
3828 3831 break;
3829 3832 case WEPKEYID:
3830 3833 wepkeyid = *(wl_wep_key_id_t *)(gbuf->wldp_buf);
3831 3834 (void) printf("\twepkeyindex: %d\n", wepkeyid + 1);
3832 3835 break;
3833 3836 case SIGNAL:
3834 3837 signal = *(wl_rssi_t *)(gbuf->wldp_buf);
3835 3838 (void) printf("\tsignal: %d\n", signal);
3836 3839 break;
3837 3840 case RADIOON:
3838 3841 radioon = *(wl_radio_t *)(gbuf->wldp_buf);
3839 3842 switch (radioon) {
3840 3843 case B_TRUE:
3841 3844 (void) printf("\tradio: on\n");
3842 3845 break;
3843 3846 case B_FALSE:
3844 3847 (void) printf("\tradio: off\n");
3845 3848 break;
3846 3849 default: /* Mark */
3847 3850 (void) fprintf(stderr,
3848 3851 gettext("%s: "
3849 3852 "invalid radioon value\n"), gExecName);
3850 3853 }
3851 3854 break;
3852 3855 case LINKSTATUS:
3853 3856 linkstatus = *(wl_linkstatus_t *)(gbuf->wldp_buf);
3854 3857 switch (linkstatus) {
3855 3858 case WL_CONNECTED:
3856 3859 (void) printf("\tlinkstatus: connected\n");
3857 3860 break;
3858 3861 case WL_NOTCONNECTED:
3859 3862 (void) printf("\tlinkstatus: not connected\n");
3860 3863 break;
3861 3864 default: /* Mark */
3862 3865 (void) fprintf(stderr,
3863 3866 gettext("%s: "
3864 3867 "invalid linkstatus value\n"), gExecName);
3865 3868 }
3866 3869 break;
3867 3870 case WLANLIST:
3868 3871 ess_num = ((wl_ess_list_t *)(gbuf->wldp_buf))->wl_ess_list_num;
3869 3872 ess_argv = safe_calloc(sizeof (char *), ess_num);
3870 3873 p_ess_conf = safe_calloc(sizeof (wl_ess_conf_t *), ess_num);
3871 3874 for (i = 0; i < ess_num; i++) {
3872 3875 p_ess_conf[i] = ((wl_ess_list_t *)gbuf->wldp_buf)
3873 3876 ->wl_ess_list_ess + i;
3874 3877 maxessidlen = (maxessidlen >
3875 3878 strlen(p_ess_conf[i]
3876 3879 ->wl_ess_conf_essid.wl_essid_essid) ?
3877 3880 maxessidlen :
3878 3881 strlen(p_ess_conf[i]
3879 3882 ->wl_ess_conf_essid.wl_essid_essid));
3880 3883 }
3881 3884 /*
3882 3885 * construct the output format.
3883 3886 */
3884 3887 if ((nt = (maxessidlen / 8 + 1)) > 4)
3885 3888 nt = 4;
3886 3889 len = snprintf(format, sizeof (format), gettext("essid"));
3887 3890 ntstr = construct_format(nt);
3888 3891 assert(ntstr != NULL);
3889 3892 len += snprintf(format + len, sizeof (format) - len, "%s",
3890 3893 ntstr);
3891 3894 len += snprintf(format + len, sizeof (format) - len,
3892 3895 gettext("bssid\t\t type\t\tencryption\tsignallevel\n"));
3893 3896
3894 3897 if ((len <= 0) || (len > sizeof (format) - 1)) {
3895 3898 (void) printf("essid\t\t\t\tbssid\t\t type\t\t"
3896 3899 "encryption\tsignallevel\n");
3897 3900 } else {
3898 3901 (void) printf("%s", format);
3899 3902 }
3900 3903
3901 3904 for (i = 0; i < ess_num; i++) {
3902 3905 ess_argv[i] = safe_malloc(MAX_SCANBUF_LEN);
3903 3906 safe_snprintf(ess_argv[i], MAX_SCANBUF_LEN,
3904 3907 "%s%c%02x:%02x:%02x:%02x:%02x:%02x%c%s",
3905 3908 p_ess_conf[i]->wl_ess_conf_essid.wl_essid_essid,
3906 3909 ',',
3907 3910 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[0]),
3908 3911 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[1]),
3909 3912 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[2]),
3910 3913 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[3]),
3911 3914 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[4]),
3912 3915 (uint8_t)(p_ess_conf[i]->wl_ess_conf_bssid[5]), ',',
3913 3916 (p_ess_conf[i]->wl_ess_conf_wepenabled ==
3914 3917 B_TRUE ? "wep":"none"));
3915 3918 len = strlen(p_ess_conf[i]->wl_ess_conf_essid.
3916 3919 wl_essid_essid);
3917 3920 cnt = nt - (min(len /8 + 1, 4) - 1);
3918 3921 ntstr = construct_format(cnt);
3919 3922 assert(ntstr != NULL);
3920 3923 (void) printf("%s%s", p_ess_conf[i]->wl_ess_conf_essid.
3921 3924 wl_essid_essid, ntstr);
3922 3925 free(ntstr);
3923 3926 for (j = 0; j < 5; j++) {
3924 3927 (void) printf("%02x:", (uint8_t)(p_ess_conf[i]
3925 3928 ->wl_ess_conf_bssid[j]));
3926 3929 }
3927 3930 (void) printf("%02x ", (uint8_t)(p_ess_conf[i]
3928 3931 ->wl_ess_conf_bssid[j]));
3929 3932
3930 3933 if (p_ess_conf[i]->wl_ess_conf_bsstype ==
3931 3934 WL_BSS_BSS)
3932 3935 (void) printf("access point");
3933 3936 else
3934 3937 (void) printf("ad-hoc");
3935 3938 if (p_ess_conf[i]->wl_ess_conf_wepenabled ==
3936 3939 WL_ENC_WEP)
3937 3940 (void) printf("\twep\t");
3938 3941 else
3939 3942 (void) printf("\tnone\t");
3940 3943 (void) printf("\t%d\n", p_ess_conf[i]->wl_ess_conf_sl);
3941 3944 }
3942 3945 add_to_history(gp_config_file, ess_num, ess_argv);
3943 3946 free(p_ess_conf);
3944 3947 for (i = 0; i < ess_num; i++) {
3945 3948 free(ess_argv[i]);
3946 3949 }
3947 3950 free(ess_argv);
3948 3951 break;
3949 3952 default:
3950 3953 (void) fprintf(stderr, gettext("%s: "
3951 3954 "invalid parameter type\n"), gExecName);
3952 3955 break;
3953 3956 }
3954 3957 }
3955 3958 /*
3956 3959 * do_get_xxx: will send ioctl to driver, then the driver will fill gbuf
3957 3960 * with related value. gbuf has a format of wldp_t structure.
3958 3961 */
3959 3962 static boolean_t
3960 3963 do_get_bssid(int fd)
3961 3964 {
3962 3965 PRTDBG(("do_get_bssid(%d)\n", fd));
3963 3966 return (call_ioctl(fd, WLAN_GET_PARAM, WL_BSSID, 0));
3964 3967 }
3965 3968
3966 3969 static boolean_t
3967 3970 do_get_essid(int fd)
3968 3971 {
3969 3972 PRTDBG(("do_get_essid(%d)\n", fd));
3970 3973 return (call_ioctl(fd, WLAN_GET_PARAM, WL_ESSID, 0));
3971 3974 }
3972 3975
3973 3976 static boolean_t
3974 3977 do_get_bsstype(int fd)
3975 3978 {
3976 3979 PRTDBG(("do_get_bsstype(%d)\n", fd));
3977 3980 return (call_ioctl(fd, WLAN_GET_PARAM, WL_BSS_TYPE, 0));
3978 3981 }
3979 3982
3980 3983 static boolean_t
3981 3984 do_get_createibss(int fd)
3982 3985 {
3983 3986 PRTDBG(("do_get_createibss(%d)\n", fd));
3984 3987 return (call_ioctl(fd, WLAN_GET_PARAM, WL_CREATE_IBSS, 0));
3985 3988 }
3986 3989
3987 3990 static boolean_t
3988 3991 do_get_channel(int fd)
3989 3992 {
3990 3993 PRTDBG(("do_get_channel(%d)\n", fd));
3991 3994 return (call_ioctl(fd, WLAN_GET_PARAM, WL_PHY_CONFIG, 0));
3992 3995 }
3993 3996
3994 3997 static boolean_t
3995 3998 do_get_wlanlist(int fd)
3996 3999 {
3997 4000 PRTDBG(("do_get_wlanlist(%d)\n", fd));
3998 4001 return (call_ioctl(fd, WLAN_GET_PARAM, WL_ESS_LIST, 0));
3999 4002 }
4000 4003
4001 4004 static boolean_t
4002 4005 do_get_linkstatus(int fd)
4003 4006 {
4004 4007 PRTDBG(("do_get_linkstauts(%d)\n", fd));
4005 4008 return (call_ioctl(fd, WLAN_GET_PARAM, WL_LINKSTATUS, 0));
4006 4009 }
4007 4010
4008 4011 static boolean_t
4009 4012 do_get_rates(int fd)
4010 4013 {
4011 4014 PRTDBG(("do_get_rates(%d)\n", fd));
4012 4015 return (call_ioctl(fd, WLAN_GET_PARAM, WL_DESIRED_RATES, 0));
4013 4016 }
4014 4017
4015 4018 static boolean_t
4016 4019 do_get_powermode(int fd)
4017 4020 {
4018 4021 PRTDBG(("do_get_powermode(%d)\n", fd));
4019 4022 return (call_ioctl(fd, WLAN_GET_PARAM, WL_POWER_MODE, 0));
4020 4023 }
4021 4024
4022 4025 static boolean_t
4023 4026 do_get_authmode(int fd)
4024 4027 {
4025 4028 PRTDBG(("do_get_authmode(%d)\n", fd));
4026 4029 return (call_ioctl(fd, WLAN_GET_PARAM, WL_AUTH_MODE, 0));
4027 4030 }
4028 4031
4029 4032 static boolean_t
4030 4033 do_get_encryption(int fd)
4031 4034 {
4032 4035 PRTDBG(("do_get_encryption(%d)\n", fd));
4033 4036 return (call_ioctl(fd, WLAN_GET_PARAM, WL_ENCRYPTION, 0));
4034 4037 }
4035 4038
4036 4039 static boolean_t
4037 4040 do_get_wepkeyid(int fd)
4038 4041 {
4039 4042 PRTDBG(("do_get_wepkeyid(%d)\n", fd));
4040 4043 return (call_ioctl(fd, WLAN_GET_PARAM, WL_WEP_KEY_ID, 0));
4041 4044 }
4042 4045 static boolean_t
4043 4046 do_get_signal(int fd)
4044 4047 {
4045 4048 PRTDBG(("do_get_signal(%d)\n", fd));
4046 4049 return (call_ioctl(fd, WLAN_GET_PARAM, WL_RSSI, 0));
4047 4050 }
4048 4051
4049 4052 static boolean_t
4050 4053 do_get_radioon(int fd)
4051 4054 {
4052 4055 PRTDBG(("do_get_radioon(%d)\n", fd));
4053 4056 return (call_ioctl(fd, WLAN_GET_PARAM, WL_RADIO, 0));
4054 4057 }
4055 4058
4056 4059 /*
4057 4060 * param has two kinds of forms:
4058 4061 * 'wepkeyn=*****' (when equalflag == B_TRUE),
4059 4062 * 'wepkeyn' (when equalflag == B_FALSE)
4060 4063 */
4061 4064 static boolean_t
4062 4065 param_is_wepkey(char *param, boolean_t equalflag)
4063 4066 {
4064 4067 if ((equalflag == B_FALSE) &&
4065 4068 (strcmp(param, "wepkey1") == 0) ||
4066 4069 (strcmp(param, "wepkey2") == 0) ||
4067 4070 (strcmp(param, "wepkey3") == 0) ||
4068 4071 (strcmp(param, "wepkey4") == 0))
4069 4072 return (B_TRUE);
4070 4073 else if ((equalflag == B_TRUE) &&
4071 4074 (strncmp(param, "wepkey1=", strlen("wepkey1="))) == 0 ||
4072 4075 (strncmp(param, "wepkey2=", strlen("wepkey2="))) == 0 ||
4073 4076 (strncmp(param, "wepkey3=", strlen("wepkey3="))) == 0 ||
4074 4077 (strncmp(param, "wepkey4=", strlen("wepkey4="))) == 0)
4075 4078 return (B_TRUE);
4076 4079 else
4077 4080 return (B_FALSE);
4078 4081 }
4079 4082
4080 4083 /*
4081 4084 * update/add items in the profile
4082 4085 */
4083 4086 static boolean_t
4084 4087 items_in_profile(aelist_t *cplist, aelist_t *wplist, int argc, char **argv)
4085 4088 {
4086 4089 int i = 0, j = 0;
4087 4090 char *param;
4088 4091 char *pequal;
4089 4092 const char *wepkey;
4090 4093
4091 4094 for (i = 0; i < argc; i++) {
4092 4095 if (param_is_wepkey(argv[i], B_TRUE) == B_TRUE) {
4093 4096 wepkey = get_value(argv[i]);
4094 4097 if (value_is_valid(WEPKEY, wepkey) == B_FALSE) {
4095 4098 (void) fprintf(stderr, gettext("%s: "
4096 4099 "invalid value '%s' for parameter "
4097 4100 "'wepkey'\n"), gExecName, wepkey);
4098 4101 return (B_FALSE);
4099 4102 }
4100 4103 update_aelist(wplist, argv[i]);
4101 4104 continue;
4102 4105 }
4103 4106 param = safe_strdup(argv[i]);
4104 4107 pequal = strchr(param, '=');
4105 4108 if (pequal == NULL) {
4106 4109 (void) fprintf(stderr, gettext("%s: "
4107 4110 "invalid argument '%s', use "
4108 4111 "parameter=value'\n"),
4109 4112 gExecName, argv[i]);
4110 4113 free(param);
4111 4114 return (B_FALSE);
4112 4115 }
4113 4116
4114 4117 *pequal++ = '\0';
4115 4118 for (j = 0; j < N_GS_FUNC; j++) {
4116 4119 if (strcmp(param, do_gs_func[j].cmd) == 0) {
4117 4120 break;
4118 4121 }
4119 4122 }
4120 4123 if (j == N_GS_FUNC) {
4121 4124 (void) fprintf(stderr, gettext("%s: "
4122 4125 "unrecognized parameter '%s'\n"),
4123 4126 gExecName, param);
4124 4127 free(param);
4125 4128 return (B_FALSE);
4126 4129 }
4127 4130 if (value_is_valid(do_gs_func[j].index, pequal) ==
4128 4131 B_FALSE) {
4129 4132 (void) fprintf(stderr, gettext("%s: "
4130 4133 "invalid value '%s' for parameter '%s'\n"),
4131 4134 gExecName, pequal, param);
4132 4135 return (B_FALSE);
4133 4136 }
4134 4137 free(param);
4135 4138 update_aelist(cplist, argv[i]);
4136 4139 }
4137 4140 return (B_TRUE);
4138 4141 }
4139 4142
4140 4143 /*
4141 4144 * do_createprofile: Called when create a profile off-line.
4142 4145 */
4143 4146 /*ARGSUSED*/
4144 4147 static boolean_t
4145 4148 do_createprofile(int fd, int argc, char **argv)
4146 4149 {
4147 4150 int i = 0;
4148 4151 char *pbuf = NULL;
4149 4152 char *pfbuf = NULL;
4150 4153 const char *profilename;
4151 4154 aelist_t *plist_config = NULL, *plist_wepkey = NULL;
4152 4155
4153 4156 PRTDBG(("do_createprofile(%d, 0x%x)\n", argc, argv));
4154 4157 if (argc <= 0) {
4155 4158 do_print_usage();
4156 4159 exit(WIFI_IMPROPER_USE);
4157 4160 }
4158 4161 /*
4159 4162 * When creating a profile, if the profile name is not specified,
4160 4163 * the essid is selected as the profile name. the paramters are
4161 4164 * saved into the section.
4162 4165 */
4163 4166 if (strchr(argv[0], '=') == NULL) {
4164 4167 pfbuf = safe_strdup(argv[0]);
4165 4168 argc--;
4166 4169 argv++;
4167 4170 }
4168 4171 for (i = 0; i < argc; i++) {
4169 4172 if (strncmp(argv[i], "essid=", strlen("essid=")) == 0) {
4170 4173 break;
4171 4174 }
4172 4175 }
4173 4176 if (i == argc) {
4174 4177 (void) fprintf(stderr,
4175 4178 gettext("%s: "
4176 4179 "essid required when creating profile\n"),
4177 4180 gExecName);
4178 4181 goto exit0;
4179 4182 }
4180 4183 profilename = (pfbuf ? pfbuf : get_value(argv[i]));
4181 4184 if (strlen(profilename) == 0) {
4182 4185 (void) fprintf(stderr,
4183 4186 gettext("%s: "
4184 4187 "non-empty essid required\n"),
4185 4188 gExecName);
4186 4189 goto exit0;
4187 4190 }
4188 4191 /*
4189 4192 * 'all', '{preference}', '{history}', '{active_profile}'
4190 4193 * and any string with '[' as start and ']' as end should
4191 4194 * not be a profile name
4192 4195 */
4193 4196 if ((strcasecmp(profilename, "all") == 0) ||
4194 4197 (strcmp(profilename, WIFI_HISTORY) == 0) ||
4195 4198 (strcmp(profilename, WIFI_PREFER) == 0) ||
4196 4199 (strcmp(profilename, WIFI_ACTIVEP) == 0) ||
4197 4200 ((profilename[0] == '[') &&
4198 4201 (profilename[strlen(profilename) - 1] == ']'))) {
4199 4202 (void) fprintf(stderr, gettext("%s: "
4200 4203 "'%s' is an invalid profile name\n"),
4201 4204 gExecName, profilename);
4202 4205 goto exit0;
4203 4206 }
4204 4207 pbuf = append_pa(profilename);
4205 4208
4206 4209 PRTDBG(("do_createprofile: profile_name = %s\n", pbuf));
4207 4210 if ((find_section(gp_config_file, pbuf) != NULL) ||
4208 4211 find_section(gp_wepkey_file, pbuf) != NULL) {
4209 4212 (void) fprintf(stderr,
4210 4213 gettext("%s: "
4211 4214 "profile '%s' already exists\n"),
4212 4215 gExecName, profilename);
4213 4216 goto exit1;
4214 4217 }
4215 4218 /*
4216 4219 * Save each parameters in the profile.
4217 4220 */
4218 4221 plist_config = new_ael(PROFILE);
4219 4222 new_section(gp_config_file, plist_config, pbuf);
4220 4223 plist_wepkey = new_ael(PROFILE);
4221 4224 new_section(gp_wepkey_file, plist_wepkey, pbuf);
4222 4225 free(pfbuf);
4223 4226 free(pbuf);
4224 4227 return (items_in_profile(plist_config, plist_wepkey,
4225 4228 argc, argv));
4226 4229 exit1:
4227 4230 free(pbuf);
4228 4231 exit0:
4229 4232 free(pfbuf);
4230 4233 return (B_FALSE);
4231 4234 }
4232 4235
4233 4236 /*ARGSUSED*/
4234 4237 static boolean_t
4235 4238 do_setprofparam(int fd, int argc, char **argv)
4236 4239 {
4237 4240 char *pbuf = NULL;
4238 4241 section_t *psection_config = NULL, *psection_wep = NULL;
4239 4242 aelist_t *plist_config = NULL, *plist_wepkey = NULL;
4240 4243
4241 4244 PRTDBG(("do_setprofparam(%d, 0x%x)\n", argc, argv));
4242 4245 if (argc < 1) {
4243 4246 do_print_usage();
4244 4247 exit(WIFI_IMPROPER_USE);
4245 4248 }
4246 4249 pbuf = append_pa(argv[0]);
4247 4250
4248 4251 psection_config = find_section(gp_config_file, pbuf);
4249 4252 psection_wep = find_section(gp_wepkey_file, pbuf);
4250 4253 if ((psection_config == NULL) || (psection_wep == NULL)) {
4251 4254 (void) fprintf(stderr, gettext("%s: "
4252 4255 "profile '%s' doesn't exist\n"),
4253 4256 gExecName, argv[0]);
4254 4257 free(pbuf);
4255 4258 return (B_FALSE);
4256 4259 }
4257 4260 free(pbuf);
4258 4261 /*
4259 4262 * modify each parameters in the profile.
4260 4263 */
4261 4264 plist_config = psection_config->list;
4262 4265 plist_wepkey = psection_wep->list;
4263 4266 argc--;
4264 4267 argv++;
4265 4268 return (items_in_profile(plist_config, plist_wepkey,
4266 4269 argc, argv));
4267 4270 }
4268 4271
4269 4272 /*ARGSUSED*/
4270 4273 static boolean_t
4271 4274 do_getprofparam(int fd, int argc, char **argv)
4272 4275 {
4273 4276 int i = 0, j = 0;
4274 4277 int flag;
4275 4278 boolean_t ret = B_TRUE;
4276 4279 section_t *p_section = NULL;
4277 4280 aelist_t *plist = NULL;
4278 4281 ae_t *pae = NULL;
4279 4282 char *pbuf = NULL;
4280 4283
4281 4284 PRTDBG(("do_getprofparam(%d, 0x%x)\n", argc, argv));
4282 4285 if (argc < 1) {
4283 4286 do_print_usage();
4284 4287 exit(WIFI_IMPROPER_USE);
4285 4288 }
4286 4289 pbuf = append_pa(argv[0]);
4287 4290 p_section = find_section(gp_config_file, pbuf);
4288 4291 if (p_section == NULL) {
4289 4292 (void) fprintf(stderr, gettext("%s: "
4290 4293 "profile '%s' doesn't exist\n"),
4291 4294 gExecName, argv[0]);
4292 4295 ret = B_FALSE;
4293 4296 goto exit0;
4294 4297 }
4295 4298 argc--;
4296 4299 argv++;
4297 4300
4298 4301 plist = p_section->list;
4299 4302 assert(plist != NULL);
4300 4303 /*
4301 4304 * If no specific parameter typed, we print out all parameters
4302 4305 */
4303 4306 if (argc == 0) {
4304 4307 pae = plist->ael_head;
4305 4308 while (pae != NULL) {
4306 4309 if (pae->ae_arg != NULL) {
4307 4310 (void) printf("\t%s\n", pae->ae_arg);
4308 4311 }
4309 4312 pae = pae->ae_next;
4310 4313 }
4311 4314 print_wepkey_info(p_section->section_id, NULL);
4312 4315 ret = B_TRUE;
4313 4316 goto exit0;
4314 4317 }
4315 4318
4316 4319 /*
4317 4320 * Match function with do_gs_func[] table, and print its result
4318 4321 */
4319 4322 for (i = 0; i < argc; i++) {
4320 4323 flag = 0;
4321 4324 for (j = 0; j < N_GS_FUNC; j++) {
4322 4325 if (strcmp(argv[i], do_gs_func[j].cmd) == 0) {
4323 4326 break;
4324 4327 }
4325 4328 if (param_is_wepkey(argv[i], B_FALSE) == B_TRUE) {
4326 4329 j = WEPKEY;
4327 4330 print_wepkey_info(p_section->section_id,
4328 4331 argv[i]);
4329 4332 flag++;
4330 4333 break;
4331 4334 }
4332 4335 }
4333 4336 if (j == N_GS_FUNC) {
4334 4337 (void) fprintf(stderr,
4335 4338 gettext("wificonifg: unrecognized parameter: "
4336 4339 "%s\n"), argv[i]);
4337 4340 ret = B_FALSE;
4338 4341 goto exit0;
4339 4342 }
4340 4343
4341 4344 pae = plist->ael_head;
4342 4345 while ((pae != NULL) && (!flag)) {
4343 4346 if ((pae->ae_arg != NULL) &&
4344 4347 (strncmp(pae->ae_arg, argv[i],
4345 4348 strlen(argv[i])) == 0)) {
4346 4349 (void) printf("\t%s\n", pae->ae_arg);
4347 4350 flag++;
4348 4351 }
4349 4352 pae = pae->ae_next;
4350 4353 }
4351 4354 if (!flag) {
4352 4355 (void) fprintf(stderr, gettext("%s: "
4353 4356 "parameter '%s' has not been set in profile %s\n"),
4354 4357 gExecName, argv[i], pbuf);
4355 4358 ret = B_FALSE;
4356 4359 goto exit0;
4357 4360 }
4358 4361 }
4359 4362 exit0:
4360 4363 free(pbuf);
4361 4364 return (ret);
4362 4365 }
4363 4366
4364 4367 /*
4365 4368 * Verify whether the value in the parameter=value pair is valid or not.
4366 4369 * For the channel, since we donot know what kind of wifi card(a,b,or g)
4367 4370 * is in the system, so we just leave to verify the validity of the value
4368 4371 * when the value is set to the card.
4369 4372 * The same goes for the rates.
4370 4373 */
4371 4374 static boolean_t
4372 4375 value_is_valid(config_item_t item, const char *value)
4373 4376 {
4374 4377 uint32_t num = 0;
4375 4378 uint8_t *rates;
4376 4379 boolean_t ret;
4377 4380
4378 4381 assert(value != NULL);
4379 4382 switch (item) {
4380 4383 case ESSID:
4381 4384 if (strlen(value) > 32)
4382 4385 ret = B_FALSE;
4383 4386 else
4384 4387 ret = B_TRUE;
4385 4388 break;
4386 4389 case BSSTYPE:
4387 4390 if ((strcasecmp(value, "bss") == 0) ||
4388 4391 (strcasecmp(value, "ap") == 0) ||
4389 4392 (strcasecmp(value, "infrastructure") == 0) ||
4390 4393 (strcasecmp(value, "ibss") == 0) ||
4391 4394 (strcasecmp(value, "ad-hoc") == 0) ||
4392 4395 (strcasecmp(value, "auto") == 0))
4393 4396 ret = B_TRUE;
4394 4397 else
4395 4398 ret = B_FALSE;
4396 4399 break;
4397 4400 case CREATEIBSS:
4398 4401 if ((strcasecmp(value, "yes") == 0) ||
4399 4402 (strcasecmp(value, "no") == 0))
4400 4403 ret = B_TRUE;
4401 4404 else
4402 4405 ret = B_FALSE;
4403 4406 break;
4404 4407 case AUTHMODE:
4405 4408 if ((strcasecmp(value, "opensystem") == 0) ||
4406 4409 (strcasecmp(value, "shared_key") == 0))
4407 4410 ret = B_TRUE;
4408 4411 else
4409 4412 ret = B_FALSE;
4410 4413 break;
4411 4414 case POWERMODE:
4412 4415 if ((strcasecmp(value, "off") == 0) ||
4413 4416 (strcasecmp(value, "mps") == 0) ||
4414 4417 (strcasecmp(value, "fast") == 0))
4415 4418 ret = B_TRUE;
4416 4419 else
4417 4420 ret = B_FALSE;
4418 4421 break;
4419 4422 case ENCRYPTION:
4420 4423 if ((strcasecmp(value, "wep") == 0) ||
4421 4424 (strcasecmp(value, "none") == 0))
4422 4425 ret = B_TRUE;
4423 4426 else
4424 4427 ret = B_FALSE;
4425 4428 break;
4426 4429 case RADIOON:
4427 4430 if ((strcasecmp(value, "on") == 0) ||
4428 4431 (strcasecmp(value, "off") == 0))
4429 4432 ret = B_TRUE;
4430 4433 else
4431 4434 ret = B_FALSE;
4432 4435 break;
4433 4436 case WEPKEYID:
4434 4437 ret = is_wepkeyindex_valid(value);
4435 4438 break;
4436 4439 case WEPKEY:
4437 4440 ret = is_wepkey_valid(value, strlen(value));
4438 4441 break;
4439 4442 case CHANNEL:
4440 4443 ret = is_channel_valid(value);
4441 4444 break;
4442 4445 case RATES:
4443 4446 rates = get_rates(value, &num);
4444 4447 if (rates == NULL) {
4445 4448 ret = B_FALSE;
4446 4449 } else {
4447 4450 free(rates);
4448 4451 ret = B_TRUE;
4449 4452 }
4450 4453 break;
4451 4454 default:
4452 4455 ret = B_FALSE;
4453 4456 break;
4454 4457 }
4455 4458
4456 4459 return (ret);
4457 4460 }
4458 4461
4459 4462 /*
4460 4463 * do_set: Called when set a parameter, the format should be
4461 4464 * parameter=value.
4462 4465 */
4463 4466 static boolean_t
4464 4467 do_set(int fd, int argc, char **argv)
4465 4468 {
4466 4469 int i = 0, j = 0;
4467 4470 char *param;
4468 4471 char *pequal;
4469 4472 char *value;
4470 4473 boolean_t ret;
4471 4474
4472 4475 PRTDBG(("do_set(%d, 0x%x)\n", argc, argv));
4473 4476 assert(fd > 0);
4474 4477 if (argc <= 0) {
4475 4478 (void) do_print_support_params(fd);
4476 4479 ret = B_FALSE;
4477 4480 goto exit0;
4478 4481 }
4479 4482 /*
4480 4483 * Set each parameters, if one failed, others behind it will
4481 4484 * not be set
4482 4485 */
4483 4486 for (i = 0; i < argc; i++) {
4484 4487 /*
4485 4488 * Separate param and its value, if the user types "param=",
4486 4489 * then value will be set to "";if the user types "param",
4487 4490 * it is an error.
4488 4491 */
4489 4492 param = safe_strdup(argv[i]);
4490 4493 pequal = strchr(param, '=');
4491 4494 value = NULL;
4492 4495 if (pequal != NULL) {
4493 4496 *pequal = '\0';
4494 4497 value = pequal + 1;
4495 4498 } else {
4496 4499 (void) fprintf(stderr,
4497 4500 gettext("%s: invalid setparam argument "
4498 4501 "'%s', use 'parameter=value'\n"),
4499 4502 gExecName, argv[i]);
4500 4503 free(param);
4501 4504 ret = B_FALSE;
4502 4505 goto exit0;
4503 4506 }
4504 4507 PRTDBG(("do_set: param = \"%s\", value = \"%s\"\n",
4505 4508 param, value));
4506 4509 for (j = 0; j < N_GS_FUNC; j++) {
4507 4510 /*
4508 4511 * Match each parameters with do_gs_func table,
4509 4512 */
4510 4513 if (strcmp(param, do_gs_func[j].cmd) == 0)
4511 4514 break;
4512 4515 if (param_is_wepkey(param, B_FALSE) == B_TRUE) {
4513 4516 value = argv[i];
4514 4517 j = WEPKEY;
4515 4518 break;
4516 4519 }
4517 4520 }
4518 4521 if (j == N_GS_FUNC) {
4519 4522 (void) fprintf(stderr,
4520 4523 gettext("%s: unrecognized parameter: "
4521 4524 "%s\n"), gExecName, param);
4522 4525 free(param);
4523 4526 ret = B_FALSE;
4524 4527 goto exit0;
4525 4528 }
4526 4529
4527 4530 if (do_gs_func[j].p_do_set_func == NULL) {
4528 4531 (void) fprintf(stderr,
4529 4532 gettext("%s: parameter '%s' is read-only\n"),
4530 4533 gExecName, do_gs_func[j].cmd);
4531 4534 free(param);
4532 4535 ret = B_FALSE;
4533 4536 goto exit0;
4534 4537 }
4535 4538 if (do_gs_func[j].p_do_set_func(fd, value)
4536 4539 == B_TRUE) {
4537 4540 ret = B_TRUE;
4538 4541 } else {
4539 4542 if (gbuf->wldp_result != WL_SUCCESS) {
4540 4543 (void) fprintf(stderr,
4541 4544 gettext("%s: "
4542 4545 "failed to set '%s' for "),
4543 4546 gExecName, param);
4544 4547 print_error(gbuf->wldp_result);
4545 4548 }
4546 4549 free(param);
4547 4550 ret = B_FALSE;
4548 4551 goto exit0;
4549 4552 }
4550 4553 free(param);
4551 4554 }
4552 4555 exit0:
4553 4556 return (ret);
4554 4557 }
4555 4558
4556 4559 static boolean_t
4557 4560 do_get(int fd, int argc, char **argv)
4558 4561 {
4559 4562 int i = 0, j = 0, n = 0;
4560 4563 boolean_t ret = B_TRUE;
4561 4564
4562 4565 PRTDBG(("do_get(%d, 0x%x)\n", argc, argv));
4563 4566 assert(fd > 0);
4564 4567 /*
4565 4568 * If no specific parameter typed, we print out all parameters
4566 4569 */
4567 4570 if (argc <= 0) {
4568 4571 for (i = 0; i < N_GS_FUNC; i++) {
4569 4572 if ((do_gs_func[i].p_do_get_func != NULL) &&
4570 4573 (do_gs_func[i].p_do_get_func(fd)
4571 4574 == B_TRUE)) {
4572 4575 print_gbuf(do_gs_func[i].index);
4573 4576 n++;
4574 4577 }
4575 4578 }
4576 4579 ret = n ? B_TRUE:B_FALSE;
4577 4580 goto exit0;
4578 4581 }
4579 4582 /*
4580 4583 * Match function with do_gs_func[] table, and print its result
4581 4584 */
4582 4585 for (i = 0; i < argc; i++) {
4583 4586 for (j = 0; j < N_GS_FUNC; j++) {
4584 4587 if (strcmp(argv[i], do_gs_func[j].cmd) == 0) {
4585 4588 break;
4586 4589 }
4587 4590 if (param_is_wepkey(argv[i], B_FALSE) == B_TRUE) {
4588 4591 j = WEPKEY;
4589 4592 break;
4590 4593 }
4591 4594 }
4592 4595 if (j == N_GS_FUNC) {
4593 4596 (void) fprintf(stderr,
4594 4597 gettext("wificonifg: unrecognized parameter: "
4595 4598 "%s\n"), argv[i]);
4596 4599 ret = B_FALSE;
4597 4600 goto exit0;
4598 4601 }
4599 4602 if (do_gs_func[j].p_do_get_func == NULL) {
4600 4603 (void) fprintf(stderr,
4601 4604 gettext("%s: parameter '%s' is write-only\n"),
4602 4605 gExecName, do_gs_func[j].cmd);
4603 4606 ret = B_FALSE;
4604 4607 goto exit0;
4605 4608 }
4606 4609 if (do_gs_func[j].p_do_get_func(fd) == B_TRUE) {
4607 4610 print_gbuf(do_gs_func[j].index);
4608 4611 ret = B_TRUE;
4609 4612 } else {
4610 4613 (void) fprintf(stderr,
4611 4614 gettext("%s: "
4612 4615 "failed to read parameter '%s' : "),
4613 4616 gExecName, argv[i]);
4614 4617 print_error(gbuf->wldp_result);
4615 4618 ret = B_FALSE;
4616 4619 }
4617 4620 }
4618 4621 exit0:
4619 4622 return (ret);
4620 4623 }
4621 4624
4622 4625 /*
4623 4626 * Only one wificonfig is running at one time.
4624 4627 * The following wificonfig which tries to be run will return error,
4625 4628 * and the pid of the process will own the filelock will be printed out.
4626 4629 */
4627 4630 static pid_t
4628 4631 enter_wifi_lock(int *fd)
4629 4632 {
4630 4633 int fd0 = -1;
4631 4634 struct flock lock;
4632 4635
4633 4636 fd0 = open(WIFI_LOCKF, O_CREAT|O_WRONLY, 0600);
4634 4637 if (fd0 < 0) {
4635 4638 (void) fprintf(stderr, gettext("%s: failed to open lockfile"
4636 4639 " '"WIFI_LOCKF"': %s\n"), gExecName, strerror(errno));
4637 4640 exit(WIFI_FATAL_ERR);
4638 4641 }
4639 4642
4640 4643 *fd = fd0;
4641 4644 lock.l_type = F_WRLCK;
4642 4645 lock.l_whence = SEEK_SET;
4643 4646 lock.l_start = 0;
4644 4647 lock.l_len = 0;
4645 4648
4646 4649 if ((fcntl(fd0, F_SETLK, &lock) == -1) &&
4647 4650 (errno == EAGAIN || errno == EDEADLK)) {
4648 4651 if (fcntl(fd0, F_GETLK, &lock) == -1) {
4649 4652 (void) fprintf(stderr,
4650 4653 gettext("%s: enter_filelock"));
4651 4654 exit(WIFI_FATAL_ERR);
4652 4655 }
4653 4656 (void) fprintf(stderr, gettext("%s:"
4654 4657 "enter_filelock:filelock is owned "
4655 4658 "by 'process %d'\n"), gExecName, lock.l_pid);
4656 4659 return (lock.l_pid);
4657 4660 }
4658 4661
4659 4662 return (getpid());
4660 4663 }
4661 4664
4662 4665 static void
4663 4666 exit_wifi_lock(int fd)
4664 4667 {
4665 4668 struct flock lock;
4666 4669
4667 4670 lock.l_type = F_UNLCK;
4668 4671 lock.l_whence = SEEK_SET;
4669 4672 lock.l_start = 0;
4670 4673 lock.l_len = 0;
4671 4674 if (fcntl(fd, F_SETLK, &lock) == -1) {
4672 4675 (void) fprintf(stderr, gettext("%s: failed to"
4673 4676 " exit_filelock: %s\n"),
4674 4677 gExecName, strerror(errno));
4675 4678 }
4676 4679 (void) close(fd);
4677 4680 }
4678 4681
4679 4682 int
4680 4683 main(int argc, char **argv)
4681 4684 {
4682 4685 int i, ret;
4683 4686 int fddev = -1;
4684 4687 int c, iflag = 0, rflag = 0, fileonly = 0, readonly = 0;
4685 4688 int fd;
4686 4689 char *iname = NULL;
4687 4690 char *path = NULL;
4688 4691 extern char *optarg;
4689 4692 extern int optind;
4690 4693 char interface[LIFNAMSIZ];
4691 4694 char file_wifi[MAX_CONFIG_FILE_LENGTH];
4692 4695 char file_wifiwepkey[MAX_CONFIG_FILE_LENGTH];
4693 4696 priv_set_t *ppriv;
4694 4697 wifi_auth_t autht;
4695 4698
4696 4699 PRTDBG(("main(%d, 0x%x)\n", argc, argv));
4697 4700 PRTDBG(("uid=%d\n", getuid()));
4698 4701 PRTDBG(("euid=%d\n", geteuid()));
4699 4702
4700 4703 #ifdef DEBUG
4701 4704 if (wifi_debug == 1) { /* for debuf purpose only */
4702 4705 (void) printf("Press RETURN to continue...\n");
4703 4706 (void) getchar();
4704 4707 }
4705 4708 #endif
4706 4709 ret = WIFI_EXIT_DEF;
4707 4710
4708 4711 (void) setlocale(LC_ALL, "");
4709 4712 (void) textdomain(TEXT_DOMAIN);
4710 4713
4711 4714 gExecName = argv[0];
4712 4715
4713 4716 gbuf = safe_malloc(MAX_BUF_LEN);
4714 4717
4715 4718 if ((ppriv = priv_str_to_set("basic", ",", NULL)) == NULL) {
4716 4719 PRTDBG(("main: priviledge init error\n"));
4717 4720 (void) fprintf(stderr, gettext("%s: "
4718 4721 "set priviledge to 'basic' error\n"),
4719 4722 gExecName);
4720 4723 ret = WIFI_FATAL_ERR;
4721 4724 goto exit0;
4722 4725 }
4723 4726 (void) priv_addset(ppriv, PRIV_NET_RAWACCESS);
4724 4727 (void) priv_addset(ppriv, PRIV_SYS_NET_CONFIG);
4725 4728 if (setppriv(PRIV_SET, PRIV_PERMITTED, ppriv) == -1) {
4726 4729 (void) fprintf(stderr, gettext("%s: "
4727 4730 "set permitted priviledge: %s\n"),
4728 4731 gExecName, strerror(errno));
4729 4732 ret = WIFI_FATAL_ERR;
4730 4733 goto exit0;
4731 4734 }
4732 4735 if (setppriv(PRIV_SET, PRIV_LIMIT, ppriv) == -1) {
4733 4736 (void) fprintf(stderr, gettext("%s: "
4734 4737 "set limit priviledge: %s\n"),
4735 4738 gExecName, strerror(errno));
4736 4739 ret = WIFI_FATAL_ERR;
4737 4740 goto exit0;
4738 4741 }
4739 4742 if (setppriv(PRIV_SET, PRIV_INHERITABLE, ppriv) == -1) {
4740 4743 (void) fprintf(stderr, gettext("%s: "
4741 4744 "set inherit priviledge: %s\n"),
4742 4745 gExecName, strerror(errno));
4743 4746 ret = WIFI_FATAL_ERR;
4744 4747 goto exit0;
4745 4748 }
4746 4749 if (setppriv(PRIV_SET, PRIV_EFFECTIVE, ppriv) == -1) {
4747 4750 (void) fprintf(stderr, gettext("%s: "
4748 4751 "set effective priviledge: %s\n"),
4749 4752 gExecName, strerror(errno));
4750 4753 ret = WIFI_FATAL_ERR;
4751 4754 goto exit0;
4752 4755 }
4753 4756 priv_freeset(ppriv);
4754 4757
4755 4758 for (i = 0; i < argc; i++) {
4756 4759 PRTDBG(("%d\t\t\"%s\"\n", i, argv[i]));
4757 4760 }
4758 4761
4759 4762 while ((c = getopt(argc, argv, "i:R:")) != EOF) {
4760 4763 switch (c) {
4761 4764 case 'i':
4762 4765 if (iflag) {
4763 4766 do_print_usage();
4764 4767 ret = WIFI_IMPROPER_USE;
4765 4768 goto exit0;
4766 4769 }
4767 4770 iflag = 1;
4768 4771 iname = optarg;
4769 4772 break;
4770 4773 case 'R':
4771 4774 if (rflag) {
4772 4775 do_print_usage();
4773 4776 ret = WIFI_IMPROPER_USE;
4774 4777 goto exit0;
4775 4778 }
4776 4779 rflag = 1;
4777 4780 path = optarg;
4778 4781 break;
4779 4782 case '?':
4780 4783 default:
4781 4784 do_print_usage();
4782 4785 ret = WIFI_IMPROPER_USE;
4783 4786 goto exit0;
4784 4787 }
4785 4788 }
4786 4789 argc -= optind;
4787 4790 argv += optind;
4788 4791
4789 4792 if (argc <= 0) {
4790 4793 if (iname) {
4791 4794 if ((fddev = open_dev(iname)) == -1) {
4792 4795 ret = WIFI_FATAL_ERR;
4793 4796 goto exit0;
4794 4797 }
4795 4798 if (do_print_support_params(fddev) ==
4796 4799 B_TRUE)
4797 4800 ret = WIFI_EXIT_DEF;
4798 4801 else
4799 4802 ret = WIFI_FATAL_ERR;
4800 4803 goto exit1;
4801 4804 } else {
4802 4805 do_print_usage();
4803 4806 ret = WIFI_IMPROPER_USE;
4804 4807 goto exit0;
4805 4808 }
4806 4809 }
4807 4810
4808 4811 for (i = 0; i < N_FUNC; i++) {
4809 4812 if (strcmp(argv[0], do_func[i].cmd) == 0) {
4810 4813 autht = ((strcmp(argv[0], "setwepkey") == 0) ||
4811 4814 (strcmp(argv[0], "setprofwepkey") == 0)) ?
4812 4815 AUTH_WEP:AUTH_OTHER;
4813 4816 if (do_func[i].b_auth &&
4814 4817 !check_authority(autht)) {
4815 4818 ret = WIFI_FATAL_ERR;
4816 4819 goto exit0;
4817 4820 }
4818 4821 if (do_func[i].b_fileonly)
4819 4822 fileonly++;
4820 4823 if (do_func[i].b_readonly)
4821 4824 readonly++;
4822 4825 break;
4823 4826 }
4824 4827 }
4825 4828 if (i == N_FUNC) {
4826 4829 (void) fprintf(stderr, gettext("%s: unrecognized "
4827 4830 "subcommand: %s\n"), gExecName, argv[0]);
4828 4831 do_print_usage();
4829 4832 ret = WIFI_IMPROPER_USE;
4830 4833 goto exit0;
4831 4834 }
4832 4835 if ((fileonly) && (iname)) {
4833 4836 do_print_usage();
4834 4837 ret = WIFI_IMPROPER_USE;
4835 4838 goto exit0;
4836 4839 }
4837 4840 if ((!fileonly) && (!iname)) {
4838 4841 if (search_interface(interface) != B_TRUE) {
4839 4842 (void) fprintf(stderr, gettext("%s: "
4840 4843 "failed to find the default wifi interface;"
4841 4844 " -i option should be used to specify the "
4842 4845 "wifi interface\n"), gExecName);
4843 4846 ret = WIFI_FATAL_ERR;
4844 4847 goto exit0;
4845 4848 }
4846 4849 iname = interface;
4847 4850 }
4848 4851 if (iname) {
4849 4852 if ((fddev = open_dev(iname)) == -1) {
4850 4853 ret = WIFI_FATAL_ERR;
4851 4854 goto exit0;
4852 4855 }
4853 4856 }
4854 4857 if (rflag) {
4855 4858 safe_snprintf(file_wifi, sizeof (file_wifi),
4856 4859 "%s%s", path, p_file_wifi);
4857 4860 safe_snprintf(file_wifiwepkey, sizeof (file_wifiwepkey),
4858 4861 "%s%s", path, p_file_wifiwepkey);
4859 4862 } else {
4860 4863 safe_snprintf(file_wifi, sizeof (file_wifi),
4861 4864 "%s", p_file_wifi);
4862 4865 safe_snprintf(file_wifiwepkey, sizeof (file_wifiwepkey),
4863 4866 "%s", p_file_wifiwepkey);
4864 4867 }
4865 4868 /*
4866 4869 * There is an occasion when more than one wificonfig processes
4867 4870 * which attempt to write the <wifi> and <wifiwepkey> files are
4868 4871 * running. We must be able to avoid this.
4869 4872 * We use file lock here to implement this.
4870 4873 */
4871 4874 if ((!readonly) && (enter_wifi_lock(&fd) != getpid())) {
4872 4875 ret = WIFI_FATAL_ERR;
4873 4876 goto exit1;
4874 4877 }
4875 4878 gp_config_file = parse_file(file_wifi);
4876 4879 if (gp_config_file == NULL) {
4877 4880 ret = WIFI_FATAL_ERR;
4878 4881 goto exit2;
4879 4882 }
4880 4883
4881 4884 gp_wepkey_file = parse_file(file_wifiwepkey);
4882 4885 if (gp_wepkey_file == NULL) {
4883 4886 destroy_config(gp_config_file);
4884 4887 ret = WIFI_FATAL_ERR;
4885 4888 goto exit2;
4886 4889 }
4887 4890 if (do_func[i].p_do_func(fddev, argc-1, argv+1)
4888 4891 == B_TRUE) {
4889 4892 /*
4890 4893 * can not write file when startconfing
4891 4894 * during boot
4892 4895 */
4893 4896 if (do_func[i].b_readonly)
4894 4897 ret = WIFI_EXIT_DEF;
4895 4898 else if ((fprint_config_file(gp_config_file,
4896 4899 file_wifi) != B_TRUE) ||
4897 4900 (fprint_config_file(gp_wepkey_file,
4898 4901 file_wifiwepkey) != B_TRUE))
4899 4902 ret = WIFI_FATAL_ERR;
4900 4903 else
4901 4904 ret = WIFI_EXIT_DEF;
4902 4905 } else {
4903 4906 PRTDBG(("Command %s failed\n", argv[0]));
4904 4907 ret = WIFI_FATAL_ERR;
4905 4908 }
4906 4909 destroy_config(gp_wepkey_file);
4907 4910 destroy_config(gp_config_file);
4908 4911 exit2:
4909 4912 if (!readonly)
4910 4913 exit_wifi_lock(fd);
4911 4914 exit1:
4912 4915 if (iname)
4913 4916 (void) close(fddev);
4914 4917 exit0:
4915 4918 free(gbuf);
4916 4919 return (ret);
4917 4920 }
4918 4921
4919 4922 #ifdef DEBUG
4920 4923 static void
4921 4924 wifi_dbgprintf(char *fmt, ...)
4922 4925 {
4923 4926 va_list ap;
4924 4927 va_start(ap, fmt);
4925 4928 (void) vfprintf(stdout, fmt, ap);
4926 4929 va_end(ap);
4927 4930 }
4928 4931 #endif
↓ open down ↓ |
2163 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX