matterbridge 3.4.5-dev-20251225-2f72161 → 3.4.5
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 +5 -8
- package/dist/broadcastServer.d.ts +144 -0
- package/dist/broadcastServer.d.ts.map +1 -0
- package/dist/broadcastServer.js +117 -0
- package/dist/broadcastServer.js.map +1 -0
- package/dist/broadcastServerTypes.d.ts +841 -0
- package/dist/broadcastServerTypes.d.ts.map +1 -0
- package/dist/broadcastServerTypes.js +24 -0
- package/dist/broadcastServerTypes.js.map +1 -0
- package/dist/cli.d.ts +30 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +97 -1
- package/dist/cli.js.map +1 -0
- package/dist/cliEmitter.d.ts +50 -0
- package/dist/cliEmitter.d.ts.map +1 -0
- package/dist/cliEmitter.js +37 -0
- package/dist/cliEmitter.js.map +1 -0
- package/dist/cliHistory.d.ts +48 -0
- package/dist/cliHistory.d.ts.map +1 -0
- package/dist/cliHistory.js +38 -0
- package/dist/cliHistory.js.map +1 -0
- package/dist/clusters/export.d.ts +2 -0
- package/dist/clusters/export.d.ts.map +1 -0
- package/dist/clusters/export.js +2 -0
- package/dist/clusters/export.js.map +1 -0
- package/dist/deviceManager.d.ts +135 -0
- package/dist/deviceManager.d.ts.map +1 -0
- package/dist/deviceManager.js +113 -1
- package/dist/deviceManager.js.map +1 -0
- package/dist/devices/airConditioner.d.ts +98 -0
- package/dist/devices/airConditioner.d.ts.map +1 -0
- package/dist/devices/airConditioner.js +57 -0
- package/dist/devices/airConditioner.js.map +1 -0
- package/dist/devices/batteryStorage.d.ts +48 -0
- package/dist/devices/batteryStorage.d.ts.map +1 -0
- package/dist/devices/batteryStorage.js +48 -1
- package/dist/devices/batteryStorage.js.map +1 -0
- package/dist/devices/cooktop.d.ts +61 -0
- package/dist/devices/cooktop.d.ts.map +1 -0
- package/dist/devices/cooktop.js +56 -0
- package/dist/devices/cooktop.js.map +1 -0
- package/dist/devices/dishwasher.d.ts +71 -0
- package/dist/devices/dishwasher.d.ts.map +1 -0
- package/dist/devices/dishwasher.js +57 -0
- package/dist/devices/dishwasher.js.map +1 -0
- package/dist/devices/evse.d.ts +76 -0
- package/dist/devices/evse.d.ts.map +1 -0
- package/dist/devices/evse.js +74 -10
- package/dist/devices/evse.js.map +1 -0
- package/dist/devices/export.d.ts +17 -0
- package/dist/devices/export.d.ts.map +1 -0
- package/dist/devices/export.js +5 -0
- package/dist/devices/export.js.map +1 -0
- package/dist/devices/extractorHood.d.ts +46 -0
- package/dist/devices/extractorHood.d.ts.map +1 -0
- package/dist/devices/extractorHood.js +43 -0
- package/dist/devices/extractorHood.js.map +1 -0
- package/dist/devices/heatPump.d.ts +47 -0
- package/dist/devices/heatPump.d.ts.map +1 -0
- package/dist/devices/heatPump.js +50 -2
- package/dist/devices/heatPump.js.map +1 -0
- package/dist/devices/laundryDryer.d.ts +67 -0
- package/dist/devices/laundryDryer.d.ts.map +1 -0
- package/dist/devices/laundryDryer.js +62 -3
- package/dist/devices/laundryDryer.js.map +1 -0
- package/dist/devices/laundryWasher.d.ts +81 -0
- package/dist/devices/laundryWasher.d.ts.map +1 -0
- package/dist/devices/laundryWasher.js +70 -4
- package/dist/devices/laundryWasher.js.map +1 -0
- package/dist/devices/microwaveOven.d.ts +168 -0
- package/dist/devices/microwaveOven.d.ts.map +1 -0
- package/dist/devices/microwaveOven.js +88 -5
- package/dist/devices/microwaveOven.js.map +1 -0
- package/dist/devices/oven.d.ts +105 -0
- package/dist/devices/oven.d.ts.map +1 -0
- package/dist/devices/oven.js +85 -0
- package/dist/devices/oven.js.map +1 -0
- package/dist/devices/refrigerator.d.ts +118 -0
- package/dist/devices/refrigerator.d.ts.map +1 -0
- package/dist/devices/refrigerator.js +102 -0
- package/dist/devices/refrigerator.js.map +1 -0
- package/dist/devices/roboticVacuumCleaner.d.ts +112 -0
- package/dist/devices/roboticVacuumCleaner.d.ts.map +1 -0
- package/dist/devices/roboticVacuumCleaner.js +100 -9
- package/dist/devices/roboticVacuumCleaner.js.map +1 -0
- package/dist/devices/solarPower.d.ts +40 -0
- package/dist/devices/solarPower.d.ts.map +1 -0
- package/dist/devices/solarPower.js +38 -0
- package/dist/devices/solarPower.js.map +1 -0
- package/dist/devices/speaker.d.ts +87 -0
- package/dist/devices/speaker.d.ts.map +1 -0
- package/dist/devices/speaker.js +84 -0
- package/dist/devices/speaker.js.map +1 -0
- package/dist/devices/temperatureControl.d.ts +166 -0
- package/dist/devices/temperatureControl.d.ts.map +1 -0
- package/dist/devices/temperatureControl.js +24 -3
- package/dist/devices/temperatureControl.js.map +1 -0
- package/dist/devices/waterHeater.d.ts +111 -0
- package/dist/devices/waterHeater.d.ts.map +1 -0
- package/dist/devices/waterHeater.js +82 -2
- package/dist/devices/waterHeater.js.map +1 -0
- package/dist/dgram/coap.d.ts +205 -0
- package/dist/dgram/coap.d.ts.map +1 -0
- package/dist/dgram/coap.js +126 -13
- package/dist/dgram/coap.js.map +1 -0
- package/dist/dgram/dgram.d.ts +143 -0
- package/dist/dgram/dgram.d.ts.map +1 -0
- package/dist/dgram/dgram.js +121 -4
- package/dist/dgram/dgram.js.map +1 -0
- package/dist/dgram/mb_coap.d.ts +24 -0
- package/dist/dgram/mb_coap.d.ts.map +1 -0
- package/dist/dgram/mb_coap.js +41 -3
- package/dist/dgram/mb_coap.js.map +1 -0
- package/dist/dgram/mb_mdns.d.ts +24 -0
- package/dist/dgram/mb_mdns.d.ts.map +1 -0
- package/dist/dgram/mb_mdns.js +172 -172
- package/dist/dgram/mb_mdns.js.map +1 -0
- package/dist/dgram/mdns.d.ts +350 -0
- package/dist/dgram/mdns.d.ts.map +1 -0
- package/dist/dgram/mdns.js +358 -144
- package/dist/dgram/mdns.js.map +1 -0
- package/dist/dgram/mdnsReflectorClient.d.ts +39 -0
- package/dist/dgram/mdnsReflectorClient.d.ts.map +1 -0
- package/dist/dgram/mdnsReflectorClient.js +132 -0
- package/dist/dgram/mdnsReflectorClient.js.map +1 -0
- package/dist/dgram/mdnsReflectorServer.d.ts +54 -0
- package/dist/dgram/mdnsReflectorServer.d.ts.map +1 -0
- package/dist/dgram/mdnsReflectorServer.js +294 -0
- package/dist/dgram/mdnsReflectorServer.js.map +1 -0
- package/dist/dgram/mdnsReflectorTypes.d.ts +28 -0
- package/dist/dgram/mdnsReflectorTypes.d.ts.map +1 -0
- package/dist/dgram/mdnsReflectorTypes.js +28 -0
- package/dist/dgram/mdnsReflectorTypes.js.map +1 -0
- package/dist/dgram/multicast.d.ts +67 -0
- package/dist/dgram/multicast.d.ts.map +1 -0
- package/dist/dgram/multicast.js +62 -1
- package/dist/dgram/multicast.js.map +1 -0
- package/dist/dgram/unicast.d.ts +64 -0
- package/dist/dgram/unicast.d.ts.map +1 -0
- package/dist/dgram/unicast.js +64 -1
- package/dist/dgram/unicast.js.map +1 -0
- package/dist/frontend.d.ts +245 -0
- package/dist/frontend.d.ts.map +1 -0
- package/dist/frontend.js +485 -38
- package/dist/frontend.js.map +1 -0
- package/dist/frontendTypes.d.ts +529 -0
- package/dist/frontendTypes.d.ts.map +1 -0
- package/dist/frontendTypes.js +45 -0
- package/dist/frontendTypes.js.map +1 -0
- package/dist/helpers.d.ts +48 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +53 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/jestutils/export.d.ts +2 -0
- package/dist/jestutils/export.d.ts.map +1 -0
- package/dist/jestutils/export.js +1 -0
- package/dist/jestutils/export.js.map +1 -0
- package/dist/jestutils/jestHelpers.d.ts +345 -0
- package/dist/jestutils/jestHelpers.d.ts.map +1 -0
- package/dist/jestutils/jestHelpers.js +371 -14
- package/dist/jestutils/jestHelpers.js.map +1 -0
- package/dist/logger/export.d.ts +2 -0
- package/dist/logger/export.d.ts.map +1 -0
- package/dist/logger/export.js +1 -0
- package/dist/logger/export.js.map +1 -0
- package/dist/matter/behaviors.d.ts +2 -0
- package/dist/matter/behaviors.d.ts.map +1 -0
- package/dist/matter/behaviors.js +2 -0
- package/dist/matter/behaviors.js.map +1 -0
- package/dist/matter/clusters.d.ts +2 -0
- package/dist/matter/clusters.d.ts.map +1 -0
- package/dist/matter/clusters.js +2 -0
- package/dist/matter/clusters.js.map +1 -0
- package/dist/matter/devices.d.ts +2 -0
- package/dist/matter/devices.d.ts.map +1 -0
- package/dist/matter/devices.js +2 -0
- package/dist/matter/devices.js.map +1 -0
- package/dist/matter/endpoints.d.ts +2 -0
- package/dist/matter/endpoints.d.ts.map +1 -0
- package/dist/matter/endpoints.js +2 -0
- package/dist/matter/endpoints.js.map +1 -0
- package/dist/matter/export.d.ts +5 -0
- package/dist/matter/export.d.ts.map +1 -0
- package/dist/matter/export.js +3 -0
- package/dist/matter/export.js.map +1 -0
- package/dist/matter/types.d.ts +3 -0
- package/dist/matter/types.d.ts.map +1 -0
- package/dist/matter/types.js +3 -0
- package/dist/matter/types.js.map +1 -0
- package/dist/matterNode.d.ts +342 -0
- package/dist/matterNode.d.ts.map +1 -0
- package/dist/matterNode.js +369 -8
- package/dist/matterNode.js.map +1 -0
- package/dist/matterbridge.d.ts +505 -0
- package/dist/matterbridge.d.ts.map +1 -0
- package/dist/matterbridge.js +824 -46
- package/dist/matterbridge.js.map +1 -0
- package/dist/matterbridgeAccessoryPlatform.d.ts +41 -0
- package/dist/matterbridgeAccessoryPlatform.d.ts.map +1 -0
- package/dist/matterbridgeAccessoryPlatform.js +38 -0
- package/dist/matterbridgeAccessoryPlatform.js.map +1 -0
- package/dist/matterbridgeBehaviors.d.ts +2404 -0
- package/dist/matterbridgeBehaviors.d.ts.map +1 -0
- package/dist/matterbridgeBehaviors.js +68 -5
- package/dist/matterbridgeBehaviors.js.map +1 -0
- package/dist/matterbridgeDeviceTypes.d.ts +698 -0
- package/dist/matterbridgeDeviceTypes.d.ts.map +1 -0
- package/dist/matterbridgeDeviceTypes.js +635 -14
- package/dist/matterbridgeDeviceTypes.js.map +1 -0
- package/dist/matterbridgeDynamicPlatform.d.ts +41 -0
- package/dist/matterbridgeDynamicPlatform.d.ts.map +1 -0
- package/dist/matterbridgeDynamicPlatform.js +38 -0
- package/dist/matterbridgeDynamicPlatform.js.map +1 -0
- package/dist/matterbridgeEndpoint.d.ts +1507 -0
- package/dist/matterbridgeEndpoint.d.ts.map +1 -0
- package/dist/matterbridgeEndpoint.js +1457 -53
- package/dist/matterbridgeEndpoint.js.map +1 -0
- package/dist/matterbridgeEndpointHelpers.d.ts +787 -0
- package/dist/matterbridgeEndpointHelpers.d.ts.map +1 -0
- package/dist/matterbridgeEndpointHelpers.js +483 -20
- package/dist/matterbridgeEndpointHelpers.js.map +1 -0
- package/dist/matterbridgeEndpointTypes.d.ts +166 -0
- package/dist/matterbridgeEndpointTypes.d.ts.map +1 -0
- package/dist/matterbridgeEndpointTypes.js +25 -0
- package/dist/matterbridgeEndpointTypes.js.map +1 -0
- package/dist/matterbridgePlatform.d.ts +539 -0
- package/dist/matterbridgePlatform.d.ts.map +1 -0
- package/dist/matterbridgePlatform.js +451 -1
- package/dist/matterbridgePlatform.js.map +1 -0
- package/dist/matterbridgeTypes.d.ts +252 -0
- package/dist/matterbridgeTypes.d.ts.map +1 -0
- package/dist/matterbridgeTypes.js +26 -0
- package/dist/matterbridgeTypes.js.map +1 -0
- package/dist/pluginManager.d.ts +372 -0
- package/dist/pluginManager.d.ts.map +1 -0
- package/dist/pluginManager.js +341 -5
- package/dist/pluginManager.js.map +1 -0
- package/dist/shelly.d.ts +181 -0
- package/dist/shelly.d.ts.map +1 -0
- package/dist/shelly.js +178 -7
- package/dist/shelly.js.map +1 -0
- package/dist/storage/export.d.ts +2 -0
- package/dist/storage/export.d.ts.map +1 -0
- package/dist/storage/export.js +1 -0
- package/dist/storage/export.js.map +1 -0
- package/dist/update.d.ts +84 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +93 -1
- package/dist/update.js.map +1 -0
- package/dist/utils/colorUtils.d.ts +101 -0
- package/dist/utils/colorUtils.d.ts.map +1 -0
- package/dist/utils/colorUtils.js +97 -2
- package/dist/utils/colorUtils.js.map +1 -0
- package/dist/utils/commandLine.d.ts +66 -0
- package/dist/utils/commandLine.d.ts.map +1 -0
- package/dist/utils/commandLine.js +61 -1
- package/dist/utils/commandLine.js.map +1 -0
- package/dist/utils/copyDirectory.d.ts +35 -0
- package/dist/utils/copyDirectory.d.ts.map +1 -0
- package/dist/utils/copyDirectory.js +37 -0
- package/dist/utils/copyDirectory.js.map +1 -0
- package/dist/utils/createDirectory.d.ts +34 -0
- package/dist/utils/createDirectory.d.ts.map +1 -0
- package/dist/utils/createDirectory.js +33 -0
- package/dist/utils/createDirectory.js.map +1 -0
- package/dist/utils/createZip.d.ts +39 -0
- package/dist/utils/createZip.d.ts.map +1 -0
- package/dist/utils/createZip.js +47 -2
- package/dist/utils/createZip.js.map +1 -0
- package/dist/utils/deepCopy.d.ts +32 -0
- package/dist/utils/deepCopy.d.ts.map +1 -0
- package/dist/utils/deepCopy.js +39 -0
- package/dist/utils/deepCopy.js.map +1 -0
- package/dist/utils/deepEqual.d.ts +54 -0
- package/dist/utils/deepEqual.d.ts.map +1 -0
- package/dist/utils/deepEqual.js +72 -1
- package/dist/utils/deepEqual.js.map +1 -0
- package/dist/utils/error.d.ts +45 -0
- package/dist/utils/error.d.ts.map +1 -0
- package/dist/utils/error.js +42 -0
- package/dist/utils/error.js.map +1 -0
- package/dist/utils/export.d.ts +13 -0
- package/dist/utils/export.d.ts.map +1 -0
- package/dist/utils/export.js +1 -0
- package/dist/utils/export.js.map +1 -0
- package/dist/utils/format.d.ts +53 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +49 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/hex.d.ts +89 -0
- package/dist/utils/hex.d.ts.map +1 -0
- package/dist/utils/hex.js +124 -0
- package/dist/utils/hex.js.map +1 -0
- package/dist/utils/inspector.d.ts +87 -0
- package/dist/utils/inspector.d.ts.map +1 -0
- package/dist/utils/inspector.js +69 -1
- package/dist/utils/inspector.js.map +1 -0
- package/dist/utils/isvalid.d.ts +103 -0
- package/dist/utils/isvalid.d.ts.map +1 -0
- package/dist/utils/isvalid.js +101 -0
- package/dist/utils/isvalid.js.map +1 -0
- package/dist/utils/network.d.ts +117 -0
- package/dist/utils/network.d.ts.map +1 -0
- package/dist/utils/network.js +103 -5
- package/dist/utils/network.js.map +1 -0
- package/dist/utils/spawn.d.ts +33 -0
- package/dist/utils/spawn.d.ts.map +1 -0
- package/dist/utils/spawn.js +71 -1
- package/dist/utils/spawn.js.map +1 -0
- package/dist/utils/tracker.d.ts +108 -0
- package/dist/utils/tracker.d.ts.map +1 -0
- package/dist/utils/tracker.js +64 -1
- package/dist/utils/tracker.js.map +1 -0
- package/dist/utils/wait.d.ts +54 -0
- package/dist/utils/wait.d.ts.map +1 -0
- package/dist/utils/wait.js +60 -8
- package/dist/utils/wait.js.map +1 -0
- package/dist/workerGlobalPrefix.d.ts +25 -0
- package/dist/workerGlobalPrefix.d.ts.map +1 -0
- package/dist/workerGlobalPrefix.js +37 -5
- package/dist/workerGlobalPrefix.js.map +1 -0
- package/dist/workerTypes.d.ts +52 -0
- package/dist/workerTypes.d.ts.map +1 -0
- package/dist/workerTypes.js +24 -0
- package/dist/workerTypes.js.map +1 -0
- package/dist/workers.d.ts +69 -0
- package/dist/workers.d.ts.map +1 -0
- package/dist/workers.js +68 -4
- package/dist/workers.js.map +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -1
package/dist/dgram/mdns.js
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
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
|
|
1
24
|
import { BLUE, CYAN, db, er, GREEN, idn, MAGENTA, nf, rs } from 'node-ansi-logger';
|
|
25
|
+
// Utils imports
|
|
2
26
|
import { hasParameter } from '../utils/commandLine.js';
|
|
27
|
+
// Net imports
|
|
3
28
|
import { Multicast } from './multicast.js';
|
|
4
29
|
export var DnsRecordType;
|
|
5
30
|
(function (DnsRecordType) {
|
|
@@ -91,6 +116,7 @@ export var DnsRecordType;
|
|
|
91
116
|
DnsRecordType[DnsRecordType["DOA"] = 259] = "DOA";
|
|
92
117
|
DnsRecordType[DnsRecordType["AMTRELAY"] = 260] = "AMTRELAY";
|
|
93
118
|
DnsRecordType[DnsRecordType["ZONEVERSION"] = 261] = "ZONEVERSION";
|
|
119
|
+
// 262-32767 are unassigned/reserved
|
|
94
120
|
DnsRecordType[DnsRecordType["TA"] = 32768] = "TA";
|
|
95
121
|
DnsRecordType[DnsRecordType["DLV"] = 32769] = "DLV";
|
|
96
122
|
})(DnsRecordType || (DnsRecordType = {}));
|
|
@@ -104,12 +130,25 @@ export var DnsClass;
|
|
|
104
130
|
export var DnsClassFlag;
|
|
105
131
|
(function (DnsClassFlag) {
|
|
106
132
|
DnsClassFlag[DnsClassFlag["FLUSH"] = 32768] = "FLUSH";
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
|
107
134
|
DnsClassFlag[DnsClassFlag["QU"] = 32768] = "QU";
|
|
108
135
|
})(DnsClassFlag || (DnsClassFlag = {}));
|
|
109
136
|
export class Mdns extends Multicast {
|
|
110
137
|
deviceQueries = new Map();
|
|
111
138
|
deviceResponses = new Map();
|
|
112
139
|
filters = [];
|
|
140
|
+
/**
|
|
141
|
+
* Creates an instance of the Mdns class.
|
|
142
|
+
*
|
|
143
|
+
* @param {string} name - The internal name of the mDNS server for the logs.
|
|
144
|
+
* @param {string} multicastAddress - The multicast address for mDNS (i.e. 224.0.0.251 for udp4 or ff02::fb for udp6).
|
|
145
|
+
* @param {number} multicastPort - The port for mDNS (i.e. 5353).
|
|
146
|
+
* @param {('udp4' | 'udp6')} socketType - The type of socket to create (either 'udp4' or 'udp6').
|
|
147
|
+
* @param {boolean} [reuseAddr] - Whether to reuse the address. Defaults to true.
|
|
148
|
+
* @param {string} [interfaceName] - The optional name of the network interface to use.
|
|
149
|
+
* @param {string} [interfaceAddress] - The optional IP address of the network interface to use.
|
|
150
|
+
* @param {string} [outgoingInterfaceAddress] - The address of the outgoing network interface.
|
|
151
|
+
*/
|
|
113
152
|
constructor(name, multicastAddress, multicastPort, socketType, reuseAddr = true, interfaceName, interfaceAddress, outgoingInterfaceAddress) {
|
|
114
153
|
super(name, multicastAddress, multicastPort, socketType, reuseAddr, interfaceName, interfaceAddress, outgoingInterfaceAddress);
|
|
115
154
|
}
|
|
@@ -129,16 +168,17 @@ export class Mdns extends Multicast {
|
|
|
129
168
|
this.onQuery(rinfo, result);
|
|
130
169
|
}
|
|
131
170
|
else {
|
|
132
|
-
const ptr = result.answers?.find((record) => record.name === '_shelly._tcp.local' && record.type === 12) ||
|
|
133
|
-
result.answers?.find((record) => record.name === '_http._tcp.local' && record.type === 12) ||
|
|
134
|
-
result.answers?.find((record) => record.type === 12) ||
|
|
135
|
-
result.answers?.find((record) => record.type === 16) ||
|
|
171
|
+
const ptr = result.answers?.find((record) => record.name === '_shelly._tcp.local' && record.type === 12 /* DnsRecordType.PTR */) ||
|
|
172
|
+
result.answers?.find((record) => record.name === '_http._tcp.local' && record.type === 12 /* DnsRecordType.PTR */) ||
|
|
173
|
+
result.answers?.find((record) => record.type === 12 /* DnsRecordType.PTR */) ||
|
|
174
|
+
result.answers?.find((record) => record.type === 16 /* DnsRecordType.TXT */) ||
|
|
136
175
|
result.answers
|
|
137
176
|
? result.answers[0]
|
|
138
|
-
: undefined;
|
|
139
|
-
this.deviceResponses.set(rinfo.address, { rinfo, response: result, dataPTR: ptr?.type === 12 ? ptr?.data : ptr?.name });
|
|
177
|
+
: undefined; // Fallback to the first answer if no PTR or TXT found
|
|
178
|
+
this.deviceResponses.set(rinfo.address, { rinfo, response: result, dataPTR: ptr?.type === 12 /* DnsRecordType.PTR */ ? ptr?.data : ptr?.name });
|
|
140
179
|
this.onResponse(rinfo, result);
|
|
141
180
|
}
|
|
181
|
+
// Apply filters if any
|
|
142
182
|
if (this.filters.length > 0) {
|
|
143
183
|
this.log.debug(`mDNS message filtered out by filters: ${this.filters.join(', ')}`);
|
|
144
184
|
for (const filter of this.filters) {
|
|
@@ -160,20 +200,28 @@ export class Mdns extends Multicast {
|
|
|
160
200
|
this.log.error(`Error decoding mDNS message: ${error instanceof Error ? error.message : error}`);
|
|
161
201
|
}
|
|
162
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Decodes an mDNS message, including the header, question section, answer section,
|
|
205
|
+
* authority section, and additional section.
|
|
206
|
+
*
|
|
207
|
+
* @param {Buffer} msg - The raw mDNS message buffer.
|
|
208
|
+
* @returns {MdnsMessage} An object representing the decoded mDNS message.
|
|
209
|
+
* @throws {Error} if the message is too short.
|
|
210
|
+
*/
|
|
163
211
|
decodeMdnsMessage(msg) {
|
|
164
212
|
if (msg.length < 12) {
|
|
165
213
|
throw new Error('mDNS message too short');
|
|
166
214
|
}
|
|
167
215
|
const id = msg.readUInt16BE(0);
|
|
168
216
|
const flags = msg.readUInt16BE(2);
|
|
169
|
-
const qr = (flags & 0x8000) >> 15;
|
|
170
|
-
const opcode = (flags & 0x7800) >> 11;
|
|
171
|
-
const aa = Boolean(flags & 0x0400);
|
|
172
|
-
const tc = Boolean(flags & 0x0200);
|
|
173
|
-
const rd = Boolean(flags & 0x0100);
|
|
174
|
-
const ra = Boolean(flags & 0x0080);
|
|
175
|
-
const z = (flags & 0x0070) >> 4;
|
|
176
|
-
const rcode = flags & 0x000f;
|
|
217
|
+
const qr = (flags & 0x8000) >> 15; // Bit 15: 0=query, 1=response.
|
|
218
|
+
const opcode = (flags & 0x7800) >> 11; // Bits 14-11.
|
|
219
|
+
const aa = Boolean(flags & 0x0400); // Bit 10.
|
|
220
|
+
const tc = Boolean(flags & 0x0200); // Bit 9.
|
|
221
|
+
const rd = Boolean(flags & 0x0100); // Bit 8.
|
|
222
|
+
const ra = Boolean(flags & 0x0080); // Bit 7.
|
|
223
|
+
const z = (flags & 0x0070) >> 4; // Bits 6-4.
|
|
224
|
+
const rcode = flags & 0x000f; // Bits 3-0.
|
|
177
225
|
const qdCount = msg.readUInt16BE(4);
|
|
178
226
|
const anCount = msg.readUInt16BE(6);
|
|
179
227
|
const nsCount = msg.readUInt16BE(8);
|
|
@@ -198,6 +246,7 @@ export class Mdns extends Multicast {
|
|
|
198
246
|
additionals: [],
|
|
199
247
|
};
|
|
200
248
|
let offset = 12;
|
|
249
|
+
// Decode the question section.
|
|
201
250
|
for (let i = 0; i < qdCount; i++) {
|
|
202
251
|
const qnameResult = this.decodeDnsName(msg, offset);
|
|
203
252
|
const qname = qnameResult.name;
|
|
@@ -208,16 +257,19 @@ export class Mdns extends Multicast {
|
|
|
208
257
|
offset += 2;
|
|
209
258
|
mdnsMessage.questions?.push({ name: qname, type: qtype, class: qclass });
|
|
210
259
|
}
|
|
260
|
+
// Decode the answer section.
|
|
211
261
|
for (let i = 0; i < anCount; i++) {
|
|
212
262
|
const rrResult = this.decodeResourceRecord(msg, offset);
|
|
213
263
|
mdnsMessage.answers?.push(rrResult.record);
|
|
214
264
|
offset = rrResult.newOffset;
|
|
215
265
|
}
|
|
266
|
+
// Decode the authority (NS) section.
|
|
216
267
|
for (let i = 0; i < nsCount; i++) {
|
|
217
268
|
const rrResult = this.decodeResourceRecord(msg, offset);
|
|
218
269
|
mdnsMessage.authorities?.push(rrResult.record);
|
|
219
270
|
offset = rrResult.newOffset;
|
|
220
271
|
}
|
|
272
|
+
// Decode the additional records section.
|
|
221
273
|
for (let i = 0; i < arCount; i++) {
|
|
222
274
|
const rrResult = this.decodeResourceRecord(msg, offset);
|
|
223
275
|
mdnsMessage.additionals?.push(rrResult.record);
|
|
@@ -225,15 +277,25 @@ export class Mdns extends Multicast {
|
|
|
225
277
|
}
|
|
226
278
|
return mdnsMessage;
|
|
227
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* Decodes a DNS name from a buffer, handling compression.
|
|
282
|
+
*
|
|
283
|
+
* @param {Buffer} msg - The full mDNS message buffer.
|
|
284
|
+
* @param {number} offset - The offset at which the DNS name starts.
|
|
285
|
+
* @returns {{ name: string; newOffset: number }} An object with the decoded name and the new offset.
|
|
286
|
+
* @throws {Error} if the offset exceeds the buffer length or too many iterations are performed.
|
|
287
|
+
*/
|
|
228
288
|
decodeDnsName(msg, offset) {
|
|
229
289
|
const labels = [];
|
|
230
290
|
let jumped = false;
|
|
231
291
|
let originalOffset = offset;
|
|
232
|
-
let iterations = 0;
|
|
292
|
+
let iterations = 0; // Prevent infinite loops
|
|
233
293
|
while (true) {
|
|
294
|
+
// Safety guard: prevent infinite loops in malformed messages.
|
|
234
295
|
if (iterations++ > 1000) {
|
|
235
296
|
throw new Error('Too many iterations while decoding DNS name. Possible malformed message.');
|
|
236
297
|
}
|
|
298
|
+
// Check that offset is within buffer bounds.
|
|
237
299
|
if (offset >= msg.length) {
|
|
238
300
|
throw new Error('Offset exceeds buffer length while decoding DNS name.');
|
|
239
301
|
}
|
|
@@ -242,7 +304,9 @@ export class Mdns extends Multicast {
|
|
|
242
304
|
offset++;
|
|
243
305
|
break;
|
|
244
306
|
}
|
|
307
|
+
// Check for pointer (first two bits are 11)
|
|
245
308
|
if ((len & 0xc0) === 0xc0) {
|
|
309
|
+
// Ensure the pointer has two bytes available.
|
|
246
310
|
if (offset + 1 >= msg.length) {
|
|
247
311
|
throw new Error('Incomplete pointer encountered while decoding DNS name.');
|
|
248
312
|
}
|
|
@@ -255,6 +319,7 @@ export class Mdns extends Multicast {
|
|
|
255
319
|
continue;
|
|
256
320
|
}
|
|
257
321
|
offset++;
|
|
322
|
+
// Check that the label length doesn't go beyond the buffer.
|
|
258
323
|
if (offset + len > msg.length) {
|
|
259
324
|
throw new Error('Label length exceeds buffer bounds while decoding DNS name.');
|
|
260
325
|
}
|
|
@@ -263,6 +328,15 @@ export class Mdns extends Multicast {
|
|
|
263
328
|
}
|
|
264
329
|
return { name: labels.join('.'), newOffset: jumped ? originalOffset : offset };
|
|
265
330
|
}
|
|
331
|
+
/**
|
|
332
|
+
* Encodes a domain name into the DNS label format.
|
|
333
|
+
*
|
|
334
|
+
* For example, "example.local" becomes:
|
|
335
|
+
* [7] "example" [5] "local" [0]
|
|
336
|
+
*
|
|
337
|
+
* @param {string} name - The domain name to encode.
|
|
338
|
+
* @returns {Buffer} The encoded domain name as a Buffer.
|
|
339
|
+
*/
|
|
266
340
|
encodeDnsName(name) {
|
|
267
341
|
const labels = name.split('.');
|
|
268
342
|
const buffers = labels.map((label) => {
|
|
@@ -270,8 +344,25 @@ export class Mdns extends Multicast {
|
|
|
270
344
|
lenBuf.writeUInt8(label.length, 0);
|
|
271
345
|
return Buffer.concat([lenBuf, Buffer.from(label)]);
|
|
272
346
|
});
|
|
347
|
+
// Append the null byte to terminate the name.
|
|
273
348
|
return Buffer.concat([...buffers, Buffer.from([0])]);
|
|
274
349
|
}
|
|
350
|
+
/**
|
|
351
|
+
* Encodes TXT record RDATA.
|
|
352
|
+
*
|
|
353
|
+
* In DNS/mDNS, TXT RDATA is a sequence of one or more <character-string>,
|
|
354
|
+
* each encoded as: [length byte][UTF-8 bytes].
|
|
355
|
+
*
|
|
356
|
+
* @param {string[]} txt - Array of TXT entries, e.g. ["key=value", "path=/"].
|
|
357
|
+
* @returns {Buffer} Encoded TXT RDATA.
|
|
358
|
+
* @throws {Error} If any entry exceeds 255 bytes.
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* const txtRdata = mdns.encodeTxtRdata(['txtvers=1', 'path=/']);
|
|
362
|
+
* mdns.sendResponse([
|
|
363
|
+
* { name: 'example._http._tcp.local', rtype: DnsRecordType.TXT, rclass: DnsClass.IN | DnsClassFlag.FLUSH, ttl: 120, rdata: txtRdata },
|
|
364
|
+
* ]);
|
|
365
|
+
*/
|
|
275
366
|
encodeTxtRdata(txt) {
|
|
276
367
|
const parts = txt.map((entry) => {
|
|
277
368
|
const value = Buffer.from(entry, 'utf8');
|
|
@@ -281,6 +372,21 @@ export class Mdns extends Multicast {
|
|
|
281
372
|
});
|
|
282
373
|
return Buffer.concat(parts);
|
|
283
374
|
}
|
|
375
|
+
/**
|
|
376
|
+
* Encodes SRV record RDATA.
|
|
377
|
+
*
|
|
378
|
+
* SRV RDATA layout (RFC 2782):
|
|
379
|
+
* - priority (2 bytes)
|
|
380
|
+
* - weight (2 bytes)
|
|
381
|
+
* - port (2 bytes)
|
|
382
|
+
* - target (DNS name)
|
|
383
|
+
*
|
|
384
|
+
* @param {number} priority - SRV priority.
|
|
385
|
+
* @param {number} weight - SRV weight.
|
|
386
|
+
* @param {number} port - Service port.
|
|
387
|
+
* @param {string} target - Target hostname (e.g. "matterbridge.local").
|
|
388
|
+
* @returns {Buffer} Encoded SRV RDATA.
|
|
389
|
+
*/
|
|
284
390
|
encodeSrvRdata(priority, weight, port, target) {
|
|
285
391
|
const fixed = Buffer.alloc(6);
|
|
286
392
|
fixed.writeUInt16BE(priority, 0);
|
|
@@ -288,6 +394,13 @@ export class Mdns extends Multicast {
|
|
|
288
394
|
fixed.writeUInt16BE(port, 4);
|
|
289
395
|
return Buffer.concat([fixed, this.encodeDnsName(target)]);
|
|
290
396
|
}
|
|
397
|
+
/**
|
|
398
|
+
* Encodes an IPv4 address for an A record RDATA (4 bytes).
|
|
399
|
+
*
|
|
400
|
+
* @param {string} ipv4 - IPv4 address, e.g. "192.168.1.10".
|
|
401
|
+
* @returns {Buffer} 4-byte buffer.
|
|
402
|
+
* @throws {Error} If the address is not a valid dotted-quad.
|
|
403
|
+
*/
|
|
291
404
|
encodeA(ipv4) {
|
|
292
405
|
const parts = ipv4.split('.').map((p) => Number(p));
|
|
293
406
|
if (parts.length !== 4 || parts.some((n) => !Number.isInteger(n) || n < 0 || n > 255)) {
|
|
@@ -295,8 +408,19 @@ export class Mdns extends Multicast {
|
|
|
295
408
|
}
|
|
296
409
|
return Buffer.from(parts);
|
|
297
410
|
}
|
|
411
|
+
/**
|
|
412
|
+
* Encodes an IPv6 address for an AAAA record RDATA (16 bytes).
|
|
413
|
+
*
|
|
414
|
+
* Supports the "::" zero-compression form and ignores an optional scope id
|
|
415
|
+
* suffix (e.g. "fe80::1%12" or "fe80::1%eth0").
|
|
416
|
+
*
|
|
417
|
+
* @param {string} ipv6WithOptionalScope - IPv6 address (optionally with scope id).
|
|
418
|
+
* @returns {Buffer} 16-byte buffer.
|
|
419
|
+
* @throws {Error} If the address is not a valid IPv6 literal.
|
|
420
|
+
*/
|
|
298
421
|
encodeAAAA(ipv6WithOptionalScope) {
|
|
299
422
|
const ipv6 = ipv6WithOptionalScope.split('%')[0];
|
|
423
|
+
// Expand IPv6 to 8 groups of 16-bit words.
|
|
300
424
|
const [left, right] = ipv6.split('::');
|
|
301
425
|
const leftParts = left ? left.split(':').filter(Boolean) : [];
|
|
302
426
|
const rightParts = right ? right.split(':').filter(Boolean) : [];
|
|
@@ -322,10 +446,19 @@ export class Mdns extends Multicast {
|
|
|
322
446
|
return [(word >> 8) & 0xff, word & 0xff];
|
|
323
447
|
}));
|
|
324
448
|
}
|
|
449
|
+
/**
|
|
450
|
+
* Decodes a DNS resource record.
|
|
451
|
+
*
|
|
452
|
+
* @param {Buffer} msg - The full mDNS message buffer.
|
|
453
|
+
* @param {number} offset - The offset at which the resource record starts.
|
|
454
|
+
* @returns {{ record: MdnsRecord; newOffset: number }} An object containing the decoded record and the new offset.
|
|
455
|
+
*/
|
|
325
456
|
decodeResourceRecord(msg, offset) {
|
|
457
|
+
// Decode the NAME field (which may be compressed)
|
|
326
458
|
const nameResult = this.decodeDnsName(msg, offset);
|
|
327
459
|
const name = nameResult.name;
|
|
328
460
|
offset = nameResult.newOffset;
|
|
461
|
+
// Read TYPE (16 bits), CLASS (16 bits), TTL (32 bits), and RDLENGTH (16 bits)
|
|
329
462
|
const type = msg.readUInt16BE(offset);
|
|
330
463
|
offset += 2;
|
|
331
464
|
const rrclass = msg.readUInt16BE(offset);
|
|
@@ -335,12 +468,14 @@ export class Mdns extends Multicast {
|
|
|
335
468
|
const rdlength = msg.readUInt16BE(offset);
|
|
336
469
|
offset += 2;
|
|
337
470
|
let data = '';
|
|
338
|
-
if (type === 12) {
|
|
471
|
+
if (type === 12 /* DnsRecordType.PTR */) {
|
|
472
|
+
// PTR record (type 12): decode its RDATA as a domain name.
|
|
339
473
|
const ptrResult = this.decodeDnsName(msg, offset);
|
|
340
474
|
data = ptrResult.name;
|
|
341
475
|
offset += rdlength;
|
|
342
476
|
}
|
|
343
|
-
else if (type === 16) {
|
|
477
|
+
else if (type === 16 /* DnsRecordType.TXT */) {
|
|
478
|
+
// TXT record: may consist of one or more length-prefixed strings.
|
|
344
479
|
const txtStrings = [];
|
|
345
480
|
const end = offset + rdlength;
|
|
346
481
|
while (offset < end) {
|
|
@@ -352,7 +487,8 @@ export class Mdns extends Multicast {
|
|
|
352
487
|
}
|
|
353
488
|
data = txtStrings.join(', ');
|
|
354
489
|
}
|
|
355
|
-
else if (type === 33) {
|
|
490
|
+
else if (type === 33 /* DnsRecordType.SRV */) {
|
|
491
|
+
// SRV record (type === 33): consists of 2 bytes for priority, 2 for weight, 2 for port, followed by the target domain name.
|
|
356
492
|
const priority = msg.readUInt16BE(offset);
|
|
357
493
|
const weight = msg.readUInt16BE(offset + 2);
|
|
358
494
|
const port = msg.readUInt16BE(offset + 4);
|
|
@@ -366,13 +502,16 @@ export class Mdns extends Multicast {
|
|
|
366
502
|
});
|
|
367
503
|
offset = srvTargetResult.newOffset;
|
|
368
504
|
}
|
|
369
|
-
else if (type === 1) {
|
|
505
|
+
else if (type === 1 /* DnsRecordType.A */) {
|
|
506
|
+
// A record (type 1): an IPv4 address stored in 4 bytes.
|
|
370
507
|
const ipBytes = msg.slice(offset, offset + 4);
|
|
371
508
|
data = Array.from(ipBytes).join('.');
|
|
372
509
|
offset += 4;
|
|
373
510
|
}
|
|
374
|
-
else if (type === 28) {
|
|
511
|
+
else if (type === 28 /* DnsRecordType.AAAA */) {
|
|
512
|
+
// AAAA record (type 28): IPv6 address stored in 16 bytes.
|
|
375
513
|
const ipBytes = msg.slice(offset, offset + 16);
|
|
514
|
+
// Convert the 16 bytes into an IPv6 address string (colon-separated)
|
|
376
515
|
const ipv6Parts = [];
|
|
377
516
|
for (let i = 0; i < 16; i += 2) {
|
|
378
517
|
ipv6Parts.push(ipBytes.readUInt16BE(i).toString(16));
|
|
@@ -380,10 +519,14 @@ export class Mdns extends Multicast {
|
|
|
380
519
|
data = ipv6Parts.join(':');
|
|
381
520
|
offset += 16;
|
|
382
521
|
}
|
|
383
|
-
else if (type === 47) {
|
|
522
|
+
else if (type === 47 /* DnsRecordType.NSEC */) {
|
|
523
|
+
// NSEC record: RDATA consists of:
|
|
524
|
+
// - Next Domain Name (in DNS label format)
|
|
525
|
+
// - Type Bit Maps (variable length)
|
|
384
526
|
const { name: nextDomain, newOffset } = this.decodeDnsName(msg, offset);
|
|
385
527
|
const nextDomainLength = newOffset - offset;
|
|
386
528
|
offset = newOffset;
|
|
529
|
+
// Calculate the remaining length for the type bit maps.
|
|
387
530
|
const bitmapLength = rdlength - nextDomainLength;
|
|
388
531
|
const bitmapData = msg.slice(offset, offset + bitmapLength);
|
|
389
532
|
const types = [];
|
|
@@ -410,6 +553,7 @@ export class Mdns extends Multicast {
|
|
|
410
553
|
offset += bitmapLength;
|
|
411
554
|
}
|
|
412
555
|
else {
|
|
556
|
+
// Fall back
|
|
413
557
|
data = msg.slice(offset, offset + rdlength).toString('hex');
|
|
414
558
|
offset += rdlength;
|
|
415
559
|
}
|
|
@@ -418,19 +562,30 @@ export class Mdns extends Multicast {
|
|
|
418
562
|
newOffset: offset,
|
|
419
563
|
};
|
|
420
564
|
}
|
|
565
|
+
/**
|
|
566
|
+
* Sends a DNS query with multiple questions.
|
|
567
|
+
*
|
|
568
|
+
* @param {Array<{ name: string; type: number; class: number; unicastResponse?: boolean }>} questions - Array of questions
|
|
569
|
+
* to include in the query.
|
|
570
|
+
* @returns {Buffer<ArrayBuffer>} The constructed query buffer.
|
|
571
|
+
*
|
|
572
|
+
* @remarks
|
|
573
|
+
* Each question should have a name (e.g., "_http._tcp.local"), type (e.g., DnsRecordType.PTR), class (e.g., DnsClass.IN),
|
|
574
|
+
* and an optional unicastResponse flag (this will add the DnsClassFlag.QU flag to the query).
|
|
575
|
+
*/
|
|
421
576
|
sendQuery(questions) {
|
|
422
577
|
const header = Buffer.alloc(12);
|
|
423
|
-
header.writeUInt16BE(0, 0);
|
|
424
|
-
header.writeUInt16BE(0, 2);
|
|
425
|
-
header.writeUInt16BE(questions.length, 4);
|
|
426
|
-
header.writeUInt16BE(0, 6);
|
|
427
|
-
header.writeUInt16BE(0, 8);
|
|
428
|
-
header.writeUInt16BE(0, 10);
|
|
578
|
+
header.writeUInt16BE(0, 0); // ID
|
|
579
|
+
header.writeUInt16BE(0, 2); // Flags
|
|
580
|
+
header.writeUInt16BE(questions.length, 4); // QDCOUNT
|
|
581
|
+
header.writeUInt16BE(0, 6); // ANCOUNT
|
|
582
|
+
header.writeUInt16BE(0, 8); // NSCOUNT
|
|
583
|
+
header.writeUInt16BE(0, 10); // ARCOUNT
|
|
429
584
|
const questionBuffers = questions.map(({ name, type: qtype, class: qclass, unicastResponse = false }) => {
|
|
430
585
|
const qname = this.encodeDnsName(name);
|
|
431
586
|
const qfields = Buffer.alloc(4);
|
|
432
587
|
qfields.writeUInt16BE(qtype, 0);
|
|
433
|
-
qfields.writeUInt16BE(unicastResponse ? qclass | 32768 : qclass, 2);
|
|
588
|
+
qfields.writeUInt16BE(unicastResponse ? qclass | 32768 /* DnsClassFlag.QU */ : qclass, 2);
|
|
434
589
|
return Buffer.concat([qname, qfields]);
|
|
435
590
|
});
|
|
436
591
|
const query = Buffer.concat([header, ...questionBuffers]);
|
|
@@ -453,31 +608,52 @@ export class Mdns extends Multicast {
|
|
|
453
608
|
});
|
|
454
609
|
return query;
|
|
455
610
|
}
|
|
611
|
+
/**
|
|
612
|
+
* Constructs an mDNS response packet and sends it to the multicast address and port.
|
|
613
|
+
*
|
|
614
|
+
* @param {Array<{ name: string; rtype: number; rclass: number; ttl: number; rdata: Buffer }>} answers - Array of answer records.
|
|
615
|
+
* @returns {Buffer<ArrayBuffer>} The constructed response buffer.
|
|
616
|
+
*
|
|
617
|
+
* @example
|
|
618
|
+
* const ptrRdata = mdnsIpv4.encodeDnsName('matterbridge._http._tcp.local');
|
|
619
|
+
* mdnsIpv4.sendResponse([{ name: '_http._tcp.local', rtype: DnsRecordType.PTR, rclass: DnsClass.IN, ttl: 120, rdata: ptrRdata }]);
|
|
620
|
+
*/
|
|
456
621
|
sendResponse(answers) {
|
|
457
622
|
if (!Array.isArray(answers) || answers.length === 0) {
|
|
458
623
|
throw new Error('sendResponse requires a non-empty answers array');
|
|
459
624
|
}
|
|
625
|
+
// Create a 12-byte DNS header.
|
|
460
626
|
const header = Buffer.alloc(12);
|
|
461
|
-
header.writeUInt16BE(0, 0);
|
|
627
|
+
header.writeUInt16BE(0, 0); // ID is set to 0 in mDNS.
|
|
628
|
+
// Set flags: QR (response) bit and AA (authoritative answer) bit.
|
|
462
629
|
header.writeUInt16BE(0x8400, 2);
|
|
463
|
-
header.writeUInt16BE(0, 4);
|
|
464
|
-
header.writeUInt16BE(answers.length, 6);
|
|
465
|
-
header.writeUInt16BE(0, 8);
|
|
466
|
-
header.writeUInt16BE(0, 10);
|
|
630
|
+
header.writeUInt16BE(0, 4); // QDCOUNT: 0 questions in response.
|
|
631
|
+
header.writeUInt16BE(answers.length, 6); // ANCOUNT: number of answer records.
|
|
632
|
+
header.writeUInt16BE(0, 8); // NSCOUNT: 0 authority records.
|
|
633
|
+
header.writeUInt16BE(0, 10); // ARCOUNT: 0 additional records.
|
|
467
634
|
const answerBuffers = answers.map(({ name, rtype, rclass, ttl, rdata }) => {
|
|
635
|
+
// Encode the domain name in DNS label format.
|
|
468
636
|
const aname = this.encodeDnsName(name);
|
|
637
|
+
// Prepare the fixed part of the answer record:
|
|
638
|
+
// - 2 bytes for qtype,
|
|
639
|
+
// - 2 bytes for qclass,
|
|
640
|
+
// - 4 bytes for TTL,
|
|
641
|
+
// - 2 bytes for RDLENGTH (length of the rdata).
|
|
469
642
|
const answerFixed = Buffer.alloc(10);
|
|
470
|
-
answerFixed.writeUInt16BE(rtype, 0);
|
|
471
|
-
answerFixed.writeUInt16BE(rclass, 2);
|
|
472
|
-
answerFixed.writeUInt32BE(ttl, 4);
|
|
473
|
-
answerFixed.writeUInt16BE(rdata.length, 8);
|
|
643
|
+
answerFixed.writeUInt16BE(rtype, 0); // Record type.
|
|
644
|
+
answerFixed.writeUInt16BE(rclass, 2); // Record class.
|
|
645
|
+
answerFixed.writeUInt32BE(ttl, 4); // Time-to-live.
|
|
646
|
+
answerFixed.writeUInt16BE(rdata.length, 8); // RDLENGTH.
|
|
647
|
+
// Concatenate the answer: encoded name, fixed fields, and resource data.
|
|
474
648
|
return Buffer.concat([aname, answerFixed, rdata]);
|
|
475
649
|
});
|
|
650
|
+
// Concatenate header and answers to form the complete mDNS response packet.
|
|
476
651
|
const response = Buffer.concat([header, ...answerBuffers]);
|
|
477
652
|
if (hasParameter('v') || hasParameter('verbose')) {
|
|
478
653
|
const decoded = this.decodeMdnsMessage(response);
|
|
479
654
|
this.logMdnsMessage(decoded);
|
|
480
655
|
}
|
|
656
|
+
// Send the response packet via the socket.
|
|
481
657
|
this.socket.send(response, 0, response.length, this.multicastPort, this.multicastAddress, (error) => {
|
|
482
658
|
if (error) {
|
|
483
659
|
const items = answers.map((a) => `- name ${MAGENTA}${a.name}${er} type ${MAGENTA}${this.dnsTypeToString(a.rtype)}${er} class ${MAGENTA}${this.dnsResponseClassToString(a.rclass)}${er} ttl ${MAGENTA}${a.ttl}${er}`).join('\n');
|
|
@@ -492,116 +668,128 @@ export class Mdns extends Multicast {
|
|
|
492
668
|
});
|
|
493
669
|
return response;
|
|
494
670
|
}
|
|
671
|
+
/**
|
|
672
|
+
* Converts a DNS record type numeric value to its string representation.
|
|
673
|
+
*
|
|
674
|
+
* @param {number} type - The numeric DNS record type.
|
|
675
|
+
* @returns {string} The string representation of the record type.
|
|
676
|
+
*/
|
|
495
677
|
dnsTypeToString(type) {
|
|
496
678
|
const typeMap = {
|
|
497
|
-
[1]: 'A',
|
|
498
|
-
[2]: 'NS',
|
|
499
|
-
[3]: 'MD',
|
|
500
|
-
[4]: 'MF',
|
|
501
|
-
[5]: 'CNAME',
|
|
502
|
-
[6]: 'SOA',
|
|
503
|
-
[7]: 'MB',
|
|
504
|
-
[8]: 'MG',
|
|
505
|
-
[9]: 'MR',
|
|
506
|
-
[10]: 'NULL',
|
|
507
|
-
[11]: 'WKS',
|
|
508
|
-
[12]: 'PTR',
|
|
509
|
-
[13]: 'HINFO',
|
|
510
|
-
[14]: 'MINFO',
|
|
511
|
-
[15]: 'MX',
|
|
512
|
-
[16]: 'TXT',
|
|
513
|
-
[17]: 'RP',
|
|
514
|
-
[18]: 'AFSDB',
|
|
515
|
-
[19]: 'X25',
|
|
516
|
-
[20]: 'ISDN',
|
|
517
|
-
[21]: 'RT',
|
|
518
|
-
[22]: 'NSAP',
|
|
519
|
-
[23]: 'NSAP_PTR',
|
|
520
|
-
[24]: 'SIG',
|
|
521
|
-
[25]: 'KEY',
|
|
522
|
-
[26]: 'PX',
|
|
523
|
-
[27]: 'GPOS',
|
|
524
|
-
[28]: 'AAAA',
|
|
525
|
-
[29]: 'LOC',
|
|
526
|
-
[30]: 'NXT',
|
|
527
|
-
[31]: 'EID',
|
|
528
|
-
[32]: 'NIMLOC',
|
|
529
|
-
[33]: 'SRV',
|
|
530
|
-
[34]: 'ATMA',
|
|
531
|
-
[35]: 'NAPTR',
|
|
532
|
-
[36]: 'KX',
|
|
533
|
-
[37]: 'CERT',
|
|
534
|
-
[38]: 'A6',
|
|
535
|
-
[39]: 'DNAME',
|
|
536
|
-
[40]: 'SINK',
|
|
537
|
-
[41]: 'OPT',
|
|
538
|
-
[42]: 'APL',
|
|
539
|
-
[43]: 'DS',
|
|
540
|
-
[44]: 'SSHFP',
|
|
541
|
-
[45]: 'IPSECKEY',
|
|
542
|
-
[46]: 'RRSIG',
|
|
543
|
-
[47]: 'NSEC',
|
|
544
|
-
[48]: 'DNSKEY',
|
|
545
|
-
[49]: 'DHCID',
|
|
546
|
-
[50]: 'NSEC3',
|
|
547
|
-
[51]: 'NSEC3PARAM',
|
|
548
|
-
[52]: 'TLSA',
|
|
549
|
-
[53]: 'SMIMEA',
|
|
550
|
-
[55]: 'HIP',
|
|
551
|
-
[56]: 'NINFO',
|
|
552
|
-
[57]: 'RKEY',
|
|
553
|
-
[58]: 'TALINK',
|
|
554
|
-
[59]: 'CDS',
|
|
555
|
-
[60]: 'CDNSKEY',
|
|
556
|
-
[61]: 'OPENPGPKEY',
|
|
557
|
-
[62]: 'CSYNC',
|
|
558
|
-
[63]: 'ZONEMD',
|
|
559
|
-
[64]: 'SVCB',
|
|
560
|
-
[65]: 'HTTPS',
|
|
561
|
-
[99]: 'SPF',
|
|
562
|
-
[100]: 'UINFO',
|
|
563
|
-
[101]: 'UID',
|
|
564
|
-
[102]: 'GID',
|
|
565
|
-
[103]: 'UNSPEC',
|
|
566
|
-
[104]: 'NID',
|
|
567
|
-
[105]: 'L32',
|
|
568
|
-
[106]: 'L64',
|
|
569
|
-
[107]: 'LP',
|
|
570
|
-
[108]: 'EUI48',
|
|
571
|
-
[109]: 'EUI64',
|
|
572
|
-
[249]: 'TKEY',
|
|
573
|
-
[250]: 'TSIG',
|
|
574
|
-
[251]: 'IXFR',
|
|
575
|
-
[252]: 'AXFR',
|
|
576
|
-
[253]: 'MAILB',
|
|
577
|
-
[254]: 'MAILA',
|
|
578
|
-
[255]: 'ANY',
|
|
579
|
-
[256]: 'URI',
|
|
580
|
-
[257]: 'CAA',
|
|
581
|
-
[258]: 'AVC',
|
|
582
|
-
[259]: 'DOA',
|
|
583
|
-
[260]: 'AMTRELAY',
|
|
584
|
-
[261]: 'ZONEVERSION',
|
|
585
|
-
[32768]: 'TA',
|
|
586
|
-
[32769]: 'DLV',
|
|
679
|
+
[1 /* DnsRecordType.A */]: 'A',
|
|
680
|
+
[2 /* DnsRecordType.NS */]: 'NS',
|
|
681
|
+
[3 /* DnsRecordType.MD */]: 'MD',
|
|
682
|
+
[4 /* DnsRecordType.MF */]: 'MF',
|
|
683
|
+
[5 /* DnsRecordType.CNAME */]: 'CNAME',
|
|
684
|
+
[6 /* DnsRecordType.SOA */]: 'SOA',
|
|
685
|
+
[7 /* DnsRecordType.MB */]: 'MB',
|
|
686
|
+
[8 /* DnsRecordType.MG */]: 'MG',
|
|
687
|
+
[9 /* DnsRecordType.MR */]: 'MR',
|
|
688
|
+
[10 /* DnsRecordType.NULL */]: 'NULL',
|
|
689
|
+
[11 /* DnsRecordType.WKS */]: 'WKS',
|
|
690
|
+
[12 /* DnsRecordType.PTR */]: 'PTR',
|
|
691
|
+
[13 /* DnsRecordType.HINFO */]: 'HINFO',
|
|
692
|
+
[14 /* DnsRecordType.MINFO */]: 'MINFO',
|
|
693
|
+
[15 /* DnsRecordType.MX */]: 'MX',
|
|
694
|
+
[16 /* DnsRecordType.TXT */]: 'TXT',
|
|
695
|
+
[17 /* DnsRecordType.RP */]: 'RP',
|
|
696
|
+
[18 /* DnsRecordType.AFSDB */]: 'AFSDB',
|
|
697
|
+
[19 /* DnsRecordType.X25 */]: 'X25',
|
|
698
|
+
[20 /* DnsRecordType.ISDN */]: 'ISDN',
|
|
699
|
+
[21 /* DnsRecordType.RT */]: 'RT',
|
|
700
|
+
[22 /* DnsRecordType.NSAP */]: 'NSAP',
|
|
701
|
+
[23 /* DnsRecordType.NSAP_PTR */]: 'NSAP_PTR',
|
|
702
|
+
[24 /* DnsRecordType.SIG */]: 'SIG',
|
|
703
|
+
[25 /* DnsRecordType.KEY */]: 'KEY',
|
|
704
|
+
[26 /* DnsRecordType.PX */]: 'PX',
|
|
705
|
+
[27 /* DnsRecordType.GPOS */]: 'GPOS',
|
|
706
|
+
[28 /* DnsRecordType.AAAA */]: 'AAAA',
|
|
707
|
+
[29 /* DnsRecordType.LOC */]: 'LOC',
|
|
708
|
+
[30 /* DnsRecordType.NXT */]: 'NXT',
|
|
709
|
+
[31 /* DnsRecordType.EID */]: 'EID',
|
|
710
|
+
[32 /* DnsRecordType.NIMLOC */]: 'NIMLOC',
|
|
711
|
+
[33 /* DnsRecordType.SRV */]: 'SRV',
|
|
712
|
+
[34 /* DnsRecordType.ATMA */]: 'ATMA',
|
|
713
|
+
[35 /* DnsRecordType.NAPTR */]: 'NAPTR',
|
|
714
|
+
[36 /* DnsRecordType.KX */]: 'KX',
|
|
715
|
+
[37 /* DnsRecordType.CERT */]: 'CERT',
|
|
716
|
+
[38 /* DnsRecordType.A6 */]: 'A6',
|
|
717
|
+
[39 /* DnsRecordType.DNAME */]: 'DNAME',
|
|
718
|
+
[40 /* DnsRecordType.SINK */]: 'SINK',
|
|
719
|
+
[41 /* DnsRecordType.OPT */]: 'OPT',
|
|
720
|
+
[42 /* DnsRecordType.APL */]: 'APL',
|
|
721
|
+
[43 /* DnsRecordType.DS */]: 'DS',
|
|
722
|
+
[44 /* DnsRecordType.SSHFP */]: 'SSHFP',
|
|
723
|
+
[45 /* DnsRecordType.IPSECKEY */]: 'IPSECKEY',
|
|
724
|
+
[46 /* DnsRecordType.RRSIG */]: 'RRSIG',
|
|
725
|
+
[47 /* DnsRecordType.NSEC */]: 'NSEC',
|
|
726
|
+
[48 /* DnsRecordType.DNSKEY */]: 'DNSKEY',
|
|
727
|
+
[49 /* DnsRecordType.DHCID */]: 'DHCID',
|
|
728
|
+
[50 /* DnsRecordType.NSEC3 */]: 'NSEC3',
|
|
729
|
+
[51 /* DnsRecordType.NSEC3PARAM */]: 'NSEC3PARAM',
|
|
730
|
+
[52 /* DnsRecordType.TLSA */]: 'TLSA',
|
|
731
|
+
[53 /* DnsRecordType.SMIMEA */]: 'SMIMEA',
|
|
732
|
+
[55 /* DnsRecordType.HIP */]: 'HIP',
|
|
733
|
+
[56 /* DnsRecordType.NINFO */]: 'NINFO',
|
|
734
|
+
[57 /* DnsRecordType.RKEY */]: 'RKEY',
|
|
735
|
+
[58 /* DnsRecordType.TALINK */]: 'TALINK',
|
|
736
|
+
[59 /* DnsRecordType.CDS */]: 'CDS',
|
|
737
|
+
[60 /* DnsRecordType.CDNSKEY */]: 'CDNSKEY',
|
|
738
|
+
[61 /* DnsRecordType.OPENPGPKEY */]: 'OPENPGPKEY',
|
|
739
|
+
[62 /* DnsRecordType.CSYNC */]: 'CSYNC',
|
|
740
|
+
[63 /* DnsRecordType.ZONEMD */]: 'ZONEMD',
|
|
741
|
+
[64 /* DnsRecordType.SVCB */]: 'SVCB',
|
|
742
|
+
[65 /* DnsRecordType.HTTPS */]: 'HTTPS',
|
|
743
|
+
[99 /* DnsRecordType.SPF */]: 'SPF',
|
|
744
|
+
[100 /* DnsRecordType.UINFO */]: 'UINFO',
|
|
745
|
+
[101 /* DnsRecordType.UID */]: 'UID',
|
|
746
|
+
[102 /* DnsRecordType.GID */]: 'GID',
|
|
747
|
+
[103 /* DnsRecordType.UNSPEC */]: 'UNSPEC',
|
|
748
|
+
[104 /* DnsRecordType.NID */]: 'NID',
|
|
749
|
+
[105 /* DnsRecordType.L32 */]: 'L32',
|
|
750
|
+
[106 /* DnsRecordType.L64 */]: 'L64',
|
|
751
|
+
[107 /* DnsRecordType.LP */]: 'LP',
|
|
752
|
+
[108 /* DnsRecordType.EUI48 */]: 'EUI48',
|
|
753
|
+
[109 /* DnsRecordType.EUI64 */]: 'EUI64',
|
|
754
|
+
[249 /* DnsRecordType.TKEY */]: 'TKEY',
|
|
755
|
+
[250 /* DnsRecordType.TSIG */]: 'TSIG',
|
|
756
|
+
[251 /* DnsRecordType.IXFR */]: 'IXFR',
|
|
757
|
+
[252 /* DnsRecordType.AXFR */]: 'AXFR',
|
|
758
|
+
[253 /* DnsRecordType.MAILB */]: 'MAILB',
|
|
759
|
+
[254 /* DnsRecordType.MAILA */]: 'MAILA',
|
|
760
|
+
[255 /* DnsRecordType.ANY */]: 'ANY',
|
|
761
|
+
[256 /* DnsRecordType.URI */]: 'URI',
|
|
762
|
+
[257 /* DnsRecordType.CAA */]: 'CAA',
|
|
763
|
+
[258 /* DnsRecordType.AVC */]: 'AVC',
|
|
764
|
+
[259 /* DnsRecordType.DOA */]: 'DOA',
|
|
765
|
+
[260 /* DnsRecordType.AMTRELAY */]: 'AMTRELAY',
|
|
766
|
+
[261 /* DnsRecordType.ZONEVERSION */]: 'ZONEVERSION',
|
|
767
|
+
[32768 /* DnsRecordType.TA */]: 'TA',
|
|
768
|
+
[32769 /* DnsRecordType.DLV */]: 'DLV',
|
|
587
769
|
};
|
|
588
770
|
return typeMap[type] ?? `TYPE${type}`;
|
|
589
771
|
}
|
|
772
|
+
/**
|
|
773
|
+
* Converts a DNS response class numeric value to its string representation.
|
|
774
|
+
*
|
|
775
|
+
* @param {number} cls - The numeric DNS class.
|
|
776
|
+
* @returns {string} The string representation of the DNS class.
|
|
777
|
+
*/
|
|
590
778
|
dnsResponseClassToString(cls) {
|
|
591
|
-
const isFlush = !!(cls & 32768);
|
|
779
|
+
const isFlush = !!(cls & 32768 /* DnsClassFlag.FLUSH */);
|
|
592
780
|
const baseClass = cls & 0x7fff;
|
|
593
781
|
let classStr;
|
|
594
782
|
switch (baseClass) {
|
|
595
|
-
case 1
|
|
783
|
+
case 1 /* DnsClass.IN */:
|
|
596
784
|
classStr = 'IN';
|
|
597
785
|
break;
|
|
598
|
-
case 3
|
|
786
|
+
case 3 /* DnsClass.CH */:
|
|
599
787
|
classStr = 'CH';
|
|
600
788
|
break;
|
|
601
|
-
case 4
|
|
789
|
+
case 4 /* DnsClass.HS */:
|
|
602
790
|
classStr = 'HS';
|
|
603
791
|
break;
|
|
604
|
-
case 255
|
|
792
|
+
case 255 /* DnsClass.ANY */:
|
|
605
793
|
classStr = 'ANY';
|
|
606
794
|
break;
|
|
607
795
|
default:
|
|
@@ -609,21 +797,28 @@ export class Mdns extends Multicast {
|
|
|
609
797
|
}
|
|
610
798
|
return isFlush ? `${classStr}|FLUSH` : classStr;
|
|
611
799
|
}
|
|
800
|
+
/**
|
|
801
|
+
* Converts a DNS question class to a human-readable string.
|
|
802
|
+
* Adds support for mDNS QU (unicast-response) bit.
|
|
803
|
+
*
|
|
804
|
+
* @param {number} cls - The numeric question class.
|
|
805
|
+
* @returns {string} The string representation, e.g. "IN|QU"
|
|
806
|
+
*/
|
|
612
807
|
dnsQuestionClassToString(cls) {
|
|
613
|
-
const isQU = !!(cls & 32768);
|
|
808
|
+
const isQU = !!(cls & 32768 /* DnsClassFlag.QU */);
|
|
614
809
|
const baseClass = cls & 0x7fff;
|
|
615
810
|
let classStr;
|
|
616
811
|
switch (baseClass) {
|
|
617
|
-
case 1
|
|
812
|
+
case 1 /* DnsClass.IN */:
|
|
618
813
|
classStr = 'IN';
|
|
619
814
|
break;
|
|
620
|
-
case 3
|
|
815
|
+
case 3 /* DnsClass.CH */:
|
|
621
816
|
classStr = 'CH';
|
|
622
817
|
break;
|
|
623
|
-
case 4
|
|
818
|
+
case 4 /* DnsClass.HS */:
|
|
624
819
|
classStr = 'HS';
|
|
625
820
|
break;
|
|
626
|
-
case 255
|
|
821
|
+
case 255 /* DnsClass.ANY */:
|
|
627
822
|
classStr = 'ANY';
|
|
628
823
|
break;
|
|
629
824
|
default:
|
|
@@ -631,25 +826,37 @@ export class Mdns extends Multicast {
|
|
|
631
826
|
}
|
|
632
827
|
return isQU ? `${classStr}|QU` : classStr;
|
|
633
828
|
}
|
|
634
|
-
|
|
635
|
-
|
|
829
|
+
/**
|
|
830
|
+
* Logs the decoded mDNS message header.
|
|
831
|
+
*
|
|
832
|
+
* @param {MdnsMessage} msg - The mDNS message header object.
|
|
833
|
+
* @param {AnsiLogger} [log] - The logger to use (defaults to this.log).
|
|
834
|
+
* @param {string} [text] - Optional additional text to include in the log.
|
|
835
|
+
*/
|
|
836
|
+
logMdnsMessage(msg, log = this.log, text = 'Decoded mDNS message') {
|
|
837
|
+
log.info(`${text}: 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}`);
|
|
636
838
|
msg.questions?.forEach((question) => {
|
|
637
|
-
|
|
839
|
+
log.info(`Question: ${CYAN}${question.name}${nf} type ${idn}${this.dnsTypeToString(question.type)}${rs}${nf} class ${CYAN}${this.dnsQuestionClassToString(question.class)}${nf}`);
|
|
638
840
|
});
|
|
639
841
|
msg.answers?.forEach((answer) => {
|
|
640
|
-
|
|
842
|
+
log.info(`Answer: ${CYAN}${answer.name}${nf} type ${idn}${this.dnsTypeToString(answer.type)}${rs}${nf} class ${CYAN}${this.dnsResponseClassToString(answer.class)}${nf} ttl ${CYAN}${answer.ttl}${nf} data ${CYAN}${answer.data}${nf}`);
|
|
641
843
|
});
|
|
642
844
|
msg.authorities?.forEach((authority) => {
|
|
643
|
-
|
|
845
|
+
log.info(`Authority: ${CYAN}${authority.name}${nf} type ${idn}${this.dnsTypeToString(authority.type)}${rs}${nf} class ${CYAN}${this.dnsResponseClassToString(authority.class)}${nf} ttl ${CYAN}${authority.ttl}${nf} data ${CYAN}${authority.data}${nf}`);
|
|
644
846
|
});
|
|
645
847
|
msg.additionals?.forEach((additional) => {
|
|
646
|
-
|
|
848
|
+
log.info(`Additional: ${CYAN}${additional.name}${nf} type ${idn}${this.dnsTypeToString(additional.type)}${rs}${nf} class ${CYAN}${this.dnsResponseClassToString(additional.class)}${nf} ttl ${CYAN}${additional.ttl}${nf} data ${CYAN}${additional.data}${nf}`);
|
|
647
849
|
});
|
|
648
|
-
|
|
850
|
+
log.info(`---\n`);
|
|
649
851
|
}
|
|
852
|
+
/**
|
|
853
|
+
* Logs the discovered devices from the mDNS queries and responses.
|
|
854
|
+
*/
|
|
650
855
|
logDevices() {
|
|
651
856
|
this.log.info(`Discovered query devices: ${MAGENTA}${this.deviceQueries.size}${nf}`);
|
|
857
|
+
// Collect devices into an array
|
|
652
858
|
const deviceQueryArray = Array.from(this.deviceQueries.entries());
|
|
859
|
+
// Sort the array by numeric value of the IP address
|
|
653
860
|
deviceQueryArray.sort(([addressA], [addressB]) => {
|
|
654
861
|
const partsA = addressA.split('.').map(Number);
|
|
655
862
|
const partsB = addressB.split('.').map(Number);
|
|
@@ -658,13 +865,17 @@ export class Mdns extends Multicast {
|
|
|
658
865
|
if (diff !== 0)
|
|
659
866
|
return diff;
|
|
660
867
|
}
|
|
868
|
+
// istanbul ignore next
|
|
661
869
|
return 0;
|
|
662
870
|
});
|
|
871
|
+
// Log the sorted devices
|
|
663
872
|
deviceQueryArray.forEach(([rinfo, response]) => {
|
|
664
873
|
this.log.info(`- ${MAGENTA}${rinfo}${nf} family ${BLUE}${response.rinfo.family}${nf} address ${BLUE}${response.rinfo.address}${nf} port ${BLUE}${response.rinfo.port}${nf}`);
|
|
665
874
|
});
|
|
666
875
|
this.log.info(`Discovered response devices: ${MAGENTA}${this.deviceResponses.size}${nf}`);
|
|
876
|
+
// Collect devices into an array
|
|
667
877
|
const deviceResponseArray = Array.from(this.deviceResponses.entries());
|
|
878
|
+
// Sort the array by numeric value of the IP address
|
|
668
879
|
deviceResponseArray.sort(([addressA], [addressB]) => {
|
|
669
880
|
const partsA = addressA.split(/[:.]/).map((part) => parseInt(part, 16));
|
|
670
881
|
const partsB = addressB.split(/[:.]/).map((part) => parseInt(part, 16));
|
|
@@ -673,10 +884,13 @@ export class Mdns extends Multicast {
|
|
|
673
884
|
if (diff !== 0)
|
|
674
885
|
return diff;
|
|
675
886
|
}
|
|
887
|
+
// istanbul ignore next
|
|
676
888
|
return 0;
|
|
677
889
|
});
|
|
890
|
+
// Log the sorted devices
|
|
678
891
|
deviceResponseArray.forEach(([rinfo, response]) => {
|
|
679
892
|
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}`);
|
|
680
893
|
});
|
|
681
894
|
}
|
|
682
895
|
}
|
|
896
|
+
//# sourceMappingURL=mdns.js.map
|