task #10495: Added support for IP_MULTICAST_LOOP at socket- and raw-API level.

This commit is contained in:
goldsimon 2010-07-12 09:34:11 +00:00
parent 714a43b18c
commit 691410ba18
6 changed files with 60 additions and 4 deletions

View File

@ -13,6 +13,10 @@ HISTORY
++ New features:
2010-07-12: Simon Goldschmidt (patch by Stephane Lesage)
* ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for
IP_MULTICAST_LOOP at socket- and raw-API level.
2010-06-16: Simon Goldschmidt
* ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow
link-layer-addressed UDP traffic to be received while a netif is down (just

View File

@ -1524,6 +1524,14 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = EINVAL;
}
break;
case IP_MULTICAST_LOOP:
if (*optlen < sizeof(u8_t)) {
err = EINVAL;
}
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
err = EAFNOSUPPORT;
}
break;
#endif /* LWIP_IGMP */
default:
@ -1738,6 +1746,15 @@ lwip_getsockopt_internal(void *arg)
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n",
s, *(u32_t *)optval));
break;
case IP_MULTICAST_LOOP:
if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) {
*(u8_t*)optval = 1;
} else {
*(u8_t*)optval = 0;
}
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n",
s, *(int *)optval));
break;
#endif /* LWIP_IGMP */
default:
LWIP_ASSERT("unhandled optname", 0);
@ -1906,6 +1923,14 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
err = EAFNOSUPPORT;
}
break;
case IP_MULTICAST_LOOP:
if (optlen < sizeof(u8_t)) {
err = EINVAL;
}
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
err = EAFNOSUPPORT;
}
break;
case IP_ADD_MEMBERSHIP:
case IP_DROP_MEMBERSHIP:
if (optlen < sizeof(struct ip_mreq)) {
@ -2098,6 +2123,13 @@ lwip_setsockopt_internal(void *arg)
case IP_MULTICAST_IF:
inet_addr_to_ipaddr(&sock->conn->pcb.udp->multicast_ip, (struct in_addr*)optval);
break;
case IP_MULTICAST_LOOP:
if (*(u8_t*)optval) {
udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP);
} else {
udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP);
}
break;
case IP_ADD_MEMBERSHIP:
case IP_DROP_MEMBERSHIP:
{

View File

@ -710,13 +710,18 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
return netif_loop_output(netif, p, dest);
}
#if LWIP_IGMP
if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
netif_loop_output(netif, p, dest);
}
#endif /* LWIP_IGMP */
#endif /* ENABLE_LOOPBACK */
#if IP_FRAG
/* don't fragment if interface has mtu set to 0 [loopif] */
if (netif->mtu && (p->tot_len > netif->mtu)) {
return ip_frag(p, netif, dest);
}
#endif
#endif /* IP_FRAG */
LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
return netif->output(netif, p, dest);

View File

@ -540,6 +540,14 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
/* in UDP, 0 checksum means 'no checksum' */
udphdr->chksum = 0x0000;
/* Multicast Loop? */
#if LWIP_IGMP
if (ip_addr_ismulticast(dst_ip) && ((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0)) {
q->flags |= PBUF_FLAG_MCASTLOOP;
}
#endif /* LWIP_IGMP */
/* PCB local address is IP_ANY_ADDR? */
if (ip_addr_isany(&pcb->local_ip)) {
/* use outgoing network interface IP address as source address */
@ -927,6 +935,10 @@ udp_new(void)
/* initialize PCB to all zeroes */
memset(pcb, 0, sizeof(struct udp_pcb));
pcb->ttl = UDP_TTL;
#if LWIP_IGMP
/* multicast loopback shall be turned on by default */
pcb->flags = PBUF_FLAG_MCASTLOOP;
#endif /* LWIP_IGMP */
}
return pcb;
}

View File

@ -67,6 +67,8 @@ typedef enum {
/** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a
a pbuf differently */
#define PBUF_FLAG_IS_CUSTOM 0x02U
/** indicates this pbuf is UDP multicast to be looped back */
#define PBUF_FLAG_MCASTLOOP 0x04U
struct pbuf {
/** next pbuf in singly linked pbuf chain */

View File

@ -63,9 +63,10 @@ PACK_STRUCT_END
# include "arch/epstruct.h"
#endif
#define UDP_FLAGS_NOCHKSUM 0x01U
#define UDP_FLAGS_UDPLITE 0x02U
#define UDP_FLAGS_CONNECTED 0x04U
#define UDP_FLAGS_NOCHKSUM 0x01U
#define UDP_FLAGS_UDPLITE 0x02U
#define UDP_FLAGS_CONNECTED 0x04U
#define UDP_FLAGS_MULTICAST_LOOP 0x08U
struct udp_pcb;