or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-multicast-dns

Low level multicast-dns implementation in pure javascript

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/multicast-dns@7.2.x

To install, run

npx @tessl/cli install tessl/npm-multicast-dns@7.2.0

0

# Multicast DNS

1

2

Multicast DNS provides a low-level multicast DNS (mDNS) implementation in pure JavaScript for Node.js applications. It enables service discovery on local networks by implementing the mDNS protocol (RFC 6762) which allows devices to discover services without requiring a centralized DNS server.

3

4

## Package Information

5

6

- **Package Name**: multicast-dns

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install multicast-dns`

10

11

## Core Imports

12

13

```javascript

14

const mdns = require('multicast-dns');

15

```

16

17

## Basic Usage

18

19

```javascript

20

const mdns = require('multicast-dns')();

21

22

// Listen for DNS responses

23

mdns.on('response', function(response) {

24

console.log('got a response packet:', response);

25

});

26

27

// Listen for DNS queries

28

mdns.on('query', function(query) {

29

console.log('got a query packet:', query);

30

31

// Respond to A record queries for 'example.local'

32

query.questions.forEach(function(q) {

33

if (q.type === 'A' && q.name === 'example.local') {

34

mdns.respond({

35

answers: [{

36

name: 'example.local',

37

type: 'A',

38

ttl: 300,

39

data: '192.168.1.5'

40

}]

41

});

42

}

43

});

44

});

45

46

// Query for an A record

47

mdns.query({

48

questions: [{

49

name: 'example.local',

50

type: 'A'

51

}]

52

});

53

```

54

55

## CLI Interface

56

57

The package includes a command-line tool for basic mDNS operations.

58

59

**Installation for global use:**

60

```bash

61

npm install -g multicast-dns

62

```

63

64

**Usage:**

65

```bash

66

# Query for a hostname (resolve to IP)

67

multicast-dns example.local

68

# Output: 192.168.1.5

69

70

# Announce a hostname (advertise current machine)

71

multicast-dns --announce example.local

72

```

73

74

The CLI tool automatically detects the local IP address for announcements and provides a simple interface for common mDNS operations.

75

76

## Architecture

77

78

Multicast DNS is built around several key components:

79

80

- **Factory Function**: Main module export creates configured mDNS instances

81

- **EventEmitter Interface**: All instances inherit from Node.js EventEmitter for event-driven communication

82

- **UDP Socket Management**: Handles IPv4/IPv6 multicast socket creation and membership management

83

- **DNS Packet Processing**: Uses dns-packet library for encoding/decoding DNS messages

84

- **Network Interface Discovery**: Automatically discovers and manages multicast group memberships across network interfaces

85

86

## Capabilities

87

88

### mDNS Instance Creation

89

90

Creates a new multicast DNS instance with configurable network and protocol options.

91

92

```javascript { .api }

93

/**

94

* Creates a new multicast DNS instance

95

* @param {Object} [options] - Configuration options

96

* @param {number} [options.port=5353] - UDP port number

97

* @param {string} [options.type='udp4'] - Socket type ('udp4' or 'udp6')

98

* @param {string} [options.ip='224.0.0.251'] - Multicast IP address

99

* @param {string} [options.host] - Alias for ip option

100

* @param {string|string[]} [options.interface] - Network interface(s) to bind to

101

* @param {boolean} [options.multicast=true] - Enable multicast functionality

102

* @param {number} [options.ttl=255] - Multicast TTL value

103

* @param {boolean} [options.loopback=true] - Receive own multicast packets

104

* @param {boolean} [options.reuseAddr=true] - Enable SO_REUSEADDR socket option

105

* @param {string|boolean} [options.bind] - Bind address or false to disable binding

106

* @param {dgram.Socket} [options.socket] - Pre-existing socket to use

107

* @returns {EventEmitter} mDNS instance with query/response capabilities

108

*/

109

function multicastdns(options)

110

```

111

112

### DNS Query Operations

113

114

Send DNS queries to discover services and devices on the local network.

115

116

```javascript { .api }

117

/**

118

* Send a DNS query packet

119

* @param {string|Object|Object[]} query - Query specification

120

* @param {string} [type] - DNS record type when query is a string

121

* @param {Object} [rinfo] - Target address information

122

* @param {Function} [callback] - Completion callback

123

*/

124

mdns.query(query, type, rinfo, callback)

125

```

126

127

**Query Format Options:**

128

129

```javascript { .api }

130

// String format with explicit type

131

mdns.query('example.local', 'A');

132

133

// String format with callback (defaults to 'ANY' type)

134

mdns.query('example.local', callback);

135

136

// String format with type and callback

137

mdns.query('example.local', 'A', callback);

138

139

// Array of question objects

140

mdns.query([{name: 'example.local', type: 'A'}]);

141

142

// Full packet object

143

mdns.query({

144

questions: [{name: 'example.local', type: 'A'}]

145

});

146

```

147

148

### DNS Response Operations

149

150

Send DNS responses to advertise services and answer queries from other devices.

151

152

```javascript { .api }

153

/**

154

* Send a DNS response packet

155

* @param {Object[]|Object} response - Response data

156

* @param {Object} [rinfo] - Target address information

157

* @param {Function} [callback] - Completion callback

158

*/

159

mdns.respond(response, rinfo, callback)

160

161

/**

162

* Alias for respond method - identical signature

163

* @param {Object[]|Object} response - Response data

164

* @param {Object} [rinfo] - Target address information

165

* @param {Function} [callback] - Completion callback

166

*/

167

mdns.response(response, rinfo, callback)

168

```

169

170

**Response Format Options:**

171

172

```javascript { .api }

173

// Array of answer records

174

mdns.respond([{

175

name: 'example.local',

176

type: 'A',

177

ttl: 300,

178

data: '192.168.1.5'

179

}]);

180

181

// Full packet object

182

mdns.respond({

183

answers: [{name: 'example.local', type: 'A', data: '192.168.1.5'}]

184

});

185

```

186

187

### Packet Transmission

188

189

Low-level packet sending for custom DNS operations.

190

191

```javascript { .api }

192

/**

193

* Send a raw DNS packet

194

* @param {Object} packet - DNS packet object

195

* @param {Object} [rinfo] - Target address information

196

* @param {Function} [callback] - Completion callback

197

*/

198

mdns.send(packet, rinfo, callback)

199

```

200

201

### Instance Management

202

203

Control the lifecycle and network configuration of mDNS instances.

204

205

```javascript { .api }

206

/**

207

* Destroy the mDNS instance and close the UDP socket

208

* @param {Function} [callback] - Completion callback

209

*/

210

mdns.destroy(callback)

211

212

/**

213

* Update multicast group memberships for current network interfaces

214

*/

215

mdns.update()

216

```

217

218

## Events

219

220

### DNS Packet Events

221

222

```javascript { .api }

223

/**

224

* Emitted for all incoming DNS packets

225

* @param {Object} packet - Decoded DNS packet

226

* @param {Object} rinfo - Remote address information

227

*/

228

mdns.on('packet', function(packet, rinfo) {})

229

230

/**

231

* Emitted for incoming DNS query packets

232

* @param {Object} query - DNS query packet

233

* @param {Object} rinfo - Remote address information

234

*/

235

mdns.on('query', function(query, rinfo) {})

236

237

/**

238

* Emitted for incoming DNS response packets

239

* @param {Object} response - DNS response packet

240

* @param {Object} rinfo - Remote address information

241

*/

242

mdns.on('response', function(response, rinfo) {})

243

```

244

245

### Lifecycle Events

246

247

```javascript { .api }

248

/**

249

* Emitted when the socket is bound and ready to send/receive

250

*/

251

mdns.on('ready', function() {})

252

253

/**

254

* Emitted when network interface memberships are updated

255

*/

256

mdns.on('networkInterface', function() {})

257

```

258

259

### Error Events

260

261

```javascript { .api }

262

/**

263

* Emitted for critical socket errors (EACCES, EADDRINUSE)

264

* @param {Error} error - Error object

265

*/

266

mdns.on('error', function(error) {})

267

268

/**

269

* Emitted for non-critical errors and warnings

270

* @param {Error} error - Error object

271

*/

272

mdns.on('warning', function(error) {})

273

```

274

275

## Data Structures

276

277

### DNS Packet Structure

278

279

```javascript { .api }

280

interface DNSPacket {

281

type: 'query' | 'response';

282

questions: Question[];

283

answers: Record[];

284

authorities: Record[];

285

additionals: Record[];

286

flags?: number;

287

flag_aa?: boolean; // Authoritative Answer flag

288

}

289

```

290

291

### Question Structure

292

293

```javascript { .api }

294

interface Question {

295

name: string; // Domain name (e.g., 'example.local')

296

type: string; // Record type ('A', 'AAAA', 'SRV', 'PTR', 'TXT', 'HINFO', 'ANY')

297

class: string; // Usually 'IN'

298

}

299

```

300

301

### Record Structure

302

303

```javascript { .api }

304

interface Record {

305

name: string; // Domain name

306

type: string; // Record type

307

class: string; // Usually 'IN'

308

ttl: number; // Time to live in seconds

309

data: any; // Record-specific data (see Record Data Types)

310

flush?: boolean; // Cache flush bit for mDNS

311

}

312

```

313

314

### Record Data Types

315

316

```javascript { .api }

317

// A Record - IPv4 address

318

// data: string (e.g., '192.168.1.5')

319

320

// AAAA Record - IPv6 address

321

// data: string (e.g., 'fe80::5ef9:38ff:fe8c:ceaa')

322

323

// SRV Record - Service record

324

// data: {

325

// port: number, // Service port number

326

// target: string, // Target hostname

327

// priority: number, // Priority value (lower = higher priority)

328

// weight: number // Weight for same priority services

329

// }

330

331

// TXT Record - Text data

332

// data: Buffer[] | string[] // Array of text strings or buffers

333

334

// PTR Record - Pointer record

335

// data: string // Target domain name

336

337

// HINFO Record - Host information

338

// data: {

339

// cpu: string, // CPU type

340

// os: string // Operating system

341

// }

342

```

343

344

### Remote Info Structure

345

346

```javascript { .api }

347

interface RemoteInfo {

348

address: string; // Remote IP address

349

port: number; // Remote port number

350

family: string; // 'IPv4' or 'IPv6'

351

size: number; // Message size in bytes

352

}

353

```

354

355

## Usage Examples

356

357

### Service Discovery

358

359

```javascript

360

const mdns = require('multicast-dns')();

361

362

// Discover all services

363

mdns.query('_services._dns-sd._udp.local', 'PTR');

364

365

mdns.on('response', function(response) {

366

response.answers.forEach(function(answer) {

367

if (answer.type === 'PTR') {

368

console.log('Found service:', answer.data);

369

}

370

});

371

});

372

```

373

374

### Service Advertisement

375

376

```javascript

377

const mdns = require('multicast-dns')();

378

379

mdns.on('query', function(query) {

380

query.questions.forEach(function(question) {

381

if (question.name === '_http._tcp.local' && question.type === 'PTR') {

382

mdns.respond({

383

answers: [{

384

name: '_http._tcp.local',

385

type: 'PTR',

386

ttl: 120,

387

data: 'My Web Server._http._tcp.local'

388

}],

389

additionals: [{

390

name: 'My Web Server._http._tcp.local',

391

type: 'SRV',

392

ttl: 120,

393

data: {

394

port: 8080,

395

target: 'my-server.local',

396

priority: 0,

397

weight: 5

398

}

399

}, {

400

name: 'my-server.local',

401

type: 'A',

402

ttl: 120,

403

data: '192.168.1.100'

404

}]

405

});

406

}

407

});

408

});

409

```

410

411

### IPv6 Configuration

412

413

**Important**: IPv6 multicast requires both `ip` and `interface` options to be specified or it will throw an error.

414

415

```javascript

416

const mdns = require('multicast-dns')({

417

type: 'udp6',

418

ip: 'ff02::fb', // Required for IPv6

419

interface: 'eth0' // Required for IPv6

420

});

421

422

mdns.query('example.local', 'AAAA');

423

424

// This will throw an error:

425

// const mdns = require('multicast-dns')({type: 'udp6'}); // Missing ip and interface

426

```

427

428

### Custom Network Interface

429

430

```javascript

431

const mdns = require('multicast-dns')({

432

interface: '192.168.1.100', // Bind to specific interface

433

port: 5353

434

});

435

436

// Listen on multiple interfaces

437

const mdns2 = require('multicast-dns')({

438

interface: ['192.168.1.100', '10.0.0.100']

439

});

440

```

441

442

## Error Handling

443

444

The library categorizes errors into critical and non-critical types:

445

446

- **Critical errors** (emit 'error'): EACCES (permission denied), EADDRINUSE (port in use)

447

- **Non-critical errors** (emit 'warning'): Invalid DNS packets, network interface issues, socket warnings

448

449

```javascript

450

const mdns = require('multicast-dns')();

451

452

mdns.on('error', function(err) {

453

console.error('Critical error:', err.message);

454

// Handle critical errors - may need to recreate instance

455

});

456

457

mdns.on('warning', function(err) {

458

console.warn('Warning:', err.message);

459

// Handle warnings - instance continues operating

460

});

461

```