Skip to content

Commit a29fc2b

Browse files
authored
Merge branch 'pali:master' into IGMPv3-query
2 parents 133a789 + eb0aec2 commit a29fc2b

File tree

9 files changed

+65
-24
lines changed

9 files changed

+65
-24
lines changed

configure.ac

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
AC_PREREQ([2.63])
2-
AC_INIT([igmpproxy], [0.3])
2+
AC_INIT([igmpproxy], [0.4])
33
AM_INIT_AUTOMAKE
44
AC_CONFIG_SRCDIR([src/igmpproxy.c])
55
AC_CONFIG_HEADERS([config.h])
@@ -28,6 +28,12 @@ AC_CHECK_MEMBERS([struct sockaddr_in.sin_len], [], [], [[
2828
#include <netinet/in.h>
2929
]])
3030

31+
# Check for Linux-style extension struct ip_mreqn (Linux, FreeBSD)
32+
# Adopted from https://github.com/troglobit/smcroute/blob/2.5.6/configure.ac#L144
33+
AC_CHECK_MEMBER([struct ip_mreqn.imr_ifindex],
34+
AC_DEFINE([HAVE_STRUCT_IP_MREQN], [1], [Define to 1 if you have a Linux-style struct ip_mreqn]),
35+
[], [[#include <netinet/in.h>]])
36+
3137
AC_SEARCH_LIBS(socket, socket)
3238

3339
AC_SEARCH_LIBS([clock_gettime],[rt])

src/config.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ int loadConfig(char *configFile) {
192192
continue;
193193
}
194194
else if(strcmp("rescanvif", token)==0) {
195-
// Got a defaultdown token...
195+
// Got a rescanvif token...
196196
my_log(LOG_DEBUG, 0, "Config: Need detect new interface.");
197197
commonConfig.rescanVif = 1;
198198

src/ifvc.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ void rebuildIfVc () {
117117

118118
memcpy( IfReq.ifr_name, Dp->Name, sizeof( IfReq.ifr_name ) );
119119

120+
if (ioctl(Sock, SIOCGIFINDEX, &IfReq ) < 0)
121+
my_log(LOG_ERR, errno, "ioctl SIOCGIFINDEX for %s", IfReq.ifr_name);
122+
Dp->ifIndex = IfReq.ifr_ifindex;
123+
120124
// Get the subnet mask...
121125
if (ioctl(Sock, SIOCGIFNETMASK, &IfReq ) < 0)
122126
my_log(LOG_ERR, errno, "ioctl SIOCGIFNETMASK for %s", IfReq.ifr_name);
@@ -175,8 +179,9 @@ void rebuildIfVc () {
175179
}
176180

177181
// Debug log the result...
178-
my_log( LOG_DEBUG, 0, "rebuildIfVc: Interface %s Addr: %s, Flags: 0x%04x, Network: %s",
182+
my_log( LOG_DEBUG, 0, "rebuildIfVc: Interface %s Index: %d Addr: %s, Flags: 0x%04x, Network: %s",
179183
Dp->Name,
184+
Dp->ifIndex,
180185
fmtInAdr( FmtBu, Dp->InAdr ),
181186
Dp->Flags,
182187
inetFmts(subnet, mask, s1));
@@ -268,6 +273,10 @@ void buildIfVc(void) {
268273

269274
memcpy( IfReq.ifr_name, IfDescEp->Name, sizeof( IfReq.ifr_name ) );
270275

276+
if (ioctl(Sock, SIOCGIFINDEX, &IfReq ) < 0)
277+
my_log(LOG_ERR, errno, "ioctl SIOCGIFINDEX for %s", IfReq.ifr_name);
278+
IfDescEp->ifIndex = IfReq.ifr_ifindex;
279+
271280
// Get the subnet mask...
272281
if (ioctl(Sock, SIOCGIFNETMASK, &IfReq ) < 0)
273282
my_log(LOG_ERR, errno, "ioctl SIOCGIFNETMASK for %s", IfReq.ifr_name);
@@ -313,8 +322,9 @@ void buildIfVc(void) {
313322
IfDescEp->ratelimit = DEFAULT_RATELIMIT;
314323

315324
// Debug log the result...
316-
my_log( LOG_DEBUG, 0, "buildIfVc: Interface %s Addr: %s, Flags: 0x%04x, Network: %s",
325+
my_log( LOG_DEBUG, 0, "buildIfVc: Interface %s Index: %d Addr: %s, Flags: 0x%04x, Network: %s",
317326
IfDescEp->Name,
327+
IfDescEp->ifIndex,
318328
fmtInAdr( FmtBu, IfDescEp->InAdr ),
319329
IfDescEp->Flags,
320330
inetFmts(subnet,mask, s1));

src/igmp.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,16 +312,18 @@ static int buildIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t gr
312312
/*
313313
* Call build_igmp() to build an IGMP message in the output packet buffer.
314314
* Then send the message from the interface with IP address 'src' to
315-
* destination 'dst'.
315+
* destination 'dst'. If struct ip_mreqn is present on the target OS, it is
316+
* used instead of 'src' to select the sending interface. 'src' is still used
317+
* as the source IP.
316318
*/
317-
void sendIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, int datalen) {
319+
void sendIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, int datalen, int ifidx) {
318320
struct sockaddr_in sdst;
319321
int setloop = 0, setigmpsource = 0, sendlen = 0;
320322

321323
sendlen = buildIgmp(src, dst, type, code, group, datalen);
322324

323325
if (IN_MULTICAST(ntohl(dst))) {
324-
k_set_if(src);
326+
k_set_if(src, ifidx);
325327
setigmpsource = 1;
326328
if (type != IGMP_DVMRP || dst == allhosts_group) {
327329
setloop = 1;
@@ -350,7 +352,7 @@ void sendIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, in
350352
k_set_loop(false);
351353
}
352354
// Restore original...
353-
k_set_if(INADDR_ANY);
355+
k_set_if(INADDR_ANY, 0);
354356
}
355357

356358
my_log(LOG_DEBUG, 0, "SENT %s from %-15s to %s",

src/igmpproxy.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ struct SubnetList {
151151
struct IfDesc {
152152
char Name[IF_NAMESIZE];
153153
struct in_addr InAdr; /* == 0 for non IP interfaces */
154+
int ifIndex;
154155
short Flags;
155156
short state;
156157
struct SubnetList* allowednets;
@@ -234,7 +235,7 @@ extern uint32_t allrouters_group;
234235
extern uint32_t alligmp3_group;
235236
void initIgmp(void);
236237
void acceptIgmp(int);
237-
void sendIgmp (uint32_t, uint32_t, int, int, uint32_t,int);
238+
void sendIgmp (uint32_t, uint32_t, int, int, uint32_t, int, int);
238239

239240
/* lib.c
240241
*/
@@ -249,7 +250,7 @@ void k_set_rcvbuf(int bufsize, int minsize);
249250
void k_hdr_include(int hdrincl);
250251
void k_set_ttl(int t);
251252
void k_set_loop(int l);
252-
void k_set_if(uint32_t ifa);
253+
void k_set_if(uint32_t ifa, int ifidx);
253254
void k_join(struct IfDesc *ifd, uint32_t grp);
254255
void k_leave(struct IfDesc *ifd, uint32_t grp);
255256

src/kern.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,22 +100,32 @@ void k_set_loop(int l) {
100100
(char *)&loop, sizeof(loop)) < 0)
101101
my_log(LOG_WARNING, errno, "setsockopt IP_MULTICAST_LOOP %u", loop);
102102
}
103+
void k_set_if(uint32_t ifa, int ifidx) {
104+
#ifdef HAVE_STRUCT_IP_MREQN
105+
struct ip_mreqn ifsel;
106+
ifsel.imr_address.s_addr = ifa;
107+
ifsel.imr_ifindex = ifidx;
108+
#else
109+
struct in_addr ifsel;
110+
ifsel.s_addr = ifa;
111+
#endif
103112

104-
void k_set_if(uint32_t ifa) {
105-
struct in_addr adr;
106-
107-
adr.s_addr = ifa;
108113
if (setsockopt(MRouterFD, IPPROTO_IP, IP_MULTICAST_IF,
109-
(char *)&adr, sizeof(adr)) < 0)
114+
(char *)&ifsel, sizeof(ifsel)) < 0)
110115
my_log(LOG_WARNING, errno, "setsockopt IP_MULTICAST_IF %s",
111116
inetFmt(ifa, s1));
112117
}
113118

114119
void k_join(struct IfDesc *ifd, uint32_t grp) {
120+
#ifdef HAVE_STRUCT_IP_MREQN
121+
struct ip_mreqn mreq;
122+
mreq.imr_address.s_addr = ifd->InAdr.s_addr;
123+
mreq.imr_ifindex = ifd->ifIndex;
124+
#else
115125
struct ip_mreq mreq;
116-
117-
mreq.imr_multiaddr.s_addr = grp;
118126
mreq.imr_interface.s_addr = ifd->InAdr.s_addr;
127+
#endif
128+
mreq.imr_multiaddr.s_addr = grp;
119129

120130
my_log(LOG_NOTICE, 0, "Joining group %s on interface %s", inetFmt(grp, s1), ifd->Name);
121131

@@ -134,10 +144,15 @@ void k_join(struct IfDesc *ifd, uint32_t grp) {
134144
}
135145

136146
void k_leave(struct IfDesc *ifd, uint32_t grp) {
147+
#ifdef HAVE_STRUCT_IP_MREQN
148+
struct ip_mreqn mreq;
149+
mreq.imr_address.s_addr = ifd->InAdr.s_addr;
150+
mreq.imr_ifindex = ifd->ifIndex;
151+
#else
137152
struct ip_mreq mreq;
138-
139-
mreq.imr_multiaddr.s_addr = grp;
140153
mreq.imr_interface.s_addr = ifd->InAdr.s_addr;
154+
#endif
155+
mreq.imr_multiaddr.s_addr = grp;
141156

142157
my_log(LOG_NOTICE, 0, "Leaving group %s on interface %s", inetFmt(grp, s1), ifd->Name);
143158

src/mroute-api.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,17 @@ void addVIF( struct IfDesc *IfDp )
131131
VifDp->IfDp = IfDp;
132132

133133
VifCtl.vifc_vifi = VifDp - VifDescVc;
134-
VifCtl.vifc_flags = 0; /* no tunnel, no source routing, register ? */
135134
VifCtl.vifc_threshold = VifDp->IfDp->threshold; // Packet TTL must be at least 1 to pass them
136135
VifCtl.vifc_rate_limit = VifDp->IfDp->ratelimit; // Ratelimit
137136

137+
#ifdef VIFF_USE_IFINDEX
138+
VifCtl.vifc_flags = VIFF_USE_IFINDEX;
139+
VifCtl.vifc_lcl_ifindex = VifDp->IfDp->ifIndex;
140+
#else
141+
VifCtl.vifc_flags = 0;
138142
VifCtl.vifc_lcl_addr.s_addr = VifDp->IfDp->InAdr.s_addr;
143+
#endif
144+
139145
VifCtl.vifc_rmt_addr.s_addr = INADDR_ANY;
140146

141147
// Set the index...

src/request.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ void sendGroupSpecificMemberQuery(void *argument) {
202202
sendIgmp(Dp->InAdr.s_addr, gvDesc->group,
203203
IGMP_MEMBERSHIP_QUERY,
204204
conf->lastMemberQueryInterval * IGMP_TIMER_SCALE,
205-
gvDesc->group, 0);
205+
gvDesc->group, 0, Dp->ifIndex);
206206

207207
my_log(LOG_DEBUG, 0, "Sent membership query from %s to %s. Delay: %d",
208208
inetFmt(Dp->InAdr.s_addr,s1), inetFmt(gvDesc->group,s2),
@@ -232,11 +232,12 @@ void sendGeneralMembershipQuery(void) {
232232
// Send the membership query...
233233
sendIgmp(Dp->InAdr.s_addr, allhosts_group,
234234
IGMP_MEMBERSHIP_QUERY,
235-
conf->queryResponseInterval * IGMP_TIMER_SCALE, 0, 0);
235+
conf->queryResponseInterval * IGMP_TIMER_SCALE, 0, 0, Dp->ifIndex);
236236

237237
my_log(LOG_DEBUG, 0,
238-
"Sent membership query from %s to %s. Delay: %d",
238+
"Sent membership query from %s ifIndex %d to %s. Delay: %d",
239239
inetFmt(Dp->InAdr.s_addr,s1),
240+
Dp->ifIndex,
240241
inetFmt(allhosts_group,s2),
241242
conf->queryResponseInterval);
242243
}

src/rttable.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,7 @@ int interfaceInRoute(int32_t group, int Ix) {
817817
struct RouteTable* croute;
818818
croute = findRoute(group);
819819
if (croute != NULL) {
820-
my_log(LOG_DEBUG, 0, "Interface id %d is in group $d", Ix, group);
820+
my_log(LOG_DEBUG, 0, "Interface id %d is in group %d", Ix, group);
821821
return BIT_TST(croute->vifBits, Ix);
822822
} else {
823823
return 0;

0 commit comments

Comments
 (0)