diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2000-10-17 04:24:28 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2000-10-17 04:24:28 +0000 |
commit | bde27cdfccf0c3f2dee3c87aa57708b5413f20a2 (patch) | |
tree | b19715d8a416a67bad25f674ba67f4fa1e98bf97 /sys/dev/pcmcia/if_ray.c | |
parent | 41f4b0409af9b784f5a9a5a084e9ef7ba319568c (diff) |
/* Authentication added by Steve Weiss <srw@alum.mit.edu> based on advice
* received by Corey Thomas, author of the Linux driver for this device.
* Authentication currently limited to adhoc networks, and was added to
* support a requirement of the newest windows drivers, so that
* interoperability the windows will remain possible.
*
* Tested with Win98 using Aviator 2.4 Pro cards, firmware 5.63,
* but no access points for infrastructure. (July 13, 2000 -srw)
*/
also, some syncing /w netbsd.
Diffstat (limited to 'sys/dev/pcmcia/if_ray.c')
-rw-r--r-- | sys/dev/pcmcia/if_ray.c | 271 |
1 files changed, 222 insertions, 49 deletions
diff --git a/sys/dev/pcmcia/if_ray.c b/sys/dev/pcmcia/if_ray.c index 58352e24018..feb3f284821 100644 --- a/sys/dev/pcmcia/if_ray.c +++ b/sys/dev/pcmcia/if_ray.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_ray.c,v 1.8 2000/09/10 17:55:08 mickey Exp $ */ -/* $NetBSD: if_ray.c,v 1.19 2000/04/22 22:36:14 thorpej Exp $ */ +/* $OpenBSD: if_ray.c,v 1.9 2000/10/17 04:24:26 mickey Exp $ */ +/* $NetBSD: if_ray.c,v 1.21 2000/07/05 02:35:54 onoe Exp $ */ /* * Copyright (c) 2000 Christian E. Hopps @@ -51,6 +51,16 @@ * Given the nature of the buggy build 4 firmware there may be problems. */ +/* Authentication added by Steve Weiss <srw@alum.mit.edu> based on advice + * received by Corey Thomas, author of the Linux driver for this device. + * Authentication currently limited to adhoc networks, and was added to + * support a requirement of the newest windows drivers, so that + * interoperability the windows will remain possible. + * + * Tested with Win98 using Aviator 2.4 Pro cards, firmware 5.63, + * but no access points for infrastructure. (July 13, 2000 -srw) + */ + #include "bpfilter.h" #include <sys/param.h> @@ -112,7 +122,7 @@ #define RAY_USE_AMEM 0 -/* #define RAY_DEBUG */ +/*#define RAY_DEBUG*/ #ifndef RAY_PID_COUNTRY_CODE_DEFAULT #define RAY_PID_COUNTRY_CODE_DEFAULT RAY_PID_COUNTRY_CODE_USA @@ -178,7 +188,9 @@ struct ray_softc { void *sc_ih; void *sc_sdhook; void *sc_pwrhook; - int sc_resumeinit; + int sc_flags; +#define RAY_FLAGS_RESUMEINIT 0x01 +#define RAY_FLAGS_ATTACHED 0x02 int sc_resetloop; struct timeout sc_check_ccs_ch; @@ -200,8 +212,9 @@ struct ray_softc { u_int sc_txfree; /* a free count for efficiency */ u_int8_t sc_bssid[ETHER_ADDR_LEN]; /* current net values */ - u_int8_t sc_cnwid[IEEE80211_NWID_LEN]; /* last nwid */ - u_int8_t sc_dnwid[IEEE80211_NWID_LEN]; /* desired nwid */ + u_int8_t sc_authid[ETHER_ADDR_LEN]; /* id of authenticating station */ + struct ieee80211_nwid sc_cnwid; /* last nwid */ + struct ieee80211_nwid sc_dnwid; /* desired nwid */ u_int8_t sc_omode; /* old operating mode SC_MODE_xx */ u_int8_t sc_mode; /* current operating mode SC_MODE_xx */ u_int8_t sc_countrycode; /* current country code */ @@ -210,7 +223,7 @@ struct ray_softc { bus_size_t sc_txpad; /* tib size plus "phy" size */ u_int8_t sc_deftxrate; /* default transfer rate */ u_int8_t sc_encrypt; - + u_int8_t sc_authstate; /* authentication state */ int sc_promisc; /* current set value */ int sc_running; /* things we are doing */ @@ -283,7 +296,17 @@ typedef void (*ray_cmd_func_t)(struct ray_softc *); #define SC_BUILD_5 0x5 #define SC_BUILD_4 0x55 +/* values for sc_authstate */ +#define RAY_AUTH_UNAUTH (0) +#define RAY_AUTH_WAITING (1) +#define RAY_AUTH_AUTH (2) +#define RAY_AUTH_NEEDED (3) +#define OPEN_AUTH_REQUEST (1) +#define OPEN_AUTH_RESPONSE (2) +#define BROADCAST_DEAUTH (0xc0) + +/* prototypes */ int ray_alloc_ccs __P((struct ray_softc *, bus_size_t *, u_int, u_int)); bus_size_t ray_fill_in_tx_ccs __P((struct ray_softc *, size_t, u_int, u_int)); void ray_attach __P((struct device *, struct device *, void *)); @@ -316,9 +339,11 @@ void ray_media_status __P((struct ifnet *, struct ifmediareq *)); void ray_power __P((int, void *)); ray_cmd_func_t ray_rccs_intr __P((struct ray_softc *, bus_size_t)); void ray_recv __P((struct ray_softc *, bus_size_t)); +void ray_recv_auth __P((struct ray_softc *,struct ieee80211_frame*)); void ray_report_params __P((struct ray_softc *)); void ray_reset __P((struct ray_softc *)); void ray_reset_resetloop __P((void *)); +int ray_send_auth __P((struct ray_softc *, u_int8_t *, u_int8_t)); void ray_set_pending __P((struct ray_softc *, u_int)); void ray_shutdown __P((void *)); int ray_simple_cmd __P((struct ray_softc *, u_int, u_int)); @@ -350,11 +375,11 @@ void ray_update_siglev __P((struct ray_softc *, u_int8_t *, u_int8_t)); #endif #ifdef RAY_DEBUG -int ray_debug = 1; -int ray_debug_xmit_sum = 1; -int ray_debug_dump_desc = 1; -int ray_debug_dump_rx = 1; -int ray_debug_dump_tx = 1; +int ray_debug = 0; +int ray_debug_xmit_sum = 0; +int ray_debug_dump_desc = 0; +int ray_debug_dump_rx = 0; +int ray_debug_dump_tx = 0; struct timeval rtv, tv1, tv2, *ttp, *ltp; #define RAY_DPRINTF(x) do { if (ray_debug) { \ struct timeval *tmp; \ @@ -594,13 +619,17 @@ ray_attach(parent, self, aux) /* * set the parameters that will survive stop/init */ - memset(sc->sc_cnwid, 0, sizeof(sc->sc_cnwid)); - memset(sc->sc_dnwid, 0, sizeof(sc->sc_dnwid)); - strncpy(sc->sc_dnwid, RAY_DEF_NWID, sizeof(sc->sc_dnwid)); - strncpy(sc->sc_cnwid, RAY_DEF_NWID, sizeof(sc->sc_dnwid)); + memset(&sc->sc_dnwid, 0, sizeof(sc->sc_dnwid)); + sc->sc_dnwid.i_len = strlen(RAY_DEF_NWID); + if (sc->sc_dnwid.i_len > IEEE80211_NWID_LEN) + sc->sc_dnwid.i_len = IEEE80211_NWID_LEN; + if (sc->sc_dnwid.i_len > 0) + memcpy(sc->sc_dnwid.i_nwid, RAY_DEF_NWID, sc->sc_dnwid.i_len); + memcpy(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid)); sc->sc_omode = sc->sc_mode = RAY_MODE_DEFAULT; - sc->sc_countrycode = sc->sc_dcountrycode = RAY_PID_COUNTRY_CODE_DEFAULT; - sc->sc_resumeinit = 0; + sc->sc_countrycode = sc->sc_dcountrycode = + RAY_PID_COUNTRY_CODE_DEFAULT; + sc->sc_flags &= ~RAY_FLAGS_RESUMEINIT; timeout_set(&sc->sc_check_ccs_ch, ray_check_ccs, sc); timeout_set(&sc->sc_check_scheduled_ch, ray_check_scheduled, sc); @@ -612,7 +641,8 @@ ray_attach(parent, self, aux) * attach the interface */ /* The version isn't the most accurate way, but it's easy. */ - printf("%s: firmware version %d\n", sc->sc_dev.dv_xname,sc->sc_version); + printf("%s: firmware version %d\n", sc->sc_dev.dv_xname, + sc->sc_version); if (sc->sc_version != SC_BUILD_4) printf("%s: supported rates %0x:%0x:%0x:%0x:%0x:%0x:%0x:%0x\n", sc->sc_xname, ep->e_rates[0], ep->e_rates[1], @@ -652,6 +682,8 @@ ray_attach(parent, self, aux) sc->sc_sdhook = shutdownhook_establish(ray_shutdown, sc); sc->sc_pwrhook = powerhook_establish(ray_power, sc); + /* The attach is successful. */ + sc->sc_flags |= RAY_FLAGS_ATTACHED; return; fail: /* disable the card */ @@ -716,6 +748,10 @@ ray_detach(self, flags) ifp = &sc->sc_if; RAY_DPRINTF(("%s: detach\n", sc->sc_xname)); + /* Succeed now if there is no work to do. */ + if ((sc->sc_flags & RAY_FLAGS_ATTACHED) == 0) + return (0); + if (ifp->if_flags & IFF_RUNNING) ray_disable(sc); @@ -819,7 +855,8 @@ ray_init(sc) sc->sc_running = 0; sc->sc_txfree = RAY_CCS_NTX; sc->sc_checkcounters = 0; - sc->sc_resumeinit = 0; + sc->sc_flags &= RAY_FLAGS_RESUMEINIT; + sc->sc_authstate = RAY_AUTH_UNAUTH; /* get startup results */ ep = &sc->sc_ecf_startup; @@ -941,13 +978,13 @@ ray_power(why, arg) sc = arg; switch (why) { case PWR_RESUME: - if (sc->sc_resumeinit) + if ((sc->sc_flags & RAY_FLAGS_RESUMEINIT)) ray_init(sc); break; case PWR_SUSPEND: if ((sc->sc_if.if_flags & IFF_RUNNING)) { ray_stop(sc); - sc->sc_resumeinit = 1; + sc->sc_flags |= RAY_FLAGS_RESUMEINIT; } break; case PWR_STANDBY: @@ -973,12 +1010,12 @@ ray_ioctl(ifp, cmd, data) u_long cmd; caddr_t data; { - u_int8_t nwid[IEEE80211_NWID_LEN]; + struct ieee80211_nwid nwid; struct ray_param_req pr; struct ray_softc *sc; struct ifreq *ifr; struct ifaddr *ifa; - int error, error2, s; + int error, error2, s, i; sc = ifp->if_softc; error = 0; @@ -1074,24 +1111,31 @@ ray_ioctl(ifp, cmd, data) error = error2 ? error2 : error; break; case SIOCS80211NWID: - RAY_DPRINTF(("%s: ioctl: cmd SIOCSNWID\n", ifp->if_xname)); + RAY_DPRINTF(("%s: ioctl: cmd SIOCS80211NWID\n", ifp->if_xname)); /* * if later people overwrite thats ok -- the latest version * will always get start/joined even if it was set by * a previous command */ - if ((error = copyin(ifr->ifr_data, nwid, sizeof(nwid)))) + if ((error = copyin(ifr->ifr_data, &nwid, sizeof(nwid)))) break; - if (!memcmp(sc->sc_dnwid, nwid, sizeof(nwid))) + if (nwid.i_len > IEEE80211_NWID_LEN) { + error = EINVAL; break; - memcpy(sc->sc_dnwid, nwid, sizeof(nwid)); + } + /* clear trailing garbages */ + for (i = nwid.i_len; i < IEEE80211_NWID_LEN; i++) + nwid.i_nwid[i] = 0; + if (!memcmp(&sc->sc_dnwid, &nwid, sizeof(nwid))) + break; + memcpy(&sc->sc_dnwid, &nwid, sizeof(nwid)); if (ifp->if_flags & IFF_RUNNING) ray_start_join_net(sc); break; case SIOCG80211NWID: - RAY_DPRINTF(("%s: ioctl: cmd SIOCHNWID\n", ifp->if_xname)); - error = copyout(sc->sc_cnwid, ifr->ifr_data, - IEEE80211_NWID_LEN); + RAY_DPRINTF(("%s: ioctl: cmd SIOCG80211NWID\n", ifp->if_xname)); + error = copyout(&sc->sc_cnwid, ifr->ifr_data, + sizeof(sc->sc_cnwid)); break; #ifdef RAY_DO_SIGLEV error = copyout(sc->sc_siglevs, ifr->ifr_data, @@ -1189,11 +1233,15 @@ ray_intr_start(sc) ray_cmd_cancel(sc, SCP_IFSTART); - if ((ifp->if_flags & IFF_RUNNING) == 0 || !sc->sc_havenet) + if ((ifp->if_flags & IFF_RUNNING) == 0 || !sc->sc_havenet) { + RAY_DPRINTF(("%s: nonet.\n",ifp->if_xname)); return; + } - if (ifp->if_snd.ifq_len == 0) + if (ifp->if_snd.ifq_len == 0) { + RAY_DPRINTF(("%s: nothing to send.\n",ifp->if_xname)); return; + } firsti = i = previ = RAY_CCS_LINK_NULL; hinti = RAY_CCS_TX_FIRST; @@ -1203,20 +1251,31 @@ ray_intr_start(sc) return; } + /* check to see if we need to authenticate before sending packets */ + if (sc->sc_authstate == RAY_AUTH_NEEDED) { + RAY_DPRINTF(("%s: Sending auth request.\n",ifp->if_xname)); + sc->sc_authstate= RAY_AUTH_WAITING; + ray_send_auth(sc,sc->sc_authid,OPEN_AUTH_REQUEST); + return; + } + pcount = 0; for (;;) { /* if we have no descriptors be done */ if (i == RAY_CCS_LINK_NULL) { i = ray_find_free_tx_ccs(sc, hinti); if (i == RAY_CCS_LINK_NULL) { + RAY_DPRINTF(("%s: no descriptors.\n",ifp->if_xname)); ifp->if_flags |= IFF_OACTIVE; break; } } IF_DEQUEUE(&ifp->if_snd, m0); - if (!m0) + if (!m0) { + RAY_DPRINTF(("%s: dry queue.\n", ifp->if_xname)); break; + } RAY_DPRINTF(("%s: gotmbuf 0x%lx\n", ifp->if_xname, (long)m0)); pktlen = m0->m_pkthdr.len; if (pktlen > ETHER_MAX_LEN - ETHER_CRC_LEN) { @@ -1377,7 +1436,7 @@ ray_intr_start(sc) } /* - * recevice a packet from the card + * receive a packet from the card */ void ray_recv(sc, ccs) @@ -1427,8 +1486,7 @@ ray_recv(sc, ccs) (u_long)pktlen, nofrag)); RAY_DPRINTF_XMIT(("%s: received packet: len %lu\n", sc->sc_xname, (u_long)pktlen)); - if (pktlen > MCLBYTES - || pktlen < (sizeof(*frame) + sizeof(struct llc))) { + if (pktlen > MCLBYTES || pktlen < (sizeof(*frame)) ) { RAY_DPRINTF(("%s: PKTLEN TOO BIG OR TOO SMALL\n", sc->sc_xname)); ifp->if_ierrors++; @@ -1523,7 +1581,7 @@ done: if (ray_debug && ray_debug_dump_rx) ray_dump_mbuf(sc, m); #endif - /* receivce the packet */ + /* receive the packet */ frame = mtod(m, struct ieee80211_frame *); fc0 = frame->i_fc[0] & (IEEE80211_FC0_VERSION_MASK|IEEE80211_FC0_TYPE_MASK); @@ -1533,9 +1591,42 @@ done: m_freem(m); return; } - if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) { - RAY_DPRINTF(("%s: pkt not type data fc0 0x%x\n", - sc->sc_xname, fc0)); + if ((fc0 & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) { + switch (frame->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) { + case IEEE80211_FC0_SUBTYPE_BEACON: + break; /* ignore beacon silently */ + case IEEE80211_FC0_SUBTYPE_AUTH: + ray_recv_auth(sc,frame); + break; + case IEEE80211_FC0_SUBTYPE_DEAUTH: + sc->sc_authstate= RAY_AUTH_UNAUTH; + break; + default: + RAY_DPRINTF(("%s: mgt packet not supported\n",sc->sc_xname)); +#ifdef RAY_DEBUG + hexdump((const u_int8_t*)frame, pktlen, 16,4,0); +#endif + RAY_DPRINTF(("\n")); + break; } + m_freem(m); + return; + + } else if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) { + RAY_DPRINTF(("%s: pkt not type data fc0 0x%x fc1 0x%x\n", + sc->sc_xname, frame->i_fc[0], frame->i_fc[1])); +#ifdef RAY_DEBUG + hexdump((const u_int8_t*)frame, pktlen, 16,4,0); +#endif + RAY_DPRINTF(("\n")); + + m_freem(m); + return; + } + + if (pktlen < sizeof(struct ieee80211_frame) + sizeof(struct llc)) + { + RAY_DPRINTF(("%s: pkt not big enough to contain llc (%d)\n", + sc->sc_xname, pktlen)); m_freem(m); return; } @@ -1599,6 +1690,79 @@ done: ether_input(ifp, eh, m); } +/* receive an auth packet + * + */ + +void +ray_recv_auth(sc, frame) + struct ray_softc *sc; + struct ieee80211_frame *frame; +{ + /* todo: deal with timers: del_timer(&local->timer); */ + u_int8_t *var= (u_int8_t*)(frame+1); + + /* if we are trying to get authenticated */ + if (sc->sc_mode == SC_MODE_ADHOC) { + RAY_DPRINTF(("%s: recv auth. packet dump:\n",sc->sc_xname)); +#ifdef RAY_DEBUG + hexdump((u_int8_t*)frame, sizeof(*frame)+6, 16,4,0); +#endif + RAY_DPRINTF(("\n")); + + if (var[2] == OPEN_AUTH_REQUEST) { + RAY_DPRINTF(("%s: Sending authentication response.\n",sc->sc_xname)); + if (!ray_send_auth(sc,frame->i_addr2,OPEN_AUTH_RESPONSE)) { + sc->sc_authstate= RAY_AUTH_NEEDED; + memcpy(sc->sc_authid, frame->i_addr2, ETHER_ADDR_LEN); + } + } + else if (var[2] == OPEN_AUTH_RESPONSE) { + RAY_DPRINTF(("%s: Authenticated!\n",sc->sc_xname)); + sc->sc_authstate= RAY_AUTH_AUTH; + } + } +} + +/* ray_send_auth + * + * dest: where to send auth packet + * auth_type: whether to send an REQUEST or a RESPONSE + */ +int +ray_send_auth(sc, dest, auth_type) + struct ray_softc *sc; + u_int8_t *dest; + u_int8_t auth_type; +{ + u_int8_t packet[sizeof(struct ieee80211_frame) + 6]; + bus_size_t bufp; + struct ieee80211_frame *frame= (struct ieee80211_frame*)packet; + int ccsindex= RAY_CCS_LINK_NULL; + ccsindex= ray_find_free_tx_ccs(sc,RAY_CCS_TX_FIRST); + if (ccsindex == RAY_CCS_LINK_NULL) { + RAY_DPRINTF(("%x: send authenticate - No free tx ccs\n")); + return -1; + } + bufp= ray_fill_in_tx_ccs(sc,sizeof(packet),ccsindex,RAY_CCS_LINK_NULL); + frame= (struct ieee80211_frame*) packet; + frame->i_fc[0]= IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_SUBTYPE_AUTH; + frame->i_fc[1]= 0; + memcpy(frame->i_addr1,dest,ETHER_ADDR_LEN); + memcpy(frame->i_addr2,sc->sc_ecf_startup.e_station_addr,ETHER_ADDR_LEN); + memcpy(frame->i_addr3,sc->sc_bssid,ETHER_ADDR_LEN); + memset(frame+1,0,6); + ((u_int8_t*)(frame+1))[2]= auth_type; + + ray_write_region(sc,bufp,packet,sizeof(packet)); + + SRAM_WRITE_1(sc, RAY_SCB_CCSI, ccsindex); + RAY_ECF_START_CMD(sc); + + RAY_DPRINTF_XMIT(("%s: sent auth packet: len %lu\n", sc->sc_xname, + (u_long)sizeof(packet))); + return 0; +} /* * scan for free buffers @@ -1887,7 +2051,7 @@ ray_ccs_done(sc, ccs) sc->sc_if.if_flags &= ~IFF_OACTIVE; sc->sc_omode = sc->sc_mode; - memcpy(sc->sc_cnwid, sc->sc_dnwid, sizeof(sc->sc_cnwid)); + memcpy(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid)); rcmd = ray_start_join_net; break; @@ -2453,7 +2617,8 @@ ray_download_params(sc) memset(sp4, 0, sizeof(*sp4)); else memset(sp5, 0, sizeof(*sp5)); - memcpy(sp->sp_ssid, sc->sc_dnwid, sizeof(sp->sp_ssid)); + /* XXX: Raylink firmware doesn't have length field for ssid */ + memcpy(sp->sp_ssid, sc->sc_dnwid.i_nwid, sizeof(sp->sp_ssid)); sp->sp_scan_mode = 0x1; memcpy(sp->sp_mac_addr, sc->sc_ecf_startup.e_station_addr, ETHER_ADDR_LEN); @@ -2647,14 +2812,14 @@ ray_start_join_net(sc) return; sc->sc_startccs = ccs; sc->sc_startcmd = cmd; - if (!memcmp(sc->sc_cnwid, sc->sc_dnwid, sizeof(sc->sc_cnwid)) + if (!memcmp(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid)) && sc->sc_omode == sc->sc_mode) SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param, 0); else { sc->sc_havenet = 0; memset(&np, 0, sizeof(np)); np.p_net_type = sc->sc_mode; - memcpy(np.p_ssid, sc->sc_dnwid, sizeof(np.p_ssid)); + memcpy(np.p_ssid, sc->sc_dnwid.i_nwid, sizeof(np.p_ssid)); ray_write_region(sc, RAY_HOST_TO_ECF_BASE, &np, sizeof(np)); SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param, 1); } @@ -2690,6 +2855,7 @@ ray_start_join_net_done(sc, cmd, ccs, stat) bus_size_t ccs; u_int stat; { + int i; struct ray_net_params np; callout_stop(&sc->sc_start_join_timo_ch); @@ -2710,13 +2876,14 @@ ray_start_join_net_done(sc, cmd, ccs, stat) return (0); /* see if our nwid is up to date */ - if (!memcmp(sc->sc_cnwid, sc->sc_dnwid, sizeof(sc->sc_cnwid)) + if (!memcmp(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid)) && sc->sc_omode == sc->sc_mode) SRAM_WRITE_FIELD_1(sc,ccs, ray_cmd_net, c_upd_param, 0); else { memset(&np, 0, sizeof(np)); np.p_net_type = sc->sc_mode; - memcpy(np.p_ssid, sc->sc_dnwid, sizeof(np.p_ssid)); + memcpy(np.p_ssid, sc->sc_dnwid.i_nwid, + sizeof(np.p_ssid)); ray_write_region(sc, RAY_HOST_TO_ECF_BASE, &np, sizeof(np)); SRAM_WRITE_FIELD_1(sc,ccs, ray_cmd_net, c_upd_param, 1); @@ -2752,13 +2919,19 @@ ray_start_join_net_done(sc, cmd, ccs, stat) if (SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param)) { ray_read_region(sc, RAY_HOST_TO_ECF_BASE, &np, sizeof(np)); - memcpy(sc->sc_cnwid, np.p_ssid, sizeof(sc->sc_cnwid)); + /* XXX: Raylink firmware doesn't have length field for ssid */ + for (i = 0; i < sizeof(np.p_ssid); i++) { + if (np.p_ssid[i] == '\0') + break; + } + sc->sc_cnwid.i_len = i; + memcpy(sc->sc_cnwid.i_nwid, np.p_ssid, sizeof(sc->sc_cnwid)); sc->sc_omode = sc->sc_mode; if (np.p_net_type != sc->sc_mode) return (ray_start_join_net); } RAY_DPRINTF(("%s: net start/join nwid %.32s bssid %s inited %d\n", - sc->sc_xname, sc->sc_cnwid, ether_sprintf(sc->sc_bssid), + sc->sc_xname, sc->sc_cnwid.i_nwid, ether_sprintf(sc->sc_bssid), SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net, c_inited))); /* network is now active */ |