PDA

Visualizza la versione completa : [C] Codice per l'invio di pacchetti tramite socket


Andre00
04-05-2007, 14:42
Su una programma per l'uso di SOCKET RAW ho trovato all'inizio questa definizioni di variabili e strutture

int sd;
char buffer[8192];
struct iphdr *ip = (struct iphdr *) buffer;
struct tcphdr *tcp = (struct tcphdr *) (buffer + sizeof(struct iphdr));

domanda che significa sta roba?
definisco intero sd ok.
definisco stringa di 8192 byte ok.
definisco puntatore alla struttura iphrd e lo pongo uguale a cosa??!?!?!??!
definisco puntatore alla struttura tcphdr e lo pongo uguale a cosa??!?!?!??!


GRAZIE E CIAO A TUTTI!

oregon
04-05-2007, 14:49
Originariamente inviato da Andre00
struct iphdr *ip = (struct iphdr *) buffer;


Dichiari un puntatore (chiamato ip) ad una struttura iphdr.

Assegni a tale puntatore il valore dell'indirizzo del buffer allocato prima.



struct tcphdr *tcp = (struct tcphdr *) (buffer + sizeof(struct iphdr));


Dichiari un puntatore (chiamato tcp) ad una struttura tcphdr.

Assegni a tale puntatore il valore dell'indirizzo del buffer spostato della lunghezza della struttura iphdr.

Praticamente il pacchetto ip e' rappresentato dal buffer.
Il secondo puntatore punta alle informazioni TCP contenute nel pacchetto.



domanda che significa sta roba?


Mi sa che prima di affrontare "sta roba", devi studiare bene come sono organizzate le informazioni nei pacchetti di rete e dare una "ripassata" all'uso dei puntatori ...

Andre00
04-05-2007, 15:07
Il problema non sono le reti so benissimo come sono strutturati header ip tcp eccc...

il mio problema sono i puntatori e lo sono sempre stati... non riesco a capirne il funzionamento.
una volta spunta un asterisco qui e la che sembra significare un contenuto invece e un indirizzo insomma una confusione immane

ma dire al puntatore ip di puntare alla struttura iphrd e porlo uguale all'indirizzo del buffer che vuol dire?
E poi io avrei fatto così per realizzare quello che dici tu:

struct iphdr *ip = &buffer;

struct iphdr *ip = (struct iphdr *) buffer;
la parte a sinistra dell'uguale mi è chiara ma è quel secondo (struct iphdr *) che mi incasina.

Perchè viene riutilizzato lo struct???! Questo davvero non lo trovo scritto in nessun manuale su puntatori o simili.

GRAZIE!

Andre00
04-05-2007, 15:18
fralaltro buffer non è una stringa?
Dopo lo script prosegue così

ip->ihl = 5; //riempio la struttura IP
ip->version = 4;
ip->tos = 16;
ip->tot_len = sizeof(buffer);
ip->id = htons(52407);
ip->frag_off = 0;
ip->ttl = 64;
ip->protocol = 6;
ip->check = 0; //per ora setto a 0 poi calcolerò quando conoscerò la dimensione del pacchetto TCP
ip->saddr = inet_addr("127.0.0.1");
ip->daddr = inet_addr("127.0.0.1");

tcp->source = htons(2485); //riempio la struttura TCP
tcp->dest = htons(21);
tcp->seq = htonl(1);
tcp->ack_seq = 0;
tcp->doff = 5;
tcp->syn = 1;
tcp->ack = 0;
tcp->window = htons(32767);
tcp->check = 0; //questo valore verrà inserito dal sistema operativo
tcp->urg_ptr = 0;

Ne dedurrei che buffer dovrebbe essere una stringa il cui spostamento di byte rispecchia la struttura di iphdr e tcphdr così decido di visualizzare buffer...

printf("Buffer %s",buffer);

e cosa ottengo? mi visualizza il carattere "E"... mah?!?!?!? io non so cosa sto facendo.... vi sarei davvero molto grato se qualcuno mi aiutasse a capire!!

GRAZIE!

Dr. Fiemost
04-05-2007, 15:23
Originariamente inviato da Andre00
struct iphdr *ip = (struct iphdr *) buffer;
la parte a sinistra dell'uguale mi è chiara ma è quel secondo (struct iphdr *) che mi incasina.
buffer è un puntatore a char, perciò per assegnarlo ad ip è necessario il cast, ovvero quel (struct iphdr *)

oregon
04-05-2007, 15:29
Originariamente inviato da Andre00
il mio problema sono i puntatori e lo sono sempre stati... non riesco a capirne il funzionamento.
una volta spunta un asterisco qui e la che sembra significare un contenuto invece e un indirizzo insomma una confusione immane

Beh ... questo e' un grosso problema per chi vuole programmare in C (in generale) ed e' un enorme problema per chi vuole scrivere programmi del tipo di cui stai parlando.

Questo perche' il puntatore e' lo strumento "principe" di un linguaggio come il C ed e' lo strumento "fondamentale" per la programmazione di rete ...

Se non hai chiarissimo il funzionamento dei puntatori, il mio consiglio e' di fermarti e studiarli a partire da zero (con un bel libro e con gli esempi passo passo di difficolta' crescente).
Ignorare l'argomento o sottovalutarlo nello studio, non ti porta da nessuna parte. Troverai sempre un "puntatore" da qualche parte, che ti fara' diventare matto (in realta', al contrario di quello che sembra, il "puntatore" e' un concetto molto semplice ...).



ma dire al puntatore ip di puntare alla struttura iphrd e porlo uguale all'indirizzo del buffer che vuol dire?

Un puntatore e' solamente l'indirizzo di un'area di memoria. Ma l'area di memoria deve esistere.

Con quella linea hai detto che l'area di memoria esistente a cui far riferimento e' l'array di 8K di caratteri

buffer

e che questa area NON e' solamente una sequenza di caratteri ma una struttura del tipo indicato dal puntatore che ne detiene l'indirizzo.



E poi io avrei fatto così per realizzare quello che dici tu:

struct iphdr *ip = &buffer;


Questa linea non e' corretta per due motivi.

Intanto, come dovresti sapere, nel caso di un array, il nome dell'array *equivale* al suo indirizzo. Quindi, scrivere buffer o &buffer e' la stessa cosa. Ecco perche'

struct iphdr *ip = buffer;

Come seconda cosa, essendo stato dichiarato buffer come "vettore di caratteri" e non come "struttura iphdr", questa scrittura avrebbe fatto generare al compilatore un warning in quanto il "tipo di dato a cui punta" il puntatore deve essere congruente con quello che sta a destra.

Dato che il puntatore punta a un dato di tipo "struct iphdr", allo stesso tipo di dato deve puntare il puntatore di destra. Dato che il puntatore buffer punta ad un "vettore di char" e' necessario far sapere al compilatore che va bene comunque in quanto il buffer verra' trattato come se fosse una "struttura iphdr" e questo fatto si indica tramite il

cast

(altro argomento che dovrai ripassare).

La forzatura del tipo di puntatore che sta a destra (il cast) si scrive cosi' ...

struct iphdr *ip = (struct iphdr *) buffer;

oregon
04-05-2007, 15:35
Originariamente inviato da Andre00
fralaltro buffer non è una stringa?

Una stringa non e' altro che una sequenza di byte (char).

Non ci vedo nulla di strano ad utilizzare una stringa come si vuole ...



Dopo lo script

Codice, non script ...



ip->ihl = 5; //riempio la struttura IP
ip->version = 4;
ip->tos = 16;
ip->tot_len = sizeof(buffer);
ip->id = htons(52407);
ip->frag_off = 0;
ip->ttl = 64;
ip->protocol = 6;
ip->check = 0; //per ora setto a 0 poi calcolerò quando conoscerò la dimensione del pacchetto TCP
ip->saddr = inet_addr("127.0.0.1");
ip->daddr = inet_addr("127.0.0.1");

tcp->source = htons(2485); //riempio la struttura TCP
tcp->dest = htons(21);
tcp->seq = htonl(1);
tcp->ack_seq = 0;
tcp->doff = 5;
tcp->syn = 1;
tcp->ack = 0;
tcp->window = htons(32767);
tcp->check = 0; //questo valore verrà inserito dal sistema operativo
tcp->urg_ptr = 0;

Ne dedurrei che buffer dovrebbe essere una stringa il cui spostamento di byte rispecchia la struttura di iphdr e tcphdr così decido di visualizzare buffer...

buffer e' un area di memoria a cui si accede tramite i puntatori che sono di un tipo particolare (ovvero di tipo iphdr e tcphdr) e quindi, *tramite i puntatori*, il compilatore accede ai singoli elementi delle strutture "mappandole" nel buffer ...

Nulla di strano ...



e cosa ottengo? mi visualizza il carattere "E"... mah?!?!?!? io non so cosa sto facendo.... vi sarei davvero molto grato se qualcuno mi aiutasse a capire!!


Sì ... ma scusa se te lo dico, da queste tue affermazioni, non mi sembra che le tue conoscenze generali del C (a parte i puntatori) siano ancora adeguate, per questo tipo di programmi in particolare, ma anche per programmi piu' semplici.

Se visualizzi come stringa un buffer che contiene degli elementi di una struttura, è ovvio che otterrai l'equivalente ASCII dei dati binari contenuti in questo ...

Non ci vedo nulla di strano in questa operazione che e' inutile proprio perche' tenti di visualizzare dei dati dal punto di vista sbagliato ... Cosa ti aspettavi di vedere?

Andre00
04-05-2007, 15:36
In teoria sarebbe a livello logico ancora meglio...
Se buffer è un puntatore a char allora dovrebbe bastare

struct iphdr *ip = buffer;

va boh.... tanto ho capito che non ne uscirò mai... il fatto è che non trovo niente online su come usare passo passo i puntatori ma non per giocare, per fare cose serie...

arrivo alla solita solfa:(detto in parole poverissime) il puntatore è una variabile che punta all'indirizzo di un'altra variabile o struttura dati ecc..
a=5

p=&a; //p= all'indirizzo di memoria di a che contiene 5

Da qui ad arrivare a tutti gli altri esempi non si sa come fare..

Comunque se avete per caso tempo e voglia di illuminarmi un po'... vi sarei gratissimo...

oregon
04-05-2007, 15:39
Originariamente inviato da Andre00
In teoria sarebbe a livello logico ancora meglio...
Se buffer è un puntatore a char allora dovrebbe bastare

struct iphdr *ip = buffer;


NO. Il puntatore a destra e quello a sinistra puntano a tipi di dati diversi! E non e' corretto.

I tipi di dati a cui i due puntatori puntano, NON devono essere diversi e quindi si usa il

cast

per indicare al compilatore che il secondo (il puntatore a destra) deve essere "reinterpretato" in quel momento, in un altro modo.



va boh.... tanto ho capito che non ne uscirò mai... il fatto è che non trovo niente online su come usare passo passo i puntatori ma non per giocare, per fare cose serie...

arrivo alla solita solfa:(detto in parole poverissime) il puntatore è una variabile che punta all'indirizzo di un'altra variabile o struttura dati ecc..
a=5

p=&a; //p= all'indirizzo di memoria di a che contiene 5

Da qui ad arrivare a tutti gli altri esempi non si sa come fare..


No ... il problema e' che si deve passare dai libri ... per un bel po' di tempo.
Lascia perdere l'apprendimento "online" ...

Andre00
04-05-2007, 15:48
Se visualizzi come stringa un buffer che contiene degli elementi di una struttura, è ovvio che otterrai l'equivalente ASCII dei dati binari contenuti in questo ...

Non ci vedo nulla di strano in questa operazione che e' inutile proprio perche' tenti di visualizzare dei dati dal punto di vista sbagliato ... Cosa ti aspettavi di vedere?

Mi aspettavo di vedere visualizzati i valori inseriti nell'header ip e tcp sotto forma di stringa.
Ovvero:

5416sizeof(buffer)eccc....
che saranno mappati come dici tu a seconda di cosa viene strutturato buffer in base a quello che a cui punta


ok che buffer è un'area di memoria ma allora come faccio a recuperare i dati che ho inserito in buffer
Ad esempio voglio visualizzare a video la versione di protocollo ip partendo da buffer.Come si fa?

printf("%d",indirizzodimemoriaincuibuffermappalaversioneip);

e come faccio a sapere qual è l'indirizzoo esatto di dove buffer ha memorizzato i dati relativi alla versione del protocollo ip?

Loading