Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5772076
  • 博文数量: 675
  • 博客积分: 20301
  • 博客等级: 上将
  • 技术积分: 7671
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 16:15
文章分类

全部博文(675)

文章存档

2012年(1)

2011年(20)

2010年(14)

2009年(63)

2008年(118)

2007年(141)

2006年(318)

分类: Python/Ruby

2009-10-26 22:11:38

要写一个捕包分析的小程序,要在windows上运行,不想找一个windows机器,安装开发环境,就想用Python来写,这样跨平台吗;-)

安装
1. python 2.5
2. pypcap

3. dpkt

4. winpcap
如果有wireshark的话,就直接安装wireshark吧,里面带着winpcap

代码
捕获接收到的所有udp报文,然后判断报文内容是不是bencode格式的,然后将bencode报文的源IP和源Port输出。
# -*- coding: utf8 -*-
#!/usr/bin/env python

import pcap
import dpkt

dev='eth0' #windows下,可以根据wireshark的输出填写:\Device\NPF_{87AF0973-017E-4479-9654-A6384FDBB030}
filter='ip dst 192.168.1.2 and udp'

pc=pcap.pcap(dev)
pc.setfilter(filter)

file = open('./dht_nodes.txt','w')
for ptime,pdata in pc:
    ether=dpkt.ethernet.Ethernet(pdata)
    #p=dpkt.ip.IP(pdata)
    ip=ether.data
    ip_str='%d.%d.%d.%d'%tuple(map(ord,list(ip.src)))

    udp=ip.data
    port=udp.sport
    node='%s:%d'%(ip_str,port)
    content_len=len(udp)-8

    #简单判断UDP报文内容是不是bencode的
    if udp.data[0] == 'd' and udp.data[content_len-1] == 'e':
        print node
        file.write(node+'\n')
        file.flush()

在windows上面安装不算麻烦,在我的debian上安装也不麻烦,但是在远程的Redhat上安装真是麻烦,不是缺这个包就是缺那个包。怒了,用C写了一个。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define ETHHDR_SIZE 14

struct ip_header
{
#ifdef WORDS_BIGENDIAN
u_int8_t ip_version:
    4,
ip_header_length:
    4;
#else
u_int8_t ip_header_length:
    4,
ip_version:
    4;
#endif

    u_int8_t ip_tos;
    u_int16_t ip_length;
    u_int16_t ip_id;
    u_int16_t ip_off;
    u_int8_t ip_ttl;
    u_int8_t ip_protocol;
    u_int16_t ip_checksum;
    struct in_addr ip_src_address;
    struct in_addr ip_dst_address;
};

struct tcp_header
{
    u_int16_t tcp_src_port;
    u_int16_t tcp_dst_port;
    u_int32_t tcp_sequence;
    u_int32_t tcp_ack;

#ifdef WORDS_BIGENDIAN
u_int8_t tcp_offset:
    4,
tcp_reserverd:
    4;
#else
u_int8_t tcp_reserverd:
    4,
tcp_offset:
    4;
#endif

    u_int8_t tcp_flags;
    u_int16_t tcp_windows;
    u_int16_t tcp_checksum;
    u_int16_t tcp_urgent_pointer;
};

struct udp_header
{
    u_int16_t udp_src_port;
    u_int16_t udp_dst_port;
    u_int16_t udp_len;
    u_int16_t udp_checksum;
};

FILE *fp;

void GoDaemon(void);
void process_pkt(u_char *argument,const struct pcap_pkthdr* packet_header,const u_char *packet_content);

int main(int argc, char *argv[])
{
    pcap_t* pcap_handle;
    char err_content[PCAP_ERRBUF_SIZE];
    char *net_interface=NULL;
    struct bpf_program bpf_filter;
    char bpf_filter_string[64]="ip dst 172.16.11.11 and udp";
    char filename[64]="./DHT_nodes.sav";
    bpf_u_int32 net_mask;
    bpf_u_int32 net_ip;

    if(argc==4)
    {
        net_interface = argv[1];
        memset(bpf_filter_string, 0, sizeof(bpf_filter_string));
        sprintf(bpf_filter_string, "ip dst %s and udp", argv[2]);
        memset(filename, 0, sizeof(filename));
        strcpy(filename, argv[3]);
        //filename=argv[3];
    }
    else
    {
        fprintf(stderr, "Usage: find_dhtnode INTERFACE IP FILENAME\n");
        fprintf(stderr, "  exp: find_dhtnode eth0 172.16.11.11 ./DHT_nodes.sav\n");
        return 0;
    }

    fp = fopen("./DHT_nodes.sav","w");
    if(fp==NULL)
    {
        perror("fopen");
        return;
    }

    assert(net_interface);
   
    //net_interface = pcap_lookupdev(err_content);
    pcap_lookupnet(net_interface,&net_ip,&net_mask,err_content);

    printf("Device: %s\n", net_interface);
    printf("Filter: %s\n", bpf_filter_string);

    pcap_handle = pcap_open_live(net_interface,BUFSIZ,1,0,err_content);

    pcap_compile(pcap_handle,&bpf_filter,bpf_filter_string,0,net_ip);

    pcap_setfilter(pcap_handle,&bpf_filter);

    if ( pcap_datalink(pcap_handle) != DLT_EN10MB )
    {
        return;
    }

    GoDaemon();

    pcap_loop(pcap_handle,-1,process_pkt,NULL);

    pcap_close(pcap_handle);

    fclose(fp);
    return 0;
}

void process_pkt(u_char *argument,const struct pcap_pkthdr* packet_header,const u_char *packet_content)
{
    struct ip_header *ip_protocol;
    struct udp_header* udp_protocol;
    unsigned char *data;
    int ip_length;
    int ip_header_length;
    int data_length;

    ip_protocol = (struct ip_header *) (packet_content+ETHHDR_SIZE);
    /*ip_length Need to change from net mode into host mode*/
    ip_length = ntohs(ip_protocol->ip_length);
    ip_header_length = ip_protocol->ip_header_length*4;

    udp_protocol = (struct udp_header *)(packet_content+ETHHDR_SIZE+ip_header_length);
    data_length = ntohs(udp_protocol->udp_len) - 8;
    data = (unsigned char *)(packet_content + ETHHDR_SIZE + ip_header_length + 8);

    if(data[0] == 'd' && data[data_length-1] == 'e')
    {
         /*inet_ntoa is not thread security*/
         fprintf(fp, "%s:%d\n",inet_ntoa(ip_protocol->ip_src_address),ntohs(udp_protocol->udp_src_port));
     fflush(fp);
    }

}

void GoDaemon(void)
{
    pid_t fs;
    printf("Initializing daemon mode\n");

    if (getppid() != 1)
    {
        fs = fork();

        if (fs > 0)
        {
            exit(0);                /* parent */
        }

        if (fs < 0)
        {
            perror("fork");
            exit(1);
        }
        setsid();
    }

    chdir("/");

    /* redirect stdin/stdout/stderr to /dev/null */
    close(0);
    close(1);
    close(2);

    open("/dev/null", O_RDWR);

    dup(0);
    dup(0);

    return;
}
阅读(5387) | 评论(6) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-12-19 23:36:36

很牛逼

chinaunix网友2010-12-19 23:36:36

很牛逼

chinaunix网友2010-01-08 10:38:04

相当牛逼

chinaunix网友2010-01-08 10:38:04

相当牛逼

chinaunix网友2009-10-27 19:03:23

lz牛逼。。。