diff --git a/CHANGELOG b/CHANGELOG index af84fc97..36ffadd3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -256,6 +256,10 @@ HISTORY ++ Bug fixes: + 2007-08-09 Frédéric Bernon, Bill Florac + * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement. + Introduce IGMP_STATS to centralize statistics management. + 2007-08-09 Frédéric Bernon, Bill Florac * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast packet on a udp pcb binded on an netif's IP address, and not on "any". diff --git a/src/core/ipv4/igmp.c b/src/core/ipv4/igmp.c index a346fd01..9f10e3d6 100644 --- a/src/core/ipv4/igmp.c +++ b/src/core/ipv4/igmp.c @@ -104,8 +104,6 @@ Steve Reynolds *----------------------------------------------------------------------------*/ static struct igmp_group* igmp_group_list; -static struct igmp_stats igmpstats; /** @todo: Should we have stats per netif? */ - static struct ip_addr allsystems; static struct ip_addr allrouters; @@ -131,9 +129,6 @@ igmp_init(void) igmp_group_list = NULL; - /* Clear stats*/ - memset(&igmpstats, 0, sizeof(igmpstats)); - for (netif = netif_list; netif != NULL; netif = netif->next) { group = igmp_lookup_group(netif, &allsystems); @@ -233,7 +228,7 @@ igmp_input(struct pbuf *p, struct netif *inp, struct ip_addr *dest) iphdr = p->payload; if (pbuf_header(p, -(IPH_HL(iphdr) * 4)) || (p->len < IGMP_MINLEN)) { pbuf_free(p); - igmpstats.igmp_length_err++; + IGMP_STATS_INC(igmp.lenerr); LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n")); return; } @@ -244,7 +239,7 @@ igmp_input(struct pbuf *p, struct netif *inp, struct ip_addr *dest) igmp = (struct igmpmsg *)p->payload; if (inet_chksum(igmp, p->len)) { pbuf_free(p); - igmpstats.igmp_checksum_err++; + IGMP_STATS_INC(igmp.chkerr); LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n")); return; } @@ -268,13 +263,13 @@ igmp_input(struct pbuf *p, struct netif *inp, struct ip_addr *dest) /* THIS IS THE GENERAL QUERY */ LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on ALL SYSTEMS ADDRESS 224.0.0.1\n")); - if (0 ==igmp->igmp_maxresp) { - igmpstats.igmp_v1_rxed++; + if (igmp->igmp_maxresp == 0) { + IGMP_STATS_INC(igmp.v1_rxed); igmp->igmp_maxresp = 10; LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n")); } - igmpstats.igmp_group_query_rxed++; + IGMP_STATS_INC(igmp.group_query_rxed); groupref = igmp_group_list; while (groupref) { if ((groupref->interface == inp) && @@ -297,7 +292,7 @@ igmp_input(struct pbuf *p, struct netif *inp, struct ip_addr *dest) /* we first need to re-lookup the group since we used dest last time */ group = igmp_lookfor_group(inp, &igmp->igmp_group_address); /* use the incoming IP address! */ if (group != NULL) { - igmpstats.igmp_unicast_query++; + IGMP_STATS_INC(igmp.unicast_query); if ((group->group_state == IDLE_MEMBER) || ((group->group_state == DELAYING_MEMBER) && (igmp->igmp_maxresp > group->timer))) { @@ -310,7 +305,8 @@ igmp_input(struct pbuf *p, struct netif *inp, struct ip_addr *dest) (group->group_address.addr != 0)) { LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got a query to a specific group with the group address as destination \n")); - igmpstats.igmp_unicast_query++; /* This is the unicast query */ + IGMP_STATS_INC(igmp.unicast_query); + if ((group->group_state == IDLE_MEMBER) || ((group->group_state == DELAYING_MEMBER) && (igmp->igmp_maxresp > group->timer))) { igmp_start_timer(group, (igmp->igmp_maxresp)/2); @@ -320,7 +316,7 @@ igmp_input(struct pbuf *p, struct netif *inp, struct ip_addr *dest) if (igmp->igmp_msgtype == IGMP_V2_MEMB_REPORT) { LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an IGMP_V2_MEMB_REPORT \n")); - igmpstats.report_rxed++; + IGMP_STATS_INC(igmp.report_rxed); if (group->group_state == DELAYING_MEMBER) { /* This is on a specific group we have already looked up */ group->timer = 0; /* stopped */ @@ -366,8 +362,6 @@ igmp_joingroup(struct netif *ifp, struct ip_addr *groupaddr) } /* OK - it was new group */ - igmpstats.igmp_joins++; - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to new group: ")); ip_addr_debug_print(IGMP_DEBUG, groupaddr); LWIP_DEBUGF(IGMP_DEBUG, ("\n")); @@ -376,6 +370,7 @@ igmp_joingroup(struct netif *ifp, struct ip_addr *groupaddr) ifp->igmp_mac_filter(ifp, groupaddr, IGMP_ADD_MAC_FILTER); } + IGMP_STATS_INC(igmp.join_sent); igmp_send(group, IGMP_V2_MEMB_REPORT); igmp_start_timer(group, 5); @@ -411,7 +406,7 @@ igmp_leavegroup(struct netif *ifp, struct ip_addr *groupaddr) if (group->last_reporter_flag) { LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: sending leaving group")); - igmpstats.igmp_leave_sent++; + IGMP_STATS_INC(igmp.leave_sent); igmp_send(group, IGMP_LEAVE_GROUP); } @@ -518,9 +513,9 @@ err_t igmp_ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t ttl, u8_t proto, struct netif *netif) { - static struct ip_hdr * iphdr = NULL; - static u16_t ip_id = 0; - u16_t * ra = NULL; + static u16_t ip_id = 0; + struct ip_hdr * iphdr = NULL; + u16_t * ra = NULL; /* First write in the "router alert" */ if (pbuf_header(p, ROUTER_ALERTLEN)) { @@ -604,7 +599,7 @@ igmp_send(struct igmp_group *group, u8_t type) if (type == IGMP_V2_MEMB_REPORT) { dest = &(group->group_address); - igmpstats.report_sent++; + 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 { diff --git a/src/core/stats.c b/src/core/stats.c index ed091d44..262c6b45 100644 --- a/src/core/stats.c +++ b/src/core/stats.c @@ -68,10 +68,25 @@ stats_display_proto(struct stats_proto *proto, char *name) LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit)); } +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(("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)); +} + void stats_display_mem(struct stats_mem *mem, char *name) { - LWIP_PLATFORM_DIAG(("\n MEM %s\n\t", name)); + LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name)); LWIP_PLATFORM_DIAG(("avail: %"MEM_SIZE_F"\n\t", mem->avail)); LWIP_PLATFORM_DIAG(("used: %"MEM_SIZE_F"\n\t", mem->used)); LWIP_PLATFORM_DIAG(("max: %"MEM_SIZE_F"\n\t", mem->max)); @@ -119,6 +134,9 @@ stats_display(void) #if ICMP_STATS stats_display_proto(&lwip_stats.icmp, "ICMP"); #endif +#if IGMP_STATS + stats_display_igmp(&lwip_stats.igmp); +#endif #if UDP_STATS stats_display_proto(&lwip_stats.udp, "UDP"); #endif diff --git a/src/include/ipv4/lwip/igmp.h b/src/include/ipv4/lwip/igmp.h index 7093aab3..c32954ff 100644 --- a/src/include/ipv4/lwip/igmp.h +++ b/src/include/ipv4/lwip/igmp.h @@ -45,17 +45,9 @@ extern "C" { #endif /* Some routers are not happy with ROUTER ALERT make it defineable, 1 to enable */ -#define USE_ROUTER_ALERT 0 - -/* - * IGMP packet format. - */ -struct igmpmsg { - u8_t igmp_msgtype; - u8_t igmp_maxresp; - u16_t igmp_checksum; - struct ip_addr igmp_group_address; -}; +#ifndef USE_ROUTER_ALERT +#define USE_ROUTER_ALERT 0 +#endif /* * IGMP constants @@ -85,6 +77,16 @@ struct igmpmsg { #define DELAYING_MEMBER 1 #define IDLE_MEMBER 2 +/* + * IGMP packet format. + */ +struct igmpmsg { + u8_t igmp_msgtype; + u8_t igmp_maxresp; + u16_t igmp_checksum; + struct ip_addr igmp_group_address; +}; + /* * now a group structure - there is * a list of groups for each interface @@ -107,21 +109,6 @@ struct igmp_group { }; - -struct igmp_stats{ - - u32_t igmp_length_err; - u32_t igmp_checksum_err; - u32_t igmp_v1_rxed; - u32_t igmp_joins; - u32_t igmp_leave_sent; - u32_t igmp_unicast_query; - u32_t report_sent; - u32_t igmp_group_query_rxed; - u32_t report_rxed; -}; - - /* Prototypes */ void igmp_init(void); diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index bbe4ac6a..67f2c120 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -598,6 +598,10 @@ #define ICMP_STATS 1 #endif +#ifndef IGMP_STATS +#define IGMP_STATS 1 +#endif + #ifndef UDP_STATS #define UDP_STATS 1 #endif @@ -624,6 +628,7 @@ #define IP_STATS 0 #define IPFRAG_STATS 0 #define ICMP_STATS 0 +#define IGMP_STATS 0 #define UDP_STATS 0 #define TCP_STATS 0 #define MEM_STATS 0 diff --git a/src/include/lwip/stats.h b/src/include/lwip/stats.h index 072391a8..51563f76 100644 --- a/src/include/lwip/stats.h +++ b/src/include/lwip/stats.h @@ -57,25 +57,37 @@ extern "C" { #endif struct stats_proto { - STAT_COUNTER xmit; /* Transmitted packets. */ - STAT_COUNTER rexmit; /* Retransmitted packets. */ - STAT_COUNTER recv; /* Received packets. */ - STAT_COUNTER fw; /* Forwarded packets. */ - STAT_COUNTER drop; /* Dropped packets. */ - STAT_COUNTER chkerr; /* Checksum error. */ - STAT_COUNTER lenerr; /* Invalid length error. */ - STAT_COUNTER memerr; /* Out of memory error. */ - STAT_COUNTER rterr; /* Routing error. */ - STAT_COUNTER proterr; /* Protocol error. */ - STAT_COUNTER opterr; /* Error in options. */ - STAT_COUNTER err; /* Misc error. */ + STAT_COUNTER xmit; /* Transmitted packets. */ + STAT_COUNTER rexmit; /* Retransmitted packets. */ + STAT_COUNTER recv; /* Received packets. */ + STAT_COUNTER fw; /* Forwarded packets. */ + STAT_COUNTER drop; /* Dropped packets. */ + STAT_COUNTER chkerr; /* Checksum error. */ + STAT_COUNTER lenerr; /* Invalid length error. */ + STAT_COUNTER memerr; /* Out of memory error. */ + STAT_COUNTER rterr; /* Routing error. */ + STAT_COUNTER proterr; /* Protocol error. */ + STAT_COUNTER opterr; /* Error in options. */ + STAT_COUNTER err; /* Misc error. */ STAT_COUNTER cachehit; }; +struct stats_igmp { + STAT_COUNTER lenerr; /* Invalid length error. */ + 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; /* */ +}; + struct stats_mem { mem_size_t avail; mem_size_t used; - mem_size_t max; + mem_size_t max; mem_size_t err; }; @@ -103,6 +115,9 @@ struct stats_ { #if ICMP_STATS struct stats_proto icmp; #endif +#if IGMP_STATS + struct stats_igmp igmp; +#endif #if UDP_STATS struct stats_proto udp; #endif @@ -148,6 +163,12 @@ void stats_init(void); #define ICMP_STATS_INC(x) #endif +#if IGMP_STATS +#define IGMP_STATS_INC(x) STATS_INC(x) +#else +#define IGMP_STATS_INC(x) +#endif + #if IP_STATS #define IP_STATS_INC(x) STATS_INC(x) #else