change the argument of SIOCS80211NWID and SIOCG80211NWID ioctls from

u_int8_t array to struct ieee80211_nwid to prepend length field.
The length field is necessary because IEEE 802.11 spec doesn't prohibit
even '\0' for SSID.
Though the name and the value of SIOC... macro is unchanged, this change
breaks binary compatibility.  The only affected userland program on the
tree is ifconfig(8).
As Jason suggested on tech-net, it is better than live with problems
since there are no releases for this ioctls yet.
This commit is contained in:
onoe 2000-07-05 02:35:53 +00:00
parent f4eab681f2
commit 807a12c8cd
6 changed files with 138 additions and 98 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ifconfig.c,v 1.81 2000/07/02 00:28:01 thorpej Exp $ */
/* $NetBSD: ifconfig.c,v 1.82 2000/07/05 02:35:55 onoe Exp $ */
/*-
* Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
@ -80,7 +80,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\
#if 0
static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94";
#else
__RCSID("$NetBSD: ifconfig.c,v 1.81 2000/07/02 00:28:01 thorpej Exp $");
__RCSID("$NetBSD: ifconfig.c,v 1.82 2000/07/05 02:35:55 onoe Exp $");
#endif
#endif /* not lint */
@ -1094,12 +1094,31 @@ setifnwid(val, d)
const char *val;
int d;
{
u_int8_t nwid[IEEE80211_NWID_LEN];
struct ieee80211_nwid nwid;
u_int8_t *p;
memset(&nwid, 0, sizeof(nwid));
(void)strncpy(nwid, val, sizeof(nwid));
if (val[0] == '0' && (val[1] == 'x' || val[1] == 'X')) {
val += 2;
p = nwid.i_nwid;
while (isxdigit(val[0]) && isxdigit(val[1])) {
#define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10)
*p++ = (tohex(val[0]) << 4) | tohex(val[1]);
#undef tohex
val += 2;
}
if (*val != '\0') {
errno = EINVAL;
warn("SIOCS80211NWID");
return;
}
nwid.i_len = p - nwid.i_nwid;
} else {
nwid.i_len = strlen(val);
memcpy(nwid.i_nwid, val, nwid.i_len);
}
(void)strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
ifr.ifr_data = (caddr_t)nwid;
ifr.ifr_data = (caddr_t)&nwid;
if (ioctl(s, SIOCS80211NWID, (caddr_t)&ifr) < 0)
warn("SIOCS80211NWID");
}
@ -1107,14 +1126,29 @@ setifnwid(val, d)
void
ieee80211_status()
{
u_int8_t nwid[IEEE80211_NWID_LEN + 1];
int i;
struct ieee80211_nwid nwid;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_data = (caddr_t)nwid;
ifr.ifr_data = (caddr_t)&nwid;
(void)strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
nwid[IEEE80211_NWID_LEN] = 0;
if (ioctl(s, SIOCG80211NWID, (caddr_t)&ifr) == 0)
printf("\tnwid %s\n", nwid);
if (ioctl(s, SIOCG80211NWID, (caddr_t)&ifr) != 0)
return;
i = 0;
if (nwid.i_nwid[0] != '0' || tolower(nwid.i_nwid[1]) != 'x') {
for (; i < nwid.i_len; i++) {
if (!isprint(nwid.i_nwid[i]))
break;
}
}
if (i == nwid.i_len)
printf("\tnwid \"%.*s\"\n", nwid.i_len, nwid.i_nwid);
else {
printf("\tnwid 0x");
for (i = 0; i < nwid.i_len; i++)
printf("%02x", nwid.i_nwid[i]);
printf("\n");
}
}
void

View File

@ -1,4 +1,4 @@
/* $NetBSD: awi.c,v 1.20 2000/07/04 14:27:57 onoe Exp $ */
/* $NetBSD: awi.c,v 1.21 2000/07/05 02:35:54 onoe Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -460,8 +460,7 @@ awi_ioctl(ifp, cmd, data)
struct ifreq *ifr = (struct ifreq *)data;
struct ifaddr *ifa = (struct ifaddr *)data;
int s, error;
size_t nwidlen;
u_int8_t nwid[IEEE80211_NWID_LEN + 1];
struct ieee80211_nwid nwid;
u_int8_t *p;
s = splnet();
@ -521,22 +520,22 @@ awi_ioctl(ifp, cmd, data)
ifp->if_mtu = ifr->ifr_mtu;
break;
case SIOCS80211NWID:
error = copyinstr(ifr->ifr_data, nwid, sizeof(nwid), &nwidlen);
error = copyin(ifr->ifr_data, &nwid, sizeof(nwid));
if (error)
break;
nwidlen--; /* eliminate trailing '\0' */
if (nwidlen > IEEE80211_NWID_LEN) {
if (nwid.i_len > IEEE80211_NWID_LEN) {
error = EINVAL;
break;
}
if (sc->sc_mib_mac.aDesired_ESS_ID[1] == nwidlen &&
memcmp(&sc->sc_mib_mac.aDesired_ESS_ID[2], nwid,
nwidlen) == 0)
if (sc->sc_mib_mac.aDesired_ESS_ID[1] == nwid.i_len &&
memcmp(&sc->sc_mib_mac.aDesired_ESS_ID[2], nwid.i_nwid,
nwid.i_len) == 0)
break;
memset(sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE);
sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID;
sc->sc_mib_mac.aDesired_ESS_ID[1] = nwidlen;
memcpy(&sc->sc_mib_mac.aDesired_ESS_ID[2], nwid, nwidlen);
sc->sc_mib_mac.aDesired_ESS_ID[1] = nwid.i_len;
memcpy(&sc->sc_mib_mac.aDesired_ESS_ID[2], nwid.i_nwid,
nwid.i_len);
if (sc->sc_enabled) {
awi_stop(sc);
error = awi_init(sc);
@ -547,7 +546,7 @@ awi_ioctl(ifp, cmd, data)
p = sc->sc_bss.essid;
else
p = sc->sc_mib_mac.aDesired_ESS_ID;
error = copyout(p + 2, ifr->ifr_data, IEEE80211_NWID_LEN);
error = copyout(p + 1, ifr->ifr_data, 1 + IEEE80211_NWID_LEN);
break;
#ifdef IFM_IEEE80211
case SIOCSIFMEDIA:

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ray.c,v 1.20 2000/05/29 17:37:16 jhawk Exp $ */
/* $NetBSD: if_ray.c,v 1.21 2000/07/05 02:35:54 onoe Exp $ */
/*
* Copyright (c) 2000 Christian E. Hopps
* All rights reserved.
@ -179,8 +179,8 @@ 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 */
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 */
@ -578,10 +578,13 @@ 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;
@ -958,12 +961,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;
@ -1053,24 +1056,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
case SIOCGRAYSIGLEV:
@ -1869,7 +1879,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;
@ -2435,7 +2445,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);
@ -2629,14 +2640,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);
}
@ -2672,6 +2683,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);
@ -2692,13 +2704,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);
@ -2734,13 +2747,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 */

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wi.c,v 1.22 2000/06/30 16:40:31 joda Exp $ */
/* $NetBSD: if_wi.c,v 1.23 2000/07/05 02:35:55 onoe Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@ -155,10 +155,11 @@ static void wi_disable __P((struct wi_softc *));
static int wi_media_change __P((struct ifnet *));
static void wi_media_status __P((struct ifnet *, struct ifmediareq *));
static int wi_set_ssid __P((struct wi_ssid *, u_int8_t *, int));
static void wi_request_fill_ssid __P((struct wi_req *, struct wi_ssid *));
static int wi_set_ssid __P((struct ieee80211_nwid *, u_int8_t *, int));
static void wi_request_fill_ssid __P((struct wi_req *,
struct ieee80211_nwid *));
static int wi_write_ssid __P((struct wi_softc *, int, struct wi_req *,
struct wi_ssid *));
struct ieee80211_nwid *));
struct cfattach wi_ca = {
sizeof(struct wi_softc), wi_match, wi_attach, wi_detach, wi_activate
@ -1112,14 +1113,13 @@ static int wi_ioctl(ifp, command, data)
u_long command;
caddr_t data;
{
int s, len, error = 0;
int s, error = 0;
struct wi_softc *sc = ifp->if_softc;
struct wi_req wreq;
struct ifreq *ifr;
struct proc *p = curproc;
struct ifaddr *ifa = (struct ifaddr *)data;
struct wi_ssid ssid, *ws;
u_int8_t nwid[IEEE80211_NWID_LEN + 1];
struct ieee80211_nwid nwid;
if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
return (ENXIO);
@ -1260,45 +1260,36 @@ static int wi_ioctl(ifp, command, data)
}
break;
case SIOCG80211NWID:
/*
* Actually, the SSID is a variable length octet sequence
* up to 32 octets, and we should have a way to pass length
* separately. But for now, we treat as if it is terminated
* by NUL. XXX.
*/
if (sc->sc_enabled == 0)
if (sc->sc_enabled == 0) {
/* Return the desired ID */
ws = &sc->wi_netid;
else {
error = copyout(&sc->wi_netid, ifr->ifr_data,
sizeof(sc->wi_netid));
} else {
wreq.wi_type = WI_RID_CURRENT_SSID;
wreq.wi_len = WI_MAX_DATALEN;
if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) ||
wreq.wi_val[0] > IEEE80211_NWID_LEN)
error = EINVAL;
else {
ws = &ssid;
wi_set_ssid(ws, (u_int8_t *)&wreq.wi_val[1],
wi_set_ssid(&nwid, (u_int8_t *)&wreq.wi_val[1],
wreq.wi_val[0]);
error = copyout(&nwid, ifr->ifr_data,
sizeof(nwid));
}
}
if (error == 0) {
/* The caller expects NUL terminated. XXX */
if (ws->ws_len < IEEE80211_NWID_LEN)
ws->ws_id[ws->ws_len] = 0;
error = copyout(ws->ws_id, ifr->ifr_data,
IEEE80211_NWID_LEN);
}
break;
case SIOCS80211NWID:
memset(nwid, 0, sizeof(nwid));
error = copyin(ifr->ifr_data, nwid, IEEE80211_NWID_LEN);
error = copyin(ifr->ifr_data, &nwid, sizeof(nwid));
if (error != 0)
break;
len = strlen(nwid); /* XXX */
if (sc->wi_netid.ws_len == len &&
memcmp(sc->wi_netid.ws_id, nwid, len) == 0)
if (nwid.i_len > IEEE80211_NWID_LEN) {
error = EINVAL;
break;
wi_set_ssid(&sc->wi_netid, nwid, len);
}
if (sc->wi_netid.i_len == nwid.i_len &&
memcmp(sc->wi_netid.i_nwid, nwid.i_nwid, nwid.i_len) == 0)
break;
wi_set_ssid(&sc->wi_netid, nwid.i_nwid, nwid.i_len);
if (sc->sc_enabled != 0)
/* Reinitialize WaveLAN. */
wi_init(sc);
@ -1635,28 +1626,28 @@ wi_detach(self, flags)
static int
wi_set_ssid(ws, id, len)
struct wi_ssid *ws;
struct ieee80211_nwid *ws;
u_int8_t *id;
int len;
{
if (len > IEEE80211_NWID_LEN)
return (EINVAL);
ws->ws_len = len;
memcpy(ws->ws_id, id, len);
ws->i_len = len;
memcpy(ws->i_nwid, id, len);
return (0);
}
static void
wi_request_fill_ssid(wreq, ws)
struct wi_req *wreq;
struct wi_ssid *ws;
struct ieee80211_nwid *ws;
{
memset(&wreq->wi_val[0], 0, sizeof(wreq->wi_val));
wreq->wi_val[0] = ws->ws_len;
wreq->wi_val[0] = ws->i_len;
wreq->wi_len = roundup(wreq->wi_val[0], 2) / 2 + 2;
memcpy(&wreq->wi_val[1], ws->ws_id, wreq->wi_val[0]);
memcpy(&wreq->wi_val[1], ws->i_nwid, wreq->wi_val[0]);
}
static int
@ -1664,7 +1655,7 @@ wi_write_ssid(sc, type, wreq, ws)
struct wi_softc *sc;
int type;
struct wi_req *wreq;
struct wi_ssid *ws;
struct ieee80211_nwid *ws;
{
wreq->wi_type = type;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wivar.h,v 1.9 2000/05/23 08:41:49 enami Exp $ */
/* $NetBSD: if_wivar.h,v 1.10 2000/07/05 02:35:55 onoe Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@ -38,14 +38,6 @@
* Oslo IETF plenary meeting.
*/
/*
* Service set identifier.
*/
struct wi_ssid {
int ws_len;
u_int8_t ws_id[IEEE80211_NWID_LEN];
};
struct wi_softc {
struct device sc_dev;
struct ethercom sc_ethercom;
@ -79,9 +71,9 @@ struct wi_softc {
u_int16_t wi_pm_enabled;
u_int16_t wi_max_sleep;
struct wi_ssid wi_nodeid;
struct wi_ssid wi_netid;
struct wi_ssid wi_ibssid;
struct ieee80211_nwid wi_nodeid;
struct ieee80211_nwid wi_netid;
struct ieee80211_nwid wi_ibssid;
u_int8_t wi_txbuf[1596];
int wi_has_wep;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ieee80211.h,v 1.3 2000/06/09 05:31:20 onoe Exp $ */
/* $NetBSD: if_ieee80211.h,v 1.4 2000/07/05 02:35:53 onoe Exp $ */
#ifndef _NET_IF_IEEE80211_H_
@ -111,7 +111,12 @@ struct ieee80211_frame {
#define IEEE80211_NWID_LEN 32
/* nwid is u_int8_t array of IEEE80211_NWID_LEN pointed at by ifr.ifr_data */
/* nwid is pointed at by ifr.ifr_data */
struct ieee80211_nwid {
u_int8_t i_len;
u_int8_t i_nwid[IEEE80211_NWID_LEN];
};
#define SIOCS80211NWID _IOWR('i', 230, struct ifreq)
#define SIOCG80211NWID _IOWR('i', 231, struct ifreq)