85 #if LWIP_IPV4 && LWIP_IGMP
99 static struct igmp_group *igmp_lookup_group(
struct netif *ifp,
const ip4_addr_t *addr);
100 static err_t igmp_remove_group(
struct netif*
netif,
struct igmp_group *group);
101 static void igmp_timeout(
struct netif *
netif,
struct igmp_group *group);
102 static void igmp_start_timer(
struct igmp_group *group,
u8_t max_time);
103 static void igmp_delaying_member(
struct igmp_group *group,
u8_t maxresp);
104 static err_t igmp_ip_output_if(
struct pbuf *p,
const ip4_addr_t *src,
const ip4_addr_t *dest,
struct netif *
netif);
105 static void igmp_send(
struct netif *
netif,
struct igmp_group *group,
u8_t type);
107 static ip4_addr_t allsystems;
108 static 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);
166 while (group !=
NULL) {
167 struct igmp_group *next = group->next;
172 ip4_addr_debug_print(
IGMP_DEBUG, &group->group_address);
194 struct igmp_group *group = netif_igmp_data(
netif);
203 while (group !=
NULL) {
204 igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
218 igmp_lookfor_group(
struct netif *ifp,
const ip4_addr_t *addr)
220 struct igmp_group *group = netif_igmp_data(ifp);
222 while (group !=
NULL) {
223 if (ip4_addr_cmp(&(group->group_address), addr)) {
243 static struct igmp_group *
244 igmp_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);
250 group = igmp_lookfor_group(ifp, addr);
257 group = (
struct igmp_group *)
memp_malloc(MEMP_IGMP_GROUP);
259 ip4_addr_set(&(group->group_address), addr);
262 group->last_reporter_flag = 0;
266 if (list_head ==
NULL) {
268 LWIP_ASSERT(
"igmp_lookup_group: first group must be allsystems",
269 (ip4_addr_cmp(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_cmp(addr, &allsystems) == 0));
276 group->next = list_head->next;
277 list_head->next = group;
281 LWIP_DEBUGF(
IGMP_DEBUG, (
"igmp_lookup_group: %sallocated a new group with address ", (group?
"":
"impossible to ")));
295 igmp_remove_group(
struct netif*
netif,
struct igmp_group *group)
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) {
323 igmp_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(
IGMP_DEBUG, &(ip4_current_header()->src));
342 ip4_addr_debug_print(
IGMP_DEBUG, &(ip4_current_header()->dest));
355 group = igmp_lookfor_group(inp, dest);
366 switch (igmp->igmp_msgtype) {
369 if ((ip4_addr_cmp(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(
IGMP_DEBUG, &igmp->igmp_group_address);
398 if (ip4_addr_cmp(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));
449 igmp_joingroup(
const ip4_addr_t *ifaddr,
const ip4_addr_t *groupaddr)
455 LWIP_ERROR(
"igmp_joingroup: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr),
return ERR_VAL;);
456 LWIP_ERROR(
"igmp_joingroup: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)),
return ERR_VAL;);
463 err = igmp_joingroup_netif(
netif, groupaddr);
486 igmp_joingroup_netif(
struct netif *
netif,
const ip4_addr_t *groupaddr)
488 struct igmp_group *group;
491 LWIP_ERROR(
"igmp_joingroup_netif: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr),
return ERR_VAL;);
492 LWIP_ERROR(
"igmp_joingroup_netif: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)),
return ERR_VAL;);
498 group = igmp_lookup_group(
netif, groupaddr);
503 LWIP_DEBUGF(
IGMP_DEBUG, (
"igmp_joingroup_netif: join to group not in state IGMP_GROUP_NON_MEMBER\n"));
511 if ((group->use==0) && (
netif->igmp_mac_filter !=
NULL)) {
521 igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
545 igmp_leavegroup(
const ip4_addr_t *ifaddr,
const ip4_addr_t *groupaddr)
551 LWIP_ERROR(
"igmp_leavegroup: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr),
return ERR_VAL;);
552 LWIP_ERROR(
"igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)),
return ERR_VAL;);
559 err_t res = igmp_leavegroup_netif(
netif, groupaddr);
581 igmp_leavegroup_netif(
struct netif *
netif,
const ip4_addr_t *groupaddr)
583 struct igmp_group *group;
586 LWIP_ERROR(
"igmp_leavegroup_netif: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr),
return ERR_VAL;);
587 LWIP_ERROR(
"igmp_leavegroup_netif: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)),
return ERR_VAL;);
593 group = igmp_lookfor_group(
netif, groupaddr);
602 if (group->use <= 1) {
604 igmp_remove_group(
netif, group);
607 if (group->last_reporter_flag) {
644 struct igmp_group *group = netif_igmp_data(
netif);
646 while (group !=
NULL) {
647 if (group->timer > 0) {
649 if (group->timer == 0) {
650 igmp_timeout(
netif, group);
666 igmp_timeout(
struct netif *
netif,
struct igmp_group *group)
671 (!(ip4_addr_cmp(&(group->group_address), &allsystems)))) {
673 ip4_addr_debug_print(
IGMP_DEBUG, &(group->group_address));
691 igmp_start_timer(
struct igmp_group *group,
u8_t max_time)
694 group->timer = max_time > 2 ? (LWIP_RAND() % max_time) : 1;
697 group->timer = max_time / 2;
700 if (group->timer == 0) {
712 igmp_delaying_member(
struct igmp_group *group,
u8_t maxresp)
716 ((group->timer == 0) || (maxresp < group->timer)))) {
717 igmp_start_timer(group, maxresp);
740 igmp_ip_output_if(
struct pbuf *p,
const ip4_addr_t *src,
const ip4_addr_t *dest,
struct netif *
netif)
757 igmp_send(
struct netif *
netif,
struct igmp_group *group,
u8_t type)
761 ip4_addr_t src = *IP4_ADDR_ANY4;
762 ip4_addr_t* dest =
NULL;
769 LWIP_ASSERT(
"igmp_send: check that first pbuf can hold struct igmp_msg",
771 ip4_addr_copy(src, *netif_ip4_addr(
netif));
774 dest = &(group->group_address);
775 ip4_addr_copy(igmp->igmp_group_address, group->group_address);
776 group->last_reporter_flag = 1;
780 ip4_addr_copy(igmp->igmp_group_address, group->group_address);
785 igmp->igmp_msgtype = type;
786 igmp->igmp_maxresp = 0;
787 igmp->igmp_checksum = 0;
790 igmp_ip_output_if(p, &src, dest,
netif);