GNU/Linux >> Znalost Linux >  >> Linux

Jak provádět čichání paketů pomocí Libpcap s ukázkovým kódem C

Síťové nástroje jako wireshark, tcpdump atd. jsou poměrně oblíbené pro sniffování paketů. Tento článek poskytuje základní přehled knihovny libpcap, která tvoří základ sniffování paketů pro mnoho nástrojů pro monitorování sítě včetně wireshark, tcpdump, snort atd.

Co je sledování paketů a jak to funguje?

Packet sniffing je technika, pomocí které lze snadno sledovat síťová data do az vašeho počítače. Data putují po síti ve formě paketů a nástroj pro vyhledávání paketů může tyto pakety snadno zachytit. Sniffery paketů většinou používají správci sítě a vývojáři pracující na síťových nástrojích. Ale celkové sniffery paketů jsou užitečné pro ladění problémů souvisejících se sítí a mohou je používat kdokoli, kdo má požadovaná oprávnění.

Sniffery paketů fungují tak, že sniffují na zařízení rozhraní, jako je eth0 atd. Seznam rozhraní lze získat příkazem ifconfig. Jakmile je rozhraní vybráno, mohou existovat některé možnosti, pomocí kterých lze filtrovat pakety na základě protokolu, zdrojového portu, cílového portu atd. Výběr možnosti filtru není nutný. Poté se zahájí zachycení paketů.

Chcete-li porozumět filtrům zachycení paketů a zobrazení, prostudujte si náš tutoriál o wireshark. Pro nástroj příkazového řádku se podívejte na tcpdump, který také provádí sniffování paketů, ale vytváří výstup na příkazovém řádku.

Knihovna libpcap

Libpcap je základní knihovna používaná pro sniffování paketů mnoha populárními nástroji pro monitorování sítě. Abychom porozuměli použití této knihovny, potřebujeme základní znalost programovacího jazyka C.

Zde je návod, jak libpcap funguje:

  • Vyberte zařízení síťového rozhraní, na kterém se má sniffování paketů provádět. Například ‚eth0‘ , ‚wlan0‘  atd. v systému Linux.
  • Jakmile je zařízení vybráno, inicializujte knihovnu pcap s tímto zařízením.
  • Dále můžeme použít možnosti filtru pro případy, jako když chceme čichat pouze pakety TCP/IP nebo pokud chceme určit, že čicháme pakety pouze z určitého zdrojového nebo cílového portu atd. Tento filtr je zkompilován a poté aplikován pomocí sadu funkcí knihovny libpcap.
  • Následně knihovna pcap vstoupí do své smyčky zachycování paketů, kde zachytí počet paketů nastavený programem.
  • Jakmile je paket zachycen, je zavolána funkce zpětného volání, ve které je celý paket k dispozici pro tisk jeho podrobností nebo jeho použití jiným způsobem

Výše uvedené čtyři kroky jsou základními kroky pro zahájení zachycování paketů prostřednictvím libpcap.

Příklad

Níže uvedený kód využívá funkce libpcap k dosažení základního zachycení paketů. Po zachycení paketů se ve funkci zpětného volání vytiskne délka každého paketu na stdout.

#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <string.h>

void callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char*
        packet)
{
  static int count = 1;

  printf("\nPacket number [%d], length of this packet is: %d\n", count++, pkthdr->len);
}

int main(int argc,char **argv)
{
    char *dev;
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t* descr;
    struct bpf_program fp;        /* to hold compiled program */
    bpf_u_int32 pMask;            /* subnet mask */
    bpf_u_int32 pNet;             /* ip address*/
    pcap_if_t *alldevs, *d;
    char dev_buff[64] = {0};
    int i =0;

    // Check if sufficient arguments were supplied
    if(argc != 3)
    {
        printf("\nUsage: %s [protocol][number-of-packets]\n",argv[0]);
        return 0;
    }

    // Prepare a list of all the devices
    if (pcap_findalldevs(&alldevs, errbuf) == -1)
    {
        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
        exit(1);
    }

    // Print the list to user
    // so that a choice can be
    // made
    printf("\nHere is a list of available devices on your system:\n\n");
    for(d=alldevs; d; d=d->next)
    {
        printf("%d. %s", ++i, d->name);
        if (d->description)
            printf(" (%s)\n", d->description);
        else
            printf(" (Sorry, No description available for this device)\n");
    }

    // Ask user to provide the interface name
    printf("\nEnter the interface name on which you want to run the packet sniffer : ");
    fgets(dev_buff, sizeof(dev_buff)-1, stdin);

    // Clear off the trailing newline that
    // fgets sets
    dev_buff[strlen(dev_buff)-1] = '';

    // Check if something was provided
    // by user
    if(strlen(dev_buff))
    {
        dev = dev_buff;
        printf("\n ---You opted for device [%s] to capture [%d] packets---\n\n Starting capture...",dev, (atoi)(argv[2]));
    }     

    // If something was not provided
    // return error.
    if(dev == NULL)
    {
        printf("\n[%s]\n", errbuf);
        return -1;
    }

    // fetch the network address and network mask
    pcap_lookupnet(dev, &pNet, &pMask, errbuf);

    // Now, open device for sniffing
    descr = pcap_open_live(dev, BUFSIZ, 0,-1, errbuf);
    if(descr == NULL)
    {
        printf("pcap_open_live() failed due to [%s]\n", errbuf);
        return -1;
    }

    // Compile the filter expression
    if(pcap_compile(descr, &fp, argv[1], 0, pNet) == -1)
    {
        printf("\npcap_compile() failed\n");
        return -1;
    }

    // Set the filter compiled above
    if(pcap_setfilter(descr, &fp) == -1)
    {
        printf("\npcap_setfilter() failed\n");
        exit(1);
    }

    // For every packet received, call the callback function
    // For now, maximum limit on number of packets is specified
    // by user.
    pcap_loop(descr,atoi(argv[2]), callback, NULL);

    printf("\nDone with packet sniffing!\n");
    return 0;
}

Ve výše uvedeném kódu:

  • Funkce pcap_findalldevs() se používá k načtení seznamu všech dostupných zařízení rozhraní. Tento seznam lze zobrazit uživateli, aby bylo možné vybrat zamýšlené rozhraní pro čichání paketů. Upozorňujeme, že existuje funkce pcap_lookupdev(), která také vrací zařízení rozhraní, ale problém s touto funkcí je, že vrací první dostupné zařízení bez zpětné smyčky. Takže v případě, že používám bezdrátové připojení k síti a zařízení rozhraní pro mé připojení je ‚wlan0‘, ale funkce pcap_lookupdev() by stále vrátila ‚eth0‘, když narazí na toto rozhraní jako první. Takže použití pcap_findalldevs() je lepší možnost, protože vytváří seznam zařízení rozhraní, ze kterých si můžete vybrat.
  • Seznam vrácený funkcí pcap_findalldevs() je předán uživateli a vstup uživatele je převzat z stdin.
  • Potom se k načtení IP adresy a síťové masky použije funkce pcap_lookupnet().
  • Prostřednictvím funkce pcap_open_live() je knihovna pcap inicializována s vybraným zařízením rozhraní.
  • Prostřednictvím funkce pcap_compile() můžeme zkompilovat libovolný filtr podle protokolu atd. nastaveného uživatelem.
  • Prostřednictvím pcap_setfilter() je tento filtr použit.
  • Nakonec pomocí funkce pcap_loop() knihovna zahájí zachycování paketů na vybraném zařízení s aplikovaným filtrem a s každým zachyceným relevantním paketem se zavolá funkce zpětného volání.

Zde je výstup výše uvedeného programu:

$ sudo ./pcap tcp 10
[sudo] password for himanshu:

Here is a list of available devices on your system:

1. eth0 (Sorry, No description available for this device)
2. wlan0 (Sorry, No description available for this device)
3. usbmon1 (USB bus number 1)
4. usbmon2 (USB bus number 2)
5. usbmon3 (USB bus number 3)
6. usbmon4 (USB bus number 4)
7. usbmon5 (USB bus number 5)
8. usbmon6 (USB bus number 6)
9. usbmon7 (USB bus number 7)
10. any (Pseudo-device that captures on all interfaces)
11. lo (Sorry, No description available for this device)

Enter the interface name on which you want to run the packet sniffer : wlan0

 ---You opted for device [wlan0] to capture [10] packets---

 Starting capture...
Packet number [1], length of this packet is: 496

Packet number [2], length of this packet is: 66

Packet number [3], length of this packet is: 357

Packet number [4], length of this packet is: 66

Packet number [5], length of this packet is: 238

Packet number [6], length of this packet is: 66

Packet number [7], length of this packet is: 403

Packet number [8], length of this packet is: 66

Packet number [9], length of this packet is: 121

Packet number [10], length of this packet is: 66

Done with packet sniffing!

Pokud nespouštíte výše uvedený program jako root, měli byste ke spuštění programu použít sudo, protože akce prováděné knihovnou libpcap vyžadují oprávnění superuživatele.


Linux
  1. Jak vytvářet vlákna v Linuxu (pomocí ukázkového programu C)

  2. Jak získat počet CPU v Linuxu pomocí C?

  3. Jak používat sdílenou paměť s Linuxem v C

  1. Jak načíst moduly jádra Linuxu z kódu C?

  2. Jak vytvořit příklad linuxového potrubí v c

  3. Jak připojit oddíl s mezerami v cestě

  1. Použití Ansible k interakci s webovými koncovými body

  2. Jak provést Chroot s jmennými prostory Linuxu?

  3. Jak změnit soubor na místě pomocí awk? (jako u sed -i)