分类: Python/Ruby
2009-10-26 22:11:38
# -*- 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() |
#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; } |