- 论坛徽章:
- 0
|
要写一个捕包分析的小程序,要在windows上运行,不想找一个windows机器,安装开发环境,就想用Python来写,这样跨平台吗;-)
安装
1. python 2.5
2. pypcap
http://code.google.com/p/pypcap/downloads/list
3. dpkt
http://code.google.com/p/dpkt/downloads/list
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
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/12592/showart_2079182.html |
|