decryption works, but addid doesn't because of unique pointer layers
[wireshark-sm.git] / test / suite_sharkd.py
blob7414deef954d9d246855769431ce4b2821c865dd
2 # Wireshark tests
3 # By Gerald Combs <gerald@wireshark.org>
5 # Copyright (c) 2018 Peter Wu <peter@lekensteyn.nl>
7 # SPDX-License-Identifier: GPL-2.0-or-later
9 '''sharkd tests'''
11 import json
12 import subprocess
13 import pytest
14 from matchers import *
17 @pytest.fixture(scope='session')
18 def cmd_sharkd(program):
19 return program('sharkd')
22 @pytest.fixture
23 def run_sharkd_session(cmd_sharkd, base_env):
24 def run_sharkd_session_real(sharkd_commands):
25 sharkd_proc = subprocess.Popen(
26 (cmd_sharkd, '-'), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8', env=base_env)
27 sharkd_proc.stdin.write('\n'.join(sharkd_commands))
28 stdout, stderr = sharkd_proc.communicate()
30 assert 'Hello in child.' in stderr
32 outputs = []
33 for line in stdout.splitlines():
34 line = line.strip()
35 if not line:
36 continue
37 try:
38 jdata = json.loads(line)
39 except json.JSONDecodeError:
40 pytest.fail('Invalid JSON: %r' % line)
41 outputs.append(jdata)
42 return tuple(outputs)
43 return run_sharkd_session_real
46 @pytest.fixture
47 def check_sharkd_session(run_sharkd_session):
48 def check_sharkd_session_real(sharkd_commands, expected_outputs):
49 sharkd_commands = [json.dumps(x) for x in sharkd_commands]
50 actual_outputs = run_sharkd_session(sharkd_commands)
51 assert expected_outputs == actual_outputs
52 return check_sharkd_session_real
55 class TestSharkd:
56 def test_sharkd_req_load_bad_pcap(self, check_sharkd_session, capture_file):
57 check_sharkd_session((
58 {"jsonrpc":"2.0", "id":1, "method":"load",
59 "params":{"file": capture_file('non-existant.pcap')}
61 ), (
62 {"jsonrpc":"2.0","id":1,"error":{"code":-2001,"message":"Unable to open the file"}},
65 def test_sharkd_req_load_truncated_pcap(self, check_sharkd_session, capture_file):
66 check_sharkd_session((
67 {"jsonrpc":"2.0", "id":1, "method":"load",
68 "params":{"file": capture_file('trunc.pcap')}
70 ), (
71 {"jsonrpc":"2.0","id":1,"result":{"status":"Less data was read than was expected","err":-12}},
74 def test_sharkd_req_status_no_pcap(self, check_sharkd_session):
75 check_sharkd_session((
76 {"jsonrpc":"2.0", "id":1, "method":"status"},
77 ), (
78 {"jsonrpc":"2.0","id":1,"result":{"frames":0,"duration":0.000000000,"columns":["No.","Time","Source","Destination","Protocol","Length","Info"],
79 "column_info":[{
80 "title":"No.","format": "%m","visible":True, "display": "R"
81 },{
82 "title": "Time", "format": "%t", "visible":True, "display": "R"
83 },{
84 "title": "Source", "format": "%s", "visible":True, "display": "R"
85 },{
86 "title": "Destination", "format": "%d", "visible":True, "display": "R"
87 },{
88 "title": "Protocol", "format": "%p", "visible":True, "display": "R"
89 },{
90 "title": "Length", "format": "%L", "visible":True, "display": "R"
91 },{
92 "title": "Info", "format": "%i", "visible":True, "display": "R"
94 }},
97 def test_sharkd_req_status(self, check_sharkd_session, capture_file):
98 check_sharkd_session((
99 {"jsonrpc":"2.0", "id":1, "method":"load",
100 "params":{"file": capture_file('dhcp.pcap')}
102 {"jsonrpc":"2.0", "id":2, "method":"status"},
103 ), (
104 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
105 {"jsonrpc":"2.0","id":2,"result":{"frames": 4, "duration": 0.070345000,
106 "filename": "dhcp.pcap", "filesize": 1400,
107 "columns":["No.","Time","Source","Destination","Protocol","Length","Info"],
108 "column_info":[{
109 "title":"No.","format": "%m","visible":True, "display": "R"
111 "title": "Time", "format": "%t", "visible":True, "display": "R"
113 "title": "Source", "format": "%s", "visible":True, "display": "R"
115 "title": "Destination", "format": "%d", "visible":True, "display": "R"
117 "title": "Protocol", "format": "%p", "visible":True, "display": "R"
119 "title": "Length", "format": "%L", "visible":True, "display": "R"
121 "title": "Info", "format": "%i", "visible":True, "display": "R"
126 def test_sharkd_req_analyse(self, check_sharkd_session, capture_file):
127 check_sharkd_session((
128 {"jsonrpc":"2.0", "id":1, "method":"load",
129 "params":{"file": capture_file('dhcp.pcap')}
131 {"jsonrpc":"2.0", "id":2, "method":"analyse"},
132 ), (
133 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
134 {"jsonrpc":"2.0","id":2,"result":{"frames": 4, "protocols": ["frame", "eth", "ethertype", "ip", "udp",
135 "dhcp"], "first": 1102274184.317452908, "last": 1102274184.387798071}},
138 def test_sharkd_req_info(self, check_sharkd_session):
139 matchTapNameList = MatchList(
140 {"tap": MatchAny(str), "name": MatchAny(str)})
141 matchNameDescriptionList = MatchList(
142 {"name": MatchAny(str), "description": MatchAny(str)})
143 check_sharkd_session((
144 {"jsonrpc":"2.0", "id":1, "method":"info"},
145 ), (
146 {"jsonrpc":"2.0","id":1,"result":{
147 "version": MatchAny(str),
148 "columns": MatchList({"format": MatchAny(str), "name": MatchAny(str)}),
149 "stats": matchTapNameList,
150 "convs": matchTapNameList,
151 "eo": matchTapNameList,
152 "srt": matchTapNameList,
153 "rtd": matchTapNameList,
154 "seqa": matchTapNameList,
155 "taps": matchTapNameList,
156 "follow": matchTapNameList,
157 "ftypes": MatchList(MatchAny(str)),
158 "capture_types": matchNameDescriptionList,
159 "encap_types": matchNameDescriptionList,
160 "nstat": matchTapNameList,
164 def test_sharkd_req_check(self, check_sharkd_session, capture_file):
165 check_sharkd_session((
166 {"jsonrpc":"2.0", "id":1, "method":"load",
167 "params":{"file": capture_file('dhcp.pcap')}
169 {"jsonrpc":"2.0", "id":2, "method":"check"},
170 {"jsonrpc":"2.0", "id":3, "method":"check", "params":{"filter": "garbage filter"}},
171 {"jsonrpc":"2.0", "id":4, "method":"check", "params":{"field": "garbage field"}},
172 {"jsonrpc":"2.0", "id":5, "method":"check", "params":{"filter": "ip", "field": "ip"}},
173 ), (
174 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
175 {"jsonrpc":"2.0","id":2,"result":{"status":"OK"}},
176 {"jsonrpc":"2.0","id":3,"error":{"code":-5001,"message":"Filter invalid - \"filter\" was unexpected in this context."}},
177 {"jsonrpc":"2.0","id":4,"error":{"code":-5002,"message":"Field garbage field not found"}},
178 {"jsonrpc":"2.0","id":5,"result":{"status":"OK"}},
181 def test_sharkd_req_complete_field(self, check_sharkd_session):
182 check_sharkd_session((
183 {"jsonrpc":"2.0", "id":1, "method":"complete"},
184 {"jsonrpc":"2.0", "id":2, "method":"complete", "params":{"field": "frame.le"}},
185 {"jsonrpc":"2.0", "id":3, "method":"complete", "params":{"field": "garbage.nothing.matches"}},
186 ), (
187 {"jsonrpc":"2.0","id":1,"result":{}},
188 {"jsonrpc":"2.0","id":2,"result":{"field": MatchList(
189 {"f": "frame.len", "t": 7, "n": "Frame Length"}, match_element=any)}
191 {"jsonrpc":"2.0","id":3,"result":{"field": []}},
194 def test_sharkd_req_complete_pref(self, check_sharkd_session):
195 check_sharkd_session((
196 {"jsonrpc":"2.0", "id":1, "method":"complete", "params":{"pref": "tcp."}},
197 {"jsonrpc":"2.0", "id":2, "method":"complete", "params":{"pref": "garbage.nothing.matches"}},
198 ), (
199 {"jsonrpc":"2.0","id":1,"result":{"pref": MatchList(
200 {"f": "tcp.check_checksum", "d": "Validate the TCP checksum if possible"}, match_element=any)}
202 {"jsonrpc":"2.0","id":2,"result":{"pref": []}},
205 def test_sharkd_req_frames(self, check_sharkd_session, capture_file):
206 # XXX need test for optional input parameters, ignored/marked/commented
207 check_sharkd_session((
208 {"jsonrpc":"2.0", "id":1, "method":"load",
209 "params":{"file": capture_file('dhcp.pcap')}
211 {"jsonrpc":"2.0", "id":2, "method":"frames"},
212 ), (
213 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
214 {"jsonrpc":"2.0","id":2,"result":
215 MatchList({
216 "c": MatchList(MatchAny(str)),
217 "num": MatchAny(int),
218 "bg": MatchAny(str),
219 "fg": MatchAny(str),
224 def test_sharkd_req_frames_delta_times(self, check_sharkd_session, capture_file):
225 check_sharkd_session((
226 {"jsonrpc":"2.0", "id":1, "method":"load",
227 "params":{"file": capture_file('logistics_multicast.pcapng')}
229 {"jsonrpc":"2.0", "id":2, "method":"frames","params":{"filter":"frame.number==1||frame.number==800","column0":"frame.time_relative:1","column1":"frame.time_delta:1","column2":"frame.time_delta_displayed:1"}},
230 ), (
231 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
232 {"jsonrpc":"2.0","id":2,"result":
234 {"c":["0.000000000","0.000000000","0.000000000"],"num":1,"bg":"feffd0","fg":"12272e"},
235 {"c":["191.872111000","0.193716000","191.872111000"],"num":800,"bg":"feffd0","fg":"12272e"},
240 def test_sharkd_req_frames_comments(self, check_sharkd_session, capture_file):
241 check_sharkd_session((
242 {"jsonrpc":"2.0", "id":1, "method":"load",
243 "params":{"file": capture_file('comments.pcapng')}
245 {"jsonrpc":"2.0", "id":2, "method":"frames","params":{"filter":"frame.number==3||frame.number==4||frame.number==5"}},
246 ), (
247 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
248 {"jsonrpc":"2.0","id":2,"result":
250 {"c":["3","0.610021","::","ff02::1:ffdc:6277","ICMPv6","78","Neighbor Solicitation for fe80::c2c1:c0ff:fedc:6277"],"num":3,"ct":True,"comments":["hello hello"],"bg":"fce0ff","fg":"12272e"},
251 {"c":["4","0.760023","::","ff02::1:ffdc:6277","ICMPv6","78","Neighbor Solicitation for fec0::c2c1:c0ff:fedc:6277"],"num":4,"ct":True,"comments":["goodbye goodbye"],"bg":"fce0ff","fg":"12272e"},
252 {"c":["5","0.802338","10.0.0.1","224.0.0.251","MDNS","138","Standard query response 0x0000 A, cache flush 10.0.0.1 PTR, cache flush Cisco29401.local NSEC, cache flush Cisco29401.local"],"num":5,"bg":"daeeff","fg":"12272e"}
257 def test_sharkd_req_tap_invalid(self, check_sharkd_session, capture_file):
258 # XXX Unrecognized taps result in an empty line, modify
259 # run_sharkd_session such that checking for it is possible.
260 check_sharkd_session((
261 {"jsonrpc":"2.0", "id":1, "method":"load",
262 "params":{"file": capture_file('dhcp.pcap')}
264 {"jsonrpc":"2.0", "id":2, "method":"tap"},
265 {"jsonrpc":"2.0", "id":3, "method":"tap", "params":{"tap0": "garbage tap"}},
266 {"jsonrpc":"2.0", "id":4, "method":"tap", "params":{"tap0": "conv:Ethernet", "filter": "garbage filter"}},
267 ), (
268 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
269 {"jsonrpc":"2.0","id":2,"error":{"code":-32600,"message":"Mandatory parameter tap0 is missing"}},
270 {"jsonrpc":"2.0","id":3,"error":{"code":-11012,"message":"sharkd_session_process_tap() garbage tap not recognized"}},
271 {"jsonrpc":"2.0","id":4,"error":{"code":-11013,"message":"sharkd_session_process_tap() name=conv:Ethernet error=Filter \"garbage filter\" is invalid - \"filter\" was unexpected in this context."}},
274 def test_sharkd_req_tap(self, check_sharkd_session, capture_file):
275 check_sharkd_session((
276 {"jsonrpc":"2.0", "id":1, "method":"load",
277 "params":{"file": capture_file('dhcp.pcap')}
279 {"jsonrpc":"2.0", "id":2, "method":"tap"},
280 {"jsonrpc":"2.0", "id":3, "method":"tap", "params":{"tap0": "conv:Ethernet", "tap1": "endpt:TCP"}},
281 ), (
282 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
283 {"jsonrpc":"2.0","id":2,"error":{"code":-32600,"message":"Mandatory parameter tap0 is missing"}},
284 {"jsonrpc":"2.0","id":3,"result":{
285 "taps": [
287 "tap": "endpt:TCP",
288 "type": "host",
289 "proto": "TCP",
290 "geoip": MatchAny(bool),
291 "hosts": [],
294 "tap": "conv:Ethernet",
295 "type": "conv",
296 "proto": "Ethernet",
297 "geoip": MatchAny(bool),
298 "convs": [
300 "saddr": MatchAny(str),
301 "daddr": "Broadcast",
302 "txf": 2,
303 "txb": 628,
304 "rxf": 0,
305 "rxb": 0,
306 "start": 0,
307 "stop": 0.070031,
308 "filter": "eth.addr==00:0b:82:01:fc:42 && eth.addr==ff:ff:ff:ff:ff:ff",
311 "saddr": MatchAny(str),
312 "daddr": MatchAny(str),
313 "rxf": 0,
314 "rxb": 0,
315 "txf": 2,
316 "txb": 684,
317 "start": 0.000295,
318 "stop": 0.070345,
319 "filter": "eth.addr==00:08:74:ad:f1:9b && eth.addr==00:0b:82:01:fc:42",
327 def test_sharkd_req_tap_rtp_streams(self, check_sharkd_session, capture_file):
328 check_sharkd_session((
329 {"jsonrpc":"2.0", "id":1, "method":"load",
330 "params":{"file": capture_file('sip-rtp.pcapng')}
332 {"jsonrpc":"2.0", "id":2, "method":"tap", "params":{"tap0": "rtp-streams"}},
333 {"jsonrpc":"2.0", "id":2, "method":"tap", "params":{"tap0": "rtp-analyse:200.57.7.204_8000_200.57.7.196_40376_0xd2bd4e3e"}},
334 ), (
335 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
336 {"jsonrpc":"2.0","id":2,"result":{
337 "taps":[{
338 "tap":"rtp-streams",
339 "type":"rtp-streams",
340 "streams":[{
341 "ssrc":"0xd2bd4e3e",
342 "payload":"g711A",
343 "saddr":"200.57.7.204",
344 "sport":8000,
345 "daddr":"200.57.7.196",
346 "dport":40376,
347 "start_time":8.479371,
348 "duration": 24.124055,
349 "pkts":548,
350 "lost":0,
351 "lost_percent":0.0,
352 "max_delta":5843.742000,
353 "min_delta":0.159,
354 "mean_delta":44.102477,
355 "min_jitter":0.388213,
356 "max_jitter":7.406751,
357 "mean_jitter":2.517173,
358 "expectednr":548,
359 "totalnr":548,
360 "problem":False,
361 "ipver":4
365 {"jsonrpc":"2.0","id":2,"result":
366 {"taps":[{
367 "tap":"rtp-analyse:200.57.7.204_8000_200.57.7.196_40376_0xd2bd4e3e",
368 "type":"rtp-analyse",
369 "ssrc":"0xd2bd4e3e",
370 "max_delta":5843.742000,
371 "max_delta_nr":168,
372 "max_jitter":7.406751,
373 "mean_jitter":2.517173,
374 "max_skew":319.289000,
375 "total_nr":548,
376 "seq_err":0,
377 "duration":24124.055000,
378 "items": MatchAny()
383 def test_sharkd_req_tap_phs(self, check_sharkd_session, capture_file):
384 check_sharkd_session((
385 {"jsonrpc":"2.0", "id":1, "method":"load",
386 "params":{"file": capture_file('protohier-with-comments.pcapng')}
388 {"jsonrpc":"2.0", "id":2, "method":"tap", "params":{"tap0": "phs"}},
389 {"jsonrpc":"2.0", "id":3, "method":"load",
390 "params":{"file": capture_file('protohier-without-comments.pcapng')}
392 {"jsonrpc":"2.0", "id":4, "method":"tap", "params":{"tap0": "phs"}},
393 {"jsonrpc":"2.0", "id":5, "method":"tap", "params":{"tap0": "phs", "filter": "ipv6"}},
394 ), (
395 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
396 {"jsonrpc":"2.0","id":2,"result":{
397 "taps":[{
398 "tap":"phs",
399 "type":"phs",
400 "filter":"",
401 "protos":[{
402 "proto":"frame",
403 "frames":115,
404 "bytes":22186,
405 "protos":[{
406 "proto":"eth",
407 "frames":115,
408 "bytes":22186,
409 "protos":[{
410 "proto":"ipv6",
411 "frames":39,
412 "bytes":7566,
413 "protos":[{
414 "proto":"icmpv6",
415 "frames":36,
416 "bytes":3684
418 "proto":"udp",
419 "frames":3,
420 "bytes":3882,
421 "protos":[{
422 "proto":"data",
423 "frames":3,
424 "bytes":3882
428 "proto":"ip",
429 "frames":70,
430 "bytes":14260,
431 "protos":[{
432 "proto":"udp",
433 "frames":60,
434 "bytes":13658,
435 "protos":[{
436 "proto":"mdns",
437 "frames":1,
438 "bytes":138
440 "proto":"ssdp",
441 "frames":30,
442 "bytes":8828
444 "proto":"nbns",
445 "frames":20,
446 "bytes":2200
448 "proto":"nbdgm",
449 "frames":1,
450 "bytes":248,
451 "protos":[{
452 "proto":"smb",
453 "frames":1,
454 "bytes":248,
455 "protos":[{
456 "proto":"mailslot",
457 "frames":1,
458 "bytes":248,
459 "protos":[{
460 "proto":"browser",
461 "frames":1,
462 "bytes":248
466 },{"proto":"dhcp",
467 "frames":4,
468 "bytes":1864
470 "proto":"dns",
471 "frames":4,
472 "bytes":380
475 "proto":"igmp",
476 "frames":10,
477 "bytes":602
480 "proto":"arp",
481 "frames":6,
482 "bytes":360
488 {"jsonrpc":"2.0","id":3,"result":{"status":"OK"}},
489 {"jsonrpc":"2.0","id":4,"result":{
490 "taps":[{
491 "tap":"phs",
492 "type":"phs",
493 "filter":"",
494 "protos":[{
495 "proto":"frame",
496 "frames":115,
497 "bytes":22186,
498 "protos":[{
499 "proto":"eth",
500 "frames":115,
501 "bytes":22186,
502 "protos":[{
503 "proto":"ipv6",
504 "frames":39,
505 "bytes":7566,
506 "protos":[{
507 "proto":"icmpv6",
508 "frames":36,
509 "bytes":3684
511 "proto":"udp",
512 "frames":3,
513 "bytes":3882,
514 "protos":[{
515 "proto":"data",
516 "frames":3,
517 "bytes":3882
521 "proto":"ip",
522 "frames":70,
523 "bytes":14260,
524 "protos":[{
525 "proto":"udp",
526 "frames":60,
527 "bytes":13658,
528 "protos":[{
529 "proto":"mdns",
530 "frames":1,
531 "bytes":138
533 "proto":"ssdp",
534 "frames":30,
535 "bytes":8828
537 "proto":"nbns",
538 "frames":20,
539 "bytes":2200
541 "proto":"nbdgm",
542 "frames":1,
543 "bytes":248,
544 "protos":[{
545 "proto":"smb",
546 "frames":1,
547 "bytes":248,
548 "protos":[{
549 "proto":"mailslot",
550 "frames":1,
551 "bytes":248,
552 "protos":[{
553 "proto":"browser",
554 "frames":1,
555 "bytes":248
559 },{"proto":"dhcp",
560 "frames":4,
561 "bytes":1864
563 "proto":"dns",
564 "frames":4,
565 "bytes":380
568 "proto":"igmp",
569 "frames":10,
570 "bytes":602
573 "proto":"arp",
574 "frames":6,
575 "bytes":360
581 {"jsonrpc": "2.0", "id": 5, "result": {
582 "taps": [{
583 "tap": "phs",
584 "type": "phs",
585 "filter": "ipv6",
586 "protos": [{
587 "bytes": 7566,
588 "frames": 39,
589 "proto": "frame",
590 "protos": [{
591 "bytes": 7566,
592 "frames": 39,
593 "proto": "eth",
594 "protos": [{
595 "bytes": 7566,
596 "frames": 39,
597 "proto": "ipv6",
598 "protos": [{
599 "bytes": 3684,
600 "frames": 36,
601 "proto": "icmpv6"
603 "bytes": 3882,
604 "frames": 3,
605 "proto": "udp",
606 "protos": [{
607 "bytes": 3882,
608 "frames": 3,
609 "proto": "data"
619 def test_sharkd_req_tap_voip_calls(self, check_sharkd_session, capture_file):
620 check_sharkd_session((
621 {"jsonrpc":"2.0", "id":1, "method":"load",
622 "params":{"file": capture_file('sip-rtp.pcapng')}
624 {"jsonrpc":"2.0", "id":2, "method":"tap", "params":{"tap0": "voip-calls"}},
625 ), (
626 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
627 {"jsonrpc":"2.0","id":2,"result":{
628 "taps":[{
629 "tap":"voip-calls",
630 "type":"voip-calls",
631 "calls":[{
632 "call":0,
633 "start_time":0.000000,
634 "stop_time":8.524137,
635 "initial_speaker":"200.57.7.195",
636 "from":"<sip:200.57.7.195:55061;user=phone>",
637 "to":"\"francisco@bestel.com\" <sip:francisco@bestel.com:55060>",
638 "protocol":"SIP",
639 "packets":5,
640 "state":"IN CALL",
641 "comment":"INVITE 200"
643 "call":1,
644 "start_time":24.665953,
645 "stop_time":24.692752,
646 "initial_speaker":"200.57.7.195",
647 "from":"\"Ivan Alizade\" <sip:5514540002@200.57.7.195:55061;user=phone>",
648 "to":"\"francisco@bestel.com\" <sip:francisco@bestel.com:55060>",
649 "protocol":"SIP",
650 "packets":3,
651 "state":"CALL SETUP",
652 "comment":"INVITE"
658 def test_sharkd_req_tap_voip_convs(self, check_sharkd_session, capture_file):
659 check_sharkd_session((
660 {"jsonrpc":"2.0", "id":1, "method":"load",
661 "params":{"file": capture_file('sip-rtp.pcapng')}
663 {"jsonrpc":"2.0", "id":2, "method":"tap", "params":{"tap0": "voip-convs:"}},
664 {"jsonrpc":"2.0", "id":3, "method":"tap", "params":{"tap0": "voip-convs:0"}},
665 {"jsonrpc":"2.0", "id":4, "method":"tap", "params":{"tap0": "voip-convs:0-1"}},
666 {"jsonrpc":"2.0", "id":5, "method":"tap", "params":{"tap0": "voip-convs:garbage"}},
667 {"jsonrpc":"2.0", "id":6, "method":"tap", "params":{"tap0": "voip-convs:999"}},
668 {"jsonrpc":"2.0", "id":7, "method":"tap", "params":{"tap0": "voip-convs:0,999,0-1,999-999,1,1"}},
669 ), (
670 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
671 {"jsonrpc":"2.0","id":2,"result":{
672 "taps":[{
673 "tap":"voip-convs:",
674 "type":"voip-convs",
675 "convs":[{
676 "frame":1,
677 "call":0,
678 "time":"0.000000",
679 "dst_addr":"200.57.7.204",
680 "dst_port":5061,
681 "src_addr":"200.57.7.195",
682 "src_port":5060,
683 "label":"INVITE SDP (g711A g729 g723 g711U)",
684 "comment":"SIP INVITE From: <sip:200.57.7.195:55061;user=phone> To:\"francisco@bestel.com\" <sip:francisco@bestel.com:55060> Call-ID:12013223@200.57.7.195 CSeq:1"
686 "frame":2,
687 "call":0,
688 "time":"0.007889",
689 "dst_addr":"200.57.7.195",
690 "dst_port":5060,
691 "src_addr":"200.57.7.204",
692 "src_port":5061,
693 "label":"100 Trying",
694 "comment":"SIP Status 100 Trying"
696 "frame":3,
697 "call":0,
698 "time":"0.047524",
699 "dst_addr":"200.57.7.195",
700 "dst_port":5060,
701 "src_addr":"200.57.7.204",
702 "src_port":5061,
703 "label":"180 Ringing",
704 "comment":"SIP Status 180 Ringing"
706 "frame":6,
707 "call":0,
708 "time":"8.477925",
709 "dst_addr":"200.57.7.195",
710 "dst_port":5060,
711 "src_addr":"200.57.7.204",
712 "src_port":5061,
713 "label":"200 Ok SDP (g711A g711U GSM iLBC speex telephone-event)",
714 "comment":"SIP Status 200 Ok"
716 "frame":7,
717 "call":0,
718 "time":"8.479371",
719 "dst_addr":"200.57.7.196",
720 "dst_port":40376,
721 "src_addr":"200.57.7.204",
722 "src_port":8000,
723 "label":"RTP (g711A) ",
724 "comment":"RTP, 548 packets. Duration: 24.12s SSRC: 0xD2BD4E3E"
726 "frame":10,
727 "call":0,
728 "time":"8.524137",
729 "dst_addr":"200.57.7.204",
730 "dst_port":5061,
731 "src_addr":"200.57.7.195",
732 "src_port":5060,
733 "label":"ACK",
734 "comment":"SIP Request INVITE ACK 200 CSeq:1"
736 "frame":352,
737 "call":1,
738 "time":"24.665953",
739 "dst_addr":"200.57.7.204",
740 "dst_port":5061,
741 "src_addr":"200.57.7.195",
742 "src_port":5060,
743 "label":"INVITE SDP (g711A g729 g723)",
744 "comment":"SIP INVITE From: \"Ivan Alizade\" <sip:5514540002@200.57.7.195:55061;user=phone> To:\"francisco@bestel.com\" <sip:francisco@bestel.com:55060> Call-ID:12015624@200.57.7.195 CSeq:1"
746 "frame":353,
747 "call":1,
748 "time":"24.674680",
749 "dst_addr":"200.57.7.195",
750 "dst_port":5060,
751 "src_addr":"200.57.7.204",
752 "src_port":5061,
753 "label":"100 Trying",
754 "comment":"SIP Status 100 Trying"
756 "frame":354,
757 "call":1,
758 "time":"24.692752",
759 "dst_addr":"200.57.7.195",
760 "dst_port":5060,
761 "src_addr":"200.57.7.204",
762 "src_port":5061,
763 "label":"180 Ringing",
764 "comment":"SIP Status 180 Ringing"
768 {"jsonrpc":"2.0","id":3,"result":{
769 "taps":[{
770 "tap":"voip-convs:0",
771 "type":"voip-convs",
772 "convs":[{
773 "frame":1,
774 "call":0,
775 "time":"0.000000",
776 "dst_addr":"200.57.7.204",
777 "dst_port":5061,
778 "src_addr":"200.57.7.195",
779 "src_port":5060,
780 "label":"INVITE SDP (g711A g729 g723 g711U)",
781 "comment":"SIP INVITE From: <sip:200.57.7.195:55061;user=phone> To:\"francisco@bestel.com\" <sip:francisco@bestel.com:55060> Call-ID:12013223@200.57.7.195 CSeq:1"
783 "frame":2,
784 "call":0,
785 "time":"0.007889",
786 "dst_addr":"200.57.7.195",
787 "dst_port":5060,
788 "src_addr":"200.57.7.204",
789 "src_port":5061,
790 "label":"100 Trying",
791 "comment":"SIP Status 100 Trying"
793 "frame":3,
794 "call":0,
795 "time":"0.047524",
796 "dst_addr":"200.57.7.195",
797 "dst_port":5060,
798 "src_addr":"200.57.7.204",
799 "src_port":5061,
800 "label":"180 Ringing",
801 "comment":"SIP Status 180 Ringing"
803 "frame":6,
804 "call":0,
805 "time":"8.477925",
806 "dst_addr":"200.57.7.195",
807 "dst_port":5060,
808 "src_addr":"200.57.7.204",
809 "src_port":5061,
810 "label":"200 Ok SDP (g711A g711U GSM iLBC speex telephone-event)",
811 "comment":"SIP Status 200 Ok"
813 "frame":7,
814 "call":0,
815 "time":"8.479371",
816 "dst_addr":"200.57.7.196",
817 "dst_port":40376,
818 "src_addr":"200.57.7.204",
819 "src_port":8000,
820 "label":"RTP (g711A) ",
821 "comment":"RTP, 548 packets. Duration: 24.12s SSRC: 0xD2BD4E3E"
823 "frame":10,
824 "call":0,
825 "time":"8.524137",
826 "dst_addr":"200.57.7.204",
827 "dst_port":5061,
828 "src_addr":"200.57.7.195",
829 "src_port":5060,"label":"ACK","comment":"SIP Request INVITE ACK 200 CSeq:1"
833 {"jsonrpc":"2.0","id":4,"result":{
834 "taps":[{
835 "tap":"voip-convs:0-1",
836 "type":"voip-convs",
837 "convs":[{
838 "frame":1,
839 "call":0,
840 "time":"0.000000",
841 "dst_addr":"200.57.7.204",
842 "dst_port":5061,
843 "src_addr":"200.57.7.195",
844 "src_port":5060,
845 "label":"INVITE SDP (g711A g729 g723 g711U)",
846 "comment":"SIP INVITE From: <sip:200.57.7.195:55061;user=phone> To:\"francisco@bestel.com\" <sip:francisco@bestel.com:55060> Call-ID:12013223@200.57.7.195 CSeq:1"
848 "frame":2,
849 "call":0,
850 "time":"0.007889",
851 "dst_addr":"200.57.7.195",
852 "dst_port":5060,
853 "src_addr":"200.57.7.204",
854 "src_port":5061,
855 "label":"100 Trying",
856 "comment":"SIP Status 100 Trying"
858 "frame":3,
859 "call":0,
860 "time":"0.047524",
861 "dst_addr":"200.57.7.195",
862 "dst_port":5060,
863 "src_addr":"200.57.7.204",
864 "src_port":5061,
865 "label":"180 Ringing",
866 "comment":"SIP Status 180 Ringing"
868 "frame":6,
869 "call":0,
870 "time":"8.477925",
871 "dst_addr":"200.57.7.195",
872 "dst_port":5060,
873 "src_addr":"200.57.7.204",
874 "src_port":5061,
875 "label":"200 Ok SDP (g711A g711U GSM iLBC speex telephone-event)",
876 "comment":"SIP Status 200 Ok"
878 "frame":7,
879 "call":0,
880 "time":"8.479371",
881 "dst_addr":"200.57.7.196",
882 "dst_port":40376,
883 "src_addr":"200.57.7.204",
884 "src_port":8000,
885 "label":"RTP (g711A) ",
886 "comment":"RTP, 548 packets. Duration: 24.12s SSRC: 0xD2BD4E3E"
888 "frame":10,
889 "call":0,
890 "time":"8.524137",
891 "dst_addr":"200.57.7.204",
892 "dst_port":5061,
893 "src_addr":"200.57.7.195",
894 "src_port":5060,
895 "label":"ACK",
896 "comment":"SIP Request INVITE ACK 200 CSeq:1"
898 "frame":352,
899 "call":1,
900 "time":"24.665953",
901 "dst_addr":"200.57.7.204",
902 "dst_port":5061,
903 "src_addr":"200.57.7.195",
904 "src_port":5060,
905 "label":"INVITE SDP (g711A g729 g723)",
906 "comment":"SIP INVITE From: \"Ivan Alizade\" <sip:5514540002@200.57.7.195:55061;user=phone> To:\"francisco@bestel.com\" <sip:francisco@bestel.com:55060> Call-ID:12015624@200.57.7.195 CSeq:1"
908 "frame":353,
909 "call":1,
910 "time":"24.674680",
911 "dst_addr":"200.57.7.195",
912 "dst_port":5060,
913 "src_addr":"200.57.7.204",
914 "src_port":5061,
915 "label":"100 Trying",
916 "comment":"SIP Status 100 Trying"
918 "frame":354,
919 "call":1,
920 "time":"24.692752",
921 "dst_addr":"200.57.7.195",
922 "dst_port":5060,
923 "src_addr":"200.57.7.204",
924 "src_port":5061,
925 "label":"180 Ringing",
926 "comment":"SIP Status 180 Ringing"
930 {"jsonrpc":"2.0","id":5,"error":{
931 "code":-11014,"message":"sharkd_session_process_tap() voip-convs=voip-convs:garbage invalid 'convs' parameter"
933 {"jsonrpc":"2.0","id":6,"result":{
934 "taps":[{
935 "tap":"voip-convs:999",
936 "type":"voip-convs",
937 "convs":[]
940 {"jsonrpc":"2.0","id":7,"result":{
941 "taps":[{
942 "tap":"voip-convs:0,999,0-1,999-999,1,1",
943 "type":"voip-convs",
944 "convs":[{
945 "frame":1,
946 "call":0,
947 "time":"0.000000",
948 "dst_addr":"200.57.7.204",
949 "dst_port":5061,
950 "src_addr":"200.57.7.195",
951 "src_port":5060,
952 "label":"INVITE SDP (g711A g729 g723 g711U)",
953 "comment":"SIP INVITE From: <sip:200.57.7.195:55061;user=phone> To:\"francisco@bestel.com\" <sip:francisco@bestel.com:55060> Call-ID:12013223@200.57.7.195 CSeq:1"
955 "frame":2,
956 "call":0,
957 "time":"0.007889",
958 "dst_addr":"200.57.7.195",
959 "dst_port":5060,
960 "src_addr":"200.57.7.204",
961 "src_port":5061,
962 "label":"100 Trying",
963 "comment":"SIP Status 100 Trying"
965 "frame":3,
966 "call":0,
967 "time":"0.047524",
968 "dst_addr":"200.57.7.195",
969 "dst_port":5060,
970 "src_addr":"200.57.7.204",
971 "src_port":5061,
972 "label":"180 Ringing",
973 "comment":"SIP Status 180 Ringing"
975 "frame":6,
976 "call":0,
977 "time":"8.477925",
978 "dst_addr":"200.57.7.195",
979 "dst_port":5060,
980 "src_addr":"200.57.7.204",
981 "src_port":5061,
982 "label":"200 Ok SDP (g711A g711U GSM iLBC speex telephone-event)",
983 "comment":"SIP Status 200 Ok"
985 "frame":7,
986 "call":0,
987 "time":"8.479371",
988 "dst_addr":"200.57.7.196",
989 "dst_port":40376,
990 "src_addr":"200.57.7.204",
991 "src_port":8000,
992 "label":"RTP (g711A) ",
993 "comment":"RTP, 548 packets. Duration: 24.12s SSRC: 0xD2BD4E3E"
995 "frame":10,
996 "call":0,
997 "time":"8.524137",
998 "dst_addr":"200.57.7.204",
999 "dst_port":5061,
1000 "src_addr":"200.57.7.195",
1001 "src_port":5060,
1002 "label":"ACK",
1003 "comment":"SIP Request INVITE ACK 200 CSeq:1"
1005 "frame":352,
1006 "call":1,
1007 "time":"24.665953",
1008 "dst_addr":"200.57.7.204",
1009 "dst_port":5061,
1010 "src_addr":"200.57.7.195",
1011 "src_port":5060,
1012 "label":"INVITE SDP (g711A g729 g723)",
1013 "comment":"SIP INVITE From: \"Ivan Alizade\" <sip:5514540002@200.57.7.195:55061;user=phone> To:\"francisco@bestel.com\" <sip:francisco@bestel.com:55060> Call-ID:12015624@200.57.7.195 CSeq:1"
1015 "frame":353,
1016 "call":1,
1017 "time":"24.674680",
1018 "dst_addr":"200.57.7.195",
1019 "dst_port":5060,
1020 "src_addr":"200.57.7.204",
1021 "src_port":5061,
1022 "label":"100 Trying",
1023 "comment":"SIP Status 100 Trying"
1025 "frame":354,
1026 "call":1,
1027 "time":"24.692752",
1028 "dst_addr":"200.57.7.195",
1029 "dst_port":5060,
1030 "src_addr":"200.57.7.204",
1031 "src_port":5061,
1032 "label":"180 Ringing",
1033 "comment":"SIP Status 180 Ringing"
1039 def test_sharkd_req_tap_hosts(self, check_sharkd_session, capture_file):
1040 matchAddrNameList = MatchList(
1041 {"name": MatchAny(str), "addr": MatchAny(str)})
1042 check_sharkd_session((
1043 {"jsonrpc":"2.0", "id":1, "method":"load",
1044 "params":{"file": capture_file('dns-mdns.pcap')}
1046 {"jsonrpc":"2.0", "id":2, "method":"tap", "params":{"tap0": "hosts:"}},
1047 {"jsonrpc":"2.0", "id":3, "method":"tap", "params":{"tap0": "hosts:ip"}},
1048 {"jsonrpc":"2.0", "id":4, "method":"tap", "params":{"tap0": "hosts:ipv4"}},
1049 {"jsonrpc":"2.0", "id":5, "method":"tap", "params":{"tap0": "hosts:ipv6"}},
1050 {"jsonrpc":"2.0", "id":6, "method":"tap", "params":{"tap0": "hosts:invalid"}},
1051 {"jsonrpc":"2.0", "id":7, "method":"tap", "params":{"tap0": "hosts:ipv4,ipv6"}},
1052 {"jsonrpc":"2.0", "id":8, "method":"tap", "params":{"tap0": "hosts:ipv4,ipv6,invalid"}},
1053 ), (
1054 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1055 {"jsonrpc":"2.0","id":2,"result":{
1056 "taps":[{
1057 "tap":"hosts:",
1058 "type":"hosts",
1059 "ipv4_hosts":matchAddrNameList,
1060 "ipv6_hosts":matchAddrNameList,
1063 {"jsonrpc":"2.0","id":3,"result":{
1064 "taps":[{
1065 "tap":"hosts:ip",
1066 "type":"hosts",
1067 "ipv4_hosts":matchAddrNameList,
1070 {"jsonrpc":"2.0","id":4,"result":{
1071 "taps":[{
1072 "tap":"hosts:ipv4",
1073 "type":"hosts",
1074 "ipv4_hosts":matchAddrNameList,
1077 {"jsonrpc":"2.0","id":5,"result":{
1078 "taps":[{
1079 "tap":"hosts:ipv6",
1080 "type":"hosts",
1081 "ipv6_hosts":matchAddrNameList,
1084 {"jsonrpc":"2.0","id":6,"error":{"code":-11015,"message":"sharkd_session_process_tap() hosts=hosts:invalid invalid 'protos' parameter"}},
1085 {"jsonrpc":"2.0","id":7,"result":{
1086 "taps":[{
1087 "tap":"hosts:ipv4,ipv6",
1088 "type":"hosts",
1089 "ipv4_hosts":matchAddrNameList,
1090 "ipv6_hosts":matchAddrNameList,
1093 {"jsonrpc":"2.0","id":8,"error":{"code":-11015,"message":"sharkd_session_process_tap() hosts=hosts:ipv4,ipv6,invalid invalid 'protos' parameter"}},
1096 def test_sharkd_req_tap_eo_http(self, check_sharkd_session, capture_file):
1097 check_sharkd_session((
1098 {"jsonrpc":"2.0", "id":1, "method":"load",
1099 "params":{"file": capture_file('http-ooo.pcap')}
1101 {"jsonrpc":"2.0", "id":2, "method":"tap", "params":{"tap0": "eo:http"}},
1102 ), (
1103 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1104 {"jsonrpc":"2.0","id":2,"result":{
1105 "taps":[{
1106 "tap":"eo:http",
1107 "type":"eo",
1108 "proto":"HTTP",
1109 "objects":[{
1110 "pkt":11,
1111 "filename":"4",
1112 "_download":"eo:http_0",
1113 "len":5,
1114 "sha1":"4a4121ecd766ed16943a0c7b54c18f743e90c3f6"
1116 "pkt":13,
1117 "_download":"eo:http_1",
1118 "len":5,
1119 "sha1":"29a51e7382d06ff40467272f02e413ca7b51636e"
1121 "pkt":14,
1122 "_download":"eo:http_2",
1123 "len":5,
1124 "sha1":"f6d0c643351580307b2eaa6a7560e76965496bc7"}]
1129 def test_sharkd_req_follow_bad(self, check_sharkd_session, capture_file):
1130 # Unrecognized taps currently produce no output (not even err).
1131 check_sharkd_session((
1132 {"jsonrpc":"2.0", "id":1, "method":"load",
1133 "params":{"file": capture_file('dhcp.pcap')}
1135 {"jsonrpc":"2.0", "id":2, "method":"follow"},
1136 {"jsonrpc":"2.0", "id":3, "method":"follow",
1137 "params":{"follow": "garbage follow", "filter": "ip"}
1139 {"jsonrpc":"2.0", "id":4, "method":"follow",
1140 "params":{"follow": "HTTP", "filter": "garbage filter"}
1142 {"jsonrpc":"2.0", "id":5, "method":"follow",
1143 "params":{"follow": "HTTP", "filter": "http", "sub_stream": "garbage sub_stream"}
1145 ), (
1146 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1147 {"jsonrpc":"2.0","id":2,"error":{"code":-32600,"message":"Mandatory parameter follow is missing"}},
1148 {"jsonrpc":"2.0","id":3,"error":{"code":-12001,"message":"sharkd_session_process_follow() follower=garbage follow not found"}},
1149 {"jsonrpc":"2.0","id":4,
1150 "error":{"code":-12002,"message":"sharkd_session_process_follow() name=HTTP error=Filter \"garbage filter\" is invalid - \"filter\" was unexpected in this context."}
1152 {"jsonrpc":"2.0","id":5,
1153 "error":{"code":-32600,"message":"The data type for member sub_stream is not valid"}
1157 def test_sharkd_req_follow_no_match(self, check_sharkd_session, capture_file):
1158 check_sharkd_session((
1159 {"jsonrpc":"2.0", "id":1, "method":"load",
1160 "params":{"file": capture_file('dhcp.pcap')}
1162 {"jsonrpc":"2.0", "id":2, "method":"follow",
1163 "params":{"follow": "HTTP", "filter": "ip"}
1165 ), (
1166 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1167 {"jsonrpc":"2.0","id":2,
1168 "result":{"shost": "NONE", "sport": "0", "sbytes": 0,
1169 "chost": "NONE", "cport": "0", "cbytes": 0}
1173 def test_sharkd_req_follow_udp(self, check_sharkd_session, capture_file):
1174 check_sharkd_session((
1175 {"jsonrpc":"2.0", "id":1, "method":"load",
1176 "params":{"file": capture_file('dhcp.pcap')}
1178 {"jsonrpc":"2.0", "id":2, "method":"follow",
1179 "params":{"follow": "UDP", "filter": "frame.number==1"}
1181 ), (
1182 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1183 {"jsonrpc":"2.0","id":2,
1184 "result":{
1185 "shost": "255.255.255.255", "sport": "67", "sbytes": 272,
1186 "chost": "0.0.0.0", "cport": "68", "cbytes": 0,
1187 "payloads": [
1188 {"n": 1, "d": MatchRegExp(r'AQEGAAAAPR0A[a-zA-Z0-9]{330}AANwQBAwYq/wAAAAAAAAA=')}]}
1192 def test_sharkd_req_follow_http2(self, check_sharkd_session, capture_file, features):
1193 # If we don't have nghttp2, we output the compressed headers.
1194 # We could test against the expected output in that case, but
1195 # just skip for now.
1196 if not features.have_nghttp2:
1197 pytest.skip('Requires nghttp2.')
1199 check_sharkd_session((
1200 {"jsonrpc":"2.0", "id":1, "method":"load",
1201 "params":{"file": capture_file('quic-with-secrets.pcapng')}
1203 {"jsonrpc":"2.0", "id":2, "method":"follow",
1204 "params":{"follow": "HTTP2", "filter": "tcp.stream eq 0 and http2.streamid eq 1", "sub_stream": 1}
1206 ), (
1207 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1208 {"jsonrpc":"2.0","id":2,
1209 "result":{
1210 "shost": "2606:4700:10::6816:826", "sport": "443", "sbytes": 656,
1211 "chost": "2001:db8:1::1", "cport": "57098", "cbytes": 109643,
1212 "payloads": [
1213 {"n": 12, "d": MatchRegExp(r'^.*VuLVVTLGVuO3E9MC45Cgo.*$')},
1214 {"n": 19, "s": 1, "d": MatchRegExp(r'^.*7IG1hPTg2NDAwCgo.*$')},
1215 {"n": 44, "s": 1, "d": MatchRegExp(r'^.*Pgo8L2h0bWw.*$')},
1220 def test_sharkd_req_iograph_bad(self, check_sharkd_session, capture_file):
1221 check_sharkd_session((
1222 {"jsonrpc":"2.0", "id":1, "method":"load",
1223 "params":{"file": capture_file('dhcp.pcap')}
1225 {"jsonrpc":"2.0", "id":2, "method":"iograph"},
1226 {"jsonrpc":"2.0", "id":3, "method":"iograph",
1227 "params":{"graph0": "garbage graph name"}
1229 {"jsonrpc":"2.0", "id":4, "method":"iograph",
1230 "params":{"graph0": "max:udp.length", "filter0": "udp.length", "interval": 0}},
1231 {"jsonrpc":"2.0", "id":5, "method":"iograph",
1232 "params":{"graph0": "max:udp.length", "filter0": "udp.length", "interval_units": "garbage units"}},
1233 ), (
1234 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1235 {"jsonrpc":"2.0","id":2,"error":{"code":-32600,"message":"Mandatory parameter graph0 is missing"}},
1236 {"jsonrpc":"2.0","id":3,"result":{"iograph": []}},
1237 {"jsonrpc":"2.0","id":4,"error":{"code":-32600,"message":"The value for interval must be a positive integer"}},
1238 {"jsonrpc":"2.0","id":5,"error":{"code":-7003,"message":"Invalid interval_units parameter: 'garbage units', must be 's', 'ms' or 'us'"}},
1241 def test_sharkd_req_iograph_basic(self, check_sharkd_session, capture_file):
1242 check_sharkd_session((
1243 {"jsonrpc":"2.0", "id":1, "method":"load",
1244 "params":{"file": capture_file('dhcp.pcap')}
1246 {"jsonrpc":"2.0", "id":2, "method":"iograph",
1247 "params":{"graph0": "max:udp.length", "filter0": "udp.length"}
1249 {"jsonrpc":"2.0", "id":3, "method":"iograph",
1250 "params":{"graph0": "packets", "graph1": "bytes"}
1252 {"jsonrpc":"2.0", "id":4, "method":"iograph",
1253 "params":{"graph0": "packets", "filter0": "garbage filter"}
1255 {"jsonrpc":"2.0", "id":5, "method":"iograph",
1256 "params":{"graph0": "packets", "graph1": "bytes", "interval": 1, "interval_units": "us"}
1258 {"jsonrpc":"2.0", "id":6, "method":"iograph",
1259 "params":{"graph0": "packets", "graph1": "bytes", "interval": 1, "interval_units": "ms"}
1261 {"jsonrpc":"2.0", "id":7, "method":"iograph",
1262 "params":{"graph0": "packets", "graph1": "bytes", "interval": 1, "interval_units": "s"}
1264 ), (
1265 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1266 {"jsonrpc":"2.0","id":2,"result":{"iograph": [{"items": [308.000000]}]}},
1267 {"jsonrpc":"2.0","id":3,"result":{"iograph": [{"items": [4.000000]}, {"items": [1312.000000]}]}},
1268 {"jsonrpc":"2.0","id":4,"error":{"code":-6001,"message":"Filter \"garbage filter\" is invalid - \"filter\" was unexpected in this context."}},
1269 {"jsonrpc":"2.0","id":5,"result":{"iograph": [
1270 {"items": [1.0, '127', 1.0, '1118f', 1.0, '112c9', 1.0]},
1271 {"items": [314.0, '127', 342.0, '1118f', 314.0, '112c9', 342.0]},
1272 ]}},
1273 {"jsonrpc":"2.0","id":6,"result":{"iograph": [
1274 {"items": [2.0, '46', 2.0]},
1275 {"items": [656.0, '46', 656.0]},
1276 ]}},
1277 {"jsonrpc":"2.0","id":7,"result":{"iograph": [
1278 {"items": [4.0]},
1279 {"items": [1312.0]},
1280 ]}},
1283 def test_sharkd_req_intervals_bad(self, check_sharkd_session, capture_file):
1284 check_sharkd_session((
1285 {"jsonrpc":"2.0", "id":1, "method":"load",
1286 "params":{"file": capture_file('dhcp.pcap')}
1288 {"jsonrpc":"2.0", "id":2, "method":"intervals",
1289 "params":{"filter": "garbage filter"}
1291 ), (
1292 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1293 {"jsonrpc":"2.0","id":2,"error":{"code":-7001,"message":"Invalid filter parameter: garbage filter"}},
1296 def test_sharkd_req_intervals_basic(self, check_sharkd_session, capture_file):
1297 check_sharkd_session((
1298 {"jsonrpc":"2.0", "id":1, "method":"load",
1299 "params":{"file": capture_file('dhcp.pcap')}
1301 {"jsonrpc":"2.0", "id":2, "method":"intervals"},
1302 {"jsonrpc":"2.0", "id":3, "method":"intervals",
1303 "params":{"interval": 1}
1305 {"jsonrpc":"2.0", "id":4, "method":"intervals",
1306 "params":{"filter": "frame.number <= 2"}
1308 ), (
1309 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1310 {"jsonrpc":"2.0","id":2,"result":{"intervals":[[0,4,1312]],"last":0,"frames":4,"bytes":1312}},
1311 {"jsonrpc":"2.0","id":3,"result":{"intervals":[[0,2,656],[70,2,656]],"last":70,"frames":4,"bytes":1312}},
1312 {"jsonrpc":"2.0","id":4,"result":{"intervals":[[0,2,656]],"last":0,"frames":2,"bytes":656}},
1315 def test_sharkd_req_frame_basic(self, check_sharkd_session, capture_file):
1316 # XXX add more tests for other options (ref_frame, prev_frame, columns, color, bytes, hidden)
1317 check_sharkd_session((
1318 {"jsonrpc":"2.0", "id":1, "method":"load",
1319 "params":{"file": capture_file('dhcp.pcap')}
1321 {"jsonrpc":"2.0", "id":2, "method":"frame",
1322 "params":{"frame": 2}
1324 ), (
1325 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1326 {"jsonrpc":"2.0","id":2,"result":{
1327 "fol": [["UDP", "udp.stream eq 1"]],
1328 "followers": [{"protocol": "UDP","filter": "udp.stream eq 1","stream": 1}]
1332 def test_sharkd_req_frame_http2(self, check_sharkd_session, capture_file):
1333 check_sharkd_session((
1334 {"jsonrpc":"2.0", "id":1, "method":"load",
1335 "params":{"file": capture_file('quic-with-secrets.pcapng')}
1337 {"jsonrpc":"2.0", "id":2, "method":"frame",
1338 "params":{"frame": 12}
1340 ), (
1341 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1342 {"jsonrpc":"2.0","id":2,"result":{
1343 "fol": [["HTTP2", "tcp.stream eq 0 and http2.streamid eq 1"],["TCP","tcp.stream eq 0"],["TLS","tcp.stream eq 0"]],
1344 "followers": [
1345 {"protocol": "HTTP2","filter": "tcp.stream eq 0 and http2.streamid eq 1","stream": 0, "sub_stream": 1},
1346 {"protocol": "TCP","filter": "tcp.stream eq 0","stream": 0},
1347 {"protocol": "TLS","filter": "tcp.stream eq 0","stream": 0},
1352 def test_sharkd_req_frame_proto(self, check_sharkd_session, capture_file):
1353 # Check proto tree output (including an UTF-8 value).
1354 check_sharkd_session((
1355 {"jsonrpc":"2.0", "id":1, "method":"load",
1356 "params":{"file": capture_file('dhcp.pcap')}
1358 {"jsonrpc":"2.0", "id":2, "method":"frame",
1359 "params":{"frame": 2, "proto": True}
1361 ), (
1362 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1363 {"jsonrpc":"2.0","id":2,"result":
1364 MatchObject({
1365 "tree": MatchList({
1366 "l": "Dynamic Host Configuration Protocol (Offer)",
1367 "t": "proto",
1368 "f": "dhcp",
1369 "fn": "dhcp",
1370 "e": MatchAny(int),
1371 "n": MatchList({
1372 "l": "Padding: 0000000000000000000000000000000000000000000000000000",
1373 "h": [316, 26],
1374 "f": "dhcp.option.padding == 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
1375 "fn": "dhcp.option.padding"
1376 }, match_element=any), # match one element from 'n'
1377 "h": [42, 300],
1378 }, match_element=any), # match one element from 'tree'
1383 def test_sharkd_req_setcomment(self, check_sharkd_session, capture_file):
1384 check_sharkd_session((
1385 {"jsonrpc":"2.0", "id":1, "method":"load",
1386 "params":{"file": capture_file('dhcp.pcap')}
1388 {"jsonrpc":"2.0", "id":2, "method":"setcomment",
1389 "params":{"frame": 99999, "comment": "meh\nbaz"}
1391 {"jsonrpc":"2.0", "id":3, "method":"setcomment",
1392 "params":{"frame": 3, "comment": "foo\nbar"}
1394 {"jsonrpc":"2.0", "id":4, "method":"frame",
1395 "params":{"frame": 3}
1398 ), (
1399 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1400 {"jsonrpc":"2.0","id":2,"error":{"code":-3002,"message":"Frame number is out of range"}},
1401 {"jsonrpc":"2.0","id":3,"result":{"status":"OK"}},
1402 {"jsonrpc":"2.0","id":4,"result":{"comment":["foo\nbar"],"fol": MatchAny(list), "followers": MatchAny(list)}},
1405 def test_sharkd_req_setconf_bad(self, check_sharkd_session):
1406 check_sharkd_session((
1407 {"jsonrpc":"2.0", "id":1, "method":"setconf",
1408 "params":{"name": "uat:garbage-pref", "value": "\"\""}
1410 ), (
1411 {"jsonrpc":"2.0","id":1,"error":{"code":-4005,"message":"Unable to set the preference"}},
1414 def test_sharkd_req_dumpconf_bad(self, check_sharkd_session):
1415 check_sharkd_session((
1416 {"jsonrpc":"2.0", "id":1, "method":"dumpconf",
1417 "params":{"pref": "bad.preference"}
1419 {"jsonrpc":"2.0", "id":2, "method":"dumpconf",
1420 "params":{"pref": "invalid-garbage-preference"}
1422 {"jsonrpc":"2.0", "id":3, "method":"dumpconf",
1423 "params":{"pref": "uat:custom_http_header_fields"}
1425 ), (
1426 {"jsonrpc":"2.0","id":1,"error":{"code":-9001,"message":"Invalid pref bad.preference."}},
1427 {"jsonrpc":"2.0","id":2,"error":{"code":-9002,"message":"Invalid pref invalid-garbage-preference."}},
1428 {"jsonrpc":"2.0","id":3,"error":{"code":-9002,"message":"Invalid pref uat:custom_http_header_fields."}},
1431 def test_sharkd_req_dumpconf_all(self, check_sharkd_session):
1432 check_sharkd_session((
1433 {"jsonrpc":"2.0", "id":1, "method":"dumpconf"},
1434 ), (
1435 {"jsonrpc":"2.0","id":1,"result":{"prefs": MatchObject({"tcp.check_checksum": {"b": 0}})}
1439 def test_sharkd_req_download_tls_secrets(self, check_sharkd_session, capture_file):
1440 # XXX test download for eo: too
1441 check_sharkd_session((
1442 {"jsonrpc":"2.0", "id":1, "method":"load",
1443 "params":{"file": capture_file('tls12-dsb.pcapng')}
1445 {"jsonrpc":"2.0", "id":2, "method":"download",
1446 "params":{"token": "ssl-secrets"}
1448 ), (
1449 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1450 # There are two used CLIENT RANDOM secrets, we don't know
1451 # the order they will appear when iterating a hash table,
1452 # and it can be different on Big-Endian systems than L-E.
1453 # Check the Base64 for both "CLIENT_RANDOM f67a" and
1454 # "CLIENT_RANDOM 1e0d".
1455 {"jsonrpc":"2.0","id":2,"result":{"file": "keylog.txt", "mime": "text/plain",
1456 "data": MatchRegExp(r'Q0xJRU5UX1JBTkRP(TSBmNjdh|TSAxZTBk).+')}
1460 def test_sharkd_req_download_rtp_stream(self, check_sharkd_session, capture_file):
1461 check_sharkd_session((
1462 {"jsonrpc":"2.0", "id":1, "method":"load",
1463 "params":{"file": capture_file('sip-rtp.pcapng')}
1465 {"jsonrpc":"2.0", "id":2, "method":"download",
1466 "params":{"token": "rtp:200.57.7.204_8000_200.57.7.196_40376_0xd2bd4e3e"}},
1467 {"jsonrpc":"2.0", "id":3, "method":"download",
1468 "params":{"token": "rtp:1.1.1.1_8000_1.1.1.2_9000_0xdddddddd"}},
1469 ), (
1470 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1471 {"jsonrpc":"2.0","id":2,"result":{
1472 "file":"rtp:200.57.7.204_8000_200.57.7.196_40376_0xd2bd4e3e",
1473 "mime":"audio/x-wav",
1474 "data":MatchRegExp(r'UklGRv.+')}
1476 {"jsonrpc":"2.0","id":3,"error":{"code":-10003,"message":"no rtp data available"}},
1479 def test_sharkd_req_download_bad_tokens(self, check_sharkd_session, capture_file):
1480 check_sharkd_session((
1481 {"jsonrpc":"2.0", "id":1, "method":"load",
1482 "params":{"file": capture_file('tls12-dsb.pcapng')}
1484 {"jsonrpc":"2.0", "id":2, "method":"download",
1485 "params":{"token": "BOGUSTOKEN"}
1487 {"jsonrpc":"2.0", "id":3, "method":"download",
1488 "params":{}
1490 ), (
1491 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1492 {"jsonrpc":"2.0","id":2,"error":{"code":-10004,"message":"unrecognized token"}},
1493 {"jsonrpc":"2.0","id":3,"error":{"code":-10005,"message":"missing token"}},
1496 def test_sharkd_req_download_eo_http_with_prior_tap_eo_http(self, check_sharkd_session, capture_file):
1497 check_sharkd_session((
1498 {"jsonrpc":"2.0", "id":1, "method":"load",
1499 "params":{"file": capture_file('http-ooo.pcap')}
1501 {"jsonrpc":"2.0", "id":2, "method":"tap", "params":{"tap0": "eo:http"}},
1502 {"jsonrpc":"2.0", "id":3, "method":"download",
1503 "params":{"token": "eo:http_0"}},
1504 {"jsonrpc":"2.0", "id":4, "method":"download",
1505 "params":{"token": "eo:http_1"}},
1506 {"jsonrpc":"2.0", "id":5, "method":"download",
1507 "params":{"token": "eo:http_2"}},
1508 {"jsonrpc":"2.0", "id":6, "method":"download",
1509 "params":{"token": "eo:http_999"}},
1510 ), (
1511 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1512 {"jsonrpc":"2.0","id":2,"result":{
1513 "taps":[{
1514 "tap":"eo:http",
1515 "type":"eo",
1516 "proto":"HTTP",
1517 "objects":[{
1518 "pkt":11,
1519 "filename":"4",
1520 "_download":"eo:http_0",
1521 "len":5,
1522 "sha1":"4a4121ecd766ed16943a0c7b54c18f743e90c3f6"
1524 "pkt":13,
1525 "_download":"eo:http_1",
1526 "len":5,
1527 "sha1":"29a51e7382d06ff40467272f02e413ca7b51636e"
1529 "pkt":14,
1530 "_download":"eo:http_2",
1531 "len":5,
1532 "sha1":"f6d0c643351580307b2eaa6a7560e76965496bc7"}]
1535 {"jsonrpc":"2.0","id":3,"result":{
1536 "file":"4","mime":"application/octet-stream","data":"Zm91cgo="}},
1537 {"jsonrpc":"2.0","id":4,"result":{
1538 "file":"eo:http_1","mime":"application/octet-stream","data":"QVRBDQo="}},
1539 {"jsonrpc":"2.0","id":5,"result":{
1540 "file":"eo:http_2","mime":"application/octet-stream","data":"MA0KDQo="}},
1541 {"jsonrpc":"2.0","id":6,"result":{}},
1543 def test_sharkd_req_download_eo_http_without_prior_tap_eo_http(self, check_sharkd_session, capture_file):
1544 check_sharkd_session((
1545 {"jsonrpc":"2.0", "id":1, "method":"load",
1546 "params":{"file": capture_file('http-ooo.pcap')}
1548 {"jsonrpc":"2.0", "id":2, "method":"download",
1549 "params":{"token": "eo:http_0"}},
1550 {"jsonrpc":"2.0", "id":3, "method":"download",
1551 "params":{"token": "eo:http_1"}},
1552 {"jsonrpc":"2.0", "id":4, "method":"download",
1553 "params":{"token": "eo:http_2"}},
1554 {"jsonrpc":"2.0", "id":5, "method":"download",
1555 "params":{"token": "eo:http_999"}},
1556 ), (
1557 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1558 {"jsonrpc":"2.0","id":2,"result":{
1559 "file":"4","mime":"application/octet-stream","data":"Zm91cgo="}},
1560 {"jsonrpc":"2.0","id":3,"result":{
1561 "file":"eo:http_1","mime":"application/octet-stream","data":"QVRBDQo="}},
1562 {"jsonrpc":"2.0","id":4,"result":{
1563 "file":"eo:http_2","mime":"application/octet-stream","data":"MA0KDQo="}},
1564 {"jsonrpc":"2.0","id":5,"result":{}},
1566 def test_sharkd_req_bye(self, check_sharkd_session):
1567 check_sharkd_session((
1568 {"jsonrpc":"2.0", "id":1, "method":"bye"},
1569 ), (
1570 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1573 def test_sharkd_bad_request(self, check_sharkd_session):
1574 check_sharkd_session((
1575 {"jsonrpc":"2.0", "id":1, "method":"dud"},
1576 ), (
1577 {'jsonrpc': '2.0', 'id': 1, 'error': {'code': -32601, 'message': 'The method dud is not supported'}},
1580 def test_sharkd_config(self, check_sharkd_session):
1581 check_sharkd_session((
1582 {"jsonrpc":"2.0", "id":1, "method":"setconf",
1583 "params":{"name": "uat:custom_http_header_fields", "value": "\"X-Header-Name\", \"Description\""}
1585 {"jsonrpc":"2.0", "id":2, "method":"setconf",
1586 "params":{"name": "tcp.check_checksum", "value": "true"}
1588 {"jsonrpc":"2.0", "id":3, "method":"dumpconf",
1589 "params":{"pref": "tcp.check_checksum"}
1591 {"jsonrpc":"2.0", "id":4, "method":"setconf",
1592 "params":{"name": "tcp.check_checksum", "value": "false"}
1594 {"jsonrpc":"2.0", "id":5, "method":"dumpconf",
1595 "params":{"pref": "tcp.check_checksum"}
1597 ), (
1598 # Check that the UAT preference is set. There is no way to query it
1599 # (other than testing for side-effects in dissection).
1600 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1601 {"jsonrpc":"2.0","id":2,"result":{"status":"OK"}},
1602 {"jsonrpc":"2.0","id":3,"result":{"prefs":{"tcp.check_checksum":{"b":1}}}},
1603 {"jsonrpc":"2.0","id":4,"result":{"status":"OK"}},
1604 {"jsonrpc":"2.0","id":5,"result":{"prefs":{"tcp.check_checksum":{"b":0}}}},
1607 def test_sharkd_config_enum(self, check_sharkd_session):
1608 '''Dump default enum preference value, change it and restore it.'''
1609 check_sharkd_session((
1610 {"jsonrpc":"2.0", "id":1, "method":"dumpconf",
1611 "params":{"pref": "wlan.ignore_wep"}
1613 {"jsonrpc":"2.0", "id":2, "method":"setconf",
1614 "params":{"name": "wlan.ignore_wep", "value": "Yes - with IV"}
1616 {"jsonrpc":"2.0", "id":3, "method":"dumpconf",
1617 "params":{"pref": "wlan.ignore_wep"}
1619 {"jsonrpc":"2.0", "id":4, "method":"setconf",
1620 "params":{"name": "wlan.ignore_wep", "value": "No"}
1622 {"jsonrpc":"2.0", "id":5, "method":"dumpconf",
1623 "params":{"pref": "wlan.ignore_wep"}
1625 ), (
1626 {"jsonrpc":"2.0","id":1,"result":{"prefs":{"wlan.ignore_wep":{"e":[{"v":0,"s":1,"d":"No"},{"v":1,"d":"Yes - without IV"},{"v":2,"d":"Yes - with IV"}]}}}},
1627 {"jsonrpc":"2.0","id":2,"result":{"status":"OK"}},
1628 {"jsonrpc":"2.0","id":3,"result":{"prefs":{"wlan.ignore_wep":{"e":[{"v":0,"d":"No"},{"v":1,"d":"Yes - without IV"},{"v":2,"s":1,"d":"Yes - with IV"}]}}}},
1629 {"jsonrpc":"2.0","id":4,"result":{"status":"OK"}},
1630 {"jsonrpc":"2.0","id":5,"result":{"prefs":{"wlan.ignore_wep":{"e":[{"v":0,"s":1,"d":"No"},{"v":1,"d":"Yes - without IV"},{"v":2,"d":"Yes - with IV"}]}}}},
1633 def test_sharkd_nested_file(self, check_sharkd_session, capture_file):
1634 '''Request a frame from a file with a deep level of nesting.'''
1635 check_sharkd_session((
1636 {"jsonrpc":"2.0", "id":1, "method":"load",
1637 "params":{"file": capture_file("http2-data-reassembly.pcap")}
1639 {"jsonrpc":"2.0", "id":2, "method":"frame",
1640 "params":{"frame": "4", "proto": "yes"}
1642 ), (
1643 {"jsonrpc":"2.0","id":1,"result":{"status":"OK"}},
1644 MatchAny(),