allow multicast socket options IP_MULTICAST_TTL, IP_MULTICAST_IF and IP_MULTICAST_LOOP to be used without IGMP

This commit is contained in:
sg 2015-08-05 22:52:23 +02:00
parent 9352988c44
commit 4edade8079
9 changed files with 52 additions and 29 deletions

View File

@ -6,6 +6,10 @@ HISTORY
++ New features: ++ New features:
2015-08-05: Simon Goldschmidt
* many files: allow multicast socket options IP_MULTICAST_TTL, IP_MULTICAST_IF
and IP_MULTICAST_LOOP to be used without IGMP
2015-04-24: Simon Goldschmidt 2015-04-24: Simon Goldschmidt
* dhcp.h/c, autoip.h/.c: added functions dhcp/autoip_supplied_address() to * dhcp.h/c, autoip.h/.c: added functions dhcp/autoip_supplied_address() to
check for the source of address assignemnt (replacement for NETIF_FLAG_DHCP) check for the source of address assignemnt (replacement for NETIF_FLAG_DHCP)

View File

@ -1830,7 +1830,7 @@ lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *opt
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n",
s, *(int *)optval)); s, *(int *)optval));
break; break;
#if LWIP_IGMP #if LWIP_MULTICAST_TX_OPTIONS
case IP_MULTICAST_TTL: case IP_MULTICAST_TTL:
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t);
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
@ -1859,7 +1859,7 @@ lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *opt
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n", LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n",
s, *(int *)optval)); s, *(int *)optval));
break; break;
#endif /* LWIP_IGMP */ #endif /* LWIP_MULTICAST_TX_OPTIONS */
default: default:
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n",
s, optname)); s, optname));
@ -2190,7 +2190,7 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n",
s, sock->conn->pcb.ip->tos)); s, sock->conn->pcb.ip->tos));
break; break;
#if LWIP_IGMP #if LWIP_MULTICAST_TX_OPTIONS
case IP_MULTICAST_TTL: case IP_MULTICAST_TTL:
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP);
sock->conn->pcb.udp->mcast_ttl = (u8_t)(*(const u8_t*)optval); sock->conn->pcb.udp->mcast_ttl = (u8_t)(*(const u8_t*)optval);
@ -2211,6 +2211,8 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_
udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP); udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP);
} }
break; break;
#endif /* LWIP_MULTICAST_TX_OPTIONS */
#if LWIP_IGMP
case IP_ADD_MEMBERSHIP: case IP_ADD_MEMBERSHIP:
case IP_DROP_MEMBERSHIP: case IP_DROP_MEMBERSHIP:
{ {

View File

@ -102,6 +102,9 @@
#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) #if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1))
#error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" #error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h"
#endif #endif
#if (LWIP_IGMP && !LWIP_MULTICAST_TX_OPTIONS)
#error "If you want to use IGMP, you have to define LWIP_MULTICAST_TX_OPTIONS==1 in your lwipopts.h"
#endif
#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) #if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0))
#error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" #error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h"
#endif #endif

View File

@ -101,7 +101,7 @@ struct ip_globals ip_data;
/** The IP header ID of the next outgoing IP packet */ /** The IP header ID of the next outgoing IP packet */
static u16_t ip_id; static u16_t ip_id;
#if LWIP_IGMP #if LWIP_MULTICAST_TX_OPTIONS
/** The default netif used for multicast */ /** The default netif used for multicast */
static struct netif* ip4_default_multicast_netif; static struct netif* ip4_default_multicast_netif;
@ -111,7 +111,7 @@ ip4_set_default_multicast_netif(struct netif* default_multicast_netif)
{ {
ip4_default_multicast_netif = default_multicast_netif; ip4_default_multicast_netif = default_multicast_netif;
} }
#endif /* LWIP_IGMP */ #endif /* LWIP_MULTICAST_TX_OPTIONS */
/** /**
* Finds the appropriate network interface for a given IP address. It * Finds the appropriate network interface for a given IP address. It
@ -895,11 +895,11 @@ err_t ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_add
LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
return netif_loop_output(netif, p); return netif_loop_output(netif, p);
} }
#if LWIP_IGMP #if LWIP_MULTICAST_TX_OPTIONS
if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) { if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
netif_loop_output(netif, p); netif_loop_output(netif, p);
} }
#endif /* LWIP_IGMP */ #endif /* LWIP_MULTICAST_TX_OPTIONS */
#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] */

View File

@ -551,13 +551,13 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ #endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
struct netif *netif; struct netif *netif;
const ip_addr_t *dst_ip_route = dst_ip; const ip_addr_t *dst_ip_route = dst_ip;
#if LWIP_IPV6 && LWIP_IPV4 && LWIP_IGMP #if LWIP_IPV6 && LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS
ip_addr_t dst_ip_tmp; ip_addr_t dst_ip_tmp;
#endif /* LWIP_IPV6 && LWIP_IPV4 && LWIP_IGMP */ #endif /* LWIP_IPV6 && LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS */
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n"));
#if LWIP_IPV6 || (LWIP_IPV4 && LWIP_IGMP) #if LWIP_IPV6 || (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS)
if (ip_addr_ismulticast(dst_ip_route)) { if (ip_addr_ismulticast(dst_ip_route)) {
#if LWIP_IPV6 #if LWIP_IPV6
if (PCB_ISIPV6(pcb)) { if (PCB_ISIPV6(pcb)) {
@ -566,7 +566,7 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
} else } else
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
{ {
#if LWIP_IPV4 && LWIP_IGMP #if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS
/* IPv4 does not use source-based routing by default, so we use an /* IPv4 does not use source-based routing by default, so we use an
administratively selected interface for multicast by default. administratively selected interface for multicast by default.
However, this can be overridden by setting an interface address However, this can be overridden by setting an interface address
@ -575,10 +575,10 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
!ip4_addr_cmp(&pcb->multicast_ip, IP4_ADDR_BROADCAST)) { !ip4_addr_cmp(&pcb->multicast_ip, IP4_ADDR_BROADCAST)) {
dst_ip_route = ip4_2_ip(&pcb->multicast_ip, &dst_ip_tmp); dst_ip_route = ip4_2_ip(&pcb->multicast_ip, &dst_ip_tmp);
} }
#endif /* LWIP_IPV4 && LWIP_IGMP */ #endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS */
} }
} }
#endif /* LWIP_IPV6 || LWIP_IGMP */ #endif /* LWIP_IPV6 || (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS) */
/* find the outgoing network interface for this packet */ /* find the outgoing network interface for this packet */
netif = ip_route(PCB_ISIPV6(pcb), &pcb->local_ip, dst_ip_route); netif = ip_route(PCB_ISIPV6(pcb), &pcb->local_ip, dst_ip_route);
@ -758,11 +758,11 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
udphdr->chksum = 0x0000; udphdr->chksum = 0x0000;
/* Multicast Loop? */ /* Multicast Loop? */
#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) #if (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS) || (LWIP_IPV6 && LWIP_IPV6_MLD)
if (((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) { if (((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) {
q->flags |= PBUF_FLAG_MCASTLOOP; q->flags |= PBUF_FLAG_MCASTLOOP;
} }
#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ #endif /* (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS) || (LWIP_IPV6 && LWIP_IPV6_MLD) */
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len)); LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));
@ -846,11 +846,11 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
} }
/* Determine TTL to use */ /* Determine TTL to use */
#if LWIP_IGMP #if LWIP_MULTICAST_TX_OPTIONS
ttl = (ip_addr_ismulticast(dst_ip) ? pcb->mcast_ttl : pcb->ttl); ttl = (ip_addr_ismulticast(dst_ip) ? pcb->mcast_ttl : pcb->ttl);
#else #else /* LWIP_MULTICAST_TX_OPTIONS */
ttl = pcb->ttl; ttl = pcb->ttl;
#endif #endif /* LWIP_MULTICAST_TX_OPTIONS */
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto)); LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto));

View File

@ -128,9 +128,9 @@ err_t ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_add
u16_t optlen); u16_t optlen);
#endif /* IP_OPTIONS_SEND */ #endif /* IP_OPTIONS_SEND */
#if LWIP_IGMP #if LWIP_MULTICAST_TX_OPTIONS
void ip4_set_default_multicast_netif(struct netif* default_multicast_netif); void ip4_set_default_multicast_netif(struct netif* default_multicast_netif);
#endif /* LWIP_IGMP */ #endif /* LWIP_MULTICAST_TX_OPTIONS */
#define ip4_netif_get_local_ip(netif) (((netif) != NULL) ? &((netif)->ip_addr) : NULL) #define ip4_netif_get_local_ip(netif) (((netif) != NULL) ? &((netif)->ip_addr) : NULL)

View File

@ -963,11 +963,11 @@
/* /*
---------------------------------- ----------------------------------
---------- IGMP options ---------- ----- Multicast/IGMP options -----
---------------------------------- ----------------------------------
*/ */
/** /**
* LWIP_IGMP==1: Turn on IGMP module. * LWIP_IGMP==1: Turn on IGMP module.
*/ */
#ifndef LWIP_IGMP #ifndef LWIP_IGMP
#define LWIP_IGMP 0 #define LWIP_IGMP 0
@ -977,6 +977,14 @@
#define LWIP_IGMP 0 #define LWIP_IGMP 0
#endif #endif
/**
* LWIP_MULTICAST_TX_OPTIONS==1: Enable multicast TX support like the socket options
* IP_MULTICAST_TTL/IP_MULTICAST_IF/IP_MULTICAST_LOOP
*/
#ifndef LWIP_MULTICAST_TX_OPTIONS
#define LWIP_MULTICAST_TX_OPTIONS LWIP_IGMP
#endif
/* /*
---------------------------------- ----------------------------------
---------- DNS options ----------- ---------- DNS options -----------

View File

@ -253,15 +253,21 @@ struct linger {
#endif /* LWIP_UDP && LWIP_UDPLITE*/ #endif /* LWIP_UDP && LWIP_UDPLITE*/
#if LWIP_IGMP #if LWIP_MULTICAST_TX_OPTIONS
/* /*
* Options and types for UDP multicast traffic handling * Options and types for UDP multicast traffic handling
*/ */
#define IP_ADD_MEMBERSHIP 3
#define IP_DROP_MEMBERSHIP 4
#define IP_MULTICAST_TTL 5 #define IP_MULTICAST_TTL 5
#define IP_MULTICAST_IF 6 #define IP_MULTICAST_IF 6
#define IP_MULTICAST_LOOP 7 #define IP_MULTICAST_LOOP 7
#endif /* LWIP_MULTICAST_TX_OPTIONS */
#if LWIP_IGMP
/*
* Options and types related to multicast membership
*/
#define IP_ADD_MEMBERSHIP 3
#define IP_DROP_MEMBERSHIP 4
typedef struct ip_mreq { typedef struct ip_mreq {
struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_multiaddr; /* IP multicast address of group */

View File

@ -100,12 +100,12 @@ struct udp_pcb {
/** ports are in host byte order */ /** ports are in host byte order */
u16_t local_port, remote_port; u16_t local_port, remote_port;
#if LWIP_IGMP #if LWIP_MULTICAST_TX_OPTIONS
/** outgoing network interface for multicast packets */ /** outgoing network interface for multicast packets */
ip4_addr_t multicast_ip; ip4_addr_t multicast_ip;
/** TTL for outgoing multicast packets */ /** TTL for outgoing multicast packets */
u8_t mcast_ttl; u8_t mcast_ttl;
#endif /* LWIP_IGMP */ #endif /* LWIP_MULTICAST_TX_OPTIONS */
#if LWIP_UDPLITE #if LWIP_UDPLITE
/** used for UDP_LITE only */ /** used for UDP_LITE only */
@ -168,12 +168,12 @@ void udp_init (void);
struct udp_pcb * udp_new_ip6(void); struct udp_pcb * udp_new_ip6(void);
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
#if LWIP_IGMP #if LWIP_MULTICAST_TX_OPTIONS
#define udp_set_multicast_netif_addr(pcb, ip4addr) do { (pcb)->multicast_ip = *(ip4addr); } while(0) #define udp_set_multicast_netif_addr(pcb, ip4addr) do { (pcb)->multicast_ip = *(ip4addr); } while(0)
#define udp_get_multicast_netif_addr(pcb) (&(pcb)->multicast_ip) #define udp_get_multicast_netif_addr(pcb) (&(pcb)->multicast_ip)
#define udp_set_multicast_ttl(pcb, value) do { (pcb)->mcast_ttl = value; } while(0) #define udp_set_multicast_ttl(pcb, value) do { (pcb)->mcast_ttl = value; } while(0)
#define udp_get_multicast_ttl(pcb) ((pcb)->mcast_ttl) #define udp_get_multicast_ttl(pcb) ((pcb)->mcast_ttl)
#endif /* LWIP_IGMP */ #endif /* LWIP_MULTICAST_TX_OPTIONS */
#if UDP_DEBUG #if UDP_DEBUG
void udp_debug_print(struct udp_hdr *udphdr); void udp_debug_print(struct udp_hdr *udphdr);