Задать вопрос
Redfern89
@Redfern89
Пишу код под МК AVR, начинающий сисадмин

Как скомпилировать программу linux?

Всем доброго времени суток! Есть такой код (не мой):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pcap/pcap.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <netinet/if_ether.h>
#include <linux/wireless.h>
#include <linux/ieee80211.h>

void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);

int main(int argc, char *argv[]) {
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t *handle;
    struct bpf_program fp;
    char filter_exp[] = "type mgt subtype beacon";
    bpf_u_int32 net;

    // Открытие сетевого интерфейса в режиме монитора
    handle = pcap_open_live("wlan0mon", BUFSIZ, 1, 1000, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Не удалось открыть устройство: %s\n", errbuf);
        exit(EXIT_FAILURE);
    }

    // Компиляция и применение фильтра
    if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
        fprintf(stderr, "Не удалось скомпилировать фильтр: %s\n", pcap_geterr(handle));
        exit(EXIT_FAILURE);
    }
    if (pcap_setfilter(handle, &fp) == -1) {
        fprintf(stderr, "Не удалось применить фильтр: %s\n", pcap_geterr(handle));
        exit(EXIT_FAILURE);
    }

    // Запуск цикла обработки пакетов
    pcap_loop(handle, -1, packet_handler, NULL);

    // Закрытие устройства
    pcap_close(handle);
    return 0;
}

void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
    struct ieee80211_hdr *wifi_hdr;
    struct iw_event *event;
    struct iw_freq freq;
    char ssid[IW_ESSID_MAX_SIZE + 1];
    char bssid[ETH_ALEN];
    int rssi;

    // Получение заголовка Wi-Fi пакета
    wifi_hdr = (struct ieee80211_hdr *) packet;

    // Получение события IW_EV_QUALITY из данных пакета
    event = (struct iw_event *) (packet + sizeof(struct ieee80211_hdr));
    while (IW_EV_LCP_PK_LEN <= IW_EV_LCP_PK_LEN + event->len && event->cmd != IW_EV_QUALITY) {
        event = (struct iw_event *) (((char *) event) + IW_EV_LCP_PK_LEN + event->len);
    }

    // Получение частоты и силы сигнала
    if (event->cmd == IW_EV_QUALITY) {
        memcpy(&freq, &event->u.freq, sizeof(struct iw_freq));
        rssi = (int) freq.m; // rssi в dBm
    } else {
        return;
    }

    // Получение ESSID и BSSID
    memset(ssid, 0, IW_ESSID_MAX_SIZE + 1);
    memcpy(bssid, wifi_hdr->addr3, ETH_ALEN);
    strncpy(ssid, (char *) (packet + sizeof(struct ieee80211_hdr) + IW_EV_LCP_PK_LEN), event->u.essid.length);

    // Вывод информации о сети
    printf("ESSID: %s\n", ssid);
    printf("BSSID: %s\n", ether_ntoa((struct ether_addr *) bssid));
    printf("Channel: %d\n", ieee80211_mhz_to_chan(freq.m));
    printf("RSSI: %d dBm\n", rssi);
    printf("\n");
}

он выводит список WiFi сетей. Но при попытке его скомпилить - вылетает с ошибкой:

$ gcc -o wifi_sniffer wifi_sniffer.c -lpcap


wifi_sniffer.c:11:10: fatal error: linux/ieee80211.h: No such file or directory
11 | #include
| ^~~~~~~~~~~~~~~~~~~
compilation terminated.


Ладно, вроде как не находит компонент ядра, укажем путь явно:

$ gcc -o wifi_sniffer wifi_sniffer.c -lpcap -I /usr/src/linux-headers-$(uname -r)/include/


Получаем много ошибок:
In file included from /usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/limits.h:6,
from /usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/kernel.h:16,
from /usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/skbuff.h:13,
from /usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/if_ether.h:19,
from /usr/include/net/ethernet.h:27,
from wifi_sniffer.c:7:
/usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/types.h:15:33: error: conflicting types for ‘fd_set’; have ‘__kernel_fd_set’
15 | typedef __kernel_fd_set fd_set;
| ^~~~~~
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:179,
from /usr/include/stdlib.h:395,
from wifi_sniffer.c:2:
/usr/include/x86_64-linux-gnu/sys/select.h:70:5: note: previous declaration of ‘fd_set’ with type ‘fd_set’
70 | } fd_set;
| ^~~~~~
/usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/types.h:16:33: error: conflicting types for ‘dev_t’; have ‘__kernel_dev_t’ {aka ‘unsigned int’}
16 | typedef __kernel_dev_t dev_t;
| ^~~~~
/usr/include/x86_64-linux-gnu/sys/types.h:59:17: note: previous declaration of ‘dev_t’ with type ‘dev_t’ {aka ‘long unsigned int’}
59 | typedef __dev_t dev_t;
| ^~~~~
/usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/types.h:20:33: error: conflicting types for ‘nlink_t’; have ‘u32’ {aka ‘unsigned int’}
20 | typedef u32 nlink_t;
| ^~~~~~~
/usr/include/x86_64-linux-gnu/sys/types.h:74:19: note: previous declaration of ‘nlink_t’ with type ‘nlink_t’ {aka ‘long unsigned int’}
74 | typedef __nlink_t nlink_t;
| ^~~~~~~
/usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/types.h:26:33: error: conflicting types for ‘timer_t’; have ‘__kernel_timer_t’ {aka ‘int’}
26 | typedef __kernel_timer_t timer_t;
| ^~~~~~~
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:130:
/usr/include/x86_64-linux-gnu/bits/types/timer_t.h:7:19: note: previous declaration of ‘timer_t’ with type ‘timer_t’ {aka ‘void *’}
7 | typedef __timer_t timer_t;
| ^~~~~~~
/usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/types.h:46:33: error: conflicting types for ‘loff_t’; have ‘__kernel_loff_t’ {aka ‘long long int’}
46 | typedef __kernel_loff_t loff_t;
| ^~~~~~
/usr/include/x86_64-linux-gnu/sys/types.h:42:18: note: previous declaration of ‘loff_t’ with type ‘loff_t’ {aka ‘long int’}
42 | typedef __loff_t loff_t;
| ^~~~~~
/usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/types.h:107:33: error: conflicting types for ‘uint64_t’; have ‘u64’ {aka ‘long long unsigned int’}
107 | typedef u64 uint64_t;
| ^~~~~~~~
In file included from /usr/include/stdint.h:37,
from /usr/lib/gcc/x86_64-linux-gnu/12/include/stdint.h:9,
from /usr/include/inttypes.h:27,
from /usr/include/pcap/pcap-inttypes.h:78,
from /usr/include/pcap/pcap.h:117,
from wifi_sniffer.c:4:
/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h:27:20: note: previous declaration of ‘uint64_t’ with type ‘uint64_t’ {aka ‘long unsigned int’}
27 | typedef __uint64_t uint64_t;
| ^~~~~~~~
/usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/types.h:108:33: error: conflicting types for ‘u_int64_t’; have ‘u64’ {aka ‘long long unsigned int’}
108 | typedef u64 u_int64_t;
| ^~~~~~~~~
/usr/include/x86_64-linux-gnu/sys/types.h:161:20: note: previous declaration of ‘u_int64_t’ with type ‘u_int64_t’ {aka ‘long unsigned int’}
161 | typedef __uint64_t u_int64_t;
| ^~~~~~~~~
/usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/types.h:109:33: error: conflicting types for ‘int64_t’; have ‘s64’ {aka ‘long long int’}
109 | typedef s64 int64_t;
| ^~~~~~~
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:155:
/usr/include/x86_64-linux-gnu/bits/stdint-intn.h:27:19: note: previous declaration of ‘int64_t’ with type ‘int64_t’ {aka ‘long int’}
27 | typedef __int64_t int64_t;
| ^~~~~~~
/usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/types.h:126:13: error: conflicting types for ‘blkcnt_t’; have ‘u64’ {aka ‘long long unsigned int’}
126 | typedef u64 blkcnt_t;
| ^~~~~~~~
/usr/include/x86_64-linux-gnu/sys/types.h:192:20: note: previous declaration of ‘blkcnt_t’ with type ‘blkcnt_t’ {aka ‘long int’}
192 | typedef __blkcnt_t blkcnt_t; /* Type to count number of disk blocks. */
| ^~~~~~~~
In file included from /usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/kernel.h:17:
/usr/src/linux-headers-6.2.2-x64v1-xanmod1/include/linux/linkage.h:8:10: fatal error: asm/linkage.h: No such file or directory
8 | #include
| ^~~~~~~~~~~~~~~
compilation terminated.


Что я делаю не так?
  • Вопрос задан
  • 455 просмотров
Подписаться 1 Простой 5 комментариев
Пригласить эксперта
Ответы на вопрос 1
hint000
@hint000
у админа три руки
Есть такой код (не мой)

Что я делаю не так?
1. вы не даёте ссылку на источник кода, а это могло бы упростить разбор.
2. вангую, что этому коду лет десять, может быть меньше, может быть больше. Давайте посмотрим, какие версии ядра Linux были поддерживаемыми лет 10 назад; а это были версии 2.6.x и 3.x.x; версия 4.0 впервые появилась в 2015 г., версия 5.0 - в 2019 г. Уже поняли, на что я намекаю? Вы пытаетесь подсунуть компилятору исходники ядра одной из последних версий, на которой этот код, возможно, никто вообще не тестировал. Сколько там изменений было за десяток лет... Короче, пробуйте его скомпилировать вместе с исходниками 3.x. Если ошибок будет хотя бы меньше - уже кое-что.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы