]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - support/sdk/c/blip/driver/radvd-1.0/device-bsd44.c
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / support / sdk / c / blip / driver / radvd-1.0 / device-bsd44.c
diff --git a/support/sdk/c/blip/driver/radvd-1.0/device-bsd44.c b/support/sdk/c/blip/driver/radvd-1.0/device-bsd44.c
new file mode 100644 (file)
index 0000000..b89ce31
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ *   $Id$
+ *
+ *   Authors:
+ *    Craig Metz               <cmetz@inner.net>
+ *
+ *   This software is Copyright 1996,1997 by the above mentioned author(s), 
+ *   All Rights Reserved.
+ *
+ *   The license which is distributed with this software in the file COPYRIGHT
+ *   applies to this software. If your distribution is missing this file, you
+ *   may request it from <pekkas@netcore.fi>.
+ *
+ */
+
+#include <config.h>
+#include <includes.h>
+#include <radvd.h>
+#include <defaults.h>
+#include <pathnames.h>         /* for PATH_PROC_NET_IF_INET6 */
+
+static uint8_t ll_prefix[] = { 0xfe, 0x80 };
+
+/*
+ * this function gets the hardware type and address of an interface,
+ * determines the link layer token length and checks it against
+ * the defined prefixes
+ */
+int
+setup_deviceinfo(int sock, struct Interface *iface)
+{
+       struct ifconf ifconf;
+       struct ifreq ifr;
+       unsigned int nlen;
+       uint8_t *p, *end;
+       struct AdvPrefix *prefix;
+       char zero[sizeof(iface->if_addr)];
+
+       /* just allocate 8192 bytes, should be more than enough.. */
+       if (!(ifconf.ifc_buf = malloc(ifconf.ifc_len = (32 << 8))))
+       {
+               flog(LOG_CRIT, "malloc failed: %s", strerror(errno));
+               goto ret;
+       }
+
+       if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0)
+       {
+               flog(LOG_ERR, "ioctl(SIOCGIFCONF) failed: %s(%d)", strerror(errno), errno);
+               goto ret;
+       }
+
+       memset(&ifr, 0, sizeof(ifr));
+       strncpy(ifr.ifr_name, iface->Name, IFNAMSIZ-1);
+       ifr.ifr_name[IFNAMSIZ-1] = '\0';
+
+       if (ioctl(sock, SIOCGIFMTU, &ifr) < 0) {
+               flog(LOG_ERR, "ioctl(SIOCGIFMTU) failed for %s: %s", iface->Name, strerror(errno));
+               goto ret;
+       }       
+
+       dlog(LOG_DEBUG, 3, "mtu for %s is %d", iface->Name, ifr.ifr_mtu);
+       iface->if_maxmtu = ifr.ifr_mtu;
+
+       p = (uint8_t *)ifconf.ifc_buf;
+       end = p + ifconf.ifc_len;
+       nlen = strlen(iface->Name);
+
+       while(p < end)
+       {
+               p += IFNAMSIZ;
+               
+               if ((p + 2) >= end)
+                       break;
+                       
+               if ((p + *p) >= end)
+                       break;
+                       
+               if ((*(p + 1) == AF_LINK) &&
+                   (((struct sockaddr_dl *)p)->sdl_nlen == nlen) &&
+                   (!memcmp(iface->Name, ((struct sockaddr_dl *)p)->sdl_data, nlen)))
+               {
+               
+                       if (((struct sockaddr_dl *)p)->sdl_alen > sizeof(iface->if_addr))
+                       {
+                               flog(LOG_ERR, "address length %d too big for",
+                                       ((struct sockaddr_dl *)p)->sdl_alen,
+                                       iface->Name);
+                               goto ret;
+                       }
+               
+                       memcpy(iface->if_hwaddr, LLADDR((struct sockaddr_dl *)p), ((struct sockaddr_dl *)p)->sdl_alen);
+                       iface->if_hwaddr_len = ((struct sockaddr_dl *)p)->sdl_alen << 3;
+
+                       switch(((struct sockaddr_dl *)p)->sdl_type) {
+                       case IFT_ETHER:
+                       case IFT_ISO88023:
+                               iface->if_prefix_len = 64;
+                               break;
+                       case IFT_FDDI:
+                               iface->if_prefix_len = 64;
+                               break;
+                       default:
+                               iface->if_prefix_len = -1;
+                               iface->if_maxmtu = -1;
+                               break;
+                       }
+
+                       dlog(LOG_DEBUG, 3, "link layer token length for %s is %d", iface->Name,
+                               iface->if_hwaddr_len);
+
+                       dlog(LOG_DEBUG, 3, "prefix length for %s is %d", iface->Name,
+                               iface->if_prefix_len);
+
+                       if (iface->if_prefix_len != -1) {
+                               memset(zero, 0, ((struct sockaddr_dl *)p)->sdl_alen);
+                               if (!memcmp(iface->if_hwaddr, zero, ((struct sockaddr_dl *)p)->sdl_alen))
+                                       flog(LOG_WARNING, "WARNING, MAC address on %s is all zero!",
+                                               iface->Name);
+                       }
+                       
+                       prefix = iface->AdvPrefixList;
+                       while (prefix)
+                       {
+                               if ((iface->if_prefix_len != -1) &&
+                                       (iface->if_prefix_len != prefix->PrefixLen))
+                               {
+                                       flog(LOG_WARNING, "prefix length should be %d for %s",
+                                               iface->if_prefix_len, iface->Name);
+                               }
+                       
+                               prefix = prefix->next;
+                       }
+                       
+                       free(ifconf.ifc_buf);
+                       return 0;
+               }
+        
+               p += *p;        
+       }
+
+ret:
+       iface->if_maxmtu = -1;
+       iface->if_hwaddr_len = -1;
+       iface->if_prefix_len = -1;
+       free(ifconf.ifc_buf);
+       return -1;
+}
+
+int setup_linklocal_addr(int sock, struct Interface *iface)
+{
+       struct ifconf ifconf;
+       unsigned int nlen;
+       uint8_t *p, *end;
+       int index = 0;
+
+       /* just allocate 8192 bytes, should be more than enough.. */
+       if (!(ifconf.ifc_buf = malloc(ifconf.ifc_len = (32 << 8))))
+       {
+               flog(LOG_CRIT, "malloc failed: %s", strerror(errno));
+               goto ret;
+       }
+
+       if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0)
+       {
+               flog(LOG_ERR, "ioctl(SIOCGIFCONF) failed: %s(%d)", strerror(errno), errno);
+               goto ret;
+       }
+
+       p = (uint8_t *)ifconf.ifc_buf;
+       end = p + ifconf.ifc_len;
+       nlen = strlen(iface->Name);
+
+       while(p < end)
+       {
+               p += IFNAMSIZ;
+       
+               if ((p + 2) >= end)
+                       break;
+                       
+               if ((p + *p) >= end)
+                       break;
+                       
+               if ((*(p + 1) == AF_LINK) &&
+                   (((struct sockaddr_dl *)p)->sdl_nlen == nlen) &&
+                   (!memcmp(iface->Name, ((struct sockaddr_dl *)p)->sdl_data, nlen)))
+               {
+                       index = ((struct sockaddr_dl *)p)->sdl_index;
+               }
+               
+               if (index && (*(p + 1) == AF_INET6))
+                 if (!memcmp(&((struct sockaddr_in6 *)p)->sin6_addr, ll_prefix, sizeof(ll_prefix)))
+                 {
+                       memcpy(&iface->if_addr, &((struct sockaddr_in6 *)p)->sin6_addr, sizeof(struct in6_addr));
+                       iface->if_index = index;
+
+                       free(ifconf.ifc_buf);
+                       return 0;
+                 }
+         
+               p += *p;
+
+       }
+
+ret:
+       flog(LOG_ERR, "no linklocal address configured for %s", iface->Name);
+       free(ifconf.ifc_buf);
+       return -1;
+}
+
+int setup_allrouters_membership(int sock, struct Interface *iface)
+{
+       return (0);
+}
+
+int check_allrouters_membership(int sock, struct Interface *iface)
+{
+       return (0);
+}
+
+int
+set_interface_linkmtu(const char *iface, uint32_t mtu)
+{
+       dlog(LOG_DEBUG, 4, "setting LinkMTU (%u) for %s is not supported",
+            mtu, iface);
+       return -1;
+}
+
+int
+set_interface_curhlim(const char *iface, uint8_t hlim)
+{
+       dlog(LOG_DEBUG, 4, "setting CurHopLimit (%u) for %s is not supported",
+            hlim, iface);
+       return -1;
+}
+
+int
+set_interface_reachtime(const char *iface, uint32_t rtime)
+{
+       dlog(LOG_DEBUG, 4, "setting BaseReachableTime (%u) for %s is not supported",
+            rtime, iface);
+       return -1;
+}
+
+int
+set_interface_retranstimer(const char *iface, uint32_t rettimer)
+{
+       dlog(LOG_DEBUG, 4, "setting RetransTimer (%u) for %s is not supported",
+            rettimer, iface);
+       return -1;
+}
+