diff options
Diffstat (limited to 'usr/src/cmd/cmd-inet/lib')
-rw-r--r-- | usr/src/cmd/cmd-inet/lib/nwamd/functions.h | 6 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/lib/nwamd/interface.c | 46 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/lib/nwamd/structures.h | 3 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/lib/nwamd/wireless.c | 117 |
4 files changed, 93 insertions, 79 deletions
diff --git a/usr/src/cmd/cmd-inet/lib/nwamd/functions.h b/usr/src/cmd/cmd-inet/lib/nwamd/functions.h index 96f4c50a63..bb88f4d2d9 100644 --- a/usr/src/cmd/cmd-inet/lib/nwamd/functions.h +++ b/usr/src/cmd/cmd-inet/lib/nwamd/functions.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -62,9 +62,9 @@ extern int lookup_count_property(const char *, const char *, uint64_t *); /* wireless.c: wifi link handling */ extern void init_mutexes(void); -extern boolean_t connect_chosen_lan(struct wireless_lan *, const char *); +extern boolean_t connect_chosen_lan(struct wireless_lan *, struct interface *); extern struct wireless_lan *prompt_for_visited(void); -extern boolean_t handle_wireless_lan(const char *); +extern boolean_t handle_wireless_lan(struct interface *); extern boolean_t scan_wireless_nets(struct interface *); extern void create_known_wifi_nets_file(void); extern void update_known_wifi_nets_file(const char *, const char *); diff --git a/usr/src/cmd/cmd-inet/lib/nwamd/interface.c b/usr/src/cmd/cmd-inet/lib/nwamd/interface.c index b66dee45f5..304cb78467 100644 --- a/usr/src/cmd/cmd-inet/lib/nwamd/interface.c +++ b/usr/src/cmd/cmd-inet/lib/nwamd/interface.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -558,7 +558,7 @@ bringupinterface(const char *ifname, const char *host, const char *ipv6addr, } if (intf->if_type == IF_WIRELESS) { - if (!handle_wireless_lan(ifname)) { + if (!handle_wireless_lan(intf)) { syslog(LOG_INFO, "Could not connect to any WLAN, not " "bringing %s up", ifname); return (B_FALSE); @@ -631,8 +631,8 @@ takedowninterface(const char *ifname, boolean_t popup, boolean_t v6onlink) (void) start_child(IFCONFIG, ifname, "inet6", "unplumb", NULL); } - if (find_if_type(ifname) == IF_WIRELESS) - (void) dladm_wlan_disconnect(ifname); + if (ifp->if_type == IF_WIRELESS) + (void) dladm_wlan_disconnect(ifp->if_linkid); dprintf("takedown interface, free cached ip address"); if (ifp != NULL) { @@ -751,6 +751,7 @@ struct interface * add_interface(sa_family_t family, const char *name, uint64_t flags) { struct interface *i; + datalink_id_t linkid = DATALINK_INVALID_LINKID; enum interface_type iftype; if (name == NULL) @@ -801,6 +802,13 @@ add_interface(sa_family_t family, const char *name, uint64_t flags) i->if_lflags = 0; i->if_timer_expire = 0; + /* + * If linkid is DATALINK_INVALID_LINKID, it is an IP-layer only + * interface. + */ + (void) dladm_name2info(name, &linkid, NULL, NULL, NULL); + i->if_linkid = linkid; + dprintf("added interface %s of type %s af %d; is %savailable", i->if_name, if_type_str(i->if_type), i->if_family, ((i->if_type == IF_WIRELESS) || @@ -1077,7 +1085,7 @@ initialize_interfaces(void) wait_time = NWAM_IF_WAIT_DELTA_MAX; } - (void) dladm_init_linkprop(); + (void) dladm_init_linkprop(DATALINK_ALL_LINKID); (void) icfg_iterate_if(AF_INET, ICFG_PLUMBED, NULL, do_add_interface); @@ -1167,6 +1175,7 @@ check_interface_timer(struct interface *ifp, void *arg) enum interface_type find_if_type(const char *name) { + uint32_t media; enum interface_type type; if (name == NULL) { @@ -1174,20 +1183,19 @@ find_if_type(const char *name) return (IF_UNKNOWN); } - if (strncmp(name, "ip.tun", 6) == 0) { - /* - * We'll need to update our tunnel detection once - * clearview/uv and clearview/tun driver projects - * go back; tunnel names won't necessarily be ip.tunN - */ - type = IF_TUN; - } else { - /* - * We didn't recognize it. Try the libdladm function - * to decide if it is wireless or not; if not, assume - * that it's wired. - */ - type = dladm_wlan_is_valid(name) ? IF_WIRELESS : IF_WIRED; + type = IF_WIRED; + if (dladm_name2info(name, NULL, NULL, NULL, &media) != + DLADM_STATUS_OK) { + if (strncmp(name, "ip.tun", 6) == 0) { + /* + * We'll need to update our tunnel detection once + * clearview/uv and clearview/tun driver projects + * go back; tunnel names won't necessarily be ip.tunN + */ + type = IF_TUN; + } + } else if (media == DL_WIFI) { + type = IF_WIRELESS; } return (type); diff --git a/usr/src/cmd/cmd-inet/lib/nwamd/structures.h b/usr/src/cmd/cmd-inet/lib/nwamd/structures.h index 0f232cd70b..caf0815d32 100644 --- a/usr/src/cmd/cmd-inet/lib/nwamd/structures.h +++ b/usr/src/cmd/cmd-inet/lib/nwamd/structures.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -89,6 +89,7 @@ struct np_event { */ struct interface { char *if_name; + datalink_id_t if_linkid; sa_family_t if_family; uint64_t if_flags; uint32_t if_lflags; diff --git a/usr/src/cmd/cmd-inet/lib/nwamd/wireless.c b/usr/src/cmd/cmd-inet/lib/nwamd/wireless.c index 78cd0f4c74..f99d103dd3 100644 --- a/usr/src/cmd/cmd-inet/lib/nwamd/wireless.c +++ b/usr/src/cmd/cmd-inet/lib/nwamd/wireless.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -152,10 +152,10 @@ static dladm_wlan_key_t *retrieve_key(const char *, const char *, static boolean_t add_wlan_entry(struct interface *, char *, char *, char *, dladm_wlan_secmode_t); static boolean_t already_in_visited_wlan_list(const struct wireless_lan *); -static boolean_t check_wlan(const char *, const char *); -static boolean_t connect_or_autoconf(struct wireless_lan *, const char *); +static boolean_t check_wlan(struct interface *, const char *); +static boolean_t connect_or_autoconf(struct wireless_lan *, struct interface *); static return_vals_t connect_to_new_wlan(const struct wireless_lan *, int, - const char *); + struct interface *); static boolean_t find_wlan_entry(struct interface *, char *, char *); static void free_wireless_lan(struct wireless_lan *); static struct wireless_lan *get_specific_lan(void); @@ -167,7 +167,7 @@ static void free_argv(char **); static char **build_wlanlist_zargv(const struct wireless_lan *, int, const char *, int, const char **, int); static char *get_zenity_response(char *const *); -static boolean_t wlan_autoconf(const char *ifname); +static boolean_t wlan_autoconf(struct interface *); static int zenity_height(int); static boolean_t get_scan_results(void *, dladm_wlan_attr_t *); static boolean_t known_wifi_nets_lookup(const char *, const char *, char *); @@ -438,20 +438,21 @@ clear_lan_entries(void) * to disassociate with it and then return false. */ static boolean_t -check_wlan(const char *intf, const char *exp_essid) +check_wlan(struct interface *intf, const char *exp_essid) { dladm_wlan_linkattr_t attr; dladm_status_t status; char cur_essid[DLADM_STRSIZE]; char errmsg[DLADM_STRSIZE]; - status = dladm_wlan_get_linkattr(intf, &attr); + status = dladm_wlan_get_linkattr(intf->if_linkid, &attr); if (status != DLADM_STATUS_OK) { - dprintf("check_wlan: dladm_wlan_get_linkattr() failed: %s", + dprintf("check_wlan: dladm_wlan_get_linkattr() for %s " + "failed: %s", intf->if_name, dladm_status2str(status, errmsg)); return (B_FALSE); } - if (attr.la_status == DLADM_WLAN_LINKSTATUS_DISCONNECTED) + if (attr.la_status == DLADM_WLAN_LINK_DISCONNECTED) return (B_FALSE); if (exp_essid == NULL) return (B_TRUE); @@ -462,8 +463,10 @@ check_wlan(const char *intf, const char *exp_essid) return (B_TRUE); /* Tell the driver to disassociate with the current AP. */ - if (dladm_wlan_disconnect(intf) != DLADM_STATUS_OK) - dprintf("check_wlan: dladm_wlan_disconnect() fails"); + if (dladm_wlan_disconnect(intf->if_linkid) != DLADM_STATUS_OK) { + dprintf("check_wlan: dladm_wlan_disconnect() for %s fails", + intf->if_name); + } return (B_FALSE); } @@ -505,7 +508,7 @@ scan_wireless_nets(struct interface *intf) * a lock in checking wireless_lan_used. */ num_ap = wireless_lan_used; - status = dladm_wlan_scan(intf->if_name, intf, get_scan_results); + status = dladm_wlan_scan(intf->if_linkid, intf, get_scan_results); if (status != DLADM_STATUS_OK) syslog(LOG_NOTICE, "cannot scan link '%s'", intf->if_name); else @@ -570,6 +573,8 @@ get_scan_results(void *arg, dladm_wlan_attr_t *attrp) void * periodic_wireless_scan(void *arg) { + datalink_id_t linkid; + /* * No periodic scan if the "-i" option is used to change the * interval to 0. @@ -601,13 +606,18 @@ periodic_wireless_scan(void *arg) */ if (ret == 0) { if (cur_llp != NULL) { - if (cur_llp->llp_type != IF_WIRELESS || - dladm_wlan_get_linkattr(cur_llp->llp_lname, - &attr) != DLADM_STATUS_OK) { + if (cur_llp->llp_type != IF_WIRELESS) + continue; + + if (dladm_name2info(cur_llp->llp_lname, &linkid, + NULL, NULL, NULL) != DLADM_STATUS_OK || + dladm_wlan_get_linkattr(linkid, &attr) != + DLADM_STATUS_OK) { continue; } + if (attr.la_status == - DLADM_WLAN_LINKSTATUS_CONNECTED && + DLADM_WLAN_LINK_CONNECTED && attr.la_wlan_attr.wa_strength > wireless_scan_level) { continue; @@ -771,7 +781,7 @@ store_key(struct wireless_lan *wlan) status = dladm_set_secobj(obj_name, class, obj_val, obj_len, - DLADM_OPT_CREATE | DLADM_OPT_PERSIST | DLADM_OPT_TEMP); + DLADM_OPT_CREATE | DLADM_OPT_PERSIST | DLADM_OPT_ACTIVE); if (status != DLADM_STATUS_OK) { syslog(LOG_ERR, "store_key: could not create secure object " "'%s' for key: %s", obj_name, @@ -826,7 +836,7 @@ retrieve_key(const char *essid, const char *bssid, dladm_secobj_class_t req) /* Try the kernel first, then fall back to persistent storage. */ status = dladm_get_secobj(cooked_key->wk_name, &class, cooked_key->wk_val, &cooked_key->wk_len, - DLADM_OPT_TEMP); + DLADM_OPT_ACTIVE); if (status != DLADM_STATUS_OK) { dprintf("retrieve_key: dladm_get_secobj(TEMP) failed: %s", dladm_status2str(status, errmsg)); @@ -1007,7 +1017,7 @@ known_wifi_nets_lookup(const char *new_essid, const char *new_bssid, * reqlan->bssid is optional (i.e., may be NULL) */ boolean_t -connect_chosen_lan(struct wireless_lan *reqlan, const char *ifname) +connect_chosen_lan(struct wireless_lan *reqlan, struct interface *intf) { uint_t keycount; dladm_wlan_key_t *key; @@ -1022,17 +1032,17 @@ connect_chosen_lan(struct wireless_lan *reqlan, const char *ifname) if (reqlan->essid == NULL) return (B_FALSE); dprintf("connect_chosen_lan(%s, %s, %s)", reqlan->essid, - STRING(reqlan->bssid), ifname); + STRING(reqlan->bssid), intf->if_name); /* If it is already connected to the required AP, just return. */ - if (check_wlan(ifname, reqlan->essid)) + if (check_wlan(intf, reqlan->essid)) return (B_TRUE); if (dladm_wlan_str2essid(reqlan->essid, &attr.wa_essid) != DLADM_STATUS_OK) { syslog(LOG_ERR, "connect_chosen_lan: invalid ESSID '%s' for '%s'", - reqlan->essid, ifname); + reqlan->essid, intf->if_name); return (B_FALSE); } attr.wa_valid = DLADM_WLAN_ATTR_ESSID; @@ -1041,7 +1051,7 @@ connect_chosen_lan(struct wireless_lan *reqlan, const char *ifname) DLADM_STATUS_OK) { syslog(LOG_ERR, "connect_chosen_lan: invalid BSSID '%s' for '%s'", - reqlan->bssid, ifname); + reqlan->bssid, intf->if_name); return (B_FALSE); } attr.wa_valid |= DLADM_WLAN_ATTR_BSSID; @@ -1068,8 +1078,8 @@ connect_chosen_lan(struct wireless_lan *reqlan, const char *ifname) * try a second time with just the ESSID. */ - status = dladm_wlan_connect(ifname, &attr, timeout, key, keycount, - flags); + status = dladm_wlan_connect(intf->if_linkid, &attr, timeout, key, + keycount, flags); dprintf("connect_chosen_lan: dladm_wlan_connect returned %s", dladm_status2str(status, errmsg)); if (status == DLADM_STATUS_TIMEDOUT && reqlan->bssid != NULL) { @@ -1078,13 +1088,14 @@ connect_chosen_lan(struct wireless_lan *reqlan, const char *ifname) reqlan->essid, reqlan->bssid, reqlan->essid); attr.wa_valid &= ~DLADM_WLAN_ATTR_BSSID; flags = 0; - status = dladm_wlan_connect(ifname, &attr, timeout, key, - keycount, flags); + status = dladm_wlan_connect(intf->if_linkid, &attr, timeout, + key, keycount, flags); } if (status != DLADM_STATUS_OK) { syslog(LOG_ERR, "connect_chosen_lan: connect to '%s' failed on '%s': %s", - reqlan->essid, ifname, dladm_status2str(status, errmsg)); + reqlan->essid, intf->if_name, + dladm_status2str(status, errmsg)); return (B_FALSE); } return (B_TRUE); @@ -1095,13 +1106,13 @@ connect_chosen_lan(struct wireless_lan *reqlan, const char *ifname) * If that fails, attempt to connect using autoconf. */ static boolean_t -connect_or_autoconf(struct wireless_lan *reqlan, const char *ifname) +connect_or_autoconf(struct wireless_lan *reqlan, struct interface *intf) { - if (!connect_chosen_lan(reqlan, ifname)) { + if (!connect_chosen_lan(reqlan, intf)) { syslog(LOG_WARNING, "Could not connect to chosen WLAN %s, going to auto-conf", reqlan->essid); - return (wlan_autoconf(ifname)); + return (wlan_autoconf(intf)); } return (B_TRUE); } @@ -1198,9 +1209,8 @@ build_wlanlist_zargv(const struct wireless_lan *lanlist, int nlans, static return_vals_t connect_to_new_wlan(const struct wireless_lan *lanlist, int nlans, - const char *ifname) + struct interface *intf) { - struct interface *intf; int i, dlist_cnt; int rtn; char **zargv; @@ -1209,19 +1219,13 @@ connect_to_new_wlan(const struct wireless_lan *lanlist, int nlans, struct wireless_lan *dlist, *reqlan; boolean_t autoconf = B_FALSE; - dprintf("connect_to_new_wlan(..., %d, %s)", nlans, ifname); + dprintf("connect_to_new_wlan(..., %d, %s)", nlans, intf->if_name); if (nlans == 0) { display(gettext("No Wifi networks found; continuing in case " "you know of any which do not broadcast.")); } - if ((intf = get_interface(ifname)) == NULL) { - dprintf("connect_to_new_wlan: cannot find wireless interface: " - "%s", ifname); - return (FAILURE); - } - /* build list of wlans to be displayed */ if ((dlist = calloc(nlans, sizeof (struct wireless_lan))) == NULL) return (FAILURE); @@ -1236,10 +1240,10 @@ connect_to_new_wlan(const struct wireless_lan *lanlist, int nlans, /* * Only use the interface which finds the AP to connect to it. */ - if (strcmp(lanlist[i].wl_if_name, ifname) != 0) { + if (strcmp(lanlist[i].wl_if_name, intf->if_name) != 0) { dprintf("connect_to_new_wlan: wrong interface (%s) for " - "%s (should be %s)", ifname, lanlist[i].essid, - lanlist[i].wl_if_name); + "%s (should be %s)", intf->if_name, + lanlist[i].essid, lanlist[i].wl_if_name); continue; } @@ -1279,7 +1283,7 @@ connect_to_new_wlan(const struct wireless_lan *lanlist, int nlans, if ((reqlan == NULL) || (reqlan->essid == NULL)) { dprintf("did not get user preference; attempting autoconf"); - rtn = wlan_autoconf(ifname) ? SUCCESS : FAILURE; + rtn = wlan_autoconf(intf) ? SUCCESS : FAILURE; goto cleanup; } dprintf("get_user_preference() returned essid %s, bssid %s, encr %s", @@ -1295,7 +1299,7 @@ connect_to_new_wlan(const struct wireless_lan *lanlist, int nlans, * now attempt to connect to selection, backing * off to autoconf if the connect fails */ - if (connect_chosen_lan(reqlan, ifname)) { + if (connect_chosen_lan(reqlan, intf)) { /* * Succeeded, so add entry to known_essid_list_file; * but first make sure the reqlan->bssid isn't empty. @@ -1305,7 +1309,8 @@ connect_to_new_wlan(const struct wireless_lan *lanlist, int nlans, dladm_wlan_linkattr_t attr; char bssid[DLADM_STRSIZE]; - status = dladm_wlan_get_linkattr(ifname, &attr); + status = dladm_wlan_get_linkattr(intf->if_linkid, + &attr); if (status == DLADM_STATUS_OK) { (void) dladm_wlan_bssid2str( @@ -1326,7 +1331,7 @@ connect_to_new_wlan(const struct wireless_lan *lanlist, int nlans, free_wireless_lan(reqlan); if (autoconf) - rtn = wlan_autoconf(ifname) ? SUCCESS : FAILURE; + rtn = wlan_autoconf(intf) ? SUCCESS : FAILURE; else rtn = SUCCESS; @@ -1391,7 +1396,7 @@ prompt_for_visited(void) } static boolean_t -wlan_autoconf(const char *ifname) +wlan_autoconf(struct interface *intf) { dladm_status_t status; boolean_t autoconf; @@ -1402,7 +1407,7 @@ wlan_autoconf(const char *ifname) } /* If the NIC is already associated with something, just return. */ - if (check_wlan(ifname, NULL)) + if (check_wlan(intf, NULL)) return (B_TRUE); /* @@ -1410,14 +1415,14 @@ wlan_autoconf(const char *ifname) * to cycle through WLANs detected in priority order, attempting * to connect. */ - status = dladm_wlan_connect(ifname, NULL, + status = dladm_wlan_connect(intf->if_linkid, NULL, DLADM_WLAN_CONNECT_TIMEOUT_DEFAULT, NULL, 0, 0); if (status != DLADM_STATUS_OK) { char errmsg[DLADM_STRSIZE]; syslog(LOG_ERR, "wlan_autoconf: dladm_wlan_connect failed for '%s': %s", - ifname, dladm_status2str(status, errmsg)); + intf->if_name, dladm_status2str(status, errmsg)); return (B_FALSE); } return (B_TRUE); @@ -1720,7 +1725,7 @@ cleanup: * B_FALSE if we were unable to connect to anything */ boolean_t -handle_wireless_lan(const char *ifname) +handle_wireless_lan(struct interface *intf) { const struct wireless_lan *cur_wlans; int i, num_wlans; @@ -1839,7 +1844,7 @@ start_over: if (strength < strongest) goto connect_any; } - result = connect_or_autoconf(target, ifname); + result = connect_or_autoconf(target, intf); connect_result = result ? SUCCESS : FAILURE; } else if (visited_wlan_list->total > 1) { @@ -1848,21 +1853,21 @@ start_over: * prompt user for which one should we connect to */ if ((req_conf = prompt_for_visited()) != NULL) { - result = connect_or_autoconf(req_conf, ifname); + result = connect_or_autoconf(req_conf, intf); connect_result = result ? SUCCESS : FAILURE; } else { /* * The user didn't make a choice; offer the full list. */ connect_result = connect_to_new_wlan(cur_wlans, - num_wlans, ifname); + num_wlans, intf); result = (connect_result == SUCCESS); } } else { connect_any: /* last case, no previously visited wlan found */ connect_result = connect_to_new_wlan(cur_wlans, num_wlans, - ifname); + intf); result = (connect_result == SUCCESS); } |