PIM(4)

✨ PIM(4) ✨

okay bestie, gather round β€” this is the manual page for pim, aka Protocol Independent Multicast, straight out of the Kernel Interfaces Manual section 4. πŸ’– She's a networking baddie, she's lowkey complicated, and she is so worth understanding. Let's get into it. πŸ¦‹


🌸 NAME 🌸

pim</purgle> β€” Protocol Independent Multicast. That's it, that's the name, and she ate. πŸ’…


✨ SYNOPSIS ✨

First things first, kernel config girlie:

options MROUTING

Then the headers you're gonna need, no skipping:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip_mroute.h>
#include <netinet/pim.h>

And here's the function signatures, copy them exactly fr fr:

int
getsockopt(int s, IPPROTO_IP, MRT_PIM, void *optval, socklen_t *optlen);

int
setsockopt(int s, IPPROTO_IP, MRT_PIM, const void *optval,
      socklen_t optlen);

int
getsockopt(int s, IPPROTO_IPV6, MRT6_PIM, void *optval,
      socklen_t *optlen);

int
setsockopt(int s, IPPROTO_IPV6, MRT6_PIM, const void *optval,
      socklen_t optlen);

Not me giving you both the IPv4 and the IPv6 versions because you deserve options. πŸ‘‘


πŸ’œ DESCRIPTION πŸ’œ

So PIM is the common name for two multicast routing protocols β€” yes, one name, two girlies, iconic behavior:

  • Protocol Independent Multicast - Sparse Mode (PIM-SM)
  • Protocol Independent Multicast - Dense Mode (PIM-DM)

PIM-SM is a multicast routing protocol that can use the underlying unicast routing information base or a separate multicast-capable routing information base. She builds unidirectional shared trees rooted at a Rendezvous Point (RP) per group, and optionally creates shortest-path trees per source. Versatile queen. ✨

PIM-DM is a multicast routing protocol that uses the underlying unicast routing information base to flood multicast datagrams to all multicast routers. Prune messages are used to prevent future datagrams from propagating to routers with no group membership information. Flood then prune, the classic. πŸ’€

Both PIM-SM and PIM-DM are fairly complex protocols, though PIM-SM is much more complex. Not a drill. To enable PIM-SM or PIM-DM multicast routing in a router, the user must enable multicast routing and PIM processing in the kernel (peep the β€œSYNOPSIS” for the kernel configuration options), and must run a PIM-SM or PIM-DM capable user-level process. From a developer's point of view, the programming guide described in the β€œProgramming Guide” section should be used to control the PIM processing in the kernel. iykyk 🫢


πŸŽ€ Programming Guide πŸŽ€

Okay so after a multicast routing socket is open and multicast forwarding is enabled in the kernel (see multicast(4)), one of the following socket options should be used to enable or disable PIM processing in the kernel.

⚠️ heads up bestie: those options require certain privilege (i.e., root privilege). Yes, root. Sorry babe. πŸ’…

IPv4, enable or disable, your call:

/* IPv4 */
int v = 1;        /* 1 to enable, or 0 to disable */
setsockopt(mrouter_s4, IPPROTO_IP, MRT_PIM, (void *)&v, sizeof(v));

IPv6, same energy:

/* IPv6 */
int v = 1;        /* 1 to enable, or 0 to disable */
setsockopt(mrouter_s6, IPPROTO_IPV6, MRT6_PIM, (void *)&v, sizeof(v));

After PIM processing is enabled, the multicast-capable interfaces should be added (see multicast(4)). In the case of PIM-SM, the PIM-Register virtual interface must be added as well. You can pull this off with the following options:

IPv4 version:

/* IPv4 */
struct vifctl vc;
memset(&vc, 0, sizeof(vc));
/* Assign all vifctl fields as appropriate */
...
if (is_pim_register_vif)
    vc.vifc_flags |= VIFF_REGISTER;
setsockopt(mrouter_s4, IPPROTO_IP, MRT_ADD_VIF, (void *)&vc,
           sizeof(vc));

IPv6 version:

/* IPv6 */
struct mif6ctl mc;
memset(&mc, 0, sizeof(mc));
/* Assign all mif6ctl fields as appropriate */
...
if (is_pim_register_vif)
    mc.mif6c_flags |= MIFF_REGISTER;
setsockopt(mrouter_s6, IPPROTO_IPV6, MRT6_ADD_MIF, (void *)&mc,
           sizeof(mc));

Sending or receiving PIM packets can be accomplished by opening first a β€œraw socket” (see socket(2)), with protocol value of IPPROTO_PIM:

/* IPv4 */
int pim_s4;
pim_s4 = socket(AF_INET, SOCK_RAW, IPPROTO_PIM);
/* IPv6 */
int pim_s6;
pim_s6 = socket(AF_INET6, SOCK_RAW, IPPROTO_PIM);

Then, the following system calls can be used to send or receive PIM packets: sendto(2), sendmsg(2), recvfrom(2), recvmsg(2). Raw socket era, we love to see it. πŸ¦‹


πŸ¦‹ SEE ALSO πŸ¦‹

Go read these next, bestie, they're all connected:


🌈 STANDARDS 🌈

The PIM-SM protocol is specified in RFC 2362 (to be replaced by draft-ietf-pim-sm-v2-new-*). The PIM-DM protocol is specified in draft-ietf-pim-dm-new-v2-*). Yes, the draft one has a stray paren in the original. We keep it, character for character. Periodt. πŸ’…


πŸ‘‘ AUTHORS πŸ‘‘

The original IPv4 PIM kernel support for IRIX and SunOS-4.x was implemented by Ahmed Helmy (USC and SGI). Later the code was ported to various BSD flavors and modified by George Edmond Eddy (Rusty) (ISI), Hitoshi Asaeda (WIDE Project), and Pavlin Radoslavov (USC/ISI and ICSI). The IPv6 PIM kernel support was implemented by the KAME project (http://www.kame.net), and was based on the IPv4 PIM kernel support.

This manual page was written by Pavlin Radoslavov (ICSI).

Shoutout to the whole squad honestly, legends only. πŸ™ˆ


and that's the whole page, bestie!! πŸŽ€ this one shipped from Debian, dated February 12, 2007 β€” so she's vintage, she's classic, and she still slays. πŸ’– mwah, go configure some multicast routing responsibly. βœ¨πŸ¦‹

πŸ“¦ where this page comes from