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

    [C/C++][Linux]creare e poi spedire pacchetto udp

    Ciao a tutti,
    vorrei sapere come si fa a spedire un pacchetto udp? azni a spedirlo non ci sono ancora arrivato....
    Il mio problema è la creazione del pacchetto UDP e la successiva spedizione...

    ho trovato un pò di materiale su internet e ci stavo provando ma quando lo lancio mi da come errore "segmentation fault"

    alleggo il codice che uso per creare il pacchetto:
    codice:
    // Allocca memoria per l'header Ethernet
    	ethernet_header = (struct ethhdr *) malloc(sizeof(struct ethhdr));
    
    	// Setta campi dell'header Ethernet
    	memcpy((void *)ethernet_header->h_source, (void *)ether_aton(SRC_ETHER_ADDR), 6);
    	memcpy((void *)ethernet_header->h_dest, (void *)ether_aton(DST_ETHER_ADDR), 6);
    	ethernet_header->h_proto = htons(ETHERTYPE_IP);
    
        udp = (struct udphdr *) malloc(sizeof(struct udphdr));
        udp = (struct udphdr *) packet1;
        udp->source=htons(sport);
        udp->dest = htons(dport);
        udp->check=0;
    
        // Allocca memoria per l'header IP
    	ip_header = (struct iphdr *) malloc(sizeof(struct iphdr));
    
    	// Setta campi dell'header IP
    	ip_header->version = 4;
    	ip_header->ihl = (sizeof(struct iphdr))/4;
    	ip_header->tos = 0;
    	ip_header->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr));
    	ip_header->id = htons(0);
    	ip_header->frag_off = 0;
    	ip_header->ttl = 64;
    	ip_header->protocol = IPPROTO_UDP;
    	ip_header->saddr = inet_addr(srcip);
    	ip_header->daddr = inet_addr(srcip);
    	ip_header->check = checksum((unsigned char *) ip_header, ip_header->ihl*4);
    
        memcpy(packet, ethernet_header, sizeof(struct ethhdr));
    	memcpy(packet + sizeof(struct ethhdr), ip_header, sizeof(struct iphdr));
    	memcpy(packet + sizeof(struct ethhdr) + sizeof(struct iphdr), udp, sizeof(struct udphdr));
    L'errore di runtime è dato dall'eseguzione delle ultime 3 memcpy.

    premetto che è materiale che ho messo insieme da vari stralci su internet.....

    Poi per la spedizione ho trovato che si può fare con pcap_sendpacket, o in alternativa con la raw socket....ma a quello ci penserò dopo!
    Alla fine quello che mi interesserebbe fare è riuscire a creare un pacchetto UDP e spedirlo senza fare il passaggio socket/device, le socket raw per l'appunto....

    Grazie
    Ciao

  2. #2

  3. #3

    Re: [C/C++][Linux]creare e poi spedire pacchetto udp

    Originariamente inviato da Oiziorbaf

    codice:
        udp = (struct udphdr *) malloc(sizeof(struct udphdr));
        udp = (struct udphdr *) packet1;
    qui come minimo produci un bel memory leak... insomma il puntatore allocato con la malloc diventa un fantasma..

  4. #4
    packet è un puntatore a un char
    codice:
    char *packet
    , così anche packet1....

    per il puntatore hai ragione, ma me ne ero accorto dopo e ho tenuto l'allocazione col malloc.
    Comunque mi da errore già con la prima memcpy....e le altre due commentate.....bho....

    premetto che arrivo dal java, e quindi l'uso dei puntatori è ancor un pò nebuloso...

    spero mi riesci a dare una mano....

  5. #5
    E come li hai inizializzati packet e packet1?
    Riduci ai minimi termini il tuo problema e posta tutto il codice compilabile, altrimenti, non possedendo una sfera di cristallo, la vedo ardua che tu posso ricevere un valido aiuto, salvo quello che non sia, di studiarsi BENE i puntatori e dimenticarti di Java.
    ;-)

  6. #6
    Allora ti posto tutte le parti che comprendono la spedizione del pacchetto, ci sarebbe anche la parte di sniffig però quella funziona, quindi sfoltisco un pò:

    codice:
    #define srcip "192.168.1.2"
    #define dstip "192.168.1.100"
    #define sport 1987
    #define dport 1987
    #define SRC_ETHER_ADDR "aa:aa:aa:aa:aa:aa"
    #define DST_ETHER_ADDR "bb:bb:bb:bb:bb:bb"
    
    char *packet,*packet1,*chpacket;
    struct iphdr *ip_header;
    struct udphdr *udp;
    struct ethhdr *ethernet_header;
    int data_size = 20;
    int packet_size;
    int udp_opt_size = 0;
    
    // Calcolo della checksum ripreso dal libro di Richard Stevens
    unsigned short checksum(unsigned char *header, int len)
    {
    	long sum = 0;  /* assume 32 bit long, 16 bit short */
    	unsigned short *ip_header = (unsigned short *)header;
       while(len > 1){
       	sum = sum + (*((unsigned short*) ip_header))++;
          if(sum & 0x80000000)   /* if high order bit set, fold */
          	sum = (sum & 0xFFFF) + (sum >> 16);
          len -= 2;
       }
       if(len)       /* take care of left over byte */
       	sum += (unsigned short) *(unsigned char *)ip_header;
       while(sum>>16)
       	sum = (sum & 0xFFFF) + (sum >> 16);
       return ~sum;
    }
    
    /* PREPARA PACCHETTO DA SPEDIRE*/
    void prepara_Pacchetto() {
        // Allocca memoria per l'header Ethernet
    	ethernet_header = (struct ethhdr *) malloc(sizeof(struct ethhdr));
    
    	// Setta campi dell'header Ethernet
    	memcpy((void *)ethernet_header->h_source, (void *)ether_aton(SRC_ETHER_ADDR), 6);
    	memcpy((void *)ethernet_header->h_dest, (void *)ether_aton(DST_ETHER_ADDR), 6);
    	ethernet_header->h_proto = htons(ETHERTYPE_IP);
    
        udp = (struct udphdr *) malloc(sizeof(struct udphdr));
        //udp = (struct udphdr *) packet1;
        udp->source=htons(sport);
        udp->dest = htons(dport);
        udp->check=0;
    
        // Allocca memoria per l'header IP
    	ip_header = (struct iphdr *) malloc(sizeof(struct iphdr));
    
    	// Setta campi dell'header IP
    	ip_header->version = 4;
    	ip_header->ihl = (sizeof(struct iphdr))/4;
    	ip_header->tos = 0;
    	ip_header->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr));
    	ip_header->id = htons(0);
    	ip_header->frag_off = 0;
    	ip_header->ttl = 64;
    	ip_header->protocol = IPPROTO_UDP;
    	ip_header->saddr = inet_addr(srcip);
    	ip_header->daddr = inet_addr(srcip);
    	ip_header->check = checksum((unsigned char *) ip_header, ip_header->ihl*4);
    
        memcpy(packet, ethernet_header, sizeof(struct ethhdr));
    	memcpy(packet + sizeof(struct ethhdr), ip_header, sizeof(struct iphdr));
    	memcpy(packet + sizeof(struct ethhdr) + sizeof(struct iphdr), udp, sizeof(struct udphdr));
    
    int main(int argc,char **argv) {
    /*****************************/
    /* PARTE INIZIALIZZAZIONE DELLO SNIFFER */
    /*****************************/
    
    // PREPARO IL PACCHETO PRIMA EFFETTUARE LO SNIFFING
    prepara_Pacchetto();
    // FATTO IL PACCHETTO INCOMINCIO L'ASCOLTO
    pcap_loop(descr,-1,my_callback,NULL);
    // SPEDIZIONE DEL PACCHETTO DI RITORNO
    //CHE DEVO ANCORA FARE
    return 0;
    }
    Si, comunque se riesco a fare questa cosa poi dovrò sicuramente vedere qualcosa dei puntatori!!
    Però prima di perdere tempo, anche se non sarebbe tempo sprecato, vorrei riuscire a fare ricazione e spedizione!

    Grazie
    Ciao

  7. #7
    Posto che il codice che hai "postato" non è compilabile così com'é:
    Originariamente inviato da Oiziorbaf
    Si, comunque se riesco a fare questa cosa poi dovrò sicuramente vedere qualcosa dei puntatori!!
    Però prima di perdere tempo, anche se non sarebbe tempo sprecato, vorrei riuscire a fare ricazione e spedizione!
    penso che sia proprio per non perdere tempo, che prima ti convenga studiare i puntatori.

  8. #8
    te lo posto tutto:
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <pcap.h> /* if this gives you an error try pcap/pcap.h */
    #include <errno.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netinet/if_ether.h> /* includes net/ethernet.h */
    #include <netinet/in.h>
    #include <netinet/ip.h>
    #include <netinet/udp.h>
    #include <netinet/ether.h>
    #include <net/ethernet.h>
    #include <linux/if_ether.h>
    #include <netinet/if_ether.h>
    #include <strings.h>
    #include <string.h>
    
    #define srcip "192.168.1.2"
    #define dstip "192.168.1.100"
    #define sport 1987
    #define dport 1987
    #define SRC_ETHER_ADDR "aa:aa:aa:aa:aa:aa"
    #define DST_ETHER_ADDR "bb:bb:bb:bb:bb:bb"
    
    
    char *packet,*packet1,*chpacket;
    struct iphdr *ip_header;
    struct udphdr *udp;
    struct ethhdr *ethernet_header;
    int data_size = 20;
    int packet_size;
    int udp_opt_size = 0;
    
    // Calcolo della checksum ripreso dal libro di Richard Stevens
    unsigned short checksum(unsigned char *header, int len)
    {
    	long sum = 0;  /* assume 32 bit long, 16 bit short */
    	unsigned short *ip_header = (unsigned short *)header;
    
       while(len > 1){
       	sum = sum + (*((unsigned short*) ip_header))++;
          if(sum & 0x80000000)   /* if high order bit set, fold */
          	sum = (sum & 0xFFFF) + (sum >> 16);
          len -= 2;
       }
    
       if(len)       /* take care of left over byte */
       	sum += (unsigned short) *(unsigned char *)ip_header;
    
       while(sum>>16)
       	sum = (sum & 0xFFFF) + (sum >> 16);
    
       return ~sum;
    }
    
    
    
    /* PREPARA PACCHETTO DA SPEDIRE*/
    void prepara_Pacchetto() {
        // Allocca memoria per l'header Ethernet
    	ethernet_header = (struct ethhdr *) malloc(sizeof(struct ethhdr));
    
    	// Setta campi dell'header Ethernet
    	memcpy((void *)ethernet_header->h_source, (void *)ether_aton(SRC_ETHER_ADDR), 6);
    	memcpy((void *)ethernet_header->h_dest, (void *)ether_aton(DST_ETHER_ADDR), 6);
    	ethernet_header->h_proto = htons(ETHERTYPE_IP);
    
        udp = (struct udphdr *) malloc(sizeof(struct udphdr));
        //udp = (struct udphdr *) packet1;
        udp->source=htons(sport);
        udp->dest = htons(dport);
        udp->check=0;
    
        // Allocca memoria per l'header IP
    	ip_header = (struct iphdr *) malloc(sizeof(struct iphdr));
    
    	// Setta campi dell'header IP
    	ip_header->version = 4;
    	ip_header->ihl = (sizeof(struct iphdr))/4;
    	ip_header->tos = 0;
    	ip_header->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr));
    	ip_header->id = htons(0);
    	ip_header->frag_off = 0;
    	ip_header->ttl = 64;
    	ip_header->protocol = IPPROTO_UDP;
    	ip_header->saddr = inet_addr(srcip);
    	ip_header->daddr = inet_addr(srcip);
    	ip_header->check = checksum((unsigned char *) ip_header, ip_header->ihl*4);
    
        memcpy(packet, ethernet_header, sizeof(struct ethhdr));
    	memcpy(packet + sizeof(struct ethhdr), ip_header, sizeof(struct iphdr));
    	memcpy(packet + sizeof(struct ethhdr) + sizeof(struct iphdr), udp, sizeof(struct udphdr));
    
    
    
        /*chpacket=(char *)packet;
        bcopy(packet1,chpacket+sizeof(struct iphdr), sizeof(packet1));
        printf("%s",chpacket);*/
    
    }
    
    /* just print a count every time we have a packet...
    */
    void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char* packet) {
        static int count = 1;
        fprintf(stdout,"%d, ",count);
        fflush(stdout);
        count++;
    }
    
    
    int main(int argc,char **argv)
    {
    int i;
    char *dev;
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t* descr;
    const u_char *packet;
    struct pcap_pkthdr hdr;
    struct ether_header *eptr;
    struct bpf_program fp;
    bpf_u_int32 maskp;
    bpf_u_int32 netp;
    char filtro[] = "dst port 80";
    
    
    /*if(argc != 2){
        fprintf(stdout,"Usage: %s \"filter program\"\n",argv[0])
        ;return 0;}*/
    
    
    /* grab a device to peak into... */
    dev = pcap_lookupdev(errbuf);
    if(dev == NULL)
    { fprintf(stderr,"%s\n",errbuf); exit(1); }
    /* ask pcap for the network address and mask of the device */
    
    pcap_lookupnet(dev,&netp,&maskp,errbuf);
    /* open device for reading this time lets set it in promiscuous
    * mode so we can monitor traffic to another machine*/
    
    descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
    if(descr == NULL) {
        printf("pcap_open_live(): %s\n",errbuf);
        exit(1);
     }
    
    /* Lets try and compile the program.. non-optimized */
    if(pcap_compile(descr,&fp,filtro,0,netp) == -1)
    {
        fprintf(stderr,"Error calling pcap_compile\n");
        exit(1);
        }
    /* set the compiled program as the filter */
    if(pcap_setfilter(descr,&fp) == -1)
    { fprintf(stderr,"Error setting filter\n"); exit(1); }
    /* ... and loop */
    prepara_Pacchetto();
    pcap_loop(descr,-1,my_callback,NULL);
    return 0;
    }
    il fatto è che dovrei riuscire a farlo il prima possibile, perché mi serve vedere se funziona!!
    Se riesci a capirci qualcosa mi faresti un enorme favore!

    Ciao

  9. #9
    ho provato a compilare il seguente programma che ha fatto un'utente del forum:

    http://www.ptrace.net/content/sources/injector.c

    per farlo funzionare ho dovuto aggiugere queste librerie:
    codice:
    #include <netinet/ether.h>
    #include <time.h>
    #include <arpa/inet.h>
    ma mi da sempre il solito errore di run time "segmentation fault"....

    se riesci prova a farlo funzionare te, perché è magari sul mio pc che va in crash!

    Grazie

  10. #10
    Allora il problema era come dicevi te un errore col puntatore a packet che non lo inizializzavo....

    codice:
    packet = (char *) malloc(sizeof(struct ethhdr));
    ora con un pò di aggiustamenti funziona e il pacchetto lo spedisce, ma non lo spedisce nel formato giusto.
    Con wireshark lo controllo ma mi da
    codice:
    Protocol: Unknown (0x0003)
    e come protocollo nella schermata principal mi da "SLL" e come info "Sent by us"....

    molto probabilmente sbaglio qualcosa nella creazione dell'header UDP.....
    ti allego tutto il programma compilabile, anche se il problema sarà nel metodo "prepara pacchetto"

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <pcap.h> /* if this gives you an error try pcap/pcap.h */
    #include <unistd.h>           // Standard Unix
    #include <net/if.h>           // Contiene la struttura ifreq e la costante simbolica IF_NAMESIZE
    #include <net/ethernet.h>		// Contiene la costante simbolica ETHERTYPE_IP
    #include <errno.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netinet/if_ether.h> /* includes net/ethernet.h */
    #include <netinet/in.h>
    #include <netinet/ip.h>
    #include <netinet/udp.h>
    #include <netinet/ether.h>
    #include <net/ethernet.h>
    #include <linux/if_ether.h>
    #include <linux/if_packet.h>  // Contiene la struttura sockaddr_ll
    #include <netinet/if_ether.h>
    #include <strings.h>
    #include <string.h>
    #include <stropts.h>
    #include <sys/ioctl.h>
    
    
    #define srcip "192.168.1.2"
    #define dstip "198.168.1.4"
    #define sport 1988
    #define dport 1987
    #define SRC_ETHER_ADDR "00:C0:9F:4A:41:10"
    #define DST_ETHER_ADDR "00:90:4b:8d:9f:ec"
    
    int raw;                           // raw socket descriptor
    char *packet;
    struct iphdr *ip_header;
    struct udphdr *udp;
    struct ethhdr *ethernet_header;
    int data_size = 20;
    int packet_size;
    int udp_opt_size = 0;
    
    // Calcolo della checksum ripreso dal libro di Richard Stevens
    unsigned short checksum(unsigned char *header, int len)
    {
    	long sum = 0;  /* assume 32 bit long, 16 bit short */
    	unsigned short *ip_header = (unsigned short *)header;
    
       while(len > 1){
       	sum = sum + (*((unsigned short*) ip_header))++;
          if(sum & 0x80000000)   /* if high order bit set, fold */
          	sum = (sum & 0xFFFF) + (sum >> 16);
          len -= 2;
       }
    
       if(len)       /* take care of left over byte */
       	sum += (unsigned short) *(unsigned char *)ip_header;
    
       while(sum>>16)
       	sum = (sum & 0xFFFF) + (sum >> 16);
    
       return ~sum;
    }
    
    
    // Crea un raw socket
    int raw_socket(int protocol)
    {
    	int rawsock;
    
    	if((rawsock = socket(PF_PACKET, SOCK_RAW, htons(protocol)))== -1)	{
    		perror("Error creating raw socket: ");
    		exit(-1);
    	}
    
    	return rawsock;
    }
    
    
    // Collega il raw socket a una data interfaccia. L'interfaccia e' gestita
    // come un semplice numero dal Kernel. Questo numero viene ricavato con la
    // chiamata a ioctl.
    int raw_bind(char *device, int rawsock, int protocol)
    {
     	struct sockaddr_ll sll;
    	struct ifreq ifr;
    
    
    	bzero(&sll, sizeof(sll));
    	bzero(&ifr, sizeof(ifr));
    
    
    	// Ricava l'interface index
    	strncpy((char *)ifr.ifr_name, device, IFNAMSIZ);
    
    	if((ioctl(rawsock, SIOCGIFINDEX, &ifr)) == -1) {
    		printf("Error getting Interface index !\n");
    		exit(-1);
    	}
    
    	// Popola struttura sll e fai bind
    	sll.sll_family = AF_PACKET;
    	sll.sll_ifindex = ifr.ifr_ifindex;
    	sll.sll_protocol = htons(protocol);
    
    	if((bind(rawsock, (struct sockaddr *)&sll, sizeof(sll)))== -1) {
    		perror("Error binding raw socket to interface\n");
    		exit(-1);
    	}
    
    	return 0;
    }
    
    
    // Invia un packetto sul socket
    int raw_send(int rawsock, char *packet, int len)
    {
        printf("CIAO1\n");
    	int sent = 0;
    	if((sent=write(rawsock, packet, len)) != len) {
    		printf("Error: could only send %d bytes of %d\n", sent, len);
    		return 0;
    	}
    	printf("CIAO\n");
    
    	return 1;
    }
    
    
    
    /* PREPARA PACCHETTO DA SPEDIRE*/
    void prepara_Pacchetto() {
        // Allocca memoria per l'header Ethernet
    	ethernet_header = (struct ethhdr *) malloc(sizeof(struct ethhdr));
    
    	// Setta campi dell'header Ethernet
    	memcpy((void *)ethernet_header->h_source, (void *)ether_aton(SRC_ETHER_ADDR), 6);
    	memcpy((void *)ethernet_header->h_dest, (void *)ether_aton(DST_ETHER_ADDR), 6);
    	ethernet_header->h_proto = htons(ETHERTYPE_IP);
    
        udp = (struct udphdr *) malloc(sizeof(struct udphdr));
        udp->source=htons(sport);
        udp->dest = htons(dport);
        udp->check=0;
    
        // Setta campi dell'header IP
    	ip_header->version = 4;
    	ip_header->ihl = (sizeof(struct iphdr))/4;
    	ip_header->tos = 0;
    	ip_header->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr));
    	ip_header->id = htons(0);
    	ip_header->frag_off = 0;
    	ip_header->ttl = 64;
    	ip_header->protocol = IPPROTO_UDP;
    	ip_header->saddr = inet_addr(srcip);
    	ip_header->daddr = inet_addr(srcip);
    	ip_header->check = checksum((unsigned char *) ip_header, ip_header->ihl*4);
    
    
        packet = (char *) malloc( (sizeof(struct ethhdr)) + (sizeof(struct iphdr)) + (sizeof(struct udphdr)) );
    
        memcpy(packet, ethernet_header, sizeof(struct ethhdr));
    	memcpy(packet + sizeof(struct ethhdr), ip_header, sizeof(struct iphdr));
    	memcpy(packet + sizeof(struct ethhdr) + sizeof(struct iphdr), udp, sizeof(struct udphdr));
    
    }
    
    /* just print a count every time we have a packet...
    */
    void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char* packet) {
        static int count = 1;
        fprintf(stdout,"%d, ",count);
        fflush(stdout);
        count++;
    }
    
    
    int main(int argc,char **argv)
    {
    //int i;
    char *dev;
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t* descr;
    struct bpf_program fp;
    bpf_u_int32 maskp;
    bpf_u_int32 netp;
    char filtro[] = "dst port 80";
    
    
    /* grab a device to peak into... */
    dev = pcap_lookupdev(errbuf);
    if(dev == NULL)
    { fprintf(stderr,"%s\n",errbuf); exit(1); }
    /* ask pcap for the network address and mask of the device */
    
    pcap_lookupnet(dev,&netp,&maskp,errbuf);
    /* open device for reading this time lets set it in promiscuous
    * mode so we can monitor traffic to another machine*/
    
    descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
    if(descr == NULL) {
        printf("pcap_open_live(): %s\n",errbuf);
        exit(1);
     }
    
    /* Lets try and compile the program.. non-optimized */
    if(pcap_compile(descr,&fp,filtro,0,netp) == -1)
    {
        fprintf(stderr,"Error calling pcap_compile\n");
        exit(1);
        }
    /* set the compiled program as the filter */
    if(pcap_setfilter(descr,&fp) == -1)
    { fprintf(stderr,"Error setting filter\n"); exit(1); }
    /* ... and loop */
    
    // crea raw socket
    	raw = raw_socket(ETH_P_ALL);
    
    	// Bind socket all'interface
    	raw_bind(argv[1], raw, ETH_P_ALL);
    
    
    
    prepara_Pacchetto();
    pcap_loop(descr,1,my_callback,NULL);
    
    
    if(!raw_send(raw, packet, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr)))
    		perror("Error sending packet");
    	else
    		printf("Packet sent successfully\n");
    
    return 0;
    }
    ........

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