diff --git a/include/net/uip/uip-arch.h b/include/net/uip/uip-arch.h index 72288cba6b..3184ac0f7c 100644 --- a/include/net/uip/uip-arch.h +++ b/include/net/uip/uip-arch.h @@ -47,7 +47,11 @@ #include #include #include + #include +#ifdef CONFIG_NET_IGMP +# include +#endif /**************************************************************************** * Included Files @@ -169,6 +173,12 @@ struct uip_driver_s uint16_t d_sndlen; + /* IGMP group list */ + +#ifdef CONFIG_NET_IGMP + FAR struct igmp_group_s *grplist; +#endif + /* Driver callbacks */ int (*d_ifup)(struct uip_driver_s *dev); diff --git a/include/net/uip/uip-igmp.h b/include/net/uip/uip-igmp.h index 7ad105ec3a..8f80ac1f2d 100755 --- a/include/net/uip/uip-igmp.h +++ b/include/net/uip/uip-igmp.h @@ -47,8 +47,15 @@ ****************************************************************************/ #include + +#include +#include + #include +#include +#include + #ifdef CONFIG_NET_IGMP /**************************************************************************** @@ -67,10 +74,20 @@ #define IGMPv3_MEMBERSHIP_REPORT 0x22 /* IGMP Ver. 3 Membership Report */ #define IGMP_LEAVE_GROUP 0x17 /* Leave Group */ -/* Header sizes */ +/* Header sizes: + * + * UIP_IGMPH_LEN - Size of IGMP header in bytes + * UIP_IPIGMPH_LEN - Size of IP + IGMP header + */ -#define UIP_IGMPH_LEN 4 /* Size of IGMP header */ -#define UIP_IPIGMPH_LEN (UIP_IGMPH_LEN + UIP_IPH_LEN) /* Size of IP + IGMP header */ +#define UIP_IGMPH_LEN 8 +#define UIP_IPIGMPH_LEN (UIP_IGMPH_LEN + UIP_IPH_LEN) + +/* Group membership states */ + +#define IGMP_NON_MEMBER 0 +#define IGMP_DELAYING_MEMBER 1 +#define IGMP_IDLE_MEMBER 2 /**************************************************************************** * Public Types @@ -124,6 +141,43 @@ struct uip_igmphdr_s uint16_t grpaddr[2]; /* 32-bit Group address */ }; +#ifdef CONFIG_NET_IGMP_STATS +struct igmp_stats_s +{ + uint32_t length_errors; + uint32_t chksum_errors; + uint32_t v1_received; + uint32_t joins; + uint32_t leave_sent; + uint32_t ucast_query; + uint32_t report_sent; + uint32_t query_received; + uint32_t report_received; +}; + +# define IGMP_STATINCR(p) ((p)++) +#else +# define IGMP_STATINCR(p) +#endif + +/* This structure represents one group member. There is a list of groups + * for each device interface structure. + * + * There will be a group for the all systems group address but this + * will not run the state machine as it is used to kick off reports + * from all the other groups + */ + +struct igmp_group_s +{ + struct igmp_group_s *next; /* Implements a singly-linked list */ + uip_ipaddr_t grpaddr; /* Group IP address */ + WDOG_ID wdog; /* WDOG used to detect timeouts */ + bool lastrpt; /* Indicates the last to report */ + uint8_t state; /* State of the group */ + uint8_t msgid; /* Pending message ID (if non-zero) */ +}; + /**************************************************************************** * Public Data ****************************************************************************/ @@ -136,10 +190,27 @@ extern "C" { #define EXTERN extern #endif +#ifdef CONFIG_NET_IGMP_STATS +struct igmp_stats_s g_igmpstats; +#endif + +extern uip_ipaddr_t g_allsystems; +extern uip_ipaddr_t g_allrouters; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ +/**************************************************************************** + * Name: uip_igmpdevinit + * + * Description: + * Called when a new network device is registered to configure that device + * for IGMP support. + * + ****************************************************************************/ + +EXTERN void uip_igmpdevinit(struct uip_driver_s *dev); #undef EXTERN #if defined(__cplusplus) diff --git a/net/uip/uip_initialize.c b/net/uip/uip_initialize.c index 867e7d66ab..8c05765bc9 100644 --- a/net/uip/uip_initialize.c +++ b/net/uip/uip_initialize.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/uip/uip_initialize.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Adapted for NuttX from logic in uIP which also has a BSD-like license: @@ -140,6 +140,12 @@ void uip_initialize(void) #ifdef CONFIG_NET_UDP uip_udpinit(); #endif + + /* Initialize IGMP support */ + +#ifdef CONFIG_NET_IGMP + uip_udpinit(); +#endif } #endif /* CONFIG_NET */ diff --git a/net/uip/uip_input.c b/net/uip/uip_input.c index 893fa3b0a1..6a8963f385 100644 --- a/net/uip/uip_input.c +++ b/net/uip/uip_input.c @@ -510,6 +510,16 @@ void uip_input(struct uip_driver_s *dev) break; #endif + /* Check for ICMP input */ + +#ifdef CONFIG_NET_IGMP +#ifndef CONFIG_NET_IPv6 + case UIP_PROTO_IGMP: /* IGMP input */ + uip_igmpinput(dev); + break; +#endif +#endif + default: /* Unrecognized/unsupported protocol */ #ifdef CONFIG_NET_STATISTICS uip_stat.ip.drop++; diff --git a/net/uip/uip_internal.h b/net/uip/uip_internal.h index 487563c81e..990a08e6f3 100644 --- a/net/uip/uip_internal.h +++ b/net/uip/uip_internal.h @@ -210,6 +210,10 @@ EXTERN void uip_icmpsend(struct uip_driver_s *dev, uip_ipaddr_t *destaddr); #endif /* CONFIG_NET_ICMP */ #ifdef CONFIG_NET_IGMP +/* Defined in uip_igmpinit.c ************************************************/ + +EXTERN void uip_igmpinit(void); + /* Defined in uip_igmpinput.c ***********************************************/ EXTERN void uip_igmpinput(struct uip_driver_s *dev);