Open derhuerst opened 4 years ago
This is my prototype:
// const {parse: parseIpAddress} = require('ipaddr.js')
const {networkInterfaces} = require('os')
const {createSocket} = require('dgram')
const {decode} = require('dns-packet')
// const isIPv6Loopback = (address) => {
// const firstPart = parseIpAddress(address).parts[0] || 0
// return firstPart.toString(2).slice(0, 10) === '1111111010'
// }
const isProperInterface = ({family, address}) => {
// return family === 'IPv6' && !isIPv6Loopback(address)
return family === 'IPv6'
}
const awdl0 = (networkInterfaces().awdl0 || []).find(isProperInterface)
if (!awdl0) throw new Error('no awdl0 interface found')
console.error(awdl0)
// const en0 = (networkInterfaces().en0 || []).find(isProperInterface)
// if (!en0) throw new Error('no en0 interface found')
const SOL_SOCKET = 0x1
// https://github.com/torvalds/linux/blob/a2d79c7174aeb43b13020dd53d85a7aefdd9f3e5/include/uapi/asm-generic/socket.h#L27
const SO_REUSEPORT = 15
// https://opensource.apple.com/source/xnu/xnu-4570.31.3/bsd/sys/socket.h :318
const SO_RECV_ANYIF = 0x1104
// https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml
const MDNSv6_MULTICAST_GROUP = 'ff02::fb'
const AWDL_CLASS = 'UNKNOWN_32769' // todo
// const ip = '::'
const ip = awdl0.address
const scope = '%awdl0'
const onMessage = (msg) => {
const {type, questions, answers} = decode(msg)
console.log(type, questions, answers)
}
const socket = createSocket({
type: 'udp6',
reuseAddr: true,
ipv6Only: true
})
socket.bind(5353, (err) => {
// socket.bind(5353, ip, (err) => {
// socket.bind(5353, ip + scope, (err) => {
// socket.bind(5353, '::' + scope, (err) => {
if (err) {
console.error(err)
process.exit(1)
}
socket.on('error', console.error)
socket.on('message', onMessage)
// this doesn't work yet! not receiving packages :(
socket.addMembership(MDNSv6_MULTICAST_GROUP, ip + scope)
setsockopt(socket, SOL_SOCKET, SO_RECV_ANYIF, 1)
})
new Python zeroconf implementation: https://github.com/jstasiak/python-zeroconf/blob/88323d0c7866f78edde063080c63a72c6e875772/zeroconf/_utils/net.py#L216-L323
Right now, this package spawns
nc
a.k.a. netcat to listen forawdl0
traffic; This is a bit hacky, doing it from within Node via its UDP socket API/TCP socket API would be cleaner.I'm not an expert, and I failed miserably at porting these working implementations:
opendrop
, written in Python, does DNS-SD + mDNS a.k.a. Zeroconf viaawdl0
.awdl0
.