mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-02 12:52:10 +00:00
task #10495: Added support for IP_MULTICAST_LOOP at socket- and raw-API level.
This commit is contained in:
parent
714a43b18c
commit
691410ba18
@ -13,6 +13,10 @@ HISTORY
|
|||||||
|
|
||||||
++ New features:
|
++ 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
|
2010-06-16: Simon Goldschmidt
|
||||||
* ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow
|
* 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
|
link-layer-addressed UDP traffic to be received while a netif is down (just
|
||||||
|
@ -1524,6 +1524,14 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
|||||||
err = EINVAL;
|
err = EINVAL;
|
||||||
}
|
}
|
||||||
break;
|
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 */
|
#endif /* LWIP_IGMP */
|
||||||
|
|
||||||
default:
|
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",
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n",
|
||||||
s, *(u32_t *)optval));
|
s, *(u32_t *)optval));
|
||||||
break;
|
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 */
|
#endif /* LWIP_IGMP */
|
||||||
default:
|
default:
|
||||||
LWIP_ASSERT("unhandled optname", 0);
|
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;
|
err = EAFNOSUPPORT;
|
||||||
}
|
}
|
||||||
break;
|
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_ADD_MEMBERSHIP:
|
||||||
case IP_DROP_MEMBERSHIP:
|
case IP_DROP_MEMBERSHIP:
|
||||||
if (optlen < sizeof(struct ip_mreq)) {
|
if (optlen < sizeof(struct ip_mreq)) {
|
||||||
@ -2098,6 +2123,13 @@ lwip_setsockopt_internal(void *arg)
|
|||||||
case IP_MULTICAST_IF:
|
case IP_MULTICAST_IF:
|
||||||
inet_addr_to_ipaddr(&sock->conn->pcb.udp->multicast_ip, (struct in_addr*)optval);
|
inet_addr_to_ipaddr(&sock->conn->pcb.udp->multicast_ip, (struct in_addr*)optval);
|
||||||
break;
|
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_ADD_MEMBERSHIP:
|
||||||
case IP_DROP_MEMBERSHIP:
|
case IP_DROP_MEMBERSHIP:
|
||||||
{
|
{
|
||||||
|
@ -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()"));
|
LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
|
||||||
return netif_loop_output(netif, p, dest);
|
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 */
|
#endif /* ENABLE_LOOPBACK */
|
||||||
#if IP_FRAG
|
#if IP_FRAG
|
||||||
/* don't fragment if interface has mtu set to 0 [loopif] */
|
/* don't fragment if interface has mtu set to 0 [loopif] */
|
||||||
if (netif->mtu && (p->tot_len > netif->mtu)) {
|
if (netif->mtu && (p->tot_len > netif->mtu)) {
|
||||||
return ip_frag(p, netif, dest);
|
return ip_frag(p, netif, dest);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* IP_FRAG */
|
||||||
|
|
||||||
LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
|
LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
|
||||||
return netif->output(netif, p, dest);
|
return netif->output(netif, p, dest);
|
||||||
|
@ -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' */
|
/* in UDP, 0 checksum means 'no checksum' */
|
||||||
udphdr->chksum = 0x0000;
|
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? */
|
/* PCB local address is IP_ANY_ADDR? */
|
||||||
if (ip_addr_isany(&pcb->local_ip)) {
|
if (ip_addr_isany(&pcb->local_ip)) {
|
||||||
/* use outgoing network interface IP address as source address */
|
/* use outgoing network interface IP address as source address */
|
||||||
@ -927,6 +935,10 @@ udp_new(void)
|
|||||||
/* initialize PCB to all zeroes */
|
/* initialize PCB to all zeroes */
|
||||||
memset(pcb, 0, sizeof(struct udp_pcb));
|
memset(pcb, 0, sizeof(struct udp_pcb));
|
||||||
pcb->ttl = UDP_TTL;
|
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;
|
return pcb;
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,8 @@ typedef enum {
|
|||||||
/** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a
|
/** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a
|
||||||
a pbuf differently */
|
a pbuf differently */
|
||||||
#define PBUF_FLAG_IS_CUSTOM 0x02U
|
#define PBUF_FLAG_IS_CUSTOM 0x02U
|
||||||
|
/** indicates this pbuf is UDP multicast to be looped back */
|
||||||
|
#define PBUF_FLAG_MCASTLOOP 0x04U
|
||||||
|
|
||||||
struct pbuf {
|
struct pbuf {
|
||||||
/** next pbuf in singly linked pbuf chain */
|
/** next pbuf in singly linked pbuf chain */
|
||||||
|
@ -63,9 +63,10 @@ PACK_STRUCT_END
|
|||||||
# include "arch/epstruct.h"
|
# include "arch/epstruct.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UDP_FLAGS_NOCHKSUM 0x01U
|
#define UDP_FLAGS_NOCHKSUM 0x01U
|
||||||
#define UDP_FLAGS_UDPLITE 0x02U
|
#define UDP_FLAGS_UDPLITE 0x02U
|
||||||
#define UDP_FLAGS_CONNECTED 0x04U
|
#define UDP_FLAGS_CONNECTED 0x04U
|
||||||
|
#define UDP_FLAGS_MULTICAST_LOOP 0x08U
|
||||||
|
|
||||||
struct udp_pcb;
|
struct udp_pcb;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user