Skip to content

Instantly share code, notes, and snippets.

View cmol's full-sized avatar

Claus Lensbøl cmol

View GitHub Profile
cmol@qui-gon:~$ ruby src/multicast.rb
Using local interface wlp4s0 with address fe80::71c0:aa40:6d16:7c59%wlp4s0
========= Sending echo REQUEST from fe80::71c0:aa40:6d16:7c59%wlp4s0
[REQUEST] Hello from fe80::ade4:80af:c170:6340%enp0s31f6
========= Sending echo REPLY to fe80::ade4:80af:c170:6340%wlp4s0
[REQUEST] Hello from fe80::a00:27ff:fe07:dea6%enp0s3
========= Sending echo REPLY to fe80::a00:27ff:fe07:dea6%wlp4s0
[REPLY] Hello from fe80::ade4:80af:c170:6340%enp0s31f6
def send_request(socket, linklocal_addr, multicast_addr, multicast_port,
flags)
puts "========= Sending echo REQUEST from #{linklocal_addr}"
socket.send("[REQUEST] Hello from #{linklocal_addr}",
flags, multicast_addr, multicast_port)
end
def create_socket(multicast_addr, multicast_port, ifindex)
# Create, bind, and return a UDP multicast socket
UDPSocket.new(Socket::AF_INET6).tap do | s |
ip = IPAddr.new(multicast_addr).hton + [ifindex].pack('I')
s.setsockopt(Socket::IPPROTO_IPV6, Socket::IPV6_JOIN_GROUP, ip)
s.setsockopt(Socket::IPPROTO_IPV6, Socket::IPV6_MULTICAST_HOPS, [1].pack('I'))
s.setsockopt(Socket::IPPROTO_IPV6, Socket::IPV6_MULTICAST_IF, [ifindex].pack('I'))
s.bind("::", multicast_port)
end
end
cmol@second-host:~$ ruby src/multicast.rb
Using local interface enp0s31f6 with address fe80::ade4:80af:c170:6340%enp0s31f6
[REPLY] Hello from fe80::71c0:aa40:6d16:7c59%wlp4s0
cmol@qui-gon:~$ ruby src/multicast.rb
Using local interface wlp4s0 with address fe80::71c0:aa40:6d16:7c59%wlp4s0
========= Sending echo REQUEST from fe80::71c0:aa40:6d16:7c59%wlp4s0
cmol@third-host:~$ ruby src/multicast.rb
Using local interface enp0s3 with address fe80::a00:27ff:fe07:dea6%enp0s3
========= Sending echo REQUEST from fe80::a00:27ff:fe07:dea6%enp0s3
[REPLY] Hello from fe80::71c0:aa40:6d16:7c59%wlp4s0
[REPLY] Hello from fe80::ade4:80af:c170:6340%enp0s31f6
@cmol
cmol / multicast.rb
Last active January 30, 2021 23:12
require 'socket'
require 'ipaddr'
def get_interface_info(name)
ifaddrs = Socket.getifaddrs.reject do |ifaddr|
!ifaddr.addr&.ipv6_linklocal? || (ifaddr.flags & Socket::IFF_MULTICAST == 0)
end
ifaddrs.select! {|ifaddr| ifaddr.name == name } if name
ifaddrs.map {|ifaddr| [ifaddr.name, ifaddr.ifindex, ifaddr.addr.ip_address] }
end
[["if_name", index, "ip_address"],[...]]
def echo_listener(socket, linklocal_addr, multicast_addr, multicast_port,
flags, msg_length)
loop do
# Listen for messages of up to specified length
message, client = socket.recvfrom(msg_length)
# Extract client information given as array and log connection
addr_info = Addrinfo.new(client)
# We are not interested in messages from our selves
def get_interface_info(name)
ifaddrs = Socket.getifaddrs.reject do |ifaddr|
!ifaddr.addr&.ipv6_linklocal? || (ifaddr.flags & Socket::IFF_MULTICAST == 0)
end
ifaddrs.select! {|ifaddr| ifaddr.name == name } if name
ifaddrs.map {|ifaddr| [ifaddr.name, ifaddr.ifindex, ifaddr.addr.ip_address] }
end