85#if LWIP_IPV4 && LWIP_IGMP
99static struct igmp_group *igmp_lookup_group(
struct netif *ifp,
const ip4_addr_t *
addr);
101static void igmp_timeout(
struct netif *
netif,
struct igmp_group *
group);
102static void igmp_start_timer(
struct igmp_group *
group,
u8_t max_time);
103static void igmp_delaying_member(
struct igmp_group *
group,
u8_t maxresp);
107static ip4_addr_t allsystems;
108static ip4_addr_t allrouters;
118 IP4_ADDR(&allsystems, 224, 0, 0, 1);
119 IP4_ADDR(&allrouters, 224, 0, 0, 2);
130 struct igmp_group *
group;
134 group = igmp_lookup_group(
netif, &allsystems);
143 ip4_addr_debug_print_val(
IGMP_DEBUG, allsystems);
162 struct igmp_group *
group = netif_igmp_data(
netif);
164 netif_set_client_data(
netif, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP,
NULL);
194 struct igmp_group *
group = netif_igmp_data(
netif);
204 igmp_delaying_member(
group, IGMP_JOIN_DELAYING_MEMBER_TMR);
218igmp_lookfor_group(
struct netif *ifp,
const ip4_addr_t *
addr)
220 struct igmp_group *
group = netif_igmp_data(ifp);
223 if (ip4_addr_eq(&(
group->group_address),
addr)) {
243static struct igmp_group *
244igmp_lookup_group(
struct netif *ifp,
const ip4_addr_t *
addr)
246 struct igmp_group *
group;
247 struct igmp_group *
list_head = netif_igmp_data(ifp);
259 ip4_addr_set(&(
group->group_address),
addr);
262 group->last_reporter_flag = 0;
268 LWIP_ASSERT(
"igmp_lookup_group: first group must be allsystems",
269 (ip4_addr_eq(
addr, &allsystems) != 0));
271 netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP,
group);
274 LWIP_ASSERT(
"igmp_lookup_group: all except first group must not be allsystems",
275 (ip4_addr_eq(
addr, &allsystems) == 0));
298 struct igmp_group *tmp_group;
301 for (tmp_group = netif_igmp_data(
netif); tmp_group !=
NULL; tmp_group = tmp_group->
next) {
302 if (tmp_group->next ==
group) {
303 tmp_group->next =
group->next;
308 if (tmp_group ==
NULL) {
323igmp_input(
struct pbuf *
p,
struct netif *inp,
const ip4_addr_t *
dest)
326 struct igmp_group *
group;
327 struct igmp_group *groupref;
340 ip4_addr_debug_print_val(
IGMP_DEBUG, ip4_current_header()->
src);
366 switch (igmp->igmp_msgtype) {
369 if ((ip4_addr_eq(
dest, &allsystems)) && ip4_addr_isany(&igmp->igmp_group_address)) {
371 LWIP_DEBUGF(
IGMP_DEBUG, (
"igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (
int)(igmp->igmp_maxresp)));
373 if (igmp->igmp_maxresp == 0) {
375 LWIP_DEBUGF(
IGMP_DEBUG, (
"igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n"));
376 igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR;
381 groupref = netif_igmp_data(inp);
385 if (groupref !=
NULL) {
386 groupref = groupref->next;
390 igmp_delaying_member(groupref, igmp->igmp_maxresp);
391 groupref = groupref->next;
395 if (!ip4_addr_isany(&igmp->igmp_group_address)) {
397 ip4_addr_debug_print_val(
IGMP_DEBUG, igmp->igmp_group_address);
398 if (ip4_addr_eq(
dest, &allsystems)) {
399 ip4_addr_t groupaddr;
400 LWIP_DEBUGF(
IGMP_DEBUG, (
" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (
int)(igmp->igmp_maxresp)));
402 ip4_addr_copy(groupaddr, igmp->igmp_group_address);
403 group = igmp_lookfor_group(inp, &groupaddr);
405 LWIP_DEBUGF(
IGMP_DEBUG, (
" with the group address as destination [igmp_maxresp=%i]\n", (
int)(igmp->igmp_maxresp)));
410 igmp_delaying_member(
group, igmp->igmp_maxresp);
426 group->last_reporter_flag = 0;
431 igmp->igmp_msgtype,
group->group_state, (
void *)&
group, (
void *)inp));
449igmp_joingroup(
const ip4_addr_t *ifaddr,
const ip4_addr_t *groupaddr)
457 LWIP_ERROR(
"igmp_joingroup: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr),
return ERR_VAL;);
458 LWIP_ERROR(
"igmp_joingroup: attempt to join allsystems address", (!ip4_addr_eq(groupaddr, &allsystems)),
return ERR_VAL;);
464 err = igmp_joingroup_netif(
netif, groupaddr);
485igmp_joingroup_netif(
struct netif *
netif,
const ip4_addr_t *groupaddr)
487 struct igmp_group *
group;
492 LWIP_ERROR(
"igmp_joingroup_netif: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr),
return ERR_VAL;);
493 LWIP_ERROR(
"igmp_joingroup_netif: attempt to join allsystems address", (!ip4_addr_eq(groupaddr, &allsystems)),
return ERR_VAL;);
504 LWIP_DEBUGF(
IGMP_DEBUG, (
"igmp_joingroup_netif: join to group not in state IGMP_GROUP_NON_MEMBER\n"));
522 igmp_start_timer(
group, IGMP_JOIN_DELAYING_MEMBER_TMR);
546igmp_leavegroup(
const ip4_addr_t *ifaddr,
const ip4_addr_t *groupaddr)
554 LWIP_ERROR(
"igmp_leavegroup: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr),
return ERR_VAL;);
555 LWIP_ERROR(
"igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_eq(groupaddr, &allsystems)),
return ERR_VAL;);
581igmp_leavegroup_netif(
struct netif *
netif,
const ip4_addr_t *groupaddr)
583 struct igmp_group *
group;
588 LWIP_ERROR(
"igmp_leavegroup_netif: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr),
return ERR_VAL;);
589 LWIP_ERROR(
"igmp_leavegroup_netif: attempt to leave allsystems address", (!ip4_addr_eq(groupaddr, &allsystems)),
return ERR_VAL;);
604 if (
group->use <= 1) {
609 if (
group->last_reporter_flag) {
646 struct igmp_group *
group = netif_igmp_data(
netif);
649 if (
group->timer > 0) {
651 if (
group->timer == 0) {
672 (!(ip4_addr_eq(&(
group->group_address), &allsystems)))) {
692igmp_start_timer(
struct igmp_group *
group,
u8_t max_time)
695 group->timer = (
u16_t)(max_time > 2 ? (LWIP_RAND() % max_time) : 1);
698 group->timer = max_time / 2;
701 if (
group->timer == 0) {
713igmp_delaying_member(
struct igmp_group *
group,
u8_t maxresp)
717 ((
group->timer == 0) || (maxresp < group->timer)))) {
718 igmp_start_timer(
group, maxresp);
762 ip4_addr_t
src = *IP4_ADDR_ANY4;
770 LWIP_ASSERT(
"igmp_send: check that first pbuf can hold struct igmp_msg",
772 ip4_addr_copy(
src, *netif_ip4_addr(
netif));
776 ip4_addr_copy(igmp->igmp_group_address,
group->group_address);
777 group->last_reporter_flag = 1;
781 ip4_addr_copy(igmp->igmp_group_address,
group->group_address);
786 igmp->igmp_msgtype =
type;
787 igmp->igmp_maxresp = 0;
788 igmp->igmp_checksum = 0;
#define LWIP_DEBUGF(debug, message)
#define LWIP_ERROR(message, expression, handler)
#define LWIP_ASSERT(message, assertion)
GLuint GLuint GLsizei GLenum type
GLenum const GLvoid * addr
#define LWIP_ASSERT_CORE_LOCKED()
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
u16_t inet_chksum(const void *dataptr, u16_t len)
void * memp_malloc(memp_t type)
void memp_free(memp_t type, void *mem)
#define NETIF_FOREACH(netif)
#define IGMP_GROUP_NON_MEMBER
#define IGMP_V2_MEMB_REPORT
#define IGMP_GROUP_IDLE_MEMBER
#define IGMP_GROUP_DELAYING_MEMBER
static unsigned __int64 next
#define IGMP_STATS_INC(x)