следующий код, показывающий ошибку сегментации - PullRequest
0 голосов
/ 11 ноября 2010

почему следующий код показывает ошибку сегментации?

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

Ответы [ 2 ]

1 голос
/ 11 ноября 2010

Сбой вызван этой строкой в ​​вашей подпрограмме BindRawSocketToInterface:

strncpy(t, device, 1024);

Здесь вы попросили strncpy записать 1024 байта в char *t. Обратите внимание, что strncpy дополняет строку назначения указанным числом нулевых байтов , см. man strncpy ).

Но t указывает на массив, который недостаточно велик, а именно ifr.ifr_name[IFNAMSIZ]. В моей системе linux IFNAMSIZ - только 16. Так что strncpy переполняет и удаляет память, которая не должна касаться.

Изменение параметра strncpy для соответствия правильному размеру массива следующим образом исправляет сбой:

strncpy(t, device, IFNAMSIZ);
1 голос
/ 11 ноября 2010

Существует нарушение памяти, когда вы не указываете достаточное количество аргументов командной строки, так как не проверяете argc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...