2010-11-11 14 views
-1

Pourquoi le code suivant indique-t-il une erreur de segmentation?Le code suivant indique une erreur de segmentation

int CreateRawSocket(int protocol_to_sniff) 
{ 
    int rawsock; 

    if((rawsock = socket(PF_PACKET, SOCK_RAW, htons(protocol_to_sniff)))== -1) 
    { 
     perror("Error creating raw socket: "); 
     exit(-1); 
    } 

    return rawsock; 
} 

int BindRawSocketToInterface(char *device, int rawsock, int protocol) 
{ 

    struct sockaddr_ll sll; 
    struct ifreq ifr; 

    bzero(&sll, sizeof(sll)); 
    bzero(&ifr,sizeof(ifr)); 

    /* First Get the Interface Index */ 

     char *t=(char*)ifr.ifr_name; 
    strncpy(t, device, 1024); 
    if((ioctl(rawsock, SIOCGIFINDEX, &ifr)) == -1) 
    { 
     printf("Error getting Interface index !\n"); 
     exit(-1); 
    } 

    /* Bind our raw socket to this interface */ 

    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 1; 

} 

void PrintPacketInHex(unsigned char *packet, int len) 
{ 
    unsigned char *p = packet; 

    printf("\n\n---------Packet---Starts----\n\n"); 

    while(len--) 
    { 
     printf("%.2x ", *p); 
     p++; 
    } 

    printf("\n\n--------Packet---Ends-----\n\n"); 

} 


main(int argc, char **argv) 
{ 
    int raw; 
    unsigned char packet_buffer[2048]; 
    int len; 
    int packets_to_sniff; 
    struct sockaddr_ll packet_info; 
    int packet_info_size = sizeof(packet_info); 

    /* create the raw socket */ 

    raw = CreateRawSocket(ETH_P_IP); 

    /* Bind socket to interface */ 

    BindRawSocketToInterface(argv[1], raw, ETH_P_IP); 

    /* Get number of packets to sniff from user */ 

    packets_to_sniff = atoi(argv[2]); 

    /* Start Sniffing and print Hex of every packet */ 

    while(packets_to_sniff--) 
    { 
     if((len = recvfrom(raw, packet_buffer, 2048, 0, (struct sockaddr*)&packet_info, &packet_info_size)) == -1) 
     { 
      perror("Recv from returned -1: "); 
      exit(-1); 
     } 
     else 
     { 
      /* Packet has been received successfully !! */ 

      PrintPacketInHex(packet_buffer, len); 
     } 
    } 


    return 0; 
} 
+1

Où planter? Sur quelle adresse se plante-t-il? Quelles sont les tailles des tampons? – Patrick

+3

Je refuse même de regarder ça. Faites un peu de débogage et affinez-le. Vous n'êtes évidemment pas novice en programmation, ou vous n'écrivez pas des programmes de cette complexité. Une fois que vous avez réduit le module spécifique et la ligne qui se bloque, retournez. –

+0

Argh mes yeux. Trop d'espace !! –

Répondre

1

L'accident est causé par cette ligne dans votre routine BindRawSocketToInterface:

strncpy(t, device, 1024); 

Vous avez demandé strncpy d'écrire 1024 octets dans char *t. Notez que strncpy remplit la chaîne de destination avec le nombre spécifié d'octets nuls, voir man strncpy).

Mais t pointe vers un tableau qui n'est pas assez grand, à savoir ifr.ifr_name[IFNAMSIZ]. Sur mon système Linux, IFNAMSIZ est seulement 16. Donc strncpy déborde et efface la mémoire qu'il ne devrait pas toucher.

Modification du paramètre strncpy pour correspondre à la taille correcte du tableau comme suit fixe le crash:

strncpy(t, device, IFNAMSIZ); 
1

Il y a une violation de mémoire lorsque vous ne donnez pas assez d'arguments de ligne de commande car vous ne vérifiez pas argc.