Hi all,

Since yesterday I have been trying to understand why "char**
essid_list" is working inside getInstalledEssidList(&count,
essid_list) but failing as soon as I try to access essid_list[0]
outside the function.

Both the source and the gdb text output are attached.

Any helpful pointers are appreciated.


Edward.
gdb auto-conn
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from auto-conn...done.
(gdb) b 202
Breakpoint 1 at 0x401223: file automated_scanner.c, line 202.
(gdb) r
Starting program: /home/edbarx/netman/backend_src/src/auto-conn 

Breakpoint 1, autoWirelessScanPlus () at automated_scanner.c:202
202             getInstalledEssidList(&count, essid_list);
(gdb) s
getInstalledEssidList (count=0x7fffffffe284, essid_list=0x1) at 
automated_scanner.c:48
48              int el_size = 0; // stands for essid_list size
(gdb) n
51              if ((dir = opendir(IFACES_PATH)) != 0) {
(gdb) n
52                      while ((ent = readdir (dir)) != 0)
(gdb) n
54                                      strcmp(".", ent->d_name) != 0 && 
(gdb) n
53                              if(
(gdb) n
52                      while ((ent = readdir (dir)) != 0)
(gdb) n
54                                      strcmp(".", ent->d_name) != 0 && 
(gdb) n
53                              if(
(gdb) n
55                                      strcmp("..", ent->d_name) != 0
(gdb) n
54                                      strcmp(".", ent->d_name) != 0 && 
(gdb) n
57                                      (*count)++;
(gdb) n
62                                      encoded_essid = ent->d_name;
(gdb) n
63                                      if (el_size < *count) {
(gdb) p encoded_essid
$1 = 0x60206b "EB-TP-LNK67"
(gdb) n
64                                              el_size =+ 10;
(gdb) n
65                                              if (el_size == 10)
(gdb) n
66                                                      essid_list = 
calloc(*count + 9, sizeof(char*));
(gdb) n
70                                      essid_list[*count - 1] = 
calloc(strlen(encoded_essid) + 1, sizeof(char));
(gdb) n
71                                      strcpy(essid_list[*count - 1], 
encoded_essid);
(gdb) n
52                      while ((ent = readdir (dir)) != 0)
(gdb) p essid_list[0]
$2 = 0x60a0b0 "EB-TP-LNK67"
(gdb) n
54                                      strcmp(".", ent->d_name) != 0 && 
(gdb) n
53                              if(
(gdb) n
55                                      strcmp("..", ent->d_name) != 0
(gdb) n
54                                      strcmp(".", ent->d_name) != 0 && 
(gdb) n
52                      while ((ent = readdir (dir)) != 0)
(gdb) n
73                      closedir(dir);
(gdb) n
87              return 0;
(gdb) n
88      }
(gdb) n
autoWirelessScanPlus () at automated_scanner.c:206
206             getRadiatingWifiList(&active_wifis, active_wifi_list);
(gdb) p essid_list[0]
Cannot access memory at address 0x1
(gdb) s
getRadiatingWifiList (active_wifis=0x7fffffffe280, active_wifi_list=0x0) at 
automated_scanner.c:94
94              char * scan_buffer = NULL;
(gdb) n
96              scan_buffer = calloc(1024, 1);
(gdb) n
99              shell_reader = popen("/sbin/iwlist wlan0 scan | grep 
\"Quality=\\|ESSID:\"", "r");
(gdb) n
101             if(!shell_reader) {
(gdb) n
113             int z = 0;
(gdb) n
115             *active_wifis = -1;
(gdb) n
116             while((scan_buffer = fgets(scan_buffer, 1024, shell_reader)))
(gdb) n
118                     z++;
(gdb) n
119                     if (z == 1) 
(gdb) n
120                             active_wifi_list = calloc(sizeof(void*), 10);
(gdb) n
124                     if (z % 2 == 1) {
(gdb) n
125                                     active_wifis++;
(gdb) n
126                                     tmp_wifi_quality = 
calloc(sizeof(wifi_quality), 1);
(gdb) n
127                                     active_wifi_list[*active_wifis] = 
tmp_wifi_quality;
(gdb) n
129                                     char* substr = strstr((char *) 
scan_buffer, "Signal level=");
(gdb) n
130                                     substr = strstr(substr, "=");
(gdb) n
131                                     char* endstr = strstr(substr + 1, " ");
(gdb) n
133                                     strncpy(tmpstr, substr + 1, endstr - 
substr - 1);
(gdb) n
134                                     tmpstr[endstr - substr + 1] = '\0';
(gdb) n
136                                     tmp_wifi_quality->quality = 
strtod(tmpstr, NULL);
(gdb) n
144                                     double log_quality = 
(tmp_wifi_quality->quality)/10;
(gdb) n
145                                     tmp_wifi_quality->quality = pow(10, 
log_quality);
(gdb) n
116             while((scan_buffer = fgets(scan_buffer, 1024, shell_reader)))
(gdb) n
118                     z++;
(gdb) n
119                     if (z == 1) 
(gdb) n
121                     else if (z % 20 == 0)
(gdb) n
124                     if (z % 2 == 1) {
(gdb) n
148                                     char* tmpstr = strtok((char*) 
scan_buffer, "\"");
(gdb) n
149                                     tmpstr = strtok(NULL, "\"");    
(gdb) n
151                                     strncpy(tmp_wifi_quality->name,  
tmpstr, strlen(tmpstr)); 
(gdb) n
116             while((scan_buffer = fgets(scan_buffer, 1024, shell_reader)))
(gdb) n
156             if (scan_buffer != NULL) free(scan_buffer);
(gdb) n
157             pclose(shell_reader);   
(gdb) n
158     }
(gdb) n
autoWirelessScanPlus () at automated_scanner.c:209
209             sortRadiatingWifisList(active_wifis, active_wifi_list);
(gdb) s
sortRadiatingWifisList (active_wifis=-1, active_wifi_list=0x0) at 
automated_scanner.c:163
163             int i, j = 0;
(gdb) n
164             while (j < active_wifis) {
(gdb) n
177     }
(gdb) n
autoWirelessScanPlus () at automated_scanner.c:212
212             int wireless = 0;
(gdb) s
214             for (counter = 0; counter < count; counter++) {
(gdb) n
215                     char* tmp_essid_list_item = essid_list[counter];
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401281 in autoWirelessScanPlus () at automated_scanner.c:215
215                     char* tmp_essid_list_item = essid_list[counter];
(gdb) 
/*
    netman - A Network Connection Manager
    Copyright (C) 2015  Edward Bartolo

    "netman" is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    "netman" is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with "netman".  If not, see <http://www.gnu.org/licenses/>.
*/

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <alloca.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <math.h>

//#include "core_functions.h"
//#include "essid_encoder.h"
#include "paths.h"

#define MAX_ESSID_LENGTH 1024



typedef struct {
	double quality;
	char name[MAX_ESSID_LENGTH];
} wifi_quality;


int getInstalledEssidList(int* count, char** essid_list)
{
	DIR * dir;
	struct dirent * ent;
	int el_size = 0; // stands for essid_list size
	
	// First get a list of installed wireless "interfaces" files
	if ((dir = opendir(IFACES_PATH)) != 0) {
		while ((ent = readdir (dir)) != 0)
			if(
				strcmp(".", ent->d_name) != 0 && 
				strcmp("..", ent->d_name) != 0
			) {
				(*count)++;
							
				char* encoded_essid;
				int err;

				encoded_essid = ent->d_name;
				if (el_size < *count) {
					el_size =+ 10;
					if (el_size == 10)
						essid_list = calloc(*count + 9, sizeof(char*));
						else essid_list = realloc(essid_list, (*count + 9)*sizeof(char*));
				}	
					
				essid_list[*count - 1] = calloc(strlen(encoded_essid) + 1, sizeof(char));
				strcpy(essid_list[*count - 1], encoded_essid);
			} 
		closedir(dir);
	} 
	else {
		int old_errno = errno;

		fprintf(
			stderr, "Error: "
			"loadExisting(): opendir(%s) failed (Error: %s)\n",
			IFACES_PATH, strerror(errno)
		);

		return old_errno;
	}
	
	return 0;
}

int getRadiatingWifiList(int* active_wifis, void** active_wifi_list)
{
	// Hopefully, here we have a list of installed essid interfaces files
	FILE * shell_reader;
	char * scan_buffer = NULL;
	int err;
	scan_buffer = calloc(1024, 1);
	
	// read output lines containing 'Quality=' and 'ESSID:'
	shell_reader = popen("/sbin/iwlist wlan0 scan | grep \"Quality=\\|ESSID:\"", "r");

	if(!shell_reader) {
		fprintf(
			stderr, 
			"ERROR: power_scan(): "
			"popen() failed (Error: %s)\n", 
			strerror(errno)
		);

		return -1;
	}

	wifi_quality* tmp_wifi_quality;
	int z = 0;
	
	*active_wifis = -1;
	while((scan_buffer = fgets(scan_buffer, 1024, shell_reader)))
	{
		z++;
		if (z == 1) 
			active_wifi_list = calloc(sizeof(void*), 10);
		else if (z % 20 == 0)
			active_wifi_list = realloc(active_wifis + 10, sizeof(void*));
			
		if (z % 2 == 1) {
				active_wifis++;
				tmp_wifi_quality = calloc(sizeof(wifi_quality), 1);
				active_wifi_list[*active_wifis] = tmp_wifi_quality;
				
				char* substr = strstr((char *) scan_buffer, "Signal level=");
				substr = strstr(substr, "=");
				char* endstr = strstr(substr + 1, " ");
				char tmpstr[MAX_ESSID_LENGTH];
				strncpy(tmpstr, substr + 1, endstr - substr - 1);
				tmpstr[endstr - substr + 1] = '\0';
				
				tmp_wifi_quality->quality = strtod(tmpstr, NULL);
				
				// P(dBm) = 10 · log10( P(mW) / 1mW)
				// we want the absolute power
				
				// P(mW) / 1mW = P*
				// P* = antilog(P/10)
				
				double log_quality = (tmp_wifi_quality->quality)/10;
				tmp_wifi_quality->quality = pow(10, log_quality);
		  }
		else {
				char* tmpstr = strtok((char*) scan_buffer, "\"");
				tmpstr = strtok(NULL, "\"");	
				
				strncpy(tmp_wifi_quality->name,  tmpstr, strlen(tmpstr)); 
			}
		//printf("%s", scan_buffer);
	}
	
	if (scan_buffer != NULL) free(scan_buffer);
	pclose(shell_reader);	
}

// sort radiating wifis according to signal strength
int sortRadiatingWifisList(const int active_wifis, void** active_wifi_list)
{
	int i, j = 0;
	while (j < active_wifis) {
		for (i = active_wifis - j - 1; i == 0; i--)
			if (
				((wifi_quality*) active_wifi_list[i - 1])->quality <
				((wifi_quality*) active_wifi_list[i])->quality
			) {
				wifi_quality* awifi_quality = (wifi_quality*) active_wifi_list[i - 1];
			  active_wifi_list[i - 1] = active_wifi_list[i];
				active_wifi_list[i] = awifi_quality;
			}
			
		j++;				 
	}
}

int wifiEssidInstalled(const int active_wifis, void** active_wifi_list, char* essid)
{
	int i;
	for (i = 0; i <= active_wifis; i++) {
		if (strcmp(((wifi_quality*) active_wifi_list[i])->name, essid) == 0) {
			return i;
		}
	}
	
	return -1;	// ie not found
}

int autoWirelessScanPlus()
{
	char** essid_list;
	int count = 0;
	
	int active_wifis;
	void** active_wifi_list;
	
	char* scan_buffer;
	
	// get a list of currently installed wifi essids
	getInstalledEssidList(&count, essid_list);
	//fprintf(stdout, essid_list[0], "\n");	
	
	// get a list of irradiating wifis
	getRadiatingWifiList(&active_wifis, active_wifi_list);
	
	// sort the radiating wifis in descending order according to strength
	sortRadiatingWifisList(active_wifis, active_wifi_list);
	
	int connection_result;
	int wireless = 0;
	int counter;
	for (counter = 0; counter < count; counter++) {
		char* tmp_essid_list_item = essid_list[counter];
		if (wifiEssidInstalled(active_wifis, active_wifi_list, tmp_essid_list_item) > -1) {
			FILE * shell_reader;
	
			// required command for popen: /sbin/ifup wlan0 -i IFACES_PATH"/"essid_list[counter]
			char ifup_cmd[40 + MAX_ESSID_LENGTH];
			strncpy(ifup_cmd, "/sbin/ifup wlan0 -i "IFACES_PATH"/", 38);
			strncat(ifup_cmd, essid_list[counter], strlen(essid_list[counter]));			
			
			shell_reader = popen(ifup_cmd, "r");
			
			if(!shell_reader) {
				fprintf(
					stderr, 
					"ERROR: autoWirelessScanPlus(): "
					"popen() failed (Error: %s)\n", 
					strerror(errno)
				);
			}
			pclose(shell_reader);
			
			shell_reader = popen(
				"/bin/ip a | grep \"state UP\"", "r"
			);
			
			if(!shell_reader) {
				fprintf(
					stderr, 
					"ERROR: autoWirelessScanPlus(): "
					"popen() failed (Error: %s)\n", 
					strerror(errno)
				);
			}
			
			scan_buffer = (char *) calloc(1025, 1);
			if (scan_buffer == NULL)
			{
				fprintf(
					stderr, 
					"ERROR: autoWirelessScanPlus(): "
					"popen() failed (Error: %s)\n", 
					strerror(errno)
				);
			}
	
			while((scan_buffer = fgets(scan_buffer, 1024, shell_reader))) {
				if (strstr((char *) scan_buffer, "wlan0") != NULL)
					wireless++;
				//else if (strstr((char *) scan_buffer, "eth0") != NULL)
				//	wired++;
			}
			pclose(shell_reader);	
			free(scan_buffer);
			
			if (wireless) break; // if connected to wireless stop iterating
		}
	}
		
			
	// free all the allocated memory
	// free the essid string list
	int u;
	for (u = 0; u < count; u++)
	  free(essid_list[u]);
		
	free(essid_list);
	
	// free the radiating wifis list
	for (u = 0; u <= active_wifis; u++)
		free((wifi_quality*) active_wifi_list[u]);
		
	free((void*) active_wifi_list);	
}

int main(int argc, char *argv[])
{
	autoWirelessScanPlus();
	return 0;
}
_______________________________________________
Dng mailing list
[email protected]
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng

Reply via email to