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

    [C] Opzioni del TCP

    Ciao a tutti
    devo leggere le opzioni di un pacchetto TCP, ed eventualmente settarle.
    Riesco a prendere correttamente l'header, riesco a leggere i vari campi come gli indirizzi e le porte, ma non riesco a leggere le opzioni.
    So che devo controllare il campo data offset per vedere dove cominciano i dati, ma anche ottenendo questa informazione dopo non so come leggere i campi che mi interessano e settarli.
    Qualche idea?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Un'idea ... posta il codice che utilizzi per accedere all'header ...

  3. #3
    Giusto, eccolo qui

    codice:
    int tcp_handle(ipq_packet_msg_t *m) {
    	struct iphdr *ip = (struct iphdr *) m->payload;
    	u_int32_t src_addr = ip->saddr;
    	u_int32_t dst_addr = ip->daddr;
    	fprintf(stderr, "TCPTCP\n");
    	fprintf(stderr, "IP sorgente: %s\n", inet_ntoa(src_addr));
    	fprintf(stderr, "IP destinazione: %s\n", inet_ntoa(dst_addr));
    
    	/* Cast the TCP Header from the raw packet */
    	struct tcphdr *tcp = (struct tcphdr *)(m->payload + (ip->ihl << 2));
    	fprintf(stderr,"DATA OFFSET == %d\n",tcp->doff);
    	fprintf(stderr,"URG=%d   ACK=%d   PSH=%d   RST=%d   SYN=%d   FIN=%d\n",
    					tcp->urg,tcp->ack,tcp->psh,tcp->rst,tcp->syn,tcp->fin);
    	unsigned int startdata = m+sizeof(struct iphdr)+sizeof(struct tcphdr)+tcp->doff;
    	/* Occorre usare la memcpy per ottenere i dati */
    	fprintf(stderr,"m->payload = %d\n",sizeof(ipq_packet_msg_t));
    	fprintf(stderr,"sizeof(ip) = %d\n",sizeof(struct iphdr));
    	fprintf(stderr,"sizeof(tcp) = %d\n",sizeof(struct tcphdr));
    	fprintf(stderr,"startdata = %u\n",startdata);
    
    	int dim_data = sizeof(ipq_packet_msg_t)-sizeof(struct tcphdr)-sizeof(struct iphdr);
    	fprintf(stderr,"The dimension of the data is %d\n",dim_data);
    	char* data = malloc(dim_data);
    	fprintf(stderr,"Data starts at %u\n",startdata);
    	fprintf(stderr,"data = %u\n",data);
    	memcpy(data,startdata,dim_data);
    	fprintf(stderr,"M=%u   struct tcphdr=%d   tcp->doff=%d\n",m,sizeof(struct tcphdr),tcp->doff);
    	fprintf(stderr,"Data = %s",data);
    	int src_port = ntohs (tcp->source);
    	int dest_port = ntohs (tcp->dest);
    	fprintf(stderr, "Source port = %d && Dest Port = %d", src_port, dest_port);
    }
    Ci sono diverse stampe, ma comunque c'e tutta la struttura dell'accesso all'header..

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Sì ... ma senza alcune indicazioni, anche con il sorgente, diventa un po' "pesante" fare delle prove e quindi si rinuncia ...

    In particolare

    1) parliamo di Linux o Windows?

    2) quale compilatore usi?

    3) quali header usi?

  5. #5
    Parliamo di Linux, infatti il parametro di quella funzione e' un pacchetto di iptables.

    Come compilatore uso gcc.

    Gli header che uso (per la parte di rete) sono i seguenti:
    tcp.h
    ip.h
    udp.h
    anche se qui udp non lo uso.
    Comunque l'header tcp che prendo e' fatto in questo modo:
    codice:
    struct tcphdr {
      __u16 source;
      __u16 dest;
      __u32 seq;
      __u32 ack_seq;
    #if defined(__LITTLE_ENDIAN_BITFIELD)
      __u16 res1:4,
        doff:4,
        fin:1,
        syn:1,
        rst:1,
        psh:1,
        ack:1,
        urg:1,
        ece:1,
        cwr:1;
    #elif defined(__BIG_ENDIAN_BITFIELD)
      __u16 doff:4,
        res1:4,
        cwr:1,
        ece:1,
        urg:1,
        ack:1,
        psh:1,
        rst:1,
        syn:1,
        fin:1;
    #else
    #error  "Adjust your <asm/byteorder.h> defines"
    #endif
      __u16 window;
      __u16 check;
      __u16 urg_ptr;
    };
    Se fosse necessario potrei anche usare altri header, quello non e' importante...

    Grazie!

  6. #6
    Moderatore di Sicurezza informatica e virus L'avatar di Habanero
    Registrato dal
    Jun 2001
    Messaggi
    9,782
    ho dato solo una occhiata sommaria al tuo codice...

    Il campo doff (data offset) prelevato dall'header tcp è composto da 4 bit e contiene la lunghezza dell'header (option comprese) espressa in unità di 32-bit (4 byte). Questo significa che l'header (option comprese) è lungo (4*doff) bytes.
    Detto questo mi sembra che il calcolo dell'inizio dei dati sia totalmente sbagliato nel tuo codice.
    Tu scrivi:

    codice:
    unsigned int startdata = m+sizeof(struct iphdr)+sizeof(struct tcphdr)+tcp->doff;
    che non ha senso perchè consideri due volte l'header tcp, calcolandolo comunque in modo errato.

    Premetto che non ho verificato praticamente ma il codice esatto dovrebbe essere:

    codice:
    unsigned int startdata = m+sizeof(struct iphdr)+4*tcp->doff;
    infatti sommi la lunghezza dell'header ip (fisso) + lunghezza header tcp (variabile a causa delle option)

    L'unica parte variabile dell'header sono le option. Se queste esistono sono posizionate subito prima dei dati.
    Se non ci fossero option l'header sarebbe lungo esattamente 20 byte.
    Se (4*tcp->doff)>20 (ovvero se (tcp->doff)>5 ) sei sicuro che ci sono delle option e che queste cominciano da

    codice:
    unsigned int startoptions = m+sizeof(struct iphdr)+20;
    Il campo option non è definito nel tuo header per cui devi accedervi in modo manuale...
    Da startoptions fino a (startdata-1)

    Ripeto, non ho verificato se funziona esattamente... ma dovrebbe essere così
    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

  7. #7
    Moderatore di Sicurezza informatica e virus L'avatar di Habanero
    Registrato dal
    Jun 2001
    Messaggi
    9,782
    noto ora... se ci sono option è assolutamente sbagliato considerare sizeof(struct tcphdr) come dimensione dell'header tcp. Vedo che tu usi quel valore per calcolarti al dimensione dei dati:

    codice:
    int dim_data = sizeof(ipq_packet_msg_t)-sizeof(struct tcphdr)-sizeof(struct iphdr);
    quella non è la dim dei dati ma dei dati+option (se presenti)
    sizeof(struct tcphdr) è la parte fissa degli header, cioè 20 bytes.

    Conclusione: per non includere le option devi sostituire quel valore con (4*tcp->doff)
    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

  8. #8
    Originariamente inviato da Habanero
    ho dato solo una occhiata sommaria al tuo codice...

    L'unica parte variabile dell'header sono le option. Se queste esistono sono posizionate subito prima dei dati.
    Se non ci fossero option l'header sarebbe lungo esattamente 20 byte.
    Se (4*tcp->doff)>20 (ovvero se (tcp->doff)>5 ) sei sicuro che ci sono delle option e che queste cominciano da

    codice:
    unsigned int startoptions = m+sizeof(struct iphdr)+20;
    Il campo option non è definito nel tuo header per cui devi accedervi in modo manuale...
    Da startoptions fino a (startdata-1)
    Quindi se ci sono option devo accecdervi ma a blocchi di 32 bit giusto? in pratica se ad esempio doff == 8 allora vuol dire che ho le opzioni a {5,6,7} giusto?

  9. #9
    Moderatore di Sicurezza informatica e virus L'avatar di Habanero
    Registrato dal
    Jun 2001
    Messaggi
    9,782
    Originariamente inviato da erbedo
    Quindi se ci sono option devo accecdervi ma a blocchi di 32 bit giusto? in pratica se ad esempio doff == 8 allora vuol dire che ho le opzioni a {5,6,7} giusto?
    Le option devono sempre essere multiple di 32 bit. Ciò significa che se un particolare tipo di option occupa 5 byte bisogna aggiungere un padding di byte posti a 0 per raggiungere gli 8 byte.
    Se doff=8 significa che l'header tcp occupa 4*8=32 byte. Togliendo la parte fissa (20 byte) degli header tcp si ottiene 12byte. Le Option occupano 12 byte.

    Non ho assolutamente capito cosa intendi con

    se ad esempio doff == 8 allora vuol dire che ho le opzioni a {5,6,7}
    Forse dovresti studiarti meglio il protocollo... Qui trovi un semplice schema del pacchetto tcp, con l'indicazione di come vengono gestite le option...
    http://www.networksorcery.com/enp/default0804.htm
    il primo byte indica il tipo di option
    il secondo la lunghezza delle option
    dal terzo byte in poi i dati della particolare option
    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
    Originariamente inviato da Habanero
    Le option devono sempre essere multiple di 32 bit. Ciò significa che se un particolare tipo di option occupa 5 byte bisogna aggiungere un padding di byte posti a 0 per raggiungere gli 8 byte.
    Se doff=8 significa che l'header tcp occupa 4*8=32 byte. Togliendo la parte fissa (20 byte) degli header tcp si ottiene 12byte. Le Option occupano 12 byte.
    Ok qui ci sono

    Originariamente inviato da Habanero
    Forse dovresti studiarti meglio il protocollo... Qui trovi un semplice schema del pacchetto tcp, con l'indicazione di come vengono gestite le option...
    http://www.networksorcery.com/enp/default0804.htm
    il primo byte indica il tipo di option
    il secondo la lunghezza delle option
    dal terzo byte in poi i dati della particolare option
    Sisi questo l'avevo capito. Intendevo che le opzioni partivano da {5*4 byte. 6*4 e 7*4 byte} seguendo quel campo doff..


    Ora faccio qualche prova poi al max postero i miei dubbi.
    Grazie mille intanto, ciao!

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 © 2025 vBulletin Solutions, Inc. All rights reserved.