-

   rss_rss_hh_new

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 51

:


[ ] PCAP

, 13 2017 . 13:59 +
  • ,
  • C
Lupus_Anay 13:59

PCAP

  • ,
  • C

Programming with pcap 2002 . PCAP. , , . , , .



, , . , C (, , ), , : , . , , PCAP (. : , , ). FreeBSD 4.3 .


: PCAP


PCAP . :


  1. , . Linux eth0, BSD xl1, . , PCAP .
  2. PCAP. PCAP , . . . , , , .
  3. , (, TCP/IP , 23 ) , "" , . , . , PCAP . , . PCAP .
  4. , PCAP . pcap_loop, PCAP , , . , , . . , , , .
  5. , , .
    . , ( 3). , .


. , .


. :


#include 
#include 

int main(int argc, char *argv[])
{
    char *dev = argv[1];
    printf("Device: %s\n", dev);
    return(0);
}

. , dev PCAP (, , )


. :


#include 
#include 

int main(int argc, char *argv[])
{
    char *dev, errbuf[PCAP_ERRBUF_SIZE];

    dev = pcap_lookupdev(errbuf);
    if (dev == NULL) 
    {
        fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
        return(2);
    }
    printf("Device: %s\n", dev);
    return(0);
}

, PCAP . " , ", . " errbuf?". PCAP . ? , , PCAP . , pcap_lookupdev() , errbuf. , ? .



. pcap_open_live(). :


pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)

. snaplen , , PCAP. promisc, true, ( , false, ). to_ms ( 0 ; , , . ). , ebuf ( , errbuf). .


, :


#include 
...
pcap_t *handle;

handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) 
{
    fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
    return(2);
}

dev, , BUFSIZ (, pcap.h). , , , errbuf; , , , .


/ : . , , , . , , . , , . . , , , , . . , , . , ( , APR). , .


. Ethernet , -Ethernet , Ethernet , , BSD OS X, PPP-, Wi-Fi- .


, , . pcap_datalink() . (C. . DHT_ )


, , :


if (pcap_datalink(handle) != DLT_EN10MB) 
{
    fprintf(stderr, "Device %s doesn't provide Ethernet headers -not  supported\n", dev);
    return(2);
}

Ethernet . , Ethernet.



. , 23(telnet) . 21(FTP). DNS ( 53 UDP). , , . pcap_compile() pcap_setfilter().


. , pcap_open_live() , . , if/else if ? : PCAP , BPF; , BPF . , PCAP .


, , . ( char). tcpdump.org; . , , , , .


pcap_compile(). :


int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)

(pcap_t* handle ). , . , . , , , (0 , 1 ). , , . -1 ; .


, . pcap_setfilter(). PCAP, :


int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

. , ( , pcap_compile()).


:


, PCAP
#include 
...
pcap_t *handle;  /*   */
char dev[] = "rl0";  /*    */
char errbuf[PCAP_ERRBUF_SIZE]; /*     */
struct bpf_program fp;  /*   */
char filter_exp[] = "port 23"; /*   */
bpf_u_int32 mask;  /*    */
bpf_u_int32 net;  /* IP  */

if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
    fprintf(stderr, "Can't get netmask for device %s\n", dev);
    net = 0;
    mask = 0;
}

handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
    fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
    return(2);
}

if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
    fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
    return(2);
}

if (pcap_setfilter(handle, &fp) == -1) {
    fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
    return(2);
}

23, , rl0.


, , . pcap_lookupnet() , IPv4 ( IPv4 ANDed , ). , .


, . , OpenBSD 2.9 c , FreeBSD 4.3 . .



, , . . . , , n . , , , . pcap_next():


u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

. , , , (, ). pcap_next() u_char , . .


pcap_next() :


#include 
#include 

int main(int argc, char *argv[])
{
    pcap_t *handle;   /*   */
    char *dev;   /*    */
    char errbuf[PCAP_ERRBUF_SIZE]; /*     */
    struct bpf_program fp;  /*   */
    char filter_exp[] = "port 23"; /*   */
    bpf_u_int32 mask;  /*   */
    bpf_u_int32 net;  /* IP */
    struct pcap_pkthdr header; /*     PCAP */
    const u_char *packet;  /*  */

    /*   */
    dev = pcap_lookupdev(errbuf);
    if (dev == NULL) 
    {
        fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
        return(2);
    }

    /*    */
    if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) 
    {
        fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev,   errbuf);
        net = 0;
        mask = 0;
    }

    /*      */
    handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
    if (handle == NULL) 
    {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        return(2);
    }

 /*     */
    if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) 
    {
        fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }

    if (pcap_setfilter(handle, &fp) == -1) 
    {
        fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }

    /*   */
    packet = pcap_next(handle, &header);
    /*    */
    printf("Jacked a packet with length of [%d]\n", header.len);
    /*   */
    pcap_close(handle);
    return(0);
}

, pcap_loockupdev(), . 23 (telnet) ( ). , pcap_close(), ( ).


pcap_loop() pcap_dispatch() ( pcap_loop()). , .


(callback function) , API. , . , . , . , , , . . PCAP, , , PCAP . pcap_loop() pcap_dispatch() . , ( . , , ).


pcap_loop() :


int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

. , pcap_loop() , ( , ). ( , ). , NULL. , , , , pcap_loop(). , . , u_char * , . , PCAP u_char *. , , PCAP , . , . pcap_dispatch() . pcap_dispatch() pcap_loop() , pcap_dispatch() , pcap_loop() . , PCAP.


pcap_loop(), . , pcap_loop() , . :


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

. void . , pcap_loop() , . pcap_loop(). , pcap_loop(), . PCAP , , , , . pcap_pkthdr pcap.h :


struct pcap_pkthdr {
    struct timeval ts; /*   */
    bpf_u_int32 caplen; /*   */
    bpf_u_int32 len; /*   */
};

. , . u_char, , pcap_loop().


( packet) ? , , , , ( , TCP/IP Ethernet , IP , TCP , , ). u_char . .


, , . TCP/IP Ethernet.


Ethernet, IP, TCP
/* Ethernet    6  */
#define ETHER_ADDR_LEN 6

 /*  Ethernet */
 struct sniff_ethernet {
    u_char ether_dhost[ETHER_ADDR_LEN]; /*   */
    u_char ether_shost[ETHER_ADDR_LEN]; /*   */
    u_short ether_type; /* IP? ARP? RARP?  .. */
 };

 /* IP header */
 struct sniff_ip {
    u_char ip_vhl;  /*  << 4 |   >> 2 */
    u_char ip_tos;  /*   */
    u_short ip_len;  /*   */
    u_short ip_id;  /*  */
    u_short ip_off;  /*    */
    #define IP_RF 0x8000  /* reserved   */
    #define IP_DF 0x4000  /* dont   */
    #define IP_MF 0x2000  /* more   */
    #define IP_OFFMASK 0x1fff /*     */
    u_char ip_ttl;  /*   */
    u_char ip_p;  /*  */
    u_short ip_sum;  /*   */
    struct in_addr ip_src,ip_dst; /*      */
 };
 #define IP_HL(ip)  (((ip)->ip_vhl) & 0x0f)
 #define IP_V(ip)  (((ip)->ip_vhl) >> 4)

 /* TCP header */
 typedef u_int tcp_seq;

 struct sniff_tcp {
    u_short th_sport; /*   */
    u_short th_dport; /*   */
    tcp_seq th_seq;  /*   */
    tcp_seq th_ack;  /*   */
    u_char th_offx2; /*  , rsvd */
    #define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
    u_char th_flags;
    #define TH_FIN 0x01
    #define TH_SYN 0x02
    #define TH_RST 0x04
    #define TH_PUSH 0x08
    #define TH_ACK 0x10
    #define TH_URG 0x20
    #define TH_ECE 0x40
    #define TH_CWR 0x80
    #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
    u_short th_win;  /*  */
    u_short th_sum;  /*   */
    u_short th_urp;  /*   */
};

PCAP u_char ? , . ? ( : ).


, , TCP/IP Ethernet. . , . , . .


/*  Ethernet    14  */
#define SIZE_ETHERNET 14

const struct sniff_ethernet *ethernet; /*  Ethernet */
const struct sniff_ip *ip; /*  IP */
const struct sniff_tcp *tcp; /*  TCP */
const char *payload; /*   */

u_int size_ip;
u_int size_tcp;

:


ethernet = (struct sniff_ethernet*)(packet);
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
size_ip = IP_HL(ip)*4;
if (size_ip < 20) {
    printf("   * Invalid IP header length: %u bytes\n", size_ip);
    return;
}
tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
size_tcp = TH_OFF(tcp)*4;
if (size_tcp < 20) {
    printf("   * Invalid TCP header length: %u bytes\n", size_tcp);
    return;
}
payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);

? . u_char .


, , . , , sniff_ethernet, , . Ethernet , 14, SIZE_ETHERNET.


, , . IP, Ethernet, . 4- IP. 4- , 4, . 20 .


TCP , 4- , " " TCP, 20 .


, :


VARIABLE LOCATION(in bytes)
sniff_ethernet X
sniff_ip X + SIZE_ETHERNET
sniff_tcp X + SIZE_ETHERNET + {IP header length}
payload X + SIZE_ETHERNET + {IP header length} + {TCP header length}

sniff_ethernet , , . sniff_ip, sniff_ethernet, , sniff_ethernet (14 SIZE_ETHERNET). sniff_tcp , X Ethernet, IP . (14 , 4 IP). , ( ) .


, , , . . sniffer.c .



PCAP. PCAP , , , . .


2002. . , :
:
, , .

This document is Copyright 2002 Tim Carstens. All rights reserved. Redistribution and use, with or without modification, are permitted provided that the following conditions are met:
Redistribution must retain the above copyright notice and this list of conditions.
The name of Tim Carstens may not be used to endorse or promote products derived from this document without specific prior written permission.
/ Insert 'wh00t' for the BSD license here /
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/337840/

:  

: [1] []
 

:
: 

: ( )

:

  URL