--- server/getmac.c.orig	Tue Jun  4 12:27:49 1996
+++ server/getmac.c	Wed Apr 22 01:13:18 1998
@@ -31,7 +31,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <nlist.h>
 #include <syslog.h>
 #include <errno.h>
 
@@ -39,23 +38,38 @@
 #include <sys/param.h>
 #include <sys/time.h>
 #include <sys/proc.h>
-#include <kvm.h>
-#include <fcntl.h>
 
 #include <sys/socket.h>
 #include <net/if.h>
 
+#if !defined(__FreeBSD__)
+
+#include <nlist.h>
+#include <kvm.h>
+#include <fcntl.h>
+
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netinet/if_ether.h>
 #include <arpa/inet.h>
 
+#else
+#include <osreldate.h>
+#if (__FreeBSD_version == 199702) || (__FreeBSD_version >= 300000)
+#include <net/if_var.h>
+#endif
+#include <sys/sysctl.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+#endif
+
 /* Cast a struct sockaddr to a sockaddr_in */
 #define SATOSIN(sa) ((struct sockaddr_in *)(sa))
 
 /* Determine if "bits" is set in "flag" */
 #define ALLSET(flag, bits) (((flag) & (bits)) == (bits))
 
+#if !defined(__FreeBSD__)
 static struct nlist nl[] = {
 #define N_IFNET 0
 	{ "_ifnet" },
@@ -104,7 +118,7 @@
 
   ac = &arpcom;
   ifp = &arpcom.ac_if;
-#if defined(__bsdi__) || defined(__FreeBSD__)
+#if defined(__bsdi__)
   ep = arpcom.ac_enaddr;
 #else
   ep = arpcom.ac_enaddr.ether_addr_octet;
@@ -150,4 +164,92 @@
   syslog(LOG_ERR, "getmac() is failed");
   return(-1);
 }
+#else
+int
+getmac(ifname, result)
+  char *ifname;
+  char *result;
+{
+  int flags;
+  struct  if_msghdr *ifm, *nextifm;
+  struct  ifa_msghdr *ifam;
+  struct  sockaddr_dl *sdl;
+  char    *buf, *lim, *next;
+  size_t needed;
+  int mib[6];
+
+  mib[0] = CTL_NET;
+  mib[1] = PF_ROUTE;
+  mib[2] = 0;
+  mib[3] = AF_INET;
+  mib[4] = NET_RT_IFLIST;
+  mib[5] = 0;
+
+  if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
+    syslog(LOG_ERR, "iflist-sysctl-estimate error in getmac(): %m");
+    return(-1);
+  }     
+  if ((buf = malloc(needed)) == NULL) {
+    syslog(LOG_ERR, "malloc error in getmac(): %m");
+    return(-1);
+  }
+  if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
+    syslog(LOG_ERR, "iflist-sysctl error in getmac(): %m");                
+    return(-1);
+  }
+  lim = buf + needed;
+
+  next = buf;
+  while (next < lim) {
+
+    ifm = (struct if_msghdr *)next;
+                
+    if (ifm->ifm_type == RTM_IFINFO) {
+      sdl = (struct sockaddr_dl *)(ifm + 1);
+      flags = ifm->ifm_flags;
+    } else {
+      syslog(LOG_ERR, "out of sync parsing NET_RT_IFLIST");
+      syslog(LOG_ERR, "expected %d, got %d", RTM_IFINFO, ifm->ifm_type);
+      syslog(LOG_ERR, "msglen = %d", ifm->ifm_msglen);
+      syslog(LOG_ERR, "buf:%p, next:%p, lim:%p", buf, next, lim);
+      return (-1);
+    }
+
+    next += ifm->ifm_msglen;
+    ifam = NULL;
+    while (next < lim) {
+
+      nextifm = (struct if_msghdr *)next;
+
+      if (nextifm->ifm_type != RTM_NEWADDR)
+        break;
+
+      if (ifam == NULL)
+        ifam = (struct ifa_msghdr *)nextifm;
+
+        next += nextifm->ifm_msglen;
+    }
+
+    /* Only look at configured, broadcast interfaces */
+    if (!ALLSET(flags, IFF_UP | IFF_BROADCAST))
+      continue;
+
+    /* Only look at the specified interface */
+    if ( strlen(ifname) != sdl->sdl_nlen)
+      continue; /* not same len */
+    if (strncmp(ifname, sdl->sdl_data, sdl->sdl_nlen) != 0)
+      continue; /* not same name */
+
+    /* found */
+    bcopy(LLADDR(sdl), result, 6);
+    free(buf);
+    return(0);
+  }
+  /* not found */
+  free(buf);
+  errno = 0;
+  syslog(LOG_ERR, "getmac() failed");
+  return(-1);
+}
+#endif
 #endif
