Subject: Re: wi and MacOSX airport
To: None <current-users@netbsd.org>
From: David Young <dyoung@ojctech.com>
List: current-users
Date: 10/29/2002 22:27:29
--U+BazGySraz5kW0T
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


Grant,

I can think of two things off the top of my head.

1 Are you using WEP encryption? MacOS X, when it is configured to use
  WEP, expects for the AP to authenticate using a shared key.  NetBSD has
  temporarily lost its shared-key authentication with wi(4)'s adoption
  of the shared 802.11 state machine.

  For what it's worth, my Powerbook with Mac OS X will join an open
  network (eek!) run with -current NetBSD sources.

  It is on my to-do list to add back shared-key authentication, but I do
  not know when I will get around to it. If somebody else would like to
  add it, I have attached some of Thomas Skibo's code, which previously
  implemented the feature. It will get you started.

2 Is the "wi0: device timeout" new with this version of NetBSD? If
  you rewind the source back to my jumbo patch, you may find much
  more conservative timings borrowed from the relatively more clueful
  linux-wlan-ng folks. It *may* end the timeouts. I am not too concerned
  about timeouts themselves. It is bad if 'wi0: init failed' appears,
  also.

It would help to see the output of tcpdump -ne -D ieee802_11 -i wi0 while
your Mac tries to associate. Also, the output of "ifconfig wi0" is useful.

Dave

-- 
David Young             OJC Technologies
dyoung@ojctech.com      Engineering from the Right Brain
                        Urbana, IL * (217) 278-3933

--U+BazGySraz5kW0T
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="wi_hostap.c"

/*	$NetBSD: wi_hostap.c,v 1.1 2002/08/11 06:13:53 thorpej Exp $	*/
/*	$OpenBSD: if_wi_hostap.c,v 1.19 2002/06/25 01:59:52 millert Exp $	*/

/*
 * Copyright (c) 2002
 *	Thomas Skibo <skibo@pacbell.net>.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Thomas Skibo.
 * 4. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Thomas Skibo AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL Thomas Skibo OR HIS DRINKING PALS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * This is experimental Host AP software for Prism 2 802.11b interfaces.
 *
 * Much of this is based upon the "Linux Host AP driver for Intersil Prism2"
 * by Jouni Malinen <jkm@ssh.com> or <jkmaline@cc.hut.fi>.
 */

/* wihap_auth_req()
 *
 *	Handle incoming authentication request.  Only handle OPEN
 *	requests.
 */
void
wihap_auth_req(struct wi_softc *sc, struct wi_frame *rxfrm,
    caddr_t pkt, int len)
{
	struct ifnet		*ifp = &sc->sc_ethercom.ec_if;
	struct wihap_info	*whi = &sc->wi_hostap_info;
	struct wihap_sta_info	*sta;
	int			i;

	u_int16_t		algo;
	u_int16_t		seq;
	u_int16_t		status;
	int			challenge_len;
	u_int32_t		challenge[32];

	struct wi_80211_hdr	*resp_hdr;

	if (len < 6)
		return;

	/* Break open packet. */
	algo = take_hword(&pkt, &len);
	seq = take_hword(&pkt, &len);
	status = take_hword(&pkt, &len);
	challenge_len = 0;
	if (len > 0 && (challenge_len = take_tlv(&pkt, &len,
	    IEEE80211_ELEMID_CHALLENGE, challenge, sizeof(challenge))) < 0)
		return;

	if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
		printf("wihap_auth_req: station %s algo=0x%x seq=0x%x\n",
		    ether_sprintf(rxfrm->wi_addr2), algo, seq);

	/* Find or create station info. */
	sta = wihap_sta_find(whi, rxfrm->wi_addr2);
	if (sta == NULL) {

		/* Are we allowing new stations?
		 */
		if (whi->apflags & WIHAPFL_MAC_FILT) {
			status = IEEE80211_STATUS_OTHER; /* XXX */
			goto fail;
		}

		/* Check for too many stations.
		 */
		if (whi->n_stations >= WIHAP_MAX_STATIONS) {
			status = IEEE80211_STATUS_TOOMANY;
			goto fail;
		}

		if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
			printf("wihap_auth_req: new station\n");

		/* Create new station. */
		sta = wihap_sta_alloc(sc, rxfrm->wi_addr2);
		if (sta == NULL) {
			/* Out of memory! */
			status = IEEE80211_STATUS_TOOMANY;
			goto fail;
		}
	}
	callout_reset(&sta->tmo, hz * whi->inactivity_time,
	    wihap_sta_timeout, sta);

	/* Note: it's okay to leave the station info structure around
	 * if the authen fails.  It'll be timed out eventually.
	 */
	switch (algo) {
	case IEEE80211_AUTH_ALG_OPEN:
		if (sc->wi_authtype != IEEE80211_AUTH_OPEN) {
			seq = 2;
			status = IEEE80211_STATUS_ALG;
			goto fail;
		}
		if (seq != 1) {
			seq = 2;
			status = IEEE80211_STATUS_SEQUENCE;
			goto fail;
		}
		challenge_len = 0;
		seq = 2;
		sta->flags |= WI_SIFLAGS_AUTHEN;
		break;
	case IEEE80211_AUTH_ALG_SHARED:
		if (sc->wi_authtype != IEEE80211_AUTH_SHARED) {
			seq = 2;
			status = IEEE80211_STATUS_ALG;
			goto fail;
		}
		switch (seq) {
		case 1:
			/* Create a challenge frame. */
			if (!sta->challenge) {
				MALLOC(sta->challenge, u_int32_t *, 128,
				       M_TEMP, M_NOWAIT);
				if (!sta->challenge)
					return;
			}
			for (i = 0; i < 32; i++)
				challenge[i] = sta->challenge[i] =
					arc4random();
			
			if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
				printf("\tchallenge: 0x%x 0x%x ...\n",
				   challenge[0], challenge[1]);
			challenge_len = 128;
			seq = 2;
			break;
		case 3:
			if (challenge_len != 128 || !sta->challenge ||
			    !(le16toh(rxfrm->wi_frame_ctl) & WI_FCTL_WEP)) {
				status = IEEE80211_STATUS_CHALLENGE;
				goto fail;
			}

			for (i=0; i<32; i++)
				if (sta->challenge[i] != challenge[i]) {
					status = IEEE80211_STATUS_CHALLENGE;
					goto fail;
				}

			sta->flags |= WI_SIFLAGS_AUTHEN;
			FREE(sta->challenge, M_TEMP);
			sta->challenge = NULL;
			challenge_len = 0;
			seq = 4;
			break;
		default:
			seq = 2;
			status = IEEE80211_STATUS_SEQUENCE;
			goto fail;
		} /* switch (seq) */
		break;
	default:
		if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
			printf("wihap_auth_req: algorithm unsupported: 0x%x\n",
			   algo);
		status = IEEE80211_STATUS_ALG;
		goto fail;
	} /* switch (algo) */

	status = IEEE80211_STATUS_SUCCESS;

fail:
	if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
		printf("wihap_auth_req: returns status=0x%x\n", status);

	/* Send response. */
	resp_hdr = (struct wi_80211_hdr *)&sc->wi_txbuf;
	memset(resp_hdr, 0, sizeof(struct wi_80211_hdr));
	resp_hdr->frame_ctl = htole16(WI_FTYPE_MGMT | WI_STYPE_MGMT_AUTH);
	bcopy(rxfrm->wi_addr2, resp_hdr->addr1, ETHER_ADDR_LEN);
	bcopy(LLADDR(ifp->if_sadl), resp_hdr->addr2, ETHER_ADDR_LEN);
	bcopy(LLADDR(ifp->if_sadl), resp_hdr->addr3, ETHER_ADDR_LEN);

	pkt = (caddr_t)&sc->wi_txbuf + sizeof(struct wi_80211_hdr);
	put_hword(&pkt, algo);
	put_hword(&pkt, seq);
	put_hword(&pkt, status);
	if (challenge_len > 0)
		put_tlv(&pkt, IEEE80211_ELEMID_CHALLENGE,
			challenge, challenge_len);

	wi_mgmt_xmit(sc, (caddr_t)&sc->wi_txbuf, pkt - (caddr_t)&sc->wi_txbuf);
}

--U+BazGySraz5kW0T--