2012-10-31 39 views
12

Tôi đang cố gắng viết một kịch bản scapy có thể làm trung bình trong thời gian ping, vì vậy tôi cần phải có thời gian trôi qua giữa gói tin trả lời/trả lời ICMP được gửi và trả lời gói. Hiện tại, tôi có điều này:Scapy cách nhận thời gian ping?

#! /usr/bin/env python 
from scapy.all import * 
from time import * 

def QoS_ping(host, count=3): 
    packet = Ether()/IP(dst=host)/ICMP() 
    t=0.0 
    for x in range(count): 
     t1=time() 
     ans=srp(packet,iface="eth0", verbose=0) 
     t2=time() 
     t+=t2-t1 
    return (t/count)*1000 

Vấn đề là sử dụng hàm time() không tăng kết quả tốt. Ví dụ, tôi tìm thấy 134 ms trên một tên miền, và với chức năng hệ thống ping trên cùng một tên miền, tôi đã tìm thấy 30 ms (trung bình của khóa học).

Câu hỏi của tôi là: Có cách nào để nhận được chính xác thời gian được trợ giúp giữa các gói tin được gửi và nhận được gói bằng scapy không? Tôi không muốn sử dụng chức năng popen() hoặc các cuộc gọi hệ thống khác vì tôi cần scapy cho quản lý gói tương lai.

+0

Bạn có thể có may mắn hơn bằng cách sử dụng 'time.clock()' thay vì 'time.time()'. –

+0

Nó cũng có thể hoạt động tốt hơn với 'srp1' thay vì' srp'. –

+0

Nathan, bất cứ điều gì bạn làm trong scapy là khủng khiếp chậm ... scapy phân tích toàn bộ gói trong python (trong không gian người dùng). Nó không thể cạnh tranh với triển khai C sử dụng các cuộc gọi hệ điều hành OS. –

Trả lời

6

Scapy là chậm vì nó là python tinh khiết phân tích toàn bộ gói trong không gian người dùng ... it is not all that unusual to hack around scapy's thoughput limitations.

Làm một quả táo để so sánh táo ... Tôi có một máy chủ Xeon với một ống ethernet trực tiếp biểu diễn với internet, nhưng lưu lượng truy cập của tôi rất nhẹ trên đó. Khi tôi chạy một ping bình thường để router Cisco nó gắn liền với, tôi trung bình khoảng 60 micro giây mỗi ...

[[email protected] ~]$ ping -W 1 -c 3 192.0.2.1 
PING 192.0.2.1 (192.0.2.6) 56(84) bytes of data. 
64 bytes from 192.0.2.1: icmp_req=1 ttl=64 time=0.078 ms 
64 bytes from 192.0.2.1: icmp_req=2 ttl=64 time=0.062 ms 
64 bytes from 192.0.2.1: icmp_req=3 ttl=64 time=0.062 ms 

--- 192.0.2.1 ping statistics --- 
3 packets transmitted, 3 received, 0% packet loss, time 1998ms 
rtt min/avg/max/mdev = 0.062/0.067/0.078/0.010 ms 
[[email protected] ~]$ 

Điểm đến cùng trong scapy ... cũng được đo bằng mili giây ...

[[email protected] ~]$ sudo python new_ping_ip.py 
Ping: 0.285587072372 
Ping: 0.230889797211 
Ping: 0.219928979874 
AVERAGE 245.468616486 
[[email protected] ~]$ 

Kết quả của Scapy gần như là lần lớn hơn ping cơ sở từ lời nhắc bash (245.469/0.062) ... Tôi đã tự mình chạy cáp, cáp này dưới cáp 10 chân tới bộ định tuyến Cisco.

Bạn có thể làm gì để có kết quả tốt hơn? Như đã đề cập trong các nhận xét, hãy xem sent_timetime ... Packet.time được điền trước khi phân tích cú pháp ... điều này vẫn chậm hơn so với ping từ trình bao, nhưng có thể giúp bạn nắm bắt các gói trong scapy.

#! /usr/bin/env python 
from scapy.all import * 

def QoS_ping(host, count=3): 
    packet = Ether()/IP(dst=host)/ICMP() 
    t=0.0 
    for x in range(count): 
     ans,unans=srp(packet,iface="eth0", filter='icmp', verbose=0) 
     rx = ans[0][1] 
     tx = ans[0][0] 
     delta = rx.time-tx.sent_time 
     print "Ping:", delta 
     t+=delta 
    return (t/count)*1000 

if __name__=="__main__": 
    total = QoS_ping('192.0.2.1') 
    print "TOTAL", total 

mẫu chạy ...

[[email protected] ~]$ sudo python ping_ip.py 
Ping: 0.000389099121094 
Ping: 0.000531911849976 
Ping: 0.000631093978882 
TOTAL 0.51736831665 
[[email protected] ~]$ 

Thậm chí sử dụng Packet.timePacket.sent_time là chậm so với một cuộc gọi shell mặc dù ...

>>> from subprocess import Popen, PIPE 
>>> import re 
>>> cmd = Popen('ping -q -c 3 192.0.2.1'.split(' '), stdout=PIPE) 
>>> output = cmd.communicate()[0] 
>>> match = re.search('(\d+\.\d+)\/(\d+\.\d+)\/(\d+\.\d+)\/(\d+\.\d+)\s+ms', output) 
>>> if not (match is None): 
...  print "Average %0.3f" % float(match.group(1)) 
... else: 
...  print "Failure" 
... 
Average 0.073 
>>> 

ping -q -c 3 cung cấp đầu ra bản tóm tắt của 3 ping mà không cần ping riêng lẻ.

Nếu bạn muốn chụp các gói tin ping của bạn (thông qua một cuộc gọi vỏ ping) cho sau này scapy chế biến, đẻ trứng tcpdump -c <num-packets> -w <filename> icmp and host <host-addr> & trước khi chạy ping CLI của bạn ... sau đó sử dụng scapy của rdpcap() để đọc các tập tin pcap từ tcpdump. Hãy chắc chắn tính toán đúng số gói bạn sẽ nắm bắt trong tệp pcap của bạn.

+0

TRẢ LỜI: Tôi đã tìm thấy điều này: "Đã gửi gói tin đã gửi_time ', trả lời gói havetime' thuộc tính." tại http://comments.gmane.org/gmane.comp.security.scapy.general/4385 – user1789326

+0

@ user1789326: bạn có thể đăng cho bạn nhận xét dưới dạng câu trả lời – jfs

+1

lý do tại sao mức trung bình là 0,29, 0,23, 0,22 là 245? – jfs

0

BTW, sử dụng python không bị trầy xước (python -u để bắt đầu nó) tăng độ chính xác thời gian vì python không chờ các bộ đệm quyết định đổ. Sử dụng kịch bản trên của bạn, nó đã thay đổi kết quả của tôi khỏi bị tắt bởi 0,4 ms để được tắt bởi 0,1-ish.

0

Mike, chỉ cần một sửa chữa nhỏ để có được thời gian trung bình, thay đổi:

print "Average %0.3f" % float(match.group(1)) 

tới:

print "Average %0.3f" % float(match.group(2)) 

từ (match.group (1)) sẽ có thời gian tối thiểu và không phải là avg như đã đề cập.

Các vấn đề liên quan