From f63674382528e0de98a68d9f9427eba6feea3629 Mon Sep 17 00:00:00 2001 From: git Date: Sun, 15 Jun 2025 14:28:51 +0100 Subject: [PATCH] Update main.js --- main.js | 127 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 94 insertions(+), 33 deletions(-) diff --git a/main.js b/main.js index b153879..b3cdb06 100644 --- a/main.js +++ b/main.js @@ -76,22 +76,18 @@ function sniffmDNSLocalPackets() { } }) - // 2. Listen for queries - mdns.on('query', function(query) {/* console.log("query requested",query);*/}); - - // 3. Handle the server being destroyed + + // 2. Handle the server being destroyed mdns.on('destroyed', function () {console.log('Server destroyed.');process.exit(0);}); - // 4. Handle the onReady event + // 3. Handle the onReady event mdns.on('ready', function () { console.log("mDNS server is ready..."); // mdns.query({questions:[{ name: '_:googlecast._tcp.local', type: 'PTR', class: 'IN'}]} ); }) - // initialize the server now that we are watching for events - mdns.initServer() - + } function injectmDNSPacketLocally(type,name,data,flush = true,_class = 'IN',ttl = 120) { console.log(`sending packet ${name} of ${type} with data: ${data}`); @@ -106,6 +102,84 @@ function injectmDNSPacketLocally(type,name,data,flush = true,_class = 'IN',ttl = } ]});} +function replyLocallyWithRemoteDevicesData(name,type,query) { + const answers = []; + if (!db.remote) db.remote = {}; + if (!db.remote.PTR) db.remote.PTR = {}; + if (!db.remote.A) db.remote.A = {}; + + // 1. If the query is asking for a PTR (pointer to a service) + if (type === 'PTR' && db.remote.PTR && db.remote.PTR[name]) { + for (let ptrData of db.remote.PTR[name]) { + answers.push({ + name, // The service name being queried + type: 'PTR', // Type of DNS record + class: 'IN', // Internet class + ttl: 120, // Time-to-live (how long to cache) + data: ptrData // The actual pointer data (e.g. device instance name) + }); + } + } + + // 2. If the query is for an A record (IPv4 address of a device) + if (type === 'A' && db.remote.A && db.remote.A[name]) { + answers.push({ + name, + type: 'A', + class: 'IN', + ttl: 120, + data: db.remote.A[name] // The IPv4 address + }); + } + + // 3. If the query is for an SRV record (hostname + port of a service) + if (type === 'SRV' && db.remote[name] && db.remote[name].SRV !== null) { + answers.push({ + name, + type: 'SRV', + class: 'IN', + ttl: 120, + data: db.remote[name].SRV // Must be an object like { port, target, priority, weight } + }); + } + + // 4. If the query is for a TXT record (extra metadata) + if (type === 'TXT' && db.remote[name] && db.remote[name].TXT !== null) { + answers.push({ + name, + type: 'TXT', + class: 'IN', + ttl: 120, + // Convert plain string to buffer; required by mdns-server + data: Buffer.from(db.remote[name].TXT, 'utf8') + }); + } + // 5. Many mDNS tools (like Avahi or Bonjour) send type: 'ANY' queries to discover all records for a name. + if (type === 'ANY') { + // Respond with everything you know about this name + if (db.remote.PTR && db.remote.PTR[name]) { + for (let ptrData of db.remote.PTR[name]) { + answers.push({ name, type: 'PTR', class: 'IN', ttl: 120, data: ptrData }); + } + } + if (db.remote.A && db.remote.A[name]) { + answers.push({ name, type: 'A', class: 'IN', ttl: 120, data: db.remote.A[name] }); + } + if (db.remote[name]) { + const r = db.remote[name]; + if (r.SRV) answers.push({ name, type: 'SRV', class: 'IN', ttl: 120, data: r.SRV }); + if (r.TXT) answers.push({ name, type: 'TXT', class: 'IN', ttl: 120, data: Buffer.from(r.TXT, 'utf8') }); + } + } + + // 6. If we prepared any answers, respond to the query + if (answers.length > 0) { + console.log(`Responding with ${answers.length} answer(s) for ${name}`); + mdns.respond({ answers }); + } + +} + /********************************* @@ -121,30 +195,17 @@ const LOCAL_IP_ADDR = getLocalNetworkAddressesIPs()[0]; const mdns = require('mdns-server')({interface: LOCAL_IP_ADDR,reuseAddr: true,loopback: false,noInit: true}); sniffmDNSLocalPackets(); -setInterval(function(){ - if (!db.remote || !db.remote.PTR) return; - // INJECT PTR - Pointers services - for (let name in db.remote.PTR) { - for (let i in db.remote.PTR[name]) - injectmDNSPacketLocally('PTR',name,db.remote.PTR[name][i]); - } - // INJECT A - Addresses - for (name in db.remote.A) { - injectmDNSPacketLocally('A',name,db.remote.A[name]); - } - - - // INJECT SRV,TXT - for (name in db.remote) { - if (["PTR","A"].includes(name)) continue; - if (db.remote[name].SRV !== null) - injectmDNSPacketLocally('SRV',name,db.remote[name].SRV); - if (db.remote[name].TXT !== null) - injectmDNSPacketLocally('TXT',name,Buffer.from(db.remote[name].TXT, 'utf8')); +mdns.on('query', function (query) { + // Loop through each question in the mDNS query + query.questions.forEach(q => { + const { name, type } = q; + console.log(`Received mDNS query for ${name} (${type})`); + replyLocallyWithRemoteDevicesData(name,type,q); + + + }); +}); - } - - - -},5000); \ No newline at end of file +// initialize the server now that we are watching for events +mdns.initServer()