Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C] programmazione di rete

    Ciao a tutti, sto cercando di realizzare un'applicazione che resti in ascolto sulla rete e stampi tutto quello che passa, uno sniffer insomma.
    I pacchetti vengono presi da iptables.
    Attualmente riesco solo a stampare alcune cose ma non altre che mi interesserebbero di piu. Posto il codice:
    codice:
    /*
     * This code is GPL.
     */
    #include <linux/netfilter.h>
    #include <netinet/ip.h>
    #include <netinet/tcp.h>
    #include <libipq.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define BUFSIZE 2048
    
    static void die (struct ipq_handle *h) {
    	ipq_perror ("there was an error");
    	ipq_destroy_handle (h);
    	exit (1);
    }
    
    int main (int argc, char **argv) {
    	int status;
    	unsigned char buf[BUFSIZE];
    	struct ipq_handle *h;
    
    	/* Creating an handle */
    	h = ipq_create_handle (0, PF_INET);
    	if (!h)
    		die (h);
    
    	/* Copying all the packet and not only metadata */
    	status = ipq_set_mode (h, IPQ_COPY_PACKET, BUFSIZE);
    	if (status < 0)
    		die (h);
    
    	do {
    		status = ipq_read (h, buf, BUFSIZE, 0);
    		if (status < 0)
    			die (h);
    
    		switch (ipq_message_type (buf)) {
    		
    			case NLMSG_ERROR: {
    			fprintf (stderr, "Received error message %d\n",
    				 ipq_get_msgerr (buf));
    			break;
    		}
    		
    		case IPQM_PACKET: {
    			ipq_packet_msg_t *m = ipq_get_packet (buf);
    			
    			struct iphdr *ip = (struct iphdr *) m->payload;
    			
    			//struct in_addr s_addr = ip->ip_src;
    			//struct in_addr d_addr = ip->ip_dst;
    			u_int32_t src_addr = ntohl(ip->saddr);
    			
    			fprintf(stderr, "Source address = %d", src_addr);
    			
    			struct tcphdr *tcp = (struct tcphdr *) (m->payload + (4 * ip->ihl));
    			int src_port = ntohs (tcp->source);
    			int dest_port = ntohs (tcp->dest);
    
    			fprintf (stderr, "\nReceived a packet!!!\n");
    			fprintf (stderr, "Source port = %d - ", src_port);
    			fprintf (stderr, "Destination port = %d\n", dest_port);
    			fprintf (stderr, "Syn = %d - ", tcp->syn);
    			fprintf (stderr, "RST = %d - ", tcp->rst);
    			fprintf (stderr, "Fyn = %d - ", tcp->fin);
    			fprintf (stderr, "Ack = %d\n", tcp->ack);
    			fprintf (stderr, "Sequence = %d\n", ntohs (tcp->seq));
    			/*fprintf(stderr, "Packet ID = %d\n", m->packet_id);
    			 * fprintf(stderr, "Marked = %d\n", m->mark);
    			 * fprintf(stderr, "Hook = %d\n", m->hook);
    			 * fprintf(stderr, "Data Len = %d\n", m->data_len);
    			 * fprintf(stderr, "Payload = %c\n", m->payload[sizeof(m->payload)]);
    			 * fprintf(stderr, "From = %s\n", m->hw_addr[sizeof(m->hw_addr)]);
    			 * fprintf(stderr, "Buffer = %c\n", buf); */
    
    			status = ipq_set_verdict (h, m->packet_id, NF_ACCEPT,
    						  0, NULL);
    			if (status < 0)
    				die (h);
    			break;
    		}
    
    		default: {
    			fprintf (stderr, "Unknown message type!\n");
    			break;
    		}
    		}
    	}
    	while (1);
    
    	ipq_destroy_handle (h);
    	return 0;
    }
    Ad esempio, mi piacerebbe sapere se un pacchetto sta entrando nella mia rete o sta cercando di uscire. Inoltre, cosa molto importante, l'indirizzo IP sorgente e destinazione. Quando lo provo a stampare ottengo solo sequenze di numeri, e non indirizzi. Credo che bisognera convertirlo, ma non conosco nessuna primitiva che lo permetta...
    Qualche aiuto? Grazie

  2. #2
    Nessuno ha qualche idea?

  3. #3
    Moderatore di Sicurezza informatica e virus L'avatar di Habanero
    Registrato dal
    Jun 2001
    Messaggi
    9,791
    gli ip prima di stamparli devi convertirli in ascii... usa inet_ntoa()

    char* inet_ntoa(struct in_addr ip);

    Per sapere se è un pacchetto entra o esce basta conoscere il proprio IP e confrontarlo con l'indirizzo sorgente e destinazione del pacchetto che ti è arrivato...
    Leggi il REGOLAMENTO!

    E' molto complicato, un mucchio di input e output, una quantità di informazioni, un mucchio di elementi da considerare, ho una quantità di elementi da tener presente...
    Drugo

  4. #4
    Si ho provato, pero non capisco come ottenere una struttura sockaddr_in. Cioe, una volta ottenuto l'iphdr e il tcphdr, come faccio per separare la struttura sockaddr_in e quindi poi usare giustamente la inet_ntoa come mi hai detto?

    Grazie Ciao

  5. #5
    Moderatore di Sicurezza informatica e virus L'avatar di Habanero
    Registrato dal
    Jun 2001
    Messaggi
    9,791
    nella struct iphdr i campi ip_src e ip_dst sono già delle struct in_addr
    sockaddr_in non c'entra nulla direi...

    Nel tuo caso dovrebbe bastare un :

    printf("IP sorgente: %s\n", inet_ntoa(ip->ip_src));
    printf("IP destinazione: %s\n", inet_ntoa(ip->ip_dst));
    Leggi il REGOLAMENTO!

    E' molto complicato, un mucchio di input e output, una quantità di informazioni, un mucchio di elementi da considerare, ho una quantità di elementi da tener presente...
    Drugo

  6. #6
    Pero la struttura iphdr non ha un campo ip_src. Questo e' il risukltato della compilazione:
    bedo@harry:~/Projects/Reti/src$ gcc main.c -o prova -lipq
    main.c: In function ‘main’:
    main.c:56: error: ‘struct iphdr’ has no member named ‘ip_src’
    bedo@harry:~/Projects/Reti/src$
    Credo di dover usare saddr come campo, ma se lo uso di fatto il risultato che ottengo e'
    IP = -1208849356
    che direi che e' errato -_-

    Ho provato anche a convertirlo da rete a host con ntohs o ntohl, ma il risultato non cambia, ottengo valori strampalati del tipo
    IP = 1460082805
    IP = -1208849356

    Douh!

  7. #7
    http://www.nersc.gov/~scottc/misc/do...8h-source.html
    riga 00148, sono membri di tipo struct in_addr.

  8. #8
    Moderatore di Sicurezza informatica e virus L'avatar di Habanero
    Registrato dal
    Jun 2001
    Messaggi
    9,791
    Originariamente inviato da zero85
    http://www.nersc.gov/~scottc/misc/do...8h-source.html
    riga 00148, sono membri di tipo struct in_addr.
    è esattamente la pagina da dove ho ricavato la struttura...
    nella riga 160 sono definiti ip_src e ip_dst....
    l'header ip non può non avere un campo sorgente....

    ntohs o ntohl non c'entrano proprio nulla.
    Leggi il REGOLAMENTO!

    E' molto complicato, un mucchio di input e output, una quantità di informazioni, un mucchio di elementi da considerare, ho una quantità di elementi da tener presente...
    Drugo

  9. #9
    Moderatore di Sicurezza informatica e virus L'avatar di Habanero
    Registrato dal
    Jun 2001
    Messaggi
    9,791
    aspetta.... forse la struttura è questa che ha nomi un filo diversi...
    http://www.valtellinux.it/knights/programmazione-2.html

    verifica se corrisponde al tuo ip.h

    se così è gli indirizzi sorgente e destinazione sono saddr e daddr ma vengono definiti come u_int32 (unsigned long) e non come struttura in_addr (anche se alla fine sono entrambi unsigned long)

    prova così:


    printf("IP sorgente: %s\n", inet_ntoa((struct in_addr)ip->saddr));
    printf("IP destinazione: %s\n", inet_ntoa((struct in_addr)ip->daddr));
    Leggi il REGOLAMENTO!

    E' molto complicato, un mucchio di input e output, una quantità di informazioni, un mucchio di elementi da considerare, ho una quantità di elementi da tener presente...
    Drugo

  10. #10
    Allora, come mi hai detto tu non funziona, ma mettendo che sono puntatori a dei in_addr funziona tutto e viene stampato correttamente l'IP
    Questo e' esattamente cio che volevo ottenere, ed e' un notevole passo avanti sul mio lavoro.
    Ora mi piacerebbe capire il perche, ovvero: essendo entrambi degli unsigned long, come mai facendo il cast funziona?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2020 vBulletin Solutions, Inc. All rights reserved.