Subject: Re: CVS commit: syssrc
To: Dave Huang <khym@bga.com>
From: Jason R Thorpe <thorpej@zembu.com>
List: current-users
Date: 12/11/2000 10:21:25
--AhhlLboLdkugWU4S
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon, Dec 11, 2000 at 12:04:08PM -0600, Dave Huang wrote:

 > Ah! I bet _that_'s why the ray driver quit interoperating with the
 > Windows drivers after I upgraded the firmware on my Aviator 2.4 cards
 > (from what I understand, the firmware upgrade turns 'em into Aviator
 > Pros).
 > 
 > I never seem to be able to run a release kernel on my NAT/router box :)

Attached is the diff so that you can just patch your 1.5 machine.

-- 
        -- Jason R. Thorpe <thorpej@zembu.com>


--AhhlLboLdkugWU4S
Content-Type: text/plain; charset=us-ascii
Content-Description: ray.c.diff
Content-Disposition: attachment; filename=foo

Index: if_ray.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pcmcia/if_ray.c,v
retrieving revision 1.23
diff -c -r1.23 if_ray.c
*** if_ray.c	2000/11/15 01:02:18	1.23
--- if_ray.c	2000/12/11 17:25:50
***************
*** 47,52 ****
--- 47,58 ----
   *	N.B. Its unclear yet whether the Aviator 2.4 cards interoperate
   *	with other 802.11 FH 2Mbps cards, since this was also untested.
   *	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 from Corey Thomas (author the the Linux RayLink driver).
+  *	Authentication is currently limited to adhoc networks, and was
+  *	added to support a requirement of the newest Windows drivers for
+  *	the RayLink.  Tested with Aviator Pro (firmware 5.63) on Win98.
   */
  
  #include "opt_inet.h"
***************
*** 179,184 ****
--- 185,192 ----
  	u_int		sc_txfree;	/* a free count for efficiency */
  
  	u_int8_t	sc_bssid[ETHER_ADDR_LEN];	/* current net values */
+ 	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 */
***************
*** 189,196 ****
  	bus_size_t	sc_txpad;	/* tib size plus "phy" size */
  	u_int8_t	sc_deftxrate;	/* default transfer rate */
  	u_int8_t	sc_encrypt;
  
- 
  	int		sc_promisc;	/* current set value */
  	int		sc_running;	/* things we are doing */
  	int		sc_scheduled;	/* things we need to do */
--- 197,204 ----
  	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 */
  	int		sc_scheduled;	/* things we need to do */
***************
*** 261,266 ****
--- 269,283 ----
  #define	SC_BUILD_5	0x5
  #define	SC_BUILD_4	0x55
  
+ /* 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
  
  static int ray_alloc_ccs __P((struct ray_softc *, bus_size_t *, u_int, u_int));
  static bus_size_t ray_fill_in_tx_ccs __P((struct ray_softc *, size_t,
***************
*** 296,304 ****
--- 313,323 ----
  static ray_cmd_func_t ray_rccs_intr __P((struct ray_softc *, bus_size_t));
  static void ray_read_region __P((struct ray_softc *, bus_size_t,void *,size_t));
  static void ray_recv __P((struct ray_softc *, bus_size_t));
+ static void ray_recv_auth __P((struct ray_softc *, struct ieee80211_frame *));
  static void ray_report_params __P((struct ray_softc *));
  static void ray_reset __P((struct ray_softc *));
  static void ray_reset_resetloop __P((void *));
+ static int ray_send_auth __P((struct ray_softc *, u_int8_t *, u_int8_t));
  static void ray_set_pending __P((struct ray_softc *, u_int));
  static void ray_shutdown __P((void *));
  static int ray_simple_cmd __P((struct ray_softc *, u_int, u_int));
***************
*** 803,808 ****
--- 822,828 ----
  	sc->sc_txfree = RAY_CCS_NTX;
  	sc->sc_checkcounters = 0;
  	sc->sc_flags &= ~RAY_FLAGS_RESUMEINIT;
+ 	sc->sc_authstate = RAY_AUTH_UNAUTH;
  
  	/* get startup results */
  	ep = &sc->sc_ecf_startup;
***************
*** 1192,1211 ****
  		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) {
  				ifp->if_flags |= IFF_OACTIVE;
  				break;
  			}
  		}
  
  		IF_DEQUEUE(&ifp->if_snd, m0);
! 		if (!m0)
  			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) {
--- 1212,1243 ----
  		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) {
! 			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) {
***************
*** 1419,1426 ****
  	    (u_long)pktlen, nofrag));
  	RAY_DPRINTF_XMIT(("%s: received packet: len %ld\n", sc->sc_xname,
  	    (u_long)pktlen));
! 	if (pktlen > MCLBYTES
! 	    || pktlen < (sizeof(*frame) + sizeof(struct llc))) {
  		RAY_DPRINTF(("%s: PKTLEN TOO BIG OR TOO SMALL\n",
  		    sc->sc_xname));
  		ifp->if_ierrors++;
--- 1451,1457 ----
  	    (u_long)pktlen, nofrag));
  	RAY_DPRINTF_XMIT(("%s: received packet: len %ld\n", sc->sc_xname,
  	    (u_long)pktlen));
! 	if (pktlen > MCLBYTES || pktlen < sizeof(*frame)) {
  		RAY_DPRINTF(("%s: PKTLEN TOO BIG OR TOO SMALL\n",
  		    sc->sc_xname));
  		ifp->if_ierrors++;
***************
*** 1525,1537 ****
  		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));
  		m_freem(m);
  		return;
  	}
  
  	if (!memcmp(frame + 1, llc_snapid, sizeof(llc_snapid)))
  		issnap = 1;
  	else {
--- 1556,1596 ----
  		m_freem(m);
  		return;
  	}
! 	if ((fc0 & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) {
! 		switch (frame->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
! 		case IEEE80211_FC0_SUBTYPE_BEACON:
! 			/* Ignore beacon silently. */
! 			break;
! 		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_dev.dv_xname));
! #ifdef RAY_DEBUG
! 			hexdump((const u_int8_t*)frame, pktlen, 16, 4, 0);
! #endif
! 			RAY_DPRINTF(("\n"));
! 			break;
! 		}
! 		m_freem(m);
! 	} else 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));
  		m_freem(m);
  		return;
  	}
  
+ 	if (pktlen < sizeof(*frame) + sizeof(struct llc)) {
+ 		RAY_DPRINTF(("%s: pkt too small for llc (%d)\n",
+ 		    sc->sc_xname, pktlen));
+ 		m_freem(m);
+ 		return;
+ 	}
+ 
  	if (!memcmp(frame + 1, llc_snapid, sizeof(llc_snapid)))
  		issnap = 1;
  	else {
***************
*** 1590,1595 ****
--- 1649,1733 ----
  	(*ifp->if_input)(ifp, m);
  }
  
+ /*
+  * receive an auth packet
+  */
+ static void
+ ray_recv_auth(sc, frame)
+ 	struct ray_softc *sc;
+ 	struct ieee80211_frame *frame;
+ {
+ 	u_int8_t *var = (u_int8_t *)(frame + 1);
+ 
+ 	if (sc->sc_mode == SC_MODE_ADHOC) {
+ 		RAY_DPRINTF(("%s: recv auth packet:\n", sc->sc_dev.dv_xname));
+ #ifdef RAY_DEBUG
+ 		hexdump((const 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_dev.dv_xname));
+ 			if (ray_send_auth(sc, frame->i_addr2,
+ 			    OPEN_AUTH_RESPONSE) == 0) {
+ 				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_dev.dv_xname));
+ 			sc->sc_authstate = RAY_AUTH_AUTH;
+ 		}
+ 	}
+ }
+ 
+ /*
+  * send an auth packet
+  */
+ static 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) + ETHER_ADDR_LEN], *var;
+ 	struct ieee80211_frame *frame;
+ 	bus_size_t bufp;
+ 	int ccsindex;
+ 
+ 	ccsindex = ray_find_free_tx_ccs(sc, RAY_CCS_TX_FIRST);
+ 	if (ccsindex == RAY_CCS_LINK_NULL) {
+ 		RAY_DPRINTF(("%s: send auth failed -- no free tx slots\n",
+ 		    sc->sc_dev.dv_xname));
+ 		return (ENOMEM);
+ 	}
+ 
+ 	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);
+ 
+ 	var = (u_int8_t *)(frame + 1);
+ 	memset(var, 0, ETHER_ADDR_LEN);
+ 	var[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_dev.dv_xname, (u_long) sizeof(packet)));
+ 
+ 	return (0);
+ }
  
  /*
   * scan for free buffers

--AhhlLboLdkugWU4S--