IOKit using dlopen - iphone

In my app I'm getting battery infos using this way (via IOKit).
static void print_raw_battery_state(io_registry_entry_t b_reg) {
CFBooleanRef boo;
CFNumberRef n;
int tmp;
int cur_cap = -1;
int max_cap = -1;
CFMutableDictionaryRef prop = NULL;
IOReturn ret;
ret = IORegistryEntryCreateCFProperties(b_reg, &prop, 0, 0);
if( (kIOReturnSuccess != ret) || (NULL == prop) )
{
printf("Couldn't read battery status; error = 0%08x\n", ret);
return;
}
boo = CFDictionaryGetValue(prop, CFSTR(kIOPMPSExternalConnectedKey));
printf(" external connected = %s\n",
(kCFBooleanTrue == boo) ? "yes" : "no");
boo = CFDictionaryGetValue(prop, CFSTR(kIOPMPSBatteryInstalledKey));
printf(" battery present = %s\n",
(kCFBooleanTrue == boo) ? "yes" : "no");
boo = CFDictionaryGetValue(prop, CFSTR(kIOPMPSIsChargingKey));
printf(" battery charging = %s\n",
(kCFBooleanTrue == boo) ? "yes" : "no");
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSCurrentCapacityKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &cur_cap);
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSCurrentCapacityKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &max_cap);
}
if( (-1 != cur_cap) && (-1 != max_cap) )
{
printf(" cap = %d/%d\n", cur_cap, max_cap);
gcurCapacity = cur_cap;//hab
gmaxCapacity = max_cap;//hab
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSTimeRemainingKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
NSLog(#" time REM = %d:%02d\n", tmp/60, tmp%60);
printf("time cicA = %d:%02d\n", tmp/60, tmp%60);
NSString *stringTimeRem = [NSString stringWithFormat:#"%d:%02d", tmp/60, tmp%60];
[[NSUserDefaults standardUserDefaults] setObject:stringTimeRem forKey:#"stringREM"];
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSAmperageKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
gcurrent = tmp;//hab
printf(" current = %d\n", tmp);
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSCycleCountKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
printf(" cycle count = %d\n", tmp);
gloadcycles = tmp;//hab
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSLocationKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
printf(" location = %d\n", tmp);
}
printf("\n");
CFRelease(prop);
return;}
How can I access those infos using dlopen ? I need to get IOReturn and io_registry_entry_t using dlopen, so Apple won't probably find that IOKit is there.
Thanks.

I need to get IOReturn and io_registry_entry_t using dlopen
Those are just types. They're declared in header files, and not compiled into the IOKit library. You can't get those using dlopen().
so Apple won't probably find that IOKit is there
Again, types aren't explicitly represented in the binary. If Apple finds out that you're using IOKit, then the reason for that will not be the use of these types. They're the function names that betray.
However, if you use dlopen() to retrieve a pointer to these functions, the strings representing function names will still be an open book to Apple's static analysis tools. You may have to do some additional obfuscation in order the binary not to expose directly the private function names:
NSString *secondPart = #"ateCFProperties";
NSString *firstPart = #"IORegistryEntryCre";
const char *fname = [[firstPart stringByAppendingString:secondPart] UTF8String];
IOReturn (*fptr)(io_registry_entry_t, CFMutableDictionaryRef *, int, int);
fptr = dlsym(dyld_handle, fname);
etc.

H2CO3 is correct. Just #includeing IOKit doesn't affect the compiled code at all. It's when you directly use the functions defined in the IOKit headers and link against IOKit that the private framework can clearly be seen in your app. One form of obfuscation for hiding the private framework and symbols used is a simple cipher shift. For example, using H2CO3's example:
// Deciphers string in-place and returns a pointer to it
__attribute__((always_inline)) char* decipher(char* str) {
int i, n = strlen(str);
for(i = 0; i < n; i++) str[i]--;
return str;
}
//...
char sym[] = "JPSfhjtuszFouszDsfbufDGQspqfsujft";
char fr[] = "Gsbnfxpslt";
char fmwk[] = "JPLju";
char lib[60];
decipher(fmwk);
sprintf(lib, "/System/Library/%s/%s.framework/Versions/A/%s", fr, fmwk, fmwk);
void* handle = dlopen(lib, RTLD_LAZY);
IOReturn (*fptr)(io_registry_event_t, CFMutableDictionaryRef*,i int, int);
fptr = dlsym(handle, decipher(sym));
// Now just call fptr() as if it were IORegistryEntryCreateCFProperties()
The difference between this and H2CO3's version is that this will prevent people manually analyzing the app from finding IOKit at all without a reasonable amount of expertise. Of course, a determined reverser can still find the usage of IOKit no matter how well you try to hide it. Obfuscation is useful here because App Store reviewers likely won't devote their time to reversing your app for days. Also, remember to strip your app before you submit it. I think stripping is enabled by default in Xcode, but I'm not sure. You'll need to figure that one out yourself.

#import "ViewController.h"
#import "IOKit/IOKitLib.h"
#import "IOKit/IOPSKeys.h"
#include <dlfcn.h>
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
static mach_port_t *s_kIOMasterPortDefault;
static kern_return_t (*s_IORegistryEntryCreateCFProperties)(mach_port_t entry, CFMutableDictionaryRef *properties, CFAllocatorRef allocator, UInt32 options);
static mach_port_t (*s_IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching CF_RELEASES_ARGUMENT);
static CFMutableDictionaryRef (*s_IOServiceMatching)(const char *name);
static CFMutableDictionaryRef g_powerSourceService;
static mach_port_t g_platformExpertDevice;
static BOOL foundSymbols = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
void* handle = dlopen("/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit", RTLD_LAZY);
s_IORegistryEntryCreateCFProperties = dlsym(handle, "IORegistryEntryCreateCFProperties");
s_kIOMasterPortDefault = dlsym(handle, "kIOMasterPortDefault");
s_IOServiceMatching = dlsym(handle, "IOServiceMatching");
s_IOServiceGetMatchingService = dlsym(handle, "IOServiceGetMatchingService");
if (s_IORegistryEntryCreateCFProperties && s_IOServiceMatching && s_IOServiceGetMatchingService) {
g_powerSourceService = s_IOServiceMatching("IOPMPowerSource");
g_platformExpertDevice = s_IOServiceGetMatchingService(*s_kIOMasterPortDefault, g_powerSourceService);
foundSymbols = (g_powerSourceService && g_platformExpertDevice);
}
});
if (!foundSymbols) {
return;
}
print_raw_battery_state(g_platformExpertDevice);
}
static void print_raw_battery_state(io_registry_entry_t b_reg) {
CFBooleanRef boo;
CFNumberRef n;
int tmp;
int cur_cap = -1;
int max_cap = -1;
CFMutableDictionaryRef prop = NULL;
IOReturn ret;
ret = IORegistryEntryCreateCFProperties(b_reg, &prop, 0, 0);
if( (kIOReturnSuccess != ret) || (NULL == prop) )
{
printf("Couldn't read battery status; error = 0%08x\n", ret);
return;
}
// battery dictionary
NSLog(#"prop: %#", prop);
printf("\n");
CFRelease(prop);
return;
}
}
#end
In iOS 11 and 12, you will only get a few values.

Related

Does Coverity support Interprocedural-Analysis

Program execute result:
zsh: segmentation fault ./test.out
Coverity analyse output:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// uaf
void test_1(void *p) {
free(p);
CID 358676: Read from pointer after free (USE_AFTER_FREE) [select issue]
printf("%x\n", *((int *)p));
}
// loop write
void test_2(int total, char *p) {
char a[100];
for(int i=0;i < total; i++) {
a[i] = *(p + i);
}
}
typedef struct {
char name[100];
}Person;
// uint8 *p
void test_3(Person *p) {
unsigned char *ptr = (unsigned char *)p;
for(int i=0; i < sizeof(Person) + 100; i++) {
*ptr = 'a';
}
free(p);
CID 358686: Read from pointer after free (USE_AFTER_FREE) [select issue]
printf("%x\n", *((int *)p));
}
// state machine
enum {
S_START,
S_IDLE,
S_BUSY,
S_UNKNOWN
};
int gState = S_START;
void *gPtr = NULL;
void handle_start() {
int size;
printf("input malloc size:\n");
CID 358721: Unchecked return value from library (CHECKED_RETURN) [select issue]
scanf("%d", &size);
CID 134591: Untrusted allocation size (TAINTED_SCALAR) [select issue]
gPtr = malloc(size);
gState = S_BUSY;
printf("S_START -> S_BUSY\n");
}
void handle_busy() {
char buff[100];
printf("input string:\n");
CID 358720: Unchecked return value from library (CHECKED_RETURN) [select issue]
CID 358719: Calling risky function (DC.STREAM_BUFFER) [select issue]
scanf("%s", buff);
strcpy(gPtr, buff);
puts(gPtr);
gState = S_IDLE;
printf("S_BUSY -> S_IDLE\n");
}
void handle_idle(void *p) {
char cmd;
printf("continue or exit(C/E)?");
CID 358718: Unchecked return value from library (CHECKED_RETURN) [select issue]
scanf("%c", &cmd);
if (cmd == 'c' || cmd == 'C') {
gState = S_BUSY;
printf("S_IDLE -> S_BUSY\n");
} else {
free(p);
printf("S_IDLE -> S_START\n");
printf("exit\n");
exit(0);
}
}
void process(void *p) {
switch (gState) {
case S_START:
handle_idle(p);
handle_start();
break;
case S_BUSY:
handle_busy();
break;
case S_IDLE:
handle_idle(p);
break;
default:
break;
}
}
void test_4(void *p) {
while (1)
{
process(p);
}
}
void test_5(void *pData) {
int kind = 0;
void *ptr = NULL;
printf("input kind:\n");
CID 358724: Unchecked return value from library (CHECKED_RETURN) [select issue]
scanf("%d", &kind);
1. Switch case default.
switch (kind) {
case 1:
ptr = malloc(100);
break;
case 2:
ptr = malloc(200);
break;
default:
2. alloc_fn: Storage is returned from allocation function malloc.
3. var_assign: Assigning: ptr = storage returned from malloc(64UL).
ptr = malloc(64);
4. Breaking from switch.
break;
}
5. Switch case default.
switch(kind) {
case 1:
memcpy(ptr, pData, 1000);
break;
case 2:
memcpy(ptr, pData, 2000);
break;
default:
6. noescape: Resource ptr is not freed or pointed-to in memcpy.
memcpy(ptr, pData, 64);
7. Breaking from switch.
break;
}
8. noescape: Resource (char *)ptr is not freed or pointed-to in printf.
printf("result: %s\n", (char *)ptr);
CID 358723 (#1-3 of 3): Resource leak (RESOURCE_LEAK)
9. leaked_storage: Variable ptr going out of scope leaks the storage it points to.
}
void test_6_sub(void *p) {
if (p == NULL) {
return;
}
free(p);
}
void test_6(void *p) {
test_6_sub(p);
}
int *n() {
return 0;
}
int main(void)
{
// int a;
// printf("input copy length: ");
// scanf("%d",&a);
// printf("copy %d bytes\n",a);
// void *p = malloc(100);
// memcpy(p, (char *)&a, a);
// printf("%s", (char *)&a);
gPtr = malloc(100);
char *p = gPtr;
free(gPtr);
char *name = "adfsasdfasdfasdfasdfasdf";
// test_4(p);
// test_6(p);
return *(n());
}
After analyse by coverity, I just do not get the vulnerability infomation what I want.
According to the introduction of Coverity
should be find the free of Null pointer vulnerability.
should be find the dead code
should be find the function call chains
But I got nothing
Is something wrong?
I got this test result at https://scan.coverity.com
Is the online service has some restrict?
The answer to the question in the title, "Does Coverity support Interprocedural-Analysis", is yes. The Coverity analysis indeed examines how functions call one another in an attempt to discover inconsistencies.
However, there are limitations to the precision of that interprocedural analysis. In particular, although it tries to keep track of relationships involving (at least) parameters, return values, and things pointed to by those, in most cases it cannot track relationships between global variables across function calls. (The reason for that is there are simply too many such variables and too many potential relationships, so trying to track them all would result in the analysis never terminating.)
In your example, there is an intended invariant that gPtr is a valid pointer if and only if gState == S_IDLE. Consequently, the handle_idle() function can only be called when gState == S_IDLE. The process() function violates that requirement by calling handle_idle() while gState == S_START, which (based on the clarification in the comments) is the bug you want to find. That deduction is unfortunately beyond the capabilities of the tool, so it does not report it.

GZip in Blackberry 10

Hi I am new to blackberry 10 platform. I am developing an application to unzip files compressed using GZip. I am looking for extracting folder that compressed with GZip.
I have the same problem and I solved this problem by adding the following method
gUncompress(const QByteArray &data)
{
qDebug()<<"Reached Guncompress";
qDebug()<<"size="<<data.size();
if (data.size() <= 4) {
qWarning("gUncompress: Input data is truncated");
return QByteArray();
}
QByteArray result;
int ret;
z_stream strm;
static const int CHUNK_SIZE = 1024;
char out[CHUNK_SIZE];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = data.size();
strm.next_in = (Bytef*)(data.data());
ret = inflateInit2(&strm, 15 + 32); // gzip decoding
if (ret != Z_OK)
return QByteArray();
// run inflate()
do {
strm.avail_out = CHUNK_SIZE;
strm.next_out = (Bytef*)(out);
ret = inflate(&strm, Z_NO_FLUSH);
Q_ASSERT(ret != Z_STREAM_ERROR); // state not clobbered
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; // and fall through
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return QByteArray();
}
result.append(out, CHUNK_SIZE - strm.avail_out);
} while (strm.avail_out == 0);
// clean up and return
inflateEnd(&strm);
return result;
}
I think this will solve your problem

Are there simple examples of how to parse a simple JSON file using the C-based YAJL library?

I know there is an Objective-C wrapper around YAJL, but this is a really fat thing which blows up the whole JASON parser to a ridiculous huge amount of 21 files, many of them with tiny scroll bars.
So to keep my app binary small I'd like to stick with the C-version of that parser. But I'm having a hard time finding any useful documentation for this rather than the wrapper.
Maybe someone who used the C-base can point out such a tutorial or documentation?
The documentation with C examples can be found here: http://lloyd.github.com/yajl/
The github repository with examples can be found here : https://github.com/lloyd/yajl
Here is a C example that reformats JSON from stdin:
#include <yajl/yajl_parse.h>
#include <yajl/yajl_gen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int reformat_null(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_null(g);
}
static int reformat_boolean(void * ctx, int boolean)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_bool(g, boolean);
}
static int reformat_number(void * ctx, const char * s, size_t l)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_number(g, s, l);
}
static int reformat_string(void * ctx, const unsigned char * stringVal,
size_t stringLen)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen);
}
static int reformat_map_key(void * ctx, const unsigned char * stringVal,
size_t stringLen)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen);
}
static int reformat_start_map(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_map_open(g);
}
static int reformat_end_map(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_map_close(g);
}
static int reformat_start_array(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_array_open(g);
}
static int reformat_end_array(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_array_close(g);
}
static yajl_callbacks callbacks = {
reformat_null,
reformat_boolean,
NULL,
NULL,
reformat_number,
reformat_string,
reformat_start_map,
reformat_map_key,
reformat_end_map,
reformat_start_array,
reformat_end_array
};
static void
usage(const char * progname)
{
fprintf(stderr, "%s: reformat json from stdin\n"
"usage: json_reformat [options]\n"
" -m minimize json rather than beautify (default)\n"
" -u allow invalid UTF8 inside strings during parsing\n",
progname);
exit(1);
}
int
main(int argc, char ** argv)
{
yajl_handle hand;
static unsigned char fileData[65536];
/* generator config */
yajl_gen g;
yajl_status stat;
size_t rd;
int retval = 0;
int a = 1;
g = yajl_gen_alloc(NULL);
yajl_gen_config(g, yajl_gen_beautify, 1);
yajl_gen_config(g, yajl_gen_validate_utf8, 1);
/* ok. open file. let's read and parse */
hand = yajl_alloc(&callbacks, NULL, (void *) g);
/* and let's allow comments by default */
yajl_config(hand, yajl_allow_comments, 1);
/* check arguments.*/
while ((a < argc) && (argv[a][0] == '-') && (strlen(argv[a]) > 1)) {
unsigned int i;
for ( i=1; i < strlen(argv[a]); i++) {
switch (argv[a][i]) {
case 'm':
yajl_gen_config(g, yajl_gen_beautify, 0);
break;
case 'u':
yajl_config(hand, yajl_dont_validate_strings, 1);
break;
default:
fprintf(stderr, "unrecognized option: '%c'\n\n",
argv[a][i]);
usage(argv[0]);
}
}
++a;
}
if (a < argc) {
usage(argv[0]);
}
for (;;) {
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
if (rd == 0) {
if (!feof(stdin)) {
fprintf(stderr, "error on file read.\n");
retval = 1;
}
break;
}
fileData[rd] = 0;
stat = yajl_parse(hand, fileData, rd);
if (stat != yajl_status_ok) break;
{
const unsigned char * buf;
size_t len;
yajl_gen_get_buf(g, &buf, &len);
fwrite(buf, 1, len, stdout);
yajl_gen_clear(g);
}
}
stat = yajl_complete_parse(hand);
if (stat != yajl_status_ok) {
unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
fprintf(stderr, "%s", (const char *) str);
yajl_free_error(hand, str);
retval = 1;
}
yajl_gen_free(g);
yajl_free(hand);
return retval;
}

Issue extracting .tar file with iOS-libarchive library

i am using iOS-libarchive library for .tar extraction on iphone. i am using the sample code given here at this link
http://code.google.com/p/libarchive/wiki/Examples
but i am facing problem in extracting .tar file.
i am placing my .tar file in library/simulator.../Application/617C31E0/Documents folder.
when i run application for extraction then it completes it flow successfully without giving any error code. but i could not fine that extracted folder anywhere in machine.
here is the piece of code, i am using in my application
static int copy_data(struct archive *ar, struct archive *aw)
{
int r;
const void *buff;
size_t size;
off_t offset;
for (;;) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF)
return (ARCHIVE_OK);
if (r != ARCHIVE_OK)
return (r);
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
warn("archive_write_data_block()",
archive_error_string(aw));
return (r);
}
}
}
static int verbose = 0;
static void extract(const char *filename, int do_extract, int flags)
{
struct archive *a;
struct archive *ext;
struct archive_entry *entry;
int r;
a = archive_read_new();
ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
/*
* Note: archive_write_disk_set_standard_lookup() is useful
* here, but it requires library routines that can add 500k or
* more to a static executable.
*/
archive_read_support_format_tar(a);
/*
* On my system, enabling other archive formats adds 20k-30k
* each. Enabling gzip decompression adds about 20k.
* Enabling bzip2 is more expensive because the libbz2 library
* isn't very well factored.
*/
if (filename != NULL && strcmp(filename, "-") == 0)
filename = NULL;
if ((r = archive_read_open_file(a, filename, 10240)))
fail("archive_read_open_file()",
archive_error_string(a), r);
for (;;) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_EOF)
break;
if (r != ARCHIVE_OK)
fail("archive_read_next_header()",
archive_error_string(a), 1);
if (verbose && do_extract)
msg("x ");
if (verbose || !do_extract)
msg(archive_entry_pathname(entry));
if (do_extract) {
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK)
warn("archive_write_header()",
archive_error_string(ext));
else {
copy_data(a, ext);
r = archive_write_finish_entry(ext);
if (r != ARCHIVE_OK)
fail("archive_write_finish_entry()",
archive_error_string(ext), 1);
}
}
if (verbose || !do_extract)
msg("\n");
}
archive_read_close(a);
archive_read_finish(a);
exit(0);
}
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
// Override point for customization after application launch
[window makeKeyAndVisible];
// Extract files from archive into named dir in the temp dir
NSString* databaseName = #"PIIS147020451170078X.tar";
NSArray* documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDir = [documentPaths objectAtIndex:0];
NSString* make7zResPath = [documentsDir stringByAppendingPathComponent:databaseName];
/*
NSString *tmpDirname = #"Extract7z";
NSString *make7zFilename = #"PIIS147020451170078X";//#"test.7z";
NSString *make7zResPath = [[NSBundle mainBundle] pathForResource:make7zFilename ofType:#"tar"];
*/
extract([make7zResPath cStringUsingEncoding:NSUTF8StringEncoding],1, ARCHIVE_EXTRACT_TIME);
return;
}
Please help me into this :(.
Thanks!!
I write another library that do exactly what you want: https://github.com/mhausherr/Light-Untar-for-iOS
In few words i've only implemented the minimal functions to untar a file.
Full explanation here http://blog.octo.com/en/untar-on-ios-the-pragmatic-way/

C++ code to find BSSID OF associated network

Hello I've written the following code which is a part of a project. It is used to find the ESSID of the current associated network.
But it has a flaw: it also the displays the ESSID of the network with which I am not associated i.e. if I try to associate myself with a wireless n/w and if it is unsuccessful i.e. NO DHCP OFFERS ARE RECEIVED, then also it will display the that ESSID with which I have made my attempt.
Could anyone give me an ioctl call to find the BSSID of current associated wireless n/w?. In my opinion it is the only way with which I a can mark b/w associated and non associated.
CODE:-
int main (void)
{
int errno;
struct iwreq wreq;
CStdString result = "None";
int sockfd;
char * id;
char ESSID[100];
memset(&wreq, 0, sizeof(struct iwreq));
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
fprintf(stderr, "Cannot open socket \n");
fprintf(stderr, "errno = %d \n", errno);
fprintf(stderr, "Error description is : %s\n",strerror(errno));
return result ;
}
CLog::Log(LOGINFO,"Socket opened successfully");
FILE* fp = fopen("/proc/net/dev", "r");
if (!fp)
{
// TBD: Error
return result;
}
char* line = NULL;
size_t linel = 0;
int n;
char* p;
int linenum = 0;
while (getdelim(&line, &linel, '\n', fp) > 0)
{
// skip first two lines
if (linenum++ < 2)
continue;
p = line;
while (isspace(*p))
++p;
n = strcspn(p, ": \t");
p[n] = 0;
strcpy(wreq.ifr_name, p);
id = new char[IW_ESSID_MAX_SIZE+100];
wreq.u.essid.pointer = id;
wreq.u.essid.length = 100;
if ( ioctl(sockfd,SIOCGIWESSID, &wreq) == -1 ) {
continue;
}
else
{
strcpy(ESSID,id);
return ESSID;
}
free(id);
}
free(line);
fclose(fp);
return result;
}