Skip to content

Instantly share code, notes, and snippets.

@ceclinux
Created July 7, 2022 10:22
Show Gist options
  • Save ceclinux/30bbc142bc7a6b51876296b165428788 to your computer and use it in GitHub Desktop.
Save ceclinux/30bbc142bc7a6b51876296b165428788 to your computer and use it in GitHub Desktop.
IP_BLOCK_SOURCE or IP_DROP_MEMBERSHIP does not have an effect for igmp socket
# ip of enp0s8: 192.168.50.98
mcjoin -i enp0s8 -t 200 -f 500 -s 224.20.30.40
#include <stdio.h> /* printf(), snprintf() */
#include <stdlib.h> /* strtol(), exit() */
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h> /* socket(), setsockopt(), bind(),
recvfrom(), sendto() */
#include <errno.h> /* perror() */
#include <netinet/in.h> /* IPPROTO_IP, sockaddr_in, htons(),*/
#include <linux/mroute.h>
#include <arpa/inet.h> /* inet_addr() */
#include <unistd.h> /* fork(), sleep() */
#include <sys/utsname.h> /* uname() */
#include <string.h> /* memset() */
int main (int argc, char *argv[])
{
struct sockaddr_in localSock;
struct ip_mreq group;
struct ip_mreq_source source_group;
int recvfd;
int datalen, ret;
int buflen = 128;
char igmpbuf[buflen];
// create socket
recvfd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
int v = 1;
setsockopt(recvfd, IPPROTO_IP, MRT_INIT, (void *)&v, sizeof(v));
// assign vif
struct vifctl vc;
memset(&vc, 0, sizeof(vc));
vc.vifc_vifi = 3;
vc.vifc_flags = 0;
vc.vifc_flags |= 8;
vc.vifc_rate_limit = 0;
vc.vifc_lcl_ifindex = 3;
setsockopt(recvfd, IPPROTO_IP, MRT_ADD_VIF, (void *)&vc,
sizeof(vc));
// join group
group.imr_multiaddr.s_addr = inet_addr("224.20.30.40");
group.imr_interface.s_addr = inet_addr("192.168.50.155");
setsockopt(recvfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char *)&group, sizeof(group));
// block source from 192.168.50.98, comment this code block out affects
// nothing.
source_group.imr_multiaddr.s_addr = inet_addr("224.20.30.40");
source_group.imr_interface.s_addr = inet_addr("192.168.50.155");
source_group.imr_sourceaddr.s_addr = inet_addr("192.168.50.98");
setsockopt(recvfd, IPPROTO_IP, IP_BLOCK_SOURCE,
(char *)&source_group, sizeof(source_group));
// Read from the socket.
datalen = sizeof(igmpbuf);
while (1){
bzero(igmpbuf, buflen);
ret = read(recvfd, igmpbuf, datalen);
if (igmpbuf[9] == 0 && igmpbuf[15] == 98 ){
printf("\nlen: %d\n", ret);
for (int i=0; i < ret; i++){
// will receive IGMPMSG from 192.168.50.98
printf("%d %#x \n",i, igmpbuf[i]);
}
}
}
close(recvfd);
return 0;
}
#include <stdio.h> /* printf(), snprintf() */
#include <stdlib.h> /* strtol(), exit() */
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h> /* socket(), setsockopt(), bind(),
recvfrom(), sendto() */
#include <errno.h> /* perror() */
#include <netinet/in.h> /* IPPROTO_IP, sockaddr_in, htons(),*/
#include <linux/mroute.h>
#include <arpa/inet.h> /* inet_addr() */
#include <unistd.h> /* fork(), sleep() */
#include <sys/utsname.h> /* uname() */
#include <string.h> /* memset() */
int main (int argc, char *argv[])
{
struct sockaddr_in localSock;
struct ip_mreq group;
struct ip_mreq_source source_group;
int recvfd;
int datalen, ret;
char igmpbuf[128];
// Create a datagram socket on which to receive.
recvfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
// Bind to the proper port number with the IP address
// specified as INADDR_ANY.
memset((char *) &localSock, 0, sizeof(localSock));
localSock.sin_family = AF_INET;
localSock.sin_port = htons(1234);;
localSock.sin_addr.s_addr = INADDR_ANY;
bind(recvfd, (struct sockaddr*)&localSock, sizeof(localSock));
// Join multicast group
group.imr_multiaddr.s_addr = inet_addr("224.20.30.40");
group.imr_interface.s_addr = inet_addr("192.168.50.155");
setsockopt(recvfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char *)&group, sizeof(group));
// block source from 192.168.50.98, comment this code block the socket will
// able to receiver udp traffic from 192.168.50.98
source_group.imr_multiaddr.s_addr = inet_addr("224.20.30.40");
source_group.imr_interface.s_addr = inet_addr("192.168.50.155");
source_group.imr_sourceaddr.s_addr = inet_addr("192.168.50.98");
// both IP_BLOCK_SOURCE and IP_DROP_SOURCE_MEMBERSHIP works
setsockopt(recvfd, IPPROTO_IP, IP_BLOCK_SOURCE,
(char *)&source_group, sizeof(source_group));
// Read from the socket.
datalen = sizeof(igmpbuf);
while (1){
bzero(igmpbuf, 128);
ret = read(recvfd, igmpbuf, datalen);
printf("\nlen: %x\n", ret);
for (int i=0; i < ret; i++){
printf("%d %#x \n",i, igmpbuf[i]);
}
}
close(recvfd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment