From 27d4cf6aef293407f48d92d362a3c9813e819657 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Mon, 8 Feb 2010 19:19:26 +0000 Subject: [PATCH] Improved IGMP stats (patch from bug #28798) --- CHANGELOG | 4 ++++ src/core/ipv4/igmp.c | 38 ++++++++++++++++++++++------------- src/core/stats.c | 21 +++++++++++-------- src/include/ipv4/lwip/igmp.h | 39 +++++++++++++++++++++--------------- src/include/lwip/stats.h | 21 +++++++++++-------- 5 files changed, 77 insertions(+), 46 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 20e9281c..4080d4fa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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. diff --git a/src/core/ipv4/igmp.c b/src/core/ipv4/igmp.c index 9dcc8866..c3f1b4c1 100644 --- a/src/core/ipv4/igmp.c +++ b/src/core/ipv4/igmp.c @@ -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); } } diff --git a/src/core/stats.c b/src/core/stats.c index a036d83b..97eb8cd7 100644 --- a/src/core/stats.c +++ b/src/core/stats.c @@ -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 */ diff --git a/src/include/ipv4/lwip/igmp.h b/src/include/ipv4/lwip/igmp.h index 66448375..fd5a0d81 100644 --- a/src/include/ipv4/lwip/igmp.h +++ b/src/include/ipv4/lwip/igmp.h @@ -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 } diff --git a/src/include/lwip/stats.h b/src/include/lwip/stats.h index aa179f5c..73a642e7 100644 --- a/src/include/lwip/stats.h +++ b/src/include/lwip/stats.h @@ -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 {