stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement. Introduce IGMP_STATS to centralize statistics management.

This commit is contained in:
fbernon 2007-08-09 20:09:22 +00:00
parent 118331207b
commit ac2932bac3
6 changed files with 90 additions and 60 deletions

View File

@ -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".

View File

@ -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 {

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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