matterbridge 3.4.5 → 3.4.6-dev-20251228-e06f048
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 +12 -0
- package/dist/broadcastServer.js +0 -117
- package/dist/broadcastServerTypes.js +0 -24
- package/dist/cli.js +1 -97
- package/dist/cliEmitter.js +0 -37
- package/dist/cliHistory.js +0 -38
- package/dist/clusters/export.js +0 -2
- package/dist/deviceManager.js +1 -113
- package/dist/devices/airConditioner.js +0 -57
- package/dist/devices/batteryStorage.js +1 -48
- package/dist/devices/cooktop.js +0 -56
- package/dist/devices/dishwasher.js +0 -57
- package/dist/devices/evse.js +10 -74
- package/dist/devices/export.js +0 -5
- package/dist/devices/extractorHood.js +0 -43
- package/dist/devices/heatPump.js +2 -50
- package/dist/devices/laundryDryer.js +3 -62
- package/dist/devices/laundryWasher.js +4 -70
- package/dist/devices/microwaveOven.js +5 -88
- package/dist/devices/oven.js +0 -85
- package/dist/devices/refrigerator.js +0 -102
- package/dist/devices/roboticVacuumCleaner.js +9 -100
- package/dist/devices/solarPower.js +0 -38
- package/dist/devices/speaker.js +0 -84
- package/dist/devices/temperatureControl.js +3 -24
- package/dist/devices/waterHeater.js +2 -82
- package/dist/dgram/coap.js +13 -126
- package/dist/dgram/dgram.js +2 -114
- package/dist/dgram/mb_coap.js +3 -41
- package/dist/dgram/mb_mdns.js +22 -76
- package/dist/dgram/mdns.js +137 -351
- package/dist/dgram/mdnsReflectorClient.js +5 -29
- package/dist/dgram/mdnsReflectorServer.js +8 -49
- package/dist/dgram/mdnsReflectorTypes.js +1 -24
- package/dist/dgram/multicast.js +1 -62
- package/dist/dgram/unicast.js +0 -60
- package/dist/frontend.js +38 -485
- package/dist/frontendTypes.js +0 -45
- package/dist/helpers.js +0 -53
- package/dist/index.js +0 -25
- package/dist/jestutils/export.js +0 -1
- package/dist/jestutils/jestHelpers.js +14 -371
- 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/matterNode.js +8 -369
- package/dist/matterbridge.js +46 -824
- package/dist/matterbridgeAccessoryPlatform.js +0 -38
- package/dist/matterbridgeBehaviors.js +5 -68
- package/dist/matterbridgeDeviceTypes.js +14 -635
- package/dist/matterbridgeDynamicPlatform.js +0 -38
- package/dist/matterbridgeEndpoint.js +53 -1457
- package/dist/matterbridgeEndpointHelpers.js +20 -483
- package/dist/matterbridgeEndpointTypes.js +0 -25
- package/dist/matterbridgePlatform.js +1 -451
- package/dist/matterbridgeTypes.js +0 -26
- package/dist/pluginManager.js +5 -341
- package/dist/shelly.js +7 -178
- package/dist/storage/export.js +0 -1
- package/dist/update.js +1 -93
- package/dist/utils/colorUtils.js +2 -97
- package/dist/utils/commandLine.js +0 -60
- package/dist/utils/copyDirectory.js +0 -37
- 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 -42
- package/dist/utils/export.js +0 -1
- package/dist/utils/format.js +0 -49
- package/dist/utils/hex.js +0 -124
- package/dist/utils/inspector.js +1 -69
- package/dist/utils/isvalid.js +0 -101
- package/dist/utils/network.js +5 -103
- package/dist/utils/spawn.js +1 -71
- package/dist/utils/tracker.js +1 -64
- package/dist/utils/wait.js +8 -60
- package/dist/workerGlobalPrefix.js +5 -37
- package/dist/workerTypes.js +0 -24
- package/dist/workers.js +4 -68
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -2
- package/dist/broadcastServer.d.ts +0 -144
- package/dist/broadcastServer.d.ts.map +0 -1
- package/dist/broadcastServer.js.map +0 -1
- package/dist/broadcastServerTypes.d.ts +0 -841
- package/dist/broadcastServerTypes.d.ts.map +0 -1
- package/dist/broadcastServerTypes.js.map +0 -1
- package/dist/cli.d.ts +0 -30
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/cliEmitter.d.ts +0 -50
- package/dist/cliEmitter.d.ts.map +0 -1
- package/dist/cliEmitter.js.map +0 -1
- package/dist/cliHistory.d.ts +0 -48
- package/dist/cliHistory.d.ts.map +0 -1
- package/dist/cliHistory.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/deviceManager.d.ts +0 -135
- package/dist/deviceManager.d.ts.map +0 -1
- package/dist/deviceManager.js.map +0 -1
- package/dist/devices/airConditioner.d.ts +0 -98
- package/dist/devices/airConditioner.d.ts.map +0 -1
- package/dist/devices/airConditioner.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/cooktop.d.ts +0 -61
- package/dist/devices/cooktop.d.ts.map +0 -1
- package/dist/devices/cooktop.js.map +0 -1
- package/dist/devices/dishwasher.d.ts +0 -71
- package/dist/devices/dishwasher.d.ts.map +0 -1
- package/dist/devices/dishwasher.js.map +0 -1
- package/dist/devices/evse.d.ts +0 -76
- package/dist/devices/evse.d.ts.map +0 -1
- package/dist/devices/evse.js.map +0 -1
- package/dist/devices/export.d.ts +0 -17
- 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 -67
- package/dist/devices/laundryDryer.d.ts.map +0 -1
- package/dist/devices/laundryDryer.js.map +0 -1
- package/dist/devices/laundryWasher.d.ts +0 -81
- package/dist/devices/laundryWasher.d.ts.map +0 -1
- package/dist/devices/laundryWasher.js.map +0 -1
- package/dist/devices/microwaveOven.d.ts +0 -168
- package/dist/devices/microwaveOven.d.ts.map +0 -1
- package/dist/devices/microwaveOven.js.map +0 -1
- package/dist/devices/oven.d.ts +0 -105
- package/dist/devices/oven.d.ts.map +0 -1
- package/dist/devices/oven.js.map +0 -1
- package/dist/devices/refrigerator.d.ts +0 -118
- package/dist/devices/refrigerator.d.ts.map +0 -1
- package/dist/devices/refrigerator.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/speaker.d.ts +0 -87
- package/dist/devices/speaker.d.ts.map +0 -1
- package/dist/devices/speaker.js.map +0 -1
- package/dist/devices/temperatureControl.d.ts +0 -166
- package/dist/devices/temperatureControl.d.ts.map +0 -1
- package/dist/devices/temperatureControl.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 -143
- 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 -350
- package/dist/dgram/mdns.d.ts.map +0 -1
- package/dist/dgram/mdns.js.map +0 -1
- package/dist/dgram/mdnsReflectorClient.d.ts +0 -39
- package/dist/dgram/mdnsReflectorClient.d.ts.map +0 -1
- package/dist/dgram/mdnsReflectorClient.js.map +0 -1
- package/dist/dgram/mdnsReflectorServer.d.ts +0 -54
- package/dist/dgram/mdnsReflectorServer.d.ts.map +0 -1
- package/dist/dgram/mdnsReflectorServer.js.map +0 -1
- package/dist/dgram/mdnsReflectorTypes.d.ts +0 -28
- package/dist/dgram/mdnsReflectorTypes.d.ts.map +0 -1
- package/dist/dgram/mdnsReflectorTypes.js.map +0 -1
- package/dist/dgram/multicast.d.ts +0 -67
- package/dist/dgram/multicast.d.ts.map +0 -1
- package/dist/dgram/multicast.js.map +0 -1
- package/dist/dgram/unicast.d.ts +0 -64
- package/dist/dgram/unicast.d.ts.map +0 -1
- package/dist/dgram/unicast.js.map +0 -1
- package/dist/frontend.d.ts +0 -245
- package/dist/frontend.d.ts.map +0 -1
- package/dist/frontend.js.map +0 -1
- package/dist/frontendTypes.d.ts +0 -529
- package/dist/frontendTypes.d.ts.map +0 -1
- package/dist/frontendTypes.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 -34
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/jestutils/export.d.ts +0 -2
- package/dist/jestutils/export.d.ts.map +0 -1
- package/dist/jestutils/export.js.map +0 -1
- package/dist/jestutils/jestHelpers.d.ts +0 -345
- package/dist/jestutils/jestHelpers.d.ts.map +0 -1
- package/dist/jestutils/jestHelpers.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/matterNode.d.ts +0 -342
- package/dist/matterNode.d.ts.map +0 -1
- package/dist/matterNode.js.map +0 -1
- package/dist/matterbridge.d.ts +0 -505
- package/dist/matterbridge.d.ts.map +0 -1
- package/dist/matterbridge.js.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.d.ts +0 -41
- package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
- package/dist/matterbridgeBehaviors.d.ts +0 -2404
- package/dist/matterbridgeBehaviors.d.ts.map +0 -1
- package/dist/matterbridgeBehaviors.js.map +0 -1
- package/dist/matterbridgeDeviceTypes.d.ts +0 -698
- package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
- package/dist/matterbridgeDeviceTypes.js.map +0 -1
- package/dist/matterbridgeDynamicPlatform.d.ts +0 -41
- package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
- package/dist/matterbridgeDynamicPlatform.js.map +0 -1
- package/dist/matterbridgeEndpoint.d.ts +0 -1507
- package/dist/matterbridgeEndpoint.d.ts.map +0 -1
- package/dist/matterbridgeEndpoint.js.map +0 -1
- package/dist/matterbridgeEndpointHelpers.d.ts +0 -787
- package/dist/matterbridgeEndpointHelpers.d.ts.map +0 -1
- package/dist/matterbridgeEndpointHelpers.js.map +0 -1
- package/dist/matterbridgeEndpointTypes.d.ts +0 -166
- package/dist/matterbridgeEndpointTypes.d.ts.map +0 -1
- package/dist/matterbridgeEndpointTypes.js.map +0 -1
- package/dist/matterbridgePlatform.d.ts +0 -539
- package/dist/matterbridgePlatform.d.ts.map +0 -1
- package/dist/matterbridgePlatform.js.map +0 -1
- package/dist/matterbridgeTypes.d.ts +0 -252
- package/dist/matterbridgeTypes.d.ts.map +0 -1
- package/dist/matterbridgeTypes.js.map +0 -1
- package/dist/pluginManager.d.ts +0 -372
- package/dist/pluginManager.d.ts.map +0 -1
- package/dist/pluginManager.js.map +0 -1
- package/dist/shelly.d.ts +0 -181
- 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 -84
- package/dist/update.d.ts.map +0 -1
- package/dist/update.js.map +0 -1
- package/dist/utils/colorUtils.d.ts +0 -101
- package/dist/utils/colorUtils.d.ts.map +0 -1
- package/dist/utils/colorUtils.js.map +0 -1
- package/dist/utils/commandLine.d.ts +0 -66
- package/dist/utils/commandLine.d.ts.map +0 -1
- package/dist/utils/commandLine.js.map +0 -1
- package/dist/utils/copyDirectory.d.ts +0 -35
- 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 -45
- package/dist/utils/error.d.ts.map +0 -1
- package/dist/utils/error.js.map +0 -1
- package/dist/utils/export.d.ts +0 -13
- package/dist/utils/export.d.ts.map +0 -1
- package/dist/utils/export.js.map +0 -1
- package/dist/utils/format.d.ts +0 -53
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/hex.d.ts +0 -89
- package/dist/utils/hex.d.ts.map +0 -1
- package/dist/utils/hex.js.map +0 -1
- package/dist/utils/inspector.d.ts +0 -87
- package/dist/utils/inspector.d.ts.map +0 -1
- package/dist/utils/inspector.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 -117
- 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/tracker.d.ts +0 -108
- package/dist/utils/tracker.d.ts.map +0 -1
- package/dist/utils/tracker.js.map +0 -1
- package/dist/utils/wait.d.ts +0 -54
- package/dist/utils/wait.d.ts.map +0 -1
- package/dist/utils/wait.js.map +0 -1
- package/dist/workerGlobalPrefix.d.ts +0 -25
- package/dist/workerGlobalPrefix.d.ts.map +0 -1
- package/dist/workerGlobalPrefix.js.map +0 -1
- package/dist/workerTypes.d.ts +0 -52
- package/dist/workerTypes.d.ts.map +0 -1
- package/dist/workerTypes.js.map +0 -1
- package/dist/workers.d.ts +0 -69
- package/dist/workers.d.ts.map +0 -1
- package/dist/workers.js.map +0 -1
package/dist/dgram/mdns.js
CHANGED
|
@@ -1,30 +1,5 @@
|
|
|
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
|
-
// Utils imports
|
|
26
2
|
import { hasParameter } from '../utils/commandLine.js';
|
|
27
|
-
// Net imports
|
|
28
3
|
import { Multicast } from './multicast.js';
|
|
29
4
|
export var DnsRecordType;
|
|
30
5
|
(function (DnsRecordType) {
|
|
@@ -116,7 +91,6 @@ export var DnsRecordType;
|
|
|
116
91
|
DnsRecordType[DnsRecordType["DOA"] = 259] = "DOA";
|
|
117
92
|
DnsRecordType[DnsRecordType["AMTRELAY"] = 260] = "AMTRELAY";
|
|
118
93
|
DnsRecordType[DnsRecordType["ZONEVERSION"] = 261] = "ZONEVERSION";
|
|
119
|
-
// 262-32767 are unassigned/reserved
|
|
120
94
|
DnsRecordType[DnsRecordType["TA"] = 32768] = "TA";
|
|
121
95
|
DnsRecordType[DnsRecordType["DLV"] = 32769] = "DLV";
|
|
122
96
|
})(DnsRecordType || (DnsRecordType = {}));
|
|
@@ -130,25 +104,12 @@ export var DnsClass;
|
|
|
130
104
|
export var DnsClassFlag;
|
|
131
105
|
(function (DnsClassFlag) {
|
|
132
106
|
DnsClassFlag[DnsClassFlag["FLUSH"] = 32768] = "FLUSH";
|
|
133
|
-
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
|
134
107
|
DnsClassFlag[DnsClassFlag["QU"] = 32768] = "QU";
|
|
135
108
|
})(DnsClassFlag || (DnsClassFlag = {}));
|
|
136
109
|
export class Mdns extends Multicast {
|
|
137
110
|
deviceQueries = new Map();
|
|
138
111
|
deviceResponses = new Map();
|
|
139
112
|
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
|
-
*/
|
|
152
113
|
constructor(name, multicastAddress, multicastPort, socketType, reuseAddr = true, interfaceName, interfaceAddress, outgoingInterfaceAddress) {
|
|
153
114
|
super(name, multicastAddress, multicastPort, socketType, reuseAddr, interfaceName, interfaceAddress, outgoingInterfaceAddress);
|
|
154
115
|
}
|
|
@@ -168,17 +129,16 @@ export class Mdns extends Multicast {
|
|
|
168
129
|
this.onQuery(rinfo, result);
|
|
169
130
|
}
|
|
170
131
|
else {
|
|
171
|
-
const ptr = result.answers?.find((record) => record.name === '_shelly._tcp.local' && record.type === 12
|
|
172
|
-
result.answers?.find((record) => record.name === '_http._tcp.local' && record.type === 12
|
|
173
|
-
result.answers?.find((record) => record.type === 12
|
|
174
|
-
result.answers?.find((record) => record.type === 16
|
|
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) ||
|
|
175
136
|
result.answers
|
|
176
137
|
? result.answers[0]
|
|
177
|
-
: undefined;
|
|
178
|
-
this.deviceResponses.set(rinfo.address, { rinfo, response: result, dataPTR: ptr?.type === 12
|
|
138
|
+
: undefined;
|
|
139
|
+
this.deviceResponses.set(rinfo.address, { rinfo, response: result, dataPTR: ptr?.type === 12 ? ptr?.data : ptr?.name });
|
|
179
140
|
this.onResponse(rinfo, result);
|
|
180
141
|
}
|
|
181
|
-
// Apply filters if any
|
|
182
142
|
if (this.filters.length > 0) {
|
|
183
143
|
this.log.debug(`mDNS message filtered out by filters: ${this.filters.join(', ')}`);
|
|
184
144
|
for (const filter of this.filters) {
|
|
@@ -200,28 +160,20 @@ export class Mdns extends Multicast {
|
|
|
200
160
|
this.log.error(`Error decoding mDNS message: ${error instanceof Error ? error.message : error}`);
|
|
201
161
|
}
|
|
202
162
|
}
|
|
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
|
-
*/
|
|
211
163
|
decodeMdnsMessage(msg) {
|
|
212
164
|
if (msg.length < 12) {
|
|
213
165
|
throw new Error('mDNS message too short');
|
|
214
166
|
}
|
|
215
167
|
const id = msg.readUInt16BE(0);
|
|
216
168
|
const flags = msg.readUInt16BE(2);
|
|
217
|
-
const qr = (flags & 0x8000) >> 15;
|
|
218
|
-
const opcode = (flags & 0x7800) >> 11;
|
|
219
|
-
const aa = Boolean(flags & 0x0400);
|
|
220
|
-
const tc = Boolean(flags & 0x0200);
|
|
221
|
-
const rd = Boolean(flags & 0x0100);
|
|
222
|
-
const ra = Boolean(flags & 0x0080);
|
|
223
|
-
const z = (flags & 0x0070) >> 4;
|
|
224
|
-
const rcode = flags & 0x000f;
|
|
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;
|
|
225
177
|
const qdCount = msg.readUInt16BE(4);
|
|
226
178
|
const anCount = msg.readUInt16BE(6);
|
|
227
179
|
const nsCount = msg.readUInt16BE(8);
|
|
@@ -246,7 +198,6 @@ export class Mdns extends Multicast {
|
|
|
246
198
|
additionals: [],
|
|
247
199
|
};
|
|
248
200
|
let offset = 12;
|
|
249
|
-
// Decode the question section.
|
|
250
201
|
for (let i = 0; i < qdCount; i++) {
|
|
251
202
|
const qnameResult = this.decodeDnsName(msg, offset);
|
|
252
203
|
const qname = qnameResult.name;
|
|
@@ -257,19 +208,16 @@ export class Mdns extends Multicast {
|
|
|
257
208
|
offset += 2;
|
|
258
209
|
mdnsMessage.questions?.push({ name: qname, type: qtype, class: qclass });
|
|
259
210
|
}
|
|
260
|
-
// Decode the answer section.
|
|
261
211
|
for (let i = 0; i < anCount; i++) {
|
|
262
212
|
const rrResult = this.decodeResourceRecord(msg, offset);
|
|
263
213
|
mdnsMessage.answers?.push(rrResult.record);
|
|
264
214
|
offset = rrResult.newOffset;
|
|
265
215
|
}
|
|
266
|
-
// Decode the authority (NS) section.
|
|
267
216
|
for (let i = 0; i < nsCount; i++) {
|
|
268
217
|
const rrResult = this.decodeResourceRecord(msg, offset);
|
|
269
218
|
mdnsMessage.authorities?.push(rrResult.record);
|
|
270
219
|
offset = rrResult.newOffset;
|
|
271
220
|
}
|
|
272
|
-
// Decode the additional records section.
|
|
273
221
|
for (let i = 0; i < arCount; i++) {
|
|
274
222
|
const rrResult = this.decodeResourceRecord(msg, offset);
|
|
275
223
|
mdnsMessage.additionals?.push(rrResult.record);
|
|
@@ -277,25 +225,15 @@ export class Mdns extends Multicast {
|
|
|
277
225
|
}
|
|
278
226
|
return mdnsMessage;
|
|
279
227
|
}
|
|
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
|
-
*/
|
|
288
228
|
decodeDnsName(msg, offset) {
|
|
289
229
|
const labels = [];
|
|
290
230
|
let jumped = false;
|
|
291
231
|
let originalOffset = offset;
|
|
292
|
-
let iterations = 0;
|
|
232
|
+
let iterations = 0;
|
|
293
233
|
while (true) {
|
|
294
|
-
// Safety guard: prevent infinite loops in malformed messages.
|
|
295
234
|
if (iterations++ > 1000) {
|
|
296
235
|
throw new Error('Too many iterations while decoding DNS name. Possible malformed message.');
|
|
297
236
|
}
|
|
298
|
-
// Check that offset is within buffer bounds.
|
|
299
237
|
if (offset >= msg.length) {
|
|
300
238
|
throw new Error('Offset exceeds buffer length while decoding DNS name.');
|
|
301
239
|
}
|
|
@@ -304,9 +242,7 @@ export class Mdns extends Multicast {
|
|
|
304
242
|
offset++;
|
|
305
243
|
break;
|
|
306
244
|
}
|
|
307
|
-
// Check for pointer (first two bits are 11)
|
|
308
245
|
if ((len & 0xc0) === 0xc0) {
|
|
309
|
-
// Ensure the pointer has two bytes available.
|
|
310
246
|
if (offset + 1 >= msg.length) {
|
|
311
247
|
throw new Error('Incomplete pointer encountered while decoding DNS name.');
|
|
312
248
|
}
|
|
@@ -319,7 +255,6 @@ export class Mdns extends Multicast {
|
|
|
319
255
|
continue;
|
|
320
256
|
}
|
|
321
257
|
offset++;
|
|
322
|
-
// Check that the label length doesn't go beyond the buffer.
|
|
323
258
|
if (offset + len > msg.length) {
|
|
324
259
|
throw new Error('Label length exceeds buffer bounds while decoding DNS name.');
|
|
325
260
|
}
|
|
@@ -328,15 +263,6 @@ export class Mdns extends Multicast {
|
|
|
328
263
|
}
|
|
329
264
|
return { name: labels.join('.'), newOffset: jumped ? originalOffset : offset };
|
|
330
265
|
}
|
|
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
|
-
*/
|
|
340
266
|
encodeDnsName(name) {
|
|
341
267
|
const labels = name.split('.');
|
|
342
268
|
const buffers = labels.map((label) => {
|
|
@@ -344,25 +270,8 @@ export class Mdns extends Multicast {
|
|
|
344
270
|
lenBuf.writeUInt8(label.length, 0);
|
|
345
271
|
return Buffer.concat([lenBuf, Buffer.from(label)]);
|
|
346
272
|
});
|
|
347
|
-
// Append the null byte to terminate the name.
|
|
348
273
|
return Buffer.concat([...buffers, Buffer.from([0])]);
|
|
349
274
|
}
|
|
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
|
-
*/
|
|
366
275
|
encodeTxtRdata(txt) {
|
|
367
276
|
const parts = txt.map((entry) => {
|
|
368
277
|
const value = Buffer.from(entry, 'utf8');
|
|
@@ -372,21 +281,6 @@ export class Mdns extends Multicast {
|
|
|
372
281
|
});
|
|
373
282
|
return Buffer.concat(parts);
|
|
374
283
|
}
|
|
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
|
-
*/
|
|
390
284
|
encodeSrvRdata(priority, weight, port, target) {
|
|
391
285
|
const fixed = Buffer.alloc(6);
|
|
392
286
|
fixed.writeUInt16BE(priority, 0);
|
|
@@ -394,13 +288,6 @@ export class Mdns extends Multicast {
|
|
|
394
288
|
fixed.writeUInt16BE(port, 4);
|
|
395
289
|
return Buffer.concat([fixed, this.encodeDnsName(target)]);
|
|
396
290
|
}
|
|
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
|
-
*/
|
|
404
291
|
encodeA(ipv4) {
|
|
405
292
|
const parts = ipv4.split('.').map((p) => Number(p));
|
|
406
293
|
if (parts.length !== 4 || parts.some((n) => !Number.isInteger(n) || n < 0 || n > 255)) {
|
|
@@ -408,19 +295,8 @@ export class Mdns extends Multicast {
|
|
|
408
295
|
}
|
|
409
296
|
return Buffer.from(parts);
|
|
410
297
|
}
|
|
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
|
-
*/
|
|
421
298
|
encodeAAAA(ipv6WithOptionalScope) {
|
|
422
299
|
const ipv6 = ipv6WithOptionalScope.split('%')[0];
|
|
423
|
-
// Expand IPv6 to 8 groups of 16-bit words.
|
|
424
300
|
const [left, right] = ipv6.split('::');
|
|
425
301
|
const leftParts = left ? left.split(':').filter(Boolean) : [];
|
|
426
302
|
const rightParts = right ? right.split(':').filter(Boolean) : [];
|
|
@@ -446,19 +322,10 @@ export class Mdns extends Multicast {
|
|
|
446
322
|
return [(word >> 8) & 0xff, word & 0xff];
|
|
447
323
|
}));
|
|
448
324
|
}
|
|
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
|
-
*/
|
|
456
325
|
decodeResourceRecord(msg, offset) {
|
|
457
|
-
// Decode the NAME field (which may be compressed)
|
|
458
326
|
const nameResult = this.decodeDnsName(msg, offset);
|
|
459
327
|
const name = nameResult.name;
|
|
460
328
|
offset = nameResult.newOffset;
|
|
461
|
-
// Read TYPE (16 bits), CLASS (16 bits), TTL (32 bits), and RDLENGTH (16 bits)
|
|
462
329
|
const type = msg.readUInt16BE(offset);
|
|
463
330
|
offset += 2;
|
|
464
331
|
const rrclass = msg.readUInt16BE(offset);
|
|
@@ -468,14 +335,12 @@ export class Mdns extends Multicast {
|
|
|
468
335
|
const rdlength = msg.readUInt16BE(offset);
|
|
469
336
|
offset += 2;
|
|
470
337
|
let data = '';
|
|
471
|
-
if (type === 12
|
|
472
|
-
// PTR record (type 12): decode its RDATA as a domain name.
|
|
338
|
+
if (type === 12) {
|
|
473
339
|
const ptrResult = this.decodeDnsName(msg, offset);
|
|
474
340
|
data = ptrResult.name;
|
|
475
341
|
offset += rdlength;
|
|
476
342
|
}
|
|
477
|
-
else if (type === 16
|
|
478
|
-
// TXT record: may consist of one or more length-prefixed strings.
|
|
343
|
+
else if (type === 16) {
|
|
479
344
|
const txtStrings = [];
|
|
480
345
|
const end = offset + rdlength;
|
|
481
346
|
while (offset < end) {
|
|
@@ -487,8 +352,7 @@ export class Mdns extends Multicast {
|
|
|
487
352
|
}
|
|
488
353
|
data = txtStrings.join(', ');
|
|
489
354
|
}
|
|
490
|
-
else if (type === 33
|
|
491
|
-
// SRV record (type === 33): consists of 2 bytes for priority, 2 for weight, 2 for port, followed by the target domain name.
|
|
355
|
+
else if (type === 33) {
|
|
492
356
|
const priority = msg.readUInt16BE(offset);
|
|
493
357
|
const weight = msg.readUInt16BE(offset + 2);
|
|
494
358
|
const port = msg.readUInt16BE(offset + 4);
|
|
@@ -502,16 +366,13 @@ export class Mdns extends Multicast {
|
|
|
502
366
|
});
|
|
503
367
|
offset = srvTargetResult.newOffset;
|
|
504
368
|
}
|
|
505
|
-
else if (type === 1
|
|
506
|
-
// A record (type 1): an IPv4 address stored in 4 bytes.
|
|
369
|
+
else if (type === 1) {
|
|
507
370
|
const ipBytes = msg.slice(offset, offset + 4);
|
|
508
371
|
data = Array.from(ipBytes).join('.');
|
|
509
372
|
offset += 4;
|
|
510
373
|
}
|
|
511
|
-
else if (type === 28
|
|
512
|
-
// AAAA record (type 28): IPv6 address stored in 16 bytes.
|
|
374
|
+
else if (type === 28) {
|
|
513
375
|
const ipBytes = msg.slice(offset, offset + 16);
|
|
514
|
-
// Convert the 16 bytes into an IPv6 address string (colon-separated)
|
|
515
376
|
const ipv6Parts = [];
|
|
516
377
|
for (let i = 0; i < 16; i += 2) {
|
|
517
378
|
ipv6Parts.push(ipBytes.readUInt16BE(i).toString(16));
|
|
@@ -519,14 +380,10 @@ export class Mdns extends Multicast {
|
|
|
519
380
|
data = ipv6Parts.join(':');
|
|
520
381
|
offset += 16;
|
|
521
382
|
}
|
|
522
|
-
else if (type === 47
|
|
523
|
-
// NSEC record: RDATA consists of:
|
|
524
|
-
// - Next Domain Name (in DNS label format)
|
|
525
|
-
// - Type Bit Maps (variable length)
|
|
383
|
+
else if (type === 47) {
|
|
526
384
|
const { name: nextDomain, newOffset } = this.decodeDnsName(msg, offset);
|
|
527
385
|
const nextDomainLength = newOffset - offset;
|
|
528
386
|
offset = newOffset;
|
|
529
|
-
// Calculate the remaining length for the type bit maps.
|
|
530
387
|
const bitmapLength = rdlength - nextDomainLength;
|
|
531
388
|
const bitmapData = msg.slice(offset, offset + bitmapLength);
|
|
532
389
|
const types = [];
|
|
@@ -553,7 +410,6 @@ export class Mdns extends Multicast {
|
|
|
553
410
|
offset += bitmapLength;
|
|
554
411
|
}
|
|
555
412
|
else {
|
|
556
|
-
// Fall back
|
|
557
413
|
data = msg.slice(offset, offset + rdlength).toString('hex');
|
|
558
414
|
offset += rdlength;
|
|
559
415
|
}
|
|
@@ -562,30 +418,19 @@ export class Mdns extends Multicast {
|
|
|
562
418
|
newOffset: offset,
|
|
563
419
|
};
|
|
564
420
|
}
|
|
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
|
-
*/
|
|
576
421
|
sendQuery(questions) {
|
|
577
422
|
const header = Buffer.alloc(12);
|
|
578
|
-
header.writeUInt16BE(0, 0);
|
|
579
|
-
header.writeUInt16BE(0, 2);
|
|
580
|
-
header.writeUInt16BE(questions.length, 4);
|
|
581
|
-
header.writeUInt16BE(0, 6);
|
|
582
|
-
header.writeUInt16BE(0, 8);
|
|
583
|
-
header.writeUInt16BE(0, 10);
|
|
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);
|
|
584
429
|
const questionBuffers = questions.map(({ name, type: qtype, class: qclass, unicastResponse = false }) => {
|
|
585
430
|
const qname = this.encodeDnsName(name);
|
|
586
431
|
const qfields = Buffer.alloc(4);
|
|
587
432
|
qfields.writeUInt16BE(qtype, 0);
|
|
588
|
-
qfields.writeUInt16BE(unicastResponse ? qclass | 32768
|
|
433
|
+
qfields.writeUInt16BE(unicastResponse ? qclass | 32768 : qclass, 2);
|
|
589
434
|
return Buffer.concat([qname, qfields]);
|
|
590
435
|
});
|
|
591
436
|
const query = Buffer.concat([header, ...questionBuffers]);
|
|
@@ -608,52 +453,31 @@ export class Mdns extends Multicast {
|
|
|
608
453
|
});
|
|
609
454
|
return query;
|
|
610
455
|
}
|
|
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
|
-
*/
|
|
621
456
|
sendResponse(answers) {
|
|
622
457
|
if (!Array.isArray(answers) || answers.length === 0) {
|
|
623
458
|
throw new Error('sendResponse requires a non-empty answers array');
|
|
624
459
|
}
|
|
625
|
-
// Create a 12-byte DNS header.
|
|
626
460
|
const header = Buffer.alloc(12);
|
|
627
|
-
header.writeUInt16BE(0, 0);
|
|
628
|
-
// Set flags: QR (response) bit and AA (authoritative answer) bit.
|
|
461
|
+
header.writeUInt16BE(0, 0);
|
|
629
462
|
header.writeUInt16BE(0x8400, 2);
|
|
630
|
-
header.writeUInt16BE(0, 4);
|
|
631
|
-
header.writeUInt16BE(answers.length, 6);
|
|
632
|
-
header.writeUInt16BE(0, 8);
|
|
633
|
-
header.writeUInt16BE(0, 10);
|
|
463
|
+
header.writeUInt16BE(0, 4);
|
|
464
|
+
header.writeUInt16BE(answers.length, 6);
|
|
465
|
+
header.writeUInt16BE(0, 8);
|
|
466
|
+
header.writeUInt16BE(0, 10);
|
|
634
467
|
const answerBuffers = answers.map(({ name, rtype, rclass, ttl, rdata }) => {
|
|
635
|
-
// Encode the domain name in DNS label format.
|
|
636
468
|
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).
|
|
642
469
|
const answerFixed = Buffer.alloc(10);
|
|
643
|
-
answerFixed.writeUInt16BE(rtype, 0);
|
|
644
|
-
answerFixed.writeUInt16BE(rclass, 2);
|
|
645
|
-
answerFixed.writeUInt32BE(ttl, 4);
|
|
646
|
-
answerFixed.writeUInt16BE(rdata.length, 8);
|
|
647
|
-
// Concatenate the answer: encoded name, fixed fields, and resource data.
|
|
470
|
+
answerFixed.writeUInt16BE(rtype, 0);
|
|
471
|
+
answerFixed.writeUInt16BE(rclass, 2);
|
|
472
|
+
answerFixed.writeUInt32BE(ttl, 4);
|
|
473
|
+
answerFixed.writeUInt16BE(rdata.length, 8);
|
|
648
474
|
return Buffer.concat([aname, answerFixed, rdata]);
|
|
649
475
|
});
|
|
650
|
-
// Concatenate header and answers to form the complete mDNS response packet.
|
|
651
476
|
const response = Buffer.concat([header, ...answerBuffers]);
|
|
652
477
|
if (hasParameter('v') || hasParameter('verbose')) {
|
|
653
478
|
const decoded = this.decodeMdnsMessage(response);
|
|
654
479
|
this.logMdnsMessage(decoded);
|
|
655
480
|
}
|
|
656
|
-
// Send the response packet via the socket.
|
|
657
481
|
this.socket.send(response, 0, response.length, this.multicastPort, this.multicastAddress, (error) => {
|
|
658
482
|
if (error) {
|
|
659
483
|
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');
|
|
@@ -668,128 +492,116 @@ export class Mdns extends Multicast {
|
|
|
668
492
|
});
|
|
669
493
|
return response;
|
|
670
494
|
}
|
|
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
|
-
*/
|
|
677
495
|
dnsTypeToString(type) {
|
|
678
496
|
const typeMap = {
|
|
679
|
-
[1
|
|
680
|
-
[2
|
|
681
|
-
[3
|
|
682
|
-
[4
|
|
683
|
-
[5
|
|
684
|
-
[6
|
|
685
|
-
[7
|
|
686
|
-
[8
|
|
687
|
-
[9
|
|
688
|
-
[10
|
|
689
|
-
[11
|
|
690
|
-
[12
|
|
691
|
-
[13
|
|
692
|
-
[14
|
|
693
|
-
[15
|
|
694
|
-
[16
|
|
695
|
-
[17
|
|
696
|
-
[18
|
|
697
|
-
[19
|
|
698
|
-
[20
|
|
699
|
-
[21
|
|
700
|
-
[22
|
|
701
|
-
[23
|
|
702
|
-
[24
|
|
703
|
-
[25
|
|
704
|
-
[26
|
|
705
|
-
[27
|
|
706
|
-
[28
|
|
707
|
-
[29
|
|
708
|
-
[30
|
|
709
|
-
[31
|
|
710
|
-
[32
|
|
711
|
-
[33
|
|
712
|
-
[34
|
|
713
|
-
[35
|
|
714
|
-
[36
|
|
715
|
-
[37
|
|
716
|
-
[38
|
|
717
|
-
[39
|
|
718
|
-
[40
|
|
719
|
-
[41
|
|
720
|
-
[42
|
|
721
|
-
[43
|
|
722
|
-
[44
|
|
723
|
-
[45
|
|
724
|
-
[46
|
|
725
|
-
[47
|
|
726
|
-
[48
|
|
727
|
-
[49
|
|
728
|
-
[50
|
|
729
|
-
[51
|
|
730
|
-
[52
|
|
731
|
-
[53
|
|
732
|
-
[55
|
|
733
|
-
[56
|
|
734
|
-
[57
|
|
735
|
-
[58
|
|
736
|
-
[59
|
|
737
|
-
[60
|
|
738
|
-
[61
|
|
739
|
-
[62
|
|
740
|
-
[63
|
|
741
|
-
[64
|
|
742
|
-
[65
|
|
743
|
-
[99
|
|
744
|
-
[100
|
|
745
|
-
[101
|
|
746
|
-
[102
|
|
747
|
-
[103
|
|
748
|
-
[104
|
|
749
|
-
[105
|
|
750
|
-
[106
|
|
751
|
-
[107
|
|
752
|
-
[108
|
|
753
|
-
[109
|
|
754
|
-
[249
|
|
755
|
-
[250
|
|
756
|
-
[251
|
|
757
|
-
[252
|
|
758
|
-
[253
|
|
759
|
-
[254
|
|
760
|
-
[255
|
|
761
|
-
[256
|
|
762
|
-
[257
|
|
763
|
-
[258
|
|
764
|
-
[259
|
|
765
|
-
[260
|
|
766
|
-
[261
|
|
767
|
-
[32768
|
|
768
|
-
[32769
|
|
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',
|
|
769
587
|
};
|
|
770
588
|
return typeMap[type] ?? `TYPE${type}`;
|
|
771
589
|
}
|
|
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
|
-
*/
|
|
778
590
|
dnsResponseClassToString(cls) {
|
|
779
|
-
const isFlush = !!(cls & 32768
|
|
591
|
+
const isFlush = !!(cls & 32768);
|
|
780
592
|
const baseClass = cls & 0x7fff;
|
|
781
593
|
let classStr;
|
|
782
594
|
switch (baseClass) {
|
|
783
|
-
case 1
|
|
595
|
+
case 1:
|
|
784
596
|
classStr = 'IN';
|
|
785
597
|
break;
|
|
786
|
-
case 3
|
|
598
|
+
case 3:
|
|
787
599
|
classStr = 'CH';
|
|
788
600
|
break;
|
|
789
|
-
case 4
|
|
601
|
+
case 4:
|
|
790
602
|
classStr = 'HS';
|
|
791
603
|
break;
|
|
792
|
-
case 255
|
|
604
|
+
case 255:
|
|
793
605
|
classStr = 'ANY';
|
|
794
606
|
break;
|
|
795
607
|
default:
|
|
@@ -797,28 +609,21 @@ export class Mdns extends Multicast {
|
|
|
797
609
|
}
|
|
798
610
|
return isFlush ? `${classStr}|FLUSH` : classStr;
|
|
799
611
|
}
|
|
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
|
-
*/
|
|
807
612
|
dnsQuestionClassToString(cls) {
|
|
808
|
-
const isQU = !!(cls & 32768
|
|
613
|
+
const isQU = !!(cls & 32768);
|
|
809
614
|
const baseClass = cls & 0x7fff;
|
|
810
615
|
let classStr;
|
|
811
616
|
switch (baseClass) {
|
|
812
|
-
case 1
|
|
617
|
+
case 1:
|
|
813
618
|
classStr = 'IN';
|
|
814
619
|
break;
|
|
815
|
-
case 3
|
|
620
|
+
case 3:
|
|
816
621
|
classStr = 'CH';
|
|
817
622
|
break;
|
|
818
|
-
case 4
|
|
623
|
+
case 4:
|
|
819
624
|
classStr = 'HS';
|
|
820
625
|
break;
|
|
821
|
-
case 255
|
|
626
|
+
case 255:
|
|
822
627
|
classStr = 'ANY';
|
|
823
628
|
break;
|
|
824
629
|
default:
|
|
@@ -826,13 +631,6 @@ export class Mdns extends Multicast {
|
|
|
826
631
|
}
|
|
827
632
|
return isQU ? `${classStr}|QU` : classStr;
|
|
828
633
|
}
|
|
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
634
|
logMdnsMessage(msg, log = this.log, text = 'Decoded mDNS message') {
|
|
837
635
|
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}`);
|
|
838
636
|
msg.questions?.forEach((question) => {
|
|
@@ -849,14 +647,9 @@ export class Mdns extends Multicast {
|
|
|
849
647
|
});
|
|
850
648
|
log.info(`---\n`);
|
|
851
649
|
}
|
|
852
|
-
/**
|
|
853
|
-
* Logs the discovered devices from the mDNS queries and responses.
|
|
854
|
-
*/
|
|
855
650
|
logDevices() {
|
|
856
651
|
this.log.info(`Discovered query devices: ${MAGENTA}${this.deviceQueries.size}${nf}`);
|
|
857
|
-
// Collect devices into an array
|
|
858
652
|
const deviceQueryArray = Array.from(this.deviceQueries.entries());
|
|
859
|
-
// Sort the array by numeric value of the IP address
|
|
860
653
|
deviceQueryArray.sort(([addressA], [addressB]) => {
|
|
861
654
|
const partsA = addressA.split('.').map(Number);
|
|
862
655
|
const partsB = addressB.split('.').map(Number);
|
|
@@ -865,17 +658,13 @@ export class Mdns extends Multicast {
|
|
|
865
658
|
if (diff !== 0)
|
|
866
659
|
return diff;
|
|
867
660
|
}
|
|
868
|
-
// istanbul ignore next
|
|
869
661
|
return 0;
|
|
870
662
|
});
|
|
871
|
-
// Log the sorted devices
|
|
872
663
|
deviceQueryArray.forEach(([rinfo, response]) => {
|
|
873
664
|
this.log.info(`- ${MAGENTA}${rinfo}${nf} family ${BLUE}${response.rinfo.family}${nf} address ${BLUE}${response.rinfo.address}${nf} port ${BLUE}${response.rinfo.port}${nf}`);
|
|
874
665
|
});
|
|
875
666
|
this.log.info(`Discovered response devices: ${MAGENTA}${this.deviceResponses.size}${nf}`);
|
|
876
|
-
// Collect devices into an array
|
|
877
667
|
const deviceResponseArray = Array.from(this.deviceResponses.entries());
|
|
878
|
-
// Sort the array by numeric value of the IP address
|
|
879
668
|
deviceResponseArray.sort(([addressA], [addressB]) => {
|
|
880
669
|
const partsA = addressA.split(/[:.]/).map((part) => parseInt(part, 16));
|
|
881
670
|
const partsB = addressB.split(/[:.]/).map((part) => parseInt(part, 16));
|
|
@@ -884,13 +673,10 @@ export class Mdns extends Multicast {
|
|
|
884
673
|
if (diff !== 0)
|
|
885
674
|
return diff;
|
|
886
675
|
}
|
|
887
|
-
// istanbul ignore next
|
|
888
676
|
return 0;
|
|
889
677
|
});
|
|
890
|
-
// Log the sorted devices
|
|
891
678
|
deviceResponseArray.forEach(([rinfo, response]) => {
|
|
892
679
|
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}`);
|
|
893
680
|
});
|
|
894
681
|
}
|
|
895
682
|
}
|
|
896
|
-
//# sourceMappingURL=mdns.js.map
|