Skip to content

Commit 49d2086

Browse files
abdelali221DacoTaco
authored andcommitted
Add WD_GetSecurity and related functions.
1 parent 8862162 commit 49d2086

2 files changed

Lines changed: 231 additions & 5 deletions

File tree

gc/ogc/wd.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ enum WDIOCTLV
7777
#define IEID_SECURITY_RSN 0x30
7878
#define IEID_VENDORSPECIFIC 0xDD
7979

80+
// OUI (Organization Unified ID) :
81+
82+
#define OUI_WPA 0x0050F201
83+
8084
// Signal Strength :
8185

8286
#define WD_SIGNAL_STRONG 3
@@ -157,6 +161,44 @@ typedef struct IE_hdr
157161
u8 len;
158162
} IE_hdr;
159163

164+
// Security :
165+
166+
enum WD_SECURITY
167+
{
168+
WD_OPEN = 0x00,
169+
WD_WEP = 0x01,
170+
WD_WPA_TKIP = 0x02,
171+
WD_WPA2_AES = 0x03,
172+
WD_WPA_AES = 0x04,
173+
WD_WPA2_TKIP = 0x05,
174+
};
175+
176+
typedef struct IE_RSN
177+
{
178+
u16 Version;
179+
180+
u32 GDCS; // Group Data Cipher Suite
181+
182+
u16 PCS_Count; // Pairwise Cipher Suite
183+
184+
u16 AKMS_Count; // AKM Suite
185+
186+
u16 RSN_Capab;
187+
188+
u16 PMKID_Count;
189+
} IE_RSN;
190+
191+
typedef struct IE_WPA
192+
{
193+
u16 Version;
194+
195+
u32 GDCS; // Group Data Cipher Suite
196+
197+
u16 PCS_Count; // Pairwise Cipher Suite
198+
199+
u16 AKMS_Count; // AKM Suite
200+
} IE_WPA;
201+
160202
// General Purpose :
161203

162204
s32 NCD_LockWirelessDriver();
@@ -178,5 +220,15 @@ u8 WD_GetNumberOfIEs(BSSDescriptor* Bss);
178220
int WD_GetIELength(BSSDescriptor* Bss, u8 ID);
179221
int WD_GetIE(BSSDescriptor* Bss, u8 ID, u8* buff, u8 buffsize);
180222
int WD_GetIEIDList(BSSDescriptor* Bss, u8* buff, u8 buffsize);
223+
int WD_GetVendorSpecificIELength(BSSDescriptor* Bss, u32 OUI);
224+
int WD_GetVendorSpecificIE(BSSDescriptor* Bss, u32 OUI, u8* buff, u8 buffsize);
225+
226+
// AP Security related :
227+
228+
int WD_GetRSNEssentials(BSSDescriptor *Bss, IE_RSN *IE);
229+
int WD_GetRSNPCSList(BSSDescriptor *Bss, u8* buff, u8 buffsize);
230+
int WD_GetWPAIEEssentials(BSSDescriptor *Bss, IE_WPA *IE);
231+
int WD_GetWPA_PCSList(BSSDescriptor *Bss, u8* destbuff, u16 buffsize);
232+
u8 WD_GetSecurity(BSSDescriptor *Bss);
181233

182234
#endif

libogc/wd.c

Lines changed: 179 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

267268
int 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

Comments
 (0)