diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html index 700137d1b90..6b2a545d988 100644 --- a/Documentation/NuttX.html +++ b/Documentation/NuttX.html @@ -452,7 +452,7 @@

-

  • TCP/IP, UDP, ICMP stacks.
  • +
  • TCP/IP, UDP, ICMP, IGMPv2 (client) stacks.
  • diff --git a/configs/eagle100/nettest/defconfig b/configs/eagle100/nettest/defconfig index 1ae40392717..0aa0f5e732c 100644 --- a/configs/eagle100/nettest/defconfig +++ b/configs/eagle100/nettest/defconfig @@ -259,7 +259,6 @@ CONFIG_EXAMPLE=nettest CONFIG_DEBUG=y CONFIG_DEBUG_VERBOSE=n CONFIG_DEBUG_SYMBOLS=n -CONFIG_DEBUG_SYMBOLS=n CONFIG_DEBUG_NET=y CONFIG_MM_REGIONS=1 CONFIG_ARCH_LOWPUTC=y diff --git a/examples/igmp/igmp.c b/examples/igmp/igmp.c index 2810739409b..c341e4c1dcf 100755 --- a/examples/igmp/igmp.c +++ b/examples/igmp/igmp.c @@ -87,7 +87,9 @@ int user_start(int argc, char *argv[]) uint8_t mac[IFHWADDRLEN]; #endif -/* Many embedded network interfaces must have a software assigned MAC */ + message("Configuring Ethernet...\n"); + + /* Many embedded network interfaces must have a software assigned MAC */ #ifdef CONFIG_EXAMPLE_IGMP_NOMAC mac[0] = 0x00; @@ -117,19 +119,23 @@ int user_start(int argc, char *argv[]) /* Not much of a test for now */ /* Join the group */ + message("Join group...\n"); addr.s_addr = HTONL(CONFIG_EXAMPLE_IGMP_GRPADDR); ipmsfilter("eth0", &addr, MCAST_INCLUDE); /* Wait a while */ + message("Wait for timeout...\n"); sleep(5); /* Leave the group */ + message("Leave group...\n"); ipmsfilter("eth0", &addr, MCAST_EXCLUDE); /* Wait a while */ sleep(5); + message("Exiting...\n"); return 0; } diff --git a/include/net/uip/uip-igmp.h b/include/net/uip/uip-igmp.h index e57d8b438fd..184153a846c 100755 --- a/include/net/uip/uip-igmp.h +++ b/include/net/uip/uip-igmp.h @@ -110,6 +110,7 @@ #define IS_SCHEDMSG(f) (((f) & IGMP_SCHEDMSG) != 0) #define IS_WAITMSG(f) (((f) & IGMP_WAITMSG) != 0) +#define ROUTER_ALERT 0x94040000 #define IGMP_TTL 1 /**************************************************************************** diff --git a/net/uip/uip_arp.c b/net/uip/uip_arp.c index b0e3e3fe7ba..6e00a6b6326 100644 --- a/net/uip/uip_arp.c +++ b/net/uip/uip_arp.c @@ -2,7 +2,7 @@ * net/uip/uip_arp.c * Implementation of the ARP Address Resolution Protocol. * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Based on uIP which also has a BSD style license: @@ -64,19 +64,29 @@ #include #include #include +#ifdef CONFIG_NET_IGMP +# include +#endif /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -#define ARP_REQUEST 1 -#define ARP_REPLY 2 +#define ARP_REQUEST 1 +#define ARP_REPLY 2 #define ARP_HWTYPE_ETH 1 -#define ETHBUF ((struct uip_eth_hdr *)&dev->d_buf[0]) -#define ARPBUF ((struct arp_hdr *)&dev->d_buf[UIP_LLH_LEN]) -#define IPBUF ((struct ethip_hdr *)&dev->d_buf[UIP_LLH_LEN]) +#define RASIZE 4 /* Size of ROUTER ALERT */ + +#define ETHBUF ((struct uip_eth_hdr *)&dev->d_buf[0]) +#define ARPBUF ((struct arp_hdr *)&dev->d_buf[UIP_LLH_LEN]) +#define IPBUF ((struct ethip_hdr *)&dev->d_buf[UIP_LLH_LEN]) + +#ifdef CONFIG_NET_IGMP +# define RA ((uint16_t *)&dev->d_buf[UIP_LLH_LEN]) +# define RAIPBUF ((struct ethip_hdr *)&dev->d_buf[UIP_LLH_LEN+RASIZE]) +#endif /**************************************************************************** * Private Types @@ -288,10 +298,28 @@ void uip_arp_out(struct uip_driver_s *dev) const struct arp_entry *tabptr = NULL; struct arp_hdr *parp = ARPBUF; struct uip_eth_hdr *peth = ETHBUF; - struct ethip_hdr *pip = IPBUF; + struct ethip_hdr *pip; in_addr_t ipaddr; in_addr_t destipaddr; + /* Check for the router alert option */ + +#if CONFIG_NET_IGMP + if (RA[0] == HTONS(ROUTER_ALERT >> 16) && RA[1] == HTONS(ROUTER_ALERT & 0xffff)) + { + /* Yes... there is a router alert. This must be an IGMP packet. + * bump up the IP header address to index around the router alert. + */ + + pip = RAIPBUF; + } + else +#else + { + pip = IPBUF; + } +#endif + /* Find the destination IP address in the ARP table and construct * the Ethernet header. If the destination IP addres isn't on the * local network, we use the default router's IP address instead. @@ -316,18 +344,18 @@ void uip_arp_out(struct uip_driver_s *dev) * addresses=0xff (ff00::/8.) */ - else if (pip->eh_destipaddr[0] >= HTONS(0xe000) && - pip->eh_destipaddr[0] <= HTONS(0xefff)) - { - /* Build the well-known IPv4 IGMP ethernet address. The first - * three bytes are fixed; the final three variable come from the - * last three bytes of the IP address. - */ + else if (NTOHS(pip->eh_destipaddr[0]) >= 0xe000 && + NTOHS(pip->eh_destipaddr[0]) <= 0xefff) + { + /* Build the well-known IPv4 IGMP ethernet address. The first + * three bytes are fixed; the final three variable come from the + * last three bytes of the IP address. + */ - const uint8_t *ip = ((uint8_t*)pip->eh_destipaddr) + 1; - memcpy(peth->dest, g_multicast_ethaddr, 3); - memcpy(&peth->dest[3], ip, 3); - } + const uint8_t *ip = ((uint8_t*)pip->eh_destipaddr) + 1; + memcpy(peth->dest, g_multicast_ethaddr, 3); + memcpy(&peth->dest[3], ip, 3); + } #endif else { diff --git a/net/uip/uip_igmpinput.c b/net/uip/uip_igmpinput.c index e2c143fc77a..ed56d9adbc6 100755 --- a/net/uip/uip_igmpinput.c +++ b/net/uip/uip_igmpinput.c @@ -118,14 +118,14 @@ void uip_igmpinput(struct uip_driver_s *dev) uip_ipaddr_t grpaddr; unsigned int ticks; - nvdbg("IGMP message: %04x%04x\n", IGMPBUF->destipaddr[1], IGMPBUF->destipaddr[0]); + nllvdbg("IGMP message: %04x%04x\n", IGMPBUF->destipaddr[1], IGMPBUF->destipaddr[0]); /* Verify the message length */ if (dev->d_len < UIP_LLH_LEN+UIP_IPIGMPH_LEN) { IGMP_STATINCR(uip_stat.igmp.length_errors); - ndbg("Length error\n"); + nlldbg("Length error\n"); return; } @@ -134,7 +134,7 @@ void uip_igmpinput(struct uip_driver_s *dev) if (uip_chksum((uint16_t*)&IGMPBUF->type, UIP_IGMPH_LEN) != 0) { IGMP_STATINCR(uip_stat.igmp.chksum_errors); - ndbg("Checksum error\n"); + nlldbg("Checksum error\n"); return; } @@ -182,13 +182,13 @@ void uip_igmpinput(struct uip_driver_s *dev) /* This is the general query */ - nvdbg("General multicast query\n"); + nllvdbg("General multicast query\n"); if (IGMPBUF->maxresp == 0) { IGMP_STATINCR(uip_stat.igmp.v1_received); IGMPBUF->maxresp = 10; - ndbg("V1 not implemented\n"); + nlldbg("V1 not implemented\n"); } IGMP_STATINCR(uip_stat.igmp.query_received); @@ -212,7 +212,7 @@ void uip_igmpinput(struct uip_driver_s *dev) } else /* if (group->grpaddr != 0) */ { - nvdbg("Group-specific multicast queury\n"); + nllvdbg("Group-specific multicast queury\n"); /* We first need to re-lookup the group since we used dest last time. * Use the incoming IPaddress! @@ -234,10 +234,10 @@ void uip_igmpinput(struct uip_driver_s *dev) else if (group->grpaddr != 0) { - nvdbg("Unitcast queury\n"); + nllvdbg("Unitcast queury\n"); IGMP_STATINCR(uip_stat.igmp.ucast_query); - ndbg("Query to a specific group with the group address as destination\n"); + nlldbg("Query to a specific group with the group address as destination\n"); ticks = uip_decisec2tick((int)IGMPBUF->maxresp); if (IS_IDLEMEMBER(group->flags) || uip_igmpcmptimer(group, ticks)) @@ -250,7 +250,7 @@ void uip_igmpinput(struct uip_driver_s *dev) case IGMPv2_MEMBERSHIP_REPORT: { - nvdbg("Membership report\n"); + nllvdbg("Membership report\n"); IGMP_STATINCR(uip_stat.igmp.report_received); if (!IS_IDLEMEMBER(group->flags)) @@ -266,8 +266,7 @@ void uip_igmpinput(struct uip_driver_s *dev) default: { - nvdbg("Unexpected msg %02x in state %d on group %p at dev %p\n", - IGMPBUF->type, group->state, &group, dev); + nlldbg("Unexpected msg %02x\n", IGMPBUF->type); } break; } diff --git a/net/uip/uip_igmpjoin.c b/net/uip/uip_igmpjoin.c index cf37ea1c0f8..b9e538c15a5 100755 --- a/net/uip/uip_igmpjoin.c +++ b/net/uip/uip_igmpjoin.c @@ -148,7 +148,7 @@ int igmp_joingroup(struct uip_driver_s *dev, FAR const struct in_addr *grpaddr) /* Add the group (MAC) address to the ether drivers MAC filter list */ - uip_addmcastmac(dev, &grpaddr->s_addr); + uip_addmcastmac(dev, (FAR uip_ipaddr_t *)&grpaddr->s_addr); return OK; } return -EEXIST; diff --git a/net/uip/uip_igmpleave.c b/net/uip/uip_igmpleave.c index ac1cc81d5cd..5665081b5dd 100755 --- a/net/uip/uip_igmpleave.c +++ b/net/uip/uip_igmpleave.c @@ -168,7 +168,7 @@ int igmp_leavegroup(struct uip_driver_s *dev, FAR const struct in_addr *grpaddr) /* And remove the group address from the ethernet drivers MAC filter set */ - uip_removemcastmac(dev, &grpaddr->s_addr); + uip_removemcastmac(dev, (FAR uip_ipaddr_t *)&grpaddr->s_addr); return OK; } return -ENOENT; diff --git a/net/uip/uip_igmpsend.c b/net/uip/uip_igmpsend.c index c815882a41c..33b3fd2d98e 100755 --- a/net/uip/uip_igmpsend.c +++ b/net/uip/uip_igmpsend.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -54,8 +55,24 @@ * Pre-processor Definitions ****************************************************************************/ -#define RASIZE (8) -#define ROUTERALERT ((uint16_t*)&dev->d_buf[UIP_LLH_LEN]) +/* Debug */ + +#undef IGMP_DUMPPKT /* Define to enable packet dump */ + +#ifndef CONFIG_DEBUG_NET +# undef IGMP_DUMPPKT +#endif + +#ifdef IGMP_DUMPPKT +# define igmp_dumppkt(b,n) lib_dumpbuffer("IGMP", (FAR const uint8_t*)(b), (n)) +#else +# define igmp_dumppkt(b,n) +#endif + +/* Buffer layout */ + +#define RASIZE (4) +#define RA ((uint16_t*)&dev->d_buf[UIP_LLH_LEN]) #define IGMPBUF ((struct uip_igmphdr_s *)&dev->d_buf[UIP_LLH_LEN + RASIZE]) #define IGMPPAYLOAD (&dev->d_buf[UIP_LLH_LEN + RASIZE + UIP_IPH_LEN]) @@ -105,6 +122,8 @@ static uint16_t uip_igmpchksum(FAR uint8_t *buffer, int buflen) void uip_igmpsend(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group, FAR uip_ipaddr_t *destipaddr) { + nllvdbg("msgid: %02x destipaddr: %08x\n", group->msgid, (int)destipaddr); + /* The total length to send is the size of the IP and IGMP headers and 8 * bytes for the ROUTER ALERT (and, eventually, the ethernet header) */ @@ -117,8 +136,8 @@ void uip_igmpsend(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group, /* Add the router alert option */ - ROUTERALERT[0] = HTONS(0x9404); - ROUTERALERT[1] = 0; + RA[0] = HTONS(ROUTER_ALERT >> 16); + RA[1] = HTONS(ROUTER_ALERT & 0xffff); /* Initialize the IPv4 header */ @@ -140,7 +159,7 @@ void uip_igmpsend(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group, /* Calculate IP checksum. */ IGMPBUF->ipchksum = 0; - IGMPBUF->ipchksum = ~uip_igmpchksum((FAR uint8_t *)ROUTERALERT, UIP_IPH_LEN + RASIZE); + IGMPBUF->ipchksum = ~uip_igmpchksum((FAR uint8_t *)RA, UIP_IPH_LEN + RASIZE); /* Set up the IGMP message */ @@ -158,7 +177,7 @@ void uip_igmpsend(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group, nllvdbg("Outgoing IGMP packet length: %d (%d)\n", dev->d_len, (IGMPBUF->len[0] << 8) | IGMPBUF->len[1]); - + igmp_dumppkt(RA, UIP_IPIGMPH_LEN + RASIZE); } #endif /* CONFIG_NET_IGMP */ diff --git a/net/uip/uip_mcastmac.c b/net/uip/uip_mcastmac.c index be0e2151314..72927f740a0 100755 --- a/net/uip/uip_mcastmac.c +++ b/net/uip/uip_mcastmac.c @@ -81,7 +81,7 @@ static void uip_mcastmac(uip_ipaddr_t *ip, FAR uint8_t *mac) mac[4] = ip4_addr3(*ip); mac[5] = ip4_addr4(*ip); - nvdbg("IP: %04x -> MAC: %02%02%02%02%02%02\n", + nvdbg("IP: %04x -> MAC: %02x%02x%02x%02x%02x%02x\n", *ip, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); }