4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
35 #include <sys/types.h>
46 #include <auth_attr.h>
47 #include <auth_list.h>
48 #include <libdevinfo.h>
56 #include <inet/wifi_ioctl.h>
63 void wifi_dbgprintf(char *fmt
, ...);
64 #define PRTDBG(msg) if (wifi_debug > 1) wifi_dbgprintf msg
69 #define MAX_HISTORY_NUM 10
70 #define MAX_PREFERENCE_NUM 10
71 #define MAX_SCANBUF_LEN 256
72 #define MAX_CONFIG_FILE_LENGTH 256
73 #define MAX_LOADPF_LENGTH 256
74 #define LOADPROFILE_TIMEOUT 10
78 * Wificonfig exit status
80 #define WIFI_EXIT_DEF 0
81 #define WIFI_FATAL_ERR 1
82 #define WIFI_IMPROPER_USE 2
83 #define WIFI_MINOR_ERR 3
85 #define WIFI_LOCKF "/var/run/lockf_wifi"
95 #define WIFI_PREFER "{preference}"
96 #define WIFI_HISTORY "{history}"
97 #define WIFI_ACTIVEP "{active_profile}"
115 CONFIG_ITEM_END
/* 15 */
121 typedef struct aelist
{
123 ae_t
*ael_head
, *ael_tail
;
126 typedef struct section
{
127 struct section
*section_next
;
133 * config_file_t is an abstract of configration file,
134 * either/etc/inet/wifi/wifi.<interface> or /etc/inet/secret/
135 * wifi/wifiwepkey.<interface>
137 typedef struct config_file
{
139 section_t
*section_head
, *section_tail
;
142 static config_file_t
*gp_config_file
= NULL
;
143 static config_file_t
*gp_wepkey_file
= NULL
;
144 static char *p_file_wifi
= "/etc/inet/wifi";
145 static char *p_file_wifiwepkey
= "/etc/inet/secret/wifiwepkey";
152 static char *p_auth_string
[] = {
158 * gbuf: is a global buf, which is used to communicate between the user and
161 static wldp_t
*gbuf
= NULL
;
162 static char *gExecName
= NULL
;
164 static void print_error(uint32_t);
165 static void *safe_malloc(size_t);
166 static void *safe_calloc(size_t, size_t);
167 static char *safe_strdup(const char *s1
);
168 static void safe_snprintf(char *s
, size_t n
,
169 const char *format
, ...);
170 static void safe_fclose(FILE *stream
);
171 static void new_ae(aelist_t
*ael
, const char *arg
);
172 static aelist_t
*new_ael(list_type_t type
);
173 static config_file_t
*new_config_file();
174 static void new_section(config_file_t
*p_config_file
, aelist_t
*p_list
,
175 const char *section_id
);
176 static void destroy_config(config_file_t
*p_config_file
);
177 static config_file_t
*parse_file(const char *pfile
);
178 static char **aeltoargv(aelist_t
*ael
, int *ael_num
);
179 static boolean_t
fprint_config_file(config_file_t
*p_config_file
,
180 const char *file_name
);
181 static char *append_pa(const char *arg
);
182 static section_t
*find_section(config_file_t
*p_config_file
,
183 const char *section_id
);
184 static ae_t
*find_ae(aelist_t
*plist
, const char *arg
);
185 static void update_aelist(aelist_t
*plist
, const char *arg
);
186 static const char *get_value(const char *arg
);
187 static char *find_active_profile(int);
188 static const char *essid_of_profile(const char *profile
);
189 static boolean_t
search_interface(char *interface
);
190 static int open_dev(char *devname
);
191 static boolean_t
call_ioctl(int, int, uint32_t, uint32_t);
192 static boolean_t
del_prefer(config_file_t
*p_config_file
, const char *prefer
,
194 static boolean_t
del_section(config_file_t
*p_config_file
, char *section_id
);
195 static boolean_t
set_prefer(config_file_t
*p_config_file
, const char *prefer
,
197 static void add_to_history(config_file_t
*p_config_file
,
198 int argc
, char **argv
);
199 static boolean_t
check_authority(wifi_auth_t type
);
200 static void heuristic_load(int fd
, uint32_t ess_num
, wl_ess_conf_t
**);
201 static char *select_profile(int fd
, int readonly
, int timeout
);
202 static char *construct_format(uint32_t nt
);
203 static void print_gbuf(config_item_t index
);
204 static boolean_t
items_in_profile(aelist_t
*, aelist_t
*, int, char **);
205 static char *get_commit_key(int, int, char **);
206 static void print_wepkey_info(const char *id
, const char *wepkeyn
);
207 static void do_print_usage();
208 static boolean_t
do_print_support_params(int fd
);
209 static boolean_t
do_autoconf(int fd
, int argc
, char **argv
);
210 static boolean_t
do_startconf(int fd
, int argc
, char **argv
);
211 static boolean_t
do_loadpf(int fd
, int argc
, char **argv
);
212 static boolean_t
do_disconnect(int fd
, int argc
, char **argv
);
213 static boolean_t
do_printpf(int fd
, int argc
, char **argv
);
214 static boolean_t
do_restoredef(int fd
, int argc
, char **argv
);
215 static boolean_t
do_history(int fd
, int argc
, char **argv
);
216 static boolean_t
do_deletepf(int fd
, int argc
, char **argv
);
217 static boolean_t
do_wepkey(int fd
, int argc
, char **argv
);
218 static boolean_t
do_setprefer(int fd
, int argc
, char **arg
);
219 static boolean_t
do_rmprefer(int fd
, int argc
, char **argv
);
220 static boolean_t
do_lsprefer(int fd
, int argc
, char **argv
);
221 static boolean_t
do_wlanlist(int fd
, int argc
, char **argv
);
222 static boolean_t
do_showstatus(int fd
, int argc
, char **argv
);
223 static boolean_t
do_getprofparam(int fd
, int argc
, char **argv
);
224 static boolean_t
do_setprofparam(int fd
, int argc
, char **argv
);
225 static boolean_t
do_setprofwepkey(int fd
, int argc
, char **argv
);
226 static boolean_t
is_rates_support(int fd
, int num
, uint8_t *rates
);
227 static boolean_t
do_set_bsstype(int fd
, const char *arg
);
228 static boolean_t
do_set_essid(int fd
, const char *arg
);
229 static boolean_t
do_set_powermode(int fd
, const char *arg
);
230 static boolean_t
do_set_rates(int fd
, const char *arg
);
231 static boolean_t
do_set_channel(int fd
, const char *arg
);
232 static boolean_t
do_set_createibss(int fd
, const char *arg
);
233 static boolean_t
do_set_radioon(int fd
, const char *arg
);
234 static boolean_t
do_set_wepkeyid(int fd
, const char *arg
);
235 static boolean_t
do_set_encryption(int fd
, const char *arg
);
236 static boolean_t
do_set_authmode(int fd
, const char *arg
);
237 static boolean_t
do_set_wepkey(int fd
, const char *pbuf
);
238 static boolean_t
do_get_createibss(int fd
);
239 static boolean_t
do_get_bsstype(int fd
);
240 static boolean_t
do_get_essid(int fd
);
241 static boolean_t
do_get_bssid(int fd
);
242 static boolean_t
do_get_radioon(int fd
);
243 static boolean_t
do_get_signal(int fd
);
244 static boolean_t
do_get_wepkeyid(int fd
);
245 static boolean_t
do_get_encryption(int fd
);
246 static boolean_t
do_get_authmode(int fd
);
247 static boolean_t
do_get_powermode(int fd
);
248 static boolean_t
do_get_rates(int fd
);
249 static boolean_t
do_get_wlanlist(int fd
);
250 static boolean_t
do_get_linkstatus(int fd
);
251 static boolean_t
do_get_channel(int fd
);
252 static boolean_t
do_get(int fd
, int argc
, char **argv
);
253 static boolean_t
do_set(int fd
, int argc
, char **argv
);
254 static boolean_t
do_createprofile(int fd
, int argc
, char **argv
);
255 static boolean_t
value_is_valid(config_item_t item
, const char *value
);
257 typedef struct cmd_ops
{
259 boolean_t (*p_do_func
)(int fd
, int argc
, char **argv
);
261 boolean_t b_fileonly
; /* operation only on the config file */
262 boolean_t b_readonly
; /* only read from the card or config file */
264 static cmd_ops_t do_func
[] = {
408 typedef enum {RW
, RO
, WO
} rw_property_t
;
409 typedef struct gs_ops
{
412 boolean_t (*p_do_get_func
)(int fd
);
413 boolean_t (*p_do_set_func
)(int fd
, const char *arg
);
416 static gs_ops_t do_gs_func
[] = {
417 {LINKSTATUS
, "linkstatus", NULL
, NULL
, RO
},
418 {BSSID
, "bssid", do_get_bssid
, NULL
, RO
},
419 {ESSID
, "essid", do_get_essid
, do_set_essid
, RW
},
420 {BSSTYPE
, "bsstype", do_get_bsstype
, do_set_bsstype
, RW
},
421 {CREATEIBSS
, "createibss", do_get_createibss
, do_set_createibss
, RW
},
422 {CHANNEL
, "channel", do_get_channel
, do_set_channel
, RW
},
423 {RATES
, "rates", do_get_rates
, do_set_rates
, RW
},
424 {POWERMODE
, "powermode", do_get_powermode
, do_set_powermode
, RW
},
425 {AUTHMODE
, "authmode", do_get_authmode
, do_set_authmode
, RW
},
426 {ENCRYPTION
, "encryption", do_get_encryption
, do_set_encryption
, RW
},
427 {WEPKEYID
, "wepkeyindex", do_get_wepkeyid
, do_set_wepkeyid
, RW
},
428 {WEPKEY
, "wepkey|1-4", NULL
, do_set_wepkey
, WO
},
429 {SIGNAL
, "signal", do_get_signal
, NULL
, RO
},
430 {RADIOON
, "radio", do_get_radioon
, do_set_radioon
, RW
},
433 #define N_FUNC sizeof (do_func) / sizeof (cmd_ops_t)
434 #define N_GS_FUNC sizeof (do_gs_func) / sizeof (gs_ops_t)
439 typedef struct wifi_rates_tab
{
442 uint8_t rates_reserve0
;
443 uint8_t rates_reserve1
;
444 uint8_t rates_reserve2
;
448 * the rates value is in increments of 500kb/s.
449 * according to the 802.11 a/b/g specs(IEEE):
450 * 802.11b(IEEE Std 802.11b-1999) page35, rates should be:
452 * 802.11a(IEEE Std 802.11a-1999) page47, rates should be:
453 * 6,9,12,18,24,36,48,54 Mb/s
454 * 802.11g(IEEE Std 802.11g-2003) page44, rates should be:
455 * 1,2,5.5,11,6,9,12,18,22,24,33,36,48,54 Mb/s
457 #define WIFI_RATES_NUM 14
458 static wifi_rates_tab_t wifi_rates_s
[WIFI_RATES_NUM
] = {
459 {"1", WL_RATE_1M
, 0, 0, 0},
460 {"2", WL_RATE_2M
, 0, 0, 0},
461 {"5.5", WL_RATE_5_5M
, 0, 0, 0},
462 {"6", WL_RATE_6M
, 0, 0, 0},
463 {"9", WL_RATE_9M
, 0, 0, 0},
464 {"11", WL_RATE_11M
, 0, 0, 0},
465 {"12", WL_RATE_12M
, 0, 0, 0},
466 {"18", WL_RATE_18M
, 0, 0, 0},
467 {"22", WL_RATE_22M
, 0, 0, 0},
468 {"24", WL_RATE_24M
, 0, 0, 0},
469 {"33", WL_RATE_33M
, 0, 0, 0},
470 {"36", WL_RATE_36M
, 0, 0, 0},
471 {"48", WL_RATE_48M
, 0, 0, 0},
472 {"54", WL_RATE_54M
, 0, 0, 0}
474 /* print the error message on why set or get ioctl command failed. */
476 print_error(uint32_t errorno
)
482 buf
= gettext("command succeeded");
484 case WL_NOTSUPPORTED
:
485 case WL_LACK_FEATURE
:
487 case WL_ACCESS_DENIED
:
488 buf
= strerror(errorno
);
491 buf
= gettext("parameter read-only");
494 buf
= gettext("parameter write-only");
497 buf
= gettext("no access point available");
500 buf
= gettext("unknown error");
503 (void) fprintf(stderr
, "%s\n", buf
);
507 safe_malloc(size_t size
)
513 (void) fprintf(stderr
, gettext("%s: malloc: %s\n"),
514 gExecName
, strerror(errno
));
515 exit(WIFI_FATAL_ERR
);
521 safe_calloc(size_t nelem
, size_t elsize
)
525 buf
= calloc(nelem
, elsize
);
527 (void) fprintf(stderr
, gettext("%s: calloc: %s\n"),
528 gExecName
, strerror(errno
));
529 exit(WIFI_FATAL_ERR
);
535 safe_strdup(const char *s1
)
541 (void) fprintf(stderr
, gettext("%s: strdup: %s\n"),
542 gExecName
, strerror(errno
));
543 exit(WIFI_FATAL_ERR
);
549 safe_snprintf(char *s
, size_t n
, const char *format
, ...)
553 va_start(ap
, format
);
555 len
= vsnprintf(s
, n
, format
, ap
);
556 if ((len
<= 0) || (len
> n
- 1)) {
557 (void) fprintf(stderr
,
558 gettext("%s: snprintf: %s\n"),
559 gExecName
, strerror(errno
));
560 exit(WIFI_FATAL_ERR
);
566 safe_fclose(FILE *stream
)
570 err
= fclose(stream
);
572 (void) fprintf(stderr
, gettext("%s: fclose: %s\n"),
573 gExecName
, strerror(errno
));
574 exit(WIFI_FATAL_ERR
);
578 * new_ae: Add an element with content pointed by arg to the list *ael.
581 new_ae(aelist_t
*ael
, const char *arg
)
585 PRTDBG(("new_ae(0x%x, \"%s\")\n", ael
, arg
));
586 assert((ael
!= NULL
) && (arg
!= NULL
));
588 pae
= safe_calloc(sizeof (*pae
), 1);
589 pae
->ae_arg
= safe_strdup(arg
);
592 if (ael
->ael_tail
== NULL
) {
595 ael
->ael_tail
->ae_next
= pae
;
601 * new_ael: Create a new aelist with list_type "type"
602 * and return the list pointer.
605 new_ael(list_type_t type
)
609 plist
= safe_calloc(sizeof (*plist
), 1);
612 plist
->ael_head
= plist
->ael_tail
= NULL
;
614 PRTDBG(("new_ael(%d) = 0x%x\n", type
, plist
));
619 * new_config_file: Creates a new config_file_t struct which is counterpart of
620 * of the configration file, and return the pointer.
622 static config_file_t
*
625 config_file_t
*p_config_file
;
627 p_config_file
= safe_calloc(sizeof (config_file_t
), 1);
628 p_config_file
->section_argc
= 0;
629 p_config_file
->section_head
= p_config_file
->section_tail
= NULL
;
631 PRTDBG(("new_config_file() = 0x%x\n", p_config_file
));
632 return (p_config_file
);
636 * new_section: Add a list pointed by "p_list", with identity "section_id" to
637 * the config_file_t struct pointed by "p_config_file"
640 new_section(config_file_t
*p_config_file
, aelist_t
*p_list
,
641 const char *section_id
)
643 section_t
*p_section
= NULL
;
645 PRTDBG(("new_section(0x%x, 0x%x, \"%s\")\n", p_config_file
, p_list
,
647 assert((p_config_file
!= NULL
) && (p_list
!= NULL
) &&
648 (section_id
!= NULL
));
650 p_section
= safe_calloc(sizeof (*p_section
), 1);
651 p_section
->list
= p_list
;
652 p_section
->section_next
= NULL
;
653 p_section
->section_id
= safe_strdup(section_id
);
655 if (p_config_file
->section_tail
== NULL
) {
656 p_config_file
->section_head
= p_section
;
658 p_config_file
->section_tail
->section_next
= p_section
;
660 p_config_file
->section_tail
= p_section
;
661 p_config_file
->section_argc
++;
665 * destroy_config:Destroy the config_file struct
668 destroy_config(config_file_t
*p_config_file
)
670 section_t
*p_section
= NULL
;
671 aelist_t
*p_list
= NULL
;
674 PRTDBG(("destory_config(0x%x)\n", p_config_file
));
675 assert(p_config_file
!= NULL
);
677 p_section
= p_config_file
->section_head
;
678 while (p_section
!= NULL
) {
679 p_list
= p_section
->list
;
680 if (p_list
!= NULL
) {
681 pae
= p_list
->ael_head
;
682 while (pae
!= NULL
) {
686 free(p_list
->ael_head
);
687 p_list
->ael_head
= pae
;
692 free(p_section
->section_id
);
693 p_section
->section_id
= NULL
;
694 p_section
= p_section
->section_next
;
695 free(p_config_file
->section_head
);
696 p_config_file
->section_head
= p_section
;
699 p_config_file
= NULL
;
703 * parse_file: Parse each section of the configration file
704 * and construct the config_file_t structure.
706 * A config file has contents below:
725 * authmode=OPENSYSTEM
728 * then its config_file_t structure will be:
731 * |~~~~~~~~~~~~~~~~~~~~~~~~~~|
733 * |~~~~~~~~~~~~T~~~~~~~~~~~~~|
734 * /| *head | *tail |\
735 * / ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \
741 * section_t V section_t V section_t
742 * |~~~~~~~~~~~~~~~|~~| |~~~~~~~~~~~~~~~|~~| |~~~~~~~~~~~~~~|~~|
743 * |"{preferrence}"| | | "{history}" | | | "[linksys]" | |
744 * |~~~~~~~~~~~~~~~| -+---->|~~~~~~~~~~~~~~~| -+->..->|~~~~~~~~~~~~~~| -+->NULL
745 * | *list | | | *list | | | *list | |
746 * ~~T~~~~~~~~~~~~~~~~~ ~~~T~~~~~~~~~~~~~~~~ ~~~T~~~~~~~~~~~~~~~
749 * V aelist_t V aelist_t V aelist_t
750 * |~~~~~~~~~~~~~| |~~~~~~~~~~~~~| |~~~~~~~~~~~~~|
751 * | argc=2 | | argc=3 | | argc=4 |
752 * |~~~~~~~~~~~~~| |~~~~~~~~~~~~~| |~~~~~~~~~~~~~|
753 * |PREFFERRENCE | | HISTORY | | PROFILE |
754 * |~~~~~~T~~~~~~| |~~~~~~T~~~~~~| |~~~~~~T~~~~~~|
755 * |*head |*tail |\ |*head |*tail |\ |*head |*tail |
756 * ~~T~~~~~~~~~~~~ \ ~~T~~~~~~~~~~~~ \ /~~~~~~~~~~~~~~~\
759 * V ae_t V ae_t ae_t V ae_t V
760 * |~~~~~~~~~T~~| |~~~~~~~~~T~~| |~~~~~~~~~T~~| |~~~~~~~~~T~~|
761 * |"essid= | -+->|"essid= | -+->NULL |"essid= | -+->..->|"wepkeyid| -+->NULL
762 * | ap7-3" | | | linksys"| | | linksys"| | | =1" | |
763 * ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
767 static config_file_t
*
768 parse_file(const char *pfile
)
773 config_file_t
*p_config_file
;
774 list_type_t cur_list
= OTHER
;
775 aelist_t
*prefer_list
= NULL
;
776 aelist_t
*history_list
= NULL
;
777 aelist_t
*profile_list
= NULL
;
778 aelist_t
*activep_list
= NULL
;
780 assert(pfile
!= NULL
);
782 * The files /etc/inet/wifi and /etc/inet/secret/wifiwepkey should
783 * be opened with "r" attribute. If these two files do not exist,
786 file
= fopen(pfile
, "r");
789 fd
= open(pfile
, O_CREAT
|O_EXCL
|O_RDWR
, 0600);
791 (void) fprintf(stderr
, gettext("%s: failed to open %s"
792 "\n"), gExecName
, pfile
);
795 file
= fdopen(fd
, "w");
796 (void) chmod(pfile
, S_IRUSR
);
799 p_config_file
= new_config_file();
801 while (fgets(buf_line
, sizeof (buf_line
), file
) != NULL
) {
802 if ((buf_line
[0] == '\n') || (buf_line
[0] == ' '))
804 /* replace the old '\n' to '\0' */
805 buf_line
[strlen(buf_line
) - 1] = '\0';
806 if (strstr(buf_line
, WIFI_PREFER
) == buf_line
) {
807 if (prefer_list
== NULL
) {
808 cur_list
= PREFERENCE
;
809 prefer_list
= new_ael(PREFERENCE
);
810 new_section(p_config_file
, prefer_list
,
813 (void) fprintf(stderr
, gettext("%s: "
814 "%s : duplicated %s section\n"),
815 gExecName
, pfile
, WIFI_PREFER
);
818 } else if (strstr(buf_line
, WIFI_HISTORY
) == buf_line
) {
819 if (history_list
== NULL
) {
821 history_list
= new_ael(HISTORY
);
822 new_section(p_config_file
, history_list
,
825 (void) fprintf(stderr
, gettext("%s: "
826 "%s : duplicated %s section\n"),
827 gExecName
, pfile
, WIFI_HISTORY
);
830 } else if (strstr(buf_line
, WIFI_ACTIVEP
) == buf_line
) {
831 if (activep_list
== NULL
) {
833 activep_list
= new_ael(ACTIVEP
);
834 new_section(p_config_file
, activep_list
,
837 (void) fprintf(stderr
, gettext("%s: "
838 "%s : duplicated %s section\n"),
839 gExecName
, pfile
, WIFI_ACTIVEP
);
842 } else if ((strchr(buf_line
, '[') == buf_line
) &&
843 (buf_line
[strlen(buf_line
) - 1] == ']')) {
845 profile_list
= new_ael(PROFILE
);
846 new_section(p_config_file
, profile_list
,
851 if (prefer_list
->ael_argc
<=
853 new_ae(prefer_list
, buf_line
);
856 if (history_list
->ael_argc
<=
858 new_ae(history_list
, buf_line
);
861 if ((activep_list
->ael_argc
<= 1) &&
862 (strpbrk(buf_line
, "=") != NULL
))
863 new_ae(activep_list
, buf_line
);
866 if (strpbrk(buf_line
, "=") != NULL
)
867 new_ae(profile_list
, buf_line
);
870 (void) fprintf(stderr
,
871 gettext("%s: %s: file format error\n"),
877 PRTDBG(("parse_file(\"%s\")=0x%x\n", pfile
, p_config_file
));
879 return (p_config_file
);
881 destroy_config(p_config_file
);
887 * construct an argument vector from an aelist
890 aeltoargv(aelist_t
*ael
, int *ael_num
)
896 PRTDBG(("aeltoargv(%x)\n", ael
));
899 argv
= safe_calloc(sizeof (*argv
), ael
->ael_argc
);
901 for (argc
= 0, ae
= ael
->ael_head
; ae
; ae
= ae
->ae_next
) {
902 /* skip bssid since it can not be set */
903 if (strncmp(ae
->ae_arg
, "bssid=", strlen("bssid=")) == 0)
905 argv
[argc
] = safe_strdup(ae
->ae_arg
);
907 if (ae
== ael
->ael_tail
)
911 PRTDBG(("aeltoargv(0x%x) = 0x%x\n\n", ael
, argv
));
917 * archived contents into a file
920 fprint_config_file(config_file_t
*p_config_file
, const char *file_name
)
925 section_t
*p_section
= NULL
;
926 aelist_t
*p_list
= NULL
;
931 PRTDBG(("fprint_config_file(0x%x, \"%s\")\n", p_config_file
,
933 assert((p_config_file
!= NULL
)&&(strcmp(file_name
, "") != 0));
935 safe_snprintf(temp_file
, sizeof (temp_file
),
936 "%s.tmp", file_name
);
937 fd
= open(temp_file
, O_CREAT
|O_WRONLY
|O_TRUNC
, 0600);
939 (void) fprintf(stderr
, gettext("%s: failed to open %s\n"),
940 gExecName
, temp_file
);
943 file
= fdopen(fd
, "w");
945 p_section
= p_config_file
->section_head
;
946 while (p_section
!= NULL
) {
947 p_list
= p_section
->list
;
948 if (p_list
!= NULL
) {
949 PRTDBG(("fprint_config_file: section_id=%s\n",
950 p_section
->section_id
));
951 len
= fprintf(file
, "\n%s\n", p_section
->section_id
);
953 (void) fprintf(stderr
, gettext("%s: "
954 "failed to update %s: %s\n"),
955 gExecName
, file_name
, strerror(errno
));
959 pae
= p_list
->ael_head
;
960 while (pae
!= NULL
) {
961 if (pae
->ae_arg
!= NULL
) {
962 len
= fprintf(file
, "%s\n",
965 (void) fprintf(stderr
,
966 gettext("%s: failed to "
968 gExecName
, file_name
,
977 p_section
= p_section
->section_next
;
981 * The attribute of the file /etc/inet/wifi and
982 * /etc/inet/security/wifiwepkey should be retained.
983 * if those file do not exist, set default file mode.
985 if (stat(file_name
, &buf
) != 0) {
986 if (errno
== ENOENT
) {
989 (void) fprintf(stderr
, gettext("%s: failed to get "
990 "file %s stat: %s\n"),
991 gExecName
, file_name
, strerror(errno
));
995 if (rename(temp_file
, file_name
) != 0) {
996 (void) fprintf(stderr
, gettext("%s: failed to update %s: %s"
997 "\n"), gExecName
, file_name
, strerror(errno
));
1000 (void) chmod(file_name
, buf
.st_mode
);
1004 * append_pa: Each section holds a section_id which identifies a section
1005 * a profile uses its essid appending "[]" to denote its section_id.
1006 * note: new memory is allocated, remember to free.
1009 append_pa(const char *arg
)
1014 assert(arg
!= NULL
);
1016 len
= strlen(arg
) + 3;
1017 pbuf
= safe_malloc(len
);
1018 safe_snprintf(pbuf
, len
, "[%s]", arg
);
1019 PRTDBG(("append_pa(\"%s\") = \"%s\"\n", arg
, pbuf
));
1023 * find a section by section_id from p_config_file,
1024 * return the section pointer.
1027 find_section(config_file_t
*p_config_file
, const char *section_id
)
1029 section_t
*p_section
= NULL
;
1031 PRTDBG(("find_section(0x%x, \"%s\")\n", p_config_file
, section_id
));
1032 assert((section_id
!= NULL
)&&(p_config_file
!= NULL
));
1034 p_section
= p_config_file
->section_head
;
1036 while (p_section
!= NULL
) {
1037 if ((p_section
->section_id
!= NULL
) &&
1038 (strcmp(p_section
->section_id
, section_id
) == 0))
1040 p_section
= p_section
->section_next
;
1046 * get_value: Get rid of "parameter=" from a "parameter=value", for example:
1047 * when we read an line from file, we gets "essid=ap7-2", this function
1048 * returns the pointer to string "ap7-2";
1052 get_value(const char *arg
)
1055 assert(arg
!= NULL
);
1057 p
= strchr(arg
, '=');
1058 PRTDBG(("get_value(\"%s\") = \"%s\"\n", arg
, p
+ 1));
1066 * search /dev/wifi to see which interface is available
1069 search_interface(char *interface
)
1076 PRTDBG(("search interface\n"));
1077 assert(interface
!= NULL
);
1080 * Try to return the first found wifi interface.
1081 * If no wifi interface is available, return B_FALSE
1084 if ((dirp
= opendir("/dev/wifi")) == NULL
) {
1085 PRTDBG(("failed to open '/dev/wifi'\n"));
1088 while ((dp
= readdir(dirp
)) != NULL
) {
1089 if (strcmp(dp
->d_name
, ".") == 0 ||
1090 strcmp(dp
->d_name
, "..") == 0)
1092 if (dp
->d_name
[strlen(dp
->d_name
) - 1] < '0' ||
1093 dp
->d_name
[strlen(dp
->d_name
) - 1] > '9')
1095 safe_snprintf(buf
, sizeof (buf
), "%s%s",
1096 "/dev/wifi/", dp
->d_name
);
1097 fd
= open(buf
, O_RDWR
);
1099 PRTDBG(("interface %s doesn't exist\n", dp
->d_name
));
1102 PRTDBG(("interface %s is the first found interface\n",
1104 (void) strlcpy(interface
, buf
, LIFNAMSIZ
);
1106 (void) closedir(dirp
);
1111 PRTDBG(("failed to find available wireless interface\n"));
1112 (void) closedir(dirp
);
1117 * open_dev: Open the driver.
1118 * if the 'devname' has format like 'ath0', we should add the path to that
1119 * device(/dev/ath0) and open it; if the 'devname' has format like
1120 * '/dev/wifi/ath0', we open it directly.
1123 open_dev(char *devname
)
1129 PRTDBG(("open_dev(\"%s\")\n", devname
));
1130 assert(devname
!= NULL
);
1132 * If the devname is got from the user input, we
1133 * add '/dev/' to that relative devname. If it
1134 * is got from the 'search interface', it is an
1137 if (strncmp(devname
, "/dev/wifi/", strlen("/dev/wifi/")) == 0) {
1138 pbuf
= safe_strdup(devname
);
1140 len
= strlen(devname
) + strlen("/dev/") + 1;
1141 pbuf
= safe_malloc(len
);
1142 safe_snprintf(pbuf
, len
, "/dev/%s", devname
);
1144 fd
= open(pbuf
, O_RDWR
);
1148 (void) fprintf(stderr
, gettext("%s: failed to open '%s': %s"
1149 "\n"), gExecName
, devname
, strerror(errno
));
1152 if (!isastream(fd
)) {
1153 (void) fprintf(stderr
, gettext("%s: %s is "
1154 "not a stream device\n"),
1155 gExecName
, devname
);
1162 * call_ioctl: Fill strioctl structure and issue an ioctl system call
1165 call_ioctl(int fd
, int cmd
, uint32_t params
, uint32_t buf_len
)
1167 struct strioctl stri
;
1169 PRTDBG(("call_ioctl_gs(%d, 0x%x, 0x%x, 0x%x)\n",
1170 fd
, cmd
, params
, buf_len
));
1173 case WLAN_GET_PARAM
:
1174 (void) memset(gbuf
, 0, MAX_BUF_LEN
);
1175 stri
.ic_len
= MAX_BUF_LEN
;
1177 case WLAN_SET_PARAM
:
1178 gbuf
->wldp_length
= buf_len
+ WIFI_BUF_OFFSET
;
1179 stri
.ic_len
= gbuf
->wldp_length
;
1182 gbuf
->wldp_length
= sizeof (wldp_t
);
1183 stri
.ic_len
= gbuf
->wldp_length
;
1186 (void) fprintf(stderr
, gettext("%s: ioctl : "
1187 "unsupported ioctl command\n"), gExecName
);
1190 gbuf
->wldp_type
= NET_802_11
;
1191 gbuf
->wldp_id
= params
;
1195 stri
.ic_dp
= (char *)gbuf
;
1197 if (ioctl(fd
, I_STR
, &stri
) == -1) {
1198 gbuf
->wldp_result
= 0xffff;
1201 if (cmd
== WLAN_COMMAND
) {
1204 return (gbuf
->wldp_result
!= WL_SUCCESS
?
1210 * del_prefer: Delete an item from the {preferrence} list, the idea is
1211 * simply free the ae_t element, and set ae_arg to NULL, then when archive
1212 * the config_file_t struct to the file, it will be delete.
1213 * The last flag is used to identify whether this function is invoked due to
1214 * the 'removeprefer' subcommand or due to 'deleteprofile' subcommand.
1217 del_prefer(config_file_t
*p_config_file
, const char *prefer
, boolean_t rflag
)
1219 section_t
*p_section
= NULL
;
1220 aelist_t
*plist
= NULL
;
1222 int i
= 0, position
= 0;
1224 ae_t
*prm_ae
= NULL
;
1226 PRTDBG(("del_prefer(0x%x, \"%s\")\n", p_config_file
, prefer
));
1227 assert((prefer
!= NULL
)&&(p_config_file
!= NULL
));
1229 p_section
= find_section(p_config_file
, WIFI_PREFER
);
1230 if (p_section
!= NULL
)
1231 plist
= p_section
->list
;
1233 if ((p_section
== NULL
) || (plist
== NULL
))
1236 number
= plist
->ael_argc
;
1237 pae
= plist
->ael_head
;
1238 prm_ae
= plist
->ael_head
;
1239 while (pae
!= NULL
) {
1240 if (strcmp(prefer
, pae
->ae_arg
) == 0) {
1242 pae
->ae_arg
= NULL
; /* mark */
1244 plist
->ael_head
= pae
->ae_next
;
1245 if (pae
->ae_next
== NULL
)
1246 plist
->ael_tail
= NULL
;
1248 for (i
= 0; i
< position
- 1; i
++)
1249 prm_ae
= prm_ae
->ae_next
;
1250 prm_ae
->ae_next
= pae
->ae_next
;
1251 if (pae
->ae_next
== NULL
)
1252 plist
->ael_tail
= prm_ae
;
1262 if ((number
== plist
->ael_argc
) && (rflag
== B_TRUE
)) {
1263 (void) fprintf(stderr
, gettext("%s: removeprefer : "
1264 "no such profile: '%s' in the preference list\n"),
1272 * del_section: Delete an section from p_config_file, the idea is
1273 * simply free the aelist_t struct and set it to NULL, when archiving
1274 * config_file_t struct to the file, we will find section list is NULL,
1275 * and will not write it to file, so it will be deleted.
1278 del_section(config_file_t
*p_config_file
, char *section_id
)
1280 section_t
*p_section
= NULL
;
1281 section_t
*prm_section
= NULL
;
1282 aelist_t
*plist
= NULL
;
1284 int i
= 0, position
= 0;
1286 PRTDBG(("del_section(0x%x, \"%s\")\n", p_config_file
, section_id
));
1287 PRTDBG(("del_section: %d section(s) in config file\n",
1288 p_config_file
->section_argc
));
1289 assert((section_id
!= NULL
)&&(p_config_file
!= NULL
));
1291 if (find_section(p_config_file
, section_id
) == NULL
) {
1294 p_section
= p_config_file
->section_head
;
1295 prm_section
= p_config_file
->section_head
;
1296 while (p_section
!= NULL
) {
1297 if (p_section
->section_id
!= NULL
) {
1298 if (strcmp(p_section
->section_id
, section_id
) == 0) {
1299 plist
= p_section
->list
;
1300 pae
= plist
->ael_head
;
1301 while (pae
!= NULL
) {
1305 free(plist
->ael_head
);
1306 plist
->ael_head
= pae
;
1309 p_section
->list
= NULL
;
1310 free(p_section
->section_id
);
1311 p_section
->section_id
= NULL
;
1314 p_config_file
->section_head
=
1315 p_section
->section_next
;
1316 if (p_section
->section_next
== NULL
)
1317 p_config_file
->section_tail
=
1320 for (i
= 0; i
< position
- 1; i
++) {
1322 prm_section
->section_next
;
1324 prm_section
->section_next
=
1325 p_section
->section_next
;
1326 if (p_section
->section_next
== NULL
)
1327 p_config_file
->section_tail
=
1331 p_config_file
->section_argc
--;
1336 p_section
= p_section
->section_next
;
1342 * set_prefer: Reorder the preferrence list.
1345 set_prefer(config_file_t
*p_config_file
, const char *prefer
, int rank
)
1348 aelist_t
*plist
= NULL
;
1349 section_t
*p_section
= NULL
;
1351 int i
= 0, position
= 0;
1352 ae_t
*pae_move
= NULL
;
1354 assert(prefer
!= NULL
);
1355 PRTDBG(("set_prefer(0x%x, \"%s\", %d)\n", p_config_file
, prefer
, rank
));
1357 pbuf
= append_pa(prefer
);
1358 if (find_section(p_config_file
, pbuf
) == NULL
) {
1359 (void) fprintf(stderr
, gettext("%s: setprefer: "
1360 "no such profile: '%s'\n"),
1367 p_section
= find_section(p_config_file
, WIFI_PREFER
);
1369 if (p_section
== NULL
) {
1370 plist
= new_ael(PREFERENCE
);
1371 new_section(p_config_file
, plist
, WIFI_PREFER
);
1372 new_ae(plist
, prefer
);
1375 plist
= p_section
->list
;
1378 pae
= plist
->ael_head
;
1379 pae_move
= plist
->ael_head
;
1380 while (pae
!= NULL
) {
1381 if (strcmp(prefer
, pae
->ae_arg
) == 0) {
1385 plist
->ael_head
= pae
->ae_next
;
1386 if (pae
->ae_next
== NULL
)
1387 plist
->ael_tail
= NULL
;
1389 for (i
= 0; i
< position
- 1; i
++)
1390 pae_move
= pae_move
->ae_next
;
1391 pae_move
->ae_next
= pae
->ae_next
;
1392 if (pae
->ae_next
== NULL
)
1393 plist
->ael_tail
= pae_move
;
1402 PRTDBG(("set_prefer: %d Profiles in prefer list\n", plist
->ael_argc
));
1403 if (rank
> plist
->ael_argc
) {
1404 new_ae(plist
, prefer
);
1405 } else if (rank
<= 1) {
1406 pae
= safe_calloc(sizeof (ae_t
), 1);
1407 pae
->ae_arg
= safe_strdup(prefer
);
1408 pae
->ae_next
= plist
->ael_head
;
1409 plist
->ael_head
= pae
;
1412 pae_move
= plist
->ael_head
;
1413 for (i
= 1; i
< rank
-1; i
++) {
1414 pae_move
= pae_move
->ae_next
;
1416 pae
= safe_calloc(sizeof (ae_t
), 1);
1417 pae
->ae_arg
= safe_strdup(prefer
);
1418 pae
->ae_next
= pae_move
->ae_next
;
1419 pae_move
->ae_next
= pae
;
1423 * If number of prefer list items is larger than the MAX_PREFERENCE_NUM
1424 * delete those items whose No is larger than MAX_PREFERENCE_NUM.
1426 if (plist
->ael_argc
> MAX_PREFERENCE_NUM
) {
1427 pae
= plist
->ael_head
;
1428 while (pae
->ae_next
!= plist
->ael_tail
)
1430 free(plist
->ael_tail
->ae_arg
);
1431 plist
->ael_tail
->ae_arg
= NULL
;
1432 free(plist
->ael_tail
);
1433 plist
->ael_tail
= pae
;
1434 plist
->ael_tail
->ae_next
= NULL
;
1437 PRTDBG(("set_prefer: %d Profiles in prefer list\n", plist
->ael_argc
));
1441 * add_to_history: Save the scanlist argv into history section
1444 add_to_history(config_file_t
*p_config_file
, int argc
, char **argv
)
1446 int i
= 0, j
= 0, pos
= 0;
1447 aelist_t
*plist
= NULL
;
1448 section_t
*p_section
= NULL
;
1454 PRTDBG(("add_to_history(0x%x, %d, 0x%x)\n", p_config_file
, argc
, argv
));
1455 assert(p_config_file
!= NULL
);
1457 p_section
= find_section(p_config_file
, WIFI_HISTORY
);
1459 if (p_section
== NULL
) {
1460 plist
= new_ael(HISTORY
);
1461 new_section(p_config_file
, plist
, WIFI_HISTORY
);
1463 plist
= p_section
->list
;
1466 if (plist
!= NULL
) {
1467 for (i
= 0; i
< argc
; i
++) {
1468 if (!strlen(argv
[i
]))
1471 pae
= plist
->ael_head
;
1472 pae_m
= plist
->ael_head
;
1474 * add time stamp to the history record
1476 cltime
= time(&cltime
);
1477 (void) snprintf(item
, sizeof (item
), "%s%c%ld",
1478 argv
[i
], ',', cltime
);
1479 while (pae
!= NULL
) {
1480 if (strncmp(item
, pae
->ae_arg
,
1481 strlen(argv
[i
])) == 0) {
1485 plist
->ael_head
= pae
->ae_next
;
1486 if (pae
->ae_next
== NULL
)
1487 plist
->ael_tail
= NULL
;
1489 for (j
= 0; j
< pos
- 1; j
++)
1490 pae_m
= pae_m
->ae_next
;
1491 pae_m
->ae_next
= pae
->ae_next
;
1492 if (pae
->ae_next
== NULL
)
1493 plist
->ael_tail
= pae_m
;
1502 new_ae(plist
, item
);
1505 if (plist
->ael_argc
> MAX_HISTORY_NUM
) {
1506 for (i
= 0; i
< plist
->ael_argc
- MAX_HISTORY_NUM
;
1508 pae
= plist
->ael_head
;
1510 plist
->ael_head
= pae
->ae_next
;
1513 plist
->ael_argc
= MAX_HISTORY_NUM
;
1521 (void) fprintf(stderr
, gettext("\t%s [-R root_path][-i interface]"
1522 " autoconf [wait={n|forever}]\n"), gExecName
);
1523 (void) fprintf(stderr
, gettext("\t%s [-R root_path][-i interface]"
1524 " connect profile [wait={n|forever}]\n"), gExecName
);
1525 (void) fprintf(stderr
, gettext("\t%s [-R root_path][-i interface]"
1526 " connect essid [wait={n|forever}]\n"), gExecName
);
1527 (void) fprintf(stderr
, gettext("\t%s [-R root_path][-i interface]"
1528 " disconnect\n"), gExecName
);
1529 (void) fprintf(stderr
, gettext("\t%s [-R root_path][-i interface]"
1530 " getparam [parameter [...]]\n"), gExecName
);
1531 (void) fprintf(stderr
, gettext("\t%s [-R root_path][-i interface]"
1532 " setparam [parameter=value [...]]\n"), gExecName
);
1533 (void) fprintf(stderr
, gettext(
1535 "\t\tbssid\t\t - read only: 6 byte mac address of "
1537 "\t\tessid\t\t - name of the network, a string of up "
1539 "\t\tbsstype\t\t - bss(ap, infrastructure), ibss(ad-hoc)"
1541 "\t\tcreateibss\t - flag to identify whether a ibss is to be\n"
1542 "\t\t\t\t created when the network to connect is\n"
1543 "\t\t\t\t not available, yes or no\n"
1544 "\t\tchannel\t\t - channel(used only when creating an ibss)\n"
1545 "\t\t\t\t valid value:\n"
1546 "\t\t\t\t\t 802.11a: 0-99\n"
1547 "\t\t\t\t\t 802.11b: 1-14\n"
1548 "\t\t\t\t\t 802.11g: 1-14\n"
1549 "\t\trates\t\t - set of rates, seperated by ',' valid rates:\n"
1550 "\t\t\t\t 1,2,5.5,6,9,11,12,18,22,24,33,36,48 and 54\n"
1551 "\t\tpowermode\t - off, mps or fast\n"
1552 "\t\tauthmode\t - opensystem or shared_key\n"
1553 "\t\tencryption\t - none or wep\n"
1554 "\t\twepkey|1-4\t - write only:\n"
1555 "\t\t\t\t 5 chars or 10 hex digits for 40bit wepkey;\n"
1556 "\t\t\t\t 13 chars or 26 hex digits for 128bit wepkey\n"
1557 "\t\twepkeyindex\t - an integer within the range 1-4\n"
1558 "\t\tsignal\t\t - read only: signal strength from 0 to 15\n"
1559 "\t\tradio\t\t - on or off\n"));
1560 (void) fprintf(stderr
, gettext("\t%s [-R root_path][-i interface]"
1561 " restoredef\n"), gExecName
);
1562 (void) fprintf(stderr
, gettext("\t%s [-R root_path][-i interface]"
1563 " scan\n"), gExecName
);
1564 (void) fprintf(stderr
, gettext("\t%s [-R root_path][-i interface]"
1565 " showstatus\n"), gExecName
);
1566 (void) fprintf(stderr
, gettext("\t%s [-R root_path][-i interface]"
1567 " setwepkey 1|2|3|4\n"), gExecName
);
1569 (void) fprintf(stderr
, "\n");
1571 (void) fprintf(stderr
, gettext("\t%s [-R root_path]"
1572 " createprofile profile parameter=value [...]\n"), gExecName
);
1573 (void) fprintf(stderr
, gettext("\t%s [-R root_path]"
1574 " deleteprofile profile1 [profile2 [...]]\n"), gExecName
);
1575 (void) fprintf(stderr
, gettext("\t%s [-R root_path]"
1576 " showprofile profile1 [profile2 [...]]\n"), gExecName
);
1577 (void) fprintf(stderr
, gettext("\t%s [-R root_path]"
1578 " setprofilewepkey profile 1|2|3|4\n"), gExecName
);
1579 (void) fprintf(stderr
, gettext("\t%s [-R root_path]"
1580 " getprofileparam profile [parameter [...]]\n"), gExecName
);
1581 (void) fprintf(stderr
, gettext("\t%s [-R root_path]"
1582 " setprofileparam profile [parameter=value [...]]\n"), gExecName
);
1584 (void) fprintf(stderr
, "\n");
1586 (void) fprintf(stderr
, gettext("\t%s [-R root_path]"
1587 " history\n"), gExecName
);
1588 (void) fprintf(stderr
, gettext("\t%s [-R root_path]"
1589 " listprefer\n"), gExecName
);
1590 (void) fprintf(stderr
, gettext("\t%s [-R root_path]"
1591 " removeprefer profile\n"), gExecName
);
1592 (void) fprintf(stderr
, gettext("\t%s [-R root_path]"
1593 " setprefer profile [n]\n"), gExecName
);
1597 * do_print_support_params: Query interface which cmd is supported
1600 do_print_support_params(int fd
)
1604 PRTDBG(("do_print_support_params(\"%d\")\n", fd
));
1607 (void) printf(gettext("\t parameter\tproperty\n"));
1608 for (i
= 0; i
< N_GS_FUNC
; i
++) {
1609 gbuf
->wldp_result
= WL_LACK_FEATURE
;
1610 if ((do_gs_func
[i
].p_do_get_func
!= NULL
) &&
1611 (do_gs_func
[i
].p_do_get_func(fd
) != B_TRUE
)) {
1614 if (gbuf
->wldp_result
== WL_SUCCESS
) {
1615 (void) printf("\t%11s", do_gs_func
[i
].cmd
);
1616 if (do_gs_func
[i
].rw
== RO
)
1617 (void) printf(gettext("\tread only\n"));
1619 (void) printf(gettext("\tread/write\n"));
1624 return (n
? B_TRUE
: B_FALSE
);
1628 * check_authority: Check if command is permitted.
1631 check_authority(wifi_auth_t type
)
1633 struct passwd
*pw
= NULL
;
1635 PRTDBG(("check_authority()\n"));
1637 pw
= getpwuid(getuid());
1640 if (chkauthattr(p_auth_string
[type
], pw
->pw_name
) == 0) {
1641 if (type
== AUTH_WEP
)
1642 (void) fprintf(stderr
, gettext("%s: "
1643 "privilege '%s' is required for setting "
1644 "wepkey.\n"), gExecName
, WIFI_WEP_AUTH
);
1646 (void) fprintf(stderr
, gettext("%s: "
1647 "privilege '%s' is required.\n"),
1648 gExecName
, WIFI_CONFIG_AUTH
);
1656 * construct the 'history' and 'scan' output format
1657 * memory allocated. need to free after the function is invoked.
1660 construct_format(uint32_t nt
)
1665 #define FORMAT_LEN 256
1666 assert((nt
>= 1) && (nt
<= 4));
1667 format
= safe_malloc(FORMAT_LEN
);
1669 for (i
= 0; i
< nt
; i
++)
1670 len
+= snprintf(format
+ len
, FORMAT_LEN
- len
, "\t");
1671 if ((len
<= 0) || (len
> FORMAT_LEN
- 1)) {
1672 return ("\t\t\t\t");
1678 * find the essid of the named profile.
1679 * gp_config_file is golable, so the return is gloable too.
1682 essid_of_profile(const char *profile
)
1684 section_t
*p_section
= NULL
;
1685 aelist_t
*plist
= NULL
;
1689 PRTDBG(("essid_of_profile: profile = %s\n", profile
));
1690 pbuf
= append_pa(profile
);
1691 p_section
= find_section(gp_config_file
, pbuf
);
1694 if (p_section
== NULL
) {
1697 plist
= p_section
->list
;
1699 pae
= plist
->ael_head
;
1700 while (pae
!= NULL
) {
1701 if (strncmp(pae
->ae_arg
, "essid=", strlen("essid=")) == 0) {
1702 PRTDBG(("essid_of_profile: essid = %s\n",
1704 return (get_value(pae
->ae_arg
));
1712 * If we don't know which profile is our favorate in 'autoconf',
1713 * we select the wifi network based on the following heuristic
1714 * 1. the network without wep.
1715 * 2. the network with the strongst signal.
1716 * 3. the network with the faster speed(not implemented since signal affects
1717 * the speed in some degree).
1720 heuristic_load(int fd
, uint32_t ess_num
, wl_ess_conf_t
**p_ess_conf
)
1724 int have_nowep_wlan
= 0;
1725 wl_rssi_t maxsignal
= 0;
1727 int timeout
= LOADPROFILE_TIMEOUT
;
1729 PRTDBG(("heuristic_load: enter\n"));
1730 (void) call_ioctl(fd
, WLAN_COMMAND
, WL_LOAD_DEFAULTS
, 0);
1731 flag
= calloc(sizeof (char), ess_num
);
1732 for (i
= 0; i
< ess_num
; i
++) { /* extract none-wep network */
1733 if (p_ess_conf
[i
]->wl_ess_conf_wepenabled
== B_FALSE
) {
1735 have_nowep_wlan
= 1;
1739 * if all the wlans are weped, we select the one with strongest signal
1740 * in all of them, otherwise we just select in the none weped ones.
1742 if (!have_nowep_wlan
)
1743 (void) memset(flag
, 1, ess_num
);
1744 for (i
= 0; i
< ess_num
; i
++) { /* extract the strongest signal ones */
1746 if (p_ess_conf
[i
]->wl_ess_conf_sl
> maxsignal
) {
1747 maxsignal
= p_ess_conf
[i
]->wl_ess_conf_sl
;
1748 (void) memset(flag
, 0, i
);
1749 } else if (p_ess_conf
[i
]->wl_ess_conf_sl
== maxsignal
)
1755 for (i
= 0; i
< ess_num
; i
++) {
1760 PRTDBG(("heuristic_load: %s is selected\n",
1761 p_ess_conf
[i
]->wl_ess_conf_essid
.wl_essid_essid
));
1762 /* select one in all the networks which meet the preceding stardands */
1764 (void) do_set_essid(fd
, "");
1766 (void) do_set_essid(fd
,
1767 p_ess_conf
[i
]->wl_ess_conf_essid
.wl_essid_essid
);
1769 if ((ess_num
== 0) || (do_get_essid(fd
) == B_FALSE
)) {
1770 (void) fprintf(stderr
, gettext("%s: autoconf:"
1771 " failed to connect to any essid\n"),
1773 exit(WIFI_MINOR_ERR
);
1775 (void) strlcpy(essid
, ((wl_essid_t
*)(gbuf
->wldp_buf
))->wl_essid_essid
,
1777 (void) printf(gettext("%s: autoconf: essid '%s' is selected%s\n"),
1779 have_nowep_wlan
? "" : ": this is a WEPed "
1782 if (!have_nowep_wlan
)
1783 exit(WIFI_FATAL_ERR
);
1785 while (timeout
> 0) {
1786 if ((do_get_linkstatus(fd
) == B_TRUE
) &&
1787 (*(wl_linkstatus_t
*)(gbuf
->wldp_buf
) == WL_CONNECTED
)) {
1788 (void) printf(gettext("%s: connecting to "
1789 "essid '%s'\n"), gExecName
, essid
);
1795 (void) fprintf(stderr
, gettext("%s: failed to connect to "
1796 "essid '%s'\n"), gExecName
, essid
);
1797 exit(WIFI_FATAL_ERR
);
1801 * Called in autoconf and startconf to find which 'profile' is selected.
1802 * The process is: check profile names in the prefer list item by item,
1803 * if the essid of the profile is in the scan list, then it is the wanted.
1804 * readonly: 1 for startconf
1806 * for autoconf, the scan result will be recorded in the history list.
1809 select_profile(int fd
, int readonly
, int timeout
)
1811 uint32_t ess_num
= 0;
1815 wl_ess_conf_t
**p_ess_conf
;
1816 section_t
*p_section
= NULL
;
1817 aelist_t
*plist
= NULL
;
1821 char *selected
= NULL
;
1822 boolean_t flag
= B_FALSE
;
1824 if ((call_ioctl(fd
, WLAN_COMMAND
, WL_SCAN
, 0) == B_FALSE
) ||
1825 (do_get_wlanlist(fd
) == B_FALSE
)) {
1826 (void) fprintf(stderr
, gettext("%s: "
1827 "autoconf : failed to scan\n"), gExecName
);
1828 exit(WIFI_FATAL_ERR
);
1830 ess_num
= ((wl_ess_list_t
*)(gbuf
->wldp_buf
))->wl_ess_list_num
;
1831 ess_argv
= safe_calloc(sizeof (char *), ess_num
);
1832 hisess_argv
= safe_calloc(sizeof (char *), ess_num
);
1833 p_ess_conf
= safe_calloc(sizeof (wl_ess_list_t
*), ess_num
);
1834 for (i
= 0; i
< ess_num
; i
++) {
1835 p_ess_conf
[i
] = ((wl_ess_list_t
*)gbuf
->wldp_buf
)
1836 ->wl_ess_list_ess
+ i
;
1837 ess_argv
[i
] = safe_malloc(MAX_SCANBUF_LEN
);
1838 if (readonly
== 0) {
1839 hisess_argv
[i
] = safe_malloc(MAX_SCANBUF_LEN
);
1840 (void) snprintf(hisess_argv
[i
], MAX_SCANBUF_LEN
,
1841 "%s%c%02x:%02x:%02x:%02x:%02x:%02x%c%s",
1842 p_ess_conf
[i
]->wl_ess_conf_essid
.wl_essid_essid
,
1844 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[0]),
1845 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[1]),
1846 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[2]),
1847 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[3]),
1848 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[4]),
1849 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[5]), ',',
1850 (p_ess_conf
[i
]->wl_ess_conf_wepenabled
== B_TRUE
1853 (void) snprintf(ess_argv
[i
], MAX_SCANBUF_LEN
, "%s",
1854 p_ess_conf
[i
]->wl_ess_conf_essid
.wl_essid_essid
);
1856 if (readonly
== 0) {
1857 add_to_history(gp_config_file
, ess_num
, hisess_argv
);
1858 for (i
= 0; i
< ess_num
; i
++) {
1859 free(hisess_argv
[i
]);
1864 p_section
= find_section(gp_config_file
, WIFI_PREFER
);
1865 if (p_section
== NULL
) {
1867 heuristic_load(fd
, ess_num
, p_ess_conf
);
1868 exit(WIFI_EXIT_DEF
);
1872 plist
= p_section
->list
;
1873 assert(plist
!= NULL
);
1874 if (plist
!= NULL
) {
1875 nprefer
= plist
->ael_argc
;
1878 heuristic_load(fd
, ess_num
, p_ess_conf
);
1879 exit(WIFI_EXIT_DEF
);
1884 pae
= plist
->ael_head
;
1885 while ((pae
!= NULL
) && (flag
!= B_TRUE
)) {
1886 parg
= essid_of_profile(pae
->ae_arg
);
1888 for (i
= 0; i
< ess_num
; i
++) {
1889 if (strcmp(parg
, ess_argv
[i
]) == 0) {
1890 selected
= pae
->ae_arg
;
1899 if ((selected
== NULL
) && (timeout
== 0)) {
1900 heuristic_load(fd
, ess_num
, p_ess_conf
);
1902 for (i
= 0; i
< ess_num
; i
++) {
1911 is_waittime_valid(char *pbuf
)
1918 for (i
= 0; i
< strlen(pbuf
); i
++) {
1919 if (isdigit(pbuf
[i
]) == 0) {
1926 * do_autoconf: First scan the wlanlist, and select one essid from scan result
1927 * by the order in {preferrence} list. If no match, then heuristic_load;
1931 do_autoconf(int fd
, int argc
, char **argv
)
1933 const char *selected
= NULL
;
1934 int timeout
= LOADPROFILE_TIMEOUT
, forever
= 0, len
= 0;
1935 char *pequal
, *param
;
1936 char **ld_argv
= NULL
;
1937 boolean_t ret
= B_TRUE
;
1939 PRTDBG(("do_autoconf(%d, 0x%x)\n", argc
, argv
));
1942 param
= safe_strdup(argv
[0]);
1943 pequal
= strchr(param
, '=');
1944 if (pequal
!= NULL
) {
1948 exit(WIFI_IMPROPER_USE
);
1950 if (strcmp(param
, "wait") != 0) {
1952 exit(WIFI_IMPROPER_USE
);
1954 if (strcmp(pequal
, "forever") == 0) {
1957 if (is_waittime_valid(pequal
) == B_FALSE
) {
1958 (void) fprintf(stderr
, gettext("%s: "
1959 "invalid value %s for 'wait'\n"),
1961 exit(WIFI_FATAL_ERR
);
1963 if (sscanf(pequal
, "%d", &timeout
) != 1) {
1965 exit(WIFI_IMPROPER_USE
);
1967 if (timeout
== -1) {
1974 (void) fprintf(stderr
, gettext("%s: trailing "
1975 "useless tokens after '%s'\n"),
1976 gExecName
, argv
[0]);
1980 while ((forever
== 1) || (timeout
> 0)) {
1982 selected
= select_profile(fd
, 0, max(timeout
, forever
));
1983 if (selected
!= NULL
)
1987 if (selected
== NULL
) {
1990 (void) printf(gettext("%s: autoconf: profile [%s]"
1991 " is selected\n"), gExecName
, selected
);
1992 ld_argv
= safe_calloc(sizeof (char *), argc
+1);
1993 ld_argv
[0] = safe_strdup(selected
);
1995 len
= max(strlen(argv
[0]), strlen("wait=forever"));
1996 ld_argv
[1] = safe_malloc(len
);
1997 safe_snprintf(ld_argv
[1], len
+ 1, forever
== 1 ?
1998 "wait=forever" : "wait=%d", timeout
);
2000 ret
= do_loadpf(fd
, argc
+1, ld_argv
);
2010 * do_startconf: almost the same as the do_autoconf, except that doesn't
2015 do_startconf(int fd
, int argc
, char **argv
)
2017 int i
= 0, ael_num
= 0;
2018 section_t
*p_section
= NULL
;
2019 section_t
*p_wep_section
= NULL
;
2020 aelist_t
*plist
= NULL
;
2021 const char *selected
= NULL
;
2024 char **argvnew
= NULL
;
2026 PRTDBG(("do_startconf(%d, 0x%x)\n", argc
, argv
));
2029 selected
= select_profile(fd
, 1, 0);
2030 if (selected
== NULL
) {
2034 (void) call_ioctl(fd
, WLAN_COMMAND
, WL_LOAD_DEFAULTS
, 0);
2036 pbuf
= append_pa(selected
);
2037 p_wep_section
= find_section(gp_wepkey_file
, pbuf
);
2038 p_section
= find_section(gp_config_file
, pbuf
);
2041 if (p_wep_section
!= NULL
) {
2042 plist
= p_wep_section
->list
;
2043 pae
= plist
->ael_head
;
2044 while (pae
!= NULL
) {
2045 if (pae
->ae_arg
!= NULL
)
2046 (void) do_set_wepkey(fd
, pae
->ae_arg
);
2051 if (p_section
!= NULL
) {
2052 plist
= p_section
->list
;
2053 if (plist
->ael_argc
== 0) {
2056 argvnew
= aeltoargv(plist
, &ael_num
);
2057 (void) do_set(fd
, ael_num
, argvnew
);
2059 for (i
= 0; i
< ael_num
; i
++)
2067 find_active_profile(int fd
)
2069 section_t
*p_section
= NULL
, *activep_section
= NULL
;
2070 aelist_t
*plist
= NULL
;
2072 const char *pessid
= NULL
, *pbssid
= NULL
;
2073 char essid
[34], bssid
[32];
2074 const char *activeprofile
= NULL
;
2076 PRTDBG(("find_active_profile: %d\n", fd
));
2077 if (do_get_essid(fd
) == B_FALSE
) {
2080 (void) strlcpy(essid
, ((wl_essid_t
*)(gbuf
->wldp_buf
))->wl_essid_essid
,
2082 if (do_get_bssid(fd
) == B_FALSE
) {
2085 safe_snprintf(bssid
, sizeof (bssid
), "%02x:%02x:%02x:%02x:%02x:%02x",
2086 ((uint8_t *)gbuf
->wldp_buf
)[0],
2087 ((uint8_t *)gbuf
->wldp_buf
)[1],
2088 ((uint8_t *)gbuf
->wldp_buf
)[2],
2089 ((uint8_t *)gbuf
->wldp_buf
)[3],
2090 ((uint8_t *)gbuf
->wldp_buf
)[4],
2091 ((uint8_t *)gbuf
->wldp_buf
)[5]);
2092 activep_section
= find_section(gp_config_file
, WIFI_ACTIVEP
);
2093 if (activep_section
== NULL
)
2095 activeprofile
= get_value(activep_section
->list
->
2097 if (activeprofile
== NULL
)
2099 p_section
= gp_config_file
->section_head
;
2100 while (p_section
!= NULL
) {
2101 if (((plist
= p_section
->list
) != NULL
) &&
2102 (plist
->type
== PROFILE
) &&
2103 (strcmp(p_section
->section_id
, activeprofile
) == 0)) {
2104 pae
= plist
->ael_head
;
2105 while (pae
!= NULL
) {
2106 if (strncmp(pae
->ae_arg
, "essid=",
2107 strlen("essid=")) == 0) {
2108 pessid
= get_value(pae
->ae_arg
);
2110 if (strncmp(pae
->ae_arg
, "bssid=",
2111 strlen("bssid=")) == 0) {
2112 pbssid
= get_value(pae
->ae_arg
);
2116 if (pessid
&& pbssid
&&
2117 (strcmp(essid
, pessid
) == 0) &&
2118 (strcmp(bssid
, pbssid
) == 0)) {
2119 return (p_section
->section_id
);
2122 p_section
= p_section
->section_next
;
2128 record_active_profile(char *pname
, int action
)
2130 section_t
*p_section
= NULL
;
2131 aelist_t
*plist
= NULL
;
2134 p_section
= find_section(gp_config_file
, WIFI_ACTIVEP
);
2135 if (p_section
== NULL
) {
2136 plist
= new_ael(ACTIVEP
);
2137 new_section(gp_config_file
, plist
, WIFI_ACTIVEP
);
2139 plist
= p_section
->list
;
2142 if (action
== RECORD_ADD
) {
2143 assert(pname
!= NULL
);
2144 safe_snprintf(pbuf
, sizeof (pbuf
), "activep=%s", pname
);
2145 update_aelist(plist
, pbuf
);
2146 } else if (action
== RECORD_DEL
) {
2147 assert(pname
== NULL
);
2148 update_aelist(plist
, "activep= ");
2153 * do_loadpf: load a profile, set related parameters both in wifi
2154 * and in wifiwepkey, if network name is not exist in the
2155 * configration files, then we clean all parameters and set essid only
2158 do_loadpf(int fd
, int argc
, char ** argv
)
2160 int i
= 0, ael_num
= 0;
2161 int timeout
= LOADPROFILE_TIMEOUT
, forever
= 0;
2162 section_t
*p_section
= NULL
;
2163 section_t
*p_wep_section
= NULL
;
2164 aelist_t
*plist
= NULL
;
2167 char **argvnew
= NULL
;
2169 char *pequal
, *param
;
2171 PRTDBG(("do_loadpf(%d, %x)\n", argc
, argv
));
2174 (void) fprintf(stderr
, gettext("%s: connect: "
2175 "profile name missing\n"), gExecName
);
2179 param
= safe_strdup(argv
[1]);
2180 pequal
= strchr(param
, '=');
2181 if (pequal
!= NULL
) {
2185 exit(WIFI_IMPROPER_USE
);
2187 if (strcmp(param
, "wait") != 0) {
2189 exit(WIFI_IMPROPER_USE
);
2191 if (strcmp(pequal
, "forever") == 0) {
2194 if (is_waittime_valid(pequal
) == B_FALSE
) {
2195 (void) fprintf(stderr
, gettext("%s: "
2196 "invalid value %s for 'wait'\n"),
2198 exit(WIFI_FATAL_ERR
);
2200 if (sscanf(pequal
, "%d", &timeout
) != 1) {
2202 exit(WIFI_IMPROPER_USE
);
2204 if (timeout
== -1) {
2211 (void) fprintf(stderr
, gettext("%s: trailing "
2212 "useless tokens after '%s'\n"),
2213 gExecName
, argv
[1]);
2216 (void) call_ioctl(fd
, WLAN_COMMAND
, WL_LOAD_DEFAULTS
, 0);
2218 pbuf
= append_pa(argv
[0]);
2219 p_wep_section
= find_section(gp_wepkey_file
, pbuf
);
2220 p_section
= find_section(gp_config_file
, pbuf
);
2222 if (p_wep_section
!= NULL
) {
2223 (void) set_prefer(gp_config_file
, argv
[0], 1);
2224 plist
= p_wep_section
->list
;
2225 pae
= plist
->ael_head
;
2226 while (pae
!= NULL
) {
2227 if (pae
->ae_arg
!= NULL
) {
2228 (void) do_set_wepkey(fd
, pae
->ae_arg
);
2234 if (p_section
!= NULL
) {
2235 connect
= "profile";
2237 (void) set_prefer(gp_config_file
, argv
[0], 1);
2238 plist
= p_section
->list
;
2239 if (plist
->ael_argc
== 0) {
2243 argvnew
= aeltoargv(plist
, &ael_num
);
2245 * if there is no 'essid' item in argvnew, the profile
2246 * name(argv[0]) is treated as essid.
2248 for (i
= 0; i
< ael_num
; i
++) {
2249 if (strncmp(argvnew
[i
], "essid=", strlen("essid="))
2254 (void) do_set_essid(fd
, argv
[0]);
2256 (void) do_set(fd
, ael_num
, argvnew
);
2258 for (i
= 0; i
< ael_num
; i
++)
2263 * set flag in {active_profile} so that showprofile knows
2264 * which profile is active when more than one profiles are
2265 * created for the same WLAN.
2267 record_active_profile(pbuf
, RECORD_ADD
);
2269 (void) do_set_essid(fd
, argv
[0]);
2273 while ((forever
== 1) || (timeout
> 0)) {
2274 if ((do_get_linkstatus(fd
) == B_TRUE
) &&
2275 (*(wl_linkstatus_t
*)(gbuf
->wldp_buf
) == WL_CONNECTED
)) {
2276 section_t
*p_section
= NULL
;
2277 aelist_t
*plist
= NULL
;
2279 /* record bssid in the profile */
2280 if (do_get_bssid(fd
) == B_FALSE
) {
2284 safe_snprintf(bssid
, sizeof (bssid
),
2285 "bssid=%02x:%02x:%02x:%02x:%02x:%02x",
2286 ((uint8_t *)gbuf
->wldp_buf
)[0],
2287 ((uint8_t *)gbuf
->wldp_buf
)[1],
2288 ((uint8_t *)gbuf
->wldp_buf
)[2],
2289 ((uint8_t *)gbuf
->wldp_buf
)[3],
2290 ((uint8_t *)gbuf
->wldp_buf
)[4],
2291 ((uint8_t *)gbuf
->wldp_buf
)[5]);
2293 p_section
= find_section(gp_config_file
, pbuf
);
2294 if (p_section
!= NULL
) {
2295 plist
= p_section
->list
;
2296 update_aelist(plist
, bssid
);
2299 (void) printf(gettext("%s: connecting to "
2300 "%s '%s'\n"), gExecName
, connect
, argv
[0]);
2305 PRTDBG(("connect counting:......%d\n", timeout
));
2307 (void) fprintf(stderr
, gettext("%s: failed to connect to "
2308 "%s '%s'\n"), gExecName
, connect
, argv
[0]);
2314 * if wepkey is set in the profile, display wepkey|n=*****
2315 * when showprofile and getprofilewepkey.
2316 * if wepkeyn is NULL, all the wepkeys will be display,
2317 * otherwise, just display the matching one.
2320 print_wepkey_info(const char *id
, const char *wepkeyn
)
2322 char *pequal
, *param
;
2323 section_t
*p_section
= NULL
;
2324 aelist_t
*plist
= NULL
;
2327 p_section
= find_section(gp_wepkey_file
, id
);
2328 if (p_section
!= NULL
) {
2329 plist
= p_section
->list
;
2330 pae
= plist
->ael_head
;
2331 while (pae
!= NULL
) {
2332 if (pae
->ae_arg
!= NULL
) {
2333 param
= safe_strdup(pae
->ae_arg
);
2334 pequal
= strchr(param
, '=');
2338 if (wepkeyn
!= NULL
) {
2339 if (strcmp(wepkeyn
, param
) == 0)
2340 (void) printf("\t%s=*****\n",
2345 (void) printf("\t%s=*****\n", param
);
2355 * do_printpf: print each parameters of the profile, if no network name
2356 * assigned, then print all profile saved in configration file.
2360 do_printpf(int fd
, int argc
, char ** argv
)
2362 section_t
*p_section
= NULL
;
2363 aelist_t
*plist
= NULL
;
2368 PRTDBG(("do_printpf(%d, %x)\n", argc
, argv
));
2371 * if no profile name is inputted, all the profiles will be displayed.
2374 p_section
= gp_config_file
->section_head
;
2375 while (p_section
!= NULL
) {
2376 plist
= p_section
->list
;
2377 if (plist
->type
== PROFILE
) {
2378 (void) printf("%s\n", p_section
->section_id
);
2379 pae
= plist
->ael_head
;
2380 while (pae
!= NULL
) {
2381 if (pae
->ae_arg
!= NULL
) {
2382 (void) printf("\t%s\n",
2388 * identify whether wepkey is set
2391 print_wepkey_info(p_section
->section_id
, NULL
);
2393 p_section
= p_section
->section_next
;
2398 for (i
= 0; i
< argc
; i
++) {
2399 pbuf
= append_pa(argv
[i
]);
2400 p_section
= find_section(gp_config_file
, pbuf
);
2402 if (p_section
!= NULL
) {
2403 (void) printf("%s\n", p_section
->section_id
);
2404 plist
= p_section
->list
;
2405 if (plist
!= NULL
) {
2406 pae
= plist
->ael_head
;
2407 while (pae
!= NULL
) {
2408 if (pae
->ae_arg
!= NULL
) {
2409 (void) printf("\t%s\n",
2415 * identify whether wepkey is set
2418 print_wepkey_info(p_section
->section_id
, NULL
);
2421 (void) fprintf(stderr
,
2422 gettext("%s: showprofile : "
2423 "no such profile: '%s'\n"),
2424 gExecName
, argv
[i
]);
2431 * find_ae: Find an ae by its contents, return its pointer.
2434 find_ae(aelist_t
*plist
, const char *arg
)
2440 if ((arg
== NULL
) || (plist
== NULL
)) {
2441 PRTDBG(("find_ae: arg= NULL or plist=NULL\n"));
2444 PRTDBG(("find_ae(0x%x, \"%s\")\n", plist
, arg
));
2445 param
= safe_strdup(arg
);
2446 pnext
= strchr(param
, '=');
2447 if (pnext
!= NULL
) {
2450 PRTDBG(("find_ae: param = \"%s\"\n", param
));
2455 pae
= plist
->ael_head
;
2456 while (pae
!= NULL
) {
2457 if ((pae
->ae_arg
!= NULL
) &&
2458 (strncmp(pae
->ae_arg
, param
, strlen(param
)) == 0)) {
2459 PRTDBG(("find_ae: param = \"%s\"\n", param
));
2470 * update_aelist: Update an aelist by arg, for example:
2471 * there are an item with content"essid=ap7-2",
2472 * update_aelist(0x..., "essid=myssid2") will update it as "essid=myssid2"
2475 update_aelist(aelist_t
*plist
, const char *arg
)
2479 assert((arg
!= NULL
)&&(plist
!= NULL
));
2480 PRTDBG(("update_aelist(0x%x, \"%s\")\n", plist
, arg
));
2481 pae
= find_ae(plist
, arg
);
2486 pae
->ae_arg
= safe_strdup(arg
);
2491 * do_deletepf: delete a profile in configration files.
2495 do_deletepf(int fd
, int argc
, char **argv
)
2500 section_t
*p_section
= NULL
, *p_sectionbak
= NULL
;
2501 aelist_t
*plist
= NULL
;
2503 PRTDBG(("do_deletepf(%d, \"%s\")\n", argc
, argv
));
2506 exit(WIFI_IMPROPER_USE
);
2510 * if a "all" is inputted, all the profiles will be deleted.
2512 if (strcasecmp(argv
[0], "all") == 0) {
2513 p_section
= gp_config_file
->section_head
;
2514 while ((p_section
!= NULL
) &&
2515 ((plist
= p_section
->list
) != NULL
)) {
2516 if (plist
->type
== PROFILE
) {
2517 p_sectionbak
= p_section
->section_next
;
2518 section_id
= safe_strdup(p_section
->section_id
);
2519 (void) del_section(gp_config_file
, section_id
);
2520 (void) del_section(gp_wepkey_file
, section_id
);
2522 * remove the '[]' of the [section_id]
2524 prefer
= section_id
+ 1;
2525 *(prefer
+ strlen(section_id
) - 2) = '\0';
2526 (void) del_prefer(gp_config_file
, prefer
,
2529 p_section
= p_sectionbak
;
2532 p_section
= p_section
->section_next
;
2536 if (gp_config_file
!= NULL
) {
2537 for (i
= 0; i
< argc
; i
++) {
2538 section_id
= append_pa(argv
[i
]);
2539 if (del_section(gp_config_file
, section_id
)
2541 if (del_section(gp_wepkey_file
, section_id
)
2543 (void) del_prefer(gp_config_file
,
2548 (void) fprintf(stderr
,
2549 gettext("%s: deleteprofile"
2550 ": no such profile: '%s'\n"),
2551 gExecName
, argv
[i
]);
2556 (void) del_prefer(gp_config_file
, argv
[i
], B_FALSE
);
2557 (void) del_section(gp_wepkey_file
, section_id
);
2565 * do_history: Print the list in {history} section.
2569 do_history(int fd
, int argc
, char **argv
)
2571 section_t
*p_section
= NULL
;
2572 aelist_t
*plist
= NULL
;
2574 char *param
, *param_bak
, *pcomma
;
2575 uint32_t maxessidlen
= 0, ulen
;
2576 char format
[256], *ntstr
;
2577 uint32_t nt
= 0, cnt
= 0;
2581 PRTDBG(("do_history(%d, 0x%x)\n", argc
, argv
));
2583 (void) fprintf(stderr
, gettext("%s: trailing useless tokens "
2584 "after 'history'\n"), gExecName
);
2586 p_section
= find_section(gp_config_file
, WIFI_HISTORY
);
2587 if (p_section
== NULL
) {
2588 PRTDBG(("no history section\n"));
2591 plist
= p_section
->list
;
2594 * If history section is empty, directly return.
2599 * construct the output format in terms of the
2600 * maxmium essid length
2603 pae
= plist
->ael_head
;
2604 while (pae
!= NULL
) {
2605 if (pae
->ae_arg
!= NULL
) {
2606 param
= safe_strdup(pae
->ae_arg
);
2607 pcomma
= strchr(param
, ',');
2608 if (pcomma
== NULL
) {
2609 (void) fprintf(stderr
,
2610 gettext("%s: history : "
2611 "data format error\n"),
2617 ulen
= strlen(param
);
2618 maxessidlen
= (maxessidlen
> ulen
2619 ? maxessidlen
:ulen
);
2624 if ((nt
= (maxessidlen
/ 8 + 1)) > 4)
2626 len
= snprintf(format
, sizeof (format
), gettext("essid"));
2627 ntstr
= construct_format(nt
);
2628 assert((ntstr
!= NULL
) && (strlen(ntstr
) <= 4));
2629 len
+= snprintf(format
+ len
, sizeof (format
) - len
, "%s", ntstr
);
2630 len
+= snprintf(format
+ len
, sizeof (format
) - len
,
2631 gettext("bssid\t\t encryption\tlast seen\n"));
2633 if ((len
<= 0) || (len
> sizeof (format
) - 1)) {
2634 (void) printf(gettext("essid\t\t\t\tbssid\t\t encryption"
2637 (void) printf("%s", format
);
2640 * output the contents of the history section.
2642 pae
= plist
->ael_head
;
2643 while (pae
!= NULL
) {
2644 if (pae
->ae_arg
!= NULL
) {
2645 param
= safe_strdup(pae
->ae_arg
);
2647 if ((pcomma
= strchr(param
, ',')) != NULL
) {
2649 cnt
= nt
- (min((strlen(param
)/8 + 1), 4) - 1);
2650 ntstr
= construct_format(cnt
);
2651 assert(ntstr
!= NULL
);
2653 (void) printf("%s%s", param
, ntstr
);
2657 if ((pcomma
= strchr(param
, ',')) != NULL
) {
2660 (void) printf("%s ", param
);
2663 if ((pcomma
= strchr(param
, ',')) != NULL
) {
2666 (void) printf("%s\t\t", param
);
2669 /* display time stamp */
2670 cltime
= (time_t)atol(param
);
2671 (void) printf("%s", ctime(&cltime
));
2681 * do_lsprefer: Print the list in {preferrence} section
2685 do_lsprefer(int fd
, int argc
, char **argv
)
2688 section_t
*p_section
= NULL
;
2689 aelist_t
*plist
= NULL
;
2693 PRTDBG(("do_lsprefer(%d, 0x%x)\n", argc
, argv
));
2695 (void) fprintf(stderr
, gettext("%s: trailing useless tokens "
2696 "after 'listprefer'\n"), gExecName
);
2698 p_section
= find_section(gp_config_file
, WIFI_PREFER
);
2699 if (p_section
!= NULL
) {
2700 plist
= p_section
->list
;
2701 if (plist
!= NULL
) {
2703 pae
= plist
->ael_head
;
2704 while (pae
!= NULL
) {
2705 if (pae
->ae_arg
!= NULL
) {
2706 pbuf
= append_pa(pae
->ae_arg
);
2707 (void) printf("%d\t%s\n", ++i
, pbuf
);
2714 PRTDBG(("no preference section\n"));
2720 * do_rmprefer: Remove an item in {preferrence} list
2724 do_rmprefer(int fd
, int argc
, char **argv
)
2727 section_t
*p_section
= NULL
;
2728 aelist_t
*plist
= NULL
;
2731 PRTDBG(("do_rmprefer(%d, 0x%x)\n", argc
, argv
));
2734 exit(WIFI_IMPROPER_USE
);
2738 * if a "all" is inputted, all the items in the preference
2739 * list will be deleted.
2741 if (strcasecmp(argv
[0], "all") == 0) {
2742 p_section
= find_section(gp_config_file
, WIFI_PREFER
);
2743 if (p_section
!= NULL
)
2744 plist
= p_section
->list
;
2746 if ((p_section
== NULL
) || (plist
== NULL
))
2748 pae
= plist
->ael_head
;
2749 while (pae
!= NULL
) {
2753 plist
->ael_head
= plist
->ael_tail
= NULL
;
2754 plist
->ael_argc
= 0;
2755 } else if (gp_config_file
!= NULL
) {
2756 for (i
= 0; i
< argc
; i
++) {
2757 if (del_prefer(gp_config_file
, argv
[i
], B_TRUE
)
2767 is_prefer_rank_valid(const char *pbuf
)
2770 boolean_t ret
= B_FALSE
;
2772 for (i
= 0; i
< strlen(pbuf
); i
++) {
2773 if (isdigit(pbuf
[i
]) == 0) {
2779 if ((i
>= 1) && (i
<= MAX_PREFERENCE_NUM
))
2786 * do_setprefer: Set network preferrence
2790 do_setprefer(int fd
, int argc
, char **argv
)
2794 PRTDBG(("do_setprefer(%d, 0x%x)\n", argc
, argv
));
2797 exit(WIFI_IMPROPER_USE
);
2802 if (is_prefer_rank_valid(argv
[1]) == B_FALSE
) {
2803 (void) fprintf(stderr
, gettext("%s: preference rank "
2804 "should be an integer within 1-10\n"), gExecName
);
2807 rank
= atoi(argv
[1]);
2809 return (set_prefer(gp_config_file
, argv
[0], rank
));
2813 is_wepkeyindex_valid(const char *pbuf
)
2816 boolean_t ret
= B_FALSE
;
2818 for (i
= 0; i
< strlen(pbuf
); i
++) {
2819 if (isdigit(pbuf
[i
]) == 0) {
2825 if ((i
>= 1) && (i
<= MAX_NWEPKEYS
))
2832 is_channel_valid(const char *pbuf
)
2835 boolean_t ret
= B_FALSE
;
2837 for (i
= 0; i
< strlen(pbuf
); i
++) {
2838 if (isdigit(pbuf
[i
]) == 0) {
2844 if ((i
>= 0) && (i
<= MAX_CHANNEL_NUM
))
2851 is_wepkey_valid(const char *pbuf
, uint32_t length
)
2854 boolean_t ret
= B_FALSE
;
2859 for (i
= 0; i
< length
; i
++) {
2860 if (isxdigit(pbuf
[i
]) == 0) {
2876 if (ret
== B_FALSE
) {
2877 (void) fprintf(stderr
, gettext("%s: "
2878 "wepkey should be:\n"
2879 "\t 40bits: 5 char or 10 hex digits.\n"
2880 "\t 128bits: 13 char or 26 hex digits.\n"),
2887 * get_valid_wepkey: get an valid wepkey from stdin
2895 struct termios stored_settings
;
2896 struct termios new_settings
;
2898 PRTDBG(("get_valid_wepkey()\n"));
2899 buf
= safe_calloc(sizeof (char), MAX_KEY_LENGTH
+ 2);
2901 * Because we need to get single char from terminal, so we need to
2902 * disable canonical mode and set buffer size to 1 tyte. And because
2903 * wepkey should not be see by others, so we disable echo too.
2905 (void) fflush(stdin
);
2906 (void) tcgetattr(0, &stored_settings
);
2907 new_settings
= stored_settings
;
2908 new_settings
.c_lflag
&= (~ICANON
);
2909 new_settings
.c_lflag
&= (~ECHO
);
2910 new_settings
.c_cc
[VTIME
] = 0;
2911 new_settings
.c_cc
[VMIN
] = 1;
2912 /* Set new terminal attributes */
2913 (void) tcsetattr(0, TCSANOW
, &new_settings
);
2914 while (((buf
[i
++] = getchar()) != '\n') && (i
< MAX_KEY_LENGTH
+ 1)) {
2915 (void) putchar('*');
2917 (void) putchar('\n');
2918 /* Restore terminal attributes */
2919 (void) tcsetattr(0, TCSANOW
, &stored_settings
);
2920 (void) fflush(stdin
);
2922 if (buf
[--i
] != '\n') {
2923 (void) fprintf(stderr
, gettext("%s: wepkey length "
2924 "exceeds 26 hex digits\n"), gExecName
);
2928 /* Replace last char '\n' with '\0' */
2930 length
= (uint8_t)i
;
2931 return ((is_wepkey_valid(buf
, length
) == B_TRUE
)?
2936 * do_set_wepkey: Set parameters in wepkey, and call ioctl
2939 do_set_wepkey(int fd
, const char *pbuf
)
2945 const char *wepkey
= NULL
;
2946 char key
[MAX_KEY_LENGTH
] = {0};
2947 unsigned int keytmp
;
2948 wl_wep_key_tab_t wepkey_tab
;
2950 PRTDBG(("do_set_wepkey(%d, \"%s\")\n", fd
, pbuf
));
2951 if (!check_authority(AUTH_WEP
)) {
2952 exit(WIFI_FATAL_ERR
);
2954 id
= pbuf
[strlen("wepkeyn") - 1] - '0';
2955 wepkey
= get_value(pbuf
);
2956 length
= strlen(wepkey
);
2960 for (i
= 0; i
< length
/ 2; i
++) {
2961 (void) sscanf(wepkey
+ i
* 2, "%2x", &keytmp
);
2962 key
[i
] = (char)keytmp
;
2968 (void) strlcpy(key
, wepkey
, MAX_KEY_LENGTH
);
2972 PRTDBG(("do_set_wepkey: error pbuf size\n"));
2973 (void) fprintf(stderr
, gettext("%s: "
2974 "wepkey should be:\n"
2975 "\t 40bits: 5 char or 10 hex digits.\n"
2976 "\t 128bits: 13 char or 26 hex digits.\n"),
2978 exit(WIFI_FATAL_ERR
);
2981 (void) memset(wepkey_tab
, 0, sizeof (wepkey_tab
));
2982 for (i
= 0; i
< MAX_NWEPKEYS
; i
++) {
2983 wepkey_tab
[i
].wl_wep_operation
= WL_NUL
;
2986 if (id
> 0 && id
<= MAX_NWEPKEYS
) {
2987 wepkey_tab
[id
-1].wl_wep_operation
= WL_ADD
;
2988 wepkey_tab
[id
-1].wl_wep_length
= len
;
2989 (void) memcpy(wepkey_tab
[id
-1].wl_wep_key
, key
, len
);
2991 (void) fprintf(stderr
, gettext("%s: wepkeyindex "
2992 "should be an integer within the range 1-4\n"), gExecName
);
2993 exit(WIFI_FATAL_ERR
);
2995 (void) memmove(gbuf
->wldp_buf
, &wepkey_tab
, sizeof (wl_wep_key_tab_t
));
2996 return (call_ioctl(fd
, WLAN_SET_PARAM
, WL_WEP_KEY_TAB
,
2997 sizeof (wl_wep_key_tab_t
)));
3001 * get the committed wepkey. the return form is like wepkey1=*****;
3005 get_commit_key(int fd
, int argc
, char **argv
)
3009 char *wepkey
= NULL
;
3010 char *wepkey_confirm
= NULL
;
3013 key
= atoi(argv
[0]);
3014 if (key
<= 0 || key
> MAX_NWEPKEYS
) {
3015 (void) fprintf(stderr
, gettext("%s: wepkeyindex "
3016 "should be an integer within the range 1-4\n"), gExecName
);
3019 (void) printf(gettext("input wepkey%d:"), key
);
3020 wepkey
= get_valid_wepkey();
3021 if (wepkey
== NULL
) {
3024 (void) printf(gettext("confirm wepkey%d:"), key
);
3025 wepkey_confirm
= get_valid_wepkey();
3026 if (wepkey_confirm
== NULL
) {
3030 if (strcmp(wepkey
, wepkey_confirm
) != 0) {
3032 free(wepkey_confirm
);
3033 (void) fprintf(stderr
,
3034 gettext("%s: wepkey: "
3035 "two inputs are not identical\n"), gExecName
);
3038 free(wepkey_confirm
); /* wepkey_confirm is no longer used */
3040 len
= MAX_KEY_LENGTH
+ strlen("wepkey1=\n") + 1;
3041 pbuf
= safe_malloc(len
);
3042 safe_snprintf(pbuf
, len
, "%s%d=%s", "wepkey", key
, wepkey
);
3044 free(wepkey
); /* wepkey is no longer used */
3051 * do_wepkey: Get input from user, call do_set_wepkey
3055 do_wepkey(int fd
, int argc
, char **argv
)
3059 PRTDBG(("do_wepkey(%d, 0x%x)\n", argc
, argv
));
3063 exit(WIFI_IMPROPER_USE
);
3066 (void) fprintf(stderr
, gettext("%s: trailing useless tokens "
3067 "after 'setwepkey'\n"), gExecName
);
3069 pbuf
= get_commit_key(fd
, argc
, argv
);
3070 if ((pbuf
!= NULL
) && (do_set_wepkey(fd
, pbuf
) == B_TRUE
)) {
3080 do_setprofwepkey(int fd
, int argc
, char **argv
)
3083 char *section_id
= NULL
;
3084 section_t
*p_section
= NULL
;
3085 aelist_t
*plist
= NULL
;
3087 PRTDBG(("do_setprofwepkey(%d, 0x%x)\n", argc
, argv
));
3090 exit(WIFI_IMPROPER_USE
);
3093 (void) fprintf(stderr
, gettext("%s: trailing useless tokens "
3094 "after 'setprofwepkey'\n"), gExecName
);
3097 section_id
= append_pa(argv
[0]);
3098 p_section
= find_section(gp_wepkey_file
, section_id
);
3100 if (p_section
== NULL
) {
3101 (void) fprintf(stderr
, gettext("%s: "
3102 "no such profile: '%s'\n"),
3103 gExecName
, argv
[0]);
3109 pbuf
= get_commit_key(fd
, argc
, argv
);
3112 plist
= p_section
->list
;
3113 update_aelist(plist
, pbuf
);
3119 * do_wlanlist: Scan for wlanlist
3123 do_wlanlist(int fd
, int argc
, char **argv
)
3125 PRTDBG(("do_wlanlist(%d, 0x%x)\n", argc
, argv
));
3128 (void) fprintf(stderr
, gettext("%s: trailing useless tokens "
3129 "after 'scan'\n"), gExecName
);
3131 if (call_ioctl(fd
, WLAN_COMMAND
, WL_SCAN
, 0) == B_FALSE
) {
3132 (void) fprintf(stderr
, gettext("%s: failed to scan\n"),
3136 if (do_get_wlanlist(fd
) == B_TRUE
) {
3137 print_gbuf(WLANLIST
);
3143 * do_showstatus: show the basic status of the interface, including
3144 * linkstauts, essid, encryption and signal strength.
3148 do_showstatus(int fd
, int argc
, char **argv
)
3151 char *active_profile
= NULL
;
3153 PRTDBG(("do_showstatus(%d, 0x%x)\n", argc
, argv
));
3157 (void) fprintf(stderr
, gettext("%s: trailing useless tokens "
3158 "after 'showstatus'\n"), gExecName
);
3160 if (do_get_linkstatus(fd
) == B_TRUE
) {
3161 print_gbuf(LINKSTATUS
);
3162 if (*(wl_linkstatus_t
*)(gbuf
->wldp_buf
) == WL_NOTCONNECTED
) {
3166 active_profile
= find_active_profile(fd
);
3167 (void) printf("\tactive profile: %s\n",
3168 active_profile
? active_profile
: "none");
3169 if (do_get_essid(fd
) == B_TRUE
) {
3172 if (do_get_bssid(fd
) == B_TRUE
) {
3175 if (do_get_encryption(fd
) == B_TRUE
) {
3176 print_gbuf(ENCRYPTION
);
3178 if (do_get_signal(fd
) == B_TRUE
) {
3179 signal
= *(wl_rssi_t
*)(gbuf
->wldp_buf
);
3181 (void) printf("\tsignal strength: weak(%d)\n",
3183 } else if ((signal
>= 4) && (signal
<= 11)) {
3184 (void) printf("\tsignal strength: medium(%d)\n",
3187 (void) printf("\tsignal strength: strong(%d)\n",
3197 * do_restoredef: Ask driver for loading default parameters
3201 do_restoredef(int fd
, int argc
, char **argv
)
3203 PRTDBG(("do_restoredef(%d, 0x%x)\n", argc
, argv
));
3207 (void) fprintf(stderr
, gettext("%s: trailing useless tokens "
3208 "after 'restoredef'\n"), gExecName
);
3210 record_active_profile(NULL
, RECORD_DEL
);
3211 if (call_ioctl(fd
, WLAN_COMMAND
, WL_LOAD_DEFAULTS
, 0) == B_FALSE
) {
3219 * do_disconnect: disconnect from the current connectted network
3223 do_disconnect(int fd
, int argc
, char **argv
)
3225 PRTDBG(("do_disconnect(%d, 0x%x)\n", argc
, argv
));
3229 (void) fprintf(stderr
, gettext("%s: trailing useless tokens "
3230 "after 'disconnect'\n"), gExecName
);
3232 record_active_profile(NULL
, RECORD_DEL
);
3233 if (call_ioctl(fd
, WLAN_COMMAND
, WL_DISASSOCIATE
, 0) == B_FALSE
) {
3241 do_set_essid(int fd
, const char *arg
)
3245 PRTDBG(("do_set_essid(%d, \"%s\")\n", fd
, arg
));
3248 * a trick here: clean the active_profile flag
3249 * in section{active_profile}
3251 record_active_profile(NULL
, RECORD_DEL
);
3253 (void) memset(&essid
, 0x0, sizeof (essid
));
3255 if (arg
== NULL
|| strcmp(arg
, "") == 0) {
3256 essid
.wl_essid_length
= 0;
3257 essid
.wl_essid_essid
[0] = '\0';
3259 essid
.wl_essid_length
= strlen(arg
);
3260 if (essid
.wl_essid_length
> MAX_ESSID_LENGTH
- 1) {
3261 (void) fprintf(stderr
, gettext("%s: "
3262 "essid exceeds 32 bytes\n"), gExecName
);
3263 exit(WIFI_FATAL_ERR
);
3265 (void) strcpy(essid
.wl_essid_essid
, arg
);
3267 (void) memmove(gbuf
->wldp_buf
, &essid
, sizeof (wl_essid_t
));
3268 return (call_ioctl(fd
, WLAN_SET_PARAM
, WL_ESSID
, sizeof (wl_essid_t
)));
3272 do_set_bsstype(int fd
, const char *arg
)
3274 wl_bss_type_t bsstype
;
3276 assert(arg
!= NULL
);
3278 PRTDBG(("do_set_bsstype(%d, \"%s\")\n", fd
, arg
));
3280 (void) memset(&bsstype
, 0xff, sizeof (bsstype
));
3282 if ((strcasecmp(arg
, "BSS") == 0) ||
3283 (strcasecmp(arg
, "AP") == 0) ||
3284 (strcasecmp(arg
, "INFRASTRUCTURE") == 0)) {
3285 bsstype
= WL_BSS_BSS
;
3286 } else if ((strcasecmp(arg
, "IBSS") == 0) ||
3287 (strcasecmp(arg
, "AD-HOC") == 0)) {
3288 bsstype
= WL_BSS_IBSS
;
3289 } else if (strcasecmp(arg
, "AUTO") == 0) {
3290 bsstype
= WL_BSS_ANY
;
3292 (void) fprintf(stderr
, gettext("%s: bsstype: "
3293 "bss(ap,infrastructure) ibss(ad-hoc) or auto\n"),
3295 exit(WIFI_FATAL_ERR
);
3298 (void) memmove(gbuf
->wldp_buf
, &bsstype
, sizeof (wl_bss_type_t
));
3299 return (call_ioctl(fd
, WLAN_SET_PARAM
, WL_BSS_TYPE
,
3300 sizeof (wl_bss_type_t
)));
3304 do_set_createibss(int fd
, const char *arg
)
3306 wl_create_ibss_t create_ibss
;
3308 assert(arg
!= NULL
);
3310 PRTDBG(("do_set_createibss(%d, \"%s\")\n", fd
, arg
));
3312 (void) memset(&create_ibss
, 0x0, sizeof (create_ibss
));
3314 if (strcasecmp(arg
, "YES") == 0) {
3315 create_ibss
= B_TRUE
;
3316 } else if (strcasecmp(arg
, "NO") == 0) {
3317 create_ibss
= B_FALSE
;
3319 (void) fprintf(stderr
, gettext("%s: "
3320 "createibss: yes or no\n"), gExecName
);
3321 exit(WIFI_FATAL_ERR
);
3324 (void) memmove(gbuf
->wldp_buf
, &create_ibss
,
3325 sizeof (wl_create_ibss_t
));
3326 return (call_ioctl(fd
, WLAN_SET_PARAM
, WL_CREATE_IBSS
,
3327 sizeof (wl_create_ibss_t
)));
3331 do_set_channel(int fd
, const char *arg
)
3333 wl_phy_conf_t phy_conf
;
3335 assert(arg
!= NULL
);
3336 PRTDBG(("do_set_channel(%d, \"%s\")\n", fd
, arg
));
3338 (void) memset(&phy_conf
, 0xff, sizeof (phy_conf
));
3340 if (is_channel_valid(arg
) == B_FALSE
) {
3341 (void) fprintf(stderr
, gettext("%s: channel No. "
3345 "\t802.11g: 1-14\n"), gExecName
);
3346 exit(WIFI_FATAL_ERR
);
3348 phy_conf
.wl_phy_dsss_conf
.wl_dsss_channel
= atoi(arg
);
3349 PRTDBG(("channel=%d\n", phy_conf
.wl_phy_dsss_conf
.wl_dsss_channel
));
3351 (void) memmove(gbuf
->wldp_buf
, &phy_conf
, sizeof (wl_phy_conf_t
));
3352 return (call_ioctl(fd
, WLAN_SET_PARAM
, WL_PHY_CONFIG
,
3353 sizeof (wl_phy_conf_t
)));
3356 * is_rates_support: Querying driver about supported rates.
3359 is_rates_support(int fd
, int num
, uint8_t *rates
)
3365 assert((rates
!= NULL
)&&(num
!= 0));
3366 PRTDBG(("is_rates_support(%d, %d, 0x%x)\n", fd
, num
, rates
));
3368 if (call_ioctl(fd
, WLAN_GET_PARAM
, WL_SUPPORTED_RATES
, 0)
3370 rates_num
= ((wl_rates_t
*)(gbuf
->wldp_buf
))->wl_rates_num
;
3372 for (i
= 0; i
< num
; i
++) {
3373 PRTDBG(("rates[%d] = %d\n", i
, rates
[i
]));
3374 for (j
= 0; j
< rates_num
; j
++) {
3375 value
= ((wl_rates_t
*)gbuf
->wldp_buf
)
3376 ->wl_rates_rates
[j
];
3377 PRTDBG(("supported rates[%d]=%d\n", j
, value
));
3378 if (value
== rates
[i
]) {
3382 if (j
== rates_num
) {
3383 if (rates
[i
] == 11) {
3384 (void) fprintf(stderr
,
3386 "rate 5.5M is not supported\n"),
3389 (void) fprintf(stderr
,
3391 "rate %dM is not supported\n"),
3392 gExecName
, rates
[i
]/2);
3406 rates_convert(const char *rates
)
3411 for (i
= 0; i
< WIFI_RATES_NUM
; i
++) {
3412 if (strcmp(rates
, wifi_rates_s
[i
].rates_s
) == 0) {
3413 ret
= wifi_rates_s
[i
].rates_i
;
3417 if (i
== WIFI_RATES_NUM
) {
3418 (void) fprintf(stderr
, gettext("%s: "
3419 "invalid rates '%s'\n"), gExecName
, rates
);
3420 exit(WIFI_FATAL_ERR
);
3426 * get_rates: convert string value arg into uint8_t array,
3427 * array length will be save into *len[i].
3429 * arg = "1,2,5.5,11"
3430 * then after call, rates[] = {2,4,11,22} will be returned.
3431 * and *len will equal to 4
3434 get_rates(const char *arg
, uint32_t *len
)
3437 uint8_t *rates
= NULL
;
3443 assert(arg
!= NULL
);
3445 if (strlen(arg
) == 0) {
3446 PRTDBG(("get_rates: empty rates string\n"));
3449 PRTDBG(("get_rates(\"%s\", 0x%x)\n", arg
, len
));
3450 pstart
= safe_strdup(arg
);
3451 pstart_bak
= pstart
;
3452 while ((pnext
= strchr(pstart
, ',')) != NULL
) {
3457 rates
= safe_calloc(sizeof (uint8_t), i
);
3459 pstart
= pstart_bak
;
3460 if ((token
= strtok(pstart
, ",")) != NULL
) {
3461 PRTDBG(("rates[0]: %s\n", token
));
3462 rates
[0] = rates_convert(token
);
3464 while ((token
= strtok(NULL
, ",")) != NULL
) {
3465 PRTDBG(("rates[%d]: %s\n", i
, token
));
3466 rates
[i
++] = rates_convert(token
);
3470 for (i
= 0; i
< *len
; i
++) {
3471 for (j
= 0; j
< i
; j
++)
3472 if (rates
[j
] == rates
[i
]) {
3473 (void) fprintf(stderr
,
3474 gettext("%s: rates duplicated\n"),
3485 do_set_rates(int fd
, const char *arg
)
3491 assert(arg
!= NULL
);
3493 PRTDBG(("do_set_rates(%d, \"%s\")\n", fd
, arg
));
3495 rates
= get_rates(arg
, &num
);
3496 if ((rates
== NULL
) ||
3497 is_rates_support(fd
, num
, rates
) == B_FALSE
) {
3498 exit(WIFI_FATAL_ERR
);
3501 ((wl_rates_t
*)(gbuf
->wldp_buf
))->wl_rates_num
= num
;
3502 for (i
= 0; i
< num
; i
++) {
3503 ((wl_rates_t
*)gbuf
->wldp_buf
)->wl_rates_rates
[i
]
3507 return (call_ioctl(fd
, WLAN_SET_PARAM
, WL_DESIRED_RATES
,
3508 offsetof(wl_rates_t
, wl_rates_rates
) +
3509 num
*sizeof (char)));
3513 do_set_powermode(int fd
, const char *arg
)
3515 wl_ps_mode_t ps_mode
;
3517 assert(arg
!= NULL
);
3519 PRTDBG(("do_set_powermode(%d, \"%s\")\n", fd
, arg
));
3521 (void) memset(&ps_mode
, 0xff, sizeof (ps_mode
));
3523 if ((strcasecmp(arg
, "OFF") == 0) ||
3524 (strcasecmp(arg
, "MPS") == 0) ||
3525 (strcasecmp(arg
, "FAST") == 0)) {
3529 ps_mode
.wl_ps_mode
= WL_PM_AM
;
3533 ps_mode
.wl_ps_mode
= WL_PM_MPS
;
3537 ps_mode
.wl_ps_mode
= WL_PM_FAST
;
3543 (void) fprintf(stderr
,
3544 gettext("%s: powermode: off mps or fast\n"), gExecName
);
3545 exit(WIFI_FATAL_ERR
);
3548 (void) memmove(gbuf
->wldp_buf
, &ps_mode
, sizeof (wl_ps_mode_t
));
3549 return (call_ioctl(fd
, WLAN_SET_PARAM
, WL_POWER_MODE
,
3550 sizeof (wl_ps_mode_t
)));
3554 do_set_authmode(int fd
, const char *arg
)
3556 wl_authmode_t auth_mode
;
3558 assert(arg
!= NULL
);
3559 PRTDBG(("do_set_authmode(%d, \"%s\")\n", fd
, arg
));
3561 (void) memset(&auth_mode
, 0xff, sizeof (auth_mode
));
3563 if (strcasecmp(arg
, "OPENSYSTEM") == 0) {
3564 auth_mode
= WL_OPENSYSTEM
;
3565 } else if (strcasecmp(arg
, "SHARED_KEY") == 0) {
3566 auth_mode
= WL_SHAREDKEY
;
3568 (void) fprintf(stderr
,
3569 gettext("%s: authmode: "
3570 "opensystem or shared_key\n"), gExecName
);
3571 exit(WIFI_FATAL_ERR
);
3574 (void) memmove(gbuf
->wldp_buf
, &auth_mode
, sizeof (wl_authmode_t
));
3575 return (call_ioctl(fd
, WLAN_SET_PARAM
, WL_AUTH_MODE
,
3576 sizeof (wl_authmode_t
)));
3580 do_set_encryption(int fd
, const char *arg
)
3582 wl_encryption_t encryption
;
3584 assert(arg
!= NULL
);
3585 PRTDBG(("do_set_encryption(%d, \"%s\")\n", fd
, arg
));
3587 (void) memset(&encryption
, 0xff, sizeof (encryption
));
3589 if (strcasecmp(arg
, "NONE") == 0) {
3590 encryption
= WL_NOENCRYPTION
;
3591 } else if (strcasecmp(arg
, "WEP") == 0) {
3592 encryption
= WL_ENC_WEP
;
3594 (void) fprintf(stderr
, gettext("%s: encryption: "
3595 "none or wep\n"), gExecName
);
3596 exit(WIFI_FATAL_ERR
);
3599 (void) memmove(gbuf
->wldp_buf
, &encryption
, sizeof (wl_encryption_t
));
3600 return (call_ioctl(fd
, WLAN_SET_PARAM
, WL_ENCRYPTION
,
3601 sizeof (wl_encryption_t
)));
3605 do_set_wepkeyid(int fd
, const char *arg
)
3607 wl_wep_key_id_t wep_key_id
;
3609 assert(arg
!= NULL
);
3610 PRTDBG(("do_set_wepkeyid(%d, \"%s\")\n", fd
, arg
));
3612 (void) memset(&wep_key_id
, 0xff, sizeof (wep_key_id
));
3613 if (is_wepkeyindex_valid(arg
) == B_FALSE
) {
3614 (void) fprintf(stderr
, gettext("%s: wepkeyindex "
3615 "should be an integer within the range 1-4\n"), gExecName
);
3616 exit(WIFI_FATAL_ERR
);
3618 wep_key_id
= atoi(arg
) - 1;
3620 (void) memmove(gbuf
->wldp_buf
, &wep_key_id
, sizeof (wl_wep_key_id_t
));
3621 return (call_ioctl(fd
, WLAN_SET_PARAM
, WL_WEP_KEY_ID
,
3622 sizeof (wl_wep_key_id_t
)));
3626 do_set_radioon(int fd
, const char *arg
)
3630 assert(arg
!= NULL
);
3631 PRTDBG(("do_set_radioon(%d, \"%s\")\n", fd
, arg
));
3633 (void) memset(&radio
, 0xff, sizeof (radio
));
3635 if (strcasecmp(arg
, "ON") == 0) {
3637 } else if (strcasecmp(arg
, "OFF") == 0) {
3640 (void) fprintf(stderr
,
3641 gettext("%s: radio : on or off\n"), gExecName
);
3642 exit(WIFI_FATAL_ERR
);
3645 (void) memmove(gbuf
->wldp_buf
, &radio
, sizeof (wl_radio_t
));
3646 return (call_ioctl(fd
, WLAN_SET_PARAM
, WL_RADIO
, sizeof (wl_radio_t
)));
3649 * print_gbuf: After each ioctl system call, gbuf will contain result, gbuf
3650 * contents's format varies from each kind of ioctl system call.
3653 print_gbuf(config_item_t index
)
3660 wl_bss_type_t bsstype
;
3661 wl_create_ibss_t createibss
;
3662 wl_ps_mode_t
*ps_mode
;
3663 wl_authmode_t authmode
;
3664 wl_encryption_t encryption
;
3665 wl_wep_key_id_t wepkeyid
;
3668 wl_ess_conf_t
**p_ess_conf
;
3669 wl_linkstatus_t linkstatus
;
3670 char format
[256], *ntstr
;
3671 uint32_t maxessidlen
= 0, nt
= 0, cnt
= 0;
3675 PRTDBG(("print_gbuf(%d)\n", index
));
3676 assert(gbuf
->wldp_length
< MAX_BUF_LEN
);
3680 (void) printf("\tbssid: ");
3681 (void) memset(bssid
, 0, sizeof (bssid
));
3682 if (memcmp((uint8_t *)gbuf
->wldp_buf
, bssid
, sizeof (bssid
))
3684 (void) printf("none\n");
3687 (void) memset(bssid
, 0xff, sizeof (bssid
));
3688 if (memcmp((uint8_t *)gbuf
->wldp_buf
, bssid
, sizeof (bssid
))
3690 (void) printf("none\n");
3693 for (i
= 0; i
< 5; i
++)
3694 (void) printf("%02x:", ((uint8_t *)gbuf
->wldp_buf
)[i
]);
3695 (void) printf("%02x\n", ((uint8_t *)gbuf
->wldp_buf
)[i
]);
3698 (void) printf("\tessid: %s\n", ((wl_essid_t
*)(gbuf
->wldp_buf
))
3702 bsstype
= *(wl_bss_type_t
*)(gbuf
->wldp_buf
);
3705 (void) printf("\tbsstype: bss(ap, infrastructure)\n");
3708 (void) printf("\tbsstype: ibss(ad-hoc)\n");
3711 (void) printf("\tbsstype: auto\n");
3714 (void) fprintf(stderr
,
3716 "invalid bsstype value\n"), gExecName
);
3720 createibss
= *(wl_create_ibss_t
*)(gbuf
->wldp_buf
);
3721 switch (createibss
) {
3723 (void) printf("\tcreateibss: yes\n");
3726 (void) printf("\tcreateibss: no\n");
3729 (void) fprintf(stderr
,
3731 "invalid createibss value\n"), gExecName
);
3735 subtype
= ((wl_fhss_t
*)(gbuf
->wldp_buf
))->wl_fhss_subtype
;
3742 (void) printf("\tchannel: %d\n", ((wl_fhss_t
*)
3743 (gbuf
->wldp_buf
))->wl_fhss_channel
);
3746 (void) printf("\tchannel: %d\n", ((wl_ofdm_t
*)
3748 ->wl_ofdm_frequency
);
3751 (void) fprintf(stderr
, gettext("%s: "
3752 "invalid subtype\n"), gExecName
);
3757 rates_num
= ((wl_rates_t
*)(gbuf
->wldp_buf
))->wl_rates_num
;
3758 (void) printf("\trates: ");
3759 for (i
= 0; i
< rates_num
; i
++) {
3761 rate
= ((wl_rates_t
*)gbuf
->wldp_buf
)
3762 ->wl_rates_rates
[i
];
3763 if (rate
== WL_RATE_5_5M
)
3764 (void) printf("5.5");
3766 (void) printf("%d", (uint8_t)(rate
/ 2));
3768 if (i
== (rates_num
- 1))
3769 (void) printf("\n");
3775 ps_mode
= (wl_ps_mode_t
*)(gbuf
->wldp_buf
);
3776 switch (ps_mode
->wl_ps_mode
) {
3778 (void) printf("\tpowermode: off\n");
3781 (void) printf("\tpowermode: mps\n");
3784 (void) printf("\tpowermode: fast\n");
3787 (void) fprintf(stderr
,
3789 "invalid powermode value\n"), gExecName
);
3794 authmode
= *(wl_authmode_t
*)(gbuf
->wldp_buf
);
3797 (void) printf("\tauthmode: opensystem\n");
3800 (void) printf("\tauthmode: shared_key\n");
3803 (void) fprintf(stderr
,
3805 "invalid authmode value\n"), gExecName
);
3810 encryption
= *(wl_encryption_t
*)(gbuf
->wldp_buf
);
3811 switch (encryption
) {
3812 case WL_NOENCRYPTION
:
3813 (void) printf("\tencryption: none\n");
3816 (void) printf("\tencryption: wep\n");
3819 (void) fprintf(stderr
,
3821 "invalid encryption value\n"), gExecName
);
3826 wepkeyid
= *(wl_wep_key_id_t
*)(gbuf
->wldp_buf
);
3827 (void) printf("\twepkeyindex: %d\n", wepkeyid
+ 1);
3830 signal
= *(wl_rssi_t
*)(gbuf
->wldp_buf
);
3831 (void) printf("\tsignal: %d\n", signal
);
3834 radioon
= *(wl_radio_t
*)(gbuf
->wldp_buf
);
3837 (void) printf("\tradio: on\n");
3840 (void) printf("\tradio: off\n");
3843 (void) fprintf(stderr
,
3845 "invalid radioon value\n"), gExecName
);
3849 linkstatus
= *(wl_linkstatus_t
*)(gbuf
->wldp_buf
);
3850 switch (linkstatus
) {
3852 (void) printf("\tlinkstatus: connected\n");
3854 case WL_NOTCONNECTED
:
3855 (void) printf("\tlinkstatus: not connected\n");
3858 (void) fprintf(stderr
,
3860 "invalid linkstatus value\n"), gExecName
);
3864 ess_num
= ((wl_ess_list_t
*)(gbuf
->wldp_buf
))->wl_ess_list_num
;
3865 ess_argv
= safe_calloc(sizeof (char *), ess_num
);
3866 p_ess_conf
= safe_calloc(sizeof (wl_ess_conf_t
*), ess_num
);
3867 for (i
= 0; i
< ess_num
; i
++) {
3868 p_ess_conf
[i
] = ((wl_ess_list_t
*)gbuf
->wldp_buf
)
3869 ->wl_ess_list_ess
+ i
;
3870 maxessidlen
= (maxessidlen
>
3871 strlen(p_ess_conf
[i
]
3872 ->wl_ess_conf_essid
.wl_essid_essid
) ?
3874 strlen(p_ess_conf
[i
]
3875 ->wl_ess_conf_essid
.wl_essid_essid
));
3878 * construct the output format.
3880 if ((nt
= (maxessidlen
/ 8 + 1)) > 4)
3882 len
= snprintf(format
, sizeof (format
), gettext("essid"));
3883 ntstr
= construct_format(nt
);
3884 assert(ntstr
!= NULL
);
3885 len
+= snprintf(format
+ len
, sizeof (format
) - len
, "%s",
3887 len
+= snprintf(format
+ len
, sizeof (format
) - len
,
3888 gettext("bssid\t\t type\t\tencryption\tsignallevel\n"));
3890 if ((len
<= 0) || (len
> sizeof (format
) - 1)) {
3891 (void) printf("essid\t\t\t\tbssid\t\t type\t\t"
3892 "encryption\tsignallevel\n");
3894 (void) printf("%s", format
);
3897 for (i
= 0; i
< ess_num
; i
++) {
3898 ess_argv
[i
] = safe_malloc(MAX_SCANBUF_LEN
);
3899 safe_snprintf(ess_argv
[i
], MAX_SCANBUF_LEN
,
3900 "%s%c%02x:%02x:%02x:%02x:%02x:%02x%c%s",
3901 p_ess_conf
[i
]->wl_ess_conf_essid
.wl_essid_essid
,
3903 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[0]),
3904 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[1]),
3905 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[2]),
3906 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[3]),
3907 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[4]),
3908 (uint8_t)(p_ess_conf
[i
]->wl_ess_conf_bssid
[5]), ',',
3909 (p_ess_conf
[i
]->wl_ess_conf_wepenabled
==
3910 B_TRUE
? "wep":"none"));
3911 len
= strlen(p_ess_conf
[i
]->wl_ess_conf_essid
.
3913 cnt
= nt
- (min(len
/8 + 1, 4) - 1);
3914 ntstr
= construct_format(cnt
);
3915 assert(ntstr
!= NULL
);
3916 (void) printf("%s%s", p_ess_conf
[i
]->wl_ess_conf_essid
.
3917 wl_essid_essid
, ntstr
);
3919 for (j
= 0; j
< 5; j
++) {
3920 (void) printf("%02x:", (uint8_t)(p_ess_conf
[i
]
3921 ->wl_ess_conf_bssid
[j
]));
3923 (void) printf("%02x ", (uint8_t)(p_ess_conf
[i
]
3924 ->wl_ess_conf_bssid
[j
]));
3926 if (p_ess_conf
[i
]->wl_ess_conf_bsstype
==
3928 (void) printf("access point");
3930 (void) printf("ad-hoc");
3931 if (p_ess_conf
[i
]->wl_ess_conf_wepenabled
==
3933 (void) printf("\twep\t");
3935 (void) printf("\tnone\t");
3936 (void) printf("\t%d\n", p_ess_conf
[i
]->wl_ess_conf_sl
);
3938 add_to_history(gp_config_file
, ess_num
, ess_argv
);
3940 for (i
= 0; i
< ess_num
; i
++) {
3946 (void) fprintf(stderr
, gettext("%s: "
3947 "invalid parameter type\n"), gExecName
);
3952 * do_get_xxx: will send ioctl to driver, then the driver will fill gbuf
3953 * with related value. gbuf has a format of wldp_t structure.
3956 do_get_bssid(int fd
)
3958 PRTDBG(("do_get_bssid(%d)\n", fd
));
3959 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_BSSID
, 0));
3963 do_get_essid(int fd
)
3965 PRTDBG(("do_get_essid(%d)\n", fd
));
3966 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_ESSID
, 0));
3970 do_get_bsstype(int fd
)
3972 PRTDBG(("do_get_bsstype(%d)\n", fd
));
3973 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_BSS_TYPE
, 0));
3977 do_get_createibss(int fd
)
3979 PRTDBG(("do_get_createibss(%d)\n", fd
));
3980 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_CREATE_IBSS
, 0));
3984 do_get_channel(int fd
)
3986 PRTDBG(("do_get_channel(%d)\n", fd
));
3987 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_PHY_CONFIG
, 0));
3991 do_get_wlanlist(int fd
)
3993 PRTDBG(("do_get_wlanlist(%d)\n", fd
));
3994 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_ESS_LIST
, 0));
3998 do_get_linkstatus(int fd
)
4000 PRTDBG(("do_get_linkstauts(%d)\n", fd
));
4001 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_LINKSTATUS
, 0));
4005 do_get_rates(int fd
)
4007 PRTDBG(("do_get_rates(%d)\n", fd
));
4008 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_DESIRED_RATES
, 0));
4012 do_get_powermode(int fd
)
4014 PRTDBG(("do_get_powermode(%d)\n", fd
));
4015 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_POWER_MODE
, 0));
4019 do_get_authmode(int fd
)
4021 PRTDBG(("do_get_authmode(%d)\n", fd
));
4022 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_AUTH_MODE
, 0));
4026 do_get_encryption(int fd
)
4028 PRTDBG(("do_get_encryption(%d)\n", fd
));
4029 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_ENCRYPTION
, 0));
4033 do_get_wepkeyid(int fd
)
4035 PRTDBG(("do_get_wepkeyid(%d)\n", fd
));
4036 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_WEP_KEY_ID
, 0));
4039 do_get_signal(int fd
)
4041 PRTDBG(("do_get_signal(%d)\n", fd
));
4042 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_RSSI
, 0));
4046 do_get_radioon(int fd
)
4048 PRTDBG(("do_get_radioon(%d)\n", fd
));
4049 return (call_ioctl(fd
, WLAN_GET_PARAM
, WL_RADIO
, 0));
4053 * param has two kinds of forms:
4054 * 'wepkeyn=*****' (when equalflag == B_TRUE),
4055 * 'wepkeyn' (when equalflag == B_FALSE)
4058 param_is_wepkey(char *param
, boolean_t equalflag
)
4060 if ((equalflag
== B_FALSE
) &&
4061 (strcmp(param
, "wepkey1") == 0) ||
4062 (strcmp(param
, "wepkey2") == 0) ||
4063 (strcmp(param
, "wepkey3") == 0) ||
4064 (strcmp(param
, "wepkey4") == 0))
4066 else if ((equalflag
== B_TRUE
) &&
4067 (strncmp(param
, "wepkey1=", strlen("wepkey1="))) == 0 ||
4068 (strncmp(param
, "wepkey2=", strlen("wepkey2="))) == 0 ||
4069 (strncmp(param
, "wepkey3=", strlen("wepkey3="))) == 0 ||
4070 (strncmp(param
, "wepkey4=", strlen("wepkey4="))) == 0)
4077 * update/add items in the profile
4080 items_in_profile(aelist_t
*cplist
, aelist_t
*wplist
, int argc
, char **argv
)
4087 for (i
= 0; i
< argc
; i
++) {
4088 if (param_is_wepkey(argv
[i
], B_TRUE
) == B_TRUE
) {
4089 wepkey
= get_value(argv
[i
]);
4090 if (value_is_valid(WEPKEY
, wepkey
) == B_FALSE
) {
4091 (void) fprintf(stderr
, gettext("%s: "
4092 "invalid value '%s' for parameter "
4093 "'wepkey'\n"), gExecName
, wepkey
);
4096 update_aelist(wplist
, argv
[i
]);
4099 param
= safe_strdup(argv
[i
]);
4100 pequal
= strchr(param
, '=');
4101 if (pequal
== NULL
) {
4102 (void) fprintf(stderr
, gettext("%s: "
4103 "invalid argument '%s', use "
4104 "parameter=value'\n"),
4105 gExecName
, argv
[i
]);
4111 for (j
= 0; j
< N_GS_FUNC
; j
++) {
4112 if (strcmp(param
, do_gs_func
[j
].cmd
) == 0) {
4116 if (j
== N_GS_FUNC
) {
4117 (void) fprintf(stderr
, gettext("%s: "
4118 "unrecognized parameter '%s'\n"),
4123 if (value_is_valid(do_gs_func
[j
].index
, pequal
) ==
4125 (void) fprintf(stderr
, gettext("%s: "
4126 "invalid value '%s' for parameter '%s'\n"),
4127 gExecName
, pequal
, param
);
4131 update_aelist(cplist
, argv
[i
]);
4137 * do_createprofile: Called when create a profile off-line.
4141 do_createprofile(int fd
, int argc
, char **argv
)
4146 const char *profilename
;
4147 aelist_t
*plist_config
= NULL
, *plist_wepkey
= NULL
;
4149 PRTDBG(("do_createprofile(%d, 0x%x)\n", argc
, argv
));
4152 exit(WIFI_IMPROPER_USE
);
4155 * When creating a profile, if the profile name is not specified,
4156 * the essid is selected as the profile name. the paramters are
4157 * saved into the section.
4159 if (strchr(argv
[0], '=') == NULL
) {
4160 pfbuf
= safe_strdup(argv
[0]);
4164 for (i
= 0; i
< argc
; i
++) {
4165 if (strncmp(argv
[i
], "essid=", strlen("essid=")) == 0) {
4170 (void) fprintf(stderr
,
4172 "essid required when creating profile\n"),
4176 profilename
= (pfbuf
? pfbuf
: get_value(argv
[i
]));
4177 if (strlen(profilename
) == 0) {
4178 (void) fprintf(stderr
,
4180 "non-empty essid required\n"),
4185 * 'all', '{preference}', '{history}', '{active_profile}'
4186 * and any string with '[' as start and ']' as end should
4187 * not be a profile name
4189 if ((strcasecmp(profilename
, "all") == 0) ||
4190 (strcmp(profilename
, WIFI_HISTORY
) == 0) ||
4191 (strcmp(profilename
, WIFI_PREFER
) == 0) ||
4192 (strcmp(profilename
, WIFI_ACTIVEP
) == 0) ||
4193 ((profilename
[0] == '[') &&
4194 (profilename
[strlen(profilename
) - 1] == ']'))) {
4195 (void) fprintf(stderr
, gettext("%s: "
4196 "'%s' is an invalid profile name\n"),
4197 gExecName
, profilename
);
4200 pbuf
= append_pa(profilename
);
4202 PRTDBG(("do_createprofile: profile_name = %s\n", pbuf
));
4203 if ((find_section(gp_config_file
, pbuf
) != NULL
) ||
4204 find_section(gp_wepkey_file
, pbuf
) != NULL
) {
4205 (void) fprintf(stderr
,
4207 "profile '%s' already exists\n"),
4208 gExecName
, profilename
);
4212 * Save each parameters in the profile.
4214 plist_config
= new_ael(PROFILE
);
4215 new_section(gp_config_file
, plist_config
, pbuf
);
4216 plist_wepkey
= new_ael(PROFILE
);
4217 new_section(gp_wepkey_file
, plist_wepkey
, pbuf
);
4220 return (items_in_profile(plist_config
, plist_wepkey
,
4231 do_setprofparam(int fd
, int argc
, char **argv
)
4234 section_t
*psection_config
= NULL
, *psection_wep
= NULL
;
4235 aelist_t
*plist_config
= NULL
, *plist_wepkey
= NULL
;
4237 PRTDBG(("do_setprofparam(%d, 0x%x)\n", argc
, argv
));
4240 exit(WIFI_IMPROPER_USE
);
4242 pbuf
= append_pa(argv
[0]);
4244 psection_config
= find_section(gp_config_file
, pbuf
);
4245 psection_wep
= find_section(gp_wepkey_file
, pbuf
);
4246 if ((psection_config
== NULL
) || (psection_wep
== NULL
)) {
4247 (void) fprintf(stderr
, gettext("%s: "
4248 "profile '%s' doesn't exist\n"),
4249 gExecName
, argv
[0]);
4255 * modify each parameters in the profile.
4257 plist_config
= psection_config
->list
;
4258 plist_wepkey
= psection_wep
->list
;
4261 return (items_in_profile(plist_config
, plist_wepkey
,
4267 do_getprofparam(int fd
, int argc
, char **argv
)
4271 boolean_t ret
= B_TRUE
;
4272 section_t
*p_section
= NULL
;
4273 aelist_t
*plist
= NULL
;
4277 PRTDBG(("do_getprofparam(%d, 0x%x)\n", argc
, argv
));
4280 exit(WIFI_IMPROPER_USE
);
4282 pbuf
= append_pa(argv
[0]);
4283 p_section
= find_section(gp_config_file
, pbuf
);
4284 if (p_section
== NULL
) {
4285 (void) fprintf(stderr
, gettext("%s: "
4286 "profile '%s' doesn't exist\n"),
4287 gExecName
, argv
[0]);
4294 plist
= p_section
->list
;
4295 assert(plist
!= NULL
);
4297 * If no specific parameter typed, we print out all parameters
4300 pae
= plist
->ael_head
;
4301 while (pae
!= NULL
) {
4302 if (pae
->ae_arg
!= NULL
) {
4303 (void) printf("\t%s\n", pae
->ae_arg
);
4307 print_wepkey_info(p_section
->section_id
, NULL
);
4313 * Match function with do_gs_func[] table, and print its result
4315 for (i
= 0; i
< argc
; i
++) {
4317 for (j
= 0; j
< N_GS_FUNC
; j
++) {
4318 if (strcmp(argv
[i
], do_gs_func
[j
].cmd
) == 0) {
4321 if (param_is_wepkey(argv
[i
], B_FALSE
) == B_TRUE
) {
4323 print_wepkey_info(p_section
->section_id
,
4329 if (j
== N_GS_FUNC
) {
4330 (void) fprintf(stderr
,
4331 gettext("wificonifg: unrecognized parameter: "
4337 pae
= plist
->ael_head
;
4338 while ((pae
!= NULL
) && (!flag
)) {
4339 if ((pae
->ae_arg
!= NULL
) &&
4340 (strncmp(pae
->ae_arg
, argv
[i
],
4341 strlen(argv
[i
])) == 0)) {
4342 (void) printf("\t%s\n", pae
->ae_arg
);
4348 (void) fprintf(stderr
, gettext("%s: "
4349 "parameter '%s' has not been set in profile %s\n"),
4350 gExecName
, argv
[i
], pbuf
);
4361 * Verify whether the value in the parameter=value pair is valid or not.
4362 * For the channel, since we donot know what kind of wifi card(a,b,or g)
4363 * is in the system, so we just leave to verify the validity of the value
4364 * when the value is set to the card.
4365 * The same goes for the rates.
4368 value_is_valid(config_item_t item
, const char *value
)
4374 assert(value
!= NULL
);
4377 if (strlen(value
) > 32)
4383 if ((strcasecmp(value
, "bss") == 0) ||
4384 (strcasecmp(value
, "ap") == 0) ||
4385 (strcasecmp(value
, "infrastructure") == 0) ||
4386 (strcasecmp(value
, "ibss") == 0) ||
4387 (strcasecmp(value
, "ad-hoc") == 0) ||
4388 (strcasecmp(value
, "auto") == 0))
4394 if ((strcasecmp(value
, "yes") == 0) ||
4395 (strcasecmp(value
, "no") == 0))
4401 if ((strcasecmp(value
, "opensystem") == 0) ||
4402 (strcasecmp(value
, "shared_key") == 0))
4408 if ((strcasecmp(value
, "off") == 0) ||
4409 (strcasecmp(value
, "mps") == 0) ||
4410 (strcasecmp(value
, "fast") == 0))
4416 if ((strcasecmp(value
, "wep") == 0) ||
4417 (strcasecmp(value
, "none") == 0))
4423 if ((strcasecmp(value
, "on") == 0) ||
4424 (strcasecmp(value
, "off") == 0))
4430 ret
= is_wepkeyindex_valid(value
);
4433 ret
= is_wepkey_valid(value
, strlen(value
));
4436 ret
= is_channel_valid(value
);
4439 rates
= get_rates(value
, &num
);
4440 if (rates
== NULL
) {
4456 * do_set: Called when set a parameter, the format should be
4460 do_set(int fd
, int argc
, char **argv
)
4468 PRTDBG(("do_set(%d, 0x%x)\n", argc
, argv
));
4471 (void) do_print_support_params(fd
);
4476 * Set each parameters, if one failed, others behind it will
4479 for (i
= 0; i
< argc
; i
++) {
4481 * Separate param and its value, if the user types "param=",
4482 * then value will be set to "";if the user types "param",
4485 param
= safe_strdup(argv
[i
]);
4486 pequal
= strchr(param
, '=');
4488 if (pequal
!= NULL
) {
4492 (void) fprintf(stderr
,
4493 gettext("%s: invalid setparam argument "
4494 "'%s', use 'parameter=value'\n"),
4495 gExecName
, argv
[i
]);
4500 PRTDBG(("do_set: param = \"%s\", value = \"%s\"\n",
4502 for (j
= 0; j
< N_GS_FUNC
; j
++) {
4504 * Match each parameters with do_gs_func table,
4506 if (strcmp(param
, do_gs_func
[j
].cmd
) == 0)
4508 if (param_is_wepkey(param
, B_FALSE
) == B_TRUE
) {
4514 if (j
== N_GS_FUNC
) {
4515 (void) fprintf(stderr
,
4516 gettext("%s: unrecognized parameter: "
4517 "%s\n"), gExecName
, param
);
4523 if (do_gs_func
[j
].p_do_set_func
== NULL
) {
4524 (void) fprintf(stderr
,
4525 gettext("%s: parameter '%s' is read-only\n"),
4526 gExecName
, do_gs_func
[j
].cmd
);
4531 if (do_gs_func
[j
].p_do_set_func(fd
, value
)
4535 if (gbuf
->wldp_result
!= WL_SUCCESS
) {
4536 (void) fprintf(stderr
,
4538 "failed to set '%s' for "),
4540 print_error(gbuf
->wldp_result
);
4553 do_get(int fd
, int argc
, char **argv
)
4555 int i
= 0, j
= 0, n
= 0;
4556 boolean_t ret
= B_TRUE
;
4558 PRTDBG(("do_get(%d, 0x%x)\n", argc
, argv
));
4561 * If no specific parameter typed, we print out all parameters
4564 for (i
= 0; i
< N_GS_FUNC
; i
++) {
4565 if ((do_gs_func
[i
].p_do_get_func
!= NULL
) &&
4566 (do_gs_func
[i
].p_do_get_func(fd
)
4568 print_gbuf(do_gs_func
[i
].index
);
4572 ret
= n
? B_TRUE
:B_FALSE
;
4576 * Match function with do_gs_func[] table, and print its result
4578 for (i
= 0; i
< argc
; i
++) {
4579 for (j
= 0; j
< N_GS_FUNC
; j
++) {
4580 if (strcmp(argv
[i
], do_gs_func
[j
].cmd
) == 0) {
4583 if (param_is_wepkey(argv
[i
], B_FALSE
) == B_TRUE
) {
4588 if (j
== N_GS_FUNC
) {
4589 (void) fprintf(stderr
,
4590 gettext("wificonifg: unrecognized parameter: "
4595 if (do_gs_func
[j
].p_do_get_func
== NULL
) {
4596 (void) fprintf(stderr
,
4597 gettext("%s: parameter '%s' is write-only\n"),
4598 gExecName
, do_gs_func
[j
].cmd
);
4602 if (do_gs_func
[j
].p_do_get_func(fd
) == B_TRUE
) {
4603 print_gbuf(do_gs_func
[j
].index
);
4606 (void) fprintf(stderr
,
4608 "failed to read parameter '%s' : "),
4609 gExecName
, argv
[i
]);
4610 print_error(gbuf
->wldp_result
);
4619 * Only one wificonfig is running at one time.
4620 * The following wificonfig which tries to be run will return error,
4621 * and the pid of the process will own the filelock will be printed out.
4624 enter_wifi_lock(int *fd
)
4629 fd0
= open(WIFI_LOCKF
, O_CREAT
|O_WRONLY
, 0600);
4631 (void) fprintf(stderr
, gettext("%s: failed to open lockfile"
4632 " '"WIFI_LOCKF
"': %s\n"), gExecName
, strerror(errno
));
4633 exit(WIFI_FATAL_ERR
);
4637 lock
.l_type
= F_WRLCK
;
4638 lock
.l_whence
= SEEK_SET
;
4642 if ((fcntl(fd0
, F_SETLK
, &lock
) == -1) &&
4643 (errno
== EAGAIN
|| errno
== EDEADLK
)) {
4644 if (fcntl(fd0
, F_GETLK
, &lock
) == -1) {
4645 (void) fprintf(stderr
,
4646 gettext("%s: enter_filelock"));
4647 exit(WIFI_FATAL_ERR
);
4649 (void) fprintf(stderr
, gettext("%s:"
4650 "enter_filelock:filelock is owned "
4651 "by 'process %d'\n"), gExecName
, lock
.l_pid
);
4652 return (lock
.l_pid
);
4659 exit_wifi_lock(int fd
)
4663 lock
.l_type
= F_UNLCK
;
4664 lock
.l_whence
= SEEK_SET
;
4667 if (fcntl(fd
, F_SETLK
, &lock
) == -1) {
4668 (void) fprintf(stderr
, gettext("%s: failed to"
4669 " exit_filelock: %s\n"),
4670 gExecName
, strerror(errno
));
4676 main(int argc
, char **argv
)
4680 int c
, iflag
= 0, rflag
= 0, fileonly
= 0, readonly
= 0;
4684 extern char *optarg
;
4686 char interface
[LIFNAMSIZ
];
4687 char file_wifi
[MAX_CONFIG_FILE_LENGTH
];
4688 char file_wifiwepkey
[MAX_CONFIG_FILE_LENGTH
];
4692 PRTDBG(("main(%d, 0x%x)\n", argc
, argv
));
4693 PRTDBG(("uid=%d\n", getuid()));
4694 PRTDBG(("euid=%d\n", geteuid()));
4697 if (wifi_debug
== 1) { /* for debuf purpose only */
4698 (void) printf("Press RETURN to continue...\n");
4702 ret
= WIFI_EXIT_DEF
;
4704 (void) setlocale(LC_ALL
, "");
4705 (void) textdomain(TEXT_DOMAIN
);
4707 gExecName
= argv
[0];
4709 gbuf
= safe_malloc(MAX_BUF_LEN
);
4711 if ((ppriv
= priv_str_to_set("basic", ",", NULL
)) == NULL
) {
4712 PRTDBG(("main: priviledge init error\n"));
4713 (void) fprintf(stderr
, gettext("%s: "
4714 "set priviledge to 'basic' error\n"),
4716 ret
= WIFI_FATAL_ERR
;
4719 (void) priv_addset(ppriv
, PRIV_NET_RAWACCESS
);
4720 (void) priv_addset(ppriv
, PRIV_SYS_NET_CONFIG
);
4721 if (setppriv(PRIV_SET
, PRIV_PERMITTED
, ppriv
) == -1) {
4722 (void) fprintf(stderr
, gettext("%s: "
4723 "set permitted priviledge: %s\n"),
4724 gExecName
, strerror(errno
));
4725 ret
= WIFI_FATAL_ERR
;
4728 if (setppriv(PRIV_SET
, PRIV_LIMIT
, ppriv
) == -1) {
4729 (void) fprintf(stderr
, gettext("%s: "
4730 "set limit priviledge: %s\n"),
4731 gExecName
, strerror(errno
));
4732 ret
= WIFI_FATAL_ERR
;
4735 if (setppriv(PRIV_SET
, PRIV_INHERITABLE
, ppriv
) == -1) {
4736 (void) fprintf(stderr
, gettext("%s: "
4737 "set inherit priviledge: %s\n"),
4738 gExecName
, strerror(errno
));
4739 ret
= WIFI_FATAL_ERR
;
4742 if (setppriv(PRIV_SET
, PRIV_EFFECTIVE
, ppriv
) == -1) {
4743 (void) fprintf(stderr
, gettext("%s: "
4744 "set effective priviledge: %s\n"),
4745 gExecName
, strerror(errno
));
4746 ret
= WIFI_FATAL_ERR
;
4749 priv_freeset(ppriv
);
4751 for (i
= 0; i
< argc
; i
++) {
4752 PRTDBG(("%d\t\t\"%s\"\n", i
, argv
[i
]));
4755 while ((c
= getopt(argc
, argv
, "i:R:")) != EOF
) {
4760 ret
= WIFI_IMPROPER_USE
;
4769 ret
= WIFI_IMPROPER_USE
;
4778 ret
= WIFI_IMPROPER_USE
;
4787 if ((fddev
= open_dev(iname
)) == -1) {
4788 ret
= WIFI_FATAL_ERR
;
4791 if (do_print_support_params(fddev
) ==
4793 ret
= WIFI_EXIT_DEF
;
4795 ret
= WIFI_FATAL_ERR
;
4799 ret
= WIFI_IMPROPER_USE
;
4804 for (i
= 0; i
< N_FUNC
; i
++) {
4805 if (strcmp(argv
[0], do_func
[i
].cmd
) == 0) {
4806 autht
= ((strcmp(argv
[0], "setwepkey") == 0) ||
4807 (strcmp(argv
[0], "setprofwepkey") == 0)) ?
4808 AUTH_WEP
:AUTH_OTHER
;
4809 if (do_func
[i
].b_auth
&&
4810 !check_authority(autht
)) {
4811 ret
= WIFI_FATAL_ERR
;
4814 if (do_func
[i
].b_fileonly
)
4816 if (do_func
[i
].b_readonly
)
4822 (void) fprintf(stderr
, gettext("%s: unrecognized "
4823 "subcommand: %s\n"), gExecName
, argv
[0]);
4825 ret
= WIFI_IMPROPER_USE
;
4828 if ((fileonly
) && (iname
)) {
4830 ret
= WIFI_IMPROPER_USE
;
4833 if ((!fileonly
) && (!iname
)) {
4834 if (search_interface(interface
) != B_TRUE
) {
4835 (void) fprintf(stderr
, gettext("%s: "
4836 "failed to find the default wifi interface;"
4837 " -i option should be used to specify the "
4838 "wifi interface\n"), gExecName
);
4839 ret
= WIFI_FATAL_ERR
;
4845 if ((fddev
= open_dev(iname
)) == -1) {
4846 ret
= WIFI_FATAL_ERR
;
4851 safe_snprintf(file_wifi
, sizeof (file_wifi
),
4852 "%s%s", path
, p_file_wifi
);
4853 safe_snprintf(file_wifiwepkey
, sizeof (file_wifiwepkey
),
4854 "%s%s", path
, p_file_wifiwepkey
);
4856 safe_snprintf(file_wifi
, sizeof (file_wifi
),
4858 safe_snprintf(file_wifiwepkey
, sizeof (file_wifiwepkey
),
4859 "%s", p_file_wifiwepkey
);
4862 * There is an occasion when more than one wificonfig processes
4863 * which attempt to write the <wifi> and <wifiwepkey> files are
4864 * running. We must be able to avoid this.
4865 * We use file lock here to implement this.
4867 if ((!readonly
) && (enter_wifi_lock(&fd
) != getpid())) {
4868 ret
= WIFI_FATAL_ERR
;
4871 gp_config_file
= parse_file(file_wifi
);
4872 if (gp_config_file
== NULL
) {
4873 ret
= WIFI_FATAL_ERR
;
4877 gp_wepkey_file
= parse_file(file_wifiwepkey
);
4878 if (gp_wepkey_file
== NULL
) {
4879 destroy_config(gp_config_file
);
4880 ret
= WIFI_FATAL_ERR
;
4883 if (do_func
[i
].p_do_func(fddev
, argc
-1, argv
+1)
4886 * can not write file when startconfing
4889 if (do_func
[i
].b_readonly
)
4890 ret
= WIFI_EXIT_DEF
;
4891 else if ((fprint_config_file(gp_config_file
,
4892 file_wifi
) != B_TRUE
) ||
4893 (fprint_config_file(gp_wepkey_file
,
4894 file_wifiwepkey
) != B_TRUE
))
4895 ret
= WIFI_FATAL_ERR
;
4897 ret
= WIFI_EXIT_DEF
;
4899 PRTDBG(("Command %s failed\n", argv
[0]));
4900 ret
= WIFI_FATAL_ERR
;
4902 destroy_config(gp_wepkey_file
);
4903 destroy_config(gp_config_file
);
4909 (void) close(fddev
);
4917 wifi_dbgprintf(char *fmt
, ...)
4921 (void) vfprintf(stdout
, fmt
, ap
);