Outgoing IGMP is functional
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2797 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
2926fe8f32
commit
bb4a701c33
@ -1822,8 +1822,8 @@ static int ez80emac_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
|
||||
FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->d_private;
|
||||
|
||||
/* Add the MAC address to the hardware multicast routing table */
|
||||
/* MISSING LOGIC!!! */
|
||||
|
||||
#warning "Multicast MAC support not implemented"
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
@ -1852,8 +1852,8 @@ static int ez80emac_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
|
||||
FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->d_private;
|
||||
|
||||
/* Add the MAC address to the hardware multicast routing table */
|
||||
/* MISSING LOGIC!!! */
|
||||
|
||||
#warning "Multicast MAC support not implemented"
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
@ -110,7 +110,6 @@
|
||||
#define IS_SCHEDMSG(f) (((f) & IGMP_SCHEDMSG) != 0)
|
||||
#define IS_WAITMSG(f) (((f) & IGMP_WAITMSG) != 0)
|
||||
|
||||
#define ROUTER_ALERT 0x94040000
|
||||
#define IGMP_TTL 1
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -75,8 +75,8 @@
|
||||
# define IPOPT_TYPE_OPTION_SEC (2 << IPOPT_TYPE_OPTION_SHIFT) /* Security (RFC 791, 1108) */
|
||||
# define IPOPT_TYPE_OPTION_LSRR (3 << IPOPT_TYPE_OPTION_SHIFT) /* Loose source and record route (RFC 791) */
|
||||
# define IPOPT_TYPE_OPTION_TIMESTAMP (4 << IPOPT_TYPE_OPTION_SHIFT) /* Timestamp (RFC 781, 791) */
|
||||
# define IPORT_TYPE_OPTION_EXTSEC (5 << IPOPT_TYPE_OPTION_SHIFT) /* Extended security (RFC 1108) */
|
||||
# define IPORT_TYPE_OPTION_COMMSEC (6 << IPOPT_TYPE_OPTION_SHIFT) /* Commercial security */
|
||||
# define IPOPT_TYPE_OPTION_EXTSEC (5 << IPOPT_TYPE_OPTION_SHIFT) /* Extended security (RFC 1108) */
|
||||
# define IPOPT_TYPE_OPTION_COMMSEC (6 << IPOPT_TYPE_OPTION_SHIFT) /* Commercial security */
|
||||
# define IPOPT_TYPE_OPTION_RR (7 << IPOPT_TYPE_OPTION_SHIFT) /* Record route (RFC 791) */
|
||||
# define IPOPT_TYPE_OPTION_SSID (8 << IPOPT_TYPE_OPTION_SHIFT) /* Stream ID (RFC 791, 1122) */
|
||||
# define IPOPT_TYPE_OPTION_SSRR (9 << IPOPT_TYPE_OPTION_SHIFT) /* Strict source and record route (RFC 791) */
|
||||
@ -110,7 +110,7 @@
|
||||
#define IPOPT_MKOPTION8(copied,class,option) \
|
||||
((uint8_t)IPOPT_MKTYPE(copied,class,option))
|
||||
#define IPOPT_MKOPTION32(type,len,ptr,data) \
|
||||
((uint32_t)(type) << 24 | (uint32_t)(len) << 16) | \
|
||||
((uint32_t)(type) << 24 | (uint32_t)(len) << 16 | \
|
||||
(uint32_t)(ptr) << 8 | (uint32_t)(data))
|
||||
|
||||
/* Option Copy Class Length Description References
|
||||
@ -169,11 +169,11 @@
|
||||
#define IPOPT_TIMESTAMP_TYPE \
|
||||
IPOPT_MKTYPE(IPOPT_TYPE_NOTCOPIED, IPOPT_TYPE_CLASS_MEASURE, IPOPT_TYPE_OPTION_TIMESTAMP)
|
||||
|
||||
#define IPORT_EXTSEC_TYPE \
|
||||
IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPORT_TYPE_OPTION_EXTSEC)
|
||||
#define IPOPT_EXTSEC_TYPE \
|
||||
IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_EXTSEC)
|
||||
|
||||
#define IPORT_COMMSEC_TYPE \
|
||||
IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPORT_TYPE_OPTION_COMMSEC)
|
||||
#define IPOPT_COMMSEC_TYPE \
|
||||
IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_COMMSEC)
|
||||
|
||||
#define IPOPT_RR_TYPE \
|
||||
IPOPT_MKTYPE(IPOPT_TYPE_NOTCOPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_RR)
|
||||
@ -222,7 +222,7 @@
|
||||
#define IPOPT_RA_TYPE \
|
||||
IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_RA)
|
||||
#define IPOPT_RA \
|
||||
IPOPT_MKOPTION32(IPORT_RA_TYPE, 4, 0, 0)
|
||||
IPOPT_MKOPTION32(IPOPT_RA_TYPE, 4, 0, 0)
|
||||
|
||||
#define IPOPT_SDBM_TYPE \
|
||||
IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_SDBM)
|
||||
|
@ -442,7 +442,7 @@ extern void uip_send(struct uip_driver_s *dev, const void *buf, int len);
|
||||
* uip_ipaddr_t ipaddr1, ipaddr2;
|
||||
*
|
||||
* uip_ipaddr(&ipaddr1, 192,16,1,2);
|
||||
* if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
|
||||
* if(uip_ipaddr_cmp(ipaddr2, ipaddr1)) {
|
||||
* printf("They are the same");
|
||||
* }
|
||||
*
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* net/uip/uip_icmsend.c
|
||||
* net/uip/uip_icmpsend.c
|
||||
*
|
||||
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2008-2010 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -43,9 +43,11 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wdog.h>
|
||||
#include <queue.h>
|
||||
#include <debug.h>
|
||||
|
||||
@ -64,6 +66,8 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
# error "IGMP for IPv6 not supported"
|
||||
#endif
|
||||
@ -72,6 +76,40 @@
|
||||
# define CONFIG_PREALLOC_IGMPGROUPS 4
|
||||
#endif
|
||||
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
#undef IGMP_GRPDEBUG /* Define to enable detailed IGMP group debug */
|
||||
|
||||
#ifndef CONFIG_NET_IGMP
|
||||
# undef IGMP_GRPDEBUG
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPP_HAVE_VARARGS
|
||||
# ifdef IGMP_GRPDEBUG
|
||||
# define grpdbg(format, arg...) ndbg(format, ##arg)
|
||||
# define grplldbg(format, arg...) nlldbg(format, ##arg)
|
||||
# define grpvdbg(format, arg...) nvdbg(format, ##arg)
|
||||
# define grpllvdbg(format, arg...) nllvdbg(format, ##arg)
|
||||
# else
|
||||
# define grpdbg(x...)
|
||||
# define grplldbg(x...)
|
||||
# define grpvdbg(x...)
|
||||
# define grpllvdbg(x...)
|
||||
# endif
|
||||
#else
|
||||
# ifdef IGMP_GRPDEBUG
|
||||
# define grpdbg ndbg
|
||||
# define grplldbg nlldbg
|
||||
# define grpvdbg nvdbg
|
||||
# define grpllvdbg nllvdbg
|
||||
# else
|
||||
# define grpdbg (void)
|
||||
# define grplldbg (void)
|
||||
# define grpvdbg (void)
|
||||
# define grpllvdbg (void)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@ -151,6 +189,8 @@ void uip_grpinit(void)
|
||||
FAR struct igmp_group_s *group;
|
||||
int i;
|
||||
|
||||
grplldbg("Initializing\n");
|
||||
|
||||
for (i = 0; i < CONFIG_PREALLOC_IGMPGROUPS; i++)
|
||||
{
|
||||
group = &g_preallocgrps[i];
|
||||
@ -178,12 +218,15 @@ FAR struct igmp_group_s *uip_grpalloc(FAR struct uip_driver_s *dev,
|
||||
nllvdbg("addr: %08x dev: %p\n", *addr, dev);
|
||||
if (up_interrupt_context())
|
||||
{
|
||||
grplldbg("Allocate from the heap\n");
|
||||
group = uip_grpheapalloc();
|
||||
}
|
||||
else
|
||||
{
|
||||
grplldbg("Use a pre-allocated group entry\n");
|
||||
group = uip_grpprealloc();
|
||||
}
|
||||
grplldbg("group: %p\n", group);
|
||||
|
||||
/* Check if we succesfully allocated a group structure */
|
||||
|
||||
@ -194,6 +237,11 @@ FAR struct igmp_group_s *uip_grpalloc(FAR struct uip_driver_s *dev,
|
||||
uip_ipaddr_copy(group->grpaddr, *addr);
|
||||
sem_init(&group->sem, 0, 0);
|
||||
|
||||
/* Initialize the group timer (but don't start it yet) */
|
||||
|
||||
group->wdog = wd_create();
|
||||
DEBUGASSERT(group->wdog);
|
||||
|
||||
/* Interrupts must be disabled in order to modify the group list */
|
||||
|
||||
flags = irqsave();
|
||||
@ -223,15 +271,21 @@ FAR struct igmp_group_s *uip_grpfind(FAR struct uip_driver_s *dev,
|
||||
FAR struct igmp_group_s *group;
|
||||
irqstate_t flags;
|
||||
|
||||
/* We must disable interrupts because we don't which context we were called
|
||||
* from.
|
||||
grplldbg("Searching for addr %08x\n", (int)*addr);
|
||||
|
||||
/* We must disable interrupts because we don't which context we were
|
||||
* called from.
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
for (group = (FAR struct igmp_group_s *)dev->grplist.head; group; group = group->next)
|
||||
for (group = (FAR struct igmp_group_s *)dev->grplist.head;
|
||||
group;
|
||||
group = group->next)
|
||||
{
|
||||
if (uip_ipaddr_cmp(&group->grpaddr, *addr))
|
||||
grplldbg("Compare: %08x vs. %08x\n", group->grpaddr, *addr);
|
||||
if (uip_ipaddr_cmp(group->grpaddr, *addr))
|
||||
{
|
||||
grplldbg("Match!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -255,10 +309,13 @@ FAR struct igmp_group_s *uip_grpallocfind(FAR struct uip_driver_s *dev,
|
||||
FAR const uip_ipaddr_t *addr)
|
||||
{
|
||||
FAR struct igmp_group_s *group = uip_grpfind(dev, addr);
|
||||
|
||||
grplldbg("group: %p addr: %08x\n", group, (int)*addr);
|
||||
if (!group)
|
||||
{
|
||||
group = uip_grpalloc(dev, addr);
|
||||
}
|
||||
grplldbg("group: %p\n", group);
|
||||
return group;
|
||||
}
|
||||
|
||||
@ -275,16 +332,26 @@ FAR struct igmp_group_s *uip_grpallocfind(FAR struct uip_driver_s *dev,
|
||||
|
||||
void uip_grpfree(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group)
|
||||
{
|
||||
/* First, remove the group structure from the group list in the device
|
||||
* structure
|
||||
*/
|
||||
irqstate_t flags;
|
||||
|
||||
grplldbg("Free: %p flags: %02x\n", group, group->flags);
|
||||
|
||||
/* Cancel the wdog */
|
||||
|
||||
flags = irqsave();
|
||||
wd_cancel(group->wdog);
|
||||
|
||||
/* Remove the group structure from the group list in the device structure */
|
||||
|
||||
irqstate_t flags = irqsave();
|
||||
sq_rem((FAR sq_entry_t*)group, &dev->grplist);
|
||||
|
||||
/* Destroy the wait semapore */
|
||||
|
||||
(void)sem_destroy(&group->sem);
|
||||
|
||||
/* Destroy the wdog */
|
||||
|
||||
wd_delete(group->wdog);
|
||||
|
||||
/* Then release the group structure resources. Check first if this is one
|
||||
* of the pre-allocated group structures that we will retain in a free list.
|
||||
@ -292,6 +359,7 @@ void uip_grpfree(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group)
|
||||
|
||||
if (IS_PREALLOCATED(group->flags))
|
||||
{
|
||||
grplldbg("Put back on free list\n");
|
||||
sq_addlast((FAR sq_entry_t*)group, &g_freelist);
|
||||
irqrestore(flags);
|
||||
}
|
||||
@ -302,6 +370,7 @@ void uip_grpfree(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group)
|
||||
*/
|
||||
|
||||
irqrestore(flags);
|
||||
grplldbg("Call sched_free()\n");
|
||||
sched_free(group);
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,6 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <wdog.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
@ -113,10 +112,6 @@ void uip_igmpdevinit(struct uip_driver_s *dev)
|
||||
|
||||
group = uip_grpalloc(dev, &g_allsystems);
|
||||
|
||||
/* Initialize the group timer (but don't start it yet) */
|
||||
|
||||
group->wdog = wd_create();
|
||||
|
||||
/* Allow the IGMP messages at the MAC level */
|
||||
|
||||
uip_addmcastmac(dev, &g_allrouters);
|
||||
|
@ -158,7 +158,7 @@ int igmp_leavegroup(struct uip_driver_s *dev, FAR const struct in_addr *grpaddr)
|
||||
|
||||
if (IS_LASTREPORT(group->flags))
|
||||
{
|
||||
ndbg("Schedul Leave Group message\n");
|
||||
ndbg("Schedule Leave Group message\n");
|
||||
IGMP_STATINCR(uip_stat.igmp.leave_sched);
|
||||
uip_igmpwaitmsg(group, IGMP_LEAVE_GROUP);
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <net/uip/uipopt.h>
|
||||
#include <net/uip/uip.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
#include <net/uip/uip-ipopt.h>
|
||||
#include <net/uip/uip-igmp.h>
|
||||
|
||||
#include "uip_internal.h"
|
||||
@ -134,8 +135,8 @@ void uip_igmpsend(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group,
|
||||
|
||||
/* Add the router alert option */
|
||||
|
||||
IGMPBUF->ra[0] = HTONS(ROUTER_ALERT >> 16);
|
||||
IGMPBUF->ra[1] = HTONS(ROUTER_ALERT & 0xffff);
|
||||
IGMPBUF->ra[0] = HTONS(IPOPT_RA >> 16);
|
||||
IGMPBUF->ra[1] = HTONS(IPOPT_RA & 0xffff);
|
||||
|
||||
/* Initialize the IPv4 header */
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
#include <wdog.h>
|
||||
#include <assert.h>
|
||||
@ -59,6 +60,40 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
#undef IGMP_GTMRDEBUG /* Define to enable detailed IGMP group debug */
|
||||
|
||||
#ifndef CONFIG_NET_IGMP
|
||||
# undef IGMP_GTMRDEBUG
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPP_HAVE_VARARGS
|
||||
# ifdef IGMP_GTMRDEBUG
|
||||
# define gtmrdbg(format, arg...) ndbg(format, ##arg)
|
||||
# define gtmrlldbg(format, arg...) nlldbg(format, ##arg)
|
||||
# define gtmrvdbg(format, arg...) nvdbg(format, ##arg)
|
||||
# define gtmrllvdbg(format, arg...) nllvdbg(format, ##arg)
|
||||
# else
|
||||
# define gtmrdbg(x...)
|
||||
# define gtmrlldbg(x...)
|
||||
# define gtmrvdbg(x...)
|
||||
# define gtmrllvdbg(x...)
|
||||
# endif
|
||||
#else
|
||||
# ifdef IGMP_GTMRDEBUG
|
||||
# define gtmrdbg ndbg
|
||||
# define gtmrlldbg nlldbg
|
||||
# define gtmrvdbg nvdbg
|
||||
# define gtmrllvdbg nllvdbg
|
||||
# else
|
||||
# define gtmrdbg (void)
|
||||
# define gtmrlldbg (void)
|
||||
# define gtmrvdbg (void)
|
||||
# define gtmrllvdbg (void)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@ -100,6 +135,14 @@ static void uip_igmptimeout(int argc, uint32_t arg, ...)
|
||||
|
||||
IGMP_STATINCR(uip_stat.igmp.report_sched);
|
||||
uip_igmpschedmsg(group, IGMPv2_MEMBERSHIP_REPORT);
|
||||
|
||||
/* Also note: The Membership Report is sent at most two times becasue
|
||||
* the timer is not reset here. Hmm.. does this mean that the group
|
||||
* is stranded if both reports were lost? This is consistent with the
|
||||
* RFC that states: "To cover the possibility of the initial Membership
|
||||
* Report being lost or damaged, it is recommended that it be repeated
|
||||
* once or twice after shortdelays [Unsolicited Report Interval]..."
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,9 +185,13 @@ int uip_decisec2tick(int decisecs)
|
||||
|
||||
void uip_igmpstartticks(FAR struct igmp_group_s *group, int ticks)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Start the timer */
|
||||
|
||||
wd_start(group->wdog, ticks, uip_igmptimeout, 1, (uint32_t)group);
|
||||
gtmrlldbg("ticks: %d\n", ticks);
|
||||
ret = wd_start(group->wdog, ticks, uip_igmptimeout, 1, (uint32_t)group);
|
||||
DEBUGASSERT(ret == OK);
|
||||
}
|
||||
|
||||
void uip_igmpstarttimer(FAR struct igmp_group_s *group, uint8_t decisecs)
|
||||
@ -153,6 +200,7 @@ void uip_igmpstarttimer(FAR struct igmp_group_s *group, uint8_t decisecs)
|
||||
* Important!! this should be a random timer from 0 to decisecs
|
||||
*/
|
||||
|
||||
gtmrdbg("decisecs: %d\n", decisecs);
|
||||
uip_igmpstartticks(group, uip_decisec2tick(decisecs));
|
||||
}
|
||||
|
||||
@ -192,6 +240,7 @@ bool uip_igmpcmptimer(FAR struct igmp_group_s *group, int maxticks)
|
||||
* test as well.
|
||||
*/
|
||||
|
||||
gtmrdbg("maxticks: %d remaining: %d\n", maxticks, remaining);
|
||||
if (maxticks > remaining)
|
||||
{
|
||||
/* Cancel the watchdog timer and return true */
|
||||
|
Loading…
x
Reference in New Issue
Block a user