Raw socket e Ipv6

di Anonimizzato10267 il
43 risposte

43 Risposte - Pagina 3

  • Ho un nuovo problema:

    Ora mi legge tutto però se imposto un indirizzo MAC, quando ricevo il pacchetto me ne ristampa un'altro:

    Qui preparo il pacchetto
    
    		//Preparo e includo nel paccheto l'header ipv6
    		ip6_header=(struct ip6_hdr *)calloc(1,sizeof(struct ip6_hdr));
    		ip6_header->ip6_ctlun.ip6_un1.ip6_un1_flow=0;
    		ip6_header->ip6_ctlun.ip6_un1.ip6_un1_plen=PACKET_LENGTH-(sizeof(struct ethhdr)+sizeof(struct ip6_hdr));
    		ip6_header->ip6_ctlun.ip6_un1.ip6_un1_nxt=59;
    		ip6_header->ip6_ctlun.ip6_un1.ip6_un1_hlim=0;
    			
    					if(inet_pton(AF_INET6,"fe80::226:c7ff:fe85:6758",&ip6_header->ip6_src)!=1 || 						    	inet_pton(AF_INET6,"fe80::226:c7ff:fe85:6758",&ip6_header->ip6_dst)!=1)
    						{ perror("inet_pton");
    						  //printf("%d", inet_pton(AF_INET6,host,&ip6_header->ip6_src));	
    				}
    
    		ip6_header=(struct ip6_hdr*)packet;
    			
    		//Preparo e includo nel pacchetto l'header ethernet
    	
    		ethernet_header=(struct ethhdr *)calloc(1,sizeof(struct ethhdr));
    		
    	
    		if(ioctl(write_socket,SIOCGIFHWADDR,&freq)==-1) {
    				perror("ioctl");
    				close(write_socket);
    				exit(1);
    		}
    		ethernet_header->h_source[0]=0x00;
    		ethernet_header->h_source[1]=0x26;
    		ethernet_header->h_source[2]=0xc7;
    		ethernet_header->h_source[3]=0x27;
    		ethernet_header->h_source[4]=0x67;
    		ethernet_header->h_source[5]=0x58;
    		ethernet_header->h_dest[0]=0x00;
    		ethernet_header->h_dest[1]=0x26;
    		ethernet_header->h_dest[2]=0xc7;
    		ethernet_header->h_dest[3]=0x85;
    		ethernet_header->h_dest[4]=0x67;
    		ethernet_header->h_dest[5]=0x58;
    		
    		printf("> Successfully received Local MAC Address : %02x:%02x:%02x:%02x:%02x:%02x\n",
                    ethernet_header->h_source[0],ethernet_header->h_source[1],ethernet_header->h_source[2]
                    ,ethernet_header->h_source[3],ethernet_header->h_source[4],ethernet_header->h_source[5]);
     
    
    		ethernet_header=(struct ethhdr*)ip6_header;
    	
    		payload=(char *)(packet+sizeof(struct ethhdr));
    		
    		strcpy(payload,"Questo che leggete qui e' il payload del pacchetto ipv6 :)");
    poi quando lo ricevo cerco di estrarre ogni header:
    read_length=recv(read_socket,buffer,PACKET_LENGTH,0);
    		if(read_length==-1) {perror("recv");}
    		else {printf("sono stati ricevuti %d di dati con successo\n", read_length);}
    		
    		//ethernet header
    		//ethhead=buffer;
    	        //ethernet_header_rec=(struct ethhdr *)buffer;
    		memcpy(&ethernet_header_rec, &buffer,sizeof(struct ethhdr));
    		printf("*********ethernet header******\n");
    		printf("> Successfully received Local MAC Address : %02x:%02x:%02x:%02x:%02x:%02x\n",
                    ethernet_header_rec->h_source[0],ethernet_header_rec->h_source[1],ethernet_header_rec->h_source[2]
                    ,ethernet_header_rec->h_source[3],ethernet_header_rec->h_source[4],ethernet_header_rec->h_source[5]);
    
    				
    		//ip6 header
    		printf("*******ip6 header******\n");
    		ip6hdr=(struct ip6_hdr*)(buffer+sizeof(struct ethhdr));
    
    		printf("il flow è %d\n", ip6hdr->ip6_ctlun.ip6_un1.ip6_un1_flow);
    		printf("il packet length è %d\n", ip6hdr->ip6_ctlun.ip6_un1.ip6_un1_plen);
    		printf("il campo successivo è %d\n", ip6hdr->ip6_ctlun.ip6_un1.ip6_un1_nxt);
    
    però mi da un indirizzo diverso, e anche i campi del ipv6 header sono sfalzati perchè???
  • --- cut ---
    quando ricevo il pacchetto me ne ristampa un'altro
    --- cut ---
    se hai il bind in locale è normale avere il loopback
    --- cut ---
    mi da un indirizzo diverso, e anche i campi del ipv6 header sono sfalzati perchè???
    --- cut ---
    è probabile che sbagli in scrittura (o lettura).
    ti avevo suggerito di dividere le due sezione per meglio debuggarle separatamente.
    scrivere codice in più non è un modo masochista per perdere tempo.
  • =======================================================================
    Se i moderatori ritengono questo thread OT lo spostino nella sezione 'Linux' - Grazie!
    =======================================================================

    Non ricordo dove ho letto il motivo della duplicazione dei pacchetti sulle interfacce di loopback. In libpcap è riportato come implementazione di upgrade: "... doesn't show duplicate packets on loopback interface, etc...".
    Tcpdump -che utilizza libpcap- non visualizza le duplicazioni ed altro (cit. "...there are no lost or duplicated packets...etc).
    In altri src viene testato: ("lo" .AND. sll_pkttype == PACKET_OUTGOING) --> skip packet.
    In modalità promiscua usando PF_PACKET con SOCK_RAW ottengo le duplicazioni dei pacchetti su tutti i protocolli. Esempio di un ICMP IPv6:
    
    FRAME 00001: 118 bytes read (2899)
    Destination: 00:00:00:00:00:00
    Source     : 00:00:00:00:00:00
    Type       : 0x86DD (IPv6)
      Version        :6
      Traffic Class  :0 0
      Flow Label     :0
      Payload Lenght :64
      Next Header    :0x3A (ICMP for IPv6)
      Hop Limit      :64
      Source Address        ::1
      Destination Address   ::1
        Payload:
        80 00 E9 5E 54 78 00 01 DF AB AE 4F 00 00 00 00 
        EB DC 09 00 00 00 00 00 10 11 12 13 14 15 16 17 
        18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 
        28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 
        00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    ----------------------------------------------------
    FRAME 00002: 118 bytes read (2899)
    Destination: 00:00:00:00:00:00
    Source     : 00:00:00:00:00:00
    Type       : 0x86DD (IPv6)
      Version        :6
      Traffic Class  :0 0
      Flow Label     :0
      Payload Lenght :64
      Next Header    :0x3A (ICMP for IPv6)
      Hop Limit      :64
      Source Address        ::1
      Destination Address   ::1
        Payload:
        80 00 E9 5E 54 78 00 01 DF AB AE 4F 00 00 00 00 
        EB DC 09 00 00 00 00 00 10 11 12 13 14 15 16 17 
        18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 
        28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 
        00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    ----------------------------------------------------
    
    Altro punto che mi piacerebbe approfondire è la combinazione 'cooked' (SOCK_DGRAM) e link level header (SOCK_RAW).
    Il manuale riporta:
    SOCK_DGRAM operates on a slightly higher level. The physical header is removed before the packet is passed to
    the user. Packets sent through a SOCK_DGRAM packet socket get a suitable physical layer header based on the
    information in the sockaddr_ll destination address before they are queued.
    Questo è quel poco che le guide forniscono. Un aiuto è sicuramente studiarsi libpcap e un'occhiatina al kernel
  • Mi rispondo da solo. non e' una duplicazione del pacchetto ma due pacchetti identici: uno in ingresso ed uno in uscita. l'uguaglianza e' data dallo stesso indirizzo rovesciato.... ahhh bastava pensare
  • Ciao, riscrivo qui perchè ho un rproblema con un programmino, che deve inviare e ricevere un pacchetto da una porta e rinviarla da un interfaccia presa da file: l'errore che mi da è nella send di invalid argument. Perchè?

    #include <netpacket/packet.h>
    #include <net/ethernet.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/ioctl.h>
    #include <unistd.h>
    #include <string.h>
    #include <net/if.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>

    #define BUFFER_LENGTH 1500

    void Sniffer(unsigned char *packet, unsigned int packet_length, const char separator);

    int main() {

    int sock1,sock2;
    FILE *fd;
    int port;
    char interface[4];
    struct sockaddr_in6 source_addr;
    struct sockaddr_in6 destination_addr;
    struct ifreq freq;
    void *buff,*buff2;
    int packet_length,packet_length2;
    unsigned char* packet;

    sock1=socket(AF_INET6,SOCK_DGRAM,0);
    sock2=socket(AF_PACKET,SOCK_DGRAM,htons(ETH_P_ALL));


    fd=fopen("port.txt","r+");

    if(fd) {
    while(!feof(fd)){
    fscanf(fd,"%d %s",&port, interface);
    }
    }

    memset(&source_addr,0,sizeof(struct sockaddr_in6));
    source_addr.sin6_family=AF_INET6;
    source_addr.sin6_port=htons(port);
    source_addr.sin6_addr=in6addr_any;



    if(bind(sock1,(struct sockaddr*)&source_addr,sizeof(struct sockaddr_in6))==-1){perror("bind");}

    //Device dove inviare

    memset(&freq,0,sizeof(struct ifreq));
    strncpy(freq.ifr_name,interface,IFNAMSIZ);
    if(ioctl(sock2,SIOCGIFINDEX,&freq)==-1){perror("ioctl");}

    destination_addr.sll_family=AF_PACKET;
    destination_addr.sll_protocol=htons(ETH_P_ALL);
    destination_addr.sll_ifindex=freq.ifr_ifindex;

    if(bind(sock2,(struct sockaddr*)&destination_addr,sizeof(struct sockaddr_ll))==-1){perror("bind");}

    if((buff=malloc(BUFFER_LENGTH))==NULL){ perror("malloc");}

    packet_length=recv(sock1,buff,BUFFER_LENGTH,0);

    if(packet_length<0){perror("recv");}

    printf("La lunghezza è %d\n",packet_length);

    packet=(unsigned char*)buff;

    Sniffer(packet,packet_length,' ');

    packet_length2=sendto(sock2,buff,BUFFER_LENGTH,0,(const struct sockaddr*)&destination_addr,sizeof(struct sockaddr_ll));

    packet_length2=send(sock2,buff,BUFFER_LENGTH,0);


    if(packet_length2<0) {
    perror("send");

    }

    printf("la lunghezza del pacchetto è %d\n", packet_length2);

    return 0;
    }



    void Sniffer(unsigned char *packet, unsigned int packet_length, const char separator)
    {
    int nl=1;

    while (packet_length--)
    {
    printf ("%02X%c",*packet++,(packet_length)?separator:' ');
    if (!(nl++%16))
    printf ("\n");
    }
    printf ("\n");

    }
    Ho usato un programma vecchio perchè volevo solo fare un test, quindi non ho separato scrittura e lettura! Quale argomento non gli va bene?
  • Ciao Berny88,
    vedo che sei sempre alle prese con questo router in IPV6... ma quando finisci lo pubblichi per farmi vedere qualcosa di diverso?

    Il pezzo che hai allegato non è taggato e ovviamente le indentazioni non ci sono...
    Ma hai provato a compilarlo o è solo una bozza giusto per capire il problema? A me non compila... hai fatto confusione con le due differenti strutture.
    A parte la distrazione, il problema che riscontri è dovuto alla recv che non è adatta alle trasmissioni UDP. Devi usare recvfrom e sendto ($man 2 recvfrom) questo perchè devi conoscere il mittente.

    Quante volte di ho detto che devi fare pezzi separati per il debug? SPEZZA, non scrivere sempre in questo calderone!

    DEBUG:
    
    $# testo la connessione sulla porta 12345
    $lsof -i :12345
    COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    ./a.out    18040   max    3u  IPv6  xxxxxx          0t0   UDP ********
    $
    $# eseguo in background.... ma puoi aprire due terminali
    $./a.out &
    [1] 19509
    $
    $# non posso usare telnet con UDP. uso netcat
    $nc -u ipv6-localhost 12345
    AAAAAAAAAAAAAAAAAAAAA[INVIO]
    41.41.41.41.41.41.41.41.41.41.41.41.41.41.41.41.
    41.41.41.41.41.0A 
    Hello there, I got it!
    [CTRL+C]
    $kill 19509
    [1]+  Terminated              ./a.out
    $
    
    edit:
    per vedere la connessione non ancora attivata senza usare lsof
    
    $netstat -aupn | grep 12345
    (Not all processes could be identified, non-owned process info
     will not be shown, you would have to be root to see it all.)
    udp        0      0 :::12345                :::*                                20454/a.out 
    
  • A me compilava!Comunque si questo era un esempio, ora devo far comunicare un sunspot con l'ethernet almeno per ora. Però ho problemi nel rinviare. In teoria, riceve e rispedisce ma quando arriva all'altro host, non ricevo la risposta del ping...e con lo sniffer vedo un ping preciso!!
  • Ciao Berny88,

    spiegati meglio, cosa è un sunspot e cosa intendi dire con: "...non arriva all'ALTRO host". Gli host sono 3? Stai facendo un ICMP con IP taroccato sul terzo o stai agendo su sunspot generando un ECHO_RESPONSE sul terzo host? Da quale host esegui lo sniffing?
  • @Berny alias user1307697

    a quanto vedo i colleghi d'oltreoceano ne sanno meno di me...
    Batti il chiodo finché è caldo!

    ciao
  • Vedo che mi segui ormai sei fan delle mie sventure ixamit contanto che ormai sono il primo nelle pagine di google tra un pò comunque un sunspot è un dispositivo RFID. Conta che ho un pc dove il sunspot è attacco e un altro pc che sarebbe la destinazione. I due pc sono collegati tramite un router ipv6. In aggiunta il pc destinatario fa anche da server dhcp per assegnare indirizzi ai vari host tra cui quello dove il sunspot è attaccato. In più visto che il sunspot ha un modo un pò rozzo di inviare i pacchetti (fa un tunnel del pacchetto strambo).
    Il programma che invia il ping non l'ho fatto io e credo che sia li l'errore perchè io riesco a prendere il pacchetto che invia al sunspot e rispedirlo al pc destinatario , e lo sniffer vede correttamente un ICMPV6 echo request ma il destinatario non risponde al ping. Non riesco a capirne il perche?
  • Ho debuggato un pochino ed ho trovato l'impiccio risolto tutto
  • In effetti sei in prima linea gu google per quanto rigurda i protocolli vers 6...

    Com'e' il pacchetto strambo a cui ti riferi? Esegue un tunnel cifrato? E quale errore avevi commesso?

    Per ultimo, quanto costa il giocattolo?
  • Nuovo post nuovo problema:

    Questa volta di carattere diverso:

    Un socket è bidirezionale, io devo inviare e leggere da due porte diverse. (devo leggere dalla porta 3654 e inviare alle 3653). Per far questo uso una bind e una connect. Ma se le metto insieme non mi permette di leggere dalla porta e se non uso la connect non mi fa scrivere dall'altra porta? Come posso gestire il problema?
    Stavo pensando di usare i semafori ma per far ciò devo capire come fare l'unbind o l'unconnect ma non penso esistano.
    Con 3 socket tutto funziona ma il ragazzo che mi segue ha detto che è una soluzione "sporca" essendo i socket bidirezionali. Come posso fare?
  • Mi sono armato di RFC ed ho risolto
Devi accedere o registrarti per scrivere nel forum
43 risposte