Improved IGMP stats (patch from bug #28798)

This commit is contained in:
goldsimon 2010-02-08 19:19:26 +00:00
parent b156d392cb
commit 27d4cf6aef
5 changed files with 77 additions and 46 deletions

View File

@ -87,6 +87,10 @@ HISTORY
++ Bugfixes:
2010-02-08: Simon Goldschmidt (Stéphane Lesage)
* igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats
(patch from bug #28798)
2010-02-08: Simon Goldschmidt (Stéphane Lesage)
* igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and
another bug when LWIP_RAND() returns zero.

View File

@ -95,9 +95,6 @@ Steve Reynolds
#include "string.h"
/*-----------------------------------------------------------------------------
* Globales
*----------------------------------------------------------------------------*/
static struct igmp_group* igmp_group_list;
static ip_addr_t allsystems;
@ -347,6 +344,7 @@ igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)
struct igmp_group* group;
struct igmp_group* groupref;
IGMP_STATS_INC(igmp.recv);
/* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */
iphdr = p->payload;
@ -373,11 +371,12 @@ igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)
}
/* Packet is ok so find an existing group */
group = igmp_lookfor_group(inp, dest); /* use the incoming IP address! */
group = igmp_lookfor_group(inp, dest); /* use the destination IP address of incoming packet */
/* If group can be found or create... */
if (!group) {
pbuf_free(p);
IGMP_STATS_INC(igmp.drop);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n"));
return;
}
@ -391,12 +390,14 @@ igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)
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)));
if (igmp->igmp_maxresp == 0) {
IGMP_STATS_INC(igmp.v1_rxed);
IGMP_STATS_INC(igmp.rx_v1);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n"));
igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR;
}
else {
IGMP_STATS_INC(igmp.rx_general);
}
IGMP_STATS_INC(igmp.group_query_rxed);
groupref = igmp_group_list;
while (groupref) {
/* Do not send messages on the all systems group address! */
@ -407,9 +408,9 @@ igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)
}
} else {
/* IGMP_MEMB_QUERY to a specific group ? */
if (!ip_addr_isany(&group->group_address) != 0) {
if (!ip_addr_isany(&igmp->igmp_group_address)) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group "));
ip_addr_debug_print(IGMP_DEBUG, &group->group_address);
ip_addr_debug_print(IGMP_DEBUG, &igmp->igmp_group_address);
if (ip_addr_cmp(dest, &allsystems)) {
LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
/* we first need to re-lookfor the group since we used dest last time */
@ -419,16 +420,22 @@ igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)
}
if (group != NULL) {
IGMP_STATS_INC(igmp.unicast_query);
IGMP_STATS_INC(igmp.rx_group);
igmp_delaying_member(group, igmp->igmp_maxresp);
}
else {
IGMP_STATS_INC(igmp.drop);
}
}
else {
IGMP_STATS_INC(igmp.proterr);
}
}
break;
}
case IGMP_V2_MEMB_REPORT: {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n"));
IGMP_STATS_INC(igmp.report_rxed);
IGMP_STATS_INC(igmp.rx_report);
if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) {
/* This is on a specific group we have already looked up */
group->timer = 0; /* stopped */
@ -440,6 +447,7 @@ igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)
default: {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n",
igmp->igmp_msgtype, group->group_state, &group, group->netif));
IGMP_STATS_INC(igmp.proterr);
break;
}
}
@ -492,7 +500,7 @@ igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr)
netif->igmp_mac_filter(netif, groupaddr, IGMP_ADD_MAC_FILTER);
}
IGMP_STATS_INC(igmp.join_sent);
IGMP_STATS_INC(igmp.tx_join);
igmp_send(group, IGMP_V2_MEMB_REPORT);
igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
@ -555,7 +563,7 @@ igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr)
/* If we are the last reporter for this group */
if (group->last_reporter_flag) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: sending leaving group\n"));
IGMP_STATS_INC(igmp.leave_sent);
IGMP_STATS_INC(igmp.tx_leave);
igmp_send(group, IGMP_LEAVE_GROUP);
}
@ -626,6 +634,7 @@ igmp_timeout(struct igmp_group *group)
ip_addr_debug_print(IGMP_DEBUG, &(group->group_address));
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif));
IGMP_STATS_INC(igmp.tx_report);
igmp_send(group, IGMP_V2_MEMB_REPORT);
}
}
@ -652,7 +661,7 @@ igmp_start_timer(struct igmp_group *group, u8_t max_time)
void
igmp_stop_timer(struct igmp_group *group)
{
group->timer = 0;
group->timer = 0;
}
/**
@ -703,6 +712,7 @@ igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
u16_t ra[2];
ra[0] = htons(ROUTER_ALERT);
ra[1] = 0x0000; /* Router shall examine packet */
IGMP_STATS_INC(igmp.xmit);
return ip_output_if_opt(p, src, dest, ttl, 0, proto, netif, ra, ROUTER_ALERTLEN);
}
@ -731,7 +741,6 @@ igmp_send(struct igmp_group *group, u8_t type)
if (type == IGMP_V2_MEMB_REPORT) {
dest = &(group->group_address);
IGMP_STATS_INC(igmp.report_sent);
ip_addr_set(&(igmp->igmp_group_address), &(group->group_address));
group->last_reporter_flag = 1; /* Remember we were the last to report */
} else {
@ -753,6 +762,7 @@ igmp_send(struct igmp_group *group, u8_t type)
pbuf_free(p);
} else {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n"));
IGMP_STATS_INC(igmp.memerr);
}
}

View File

@ -72,15 +72,20 @@ void
stats_display_igmp(struct stats_igmp *igmp)
{
LWIP_PLATFORM_DIAG(("\nIGMP\n\t"));
LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr));
LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", igmp->xmit));
LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", igmp->recv));
LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", igmp->drop));
LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr));
LWIP_PLATFORM_DIAG(("v1_rxed: %"STAT_COUNTER_F"\n\t", igmp->v1_rxed));
LWIP_PLATFORM_DIAG(("join_sent: %"STAT_COUNTER_F"\n\t", igmp->join_sent));
LWIP_PLATFORM_DIAG(("leave_sent: %"STAT_COUNTER_F"\n\t", igmp->leave_sent));
LWIP_PLATFORM_DIAG(("unicast_query: %"STAT_COUNTER_F"\n\t", igmp->unicast_query));
LWIP_PLATFORM_DIAG(("report_sent: %"STAT_COUNTER_F"\n\t", igmp->report_sent));
LWIP_PLATFORM_DIAG(("report_rxed: %"STAT_COUNTER_F"\n\t", igmp->report_rxed));
LWIP_PLATFORM_DIAG(("group_query_rxed: %"STAT_COUNTER_F"\n", igmp->group_query_rxed));
LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr));
LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr));
LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr));
LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1));
LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n", igmp->rx_group));
LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n", igmp->rx_general));
LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report));
LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join));
LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave));
LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n\t", igmp->tx_report));
}
#endif /* IGMP_STATS */

View File

@ -107,34 +107,41 @@ PACK_STRUCT_END
* from all the other groups
*/
struct igmp_group {
/** next link */
struct igmp_group *next;
/** interface on which the group is active */
struct netif *netif;
/** multicast address */
ip_addr_t group_address;
u8_t last_reporter_flag; /* signifies we were the last person to report */
/** signifies we were the last person to report */
u8_t last_reporter_flag;
/** current state of the group */
u8_t group_state;
/** timer for reporting, negative is OFF */
u16_t timer;
u8_t use; /* counter of simultaneous uses */
/** counter of simultaneous uses */
u8_t use;
};
/* Prototypes */
void igmp_init(void);
err_t igmp_start( struct netif *netif);
err_t igmp_stop( struct netif *netif);
void igmp_report_groups( struct netif *netif);
struct igmp_group *igmp_lookfor_group( struct netif *ifp, ip_addr_t *addr);
struct igmp_group *igmp_lookup_group( struct netif *ifp, ip_addr_t *addr);
err_t igmp_remove_group( struct igmp_group *group);
void igmp_input( struct pbuf *p, struct netif *inp, ip_addr_t *dest);
err_t igmp_joingroup( ip_addr_t *ifaddr, ip_addr_t *groupaddr);
err_t igmp_leavegroup( ip_addr_t *ifaddr, ip_addr_t *groupaddr);
err_t igmp_start(struct netif *netif);
err_t igmp_stop(struct netif *netif);
void igmp_report_groups(struct netif *netif);
struct igmp_group *igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr);
struct igmp_group *igmp_lookup_group(struct netif *ifp, ip_addr_t *addr);
err_t igmp_remove_group(struct igmp_group *group);
void igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest);
err_t igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr);
err_t igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr);
void igmp_tmr(void);
void igmp_timeout( struct igmp_group *group);
void igmp_start_timer( struct igmp_group *group, u8_t max_time);
void igmp_stop_timer( struct igmp_group *group);
void igmp_delaying_member( struct igmp_group *group, u8_t maxresp);
err_t igmp_ip_output_if( struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t proto, struct netif *netif);
void igmp_send( struct igmp_group *group, u8_t type);
void igmp_start_timer(struct igmp_group *group, u8_t max_time);
void igmp_stop_timer(struct igmp_group *group);
void igmp_delaying_member(struct igmp_group *group, u8_t maxresp);
err_t igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t proto, struct netif *netif);
void igmp_send(struct igmp_group *group, u8_t type);
#ifdef __cplusplus
}

View File

@ -71,15 +71,20 @@ struct stats_proto {
};
struct stats_igmp {
STAT_COUNTER lenerr; /* Invalid length error. */
STAT_COUNTER xmit; /* Transmitted packets. */
STAT_COUNTER recv; /* Received packets. */
STAT_COUNTER drop; /* Dropped packets. */
STAT_COUNTER chkerr; /* Checksum error. */
STAT_COUNTER v1_rxed; /* */
STAT_COUNTER join_sent; /* */
STAT_COUNTER leave_sent; /* */
STAT_COUNTER unicast_query; /* */
STAT_COUNTER report_sent; /* */
STAT_COUNTER report_rxed; /* */
STAT_COUNTER group_query_rxed; /* */
STAT_COUNTER lenerr; /* Invalid length error. */
STAT_COUNTER memerr; /* Out of memory error. */
STAT_COUNTER proterr; /* Protocol error. */
STAT_COUNTER rx_v1; /* Received v1 frames. */
STAT_COUNTER rx_group; /* Received group-specific queries. */
STAT_COUNTER rx_general; /* Received general queries. */
STAT_COUNTER rx_report; /* Received reports. */
STAT_COUNTER tx_join; /* Sent joins. */
STAT_COUNTER tx_leave; /* Sent leaves. */
STAT_COUNTER tx_report; /* Sent reports. */
};
struct stats_mem {