Print this page
        
@@ -52,10 +52,24 @@
  * @brief  Functions to interact with the network sockets and NIC driver.
  *
  *
  */
 
+#ifdef __sun
+/*
+ * These are needed to enable control messages on sendmsg().
+ * I'll save the commentary on why the bend-over-backwards old way of doing
+ * sendmsg() is still around.
+ *
+ * STRICTLY SPEAKING this program should be linked against libxnet instead
+ * of libsocket because of these interfaces, but we'll cross that bridge
+ * when we get to it.
+ */
+#define _XOPEN_SOURCE 500
+#define __EXTENSIONS__
+#endif
+
 #include "../ptpd.h"
 
 #ifdef PTPD_PCAP
 #ifdef HAVE_PCAP_PCAP_H
 #include <pcap/pcap.h>
@@ -304,12 +318,12 @@
 
     int ret;
     if(!strlen(ifaceName))
         return 0;
 
+#if defined(AF_LINK) && !defined(__sun)
 /* BSD* - AF_LINK gives us access to the hw address via struct sockaddr_dl */
-#ifdef AF_LINK
 
     struct ifaddrs *ifaddr, *ifa;
 
     if(getifaddrs(&ifaddr) == -1) {
         PERROR("Could not get interface list");
@@ -345,12 +359,12 @@
 end:
 
     freeifaddrs(ifaddr);
     return ret;
 
-/* Linux, basically */
 #else
+/* Linux and Solarish systems have SIOCGIFHWADDR/SIOCGLIFHWADDR.  Use it. */
 
     int sockfd;
     struct ifreq ifr;
 
     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
@@ -358,11 +372,11 @@
     if(sockfd < 0) {
         PERROR("Could not open test socket");
         return -1;
     }
 
-    memset(&ifr, 0, sizeof(struct ifreq));
+    memset(&ifr, 0, sizeof (ifr));
 
     strncpy(ifr.ifr_name, ifaceName, IFACE_NAME_LENGTH);
 
     if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {
             DBGV("failed to request hardware address for %s", ifaceName);
@@ -369,19 +383,27 @@
             ret = -1;
             goto end;
     }
 
 
+#ifdef __sun
+    int af = ifr.ifr_addr.sa_family;
+#else
     int af = ifr.ifr_hwaddr.sa_family;
+#endif
 
     if (    af == ARPHRD_ETHER
          || af == ARPHRD_IEEE802
 #ifdef ARPHRD_INFINIBAND
          || af == ARPHRD_INFINIBAND
 #endif
         ) {
+#ifdef __sun
+            memcpy(hwAddr, ifr.ifr_addr.sa_data, hwAddrSize);
+#else
             memcpy(hwAddr, ifr.ifr_hwaddr.sa_data, hwAddrSize);
+#endif
             ret = 1;
         } else {
             DBGV("Unsupported hardware address family on %s\n", ifaceName);
             ret = 0;
         }
@@ -572,11 +594,11 @@
 }
 
 static Boolean
 netSetMulticastTTL(int sockfd, int ttl) {
 
-#ifdef __OpenBSD__
+#if defined(__OpenBSD__) || defined(__sun)
         uint8_t temp = (uint8_t) ttl;
 #else
         int temp = ttl;
 #endif
 
@@ -588,11 +610,11 @@
         return TRUE;
 }
 
 static Boolean
 netSetMulticastLoopback(NetPath * netPath, Boolean value) {
-#ifdef __OpenBSD__
+#if defined(__OpenBSD__) || defined(__sun)
         uint8_t temp = value ? 1 : 0;
 #else
         int temp = value ? 1 : 0;
 #endif
         DBG("Going to set multicast loopback with %d \n", temp);
@@ -746,11 +768,15 @@
 hostLookup(const char* hostname, Integer32* addr)
 {
         if (hostname[0]) {
                 /* Attempt a DNS lookup first. */
                 struct hostent *host;
+#ifdef __sun
+                host = getipnodebyname(hostname, AF_INET, AI_DEFAULT, &errno);
+#else
                 host = gethostbyname2(hostname, AF_INET);
+#endif
                 if (host != NULL) {
                         if (host->h_length != 4) {
                                 PERROR("unicast host resolved to non ipv4"
                                        "address");
                                 return FALSE;