mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-07-04 20:08:57 +00:00
Improved IGMP stats (patch from bug #28798)
This commit is contained in:
parent
b156d392cb
commit
27d4cf6aef
|
@ -87,6 +87,10 @@ HISTORY
|
||||||
|
|
||||||
++ Bugfixes:
|
++ 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)
|
2010-02-08: Simon Goldschmidt (Stéphane Lesage)
|
||||||
* igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and
|
* igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and
|
||||||
another bug when LWIP_RAND() returns zero.
|
another bug when LWIP_RAND() returns zero.
|
||||||
|
|
|
@ -95,9 +95,6 @@ Steve Reynolds
|
||||||
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
|
||||||
* Globales
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static struct igmp_group* igmp_group_list;
|
static struct igmp_group* igmp_group_list;
|
||||||
static ip_addr_t allsystems;
|
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* group;
|
||||||
struct igmp_group* groupref;
|
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 */
|
/* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */
|
||||||
iphdr = p->payload;
|
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 */
|
/* 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 can be found or create... */
|
||||||
if (!group) {
|
if (!group) {
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
|
IGMP_STATS_INC(igmp.drop);
|
||||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n"));
|
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n"));
|
||||||
return;
|
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)));
|
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) {
|
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"));
|
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;
|
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;
|
groupref = igmp_group_list;
|
||||||
while (groupref) {
|
while (groupref) {
|
||||||
/* Do not send messages on the all systems group address! */
|
/* 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 {
|
} else {
|
||||||
/* IGMP_MEMB_QUERY to a specific group ? */
|
/* 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 "));
|
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)) {
|
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)));
|
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 */
|
/* 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) {
|
if (group != NULL) {
|
||||||
IGMP_STATS_INC(igmp.unicast_query);
|
IGMP_STATS_INC(igmp.rx_group);
|
||||||
igmp_delaying_member(group, igmp->igmp_maxresp);
|
igmp_delaying_member(group, igmp->igmp_maxresp);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
IGMP_STATS_INC(igmp.drop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IGMP_STATS_INC(igmp.proterr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IGMP_V2_MEMB_REPORT: {
|
case IGMP_V2_MEMB_REPORT: {
|
||||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n"));
|
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) {
|
if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) {
|
||||||
/* This is on a specific group we have already looked up */
|
/* This is on a specific group we have already looked up */
|
||||||
group->timer = 0; /* stopped */
|
group->timer = 0; /* stopped */
|
||||||
|
@ -440,6 +447,7 @@ igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)
|
||||||
default: {
|
default: {
|
||||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n",
|
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->igmp_msgtype, group->group_state, &group, group->netif));
|
||||||
|
IGMP_STATS_INC(igmp.proterr);
|
||||||
break;
|
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);
|
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_send(group, IGMP_V2_MEMB_REPORT);
|
||||||
|
|
||||||
igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
|
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 we are the last reporter for this group */
|
||||||
if (group->last_reporter_flag) {
|
if (group->last_reporter_flag) {
|
||||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: sending leaving group\n"));
|
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);
|
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));
|
ip_addr_debug_print(IGMP_DEBUG, &(group->group_address));
|
||||||
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif));
|
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif));
|
||||||
|
|
||||||
|
IGMP_STATS_INC(igmp.tx_report);
|
||||||
igmp_send(group, IGMP_V2_MEMB_REPORT);
|
igmp_send(group, IGMP_V2_MEMB_REPORT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -703,6 +712,7 @@ igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
|
||||||
u16_t ra[2];
|
u16_t ra[2];
|
||||||
ra[0] = htons(ROUTER_ALERT);
|
ra[0] = htons(ROUTER_ALERT);
|
||||||
ra[1] = 0x0000; /* Router shall examine packet */
|
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);
|
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) {
|
if (type == IGMP_V2_MEMB_REPORT) {
|
||||||
dest = &(group->group_address);
|
dest = &(group->group_address);
|
||||||
IGMP_STATS_INC(igmp.report_sent);
|
|
||||||
ip_addr_set(&(igmp->igmp_group_address), &(group->group_address));
|
ip_addr_set(&(igmp->igmp_group_address), &(group->group_address));
|
||||||
group->last_reporter_flag = 1; /* Remember we were the last to report */
|
group->last_reporter_flag = 1; /* Remember we were the last to report */
|
||||||
} else {
|
} else {
|
||||||
|
@ -753,6 +762,7 @@ igmp_send(struct igmp_group *group, u8_t type)
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
} else {
|
} else {
|
||||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n"));
|
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n"));
|
||||||
|
IGMP_STATS_INC(igmp.memerr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,15 +72,20 @@ void
|
||||||
stats_display_igmp(struct stats_igmp *igmp)
|
stats_display_igmp(struct stats_igmp *igmp)
|
||||||
{
|
{
|
||||||
LWIP_PLATFORM_DIAG(("\nIGMP\n\t"));
|
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(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr));
|
||||||
LWIP_PLATFORM_DIAG(("v1_rxed: %"STAT_COUNTER_F"\n\t", igmp->v1_rxed));
|
LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr));
|
||||||
LWIP_PLATFORM_DIAG(("join_sent: %"STAT_COUNTER_F"\n\t", igmp->join_sent));
|
LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr));
|
||||||
LWIP_PLATFORM_DIAG(("leave_sent: %"STAT_COUNTER_F"\n\t", igmp->leave_sent));
|
LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr));
|
||||||
LWIP_PLATFORM_DIAG(("unicast_query: %"STAT_COUNTER_F"\n\t", igmp->unicast_query));
|
LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1));
|
||||||
LWIP_PLATFORM_DIAG(("report_sent: %"STAT_COUNTER_F"\n\t", igmp->report_sent));
|
LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n", igmp->rx_group));
|
||||||
LWIP_PLATFORM_DIAG(("report_rxed: %"STAT_COUNTER_F"\n\t", igmp->report_rxed));
|
LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n", igmp->rx_general));
|
||||||
LWIP_PLATFORM_DIAG(("group_query_rxed: %"STAT_COUNTER_F"\n", igmp->group_query_rxed));
|
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 */
|
#endif /* IGMP_STATS */
|
||||||
|
|
||||||
|
|
|
@ -107,34 +107,41 @@ PACK_STRUCT_END
|
||||||
* from all the other groups
|
* from all the other groups
|
||||||
*/
|
*/
|
||||||
struct igmp_group {
|
struct igmp_group {
|
||||||
|
/** next link */
|
||||||
struct igmp_group *next;
|
struct igmp_group *next;
|
||||||
|
/** interface on which the group is active */
|
||||||
struct netif *netif;
|
struct netif *netif;
|
||||||
|
/** multicast address */
|
||||||
ip_addr_t group_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;
|
u8_t group_state;
|
||||||
|
/** timer for reporting, negative is OFF */
|
||||||
u16_t timer;
|
u16_t timer;
|
||||||
u8_t use; /* counter of simultaneous uses */
|
/** counter of simultaneous uses */
|
||||||
|
u8_t use;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
void igmp_init(void);
|
void igmp_init(void);
|
||||||
err_t igmp_start( struct netif *netif);
|
err_t igmp_start(struct netif *netif);
|
||||||
err_t igmp_stop( struct netif *netif);
|
err_t igmp_stop(struct netif *netif);
|
||||||
void igmp_report_groups( 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_lookfor_group(struct netif *ifp, ip_addr_t *addr);
|
||||||
struct igmp_group *igmp_lookup_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);
|
err_t igmp_remove_group(struct igmp_group *group);
|
||||||
void igmp_input( struct pbuf *p, struct netif *inp, ip_addr_t *dest);
|
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_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr);
|
||||||
err_t igmp_leavegroup( 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_tmr(void);
|
||||||
void igmp_timeout( struct igmp_group *group);
|
void igmp_timeout( struct igmp_group *group);
|
||||||
void igmp_start_timer( struct igmp_group *group, u8_t max_time);
|
void igmp_start_timer(struct igmp_group *group, u8_t max_time);
|
||||||
void igmp_stop_timer( struct igmp_group *group);
|
void igmp_stop_timer(struct igmp_group *group);
|
||||||
void igmp_delaying_member( struct igmp_group *group, u8_t maxresp);
|
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);
|
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_send(struct igmp_group *group, u8_t type);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,15 +71,20 @@ struct stats_proto {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stats_igmp {
|
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 chkerr; /* Checksum error. */
|
||||||
STAT_COUNTER v1_rxed; /* */
|
STAT_COUNTER lenerr; /* Invalid length error. */
|
||||||
STAT_COUNTER join_sent; /* */
|
STAT_COUNTER memerr; /* Out of memory error. */
|
||||||
STAT_COUNTER leave_sent; /* */
|
STAT_COUNTER proterr; /* Protocol error. */
|
||||||
STAT_COUNTER unicast_query; /* */
|
STAT_COUNTER rx_v1; /* Received v1 frames. */
|
||||||
STAT_COUNTER report_sent; /* */
|
STAT_COUNTER rx_group; /* Received group-specific queries. */
|
||||||
STAT_COUNTER report_rxed; /* */
|
STAT_COUNTER rx_general; /* Received general queries. */
|
||||||
STAT_COUNTER group_query_rxed; /* */
|
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 {
|
struct stats_mem {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user