1#!/usr/bin/env python
2
3import time, sys
4
5import dnet
6sys.path.insert(0, '.')
7import dpkt
8from impacket import ImpactDecoder, ImpactPacket
9from openbsd import packet
10import scapy
11import xstruct
12
13xip = xstruct.structdef('>', [
14    ('v_hl', ('B', 1), (4 << 4) | (dnet.IP_HDR_LEN >> 2)),
15    ('tos', ('B', 1), dnet.IP_TOS_DEFAULT),
16    ('len', ('H', 1), dnet.IP_HDR_LEN),
17    ('id', ('H', 1), 0),
18    ('off', ('H', 1), 0),
19    ('ttl', ('B', 1), dnet.IP_TTL_DEFAULT),
20    ('p', ('B', 1), 0),
21    ('sum', ('H', 1), 0),
22    ('src', ('s', dnet.IP_ADDR_LEN), dnet.IP_ADDR_ANY),
23    ('dst', ('s', dnet.IP_ADDR_LEN), dnet.IP_ADDR_ANY)
24    ])
25
26xudp = xstruct.structdef('>', [
27    ('sport', ('B', 1), 0),
28    ('dport', ('B', 1), 0),
29    ('ulen', ('H', 1), dnet.UDP_HDR_LEN),
30    ('sum', ('H', 1), 0)
31    ])
32
33def compare_create(cnt):
34    """
35dpkt: 14915.2445937 pps
36dpkt (manual): 15494.3632903 pps
37impacket: 3929.30572776 pps
38openbsd.packet: 1503.7928579 pps
39scapy: 348.449269721 pps
40xstruct: 88314.8953732 pps
41"""
42    src = dnet.addr('1.2.3.4').ip
43    dst = dnet.addr('5.6.7.8').ip
44    data = 'hello world'
45
46    start = time.time()
47    for i in xrange(cnt):
48        dnet.ip_checksum(
49            str(dpkt.ip.IP(src=src, dst=dst, p=dnet.IP_PROTO_UDP,
50                         len = dnet.IP_HDR_LEN + dnet.UDP_HDR_LEN + len(data),
51                         data=dpkt.udp.UDP(sport=111, dport=222,
52                                       ulen=dnet.UDP_HDR_LEN + len(data),
53                                       data=data))))
54    print 'dpkt:', cnt / (time.time() - start), 'pps'
55
56    start = time.time()
57    for i in xrange(cnt):
58        dnet.ip_checksum(str(dpkt.ip.IP(src=src, dst=dst, p=dnet.IP_PROTO_UDP,
59                                     len=dnet.IP_HDR_LEN + dnet.UDP_HDR_LEN +
60                                     len(data))) +
61                         str(dpkt.udp.UDP(sport=111, dport=222,
62                                      ulen=dnet.UDP_HDR_LEN + len(data))) +
63                         data)
64    print 'dpkt (manual):', cnt / (time.time() - start), 'pps'
65
66    start = time.time()
67    for i in xrange(cnt):
68        ip = ImpactPacket.IP()
69        ip.set_ip_src('1.2.3.4')
70        ip.set_ip_dst('5.6.7.8')
71        udp = ImpactPacket.UDP()
72        udp.set_uh_sport(111)
73        udp.set_uh_dport(222)
74        udp.contains(ImpactPacket.Data(data))
75        ip.contains(udp)
76        ip.get_packet()
77    print 'impacket:', cnt / (time.time() - start), 'pps'
78
79    start = time.time()
80    for i in xrange(cnt):
81        p = packet.createPacket(packet.IP, packet.UDP)
82        p['ip'].src = '1.2.3.4'
83        p['ip'].dst = '5.6.7.8'
84        p['udp'].sport = 111
85        p['udp'].dport = 22
86        p['udp'].payload = data
87        p.finalise()
88        p.getRaw()
89    print 'openbsd.packet:', cnt / (time.time() - start), 'pps'
90
91    start = time.time()
92    for i in xrange(cnt):
93        ip = scapy.IP(src='1.2.3.4', dst='5.6.7.8') / \
94             scapy.UDP(sport=111, dport=222) / data
95        ip.build()
96    print 'scapy:', cnt / (time.time() - start), 'pps'
97
98    start = time.time()
99    for i in xrange(cnt):
100        udp = xudp()
101        udp.sport = 111
102        udp.dport = 222
103        udp.ulen = dnet.UDP_HDR_LEN + len(data)
104        ip = xip()
105        ip.src = src
106        ip.dst = dst
107        ip.p = dnet.IP_PROTO_UDP
108        ip.len = dnet.IP_HDR_LEN + udp.ulen
109        dnet.ip_checksum(str(ip) + str(udp) + data)
110    print 'xstruct:', cnt / (time.time() - start), 'pps'
111
112def compare_parse(cnt):
113    """
114dpkt: 23347.462887 pps
115impacket: 9937.75963595 pps
116openbsd.packet: 6826.5955563 pps
117scapy: 1461.74727127 pps
118xstruct: 206100.202449 pps
119"""
120    s = 'E\x00\x00T\xc2\xf3\x00\x00\xff\x01\xe2\x18\n\x00\x01\x92\n\x00\x01\x0b\x08\x00\xfc\x11:g\x00\x00A,\xc66\x00\x0e\xcf\x12\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!"#$%&\'()*+,-./01234567'
121
122    start = time.time()
123    for i in xrange(cnt):
124        dpkt.ip.IP(s)
125    print 'dpkt:', cnt / (time.time() - start), 'pps'
126
127    decoder = ImpactDecoder.IPDecoder()
128    start = time.time()
129    for i in xrange(cnt):
130        decoder.decode(s)
131    print 'impacket:', cnt / (time.time() - start), 'pps'
132
133    start = time.time()
134    for i in xrange(cnt):
135        packet.Packet(packet.IP, s)
136    print 'openbsd.packet:', cnt / (time.time() - start), 'pps'
137
138    start = time.time()
139    for i in xrange(cnt):
140        scapy.IP(s)
141    print 'scapy:', cnt / (time.time() - start), 'pps'
142
143    start = time.time()
144    for i in xrange(cnt):
145        ip = xip(s[:dnet.IP_HDR_LEN])
146        udp = xudp(s[dnet.IP_HDR_LEN:dnet.IP_HDR_LEN + dnet.UDP_HDR_LEN])
147        data = s[dnet.IP_HDR_LEN + dnet.UDP_HDR_LEN:]
148    print 'xstruct:', cnt / (time.time() - start), 'pps'
149
150def compare_checksum(cnt):
151    s = 'A' * 80
152    start = time.time()
153    for i in range(cnt):
154        dpkt.in_cksum(s)
155    print 'dpkt.in_cksum:', cnt / (time.time() - start), 'pps'
156
157    start = time.time()
158    for i in range(cnt):
159        dnet.ip_cksum_carry(dnet.ip_cksum_add(s, 0))
160    print 'dnet.ip_cksum_add/carry:', cnt / (time.time() - start), 'pps'
161
162def main():
163    import psyco
164    psyco.full()
165
166    ITER=10000
167
168    print 'checksum:'
169    compare_checksum(100000)
170
171    print 'create:'
172    compare_create(ITER)
173
174    print 'parse:'
175    compare_parse(ITER)
176
177if __name__ == '__main__':
178    main()
179    """
180    import hotshot, hotshot.stats
181    prof = hotshot.Profile('/var/tmp/dpkt.prof')
182    prof.runcall(main)
183    prof.close()
184    stats = hotshot.stats.load('/var/tmp/dpkt.prof')
185    stats.strip_dirs()
186    stats.sort_stats('time', 'calls')
187    stats.print_stats(20)
188    """
189