C указатели и память (PCAP и обработка пакетов) - PullRequest
3 голосов
/ 16 февраля 2012

Это мое первое приложение на C, поэтому прошу прощения за незнание.Я работаю над переносом приложения на основе Python libpcap на C по соображениям скорости.У меня проблемы с пониманием, как извлечь информацию из пакета.Это относится к моей функции-обработчику как u_char, и вы можете оттуда ее изменить.В Python я бы просто нарезал «строку» и извлек свою информацию таким образом, но я не знаю, как поступить.

Например, как извлечь MAC-адреса назначения и источника из Ethernetкадр (байты 0-6 и 7-11 соответственно).Прямо сейчас у меня есть:

void handle_sniffed(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
    u_char *mac_dst = malloc(6*sizeof(u_char));
    u_char *mac_src = malloc(6*sizeof(u_char));
    memcpy(mac_dst, packet, 6);
    memcpy(mac_src, packet+6, 6);
}

Я делаю это правильно, и теперь, как мне отобразить MAC-адрес, например, используя printf?

Ответы [ 2 ]

1 голос
/ 16 февраля 2012

Я думаю, что вы делаете это просто отлично, memcpy() атрибуты просто отлично, malloc() правильно. Вы можете использовать встроенную функцию , например, для выделения памяти / проверки выделения (вы должны проверять каждое выделение):

inline void* s_malloc(size_t size){
    void *ptr = malloc( size);
    if( !ptr){
         printf( "Allocation failed");
         exit(1);
    }
    return ptr;
}

Вы также можете написать макрос для этого, но, вероятно, вы не сможете использовать его как функцию. Если у вас, ребята, есть лучший способ сделать это, я буду рад расширить / отредактировать.

В любом случае, чтобы ответить на ваш вопрос. Как вывести MAC-адрес. Вот руководство для prinf(), посмотрите на x соотв. X формат. Выводится десятичное число.

Он прекрасно работает, пока вы не захотите напечатать однозначное длинное число. Итак, давайте скажем printf() напечатать число с точностью до 2 чисел .2. И мы также должны сказать ему, что это должен быть «левый» блок вместо «десятичных дробных разрядов на правой стороне», то есть - (проверьте все вручную). Итак, полная строка для печати одного байта MAC: %-.2X. Полный пример будет:

#include <stdio.h>

int main(){
    unsigned char data[6] = {0x00, 0xab, 0x03, 0xff, 0xba, 0x10};
    printf( "%-.2X:%-.2X:%-.2X:%-.2X:%-.2X:%-.2X\n", data[0], data[1], data[2],
           data[3], data[4], data[5]);

    return 0;
}

И результат:

[vyktor@grepfruit tmp]$ gcc -Wall src.cpp && ./a.out 
00:AB:03:FF:BA:10

Чтобы ускорить процесс, вы можете создать такую ​​функцию:

void print_mac( const unsigned char *data){
    printf( "%-.2X:%-.2X:%-.2X:%-.2X:%-.2X:%-.2X\n", data[0], data[1], data[2],
           data[3], data[4], data[5]);
}

// Usage example:
printf( "SrcMAC: ");
print_mac(packet+6);
printf( "DstMAC: ");
print_mac(packet);

Конечно, может быть лучший способ сделать это. Я попытался сделать это понятным и познавательным, если вы ничего не понимаете, пожалуйста, не стесняйтесь спрашивать в комментарии

1 голос
/ 16 февраля 2012

Анализатор пакетов как первая C-программа? Впечатляет.

В C правильным способом было бы создать структуру, которая содержит макет одного пакета, затем вы можете привести указатель пакета, который вам дан, к этой структуре и отменить ссылку, например длинный длинный, который содержит MAC-адрес.

Можете ли вы сказать нам, где найти спецификации для пакетов, которые вы получаете, тогда мы можем помочь вам создать соответствующую структуру.

...