- Linux built-in or open source program to join multicast group?
- 5 Answers 5
- Net-Labs.in
- Network, ISP
- Маршрутизация multicast в Linux
- Статическая маршрутизация multicast
- Ренамберинг мультикаст групп
- Прочее
- Multicast Join on Linux and IGMPv3
- 1 Answer 1
- Linux — How to Join Multicast Group
- Enabling / Disabling on an Interface
- IP Ranges and Groups
- Setting Up Multicast on Linux
- Testing
- |Winsock & .NET | Winsock | | Linux Socket Index | The TCP/IP Stack > |
- LINUX SOCKET PART 13: MULTICAST
- Network Story 2
- Network Story 4
- Network Story 6
- Socket Example 2
- Socket Example 4
- Socket Example 6
- Advanced TCP/IP 1
- Advanced TCP/IP 3
- Advanced TCP/IP 5
Linux built-in or open source program to join multicast group?
I’m using tcpdump to capture multicast packets and had to code up a custom program to join multicast feeds so tcpdump will «see» the packets. Just wondering if netcat or any other applications can perform this function instead?
5 Answers 5
You can do this using the ip maddr add command.
SYNTAX
DESCRIPTION
It attaches/detaches a static link layer multicast address to listen on the interface. Note that it is impossible to join protocol multicast groups statically. This command only manages link layer addresses.
EXAMPLES
Example for a wired connection:
Example for a wireless connection:
One can use socat to subscribe to groups. This works nicely for both L2 and L3 subscription:
This will subscribe to group 239.0.1.68 using the interface with address 10.100.201.1 . The UDP4-DATAGRAM:239.101.1.68:8889 bit listens for packets on a dummy group and udp port that should not receive any data to prevent socat from also outputting everything to stdout. If, instead, you want to direct the payload to stdout, change that group and port to be actual group and port that you want to subscribe to.
Multiple comma-separated ip-add-membership directives can be specified to subscribe to multiple groups at the same time. When socat exits, it seems to clear out the IGMP subscriptions too.
Источник
Net-Labs.in
Network, ISP
Маршрутизация multicast в Linux
В современных реалиях, скорее всего, нет смысла заниматься маршрутизацией(репликацией) multicast-трафика с помощью софтроутеров(будь то ядро Linux или что-то иное). Причина довольно простая – даже дешёвые свитчи умеют L2/L3-multicast(хоть и с ограничениями по количеству групп/маршрутов, но всё же это делается в asic-ах). Однако, существует ряд задач, которые могут быть не решены в “железе” (нет поддержки со стороны ПО/невозможно реализовать ввиду возможностей asic), например ренамберинг(изменение destination ip), внесение случайных задержек(перемешивание), отправка multicast в тунель, резервирование источника по произвольному критерию.
Зачем может потребоваться ренамберинг мультикаст группы? Во-первых, маппинг IP-mac неодназначен(например, группам 238.1.1.1 и 239.1.1.1 соответствует один и тот же mac-адрес), что может вызвать проблемы в L2-сегменте. Конечно, такая коллизия маловероятна, однако возможна, когда вы берёте multicast из разных внешних источников(в принципе, IP-адреса могут даже полностью совпасть). Во-вторых, вы можете захотеть скрыть свой источник, изменив и destination и source адрес. В destination может быть “спрятан” номер AS источника(RFC3180), по source тоже можно догадаться об источнике, если он не серый. В третьих, перенумеровать группу может потребоваться для избежания коллизии на оборудовании, где заканчивается TCAM под multicast (как временное решение до замены оборудования/изменения схемы сети). И наконец, вы решили зарезервировать ТВ-каналы путём их получения из разных источников(т.е. вливать на сервер 2 разных группы(но одинаковых по контенту) и забирать из него одну, результирующую(работающую))
Внести случайную задержку(reordering) или потери может потребоваться для проверки поведения используемых STB/soft-плееров. Например, вам интересно, как будет выглядеть картинка, если где-то на сети мультикаст пройдёт через per-packet балансировку и не зависнет ли плеер при наличии потери пакетов, будут ли издаваться неприятные скрипящие звуки или же просто квадратики и тишина.
При написании этой заметки использовался Ubuntu Linux 14.04 LTS (ядро 3.13.0-24-generic), но применимо для большинства современных дистрибутивов, однако необходимо проверить поддержку IPv4 multicast в ядре:
В отличии от unicast роутинга, утилиты ip недостаточно даже для статической (S, G) маршрутизации, не говоря уже про динамическую. Для формирования таблицы мультикаст-репликации требуются “сторонние” userspace-утилиты. Например, для статических маршрутов это smcroute, для построения таблицы по igmp-запросам с даунлинк-интерфейсов – igmpproxy(маршрут добавляется в ядро тогда, когда “снизу” приходит igmp-запрос), для работы с PIM-SM сигнализацией – pimd(требуется поддержка PIMSM_V2 со стороны ядра).
Статическая маршрутизация multicast
Рассмотрим следующую задачу: осуществить репликацию мультикаст-трафика (*, 233.251.240.1) с интерфейса eth1 на интерфейсы eth2 и eth3, при этом на eth1 эта группа приходит только по igmpv2-запросу.
Конфигурация интерфейсов выглядет следующим образом:
К сожаленью, smcroute в ubuntu 14.04 не поддерживает (*, G)-форму, поэтому придётся скомпилировать из исходников:
Прежде чем запускать маршрутизацию(инсталлировать маршруты в ядро), нужно отключить RPF на интерфейсе eth1(поскольку по условию задачи считаем, что source ip multicast-группы может быть произвольным):
Кроме того, устанавливаем явным образом режим работы igmp на интерфейсе eth1:
Теперь переходим к конфигурации smcroute(/etc/smcroute.conf):
(необходим перевод строки в конце конфигурации)
Первая строчка – подключить группу по протоколу igmp(залить эту информацию в ядро), вторая – собственно мультикаст-маршрут.
Запускаем smcroute:
(логи пишутся в syslog)
Проверяем таблицу igmp:
Всё верно, 01F0FBE9 это наша группа 233.251.240.1.
До того, как в eth1 польётся мультикаст, таблица маршрутизации в ядре будет выглядеть таким образом:
Затем примет такой вид:
Проверяем работу репликации:
Ренамберинг мультикаст групп
Для того, чтобы изменить IP multicast группы используем DNAT. Например, мы хотим изменить 233.251.240.1 на 233.251.250.5:
/etc/smcroute.conf будет выглядеть следующим образом:
(в маршруте фигурирует новый адрес по причине того, что DNAT делается в PREROUTING-е)
Далее, чистим conntrack(командой “conntrack -F”) и проверяем:
Как нетрудно догадаться, чтобы подменить ещё и source ip, будем использовать SNAT:
Снова чистим conntrack(“conntrack -F”) и проверяем:
Прочее
С помощью iptables и tc можно ещё что-нибудь сделать с трафиком(внести задержки и потери, например). При желании, можно организовать резервирование ТВ-канала путём переключения источника вещания с помощью скриптов(smcroute-ом можно управлять “извне”), придумав произвольные критерии выбора лучшего источника(подобные решения для операторов существуют и стоят больших денег)
Источник
Multicast Join on Linux and IGMPv3
We’ve run into a thorny problem. We are writing a c++ program that receives multicast UDP traffic. We’re in the process of moving our applications to a different network environment and our operations team has requested that we support IGMPv3 membership announcements from our applications. Initial investigations indicate that Linux 2.6 kernels do support IGMPv3. Therefore, I’m puzzled that when we run tcpdump we see the following output traces:
My understanding is that one could force the kernel to use a lower version of IGMP by specifying a non-zero value in the file /proc/sys/net/ipv4/conf/eth1.22/force_igmp_version; however, I’ve confirmed that the file has a zero value configuration.
Our application is using the following code to join the multicast group:
Is there something extra that we need to include in the source program to force IGMPv3?
1 Answer 1
Couple of things to be aware of.
The first is that (as I understand it) setting the /proc/sys/net/ipv4/conf/eth1.22/force_igmp_version to 0 doesn’t mean «use v3», but actually sets it to «auto». I beleive that you can set it to 3 to force it use igmp v3.
However, the other thing to be aware of is that the behavior of the igmp stack is determined by the environment that it finds itself in. If your linux box is receiving igmp v2 membership queries from an upstream igmp router, then I believe that the default linux behavior (as mandated by the igmp v3 rfc) is to use only igmp v2 for reports.
As I understand it when you set /proc/sys/net/ipv4/conf/eth1.22/force_igmp_version to 0 it uses this behavior.
Источник
Linux — How to Join Multicast Group
Joining a multicast group from Linux is easy ( sort of ). I’ve done minimal testing so use this information at your own risk.
To join a multicast group on Linux, just start listening on a UDP port using a multicast IP address like this:
For more details about how to use this tool, keep reading.
Enabling / Disabling on an Interface
Assuming your interface is named вЂeno2’ you can use the following.
Check if multicast is enabled on an interface. If it is enabled you will see the word “MULTICAST” otherwise you won’t.
Enable multicast on an interface:
Disable multicast on an interface:
IP Ranges and Groups
224.0.0.0 – 239.255.255.255 | Class D addresses are used for multicast |
224.0.0.0 — 224.0.0.255 | Reserved for local use, never forwarded |
239.0.0.0 — 239.255.255.255 | Reserved for administrative scoping |
224.0.0.1 | all hosts group |
224.0.0.2 | all multicast routers group |
224.0.0.4 | all DVMRP routers |
224.0.0.5 | all OSPF routers |
224.0.013 | all PIM routers |
- 224.0.0.1 all hosts join this at start up if they are multicast capable.
To find all hosts with multicast enabled, run:
Setting Up Multicast on Linux
I believe this will give you a multicast router. You may need to enable routing in the kernel. I haven’t tested this.
Enable multicast on the interface like this:
Add a route for a class D network:
Sniff multicast traffic on this interface. If you see any packets it is working:
The following will show multicast addresses:
Testing
There is a nice tool for testing multicast. You can find it on GitHub here:
You can pull down the zip file here:
Unzip it, enter the directory, and run “make” to build it.
Once built it will give you the “msend” and “mreceive” tools that can be run directly from that directory.
Open two terminals.
On the first terminal, run the following command. This will start listening on port 2222. It also joins the multicast group 224.2.2.2.
On the second terminal, run the following command:
It should show the IP of 224.2.2.2 indicating that it has joined that group.
Now start sending packets from the second terminal like this:
You should see these coming through and being output on the first terminal.
- Type [ctrl] — c on both terminals to stop.
Once you’ve done this you can verify that it is no longer a member of the group like this:
You should see that it now displays nothing indicating that it has left the group. As soon as the receive command stops, it will leave the group.
It is worth noting that ssmping is a tool that some people use to test multicast networks. I don’t have a ton of background with this tool but some people find it useful.
Источник
|Winsock & .NET | Winsock | | Linux Socket Index | The TCP/IP Stack > |
LINUX SOCKET PART 13: MULTICAST
Network Story 2
Network Story 4
Network Story 6
Socket Example 2
Socket Example 4
Socket Example 6
Advanced TCP/IP 1
Advanced TCP/IP 3
Advanced TCP/IP 5
Working program examples if any compiled using gcc , tested using the public IPs, run on Linux Fedora 3 with several times update, as normal user. The Fedora machine used for the testing having the » No Stack Execute » disabled and the SELinux set to default configuration. All the program example is generic. Beware codes that expand more than one line.
Example: Sending and receiving a multicast datagram
IP multicasting provides the capability for an application to send a single IP datagram that a group of hosts in a network can receive. The hosts that are in the group may reside on a single subnet or may be on different subnets that have been connected by multicast capable routers.
Hosts may join and leave groups at any time. There are no restrictions on the location or number of members in a host group. A class D Internet address in the range 224.0.0.1 to 239.255.255.255 identifies a host group.
An application program can send or receive multicast datagrams by using the socket() API and connectionless SOCK_DGRAM type sockets. Each multicast transmission is sent from a single network interface, even if the host has more than one multicasting-capable interface.
It is a one-to-many transmission method. You cannot use connection-oriented sockets of type SOCK_STREAM for multicasting.
When a socket of type SOCK_DGRAM is created, an application can use the setsockopt() function to control the multicast characteristics associated with that socket. The setsockopt() function accepts the following IPPROTO_IP level flags:
IP_ADD_MEMBERSHIP: Joins the multicast group specified.
IP_DROP_MEMBERSHIP: Leaves the multicast group specified.
IP_MULTICAST_IF: Sets the interface over which outgoing multicast datagrams are sent.
IP_MULTICAST_TTL: Sets the Time To Live (TTL) in the IP header for outgoing multicast datagrams. By default it is set to 1. TTL of 0 are not transmitted on any sub-network. Multicast datagrams with a TTL of greater than 1 may be delivered to more than one sub-network, if there are one or more multicast routers attached to the first sub-network.
IP_MULTICAST_LOOP: Specifies whether or not a copy of an outgoing multicast datagram is delivered to the sending host as long as it is a member of the multicast group.
The following examples enable a socket to send and receive multicast datagrams. The steps needed to send a multicast datagram differ from the steps needed to receive a multicast datagram.
Example: Sending a multicast datagram, a server program
The following example enables a socket to perform the steps listed below and to send multicast datagrams:
Create an AF_INET, SOCK_DGRAM type socket.
Initialize a sockaddr_in structure with the destination group IP address and port number.
Set the IP_MULTICAST_LOOP socket option according to whether the sending system should receive a copy of the multicast datagrams that are transmitted.
Set the IP_MULTICAST_IF socket option to define the local interface over which you want to send the multicast datagrams.
Send the datagram.
[bodo@bakawali testsocket]$ cat mcastserver.c
/* Send Multicast Datagram code example. */
struct sockaddr_in groupSock;
char databuf[1024] = «Multicast test message lol!»;
int datalen = sizeof(databuf);
int main (int argc, char *argv[ ])
/* Create a datagram socket on which to send. */
sd = socket(AF_INET, SOCK_DGRAM, 0);
perror(«Opening datagram socket error»);
printf(«Opening the datagram socket. OK.\n»);
/* Initialize the group sockaddr structure with a */
/* group address of 225.1.1.1 and port 5555. */
/* Disable loopback so you do not receive your own datagrams.
if(setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopch, sizeof(loopch))
perror(«Setting IP_MULTICAST_LOOP error»);
printf(«Disabling the loopback. OK.\n»);
/* Set local interface for outbound multicast datagrams. */
/* The IP address specified must be associated with a local, */
/* multicast capable interface. */
if(setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, (char *)&localInterface, sizeof(localInterface))
perror(«Setting local interface error»);
printf(«Setting the local interface. OK\n»);
/* Send a message to the multicast group specified by the*/
/* groupSock sockaddr structure. */
/*int datalen = 1024;*/
if(sendto(sd, databuf, datalen, 0, (struct sockaddr*)&groupSock, sizeof(groupSock))
printf(«Sending datagram message. OK\n»);
/* Try the re-read from the socket if the loopback is not disable
if(read(sd, databuf, datalen)
perror(«Reading datagram message error\n»);
printf(«Reading datagram message from client. OK\n»);
printf(«The message is: %s\n», databuf);
Compile and link the program.
[bodo@bakawali testsocket]$ gcc -g mcastserver.c -o mcastserver
Before running this multicaster program, you have to run the client program first as in the following.
Example: Receiving a multicast datagram, a client
The following example enables a socket to perform the steps listed below and to receive multicast datagrams:
Create an AF_INET, SOCK_DGRAM type socket.
Set the SO_REUSEADDR option to allow multiple applications to receive datagrams that are destined to the same local port number.
Use the bind() verb to specify the local port number. Specify the IP address as INADDR_ANY in order to receive datagrams that are addressed to a multicast group.
Use the IP_ADD_MEMBERSHIP socket option to join the multicast group that receives the datagrams. When joining a group, specify the class D group address along with the IP address of a local interface. The system must call the IP_ADD_MEMBERSHIP socket option for each local interface receiving the multicast datagrams.
Receive the datagram.
/* Receiver/client multicast Datagram example. */
Источник