netplaySniff – Diff between revs 11 and 12
?pathlinks?
Rev 11 | Rev 12 | |||
---|---|---|---|---|
Line 9... | Line 9... | |||
9 | const mqtt = require('mqtt') |
9 | const mqtt = require('mqtt') |
|
10 | const YAML = require('yamljs') |
10 | const YAML = require('yamljs') |
|
11 | const Cap = require('cap').Cap |
11 | const Cap = require('cap').Cap |
|
12 | const decoders = require('cap').decoders |
12 | const decoders = require('cap').decoders |
|
13 | const PROTOCOL = decoders.PROTOCOL |
13 | const PROTOCOL = decoders.PROTOCOL |
|
14 | const shortHash = require('short-hash') |
14 | const crypto = require('crypto') |
|
15 | const { exec } = require("child_process") |
15 | const { exec } = require("child_process") |
|
16 | const Inotify = require('inotify-remastered').Inotify |
16 | const Inotify = require('inotify-remastered').Inotify |
|
17 | const inotify = new Inotify() |
17 | const inotify = new Inotify() |
|
18 | const sqlite = require('sqlite3') |
18 | const sqlite = require('sqlite3') |
|
19 | const { Command } = require('commander') |
19 | const { Command } = require('commander') |
|
20 | const net = require('net') |
- | ||
Line 21... | Line 20... | |||
21 | |
20 | |
|
22 | // set up logger |
21 | // set up logger |
|
23 | const logger = createLogger({ |
22 | const logger = createLogger({ |
|
24 | format: format.combine( |
23 | format: format.combine( |
|
Line 107... | Line 106... | |||
107 | |
106 | |
|
108 | const cap = new Cap() |
107 | const cap = new Cap() |
|
109 | const filter = `tcp and dst port ${config.netplay.port}` |
108 | const filter = `tcp and dst port ${config.netplay.port}` |
|
110 | const bufSize = 10 * 1024 * 1024 |
109 | const bufSize = 10 * 1024 * 1024 |
|
111 | const buffer = Buffer.alloc(65535) |
110 | const buffer = Buffer.alloc(65535) |
|
112 | var device = Cap.findDevice(config.host); |
111 | var device = Cap.findDevice(config.listen); |
|
113 | const linkType = cap.open(device, filter, bufSize, buffer) |
112 | const linkType = cap.open(device, filter, bufSize, buffer) |
|
114 | cap.setMinBytes && cap.setMinBytes(0) |
113 | cap.setMinBytes && cap.setMinBytes(0) |
|
115 | cap.on('packet', () => { |
114 | cap.on('packet', () => { |
|
116 | let netplay = {} |
115 | let netplay = {} |
|
Line 122... | Line 121... | |||
122 | if (ret.info.type !== PROTOCOL.ETHERNET.IPV4) { |
121 | if (ret.info.type !== PROTOCOL.ETHERNET.IPV4) { |
|
123 | return |
122 | return |
|
124 | } |
123 | } |
|
Line 125... | Line 124... | |||
125 | |
124 | |
|
126 | ret = decoders.IPV4(buffer, ret.offset) |
125 | ret = decoders.IPV4(buffer, ret.offset) |
|
127 | netplay.ip = ret.info.srcaddr |
126 | netplay.src = ret.info.srcaddr |
|
128 | netplay.to = ret.info.dstaddr |
127 | netplay.dst = ret.info.dstaddr |
|
129 | if (ret.info.protocol !== PROTOCOL.IP.TCP) { |
128 | if (ret.info.protocol !== PROTOCOL.IP.TCP) { |
|
130 | return |
129 | return |
|
Line 131... | Line 130... | |||
131 | } |
130 | } |
|
Line 141... | Line 140... | |||
141 | return |
140 | return |
|
142 | } |
141 | } |
|
Line 143... | Line 142... | |||
143 | |
142 | |
|
144 | // remove NULL and NETPLAY_CMD_NICK |
143 | // remove NULL and NETPLAY_CMD_NICK |
|
- | 144 | netplay.nick = payload.toString().replace(/[\u0000\u0020]+/gi, '') |
||
145 | netplay.nick = payload.toString().replace(/[\u0000\u0020]+/gi, '') |
145 | var shasum = crypto.createHash('sha1') |
|
- | 146 | shasum.update(`${netplay.nick}${netplay.src}`) |
||
146 | netplay.hash = shortHash(`${netplay.nick}${netplay.ip}`) |
147 | netplay.hash = shasum.digest('hex') |
|
Line 147... | Line 148... | |||
147 | netplay.time = new Date().toISOString() |
148 | netplay.time = new Date().toISOString() |
|
Line 148... | Line 149... | |||
148 | |
149 | |
|
149 | logger.info(`Player ${netplay.nick} joined via IP ${netplay.ip}`); |
150 | logger.info(`Player ${netplay.nick} joined via IP ${netplay.src}`); |
|
150 | |
151 | |
|
151 | const db = new sqlite.Database(config.db.file, sqlite.OPEN_CREATE | sqlite.OPEN_READWRITE | sqlite.OPEN_FULLMUTEX, (error) => { |
152 | const db = new sqlite.Database(config.db.file, sqlite.OPEN_CREATE | sqlite.OPEN_READWRITE | sqlite.OPEN_FULLMUTEX, (error) => { |
|
152 | if (error) { |
153 | if (error) { |
|
Line 153... | Line 154... | |||
153 | logger.error(`failed to open database: ${config.db.file}`) |
154 | logger.error(`failed to open database: ${config.db.file}`) |
|
154 | return |
155 | return |
|
155 | } |
156 | } |
|
156 | |
157 | |
|
157 | db.run(`CREATE TABLE IF NOT EXISTS "players" ("nick" TEXT(15) NOT NULL, "ip" TEXT NOT NULL)`, (error, result) => { |
158 | db.run(`CREATE TABLE IF NOT EXISTS "players" ("hash" TEXT(40) NOT NULL PRIMARY KEY, "nick" TEXT(15) NOT NULL, "ip" TEXT NOT NULL)`, (error, result) => { |
|
158 | if (error) { |
159 | if (error) { |
|
159 | logger.error(`could not create database table: ${error}`); |
160 | logger.error(`could not create database table: ${error}`); |
|
160 | return |
161 | return |
|
161 | } |
162 | } |
|
162 | db.run(`INSERT INTO "players" ("nick", "ip") VALUES ($nick, $ip)`, { $nick: netplay.nick, $ip: netplay.ip }, (error) => { |
163 | db.run(`REPLACE INTO "players" ("hash", "nick", "ip") VALUES ($hash, $nick, $ip)`, { $hash: netplay.hash, $nick: netplay.nick, $ip: netplay.src }, (error) => { |
|
Line 170... | Line 171... | |||
170 | }) |
171 | }) |
|
171 | }) |
172 | }) |
|
Line 172... | Line 173... | |||
172 | |
173 | |
|
173 | // send data to MQTT server |
174 | // send data to MQTT server |
|
174 | const data = JSON.stringify(netplay, null, 4) |
175 | const data = JSON.stringify(netplay, null, 4) |
|
175 | mqttClient.publish(`${config.mqtt.topic}`, data, (error, packet) => { |
176 | mqttClient.publish(config.mqtt.topic, data, (error, packet) => { |
|
176 | logger.info(`player data sent to MQTT broker`) |
177 | logger.info(`player data sent to MQTT broker`) |
|
Line 177... | Line 178... | |||
177 | }) |
178 | }) |
|
178 | |
179 | |
|
179 | // ban by nick. |
180 | // ban by nick. |
|
180 | let nickBanSet = new Set(config.bans.nicknames) |
181 | let nickBanSet = new Set(config.bans.nicknames) |
|
181 | if (nickBanSet.has(netplay.nick)) { |
182 | if (nickBanSet.has(netplay.nick)) { |
|
182 | logger.info(`nick found to be banned: ${netplay.nick}`) |
183 | logger.info(`nick found to be banned: ${netplay.nick}`) |
|
183 | exec(`iptables -t mangle -A PREROUTING -p tcp --src ${netplay.ip} --dport ${config.netplay.port} -j DROP`, (error, stdout, stderr) => { |
184 | exec(`iptables -t mangle -A PREROUTING -p tcp --src ${netplay.src} --dport ${config.netplay.port} -j DROP`, (error, stdout, stderr) => { |
|
184 | if (error) { |
185 | if (error) { |
|
185 | logger.error(`Error returned while banning connecting client ${error.message}`) |
186 | logger.error(`Error returned while banning connecting client ${error.message}`) |
|
186 | return |
187 | return |