2013-02-26 3 views
1

Я пытаюсь вернуть сырые пакеты из сокета и не удалось. Сообщение печатает только при отправке пакетов на сайт сервера. Когда пакеты не передаются - программа зависает в recv (сокет в синхронном режиме).recv с сырым сокетом

Проблема в том, что сообщение для печати является «буфером», но без полученных данных.

#include <sys/socket.h> 
#include <linux/if_packet.h> 
#include <linux/if_ether.h> 
#include <linux/if_arp.h> 

#define ETH_FRAME_LEN 1400 

int main(){ 

    int s; /*socketdescriptor*/ 

    s = socket(PF_PACKET, SOCK_RAW, htons(0x88b5)); 
    if (s == -1) { perror("socket"); } 

     struct sockaddr_ll socket_address; 
    int r; 
    char ifName[IFNAMSIZ] = "eth0"; 

    struct ifreq ifr; 
     strncpy((char *)ifr.ifr_name ,device , IFNAMSIZ); 

    /* Get the index of the interface to send on */ 
    memset(&if_idx, 0, sizeof(struct ifreq)); 
    strncpy(if_idx.ifr_name, ifName, IFNAMSIZ-1); 
    if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) 
     perror("SIOCGIFINDEX"); 

    /* Get the MAC address of the interface to send on */ 
    memset(&if_mac, 0, sizeof(struct ifreq)); 
    strncpy(if_mac.ifr_name, ifName, IFNAMSIZ-1); 
    if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0) 
     perror("SIOCGIFHWADDR"); 

     memset(&socket_address, 0, sizeof(socket_address)); 
     socket_address.sll_ifindex = ifr.if_idx; 
     socket_address.sll_protocol = htons(0x88b5); 
     socket_address.sll_family = PF_PACKET; 
     socket_address.sll_pkttype = PACKET_OUTGOING; 

     r = bind(s, (struct sockaddr*)&socket_address, 
        sizeof(socket_address)); 
    if (r < 0) { perror("bind")}; 

    void* buffer = (void*)malloc(ETH_FRAME_LEN); /*Buffer for ethernet frame*/ 
    int length = 0; /*length of the received frame*/ 

    length = recv(s, buffer, ETH_FRAME_LEN, 0,); 
    if (length == -1) { perror("recvfrom"); } 
    printf ("buffer %s\n", buffer); 

} 

ответ

2

Вы можете использовать только формат %s спецификатор для строк C-стиле. Вы не можете использовать его для произвольных двоичных данных. Как он узнает, сколько символов нужно печатать? У вас есть длина в переменной, называемой length. Вам нужно напечатать много символов. Например:

for (int i = 0; i < length; ++i) 
    putchar(((char *)buffer)[i]); 

Это будет, вероятно, выглядеть как мусор, потому что вы выводите кучу непечатаемых символов. Возможно, вы хотите что-то вроде:

void print(void *buf, int length) 
{ 
     char *bp = (char *) buf; 
     for (int i = 0; i < length; ++i) 
      putchar(isprintf(bp[i]) ? bp[i] : '.'); 
     putchar('\n'); 
} 

Это заменит непечатаемые символы точками.

+1

Вы правы, он не может выводить символы, не подлежащие печати. Спасибо большое! – user1016711

Смежные вопросы