forked from node-pcap/node_pcap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpcap.js
126 lines (103 loc) · 3.85 KB
/
pcap.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
var util = require("util");
var events = require("events");
var binding = require("./build/Release/pcap_binding");
var SocketWatcher = require("socketwatcher").SocketWatcher;
var decode = require("./decode").decode;
var tcp_tracker = require("./tcp_tracker");
var DNSCache = require("./dns_cache");
exports.decode = decode;
exports.TCPTracker = tcp_tracker.TCPTracker;
exports.TCPSession = tcp_tracker.TCPSession;
exports.DNSCache = DNSCache;
function PcapSession(is_live, device_name, filter, buffer_size, outfile, is_monitor) {
this.is_live = is_live;
this.device_name = device_name;
this.filter = filter || "";
this.buffer_size = buffer_size;
this.outfile = outfile || "";
this.is_monitor = Boolean(is_monitor);
this.link_type = null;
this.fd = null;
this.opened = null;
this.buf = null;
this.header = null;
this.read_watcher = null;
this.empty_reads = 0;
this.packets_read = null;
this.session = new binding.PcapSession();
if (typeof this.buffer_size === "number" && !isNaN(this.buffer_size)) {
this.buffer_size = Math.round(this.buffer_size);
} else {
this.buffer_size = 10 * 1024 * 1024; // Default buffer size is 10MB
}
var self = this;
// called for each packet read by pcap
function packet_ready() {
self.on_packet_ready();
}
if (this.is_live) {
this.device_name = this.device_name || binding.default_device();
this.link_type = this.session.open_live(this.device_name, this.filter, this.buffer_size, this.outfile, packet_ready, this.is_monitor);
} else {
this.link_type = this.session.open_offline(this.device_name, this.filter, this.buffer_size, this.outfile, packet_ready, this.is_monitor);
}
this.fd = this.session.fileno();
this.opened = true;
this.buf = new Buffer(this.buffer_size || 65535);
this.header = new Buffer(16);
if (is_live) {
this.readWatcher = new SocketWatcher();
// readWatcher gets a callback when pcap has data to read. multiple packets may be readable.
this.readWatcher.callback = function pcap_read_callback() {
var packets_read = self.session.dispatch(self.buf, self.header);
if (packets_read < 1) {
this.empty_reads += 1;
}
};
this.readWatcher.set(this.fd, true, false);
this.readWatcher.start();
} else {
setImmediate(function() {
var packets = 0;
do {
packets = self.session.dispatch(self.buf, self.header);
} while ( packets > 0 );
self.emit("complete");
});
}
events.EventEmitter.call(this);
}
util.inherits(PcapSession, events.EventEmitter);
exports.lib_version = binding.lib_version();
PcapSession.prototype.findalldevs = function () {
return binding.findalldevs();
};
function PacketWithHeader(buf, header, link_type) {
this.buf = buf;
this.header = header;
this.link_type = link_type;
}
PcapSession.prototype.on_packet_ready = function () {
var full_packet = new PacketWithHeader(this.buf, this.header, this.link_type);
this.emit("packet", full_packet);
};
PcapSession.prototype.close = function () {
this.opened = false;
this.session.close();
this.readWatcher.stop();
// TODO - remove listeners so program will exit I guess?
};
PcapSession.prototype.stats = function () {
return this.session.stats();
};
PcapSession.prototype.inject = function (data) {
return this.session.inject(data);
};
exports.Pcap = PcapSession;
exports.PcapSession = PcapSession;
exports.createSession = function (device, filter, buffer_size, monitor) {
return new PcapSession(true, device, filter, buffer_size, null, monitor);
};
exports.createOfflineSession = function (path, filter) {
return new PcapSession(false, path, filter, 0, null, null);
};