Date: Thu, 21 Jun 2001 20:47:55 -0700 From: Brooks Davis <brooks@one-eyed-alien.net> To: audit@freebsd.org, mobile@freebsd.org Subject: review request: an(4) patches Message-ID: <20010621204755.A18153@Odin.AC.HMC.Edu>
next in thread | raw e-mail | index | archive | help
--ew6BAiZeqk4r7MaW Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable I'd like to request a review of the attached patch to the an driver before I commit it. It corrects a number of minor problems with the output of ifconfig status for an cards as well as insuring that changes in the length of resources on the cards (from firmware upgrades, etc) don't smash the kernel's stack. Once this patch has spent a week or so in -current we'll be ready for the 802.11 ifconfig support MFC. -- Brooks Index: if_aironet_ieee.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/dev/an/if_aironet_ieee.h,v retrieving revision 1.5 diff -u -r1.5 if_aironet_ieee.h --- if_aironet_ieee.h 2001/05/26 09:26:58 1.5 +++ if_aironet_ieee.h 2001/06/01 23:24:42 @@ -528,7 +528,7 @@ u_int16_t an_max_noise_prev_sec; /* 0x7A */ u_int16_t an_avg_noise_prev_min; /* 0x7C */ u_int16_t an_max_noise_prev_min; /* 0x7E */ - u_int16_t an_spare[3]; + u_int16_t an_spare[5]; }; =20 #define AN_STATUS_OPMODE_CONFIGURED 0x0001 Index: if_an.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/dev/an/if_an.c,v retrieving revision 1.18 diff -u -r1.18 if_an.c --- if_an.c 2001/06/15 00:10:30 1.18 +++ if_an.c 2001/06/22 03:43:18 @@ -162,9 +162,13 @@ struct mbuf *, unsigned short)); #endif =20 +static void an_dump_record __P((struct an_softc *,struct an_ltv_gen *, + char *)); + static int an_media_change __P((struct ifnet *)); static void an_media_status __P((struct ifnet *, struct ifmediareq *)); =20 +static int an_dump=3D0; /*=20 * We probe for an Aironet 4500/4800 card by attempting to * read the default SSID list. On reset, the first entry in @@ -511,7 +515,7 @@ int status; { struct ifnet *ifp; - int id; + int id, i; =20 /* TX DONE enable lan monitor DJA an_enable_sniff(); @@ -529,12 +533,13 @@ } else ifp->if_opackets++; =20 - if (id !=3D sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons]) - printf("an%d: id mismatch: expected %x, got %x\n", - sc->an_unit, - sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons], id); + for (i =3D 0; i < AN_TX_RING_CNT; i++ ) { + if (id =3D=3D sc->an_rdata.an_tx_ring[i]) { + sc->an_rdata.an_tx_ring[i] =3D 0; + break; + } + } =20 - sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons] =3D 0; AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT); =20 return; @@ -720,9 +725,10 @@ struct an_ltv_gen *ltv; { u_int16_t *ptr; + u_int8_t *ptr2; int i, len; =20 - if (ltv->an_len =3D=3D 0 || ltv->an_type =3D=3D 0) + if (ltv->an_len <=3D 2 || ltv->an_type =3D=3D 0) return(EINVAL); =20 /* Tell the NIC to enter record read mode. */ @@ -741,20 +747,29 @@ * Read the length and record type and make sure they * match what we expect (this verifies that we have enough * room to hold all of the returned data). + * Length includes type but not length. */ len =3D CSR_READ_2(sc, AN_DATA1); - if (len > (ltv->an_len - 2)) { + if (len > (ltv->an_len-2)) { printf("an%d: record length mismatch -- expected %d, " - "got %d\n", sc->an_unit, (ltv->an_len - 2), len); - len =3D (ltv->an_len - 2); + "got %d for Rid %x\n", sc->an_unit, + ltv->an_len-2, len, ltv->an_type); + len =3D ltv->an_len -2; + }else{ + ltv->an_len =3D len +2; } =20 - ltv->an_len =3D len; - /* Now read the data. */ + len -=3D 2; /* skip the type */ ptr =3D <v->an_val; - for (i =3D 0; i < (ltv->an_len - 2) >> 1; i++) - ptr[i] =3D CSR_READ_2(sc, AN_DATA1); + for (i =3D len; i > 1; i-=3D2) + *ptr++ =3D CSR_READ_2(sc, AN_DATA1); + if (i){ + ptr2 =3D (u_int8_t *)ptr; + *ptr2 =3D CSR_READ_1(sc, AN_DATA1); + } + if (an_dump) + an_dump_record(sc, ltv, "Read"); =20 return(0); } @@ -767,19 +782,32 @@ struct an_ltv_gen *ltv; { u_int16_t *ptr; - int i; + u_int8_t *ptr2; + int i, len; + + if (an_dump) + an_dump_record(sc, ltv, "Write"); =20 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) return(EIO); - + =09 if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) return(EIO); =20 - CSR_WRITE_2(sc, AN_DATA1, ltv->an_len-2); + /* + * Length includes type but not length. + */ + len =3D ltv->an_len-2; + CSR_WRITE_2(sc, AN_DATA1, len); =09 + len -=3D 2; /* skip the type */ ptr =3D <v->an_val; - for (i =3D 0; i < (ltv->an_len - 4) >> 1; i++) - CSR_WRITE_2(sc, AN_DATA1, ptr[i]); + for (i=3Dlen; i > 1; i-=3D2) + CSR_WRITE_2(sc, AN_DATA1, *ptr++); + if (i){ + ptr2 =3D (u_int8_t *)ptr; + CSR_WRITE_1(sc, AN_DATA0, *ptr2); + } =20 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type)) return(EIO); @@ -787,6 +815,50 @@ return(0); } =20 +static void an_dump_record(sc, ltv, string) + struct an_softc *sc; + struct an_ltv_gen *ltv; + char *string; +{ + u_int8_t *ptr2; + int len; + int i; + int count =3D 0; + char buf[17], temp; + + len =3D ltv->an_len-4; + printf("an%d: RID %4x, Length %4d, Mode %s\n",=20 + sc->an_unit, ltv->an_type, ltv->an_len-4, string); + + if(an_dump =3D=3D 1 || (an_dump =3D=3D ltv->an_type)){ + printf("an%d:\t", sc->an_unit); + bzero(buf,sizeof(buf)); + + ptr2 =3D (u_int8_t *)<v->an_val; + for (i=3Dlen; i>0; i--){ + printf("%02x ", *ptr2); + + temp=3D*ptr2++; + if(temp>=3D' ' && temp <=3D'~') + buf[count]=3Dtemp; + else if(temp>=3D'A' && temp <=3D'Z') + buf[count]=3Dtemp; + else + buf[count]=3D'.'; + if(++count =3D=3D 16){ + count =3D 0; + printf("%s\n",buf); + printf("an%d:\t", sc->an_unit); + bzero(buf,sizeof(buf)); + } + } + for(; count !=3D 16; count++){ + printf(" "); + } + printf(" %s\n",buf); + } +} + static int an_seek(sc, id, off, chan) struct an_softc *sc; int id, off, chan; @@ -838,12 +910,11 @@ } =20 ptr =3D (u_int16_t *)buf; - for (i =3D 0; i < len / 2; i++) - ptr[i] =3D CSR_READ_2(sc, AN_DATA1); - i*=3D2; - if (i<len){ - ptr2 =3D (u_int8_t *)buf; - ptr2[i] =3D CSR_READ_1(sc, AN_DATA1); + for (i =3D len; i > 1; i-=3D2) + *ptr++ =3D CSR_READ_2(sc, AN_DATA1); + if (i){ + ptr2 =3D (u_int8_t *)ptr; + *ptr2 =3D CSR_READ_1(sc, AN_DATA1); } =20 return(0); @@ -865,12 +936,11 @@ } =20 ptr =3D (u_int16_t *)buf; - for (i =3D 0; i < (len / 2); i++) - CSR_WRITE_2(sc, AN_DATA0, ptr[i]); - i*=3D2; - if (i<len){ - ptr2 =3D (u_int8_t *)buf; - CSR_WRITE_1(sc, AN_DATA0, ptr2[i]); + for (i =3D len; i > 1; i-=3D2) + CSR_WRITE_2(sc, AN_DATA0, *ptr++); + if (i){ + ptr2 =3D (u_int8_t *)ptr; + CSR_WRITE_1(sc, AN_DATA0, *ptr2); } =20 return(0); @@ -1190,16 +1260,16 @@ len =3D 0; if(ireq->i_val < 4) { areq.an_type =3D AN_RID_WEP_TEMP; - for(i=3D0; i<4; i++) { - areq.an_len =3D sizeof(areq); + for(i=3D0; i<5; i++) { if (an_read_record(sc, (struct an_ltv_gen *)&areq)) { error =3D EINVAL; break; } - len =3D key->klen; - if(i =3D=3D ireq->i_val) + if(key->kindex =3D=3D 0xffff) break; + if(key->kindex =3D=3D ireq->i_val) + len =3D key->klen; /* Required to get next entry */ areq.an_type =3D AN_RID_WEP_PERM; } @@ -1219,6 +1289,25 @@ ireq->i_val =3D 8; break; case IEEE80211_IOC_WEPTXKEY: + /* + * For some strange reason, you have to read all + * keys before you can read the txkey. + */ + areq.an_type =3D AN_RID_WEP_TEMP; + for(i=3D0; i<5; i++) { + if (an_read_record(sc, + (struct an_ltv_gen *)&areq)) { + error =3D EINVAL; + break; + } + if(key->kindex =3D=3D 0xffff) + break; + /* Required to get next entry */ + areq.an_type =3D AN_RID_WEP_PERM; + } + if(error) + break; + areq.an_type =3D AN_RID_WEP_PERM; key->kindex =3D 0xffff; if (an_read_record(sc, Index: if_anreg.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/dev/an/if_anreg.h,v retrieving revision 1.7 diff -u -r1.7 if_anreg.h --- if_anreg.h 2001/05/26 09:26:58 1.7 +++ if_anreg.h 2001/06/01 23:24:42 @@ -532,7 +532,7 @@ u_int16_t an_max_noise_prev_sec; /* 0x7A */ u_int16_t an_avg_noise_prev_min; /* 0x7C */ u_int16_t an_max_noise_prev_min; /* 0x7E */ - u_int16_t an_spare[3]; + u_int16_t an_spare[5]; }; =20 #define AN_STATUS_OPMODE_CONFIGURED 0x0001 --=20 Any statement of the form "X is the one, true Y" is FALSE. PGP fingerprint 655D 519C 26A7 82E7 2529 9BF0 5D8E 8BE9 F238 1AD4 --ew6BAiZeqk4r7MaW Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.4 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQE7Mr/pXY6L6fI4GtQRAmBDAJwNPkSvxJW/X4TbsEzYeCdxxNdT/wCg09n1 q4qyjZvd+m2pLXhFZssD494= =pkgJ -----END PGP SIGNATURE----- --ew6BAiZeqk4r7MaW-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010621204755.A18153>