diff packages/net/common/current/src/ipv6_routing_thread.c @ 957:db3e0a2fda2f

2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch> * src/network_support.c (init_loopback_interface): Close the socket when things go wrong otherwise we leak sockets. * src/tftp_server.c (tftpd_server): Added support for IPv6 as well as IPv4. Extended the multithreading support so that it works correctly when there are multiple servers on multiple ports. * doc/tcpip.sgml: Documentation for the changes made to the tftp server. 2003-04-10 Andrew Lunn <andrew.lunn@ascom.ch> * src/network_support.c (init_all_network_interfaces): Wait upto 4 seconds for a router solicit message to be received. Once we have received the message we know we have a valid IPv6 address. * src/tftp_client.c: Added support for IPv6. This requires two new functions, tftp_client_{get|put} which are protocol version independent. * tests/tftp_client_test.c (tftp_test): Added tests which use IPv6 addresses. 2003-04-07 Andrew Lunn <andrew.lunn@ascom.ch> * src/getaddrinfo.c (getaddrinfo): Correctly deal with node when its not NULL. Its OK for the address to not parse for an address family when AF_UNSPEC is passed in hints. Also get the socktype correct when wildcarding for services that use UDP. * tests/addr_test.c: Added more test cases which test IP addresses in number format as node. 2003-04-05 Andrew Lunn <andrew.lunn@ascom.ch> * cdl/net.cdl: Added addr_tests to the HW tests. * tests/addr_test.c (net_test): void function not int. * tests/ping_test.c (net_test): Added IPv6 ping test. This pings the router which answers our router solicit message. * src/ipv6_routing_thread.c (cyg_rs): Print out the router advertisement message. Cleaned up the debug messages so they can be disabled. * src/ipv6_routing_thread.c (cyg_net_get_ipv6_advrouter): New function to return the address of the router. * include/network.h: Added prototype for above and ipv6_start_routing_thread which did not have a prototype. * src/ipv6_routing_thread.c (cyg_rs): Only wait 2 seconds before sending the first solicit request rather than 10. * src/dhcp_prot.c (do_dhcp_down_net): clear the if_laddrreq before using it. If the request fails finish the IPv4 code rather than returning,. 2003-04-02 Andrew Lunn <andrew.lunn@ascom.ch> * tests/ping_lo_test.c: Added IPv6 ping test. * src/getproto.c: Added the protocol ipv6-icmp.
author asl
date Wed, 23 Apr 2003 08:52:08 +0000
parents 58c748750ca6
children 16d247bb9c70
line wrap: on
line diff
--- a/packages/net/common/current/src/ipv6_routing_thread.c
+++ b/packages/net/common/current/src/ipv6_routing_thread.c
@@ -19,7 +19,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    gthomas
-// Contributors: gthomas, lhamilton
+// Contributors: gthomas, lhamilton, andrew.lunn@ascom.ch
 // Date:         2002-04-16
 // Purpose:      
 // Description:  
@@ -58,7 +58,7 @@
 
 void _show_all_interfaces(void);
 
-#define DBG_PRINT                          1
+//#define DBG_PRINT                          1
 #define ALLROUTER                  "ff02::2"
 
 #define STACK_SIZE    CYGNUM_HAL_STACK_SIZE_TYPICAL+2048
@@ -87,6 +87,19 @@ static struct timeval last_ra_time;
 static struct timeval idle_expire;
 static struct icmp6stat *istat;
 extern struct icmp6stat cyg_icmp6stat;
+static struct sockaddr_in6 router;
+static int router_valid = 0;
+
+// Return the address of the last router to send us a router advertisement 
+// Copy the address into addr and return true. If we have not received an
+// advertisement yet, return false
+int cyg_net_get_ipv6_advrouter(struct sockaddr_in6 * addr) {
+  
+  if (addr) {
+    memcpy(addr,&router,sizeof(*addr));
+  }
+  return router_valid;
+}
 
 static void
 cyg_rs_exit(void)
@@ -154,17 +167,87 @@ receive_ra_packet(void)
 {
   int len;
   char msg[1024];
+  struct nd_router_advert *advert;
+  cyg_uint8 *opts;
+  int optlen;
+  int addrlen = sizeof(router);
+  char buf[64];
 
   dprnt("%s", __FUNCTION__);
 
-  len = read(s, msg, sizeof(msg));
+  len = recvfrom(s, msg, sizeof(msg),0,(struct sockaddr *)&router,&addrlen);
   if (len < 0) {
     dprnt("  Can't read RA data: %s", strerror(errno));
     return;
   }
+  router_valid = 1;
+
+  inet_ntop(AF_INET6,(void *)&router.sin6_addr,buf,64);  
+  dprnt("Router Advertisement from %s",buf);
   dprnt("packet data (buf len=%d) :", len);
+#ifdef DBG_PRINT  
   diag_dump_buf(msg, len);
+#endif
 
+  advert = (struct nd_router_advert *)msg;
+
+  dprnt("AdvCurHopLimit: %d", (int) advert->nd_ra_curhoplimit);
+  dprnt("AdvManagedFlag: %s",
+	(advert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) ? "yes" : "no");
+  dprnt("AdvOtherConfigFlag: %s",
+	(advert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) ? "yes":"no");
+  dprnt("AdvHomeAgentFlag: %s",
+	 (advert->nd_ra_flags_reserved & ND_RA_FLAG_HOME_AGENT) ? 
+	 "yes" : "no");
+  dprnt("AdvReachableTime: %lu", 
+	 (unsigned long)ntohl(advert->nd_ra_reachable));
+  dprnt("AdvRetransTimer: %lu", 
+	(unsigned long)ntohl(advert->nd_ra_retransmit));
+  
+  // Now process the optinal fields 
+  len -= sizeof(*advert);
+  opts = (cyg_uint8 *)(msg + sizeof(struct nd_router_advert));
+
+  while (len > 0) {
+     optlen = (opts[1] << 3);
+     switch (*opts) {
+     case ND_OPT_MTU: {
+       struct nd_opt_mtu *mtu = (struct nd_opt_mtu *) opts;
+
+       dprnt("AdvLinkMTU: %lu", 
+	     (unsigned long)ntohl(mtu->nd_opt_mtu_mtu));
+       break;
+     }
+     case ND_OPT_PREFIX_INFORMATION: {
+       struct nd_opt_prefix_info *pinfo = (struct nd_opt_prefix_info *) opts;
+
+       inet_ntop(AF_INET6,(void *)&pinfo->nd_opt_pi_prefix,buf,64);
+       dprnt("Prefix:  %s/%d",buf,pinfo->nd_opt_pi_prefix_len);
+       break;
+     }
+     case ND_OPT_SOURCE_LINKADDR: {
+       char *cp = buf;
+       int i;
+       
+       for (i = 2 ; i < optlen ; i++) {
+	 cp += diag_sprintf(cp,"%02x ", (unsigned int) opts[i]);
+       }
+      
+       dprnt("AdvSourceLinkAddress: %s",buf);
+       break;
+     }
+     case ND_OPT_ADVINTERVAL:
+     case ND_OPT_HOMEAGENT_INFO:
+       dprnt("Mobile IPv6 entension options (not decoded)");
+       break;
+     default:
+       dprnt("Unknown option %d\n", (int)*opts);
+       break;
+     }
+     len -= optlen;
+     opts += optlen;
+  }
+       
   racount++;
   get_realtime(&last_ra_time);
   dprnt("racount=%d, timestamp=%d sec",
@@ -251,7 +334,9 @@ cyg_rs(cyg_addrword_t param)
   u_int hlim = 255;
   fd_set fdset;
 
+#ifdef DBG_PRINT
   _show_all_interfaces();
+#endif
 
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = AF_INET6;
@@ -289,7 +374,7 @@ cyg_rs(cyg_addrword_t param)
   idle_expire.tv_usec = 0;
   select_timeout.tv_usec = 0;
   last_ra_time.tv_usec = 0;
-  last_ra_time.tv_sec = 10;
+  last_ra_time.tv_sec = 2;
   select(0, 0, 0, 0, &last_ra_time);
 
   racount = 0;