@@ -225,12 +225,13 @@ int WD_GetIE(BSSDescriptor* Bss, u8 ID, u8* buff, u8 buffsize) {
225225 u16 IEslen = Bss -> IEs_length ;
226226
227227 u8 * ptr = (u8 * )Bss ;
228- IE_hdr * hdr = (IE_hdr * )& ptr [sizeof (BSSDescriptor )];
228+ IE_hdr * hdr = (IE_hdr * )& ptr [sizeof (BSSDescriptor ) + 1 ];
229229 u16 offset = 0 ;
230230
231- while (hdr -> ID != ID && (offset + hdr -> len ) < IEslen && hdr -> len != 0 )
231+ while ((offset + hdr -> len ) < IEslen )
232232 {
233233 hdr = (IE_hdr * )& ptr [sizeof (BSSDescriptor ) + offset ];
234+ if (hdr -> ID == ID ) break ;
234235 offset += hdr -> len + sizeof (IE_hdr );
235236 }
236237
@@ -266,23 +267,196 @@ int WD_GetIEIDList(BSSDescriptor* Bss, u8* buff, u8 buffsize) {
266267
267268int WD_GetVendorSpecificIE (BSSDescriptor * Bss , u32 OUI , u8 * buff , u8 buffsize ) {
268269 if (!buff ) return WD_INVALIDBUFF ;
270+ u16 IEslen = Bss -> IEs_length ;
271+
272+ u8 * ptr = (u8 * )Bss ;
273+ IE_hdr * hdr = (IE_hdr * )& ptr [sizeof (BSSDescriptor )];
274+ u16 offset = 0 ;
275+
276+ u32 tgtOUI = 0 ;
277+
278+ while ((offset + hdr -> len ) < IEslen && hdr -> len != 0 )
279+ {
280+ hdr = (IE_hdr * )& ptr [sizeof (BSSDescriptor ) + offset ];
281+ tgtOUI = ptr [sizeof (BSSDescriptor ) + offset + 2 ] << 24 |
282+ ptr [sizeof (BSSDescriptor ) + offset + 3 ] << 16 |
283+ ptr [sizeof (BSSDescriptor ) + offset + 4 ] << 8 |
284+ ptr [sizeof (BSSDescriptor ) + offset + 5 ];
285+ if (hdr -> ID == IEID_VENDORSPECIFIC && tgtOUI == OUI ) break ;
286+ offset += hdr -> len + sizeof (IE_hdr );
287+ }
288+
289+ if (hdr -> ID != IEID_VENDORSPECIFIC ||
290+ tgtOUI != OUI ) return WD_NOTFOUND ;
291+ if (buffsize < hdr -> len ) return WD_BUFFTOOSMALL ;
269292
293+ memset (buff , 0 , buffsize );
294+ memcpy (buff , & ptr [offset + sizeof (BSSDescriptor ) + sizeof (IE_hdr )], hdr -> len );
295+
296+ return WD_SUCCESS ;
297+ }
298+
299+ int WD_GetVendorSpecificIELength (BSSDescriptor * Bss , u32 OUI ) {
270300 u16 IEslen = Bss -> IEs_length ;
271301
272302 u8 * ptr = (u8 * )Bss ;
273303 IE_hdr * hdr = (IE_hdr * )& ptr [sizeof (BSSDescriptor )];
274304 u16 offset = 0 ;
275305
276- while ((hdr -> ID != IEID_VENDORSPECIFIC && (u32 )ptr [sizeof (BSSDescriptor ) + offset + 2 ] != OUI ) && (offset + hdr -> len ) < IEslen && hdr -> len != 0 )
306+ u32 tgtOUI = 0 ;
307+
308+ while ((offset + hdr -> len ) < IEslen && hdr -> len != 0 )
277309 {
278310 hdr = (IE_hdr * )& ptr [sizeof (BSSDescriptor ) + offset ];
311+ tgtOUI = ptr [sizeof (BSSDescriptor ) + offset + 2 ] << 24 |
312+ ptr [sizeof (BSSDescriptor ) + offset + 3 ] << 16 |
313+ ptr [sizeof (BSSDescriptor ) + offset + 4 ] << 8 |
314+ ptr [sizeof (BSSDescriptor ) + offset + 5 ];
315+ if (hdr -> ID == IEID_VENDORSPECIFIC && tgtOUI == OUI ) break ;
279316 offset += hdr -> len + sizeof (IE_hdr );
280317 }
281318
282- if ( hdr -> ID != IEID_VENDORSPECIFIC ||
283- (u32 )ptr [sizeof (BSSDescriptor ) + offset + 2 ] != OUI ) return WD_NOTFOUND ;
319+ if (hdr -> ID != IEID_VENDORSPECIFIC ||
320+ tgtOUI != OUI ) return WD_NOTFOUND ;
321+
322+ return hdr -> len ;
323+ }
324+
325+ int WD_GetRSN_PCSList (BSSDescriptor * Bss , u8 * destbuff , u16 buffsize ) {
326+ if (!Bss ) return WD_INVALIDBUFF ;
327+ if (!destbuff ) return WD_INVALIDBUFF ;
328+
329+ IE_RSN IE ;
330+
331+ int ret = WD_GetRSNEssentials (Bss , & IE );
332+
333+ if (ret < 0 ) return WD_INVALIDBUFF ;
334+ if (IE .PCS_Count * 4 > buffsize ) return WD_BUFFTOOSMALL ;
335+
336+ u8 IE_len = WD_GetIELength (Bss , IEID_SECURITY_RSN );
337+
338+ u8 buff [IE_len ];
339+ WD_GetIE (Bss , IEID_SECURITY_RSN , buff , IE_len );
340+
341+ memset (destbuff , 0 , buffsize );
342+ memcpy (destbuff , & buff [8 ], IE .PCS_Count * 4 );
284343
285344 return WD_SUCCESS ;
286345}
287346
347+ int WD_GetWPA_PCSList (BSSDescriptor * Bss , u8 * destbuff , u16 buffsize ) {
348+ if (!Bss ) return WD_INVALIDBUFF ;
349+ if (!destbuff ) return WD_INVALIDBUFF ;
350+
351+ IE_WPA IE ;
352+
353+ int ret = WD_GetWPAIEEssentials (Bss , & IE );
354+
355+ if (ret < 0 ) return WD_INVALIDBUFF ;
356+ if (IE .PCS_Count * 4 > buffsize ) return WD_BUFFTOOSMALL ;
357+
358+ u8 IE_len = WD_GetIELength (Bss , IEID_SECURITY_RSN );
359+ u8 buff [IE_len ];
360+ WD_GetIE (Bss , IEID_SECURITY_RSN , buff , IE_len );
361+
362+ memset (destbuff , 0 , buffsize );
363+ memcpy (destbuff , & buff [8 ], IE .PCS_Count * 4 );
364+
365+ return WD_SUCCESS ;
366+ }
367+
368+ int WD_GetRSNEssentials (BSSDescriptor * Bss , IE_RSN * IE ) {
369+ if (!Bss ) return WD_INVALIDBUFF ;
370+ if (!IE ) return WD_INVALIDBUFF ;
371+
372+ u8 IE_size = WD_GetIELength (Bss , IEID_SECURITY_RSN );
373+ if (IE_size < 0 ) return WD_NOTFOUND ;
374+
375+ u8 buff [IE_size ];
376+
377+ WD_GetIE (Bss , IEID_SECURITY_RSN , buff , IE_size );
378+
379+ u8 offset = 0 ;
380+ IE -> Version = buff [0 + offset ] | buff [1 + offset ] << 8 ;
381+ offset += 2 ;
382+ IE -> GDCS = buff [0 + offset ] << 24 | buff [1 + offset ] << 16 | buff [2 + offset ] << 8 | buff [3 + offset ];
383+ offset += 4 ;
384+ IE -> PCS_Count = buff [0 + offset ] | buff [1 + offset ] << 8 ;
385+ offset += 2 + IE -> PCS_Count * 4 ;
386+ IE -> AKMS_Count = buff [0 + offset ] | buff [1 + offset ] << 8 ;
387+ offset += 2 + IE -> AKMS_Count * 4 ;
388+
389+ return WD_SUCCESS ;
390+ }
391+
392+ int WD_GetWPAIEEssentials (BSSDescriptor * Bss , IE_WPA * IE ) {
393+ if (!Bss ) return WD_INVALIDBUFF ;
394+ if (!IE ) return WD_INVALIDBUFF ;
395+
396+ u8 IE_size = WD_GetVendorSpecificIELength (Bss , OUI_WPA );
397+ if (IE_size < 0 ) return WD_NOTFOUND ;
398+
399+ u8 buff [IE_size ];
400+
401+ WD_GetVendorSpecificIE (Bss , OUI_WPA , buff , IE_size );
402+
403+ u8 offset = 4 ;
404+ IE -> Version = buff [0 + offset ] | buff [1 + offset ] << 8 ;
405+ offset += 2 ;
406+ IE -> GDCS = buff [0 + offset ] << 24 | buff [1 + offset ] << 16 | buff [2 + offset ] << 8 | buff [3 + offset ];
407+ offset += 4 ;
408+ IE -> PCS_Count = buff [0 + offset ] | buff [1 + offset ] << 8 ;
409+ offset += 2 + IE -> PCS_Count * 4 ;
410+ IE -> AKMS_Count = buff [0 + offset ] | buff [1 + offset ] << 8 ;
411+ offset += 2 + IE -> AKMS_Count * 4 ;
412+
413+ return WD_SUCCESS ;
414+ }
415+
416+ u8 WD_GetSecurity (BSSDescriptor * Bss ) {
417+ if (!Bss ) return WD_INVALIDBUFF ;
418+ if (!(Bss -> Capabilities & CAPAB_SECURED_FLAG )) return WD_OPEN ;
419+
420+ int ie_len = WD_GetVendorSpecificIELength (Bss , OUI_WPA );
421+
422+ if (ie_len != WD_NOTFOUND && ie_len > 0 ) { // WPA
423+ IE_WPA IE ;
424+ WD_GetWPAIEEssentials (Bss , & IE );
425+
426+ u8 buff [IE .PCS_Count * 4 ];
427+ WD_GetWPA_PCSList (Bss , buff , IE .PCS_Count * 4 );
428+
429+ u8 offset = 0 ;
430+
431+ for (int i = 0 ; i < IE .PCS_Count ; i ++ ) {
432+ if (buff [offset + 3 ] == 0x02 ) return WD_WPA_TKIP ;
433+ else if (buff [offset + 3 ] == 0x04 ) return WD_WPA_AES ;
434+ offset += 4 ;
435+ }
436+ }
437+
438+ ie_len = WD_GetIELength (Bss , IEID_SECURITY_RSN );
439+
440+ if (ie_len != WD_NOTFOUND && ie_len > 0 ) { // WPA2
441+ IE_RSN IE ;
442+ WD_GetRSNEssentials (Bss , & IE );
443+
444+ u8 ret = 0 ;
445+
446+ u8 buff [IE .PCS_Count * 4 ];
447+ WD_GetRSN_PCSList (Bss , buff , IE .PCS_Count * 4 );
448+
449+ u8 offset = 0 ;
450+
451+ for (int i = 0 ; i < IE .PCS_Count ; i ++ ) {
452+ if (buff [offset + 3 ] == 0x02 ) ret = WD_WPA2_TKIP ;
453+ if (buff [offset + 3 ] == 0x04 ) ret = WD_WPA2_AES ;
454+ offset += 4 ;
455+ }
456+
457+ return ret ;
458+ }
459+ return WD_WEP ;
460+ }
461+
288462#endif
0 commit comments