netplaySniff – Diff between revs 11 and 12

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
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