2011-08-08 2 views
1

У меня возникли проблемы со следующим кодом. Я получаю свои данные без проблем, однако данные загружаются посторонними битами! Например, следующий код захватывает весь трафик, направленный на него из nfqueue, и выводит каждый байт, за которым следует новая строка.Почему я получаю дополнительные биты в своих вызовах recv() с libnfqueue?

Сначала данные - именно то, что я ожидал бы, но тогда есть строки, которые кажутся 4 байтами на них!

int main(int argc, char** argv) { 
    int fd; 
    ssize_t rv; 
    char buf[4096]; 
    struct nfq_handle* h; 
    struct nfq_q_handle* qh; 

    h = nfq_open(); 
    if (!h) { 
     fprintf(stderr, "error during nfq_open()\n"); 
     exit(1); 
    } 

    if (nfq_unbind_pf(h, AF_INET) < 0) { 
     fprintf(stderr, "error during nfq_unbind_pf()\n"); 
     exit(1); 
    } 

    if (nfq_bind_pf(h, AF_INET) < 0) { 
     fprintf(stderr, "error during nfq_bind_pf()\n"); 
     exit(1); 
    } 

    printf("Binding to queue 0...\n"); 
    qh = nfq_create_queue(h, 0, &cb, NULL); 
    if (!qh) { 
     fprintf(stderr, "error during nfq_create_queue()\n"); 
     exit(1); 
    } 

    printf("Copying packets...\n"); 
    if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) { 
     fprintf(stderr, "error during nfq_set_mode()\n"); 
     exit(1); 
    } 

    fd = nfq_fd(h); 

    memset(buf, 0, 4096); 
    while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) { 
    for (int i = 0; i < rv; i++) printf("%02x\n", *(buf+i)); 
    printf("\n\n"); 
     nfq_handle_packet(h, buf, rv); 
    } 

    nfq_destroy_queue(qh); 
    nfq_close(h); 
} 

Выход:

... 
50 
10 
39 
08 
48 
ffffffa4 
00 
00 
... 

Я не мог найти что-нибудь в Интернете, или в трекеров ошибка, подобную этой проблемы. Где я могу начать его диагностировать? Почему все эти дополнительные биты в моих данных? Как я могу это исправить?

Я сделал сравнение с выходом tcpdump, и они тоже не появляются.

ответ

2

Кажется, что буфер содержит символ со значением, превышающим 128, и имеет место ошибка с подписанным/неподписанным преобразованием.

Я вычислил значение вашего байта - это 164. Попробуйте преобразовать байты в беззнаковые символы перед передачей их PRINTF:

printf("%02x\n", *(unsigned char*)(buf+i)); 
+0

Вау, глупый меня. Оказывается, это именно то, что проблема. Благодаря! – worr

+3

Хотя это работает на двухкомпонентных машинах, правильный и переносимый способ сделать это: '* (unsigned char *) (buf + i)', то есть отбрасывать тип указателя * перед * разыменованием, а не разыменовываться с неправильным типом (подписанный 'char'), а затем лить это в нужном типе. –