summaryrefslogtreecommitdiff
path: root/igmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'igmp.c')
-rw-r--r--igmp.c54
1 files changed, 30 insertions, 24 deletions
diff --git a/igmp.c b/igmp.c
index 784ed2f..3795060 100644
--- a/igmp.c
+++ b/igmp.c
@@ -4,11 +4,13 @@
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
+#include <net/if.h>
#include <netinet/ip.h>
#include <linux/bpf.h>
#include <linux/filter.h>
#include <arpa/inet.h>
#include <errno.h>
+#include <sys/ioctl.h>
/* Remove later */
#include <time.h>
@@ -491,6 +493,11 @@ igmp_init(struct cfg *cfg)
int sfd;
int opt;
+ if (!cfg->do_igmp) {
+ debug(DBG_IGMP, "igmp snooping disabled\n");
+ return;
+ }
+
igmp = zmalloc(sizeof(*igmp));
if (!igmp)
return;
@@ -502,44 +509,42 @@ igmp_init(struct cfg *cfg)
sfd = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_ALL));
if (sfd < 0) {
if (errno == EACCES || errno == EPERM)
- verbose("permission denied\n");
+ error("permission denied\n");
else
- error("socket: %m (%i)\n", errno);
+ error("%m\n");
goto out_free;
}
if (setsockopt(sfd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0)
- perrordie("igmp setsockopt(SO_ATTACH_FILTER): %m");
+ die("setsockopt(SO_ATTACH_FILTER): %m");
if (setsockopt(sfd, SOL_SOCKET, SO_LOCK_FILTER, &opt, sizeof(opt)) < 0)
- perrordie("igmp setsockopt(SO_LOCK_FILTER): %m");
+ die("setsockopt(SO_LOCK_FILTER): %m");
- /*
- struct ifreq ifreq = {
- .ifr_name = "enp8s0",
- .ifr_ifindex = 0,
- };
+ if (cfg->igmp_iface) {
+ struct ifreq ifreq;
+ int r;
- strcpy(ifreq.ifr_name, "enp8s0");
+ r = snprintf(ifreq.ifr_name, sizeof(ifreq.ifr_name),
+ "%s", cfg->igmp_iface);
+ if (r < 0 || r >= sizeof(ifreq.ifr_name))
+ die("invalid interface name");
- if (ioctl(sfd, SIOCGIFINDEX, &ifreq) < 0) {
- perror("ioctl");
- exit(EXIT_FAILURE);
- }
+ if (ioctl(sfd, SIOCGIFINDEX, &ifreq) < 0)
+ perrordie("ioctl");
- fprintf(stderr, "Ifindex = %i\n", ifreq.ifr_ifindex);
+ debug(DBG_IGMP, "using interface %s (%i)\n",
+ cfg->igmp_iface, ifreq.ifr_ifindex);
- struct packet_mreq mreq = {
- .mr_ifindex = ifreq.ifr_ifindex,
- .mr_type = PACKET_MR_ALLMULTI
- };
+ struct packet_mreq mreq = {
+ .mr_ifindex = ifreq.ifr_ifindex,
+ .mr_type = PACKET_MR_ALLMULTI
+ };
- r = setsockopt(sfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
- if (r < 0) {
- perror("setsockopt");
- exit(EXIT_FAILURE);
+ if (setsockopt(sfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
+ &mreq, sizeof(mreq)) < 0)
+ die("setsockopt(PACKET_ADD_MEMBERSHIP): %m");
}
- */
/* can't set .sll_protocol to htons(ETH_P_IP), see comment above */
if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
@@ -547,6 +552,7 @@ igmp_init(struct cfg *cfg)
goto out_fd;
}
+ debug(DBG_IGMP, "init successful, using fd %i\n", sfd);
uring_task_init(&igmp->task, "igmp", uring_parent(cfg), igmp_free);
uring_task_set_fd(&igmp->task, sfd);
uring_task_set_buf(&igmp->task, &igmp->tbuf);