코딩/C

pcap

비니화이팅 2020. 2. 24. 16:22

1. #apt-get install libpcap-dev로 pcap라이브러리 설치

 

2. pro파일에 LIBS += -lpcap추가

 

3. #include <pcap.h> 추가

 

Example 1

/* tcp 80 패킷만 출력 */
#include <stdio.h>
#include <pcap.h>
#include <arpa/inet.h>  /* in_addr 구조체 */
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

int cnt=0;

void printMac(u_int8_t eth_mac[]) {
    for(int i=0; i<=ETHER_ADDR_LEN-2; i++){
        printf("%02x:", eth_mac[i]);
    }
    printf("%02x\n", eth_mac[ETHER_ADDR_LEN-1]);
}

void callback(u_char *args, const pcap_pkthdr *header, const u_char *packet)
{
    struct ether_header *eth;
    struct ip *iph;
    struct tcphdr *tcph;

    printf("================= num.%d =================\n", ++cnt);

    eth = (struct ether_header *)packet;
    printf("<ethernet>\n");
    printf("Dst MAC -> ");
    printMac(eth->ether_dhost);
    printf("Src MAC -> ");
    printMac(eth->ether_shost);
    printf("\n");

    iph = (struct ip *)(packet += sizeof(struct ether_header));
    printf("<IP>\n");
    printf("Src IP Address : %s\n", inet_ntoa(iph->ip_src));
    printf("Dst IP Address : %s\n", inet_ntoa(iph->ip_dst));
    printf("\n");

    tcph = (struct tcphdr *)(packet + iph->ip_hl * 4);   /* 5 * 4 = 20byte */
   printf("<TCP>\n");
    printf("Src Port : %d\n" , ntohs(tcph->source));
    printf("Dst Port : %d\n" , ntohs(tcph->dest));
    printf("\n");
}

int main(int argc, char **argv)
{
    char *dev;
    char *errbuf;
    char rule[] = "port 80";
    bpf_u_int32 net;
    bpf_u_int32 mask;
    struct in_addr net_addr, mask_addr;
    struct bpf_program fp;   /* 패킷에 대한 필터를 만들어줌. 컴파일된 필터 */
    pcap_t *handle;

    if(!(dev = pcap_lookupdev(errbuf))) {   /* 네떡 인터페이스 */
        printf("%s", errbuf); return -1;
    }

    if(pcap_lookupnet(dev, &net, &mask , errbuf) == -1) {   /* 네떡 정보 출력 */
        printf("%s", errbuf); return -1;
    }

    net_addr.s_addr = net;
    mask_addr.s_addr = mask;

    printf("Device : %s\n", dev);
    printf("Net Address : %s\n", inet_ntoa(net_addr));
    printf("Netmask : %s\n", inet_ntoa(mask_addr));

    if(!(handle = pcap_open_live(dev, 65535, 1, 0, errbuf))) {  /* promisc mode로 인터페이스 핸들러 반환 */
        printf("%s", errbuf); return -1;
    }

    if(pcap_compile(handle, &fp, rule, 1, net) == -1){    /* 필터 컴파일 */
        printf("pcap_complie error"); return -1;
    }

    if(pcap_setfilter(handle, &fp) == -1) { /* 필터 적용 */
        printf("pcap_setfilter error"); return -1;
    }

    pcap_loop(handle, 0, callback, NULL); /* 계속(0) 패킷 캡처 */

    pcap_close(handle);

    return 0;
}

 

Example 2

#include <stdio.h>
#include <string.h>
#include <pcap.h>
#include <arpa/inet.h>  /* in_addr 구조체 */
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

void printMac(u_int8_t eth_mac[]) {
    for(int i=0; i<=ETHER_ADDR_LEN-2; i++){
        printf("%02x:", eth_mac[i]);
    }
    printf("%02x\n", eth_mac[ETHER_ADDR_LEN-1]);
}

int main(int argc, char **argv)
{
    int cnt=0;
    int res;
    char *dev;
    char *errbuf;
    char *ptr;
    const unsigned char *data;
    bpf_u_int32 net;
    bpf_u_int32 mask;
    struct in_addr net_addr, mask_addr;
    struct ether_header *eth;
    struct ip *iph;
    struct tcphdr *tcph;
    struct pcap_pkthdr *header;
    pcap_t *handle;

    if(!(dev = pcap_lookupdev(errbuf))) {   /* 네떡 인터페이스 */
        printf("%s", errbuf); return -1;
    }

    if(pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {   /* 네떡 정보 출력 */
        printf("%s", errbuf); return -1;
    }

    net_addr.s_addr = net;
    mask_addr.s_addr = mask;

    if(!(handle = pcap_open_live(dev, 65535, 1, 0, errbuf))) {  /* promisc mode로 인터페이스 핸들러 반환 */
        printf("%s", errbuf); return -1;
    }

    while((res=pcap_next_ex(handle, &header,&data))>=0) {    /* pcap_loop 대신 */
        if (res==0) continue;

        eth = (struct ether_header *)data;
        iph = (struct ip *)(data += sizeof(struct ether_header));
        tcph = (struct tcphdr *)(data += iph->ip_hl * 4);

        if(ntohs(tcph->dest)==80)
        {
        data += tcph->th_off * 4;
        if((ptr = strstr((char *)data, "Host")) != NULL) {
            int cnt=0;
            while(!(ptr[cnt] == 0x0d)){
                printf("%c", ptr[cnt++]);
            }
            printf("\n");
        }
        }
    }
    pcap_close(handle);

    return 0;
}