Chinaunix首页 | 论坛 | 博客
  • 博客访问: 140768
  • 博文数量: 12
  • 博客积分: 1411
  • 博客等级: 上尉
  • 技术积分: 433
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-25 14:25
文章分类

全部博文(12)

文章存档

2009年(3)

2008年(9)

我的朋友

分类: C/C++

2008-05-27 14:44:57

    用libpcap库对网络来的数据包进行抓取,然后提供给程序来分析,这个程序实现了对HTTP的GET包进行抓取并且打印。
    通过些例子可以了解整个网络数据包的抓取与处理过程,学习从最基本的东西入手。再复杂的系统不过是通过最最基本的东西来的,简单化是学习原理最好的方法。我认为,学习一个东西一下子搞了太复杂,反而起了反作用,让你的头一下子晕了,不知道应该干什么了?
 
 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pcap.h>

#include <netinet/if_ether.h>

#define FALSE 0
#define TRUE 1
#define MAC_ALEN 6

/*********************************/
#define IP_PROTO_TCP 6
#define IP_PROTO_UDP 17

#define SYSTEM_IP inet_addr("10.8.0.27")

#define TCP_HLEN(pTcp) ((pTcp->hlen & 0xf0) >> 2)
#define TCP_DATA(pTcp) ((char *)pTcp+TCP_HLEN(pTcp))

typedef signed char BOOL;

typedef unsigned char UINT1;
typedef unsigned short UINT2;
typedef unsigned long UINT4;
typedef unsigned long long int UINT8;



typedef struct __st_ether
{
    UINT1 dest[MAC_ALEN];
    UINT1 src[MAC_ALEN];
    UINT2 proto;
    UINT1 data[1];
} tEther;


typedef struct __st_ip
{
    UINT1 hlen;
    UINT1 tos;
    UINT2 len;
    UINT2 ipid;
    UINT2 flagoff;
    UINT1 ttl;
    UINT1 proto;
    UINT2 cksum;
    UINT4 src;
    UINT4 dest;
    UINT1 data[1];
    
}tIp;


typedef struct __st_tcp
{
    UINT2 sport;
    UINT2 dport;
    UINT4 seq;
    UINT4 ack;
    UINT1 hlen;
    UINT1 code;
    UINT2 window;
    UINT2 chsum;
    UINT2 urg;
    char data[1];
    
}tTcp;


typedef struct __st_udp
{
    UINT2 sport;
    UINT2 dport;
    UINT2 len;
    UINT2 cksum;
    char data[1];
    
}tUdp;



void proc_pkt(u_char *user, const struct pcap_pkthdr *hp, const u_char *packet);

char *inet_htoa(UINT4 ipaddr);


//UINT4 system_ip;

//system_ip = inet_addr("10.8.0.27");



int main(int argc, char **argv)
{
    char *dev = NULL;
    pcap_t *descr;
    struct pcap_pkthdr hdr;
    u_char *packet;
    char errbuf[PCAP_ERRBUF_SIZE];
    int promisc = 0;
    int pcap_time_out = 100;

    struct tEther *pEpkt;


    bpf_u_int32 net, mask;

    dev = pcap_lookupdev(errbuf);

    pcap_lookupnet(dev, &net, &mask, errbuf);

    pcap_open_live(dev, 3000, 1, 100, errbuf);

    net = ntohl(net);
    mask = ntohl(mask);

    descr = pcap_open_live(dev,BUFSIZ,promisc,pcap_time_out,errbuf);


    pcap_loop (descr, -1, proc_pkt, NULL);
    

    printf("Net [%s], mask [%s]\n", inet_htoa(net), inet_htoa(mask));


    //printf("%s\n", dev);


    return 0;
}


void proc_pkt(u_char *user, const struct pcap_pkthdr *hp, const u_char *packet)
{
    tEther *pEther;
    tIp *pIp;

    pEther = (tEther *)packet;


    if (ntohs(pEther->proto) == ETHERTYPE_IP)
    {
        //printf("Get a ip pkt\n");

        //pIp = (tIp *)(packet + sizeof(tEther));

        pIp = (tIp *)pEther->data;

        if (pIp->dest == SYSTEM_IP || pIp->src == SYSTEM_IP)
        {
            //printf("fasfd");

            return ;
        }
        //printf("Src ip [%s], dest ip [%s], proto [%d]\n", inet_htoa(ntohl(pIp->src)), inet_htoa(ntohl(pIp->dest)), pIp->proto);


        if (pIp->proto == IP_PROTO_TCP)
        {
            tTcp *pTcp;
            char *tcp_data;
            char *pNext;
            char *http_get;
            int get_len;
            int host_len;
            char *http_host;
            char *tmp;
            char *tmp1 = NULL;

            pTcp = (tTcp *)pIp->data;

            tcp_data = (char *)pTcp->data;
            //tcp_data = TCP_DATA(pTcp);


            if (pTcp->dport == htons(80))
            {
                //printf("This is http pkt, dport [%d]\n", ntohs(pTcp->dport));


                pNext = strstr(tcp_data, " HTTP/1.");
                if (pNext == NULL)
                    return ;

                *pNext = '\0';
                http_get = tcp_data + 4;
                get_len = pNext - http_get;
                    
                    
                tmp = strstr(pNext+1, "Host: ");
                if (tmp == NULL)
                    return ;

                http_host = tmp + 6;
                tmp1 = strchr(http_host, '\r');

                if (tmp1 == NULL)
                    return ;

                *tmp1 = '\0';
                host_len = tmp1 - http_host;
                printf("Host [%s], host_len [%d]\n", http_host, host_len);
                                                       
            }
            
            //printf("%5s %19s %19s %8d %8d\n", "tcp", inet_htoa(ntohl(pIp->src)), inet_htoa(ntohl(pIp->dest)), ntohs(pTcp->sport), ntohs(pTcp->dport));

            
        }
        else if (pIp->proto == IP_PROTO_UDP)
        {
            tUdp *pUdp;
            pUdp = (tUdp *)pIp->data;
            
            //printf("%5s %19s %19s %8d %8d\n", "udp",inet_htoa(ntohl(pIp->src)), inet_htoa(ntohl(pIp->dest)), ntohs(pUdp->sport), ntohs(pUdp->dport));

        }
        
    }

    return ;
}


char *inet_htoa(UINT4 ipaddr)
{
    static char buf[10][20];
    static int index=0;
    UINT1 t1;
    BOOL bFlag = FALSE;
    char *pbuf = buf[index];

    t1 = (ipaddr >> 24) & 0xff;
    *pbuf = (t1 / 100);
    if (*pbuf != 0)
    {
        *pbuf += 0x30;
        pbuf++;
        bFlag = TRUE;
    }
    *pbuf = ((t1 / 10) % 10);
    if (*pbuf != 0)
    {
        *pbuf += 0x30;
        pbuf++;
    }
    else if (bFlag)
    {
        *pbuf += 0x30;
        pbuf++;
    }
    *pbuf++ = (t1 % 10) + 0x30;
    *pbuf++ = '.';

    /******************************/
    bFlag = FALSE;
    t1 = (ipaddr >> 16) & 0xff;
    *pbuf = (t1 / 100);
    if (*pbuf != 0)
    {
        *pbuf += 0x30;
        pbuf++;
        bFlag = TRUE;
    }
    *pbuf = ((t1 / 10) % 10);
    if (*pbuf != 0)
    {
        *pbuf += 0x30;
        pbuf++;
    }
    else if (bFlag)
    {
        *pbuf += 0x30;
        pbuf++;
    }
    *pbuf++ = (t1 % 10) + 0x30;
    *pbuf++ = '.';

    /******************************/
    bFlag = FALSE;
    t1 = (ipaddr >> 8) & 0xff;
    *pbuf = (t1 / 100);
    if (*pbuf != 0)
    {
        *pbuf += 0x30;
        pbuf++;
        bFlag = TRUE;
    }
    *pbuf = ((t1 / 10) % 10);
    if (*pbuf != 0)
    {
        *pbuf += 0x30;
        pbuf++;
    }
    else if (bFlag)
    {
        *pbuf += 0x30;
        pbuf++;
    }
    *pbuf++ = (t1 % 10) + 0x30;
    *pbuf++ = '.';

    /******************************/
    bFlag = FALSE;
    t1 = ipaddr & 0xff;
    *pbuf = (t1 / 100);
    if (*pbuf != 0)
    {
        *pbuf += 0x30;
        pbuf++;
        bFlag = TRUE;
    }
    *pbuf = ((t1 / 10) % 10);
    if (*pbuf != 0)
    {
        *pbuf += 0x30;
        pbuf++;
    }
    else if (bFlag)
    {
        *pbuf += 0x30;
        pbuf++;
    }
    *pbuf++ = (t1 % 10) + 0x30;
    *pbuf = '\0';

    pbuf = buf[index++];
    index = index % 10;
    return pbuf;
}

阅读(3220) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-09-08 16:05:01

系统的那个函数不能重入

chinaunix网友2009-07-17 10:51:59

为什么要自己实现inet_ntoa? 没有必要,先建立一个struct in_addr结构,再把IP地址(十进制表示)赋给它,然后直接调用inet_ntoa不就转化成点分十进制了嘛

chinaunix网友2008-12-06 21:29:34

代码如果注释一下就好了!这样可读性就更强了!