matterbridge 3.1.7 → 3.1.8-dev-20250725-d6e57e3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/cli.js +2 -91
- package/dist/cliEmitter.js +0 -30
- package/dist/clusters/export.js +0 -2
- package/dist/defaultConfigSchema.js +0 -24
- package/dist/deviceManager.js +1 -94
- package/dist/devices/batteryStorage.js +1 -48
- package/dist/devices/dishwasher.js +3 -78
- package/dist/devices/evse.js +10 -74
- package/dist/devices/export.js +0 -2
- package/dist/devices/extractorHood.js +0 -42
- package/dist/devices/heatPump.js +2 -50
- package/dist/devices/laundryDryer.js +6 -83
- package/dist/devices/laundryWasher.js +7 -91
- package/dist/devices/roboticVacuumCleaner.js +7 -93
- package/dist/devices/solarPower.js +0 -38
- package/dist/devices/waterHeater.js +2 -82
- package/dist/dgram/coap.js +13 -126
- package/dist/dgram/dgram.js +2 -113
- package/dist/dgram/mb_coap.js +3 -41
- package/dist/dgram/mb_mdns.js +13 -51
- package/dist/dgram/mdns.js +137 -298
- package/dist/dgram/multicast.js +1 -60
- package/dist/dgram/unicast.js +0 -54
- package/dist/frontend.js +21 -435
- package/dist/globalMatterbridge.js +0 -47
- package/dist/helpers.js +0 -53
- package/dist/index.js +1 -30
- package/dist/logger/export.js +0 -1
- package/dist/matter/behaviors.js +0 -2
- package/dist/matter/clusters.js +0 -2
- package/dist/matter/devices.js +0 -2
- package/dist/matter/endpoints.js +0 -2
- package/dist/matter/export.js +0 -3
- package/dist/matter/types.js +0 -3
- package/dist/matterbridge.js +55 -811
- package/dist/matterbridgeAccessoryPlatform.js +0 -36
- package/dist/matterbridgeBehaviors.js +5 -65
- package/dist/matterbridgeDeviceTypes.js +15 -579
- package/dist/matterbridgeDynamicPlatform.js +0 -36
- package/dist/matterbridgeEndpoint.js +54 -1214
- package/dist/matterbridgeEndpointHelpers.js +12 -344
- package/dist/matterbridgePlatform.js +0 -233
- package/dist/matterbridgeTypes.js +0 -25
- package/dist/pluginManager.js +3 -249
- package/dist/shelly.js +7 -168
- package/dist/storage/export.js +0 -1
- package/dist/update.js +0 -54
- package/dist/utils/colorUtils.js +2 -263
- package/dist/utils/commandLine.js +0 -54
- package/dist/utils/copyDirectory.js +1 -38
- package/dist/utils/createDirectory.js +0 -33
- package/dist/utils/createZip.js +2 -47
- package/dist/utils/deepCopy.js +0 -39
- package/dist/utils/deepEqual.js +1 -72
- package/dist/utils/error.js +0 -41
- package/dist/utils/export.js +0 -1
- package/dist/utils/hex.js +0 -58
- package/dist/utils/isvalid.js +0 -101
- package/dist/utils/network.js +5 -81
- package/dist/utils/spawn.js +0 -40
- package/dist/utils/wait.js +9 -62
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -2
- package/dist/cli.d.ts +0 -26
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/cliEmitter.d.ts +0 -34
- package/dist/cliEmitter.d.ts.map +0 -1
- package/dist/cliEmitter.js.map +0 -1
- package/dist/clusters/export.d.ts +0 -2
- package/dist/clusters/export.d.ts.map +0 -1
- package/dist/clusters/export.js.map +0 -1
- package/dist/defaultConfigSchema.d.ts +0 -28
- package/dist/defaultConfigSchema.d.ts.map +0 -1
- package/dist/defaultConfigSchema.js.map +0 -1
- package/dist/deviceManager.d.ts +0 -112
- package/dist/deviceManager.d.ts.map +0 -1
- package/dist/deviceManager.js.map +0 -1
- package/dist/devices/batteryStorage.d.ts +0 -48
- package/dist/devices/batteryStorage.d.ts.map +0 -1
- package/dist/devices/batteryStorage.js.map +0 -1
- package/dist/devices/dishwasher.d.ts +0 -91
- package/dist/devices/dishwasher.d.ts.map +0 -1
- package/dist/devices/dishwasher.js.map +0 -1
- package/dist/devices/evse.d.ts +0 -75
- package/dist/devices/evse.d.ts.map +0 -1
- package/dist/devices/evse.js.map +0 -1
- package/dist/devices/export.d.ts +0 -11
- package/dist/devices/export.d.ts.map +0 -1
- package/dist/devices/export.js.map +0 -1
- package/dist/devices/extractorHood.d.ts +0 -46
- package/dist/devices/extractorHood.d.ts.map +0 -1
- package/dist/devices/extractorHood.js.map +0 -1
- package/dist/devices/heatPump.d.ts +0 -47
- package/dist/devices/heatPump.d.ts.map +0 -1
- package/dist/devices/heatPump.js.map +0 -1
- package/dist/devices/laundryDryer.d.ts +0 -87
- package/dist/devices/laundryDryer.d.ts.map +0 -1
- package/dist/devices/laundryDryer.js.map +0 -1
- package/dist/devices/laundryWasher.d.ts +0 -242
- package/dist/devices/laundryWasher.d.ts.map +0 -1
- package/dist/devices/laundryWasher.js.map +0 -1
- package/dist/devices/roboticVacuumCleaner.d.ts +0 -112
- package/dist/devices/roboticVacuumCleaner.d.ts.map +0 -1
- package/dist/devices/roboticVacuumCleaner.js.map +0 -1
- package/dist/devices/solarPower.d.ts +0 -40
- package/dist/devices/solarPower.d.ts.map +0 -1
- package/dist/devices/solarPower.js.map +0 -1
- package/dist/devices/waterHeater.d.ts +0 -111
- package/dist/devices/waterHeater.d.ts.map +0 -1
- package/dist/devices/waterHeater.js.map +0 -1
- package/dist/dgram/coap.d.ts +0 -205
- package/dist/dgram/coap.d.ts.map +0 -1
- package/dist/dgram/coap.js.map +0 -1
- package/dist/dgram/dgram.d.ts +0 -140
- package/dist/dgram/dgram.d.ts.map +0 -1
- package/dist/dgram/dgram.js.map +0 -1
- package/dist/dgram/mb_coap.d.ts +0 -24
- package/dist/dgram/mb_coap.d.ts.map +0 -1
- package/dist/dgram/mb_coap.js.map +0 -1
- package/dist/dgram/mb_mdns.d.ts +0 -24
- package/dist/dgram/mb_mdns.d.ts.map +0 -1
- package/dist/dgram/mb_mdns.js.map +0 -1
- package/dist/dgram/mdns.d.ts +0 -288
- package/dist/dgram/mdns.d.ts.map +0 -1
- package/dist/dgram/mdns.js.map +0 -1
- package/dist/dgram/multicast.d.ts +0 -65
- package/dist/dgram/multicast.d.ts.map +0 -1
- package/dist/dgram/multicast.js.map +0 -1
- package/dist/dgram/unicast.d.ts +0 -56
- package/dist/dgram/unicast.d.ts.map +0 -1
- package/dist/dgram/unicast.js.map +0 -1
- package/dist/frontend.d.ts +0 -304
- package/dist/frontend.d.ts.map +0 -1
- package/dist/frontend.js.map +0 -1
- package/dist/globalMatterbridge.d.ts +0 -59
- package/dist/globalMatterbridge.d.ts.map +0 -1
- package/dist/globalMatterbridge.js.map +0 -1
- package/dist/helpers.d.ts +0 -48
- package/dist/helpers.d.ts.map +0 -1
- package/dist/helpers.js.map +0 -1
- package/dist/index.d.ts +0 -33
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/logger/export.d.ts +0 -2
- package/dist/logger/export.d.ts.map +0 -1
- package/dist/logger/export.js.map +0 -1
- package/dist/matter/behaviors.d.ts +0 -2
- package/dist/matter/behaviors.d.ts.map +0 -1
- package/dist/matter/behaviors.js.map +0 -1
- package/dist/matter/clusters.d.ts +0 -2
- package/dist/matter/clusters.d.ts.map +0 -1
- package/dist/matter/clusters.js.map +0 -1
- package/dist/matter/devices.d.ts +0 -2
- package/dist/matter/devices.d.ts.map +0 -1
- package/dist/matter/devices.js.map +0 -1
- package/dist/matter/endpoints.d.ts +0 -2
- package/dist/matter/endpoints.d.ts.map +0 -1
- package/dist/matter/endpoints.js.map +0 -1
- package/dist/matter/export.d.ts +0 -5
- package/dist/matter/export.d.ts.map +0 -1
- package/dist/matter/export.js.map +0 -1
- package/dist/matter/types.d.ts +0 -3
- package/dist/matter/types.d.ts.map +0 -1
- package/dist/matter/types.js.map +0 -1
- package/dist/matterbridge.d.ts +0 -463
- package/dist/matterbridge.d.ts.map +0 -1
- package/dist/matterbridge.js.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.d.ts +0 -42
- package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
- package/dist/matterbridgeBehaviors.d.ts +0 -1351
- package/dist/matterbridgeBehaviors.d.ts.map +0 -1
- package/dist/matterbridgeBehaviors.js.map +0 -1
- package/dist/matterbridgeDeviceTypes.d.ts +0 -709
- package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
- package/dist/matterbridgeDeviceTypes.js.map +0 -1
- package/dist/matterbridgeDynamicPlatform.d.ts +0 -42
- package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
- package/dist/matterbridgeDynamicPlatform.js.map +0 -1
- package/dist/matterbridgeEndpoint.d.ts +0 -1348
- package/dist/matterbridgeEndpoint.d.ts.map +0 -1
- package/dist/matterbridgeEndpoint.js.map +0 -1
- package/dist/matterbridgeEndpointHelpers.d.ts +0 -406
- package/dist/matterbridgeEndpointHelpers.d.ts.map +0 -1
- package/dist/matterbridgeEndpointHelpers.js.map +0 -1
- package/dist/matterbridgePlatform.d.ts +0 -310
- package/dist/matterbridgePlatform.d.ts.map +0 -1
- package/dist/matterbridgePlatform.js.map +0 -1
- package/dist/matterbridgeTypes.d.ts +0 -195
- package/dist/matterbridgeTypes.d.ts.map +0 -1
- package/dist/matterbridgeTypes.js.map +0 -1
- package/dist/pluginManager.d.ts +0 -270
- package/dist/pluginManager.d.ts.map +0 -1
- package/dist/pluginManager.js.map +0 -1
- package/dist/shelly.d.ts +0 -174
- package/dist/shelly.d.ts.map +0 -1
- package/dist/shelly.js.map +0 -1
- package/dist/storage/export.d.ts +0 -2
- package/dist/storage/export.d.ts.map +0 -1
- package/dist/storage/export.js.map +0 -1
- package/dist/update.d.ts +0 -59
- package/dist/update.d.ts.map +0 -1
- package/dist/update.js.map +0 -1
- package/dist/utils/colorUtils.d.ts +0 -117
- package/dist/utils/colorUtils.d.ts.map +0 -1
- package/dist/utils/colorUtils.js.map +0 -1
- package/dist/utils/commandLine.d.ts +0 -59
- package/dist/utils/commandLine.d.ts.map +0 -1
- package/dist/utils/commandLine.js.map +0 -1
- package/dist/utils/copyDirectory.d.ts +0 -33
- package/dist/utils/copyDirectory.d.ts.map +0 -1
- package/dist/utils/copyDirectory.js.map +0 -1
- package/dist/utils/createDirectory.d.ts +0 -34
- package/dist/utils/createDirectory.d.ts.map +0 -1
- package/dist/utils/createDirectory.js.map +0 -1
- package/dist/utils/createZip.d.ts +0 -39
- package/dist/utils/createZip.d.ts.map +0 -1
- package/dist/utils/createZip.js.map +0 -1
- package/dist/utils/deepCopy.d.ts +0 -32
- package/dist/utils/deepCopy.d.ts.map +0 -1
- package/dist/utils/deepCopy.js.map +0 -1
- package/dist/utils/deepEqual.d.ts +0 -54
- package/dist/utils/deepEqual.d.ts.map +0 -1
- package/dist/utils/deepEqual.js.map +0 -1
- package/dist/utils/error.d.ts +0 -44
- package/dist/utils/error.d.ts.map +0 -1
- package/dist/utils/error.js.map +0 -1
- package/dist/utils/export.d.ts +0 -12
- package/dist/utils/export.d.ts.map +0 -1
- package/dist/utils/export.js.map +0 -1
- package/dist/utils/hex.d.ts +0 -49
- package/dist/utils/hex.d.ts.map +0 -1
- package/dist/utils/hex.js.map +0 -1
- package/dist/utils/isvalid.d.ts +0 -103
- package/dist/utils/isvalid.d.ts.map +0 -1
- package/dist/utils/isvalid.js.map +0 -1
- package/dist/utils/network.d.ts +0 -74
- package/dist/utils/network.d.ts.map +0 -1
- package/dist/utils/network.js.map +0 -1
- package/dist/utils/spawn.d.ts +0 -33
- package/dist/utils/spawn.d.ts.map +0 -1
- package/dist/utils/spawn.js.map +0 -1
- package/dist/utils/wait.d.ts +0 -56
- package/dist/utils/wait.d.ts.map +0 -1
- package/dist/utils/wait.js.map +0 -1
package/dist/dgram/mdns.js
CHANGED
|
@@ -1,28 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description This file contains the class Mdns.
|
|
3
|
-
* @file mdns.ts
|
|
4
|
-
* @author Luca Liguori
|
|
5
|
-
* @created 2025-03-22
|
|
6
|
-
* @version 1.0.0
|
|
7
|
-
* @license Apache-2.0
|
|
8
|
-
*
|
|
9
|
-
* Copyright 2025, 2026, 2027 Luca Liguori.
|
|
10
|
-
*
|
|
11
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
|
-
* you may not use this file except in compliance with the License.
|
|
13
|
-
* You may obtain a copy of the License at
|
|
14
|
-
*
|
|
15
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
16
|
-
*
|
|
17
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
18
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20
|
-
* See the License for the specific language governing permissions and
|
|
21
|
-
* limitations under the License.
|
|
22
|
-
*/
|
|
23
|
-
// AnsiLogger imports
|
|
24
1
|
import { BLUE, CYAN, db, er, GREEN, idn, MAGENTA, nf, rs } from 'node-ansi-logger';
|
|
25
|
-
// Net imports
|
|
26
2
|
import { Multicast } from './multicast.js';
|
|
27
3
|
export var DnsRecordType;
|
|
28
4
|
(function (DnsRecordType) {
|
|
@@ -114,7 +90,6 @@ export var DnsRecordType;
|
|
|
114
90
|
DnsRecordType[DnsRecordType["DOA"] = 259] = "DOA";
|
|
115
91
|
DnsRecordType[DnsRecordType["AMTRELAY"] = 260] = "AMTRELAY";
|
|
116
92
|
DnsRecordType[DnsRecordType["ZONEVERSION"] = 261] = "ZONEVERSION";
|
|
117
|
-
// 262-32767 are unassigned/reserved
|
|
118
93
|
DnsRecordType[DnsRecordType["TA"] = 32768] = "TA";
|
|
119
94
|
DnsRecordType[DnsRecordType["DLV"] = 32769] = "DLV";
|
|
120
95
|
})(DnsRecordType || (DnsRecordType = {}));
|
|
@@ -128,23 +103,11 @@ export var DnsClass;
|
|
|
128
103
|
export var DnsClassFlag;
|
|
129
104
|
(function (DnsClassFlag) {
|
|
130
105
|
DnsClassFlag[DnsClassFlag["FLUSH"] = 32768] = "FLUSH";
|
|
131
|
-
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
|
132
106
|
DnsClassFlag[DnsClassFlag["QU"] = 32768] = "QU";
|
|
133
107
|
})(DnsClassFlag || (DnsClassFlag = {}));
|
|
134
108
|
export class Mdns extends Multicast {
|
|
135
109
|
deviceQueries = new Map();
|
|
136
110
|
deviceResponses = new Map();
|
|
137
|
-
/**
|
|
138
|
-
* Creates an instance of the Mdns class.
|
|
139
|
-
*
|
|
140
|
-
* @param {string} name - The internal name of the mDNS server for the logs.
|
|
141
|
-
* @param {string} multicastAddress - The multicast address for mDNS (i.e. 224.0.0.251 for udp4 or ff02::fb for udp6).
|
|
142
|
-
* @param {number} multicastPort - The port for mDNS (i.e. 5353).
|
|
143
|
-
* @param {('udp4' | 'udp6')} socketType - The type of socket to create (either 'udp4' or 'udp6').
|
|
144
|
-
* @param {boolean} [reuseAddr] - Whether to reuse the address. Defaults to true.
|
|
145
|
-
* @param {string} [interfaceName] - The optional name of the network interface to use.
|
|
146
|
-
* @param {string} [interfaceAddress] - The optional IP address of the network interface to use.
|
|
147
|
-
*/
|
|
148
111
|
constructor(name, multicastAddress, multicastPort, socketType, reuseAddr = true, interfaceName, interfaceAddress) {
|
|
149
112
|
super(name, multicastAddress, multicastPort, socketType, reuseAddr, interfaceName, interfaceAddress);
|
|
150
113
|
}
|
|
@@ -163,14 +126,14 @@ export class Mdns extends Multicast {
|
|
|
163
126
|
this.onQuery(rinfo, result);
|
|
164
127
|
}
|
|
165
128
|
else {
|
|
166
|
-
const ptr = result.answers?.find((record) => record.name === '_shelly._tcp.local' && record.type === 12
|
|
167
|
-
result.answers?.find((record) => record.name === '_http._tcp.local' && record.type === 12
|
|
168
|
-
result.answers?.find((record) => record.type === 12
|
|
169
|
-
result.answers?.find((record) => record.type === 16
|
|
129
|
+
const ptr = result.answers?.find((record) => record.name === '_shelly._tcp.local' && record.type === 12) ||
|
|
130
|
+
result.answers?.find((record) => record.name === '_http._tcp.local' && record.type === 12) ||
|
|
131
|
+
result.answers?.find((record) => record.type === 12) ||
|
|
132
|
+
result.answers?.find((record) => record.type === 16) ||
|
|
170
133
|
result.answers
|
|
171
134
|
? result.answers[0]
|
|
172
|
-
: undefined;
|
|
173
|
-
this.deviceResponses.set(rinfo.address, { rinfo, response: result, dataPTR: ptr?.type === 12
|
|
135
|
+
: undefined;
|
|
136
|
+
this.deviceResponses.set(rinfo.address, { rinfo, response: result, dataPTR: ptr?.type === 12 ? ptr?.data : ptr?.name });
|
|
174
137
|
this.onResponse(rinfo, result);
|
|
175
138
|
}
|
|
176
139
|
this.logMdnsMessage(result);
|
|
@@ -179,28 +142,20 @@ export class Mdns extends Multicast {
|
|
|
179
142
|
this.log.error(`Error decoding mDNS message: ${error instanceof Error ? error.message : error}`);
|
|
180
143
|
}
|
|
181
144
|
}
|
|
182
|
-
/**
|
|
183
|
-
* Decodes an mDNS message, including the header, question section, answer section,
|
|
184
|
-
* authority section, and additional section.
|
|
185
|
-
*
|
|
186
|
-
* @param {Buffer} msg - The raw mDNS message buffer.
|
|
187
|
-
* @returns {MdnsMessage} An object representing the decoded mDNS message.
|
|
188
|
-
* @throws Error if the message is too short.
|
|
189
|
-
*/
|
|
190
145
|
decodeMdnsMessage(msg) {
|
|
191
146
|
if (msg.length < 12) {
|
|
192
147
|
throw new Error('mDNS message too short');
|
|
193
148
|
}
|
|
194
149
|
const id = msg.readUInt16BE(0);
|
|
195
150
|
const flags = msg.readUInt16BE(2);
|
|
196
|
-
const qr = (flags & 0x8000) >> 15;
|
|
197
|
-
const opcode = (flags & 0x7800) >> 11;
|
|
198
|
-
const aa = Boolean(flags & 0x0400);
|
|
199
|
-
const tc = Boolean(flags & 0x0200);
|
|
200
|
-
const rd = Boolean(flags & 0x0100);
|
|
201
|
-
const ra = Boolean(flags & 0x0080);
|
|
202
|
-
const z = (flags & 0x0070) >> 4;
|
|
203
|
-
const rcode = flags & 0x000f;
|
|
151
|
+
const qr = (flags & 0x8000) >> 15;
|
|
152
|
+
const opcode = (flags & 0x7800) >> 11;
|
|
153
|
+
const aa = Boolean(flags & 0x0400);
|
|
154
|
+
const tc = Boolean(flags & 0x0200);
|
|
155
|
+
const rd = Boolean(flags & 0x0100);
|
|
156
|
+
const ra = Boolean(flags & 0x0080);
|
|
157
|
+
const z = (flags & 0x0070) >> 4;
|
|
158
|
+
const rcode = flags & 0x000f;
|
|
204
159
|
const qdCount = msg.readUInt16BE(4);
|
|
205
160
|
const anCount = msg.readUInt16BE(6);
|
|
206
161
|
const nsCount = msg.readUInt16BE(8);
|
|
@@ -225,7 +180,6 @@ export class Mdns extends Multicast {
|
|
|
225
180
|
additionals: [],
|
|
226
181
|
};
|
|
227
182
|
let offset = 12;
|
|
228
|
-
// Decode the question section.
|
|
229
183
|
for (let i = 0; i < qdCount; i++) {
|
|
230
184
|
const qnameResult = this.decodeDnsName(msg, offset);
|
|
231
185
|
const qname = qnameResult.name;
|
|
@@ -236,19 +190,16 @@ export class Mdns extends Multicast {
|
|
|
236
190
|
offset += 2;
|
|
237
191
|
mdnsMessage.questions?.push({ name: qname, type: qtype, class: qclass });
|
|
238
192
|
}
|
|
239
|
-
// Decode the answer section.
|
|
240
193
|
for (let i = 0; i < anCount; i++) {
|
|
241
194
|
const rrResult = this.decodeResourceRecord(msg, offset);
|
|
242
195
|
mdnsMessage.answers?.push(rrResult.record);
|
|
243
196
|
offset = rrResult.newOffset;
|
|
244
197
|
}
|
|
245
|
-
// Decode the authority (NS) section.
|
|
246
198
|
for (let i = 0; i < nsCount; i++) {
|
|
247
199
|
const rrResult = this.decodeResourceRecord(msg, offset);
|
|
248
200
|
mdnsMessage.authorities?.push(rrResult.record);
|
|
249
201
|
offset = rrResult.newOffset;
|
|
250
202
|
}
|
|
251
|
-
// Decode the additional records section.
|
|
252
203
|
for (let i = 0; i < arCount; i++) {
|
|
253
204
|
const rrResult = this.decodeResourceRecord(msg, offset);
|
|
254
205
|
mdnsMessage.additionals?.push(rrResult.record);
|
|
@@ -256,25 +207,15 @@ export class Mdns extends Multicast {
|
|
|
256
207
|
}
|
|
257
208
|
return mdnsMessage;
|
|
258
209
|
}
|
|
259
|
-
/**
|
|
260
|
-
* Decodes a DNS name from a buffer, handling compression.
|
|
261
|
-
*
|
|
262
|
-
* @param {Buffer} msg - The full mDNS message buffer.
|
|
263
|
-
* @param {number} offset - The offset at which the DNS name starts.
|
|
264
|
-
* @returns {{ name: string; newOffset: number }} An object with the decoded name and the new offset.
|
|
265
|
-
* @throws Error if the offset exceeds the buffer length or too many iterations are performed.
|
|
266
|
-
*/
|
|
267
210
|
decodeDnsName(msg, offset) {
|
|
268
211
|
const labels = [];
|
|
269
212
|
let jumped = false;
|
|
270
213
|
let originalOffset = offset;
|
|
271
|
-
let iterations = 0;
|
|
214
|
+
let iterations = 0;
|
|
272
215
|
while (true) {
|
|
273
|
-
// Safety guard: prevent infinite loops in malformed messages.
|
|
274
216
|
if (iterations++ > 1000) {
|
|
275
217
|
throw new Error('Too many iterations while decoding DNS name. Possible malformed message.');
|
|
276
218
|
}
|
|
277
|
-
// Check that offset is within buffer bounds.
|
|
278
219
|
if (offset >= msg.length) {
|
|
279
220
|
throw new Error('Offset exceeds buffer length while decoding DNS name.');
|
|
280
221
|
}
|
|
@@ -283,9 +224,7 @@ export class Mdns extends Multicast {
|
|
|
283
224
|
offset++;
|
|
284
225
|
break;
|
|
285
226
|
}
|
|
286
|
-
// Check for pointer (first two bits are 11)
|
|
287
227
|
if ((len & 0xc0) === 0xc0) {
|
|
288
|
-
// Ensure the pointer has two bytes available.
|
|
289
228
|
if (offset + 1 >= msg.length) {
|
|
290
229
|
throw new Error('Incomplete pointer encountered while decoding DNS name.');
|
|
291
230
|
}
|
|
@@ -298,7 +237,6 @@ export class Mdns extends Multicast {
|
|
|
298
237
|
continue;
|
|
299
238
|
}
|
|
300
239
|
offset++;
|
|
301
|
-
// Check that the label length doesn't go beyond the buffer.
|
|
302
240
|
if (offset + len > msg.length) {
|
|
303
241
|
throw new Error('Label length exceeds buffer bounds while decoding DNS name.');
|
|
304
242
|
}
|
|
@@ -307,15 +245,6 @@ export class Mdns extends Multicast {
|
|
|
307
245
|
}
|
|
308
246
|
return { name: labels.join('.'), newOffset: jumped ? originalOffset : offset };
|
|
309
247
|
}
|
|
310
|
-
/**
|
|
311
|
-
* Encodes a domain name into the DNS label format.
|
|
312
|
-
*
|
|
313
|
-
* For example, "example.local" becomes:
|
|
314
|
-
* [7] "example" [5] "local" [0]
|
|
315
|
-
*
|
|
316
|
-
* @param {string} name - The domain name to encode.
|
|
317
|
-
* @returns {Buffer} The encoded domain name as a Buffer.
|
|
318
|
-
*/
|
|
319
248
|
encodeDnsName(name) {
|
|
320
249
|
const labels = name.split('.');
|
|
321
250
|
const buffers = labels.map((label) => {
|
|
@@ -323,22 +252,12 @@ export class Mdns extends Multicast {
|
|
|
323
252
|
lenBuf.writeUInt8(label.length, 0);
|
|
324
253
|
return Buffer.concat([lenBuf, Buffer.from(label)]);
|
|
325
254
|
});
|
|
326
|
-
// Append the null byte to terminate the name.
|
|
327
255
|
return Buffer.concat([...buffers, Buffer.from([0])]);
|
|
328
256
|
}
|
|
329
|
-
/**
|
|
330
|
-
* Decodes a DNS resource record.
|
|
331
|
-
*
|
|
332
|
-
* @param {Buffer} msg - The full mDNS message buffer.
|
|
333
|
-
* @param {number} offset - The offset at which the resource record starts.
|
|
334
|
-
* @returns {{ record: MdnsRecord; newOffset: number }} An object containing the decoded record and the new offset.
|
|
335
|
-
*/
|
|
336
257
|
decodeResourceRecord(msg, offset) {
|
|
337
|
-
// Decode the NAME field (which may be compressed)
|
|
338
258
|
const nameResult = this.decodeDnsName(msg, offset);
|
|
339
259
|
const name = nameResult.name;
|
|
340
260
|
offset = nameResult.newOffset;
|
|
341
|
-
// Read TYPE (16 bits), CLASS (16 bits), TTL (32 bits), and RDLENGTH (16 bits)
|
|
342
261
|
const type = msg.readUInt16BE(offset);
|
|
343
262
|
offset += 2;
|
|
344
263
|
const rrclass = msg.readUInt16BE(offset);
|
|
@@ -348,14 +267,12 @@ export class Mdns extends Multicast {
|
|
|
348
267
|
const rdlength = msg.readUInt16BE(offset);
|
|
349
268
|
offset += 2;
|
|
350
269
|
let data = '';
|
|
351
|
-
if (type === 12
|
|
352
|
-
// PTR record (type 12): decode its RDATA as a domain name.
|
|
270
|
+
if (type === 12) {
|
|
353
271
|
const ptrResult = this.decodeDnsName(msg, offset);
|
|
354
272
|
data = ptrResult.name;
|
|
355
273
|
offset += rdlength;
|
|
356
274
|
}
|
|
357
|
-
else if (type === 16
|
|
358
|
-
// TXT record: may consist of one or more length-prefixed strings.
|
|
275
|
+
else if (type === 16) {
|
|
359
276
|
const txtStrings = [];
|
|
360
277
|
const end = offset + rdlength;
|
|
361
278
|
while (offset < end) {
|
|
@@ -367,8 +284,7 @@ export class Mdns extends Multicast {
|
|
|
367
284
|
}
|
|
368
285
|
data = txtStrings.join(', ');
|
|
369
286
|
}
|
|
370
|
-
else if (type === 33
|
|
371
|
-
// SRV record (type === 33): consists of 2 bytes for priority, 2 for weight, 2 for port, followed by the target domain name.
|
|
287
|
+
else if (type === 33) {
|
|
372
288
|
const priority = msg.readUInt16BE(offset);
|
|
373
289
|
const weight = msg.readUInt16BE(offset + 2);
|
|
374
290
|
const port = msg.readUInt16BE(offset + 4);
|
|
@@ -382,16 +298,13 @@ export class Mdns extends Multicast {
|
|
|
382
298
|
});
|
|
383
299
|
offset = srvTargetResult.newOffset;
|
|
384
300
|
}
|
|
385
|
-
else if (type === 1
|
|
386
|
-
// A record (type 1): an IPv4 address stored in 4 bytes.
|
|
301
|
+
else if (type === 1) {
|
|
387
302
|
const ipBytes = msg.slice(offset, offset + 4);
|
|
388
303
|
data = Array.from(ipBytes).join('.');
|
|
389
304
|
offset += 4;
|
|
390
305
|
}
|
|
391
|
-
else if (type === 28
|
|
392
|
-
// AAAA record (type 28): IPv6 address stored in 16 bytes.
|
|
306
|
+
else if (type === 28) {
|
|
393
307
|
const ipBytes = msg.slice(offset, offset + 16);
|
|
394
|
-
// Convert the 16 bytes into an IPv6 address string (colon-separated)
|
|
395
308
|
const ipv6Parts = [];
|
|
396
309
|
for (let i = 0; i < 16; i += 2) {
|
|
397
310
|
ipv6Parts.push(ipBytes.readUInt16BE(i).toString(16));
|
|
@@ -399,14 +312,10 @@ export class Mdns extends Multicast {
|
|
|
399
312
|
data = ipv6Parts.join(':');
|
|
400
313
|
offset += 16;
|
|
401
314
|
}
|
|
402
|
-
else if (type === 47
|
|
403
|
-
// NSEC record: RDATA consists of:
|
|
404
|
-
// - Next Domain Name (in DNS label format)
|
|
405
|
-
// - Type Bit Maps (variable length)
|
|
315
|
+
else if (type === 47) {
|
|
406
316
|
const { name: nextDomain, newOffset } = this.decodeDnsName(msg, offset);
|
|
407
317
|
const nextDomainLength = newOffset - offset;
|
|
408
318
|
offset = newOffset;
|
|
409
|
-
// Calculate the remaining length for the type bit maps.
|
|
410
319
|
const bitmapLength = rdlength - nextDomainLength;
|
|
411
320
|
const bitmapData = msg.slice(offset, offset + bitmapLength);
|
|
412
321
|
const types = [];
|
|
@@ -433,7 +342,6 @@ export class Mdns extends Multicast {
|
|
|
433
342
|
offset += bitmapLength;
|
|
434
343
|
}
|
|
435
344
|
else {
|
|
436
|
-
// Fall back
|
|
437
345
|
data = msg.slice(offset, offset + rdlength).toString('hex');
|
|
438
346
|
offset += rdlength;
|
|
439
347
|
}
|
|
@@ -442,28 +350,19 @@ export class Mdns extends Multicast {
|
|
|
442
350
|
newOffset: offset,
|
|
443
351
|
};
|
|
444
352
|
}
|
|
445
|
-
/**
|
|
446
|
-
* Sends a DNS query with multiple questions.
|
|
447
|
-
*
|
|
448
|
-
* @param {Array<{ name: string; type: number; class: number; unicastResponse?: boolean }>} questions - Array of questions
|
|
449
|
-
*
|
|
450
|
-
* @remarks
|
|
451
|
-
* Each question should have a name (e.g., "_http._tcp.local"), type (e.g., DnsRecordType.PTR), class (e.g., DnsClass.IN),
|
|
452
|
-
* and an optional unicastResponse flag (this will add the DnsClassFlag.QU flag to the query).
|
|
453
|
-
*/
|
|
454
353
|
sendQuery(questions) {
|
|
455
354
|
const header = Buffer.alloc(12);
|
|
456
|
-
header.writeUInt16BE(0, 0);
|
|
457
|
-
header.writeUInt16BE(0, 2);
|
|
458
|
-
header.writeUInt16BE(questions.length, 4);
|
|
459
|
-
header.writeUInt16BE(0, 6);
|
|
460
|
-
header.writeUInt16BE(0, 8);
|
|
461
|
-
header.writeUInt16BE(0, 10);
|
|
355
|
+
header.writeUInt16BE(0, 0);
|
|
356
|
+
header.writeUInt16BE(0, 2);
|
|
357
|
+
header.writeUInt16BE(questions.length, 4);
|
|
358
|
+
header.writeUInt16BE(0, 6);
|
|
359
|
+
header.writeUInt16BE(0, 8);
|
|
360
|
+
header.writeUInt16BE(0, 10);
|
|
462
361
|
const questionBuffers = questions.map(({ name, type: qtype, class: qclass, unicastResponse = false }) => {
|
|
463
362
|
const qname = this.encodeDnsName(name);
|
|
464
363
|
const qfields = Buffer.alloc(4);
|
|
465
364
|
qfields.writeUInt16BE(qtype, 0);
|
|
466
|
-
qfields.writeUInt16BE(unicastResponse ? qclass | 32768
|
|
365
|
+
qfields.writeUInt16BE(unicastResponse ? qclass | 32768 : qclass, 2);
|
|
467
366
|
return Buffer.concat([qname, qfields]);
|
|
468
367
|
});
|
|
469
368
|
const query = Buffer.concat([header, ...questionBuffers]);
|
|
@@ -483,46 +382,22 @@ export class Mdns extends Multicast {
|
|
|
483
382
|
}
|
|
484
383
|
});
|
|
485
384
|
}
|
|
486
|
-
/**
|
|
487
|
-
* Constructs an mDNS response packet and sends it to the multicast address and port.
|
|
488
|
-
*
|
|
489
|
-
* @param {string} name - The domain name being responded to (e.g., "example.local").
|
|
490
|
-
* @param {number} rtype - The response type (e.g., 1 for A, 28 for AAAA, etc.).
|
|
491
|
-
* @param {number} rclass - The response class (typically 1 for IN).
|
|
492
|
-
* @param {number} ttl - The time-to-live for the answer record.
|
|
493
|
-
* @param {Buffer} rdata - The resource data for the response (e.g., 4 bytes for an A record IPv4 address).
|
|
494
|
-
*
|
|
495
|
-
* @example
|
|
496
|
-
* const ptrRdata = mdnsIpv4.encodeDnsName('matterbridge._http._tcp.local');
|
|
497
|
-
* mdnsIpv4.sendResponse('_http._tcp.local', DnsRecordType.PTR, DnsClass.IN, 120, ptrRdata);
|
|
498
|
-
*/
|
|
499
385
|
sendResponse(name, rtype, rclass, ttl, rdata) {
|
|
500
|
-
// Create a 12-byte DNS header.
|
|
501
386
|
const header = Buffer.alloc(12);
|
|
502
|
-
header.writeUInt16BE(0, 0);
|
|
503
|
-
// Set flags: QR (response) bit and AA (authoritative answer) bit.
|
|
387
|
+
header.writeUInt16BE(0, 0);
|
|
504
388
|
header.writeUInt16BE(0x8400, 2);
|
|
505
|
-
header.writeUInt16BE(0, 4);
|
|
506
|
-
header.writeUInt16BE(1, 6);
|
|
507
|
-
header.writeUInt16BE(0, 8);
|
|
508
|
-
header.writeUInt16BE(0, 10);
|
|
509
|
-
// Encode the domain name in DNS label format.
|
|
389
|
+
header.writeUInt16BE(0, 4);
|
|
390
|
+
header.writeUInt16BE(1, 6);
|
|
391
|
+
header.writeUInt16BE(0, 8);
|
|
392
|
+
header.writeUInt16BE(0, 10);
|
|
510
393
|
const aname = this.encodeDnsName(name);
|
|
511
|
-
// Prepare the fixed part of the answer record:
|
|
512
|
-
// - 2 bytes for qtype,
|
|
513
|
-
// - 2 bytes for qclass,
|
|
514
|
-
// - 4 bytes for TTL,
|
|
515
|
-
// - 2 bytes for RDLENGTH (length of the rdata).
|
|
516
394
|
const answerFixed = Buffer.alloc(10);
|
|
517
|
-
answerFixed.writeUInt16BE(rtype, 0);
|
|
518
|
-
answerFixed.writeUInt16BE(rclass, 2);
|
|
519
|
-
answerFixed.writeUInt32BE(ttl, 4);
|
|
520
|
-
answerFixed.writeUInt16BE(rdata.length, 8);
|
|
521
|
-
// Concatenate the answer: encoded name, fixed fields, and resource data.
|
|
395
|
+
answerFixed.writeUInt16BE(rtype, 0);
|
|
396
|
+
answerFixed.writeUInt16BE(rclass, 2);
|
|
397
|
+
answerFixed.writeUInt32BE(ttl, 4);
|
|
398
|
+
answerFixed.writeUInt16BE(rdata.length, 8);
|
|
522
399
|
const answer = Buffer.concat([aname, answerFixed, rdata]);
|
|
523
|
-
// Concatenate header and answer to form the complete mDNS response packet.
|
|
524
400
|
const response = Buffer.concat([header, answer]);
|
|
525
|
-
// Send the response packet via the socket.
|
|
526
401
|
this.socket.send(response, 0, response.length, this.multicastPort, this.multicastAddress, (error) => {
|
|
527
402
|
if (error) {
|
|
528
403
|
this.log.error(`Dgram mDNS server failed to send response message for ${MAGENTA}${name}${er} type ${MAGENTA}${this.dnsTypeToString(rtype)}${er} class ${MAGENTA}${this.dnsResponseClassToString(rclass)}${er} ttl ${MAGENTA}${ttl}${er}: ${error instanceof Error ? error.message : error}`);
|
|
@@ -534,128 +409,116 @@ export class Mdns extends Multicast {
|
|
|
534
409
|
}
|
|
535
410
|
});
|
|
536
411
|
}
|
|
537
|
-
/**
|
|
538
|
-
* Converts a DNS record type numeric value to its string representation.
|
|
539
|
-
*
|
|
540
|
-
* @param {number} type - The numeric DNS record type.
|
|
541
|
-
* @returns {string} The string representation of the record type.
|
|
542
|
-
*/
|
|
543
412
|
dnsTypeToString(type) {
|
|
544
413
|
const typeMap = {
|
|
545
|
-
[1
|
|
546
|
-
[2
|
|
547
|
-
[3
|
|
548
|
-
[4
|
|
549
|
-
[5
|
|
550
|
-
[6
|
|
551
|
-
[7
|
|
552
|
-
[8
|
|
553
|
-
[9
|
|
554
|
-
[10
|
|
555
|
-
[11
|
|
556
|
-
[12
|
|
557
|
-
[13
|
|
558
|
-
[14
|
|
559
|
-
[15
|
|
560
|
-
[16
|
|
561
|
-
[17
|
|
562
|
-
[18
|
|
563
|
-
[19
|
|
564
|
-
[20
|
|
565
|
-
[21
|
|
566
|
-
[22
|
|
567
|
-
[23
|
|
568
|
-
[24
|
|
569
|
-
[25
|
|
570
|
-
[26
|
|
571
|
-
[27
|
|
572
|
-
[28
|
|
573
|
-
[29
|
|
574
|
-
[30
|
|
575
|
-
[31
|
|
576
|
-
[32
|
|
577
|
-
[33
|
|
578
|
-
[34
|
|
579
|
-
[35
|
|
580
|
-
[36
|
|
581
|
-
[37
|
|
582
|
-
[38
|
|
583
|
-
[39
|
|
584
|
-
[40
|
|
585
|
-
[41
|
|
586
|
-
[42
|
|
587
|
-
[43
|
|
588
|
-
[44
|
|
589
|
-
[45
|
|
590
|
-
[46
|
|
591
|
-
[47
|
|
592
|
-
[48
|
|
593
|
-
[49
|
|
594
|
-
[50
|
|
595
|
-
[51
|
|
596
|
-
[52
|
|
597
|
-
[53
|
|
598
|
-
[55
|
|
599
|
-
[56
|
|
600
|
-
[57
|
|
601
|
-
[58
|
|
602
|
-
[59
|
|
603
|
-
[60
|
|
604
|
-
[61
|
|
605
|
-
[62
|
|
606
|
-
[63
|
|
607
|
-
[64
|
|
608
|
-
[65
|
|
609
|
-
[99
|
|
610
|
-
[100
|
|
611
|
-
[101
|
|
612
|
-
[102
|
|
613
|
-
[103
|
|
614
|
-
[104
|
|
615
|
-
[105
|
|
616
|
-
[106
|
|
617
|
-
[107
|
|
618
|
-
[108
|
|
619
|
-
[109
|
|
620
|
-
[249
|
|
621
|
-
[250
|
|
622
|
-
[251
|
|
623
|
-
[252
|
|
624
|
-
[253
|
|
625
|
-
[254
|
|
626
|
-
[255
|
|
627
|
-
[256
|
|
628
|
-
[257
|
|
629
|
-
[258
|
|
630
|
-
[259
|
|
631
|
-
[260
|
|
632
|
-
[261
|
|
633
|
-
[32768
|
|
634
|
-
[32769
|
|
414
|
+
[1]: 'A',
|
|
415
|
+
[2]: 'NS',
|
|
416
|
+
[3]: 'MD',
|
|
417
|
+
[4]: 'MF',
|
|
418
|
+
[5]: 'CNAME',
|
|
419
|
+
[6]: 'SOA',
|
|
420
|
+
[7]: 'MB',
|
|
421
|
+
[8]: 'MG',
|
|
422
|
+
[9]: 'MR',
|
|
423
|
+
[10]: 'NULL',
|
|
424
|
+
[11]: 'WKS',
|
|
425
|
+
[12]: 'PTR',
|
|
426
|
+
[13]: 'HINFO',
|
|
427
|
+
[14]: 'MINFO',
|
|
428
|
+
[15]: 'MX',
|
|
429
|
+
[16]: 'TXT',
|
|
430
|
+
[17]: 'RP',
|
|
431
|
+
[18]: 'AFSDB',
|
|
432
|
+
[19]: 'X25',
|
|
433
|
+
[20]: 'ISDN',
|
|
434
|
+
[21]: 'RT',
|
|
435
|
+
[22]: 'NSAP',
|
|
436
|
+
[23]: 'NSAP_PTR',
|
|
437
|
+
[24]: 'SIG',
|
|
438
|
+
[25]: 'KEY',
|
|
439
|
+
[26]: 'PX',
|
|
440
|
+
[27]: 'GPOS',
|
|
441
|
+
[28]: 'AAAA',
|
|
442
|
+
[29]: 'LOC',
|
|
443
|
+
[30]: 'NXT',
|
|
444
|
+
[31]: 'EID',
|
|
445
|
+
[32]: 'NIMLOC',
|
|
446
|
+
[33]: 'SRV',
|
|
447
|
+
[34]: 'ATMA',
|
|
448
|
+
[35]: 'NAPTR',
|
|
449
|
+
[36]: 'KX',
|
|
450
|
+
[37]: 'CERT',
|
|
451
|
+
[38]: 'A6',
|
|
452
|
+
[39]: 'DNAME',
|
|
453
|
+
[40]: 'SINK',
|
|
454
|
+
[41]: 'OPT',
|
|
455
|
+
[42]: 'APL',
|
|
456
|
+
[43]: 'DS',
|
|
457
|
+
[44]: 'SSHFP',
|
|
458
|
+
[45]: 'IPSECKEY',
|
|
459
|
+
[46]: 'RRSIG',
|
|
460
|
+
[47]: 'NSEC',
|
|
461
|
+
[48]: 'DNSKEY',
|
|
462
|
+
[49]: 'DHCID',
|
|
463
|
+
[50]: 'NSEC3',
|
|
464
|
+
[51]: 'NSEC3PARAM',
|
|
465
|
+
[52]: 'TLSA',
|
|
466
|
+
[53]: 'SMIMEA',
|
|
467
|
+
[55]: 'HIP',
|
|
468
|
+
[56]: 'NINFO',
|
|
469
|
+
[57]: 'RKEY',
|
|
470
|
+
[58]: 'TALINK',
|
|
471
|
+
[59]: 'CDS',
|
|
472
|
+
[60]: 'CDNSKEY',
|
|
473
|
+
[61]: 'OPENPGPKEY',
|
|
474
|
+
[62]: 'CSYNC',
|
|
475
|
+
[63]: 'ZONEMD',
|
|
476
|
+
[64]: 'SVCB',
|
|
477
|
+
[65]: 'HTTPS',
|
|
478
|
+
[99]: 'SPF',
|
|
479
|
+
[100]: 'UINFO',
|
|
480
|
+
[101]: 'UID',
|
|
481
|
+
[102]: 'GID',
|
|
482
|
+
[103]: 'UNSPEC',
|
|
483
|
+
[104]: 'NID',
|
|
484
|
+
[105]: 'L32',
|
|
485
|
+
[106]: 'L64',
|
|
486
|
+
[107]: 'LP',
|
|
487
|
+
[108]: 'EUI48',
|
|
488
|
+
[109]: 'EUI64',
|
|
489
|
+
[249]: 'TKEY',
|
|
490
|
+
[250]: 'TSIG',
|
|
491
|
+
[251]: 'IXFR',
|
|
492
|
+
[252]: 'AXFR',
|
|
493
|
+
[253]: 'MAILB',
|
|
494
|
+
[254]: 'MAILA',
|
|
495
|
+
[255]: 'ANY',
|
|
496
|
+
[256]: 'URI',
|
|
497
|
+
[257]: 'CAA',
|
|
498
|
+
[258]: 'AVC',
|
|
499
|
+
[259]: 'DOA',
|
|
500
|
+
[260]: 'AMTRELAY',
|
|
501
|
+
[261]: 'ZONEVERSION',
|
|
502
|
+
[32768]: 'TA',
|
|
503
|
+
[32769]: 'DLV',
|
|
635
504
|
};
|
|
636
505
|
return typeMap[type] ?? `TYPE${type}`;
|
|
637
506
|
}
|
|
638
|
-
/**
|
|
639
|
-
* Converts a DNS response class numeric value to its string representation.
|
|
640
|
-
*
|
|
641
|
-
* @param {number} cls - The numeric DNS class.
|
|
642
|
-
* @returns {string} The string representation of the DNS class.
|
|
643
|
-
*/
|
|
644
507
|
dnsResponseClassToString(cls) {
|
|
645
|
-
const isFlush = !!(cls & 32768
|
|
508
|
+
const isFlush = !!(cls & 32768);
|
|
646
509
|
const baseClass = cls & 0x7fff;
|
|
647
510
|
let classStr;
|
|
648
511
|
switch (baseClass) {
|
|
649
|
-
case 1
|
|
512
|
+
case 1:
|
|
650
513
|
classStr = 'IN';
|
|
651
514
|
break;
|
|
652
|
-
case 3
|
|
515
|
+
case 3:
|
|
653
516
|
classStr = 'CH';
|
|
654
517
|
break;
|
|
655
|
-
case 4
|
|
518
|
+
case 4:
|
|
656
519
|
classStr = 'HS';
|
|
657
520
|
break;
|
|
658
|
-
case 255
|
|
521
|
+
case 255:
|
|
659
522
|
classStr = 'ANY';
|
|
660
523
|
break;
|
|
661
524
|
default:
|
|
@@ -663,28 +526,21 @@ export class Mdns extends Multicast {
|
|
|
663
526
|
}
|
|
664
527
|
return isFlush ? `${classStr}|FLUSH` : classStr;
|
|
665
528
|
}
|
|
666
|
-
/**
|
|
667
|
-
* Converts a DNS question class to a human-readable string.
|
|
668
|
-
* Adds support for mDNS QU (unicast-response) bit.
|
|
669
|
-
*
|
|
670
|
-
* @param {number} cls - The numeric question class.
|
|
671
|
-
* @returns {string} The string representation, e.g. "IN|QU"
|
|
672
|
-
*/
|
|
673
529
|
dnsQuestionClassToString(cls) {
|
|
674
|
-
const isQU = !!(cls & 32768
|
|
530
|
+
const isQU = !!(cls & 32768);
|
|
675
531
|
const baseClass = cls & 0x7fff;
|
|
676
532
|
let classStr;
|
|
677
533
|
switch (baseClass) {
|
|
678
|
-
case 1
|
|
534
|
+
case 1:
|
|
679
535
|
classStr = 'IN';
|
|
680
536
|
break;
|
|
681
|
-
case 3
|
|
537
|
+
case 3:
|
|
682
538
|
classStr = 'CH';
|
|
683
539
|
break;
|
|
684
|
-
case 4
|
|
540
|
+
case 4:
|
|
685
541
|
classStr = 'HS';
|
|
686
542
|
break;
|
|
687
|
-
case 255
|
|
543
|
+
case 255:
|
|
688
544
|
classStr = 'ANY';
|
|
689
545
|
break;
|
|
690
546
|
default:
|
|
@@ -692,11 +548,6 @@ export class Mdns extends Multicast {
|
|
|
692
548
|
}
|
|
693
549
|
return isQU ? `${classStr}|QU` : classStr;
|
|
694
550
|
}
|
|
695
|
-
/**
|
|
696
|
-
* Logs the decoded mDNS message header.
|
|
697
|
-
*
|
|
698
|
-
* @param {MdnsMessage} msg - The mDNS message header object.
|
|
699
|
-
*/
|
|
700
551
|
logMdnsMessage(msg) {
|
|
701
552
|
this.log.info(`Decoded mDNS message: ID ${MAGENTA}${msg.id}${nf}, QR ${GREEN}${msg.qr === 0 ? 'Query' : 'Response'}${nf}, OPCODE ${MAGENTA}${msg.opcode}${nf}, AA ${MAGENTA}${msg.aa}${nf}, TC ${MAGENTA}${msg.tc}${nf}, RD ${MAGENTA}${msg.rd}${nf}, RA ${MAGENTA}${msg.ra}${nf}, Z ${MAGENTA}${msg.z}${nf}, RCODE ${MAGENTA}${msg.rcode}${nf}, QDCount ${MAGENTA}${msg.qdCount}${nf}, ANCount ${MAGENTA}${msg.anCount}${nf}, NSCount ${MAGENTA}${msg.nsCount}${nf}, ARCount ${MAGENTA}${msg.arCount}${nf}`);
|
|
702
553
|
msg.questions?.forEach((question) => {
|
|
@@ -713,14 +564,9 @@ export class Mdns extends Multicast {
|
|
|
713
564
|
});
|
|
714
565
|
this.log.info(`---\n`);
|
|
715
566
|
}
|
|
716
|
-
/**
|
|
717
|
-
* Logs the discovered devices from the mDNS queries and responses.
|
|
718
|
-
*/
|
|
719
567
|
logDevices() {
|
|
720
568
|
this.log.info(`Discovered query devices: ${MAGENTA}${this.deviceQueries.size}${nf}`);
|
|
721
|
-
// Collect devices into an array
|
|
722
569
|
const deviceQueryArray = Array.from(this.deviceQueries.entries());
|
|
723
|
-
// Sort the array by numeric value of the IP address
|
|
724
570
|
deviceQueryArray.sort(([addressA], [addressB]) => {
|
|
725
571
|
const partsA = addressA.split('.').map(Number);
|
|
726
572
|
const partsB = addressB.split('.').map(Number);
|
|
@@ -729,17 +575,13 @@ export class Mdns extends Multicast {
|
|
|
729
575
|
if (diff !== 0)
|
|
730
576
|
return diff;
|
|
731
577
|
}
|
|
732
|
-
// istanbul ignore next
|
|
733
578
|
return 0;
|
|
734
579
|
});
|
|
735
|
-
// Log the sorted devices
|
|
736
580
|
deviceQueryArray.forEach(([rinfo, response]) => {
|
|
737
581
|
this.log.info(`- ${MAGENTA}${rinfo}${nf} family ${BLUE}${response.rinfo.family}${nf} address ${BLUE}${response.rinfo.address}${nf} port ${BLUE}${response.rinfo.port}${nf}`);
|
|
738
582
|
});
|
|
739
583
|
this.log.info(`Discovered response devices: ${MAGENTA}${this.deviceResponses.size}${nf}`);
|
|
740
|
-
// Collect devices into an array
|
|
741
584
|
const deviceResponseArray = Array.from(this.deviceResponses.entries());
|
|
742
|
-
// Sort the array by numeric value of the IP address
|
|
743
585
|
deviceResponseArray.sort(([addressA], [addressB]) => {
|
|
744
586
|
const partsA = addressA.split(/[:.]/).map((part) => parseInt(part, 16));
|
|
745
587
|
const partsB = addressB.split(/[:.]/).map((part) => parseInt(part, 16));
|
|
@@ -748,13 +590,10 @@ export class Mdns extends Multicast {
|
|
|
748
590
|
if (diff !== 0)
|
|
749
591
|
return diff;
|
|
750
592
|
}
|
|
751
|
-
// istanbul ignore next
|
|
752
593
|
return 0;
|
|
753
594
|
});
|
|
754
|
-
// Log the sorted devices
|
|
755
595
|
deviceResponseArray.forEach(([rinfo, response]) => {
|
|
756
596
|
this.log.info(`- ${MAGENTA}${rinfo}${nf} family ${BLUE}${response.rinfo.family}${nf} address ${BLUE}${response.rinfo.address}${nf} port ${BLUE}${response.rinfo.port}${nf} PTR ${GREEN}${response.dataPTR}${nf}`);
|
|
757
597
|
});
|
|
758
598
|
}
|
|
759
599
|
}
|
|
760
|
-
//# sourceMappingURL=mdns.js.map
|