Barra laterale

programmazione:c:una_funzione_per_conoscere_ip_pubblico

Una funzione per conoscere il nostro ip pubblico

Autore: Fabio Di Matteo
Ultima revisione: 28/06/2012

La funzione in questione (interamente scritta in Posix) interroga un webserver e si fa restituire il nostro ip pubblico facendo uso dei socket.

char* GetPublicIp()

restituisce un array di caratteri (stringa) contenente il nostro ip pubblico o in caso d'errore NULL

Il sorgente

get-public-ip.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
 
 
 
 
char* GetPublicIp() ;
char* keyread(char *path, char* key);
 
/* 
* GetPublicIp() restituisce il nostro ip PUBBLICO che effettua le connessioni verso internet oppure ritorna NULL
* Keyread() ,usata da GetPublicIp() , filtra l'indirizzo ip dalla risposta del webserver
* la pagina index.php  è costituita dal seguente codice <?php echo "IP ".@$REMOTE_ADDR."\n";  ?>
*/
 
 
char* GetPublicIp() 
{
	/*Cambiare se serve*/
	const unsigned short port = 80;
	const char* indirizzo_server="62.149.140.82";
	const char* request="GET /myip/index.php HTTP/1.1\r\nHost: www.freemedialab.org\r\n\r\nAccept: text/plain\r\n\r\n";
	char* temp="/tmp/temp.tmp";
	/*----------*/
 
	#define MAX 1024
 
	int sd;
	struct sockaddr_in client;
	struct hostent *hp;
	char buff[MAX];
	char risp[MAX];
 
 
	/* Dobbiamo riempire la struttura client ma prima 
 	* ci occorrono alcune
 	* informazioni che ricaviamo appoggiandoci 
 	* alla struttura hp
 	*/
	hp = gethostbyname(indirizzo_server);
 
	bzero(&client, sizeof(client));
	client.sin_family = AF_INET;
	client.sin_port = htons(port);
	client.sin_addr.s_addr =((struct in_addr*)(hp->h_addr))->s_addr;
 
	/* Creiamo il socket */
	if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    		printf("Errore nella creazione del socket!\n");
 
 
	/* connettiamoci all'host */
	if (connect(sd, (struct sockaddr *)&client, sizeof(client)) < 0){
		return NULL;
	}
 
	/*Spediamo la richiesta http*/
	sprintf(buff,"%s", request);
	send(sd, buff, sizeof(buff), MSG_WAITALL);
 
	/*Riceviamo la risposta http*/
	recv(sd, buff, sizeof(buff), MSG_WAITALL);
	sprintf(risp, "%s",buff);
	close(sd);
 
	/*Metto la risposta in un file*/
	FILE *f=fopen(temp, "w");
	fprintf(f, "%s",risp);
	fclose(f);
 
 
	/*Filtriamo il solo ip dal file*/
	char* ip; 
	ip=keyread(temp, "IP");
	unlink(temp); 
 
	/*Ritorniamo il valore dell'Ip*/
	return ip;
}
 
 
char* keyread(char *path, char* key)
{
	#define MAXKEY  50
	#define MAXVALUE  50
	#define MAXLINE 256
 
	FILE *f=fopen(path, "r");
	char valuetmp[MAXVALUE], line[MAXVALUE+MAXKEY], *value, key_now[MAXKEY] ;
	int i;
 
	while (feof(f)==0){
		fgets(line,MAXVALUE+MAXKEY,f);
		if (line[0]=='I' && line[1]=='P'){
			sscanf(line, "%s %s\n",key_now, valuetmp);
			if (strcmp(key_now, key)==0){
				value=malloc(sizeof(valuetmp));
				strcpy(value,valuetmp);
				return value;
			}
		}
	}
	fclose(f);
}
 
 
 
int main (int argc, char *argv[])
{
	if (GetPublicIp()!=NULL)
		printf("%s\n",GetPublicIp());
	else printf("Problemi di connessione\n");
 
return 0;
}

index.php

<?php 
	header("Content-Type: text/plain");
	printf( "IP %s\n", @$REMOTE_ADDR);
?>

Il makefile

CPP = gcc

all:
	$(CPP) get-public-ip.c -o get-public-ip

clean:
	rm get-public-ip

Versione glib/GIO

Di seguito la versione glib/GIO di get-public-ip .

get-public-ip.c

#include <stdio.h>
#include <stdlib.h>
 
#include <glib.h>
#include <gio/gio.h>
 
void GetFile()
{
	//Una varibile per gli eventuali errori
	GError *error=NULL;
 
	// Scarico il file index.php con le informazioni che ci interessano
	//Uri del Gfile sorgente(mySRC) e uri del Gfile di destinazione (myDEST)
	GFile*  mySRC =  g_file_new_for_uri("https://www.freemedialab.org/myip/index.php");
	GFile*  myDEST =  g_file_new_for_uri("file:///tmp/myip.txt");
 
	//Copio il file con questa semplice funzione
	g_file_copy (mySRC,  myDEST,  G_FILE_COPY_OVERWRITE, NULL, NULL,  NULL,    &error);
 
 
	//Verifico se ci sono stati errori e stampo dei messaggi
	if (error!=NULL)
	{
		 g_error("Attenzione errore nella copia: %s\n",error->message);
		 exit(-1) ;
	}
}
 
 
 
char* GetKey(gchar* group ,gchar* key)
{
	//Una varibile per gli eventuali errori
	GError *error=NULL;
 
	//Scarico il file con le nostre informazioni
	GetFile();
 
	//Mi preparo a leggere il file con le chiavi
	GKeyFile * mykey = g_key_file_new();
	g_key_file_load_from_file (mykey, "/tmp/myip.txt", G_KEY_FILE_KEEP_COMMENTS, &error);
	gchar* myval= g_key_file_get_value  (mykey, group, key, &error);
        g_key_file_free (mykey);
 
	//Gestisco eventuali errori di lettura
	if (error!=NULL)
	{
		 g_error("Attenzione errore nella lettura : %s\n",error->message);
		return NULL;
	}
 
	return myval;
} 
 
 
 
int main (int argc, char *argv[])
{
	//Inizializzo i tipi di glib
	g_type_init();
 
	g_print("%s\n",GetKey("Connessione","IP"));
	g_print("%s\n",GetKey("Connessione","HTTP_USER_AGENT"));
return 0;
}

index.php

<?php 
	header("Content-Type: text/plain");
 
	printf( "[Connessione]\n");
	printf( "IP = %s\n", @$REMOTE_ADDR);
 
	printf( "HTTP_USER_AGENT = %s\n", $_SERVER['HTTP_USER_AGENT']);
?> 

Il makefile

CPP = gcc
OPTS = `pkg-config --cflags --libs gio-2.0` 

all:
	$(CPP)  get-public-ip.c -o get-public-ip $(OPTS)

clean:
	rm get-public-ip

</code>


programmazione/c/una_funzione_per_conoscere_ip_pubblico.txt · Ultima modifica: 18/04/2018 - 15:49 (modifica esterna)