0
# Packet Analysis
1
2
Packet collection management, filtering, analysis, and visualization tools for working with captured network traffic, packet sequences, and network communication patterns.
3
4
## Capabilities
5
6
### Packet Lists
7
8
Container classes for managing collections of packets with analysis and manipulation methods.
9
10
```python { .api }
11
class PacketList:
12
"""
13
List container for network packets with analysis methods.
14
"""
15
def __init__(self, res: list = None, name: str = "PacketList"):
16
"""
17
Initialize packet list.
18
19
Parameters:
20
- res: List of packets
21
- name: Name for the packet list
22
"""
23
24
def summary(self, prn: callable = None, lfilter: callable = None) -> None:
25
"""
26
Display summary of packets in the list.
27
28
Parameters:
29
- prn: Function to generate custom summary for each packet
30
- lfilter: Function to filter packets for summary
31
"""
32
33
def show(self, *args, **kwargs) -> None:
34
"""
35
Display detailed information for all packets.
36
37
Parameters:
38
- *args: Arguments passed to packet.show()
39
- **kwargs: Keyword arguments passed to packet.show()
40
"""
41
42
def filter(self, func: callable) -> 'PacketList':
43
"""
44
Filter packets using a custom function.
45
46
Parameters:
47
- func: Function that takes a packet and returns bool
48
49
Returns:
50
PacketList: New list with filtered packets
51
"""
52
53
def split(self, func: callable) -> list['PacketList']:
54
"""
55
Split packet list into multiple lists based on a function.
56
57
Parameters:
58
- func: Function that returns a key for grouping
59
60
Returns:
61
list[PacketList]: List of packet lists
62
"""
63
64
def plot(self, f: callable = None, lfilter: callable = None, **kwargs):
65
"""
66
Plot packet data using matplotlib.
67
68
Parameters:
69
- f: Function to extract plot data from packets
70
- lfilter: Function to filter packets for plotting
71
- **kwargs: Additional plotting arguments
72
"""
73
74
def make_table(self, *args, **kwargs) -> str:
75
"""
76
Create a formatted table from packet data.
77
78
Parameters:
79
- *args: Column functions or field names
80
- **kwargs: Formatting options
81
82
Returns:
83
str: Formatted table string
84
"""
85
86
def conversations(self, getsrcdst: callable = None) -> dict:
87
"""
88
Extract network conversations from packet list.
89
90
Parameters:
91
- getsrcdst: Function to extract source/destination from packets
92
93
Returns:
94
dict: Dictionary of conversations with statistics
95
"""
96
97
def replace(self, *args, **kwargs) -> 'PacketList':
98
"""
99
Replace packet fields with new values.
100
101
Parameters:
102
- *args: Field replacement specifications
103
- **kwargs: Keyword field replacements
104
105
Returns:
106
PacketList: New list with replaced fields
107
"""
108
109
class SndRcvList(PacketList):
110
"""
111
List of sent/received packet pairs from sr() operations.
112
"""
113
def __init__(self, res: list = None, name: str = "Results"):
114
"""
115
Initialize send/receive list.
116
117
Parameters:
118
- res: List of (sent, received) packet tuples
119
- name: Name for the list
120
"""
121
122
def make_table(self, *args, **kwargs) -> str:
123
"""
124
Create table showing sent vs received packet pairs.
125
126
Parameters:
127
- *args: Column functions for sent/received packets
128
- **kwargs: Formatting options
129
130
Returns:
131
str: Formatted table string
132
"""
133
134
class QueryAnswer(SndRcvList):
135
"""
136
Query/answer packet pairs with additional analysis methods.
137
"""
138
```
139
140
### File Operations
141
142
Functions for reading and writing packet capture files in various formats.
143
144
```python { .api }
145
def rdpcap(filename: str, count: int = -1) -> PacketList:
146
"""
147
Read packets from a pcap file.
148
149
Parameters:
150
- filename: Path to pcap file
151
- count: Maximum number of packets to read (-1 for all)
152
153
Returns:
154
PacketList: Packets read from file
155
"""
156
157
def wrpcap(filename: str, pkt: PacketList, linktype: int = None,
158
gz: bool = False, endianness: str = "=", append: bool = False,
159
sync: bool = False) -> None:
160
"""
161
Write packets to a pcap file.
162
163
Parameters:
164
- filename: Output file path
165
- pkt: Packets to write
166
- linktype: Data link type for pcap header
167
- gz: Compress with gzip
168
- endianness: Byte order ("=" native, "<" little, ">" big)
169
- append: Append to existing file
170
- sync: Sync to disk after each packet
171
"""
172
173
def rdpcapng(filename: str) -> PacketList:
174
"""
175
Read packets from a pcapng file.
176
177
Parameters:
178
- filename: Path to pcapng file
179
180
Returns:
181
PacketList: Packets read from file
182
"""
183
184
def wrpcapng(filename: str, pkt: PacketList, **kwargs) -> None:
185
"""
186
Write packets to a pcapng file.
187
188
Parameters:
189
- filename: Output file path
190
- pkt: Packets to write
191
- **kwargs: Additional options
192
"""
193
194
class PcapReader:
195
"""
196
Iterator for reading large pcap files efficiently.
197
"""
198
def __init__(self, filename: str):
199
"""
200
Initialize pcap reader.
201
202
Parameters:
203
- filename: Path to pcap file
204
"""
205
206
def __iter__(self):
207
"""Return iterator."""
208
209
def __next__(self) -> Packet:
210
"""Get next packet from file."""
211
212
def close(self) -> None:
213
"""Close the file."""
214
215
class PcapWriter:
216
"""
217
Writer for creating pcap files incrementally.
218
"""
219
def __init__(self, filename: str, append: bool = False, sync: bool = False):
220
"""
221
Initialize pcap writer.
222
223
Parameters:
224
- filename: Output file path
225
- append: Append to existing file
226
- sync: Sync after each write
227
"""
228
229
def write(self, pkt: Packet) -> None:
230
"""
231
Write a packet to the file.
232
233
Parameters:
234
- pkt: Packet to write
235
"""
236
237
def close(self) -> None:
238
"""Close the file."""
239
```
240
241
### Traffic Analysis
242
243
Functions for analyzing network traffic patterns and extracting insights from packet data.
244
245
```python { .api }
246
def traceroute(target: str, dport: int = 80, minttl: int = 1, maxttl: int = 30,
247
timeout: float = 2, verbose: int = None, **kwargs) -> TracerouteResult:
248
"""
249
Perform traceroute to a target.
250
251
Parameters:
252
- target: Target IP address or hostname
253
- dport: Destination port
254
- minttl: Minimum TTL value
255
- maxttl: Maximum TTL value
256
- timeout: Timeout per hop
257
- verbose: Verbosity level
258
- **kwargs: Additional arguments
259
260
Returns:
261
TracerouteResult: Traceroute results with hop information
262
"""
263
264
class TracerouteResult:
265
"""
266
Container for traceroute results with analysis methods.
267
"""
268
def show(self) -> None:
269
"""Display traceroute results."""
270
271
def graph(self, **kwargs):
272
"""Generate graph visualization of the route."""
273
274
def world_trace(self) -> None:
275
"""Show route on world map."""
276
277
def arping(net: str, timeout: float = 2, cache: bool = 0, verbose: int = None,
278
**kwargs) -> tuple[SndRcvList, PacketList]:
279
"""
280
Send ARP requests to discover hosts on network.
281
282
Parameters:
283
- net: Network address (e.g., "192.168.1.0/24")
284
- timeout: Timeout for responses
285
- cache: Use ARP cache
286
- verbose: Verbosity level
287
- **kwargs: Additional arguments
288
289
Returns:
290
tuple: (answered_requests, unanswered_requests)
291
"""
292
293
def arpcachepoison(target: str, victim: str, interval: float = 60) -> None:
294
"""
295
Perform ARP cache poisoning attack.
296
297
Parameters:
298
- target: Target IP address
299
- victim: Victim IP address
300
- interval: Poisoning interval in seconds
301
"""
302
```
303
304
### Session Reconstruction
305
306
Tools for reconstructing network sessions and conversations from packet captures.
307
308
```python { .api }
309
class DefaultSession:
310
"""
311
Default session for basic packet processing.
312
"""
313
def on_packet_received(self, pkt: Packet) -> Packet:
314
"""Process received packet."""
315
316
class TCPSession:
317
"""
318
TCP session reconstruction and stream following.
319
"""
320
def __init__(self):
321
"""Initialize TCP session tracker."""
322
323
def process(self, pkt: Packet) -> None:
324
"""Process a packet for session reconstruction."""
325
326
def get_sessions(self) -> dict:
327
"""Get reconstructed TCP sessions."""
328
329
class IPSession:
330
"""
331
IP-level session management and defragmentation.
332
"""
333
def __init__(self):
334
"""Initialize IP session tracker."""
335
```
336
337
### Statistical Analysis
338
339
Functions for statistical analysis of network traffic patterns.
340
341
```python { .api }
342
def conversations(pkts: PacketList, getsrcdst: callable = None) -> dict:
343
"""
344
Extract conversations from packet list.
345
346
Parameters:
347
- pkts: Packet list to analyze
348
- getsrcdst: Function to extract source/destination
349
350
Returns:
351
dict: Conversation statistics
352
"""
353
354
def sessions(pkts: PacketList) -> dict:
355
"""
356
Extract session information from packets.
357
358
Parameters:
359
- pkts: Packet list to analyze
360
361
Returns:
362
dict: Session statistics
363
"""
364
365
def protocols(pkts: PacketList) -> dict:
366
"""
367
Analyze protocol distribution in packet list.
368
369
Parameters:
370
- pkts: Packet list to analyze
371
372
Returns:
373
dict: Protocol statistics
374
"""
375
```
376
377
## Filtering and Processing
378
379
### Lambda Filters
380
381
```python { .api }
382
# Common filter functions for packet analysis
383
lambda_filters = {
384
"tcp": lambda pkt: pkt.haslayer(TCP),
385
"udp": lambda pkt: pkt.haslayer(UDP),
386
"icmp": lambda pkt: pkt.haslayer(ICMP),
387
"dns": lambda pkt: pkt.haslayer(DNS),
388
"http": lambda pkt: pkt.haslayer(TCP) and (pkt[TCP].dport == 80 or pkt[TCP].sport == 80),
389
"https": lambda pkt: pkt.haslayer(TCP) and (pkt[TCP].dport == 443 or pkt[TCP].sport == 443),
390
}
391
```
392
393
## Usage Examples
394
395
### Basic Packet List Operations
396
397
```python
398
from scapy.all import *
399
400
# Read packets from file
401
packets = rdpcap("capture.pcap")
402
print(f"Loaded {len(packets)} packets")
403
404
# Display packet summaries
405
packets.summary()
406
407
# Filter for TCP packets only
408
tcp_packets = packets.filter(lambda pkt: pkt.haslayer(TCP))
409
print(f"Found {len(tcp_packets)} TCP packets")
410
411
# Show detailed view of first 5 packets
412
tcp_packets[:5].show()
413
```
414
415
### Traffic Analysis
416
417
```python
418
# Analyze conversations in capture
419
conversations = packets.conversations()
420
for conv, stats in conversations.items():
421
print(f"Conversation {conv}: {stats['packets']} packets, {stats['bytes']} bytes")
422
423
# Create summary table
424
table = packets.make_table(
425
lambda pkt: pkt[IP].src if pkt.haslayer(IP) else "N/A",
426
lambda pkt: pkt[IP].dst if pkt.haslayer(IP) else "N/A",
427
lambda pkt: pkt[IP].proto if pkt.haslayer(IP) else "N/A"
428
)
429
print(table)
430
431
# Plot packet sizes over time
432
packets.plot(lambda pkt: len(pkt), title="Packet Sizes Over Time")
433
```
434
435
### Network Discovery
436
437
```python
438
# ARP scan of local network
439
answered, unanswered = arping("192.168.1.0/24")
440
print("Live hosts:")
441
for sent, received in answered:
442
print(f" {received.psrc} -> {received.hwsrc}")
443
444
# Traceroute to target
445
trace_result = traceroute("8.8.8.8")
446
trace_result.show()
447
448
# DNS enumeration
449
dns_queries = [IP(dst="8.8.8.8")/UDP(dport=53)/DNS(rd=1, qd=DNSQR(qname=f"{word}.example.com"))
450
for word in ["www", "mail", "ftp", "admin", "test"]]
451
answered, unanswered = sr(dns_queries, timeout=2, verbose=0)
452
```
453
454
### File Processing
455
456
```python
457
# Process large pcap files efficiently
458
with PcapReader("large_capture.pcap") as reader:
459
tcp_count = 0
460
udp_count = 0
461
462
for packet in reader:
463
if packet.haslayer(TCP):
464
tcp_count += 1
465
elif packet.haslayer(UDP):
466
udp_count += 1
467
468
if (tcp_count + udp_count) % 1000 == 0:
469
print(f"Processed {tcp_count + udp_count} packets")
470
471
print(f"Final counts: TCP={tcp_count}, UDP={udp_count}")
472
473
# Create filtered capture file
474
web_traffic = packets.filter(lambda pkt: pkt.haslayer(TCP) and
475
(pkt[TCP].dport in [80, 443] or pkt[TCP].sport in [80, 443]))
476
wrpcap("web_traffic.pcap", web_traffic)
477
```
478
479
### Advanced Analysis
480
481
```python
482
# TCP session reconstruction
483
sessions = {}
484
for pkt in packets.filter(lambda p: p.haslayer(TCP)):
485
if pkt.haslayer(IP):
486
session_key = (pkt[IP].src, pkt[TCP].sport, pkt[IP].dst, pkt[TCP].dport)
487
if session_key not in sessions:
488
sessions[session_key] = []
489
sessions[session_key].append(pkt)
490
491
# Analyze each session
492
for session_key, session_packets in sessions.items():
493
src_ip, src_port, dst_ip, dst_port = session_key
494
print(f"Session {src_ip}:{src_port} -> {dst_ip}:{dst_port}")
495
print(f" Packets: {len(session_packets)}")
496
print(f" Duration: {session_packets[-1].time - session_packets[0].time:.2f}s")
497
498
# Protocol distribution analysis
499
protocols = {}
500
for pkt in packets:
501
if pkt.haslayer(IP):
502
proto = pkt[IP].proto
503
proto_name = {1: "ICMP", 6: "TCP", 17: "UDP"}.get(proto, f"Proto-{proto}")
504
protocols[proto_name] = protocols.get(proto_name, 0) + 1
505
506
print("Protocol distribution:")
507
for proto, count in sorted(protocols.items(), key=lambda x: x[1], reverse=True):
508
print(f" {proto}: {count} packets")
509
```
510
511
### Visualization and Reporting
512
513
```python
514
# Plot traffic over time
515
import matplotlib.pyplot as plt
516
517
timestamps = [float(pkt.time) for pkt in packets]
518
start_time = min(timestamps)
519
relative_times = [(t - start_time) for t in timestamps]
520
521
plt.figure(figsize=(12, 6))
522
plt.hist(relative_times, bins=50, alpha=0.7)
523
plt.xlabel("Time (seconds)")
524
plt.ylabel("Packet count")
525
plt.title("Traffic Distribution Over Time")
526
plt.show()
527
528
# Generate traffic report
529
def generate_report(packets):
530
report = []
531
report.append(f"Traffic Analysis Report")
532
report.append(f"=" * 30)
533
report.append(f"Total packets: {len(packets)}")
534
535
# Protocol breakdown
536
proto_counts = {}
537
for pkt in packets:
538
if pkt.haslayer(IP):
539
proto = {1: "ICMP", 6: "TCP", 17: "UDP"}.get(pkt[IP].proto, "Other")
540
proto_counts[proto] = proto_counts.get(proto, 0) + 1
541
542
report.append("\\nProtocol Distribution:")
543
for proto, count in proto_counts.items():
544
pct = (count / len(packets)) * 100
545
report.append(f" {proto}: {count} packets ({pct:.1f}%)")
546
547
return "\\n".join(report)
548
549
print(generate_report(packets))
550
```