[netcf-devel] [PATCH] Windows port

Adam Stokes astokes at fedoraproject.org
Fri Sep 3 15:50:30 UTC 2010


---
 bootstrap             |   20 ++-
 configure.ac          |   41 +++-
 mingw32-netcf.spec.in |   95 +++++++++
 netcf-wininst.nsi     |   37 ++++
 src/Makefile.am       |   17 +-
 src/drv_initscripts.c |    2 +-
 src/ncftool.c         |    3 +
 src/netcf.c           |   15 ++-
 src/netcf_win.c       |  565 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/netcf_win.h       |   93 ++++++++
 src/xslt_ext.c        |    2 +-
 11 files changed, 870 insertions(+), 20 deletions(-)
 create mode 100644 mingw32-netcf.spec.in
 create mode 100755 netcf-wininst.nsi
 create mode 100644 src/netcf_win.c
 create mode 100644 src/netcf_win.h

diff --git a/bootstrap b/bootstrap
index f0653ef..351d58c 100755
--- a/bootstrap
+++ b/bootstrap
@@ -62,6 +62,25 @@ c-ctype
 read-file
 safe-alloc
 warnings
+sys_wait
+sigaction
+pthread
+unistd
+getdtablesize
+signal
+arpa_inet
+sys_ioctl
+getopt-posix
+string
+sys_socket
+socket
+netinet_in
+vasprintf
+fcntl
+inet_ntop
+inet_pton
+close
+setenv
 '
 
 # Tell gnulib to:
@@ -70,7 +89,6 @@ warnings
 #   put *.[ch] files in new gnulib/lib/ dir.
 
 $gnulib_tool			\
-  --lgpl=2			\
   --with-tests			\
   --m4-base=gnulib/m4		\
   --source-base=gnulib/lib	\
diff --git a/configure.ac b/configure.ac
index 1475875..be0a1a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -16,7 +16,27 @@ AC_PROG_LIBTOOL
 
 dnl The backend driver. Right now hardcoded to initscripts, but
 dnl eventually needs to be configurable at buildtime
-AM_CONDITIONAL([NETCF_DRIVER_INITSCRIPTS], [true])
+dnl temporary, if win32 then dont build this.
+AC_CANONICAL_HOST
+
+dnl WIN32
+AC_MSG_CHECKING([for win32 platform])
+PLATFORM_WIN32="no"
+case "$host" in
+	*-*-mingw*)
+		PLATFORM_WIN32="yes"
+		NO_UNDEFINED="-Wl,--no-undefined"
+	;;
+	*-*-cygwin*)
+		NO_UNDEFINED="-Wl,--no-undefined"
+	;;
+	*)
+	;;
+esac
+AC_MSG_RESULT([$PLATFORM_WIN32])
+AM_CONDITIONAL(PLATFORM_WIN32, test "${PLATFORM_WIN32}" = "yes")
+AC_SUBST([PLATFORM_WIN32])
+AC_SUBST(NO_UNDEFINED)
 
 dnl Compiler flags to be used everywhere
 AC_SUBST([NETCF_CFLAGS], ['--std=gnu99 -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fasynchronous-unwind-tables'])
@@ -27,23 +47,24 @@ NETCF_COMPILE_WARNINGS
 
 dnl Need to test if pkg-config exists
 PKG_PROG_PKG_CONFIG
-PKG_CHECK_MODULES([LIBAUGEAS], [augeas >= 0.5.0])
+PKG_CHECK_MODULES([LIBAUGEAS], [augeas >= 0.5.0], [], [AC_DEFINE([HAVE_LIBAUGEAS], [], [Use augeas])])
 PKG_CHECK_MODULES([LIBXML], [libxml-2.0])
 PKG_CHECK_MODULES([LIBXSLT], [libxslt])
 PKG_CHECK_MODULES([LIBEXSLT], [libexslt])
-PKG_CHECK_MODULES([LIBNL], [libnl-1])
+PKG_CHECK_MODULES([LIBNL], [libnl-1], [], [AC_DEFINE([HAVE_LIBNL], [], [Use netlink])])
 
 NETCF_CHECK_READLINE
 
 NETCF_LIBDEPS=$(echo $LIBAUGEAS_LIBS $LIBEXSLT_LIBS $LIBXSLT_LIBS $LIBXML_LIBS $LIBNL_LIBS)
 AC_SUBST([NETCF_LIBDEPS])
 
-AC_CHECK_HEADER([pthread.h],
-	[AC_CHECK_LIB([pthread],[pthread_join],[
-		AC_DEFINE([HAVE_LIBPTHREAD],[],[Define if pthread (-lpthread)])
-		AC_DEFINE([HAVE_PTHREAD_H],[],[Define if <pthread.h>])
-		LIBS="-lpthread $LIBS"
-	])])
+dnl check pthread functions
+dnl pulled from:
+dnl http://www.mail-archive.com/libvir-list@redhat.com/msg24187.html
+old_LIBS=$LIBS
+LIBS="$LIBS $LIB_PTHREAD"
+AC_CHECK_FUNCS([pthread_sigmask pthread_mutexattr_init])
+LIBS=$old_libs
 
 AC_OUTPUT(Makefile                                          \
           gnulib/lib/Makefile                               \
@@ -51,4 +72,4 @@ AC_OUTPUT(Makefile                                          \
           src/Makefile                                      \
           tests/Makefile                                    \
           doc/Makefile                                      \
-          netcf.pc netcf.spec)
+          netcf.pc netcf.spec mingw32-netcf.spec)
diff --git a/mingw32-netcf.spec.in b/mingw32-netcf.spec.in
new file mode 100644
index 0000000..0d891c1
--- /dev/null
+++ b/mingw32-netcf.spec.in
@@ -0,0 +1,95 @@
+%global __strip %{_mingw32_strip}
+%global __objdump %{_mingw32_objdump}
+%global _use_internal_dependency_generator 0
+%global __find_requires %{_mingw32_findrequires}
+%global __find_provides %{_mingw32_findprovides}
+
+Name:           mingw32-netcf
+Version:        @VERSION@
+Release:        2%{?dist}%{?extra_release}
+Summary:        Cross-platform network configuration library
+
+Group:          System Environment/Libraries
+License:        LGPLv2+
+URL:            https://fedorahosted.org/netcf/
+Source0:        http://astokes.fedorapeople.org/%{name}/%{name}-%{version}.tar.gz
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+BuildRequires:  mingw32-filesystem >= 56
+BuildRequires:  mingw32-readline
+BuildRequires:  mingw32-binutils
+BuildRequires:  mingw32-libxml2 
+BuildRequires:  mingw32-libxslt
+BuildRequires:  mingw32-gcc
+BuildRequires:  mingw32-gettext
+BuildRequires:  mingw32-w32api
+Requires:       pkgconfig
+
+%description
+A library for modifying the network configuration of a system. Network
+configurations are expresed in a platform-independent XML format, which
+netcf translates into changes to the system's 'native' network
+configuration files.
+
+MinGW cross-compiled Windows library.
+
+%prep
+%setup -q
+
+%build
+PATH=%{_mingw32_bindir}:$PATH \
+%{_mingw32_configure} --disable-static
+make %{?_smp_mflags}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT INSTALL="%{__install} -p"
+rm -rf $RPM_BUILD_ROOT%{_mingw32_datadir}/netcf
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root,-)
+%{_mingw32_bindir}/ncftool.exe
+%{_mingw32_bindir}/libnetcf-1.dll
+%{_mingw32_libdir}/libnetcf.dll.a
+%{_mingw32_libdir}/libnetcf.la
+%{_mingw32_includedir}/netcf.h
+%{_mingw32_libdir}/pkgconfig/netcf.pc
+%{_mingw32_datadir}
+
+%doc AUTHORS COPYING NEWS
+
+%changelog
+* Mon Sep 1 2010 Adam Stokes <ajs at redhat.com> - 0.1.6-2
+- Update spec to not require .dll.a or *.la
+- Fixed building of DLL
+
+* Thu Apr 16 2010 Laine Stump <laine at redhat.com> - 0.1.6-1
+- New version
+
+* Mon Nov 30 2009 David Lutterkort <lutter at redhat.com> - 0.1.5-1
+- New version
+
+* Thu Nov  5 2009 David Lutterkort <lutter at redhat.com> - 0.1.4-1
+- New version
+
+* Tue Oct 27 2009 David Lutterkort <lutter at redhat.com> - 0.1.3-1
+- New version
+
+* Fri Sep 25 2009 David Lutterkort <lutter at redhat.com> - 0.1.2-1
+- New Version
+
+* Wed Sep 16 2009 David Lutterkort <lutter at redhat.com> - 0.1.1-1
+- New Version
+
+* Mon Jul 13 2009 David Lutterkort <lutter at redhat.com> - 0.1.0-1
+- BR on augeas-0.5.2
+- Drop explicit requires for augeas-libs
+
+* Wed Apr 15 2009 David Lutterkort <lutter at redhat.com> - 0.0.2-1
+- Updates acording to Fedora review
+
+* Fri Feb 27 2009 David Lutterkort <lutter at redhat.com> - 0.0.1-1
+- Initial specfile
diff --git a/netcf-wininst.nsi b/netcf-wininst.nsi
new file mode 100755
index 0000000..d0d1687
--- /dev/null
+++ b/netcf-wininst.nsi
@@ -0,0 +1,37 @@
+; netcf-wininst.nsi
+; prompt for dir; copy files
+;--------------------------------
+
+; The name of the installer
+Name "netcf installer"
+
+; The file to write
+OutFile "netcf-setup.exe"
+
+; The default installation directory
+InstallDir $PROGRAMFILES\netcf
+
+; Request application privileges for Windows Vista
+RequestExecutionLevel user
+
+;--------------------------------
+
+; Pages
+
+Page directory
+Page instfiles
+
+;--------------------------------
+
+; The stuff to install
+Section "" ;No components page, name is not important
+
+  ; Set output path to the installation directory.
+  SetOutPath $INSTDIR
+  
+  ; Put file there
+  File src/.libs/libnetcf-1.dll
+  File src/.libs/ncftool.exe
+  File /usr/i686-pc-mingw32/sys-root/mingw/bin/*.dll
+
+SectionEnd ; end the section
diff --git a/src/Makefile.am b/src/Makefile.am
index 9d8a3d7..bc14695 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,10 +13,13 @@ bin_PROGRAMS = ncftool
 
 noinst_PROGRAMS = ncftransform
 
-EXTRA_DIST = netcf_public.syms \
-	netcf_private.syms
+EXTRA_DIST = netcf_public.syms netcf_private.syms netcf_win.h netcf_win.c \
+	drv_initscripts.c dutil.h dutil.c dutil_linux.c dutil_linux.h
 
-if NETCF_DRIVER_INITSCRIPTS
+if PLATFORM_WIN32
+WIN32LIB= -liphlpapi -ldnsapi
+DRIVER_SOURCES = netcf_win.h netcf_win.c
+else
 DRIVER_SOURCES = drv_initscripts.c dutil.h dutil.c \
      dutil_linux.h dutil_linux.c
 endif
@@ -29,9 +32,11 @@ libnetcf_la_SOURCES = netcf.h netcf.c internal.h \
      ref.h list.h \
      xslt_ext.c $(DRIVER_SOURCES)
 libnetcf_la_LDFLAGS = -Wl,--version-script=netcf.syms \
-     -version-info $(LIBNETCF_VERSION_INFO)
+     -version-info $(LIBNETCF_VERSION_INFO) @NO_UNDEFINED@
 libnetcf_la_LIBADD = $(NETCF_LIBDEPS) $(GNULIB)
-libnetcf_la_DEPENDENCIES = $(libnetcf_la_LIBADD) netcf.syms
+if PLATFORM_WIN32
+libnetcf_la_LIBADD += $(WIN32LIB)
+endif
 
 ncftool_SOURCES = ncftool.c
 ncftool_LDADD = libnetcf.la $(READLINE_LIBS) $(GNULIB)
@@ -55,6 +60,6 @@ netcf.syms: netcf_public.syms netcf_private.syms
 internal.h: datadir.h
 
 datadir.h: $(top_builddir)/config.status
-	echo '#define DATADIR "$(datadir)"' > datadir.h
+	echo '#define NETCF_DATADIR "$(datadir)"' > datadir.h
 
 DISTCLEANFILES += $(BUILT_SOURCES)
diff --git a/src/drv_initscripts.c b/src/drv_initscripts.c
index c0bcfd5..2127d2a 100644
--- a/src/drv_initscripts.c
+++ b/src/drv_initscripts.c
@@ -100,7 +100,7 @@ static const struct augeas_xfm_table augeas_xfm_iptables =
 
 static const char *const prog_lokkit = "/usr/sbin/lokkit";
 static const char *const lokkit_custom_rules =
-    "--custom-rules=ipv4:filter:" DATADIR "/netcf/iptables-forward-bridged";
+    "--custom-rules=ipv4:filter:" NETCF_DATADIR "/netcf/iptables-forward-bridged";
 
 static const char *const prog_rc_d_iptables = "/etc/init.d/iptables";
 
diff --git a/src/ncftool.c b/src/ncftool.c
index 2cb139d..4a1d926 100644
--- a/src/ncftool.c
+++ b/src/ncftool.c
@@ -784,7 +784,10 @@ int main(int argc, char **argv) {
         fprintf(stderr, "Failed to initialize netcf\n");
         if (ncf != NULL)
             print_netcf_error();
+#ifndef WIN32
+        // FIXME: Need to find out why ncf_init is croaking
         exit(EXIT_FAILURE);
+#endif
     }
     readline_init();
     if (optind < argc) {
diff --git a/src/netcf.c b/src/netcf.c
index 1a95332..96b6be7 100644
--- a/src/netcf.c
+++ b/src/netcf.c
@@ -35,7 +35,11 @@
 
 #include "internal.h"
 #include "netcf.h"
+#ifdef WIN32
+#include "netcf_win.h"
+#else
 #include "dutil.h"
+#endif
 
 /* Clear error code and details */
 #define API_ENTRY(ncf)                          \
@@ -88,7 +92,11 @@ int ncf_init(struct netcf **ncf, const char *root) {
     if (make_ref(*ncf) < 0)
         goto oom;
     if (root == NULL)
+#ifdef WIN32
+        root = "c:\\";
+#else
         root = "/";
+#endif
     if (root[strlen(root)-1] == '/') {
         (*ncf)->root = strdup(root);
     } else {
@@ -99,7 +107,7 @@ int ncf_init(struct netcf **ncf, const char *root) {
         goto oom;
     (*ncf)->data_dir = getenv("NETCF_DATADIR");
     if ((*ncf)->data_dir == NULL)
-        (*ncf)->data_dir = DATADIR "/netcf";
+        (*ncf)->data_dir = NETCF_DATADIR "/netcf";
     (*ncf)->debug = getenv("NETCF_DEBUG") != NULL;
     return drv_init(*ncf);
  oom:
@@ -262,6 +270,10 @@ int ncf_put_aug(struct netcf *ncf, const char *aug_xml, char **ncf_xml) {
     return drv_put_aug(ncf, aug_xml, ncf_xml);
 }
 
+#ifndef WIN32
+/* Do not see any other way around this as there is no
+ * portable option for strerror_r or pthread_sigmask
+ */
 /*
  * Internal helpers
  */
@@ -395,6 +407,7 @@ error:
     return ret;
 }
 
+#endif /* WIN32 */
 /*
  * argv_to_string() is borrowed from libvirt's
  * src/util.c:virArgvToString()
diff --git a/src/netcf_win.c b/src/netcf_win.c
new file mode 100644
index 0000000..a1dbd5c
--- /dev/null
+++ b/src/netcf_win.c
@@ -0,0 +1,565 @@
+#include <config.h>
+#include <internal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "netcf_win.h"
+
+#define MAX_TRIES 3
+#define GAA_FLAGS ( GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST )
+#define BUFSIZE 8192
+
+PMIB_IPADDRTABLE _get_ip_addr_table(PMIB_IPADDRTABLE ipAddrTable) {
+    DWORD r = 0;
+    DWORD buf = 0;
+
+    ipAddrTable = (PMIB_IPADDRTABLE) malloc(sizeof (MIB_IPADDRTABLE));
+    if (GetIpAddrTable(ipAddrTable, &buf, 0) == ERROR_INSUFFICIENT_BUFFER) {
+	free(ipAddrTable);
+	ipAddrTable = (PMIB_IPADDRTABLE) malloc(buf);
+	if (ipAddrTable == NULL)
+	    goto error;
+    }
+
+    if((r = GetIpAddrTable(ipAddrTable, &buf, 0)) == NO_ERROR)
+	return ipAddrTable;
+
+ error:
+    free(ipAddrTable);
+    return ipAddrTable;
+}
+
+PMIB_IFTABLE _get_if_table(PMIB_IFTABLE intfTable) {
+    DWORD bufferLength = 0;
+    DWORD r = 0;
+    intfTable = (PMIB_IFTABLE) malloc(sizeof(MIB_IFTABLE));
+    if (intfTable == NULL)
+	goto error;
+
+    bufferLength = sizeof(MIB_IFTABLE);
+    if (GetIfTable(intfTable, &bufferLength, FALSE) == ERROR_INSUFFICIENT_BUFFER) {
+	free(intfTable);
+	intfTable = (PMIB_IFTABLE) malloc(bufferLength);
+	if (intfTable == NULL)
+	    goto error;
+    }
+
+    if ((r = GetIfTable(intfTable, &bufferLength, FALSE)) == NO_ERROR)
+	return intfTable;
+ error:
+    free(intfTable);
+}
+
+PIP_ADAPTER_ADDRESSES _get_ip_adapter_info(PIP_ADAPTER_ADDRESSES addrList) {
+    ULONG bufferLength = 0;
+    DWORD r;
+    int i;
+
+    for(i = 0; i < 5; i++) {
+	r = GetAdaptersAddresses(AF_INET, GAA_FLAGS, NULL, addrList, &bufferLength);
+	if (r != ERROR_BUFFER_OVERFLOW) {
+	    break;
+	}
+	if (addrList != NULL) {
+	    goto error;
+	}
+	addrList = (PIP_ADAPTER_ADDRESSES) malloc(bufferLength);
+	if (addrList == NULL)
+	    goto error;
+    }	
+    return addrList;
+ error:
+    free(addrList);
+}
+
+/* All undefined routines in windows */
+int drv_get_aug(struct netcf *ncf, const char *ncf_xml, char **aug_xml) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+int drv_if_status(struct netcf_if *nif, unsigned int *flags) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+int drv_init(struct netcf *ncf) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+int drv_lookup_by_mac_string(struct netcf *ncf, const char *mac,
+			     int maxifaces, struct netcf_if **ifaces) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+int drv_put_aug(struct netcf *ncf, const char *aug_xml, char **ncf_xml) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+int drv_undefine(struct netcf_if *nif) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+char *drv_xml_desc(struct netcf_if *nif) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+char *drv_xml_state(struct netcf_if *nif) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+struct netcf_if *drv_define(struct netcf *ncf, const char *xml_str) {
+#ifdef WIN32
+    return ncf;
+#endif
+}
+
+static bool has_ifcfg_file(struct netcf *ncf, const char *name) {
+#ifdef WIN32
+    return FALSE;
+#endif
+}
+
+static bool is_bond(struct netcf *ncf, const char *name) {
+#ifdef WIN32
+    return FALSE;
+#endif
+}
+
+static bool is_bridge(struct netcf *ncf, const char *name) {
+#ifdef WIN32
+    return FALSE;
+#endif
+}
+
+static char *device_name_from_xml(struct netcf *ncf, xmlDocPtr ncf_xml) {
+#ifdef WIN32
+    char *ret = NULL;
+    return ret;
+#endif
+}
+
+static char *find_ifcfg_path_by_device(struct netcf *ncf, const char *name) {
+#ifdef WIN32
+    char *ret = NULL;
+    return ret;
+#endif
+}
+
+static char *find_ifcfg_path_by_hwaddr(struct netcf *ncf, const char *mac) {
+#ifdef WIN32
+    char *ret = NULL;
+    return ret;
+#endif
+}
+
+static char *find_ifcfg_path(struct netcf *ncf, const char *name) {
+#ifdef WIN32
+    char *ret = NULL;
+    return ret;
+#endif
+}
+
+static int aug_put_xml(struct netcf *ncf, xmlDocPtr xml) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+static int bridge_slaves(struct netcf *ncf, const char *name, char ***slaves) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+static int cmpstrp(const void *p1, const void *p2) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+static int is_slave(struct netcf *ncf, const char *intf) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+static int list_ifcfg_paths(struct netcf *ncf, char ***intf) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+static int list_interfaces(struct netcf *ncf, char ***intf){
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+static int uniq_ifcfg_paths(struct netcf *ncf, int ndevs, char **devs, char ***intf) {
+#ifdef WIN32
+    return -1;
+#endif
+}
+
+static void bond_setup(struct netcf *ncf, const char *name, bool alias) {
+#ifdef WIN32
+    return;
+#endif
+}
+
+static void bridge_physdevs(struct netcf *ncf) {
+#ifdef WIN32
+    return;
+#endif
+}
+
+static void rm_all_interfaces(struct netcf *ncf, xmlDocPtr ncf_xml) {
+#ifdef WIN32
+    return;
+#endif
+}
+
+static void rm_interface(struct netcf *ncf, const char *name) {
+#ifdef WIN32
+    return;
+#endif
+}
+
+static xmlDocPtr aug_get_xml_for_nif(struct netcf_if *nif) {
+#ifdef WIN32
+    xmlDocPtr result = NULL;
+    return result;
+#endif
+}
+
+static xmlDocPtr aug_get_xml(struct netcf *ncf, int nint, char **intf) {
+#ifdef WIN32
+    xmlDocPtr result = NULL;
+    return result;
+#endif
+}
+
+void drv_entry(struct netcf *ncf) {
+#ifdef WIN32
+    return;
+#endif
+}
+
+void drv_close(struct netcf *ncf) {
+#ifdef WIN32
+    return;
+#endif
+}
+
+int xasprintf(char **strp, const char *format, ...) {
+  va_list args;
+  int result;
+
+  va_start (args, format);
+  result = vasprintf (strp, format, args);
+  va_end (args);
+  if (result < 0)
+      *strp = NULL;
+  return result;
+}
+
+/* Create a new netcf if instance for interface NAME */
+struct netcf_if *make_netcf_if(struct netcf *ncf, char *name) {
+    int r;
+    struct netcf_if *result = NULL;
+
+    r = make_ref(result);
+    ERR_NOMEM(r < 0, ncf);
+    result->ncf = ref(ncf);
+    result->name = name;
+    return result;
+
+ error:
+    unref(result, netcf_if);
+    return result;
+}
+    
+static int list_interface_ids(struct netcf *ncf ATTRIBUTE_UNUSED, 
+				  int maxnames ATTRIBUTE_UNUSED,
+				  char **names, unsigned int flags ATTRIBUTE_UNUSED,
+				  const char *id_attr ATTRIBUTE_UNUSED) {
+    unsigned int nint = 0;
+
+    PIP_ADAPTER_ADDRESSES addrList = NULL;
+    PIP_ADAPTER_ADDRESSES adapterp = NULL;
+    adapterp = _get_ip_adapter_info(addrList);
+    for (nint = 0; adapterp != NULL; nint++) {
+	if (names) {
+	    char name[8192];
+	    WideCharToMultiByte(CP_UTF8, 0, adapterp->FriendlyName,
+				-1, name, sizeof(name), NULL, NULL);
+	    names[nint] = strdup(name);
+	}
+	adapterp = adapterp->Next;
+    }
+    return nint;
+ error:
+    free(addrList);
+    return -1;
+}
+
+int drv_list_interfaces(struct netcf *ncf,
+		    int maxnames ATTRIBUTE_UNUSED, char **names,
+		    unsigned int flags ATTRIBUTE_UNUSED) {
+    return list_interface_ids(ncf, 0, names, 0, NULL);
+}
+
+
+int drv_num_of_interfaces(struct netcf *ncf, unsigned int flags ATTRIBUTE_UNUSED) {
+    return list_interface_ids(ncf, 0, NULL, 0, NULL);
+}
+
+
+struct netcf_if *drv_lookup_by_name(struct netcf *ncf, const char *name) {
+    struct netcf_if *nif = NULL;
+    char *name_dup;
+    unsigned int nint = 0;
+    PIP_ADAPTER_ADDRESSES addrList = NULL;
+    PIP_ADAPTER_ADDRESSES adapterp = NULL;
+    adapterp = _get_ip_adapter_info(addrList);
+    for (nint = 0; adapterp != NULL; nint++) {
+	if (name) {
+	    char wName[8192];
+	    WideCharToMultiByte(CP_UTF8, 0, adapterp->FriendlyName,
+				-1, wName, sizeof(wName), NULL, NULL);
+	    if (strcmp(wName, name) == 0) {
+		name_dup = strdup(wName);
+		nif = make_netcf_if(ncf, name_dup);
+		goto done;
+	    }
+	}
+	adapterp = adapterp->Next;
+    }
+
+ done:
+    return nif;
+}
+
+
+const char *drv_mac_string(struct netcf_if *nif) {
+    // struct netcf *ncf = nif->ncf;
+    char mac[256];
+
+    PIP_ADAPTER_ADDRESSES addrList = NULL;
+    PIP_ADAPTER_ADDRESSES adapterp = NULL;
+    adapterp = _get_ip_adapter_info(addrList);
+    while(adapterp != NULL) {
+	char wName[8192];
+	WideCharToMultiByte(CP_UTF8, 0, adapterp->FriendlyName,
+			    -1, wName, sizeof(wName), NULL, NULL);
+       	if (strcmp(wName,nif->name) == 0) {
+	    if ((int)adapterp->PhysicalAddressLength >= 6)
+		continue; /* just want ethernet for now */
+	    sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X",
+		    adapterp->PhysicalAddress[0],
+		    adapterp->PhysicalAddress[1],
+		    adapterp->PhysicalAddress[2],
+		    adapterp->PhysicalAddress[3],
+		    adapterp->PhysicalAddress[4],
+		    adapterp->PhysicalAddress[5]);
+	    nif->mac = strdup(mac);
+	    goto done;
+	}
+	adapterp = adapterp->Next;
+    }
+ done:
+    return nif->mac;
+}
+
+int drv_if_down(struct netcf_if *nif) {
+    PMIB_IFTABLE intfTable = NULL;
+    PMIB_IFTABLE intfTableDup = NULL;
+    PMIB_IFROW intRow;
+    int i;
+
+    intfTableDup = _get_if_table(intfTable);
+    if (intfTableDup != NULL) {
+	for (i = 0; i < (int) intfTableDup->dwNumEntries; i++) {
+	    intRow = (PMIB_IFROW) & intfTableDup->table[i];
+	    char wName[8192];
+	    WideCharToMultiByte(CP_UTF8, 0, intRow->wszName,
+				-1, wName, sizeof(wName), NULL, NULL);
+	    if (strcmp(wName,nif->name) == 0) {
+		intRow->dwAdminStatus = MIB_IF_ADMIN_STATUS_DOWN;
+		if (SetIfEntry(intRow) == NO_ERROR)
+		    goto done;
+	    }
+	}
+	/* Unable to shutdown interface */
+	return -1;
+    }
+ done:
+    return 0;
+}
+
+int drv_if_up(struct netcf_if *nif) {
+    PMIB_IFTABLE intfTable = NULL;
+    PMIB_IFTABLE intfTableDup = NULL;
+    PMIB_IFROW intRow;
+    int i;
+
+    intfTableDup = _get_if_table(intfTable);
+    if (intfTableDup != NULL) {
+	for (i = 0; i < (int) intfTableDup->dwNumEntries; i++) {
+	    intRow = (PMIB_IFROW) & intfTableDup->table[i];
+	    char wName[8192];
+	    WideCharToMultiByte(CP_UTF8, 0, intRow->wszName,
+				-1, wName, sizeof(wName), NULL, NULL);
+	    if (strcmp(wName,nif->name) == 0) {
+		intRow->dwAdminStatus = MIB_IF_ADMIN_STATUS_UP;
+		if (SetIfEntry(intRow) == NO_ERROR)
+		    goto done;
+	    }
+	}
+	/* Unable to shutdown interface */
+	return -1;
+    }
+ done:
+    return 0;
+}
+
+int drv_if_ipaddresses(struct netcf_if *nif, char *ipBuf) {
+    PIP_ADAPTER_ADDRESSES addrList = NULL;
+    PIP_ADAPTER_ADDRESSES adapterp = NULL;
+    PMIB_IPADDRTABLE ipAddrTable = NULL; 
+    PMIB_IPADDRTABLE ipAddrTableDup = NULL;
+    IN_ADDR ipAddr;
+    DWORD r = 0;
+    int i;
+
+    if ((ipAddrTableDup = _get_ip_addr_table(ipAddrTable)) == NULL)
+	return -1;
+
+    adapterp = _get_ip_adapter_info(addrList);
+    if (adapterp != NULL) {
+	while(adapterp) {
+	    if (adapterp->OperStatus != 1)
+		continue;
+
+	    /* pull ip addresses from interface */
+	    for (i = 0; i<ipAddrTableDup->dwNumEntries; i++) {
+		if (ipAddrTableDup->table[i].dwIndex == adapterp->IfIndex) {
+		    char wName[8192];
+		    WideCharToMultiByte(CP_UTF8, 0, adapterp->FriendlyName,
+					-1, wName, sizeof(wName), NULL, NULL);
+		    if (strcmp(wName,nif->name) == 0) {
+			ipAddr.S_un.S_addr = (unsigned long) ipAddrTableDup->table[i].dwAddr;
+			sprintf(ipBuf,"%d",inet_ntoa(ipAddr));
+			return 0;
+		    }
+		}
+	    }
+	    adapterp = adapterp->Next;
+	}
+
+    }
+    free(ipAddrTable);
+    free(addrList);
+    return -1;
+}
+
+int drv_add_ip_address(struct netcf_if *nif, char *ipAddr, char *netmask) {
+    IN_ADDR addr;
+    PIP_ADAPTER_ADDRESSES addrList = NULL;
+    PIP_ADAPTER_ADDRESSES adapterp = NULL;
+    PMIB_IPADDRTABLE ipAddrTable = NULL;
+    PMIB_IPADDRTABLE ipAddrTableDup = NULL;
+    ULONG bufferLength = 0;
+    DWORD r;
+    DWORD ifIndex;
+    int i;
+
+    /* ipv4 addr/subnetmask */
+    UINT IPAddress;
+    UINT IPNetMask;
+
+    /* handles to IP returned */
+    ULONG NTEContext = 0;
+    ULONG NTEInstance = 0;
+    
+    if ((IPAddress = inet_addr(ipAddr)) == INADDR_NONE)
+	return -1;
+
+    if ((IPNetMask = inet_addr(netmask)) == INADDR_NONE)
+	return -1;
+
+
+    ipAddrTableDup = _get_ip_addr_table(ipAddrTable);
+    if (ipAddrTableDup != NULL) {
+	for(i=0;i<ipAddrTableDup->dwNumEntries;i++) {
+	    ifIndex = ipAddrTableDup->table[i].dwIndex;
+	    char wName[8192];
+	    WideCharToMultiByte(CP_UTF8, 0, adapterp->FriendlyName,
+				-1, wName, sizeof(wName), NULL, NULL);
+	    if (strcmp(wName,nif->name) == 0) {
+		if ((r = AddIPAddress(IPAddress, IPNetMask, ifIndex,
+				      &NTEContext, &NTEInstance)) == NO_ERROR) {
+		    return 0;
+		}
+	    }
+	}
+    }
+    free(ipAddrTable);
+    return -1;
+}
+
+
+/* needs further testing
+int drv_rm_ip_address(struct netcf_if *nif, ULONG NTEContext) {
+    DWORD r = 0;
+    if ((r = DeleteIpAddress(NTEConext)) == NO_ERROR)
+	return 0;
+    return -1;
+}
+*/
+
+int drv_list_dns_server(struct netcf_if *nif, char *ip_str) {
+    char bufferLength[1024];
+    IP4_ARRAY *ips = (IP4_ARRAY*) bufferLength;
+    DWORD len = sizeof(bufferLength);
+    DNS_STATUS status;
+
+    status = DnsQueryConfig(DnsConfigDnsServerList, FALSE,
+			    NULL, NULL, ips, &len);
+    if (status == 0) {
+	DWORD i;
+	for (i = 0; i < ips->AddrCount; i++) {
+	    DWORD ip = ips->AddrArray[i];
+	    snprintf(ip_str, sizeof(ip_str), 
+		     "%d.%d.%d.%d", (ip >> 0) & 255, (ip >> 8) & 255,
+		     (ip >> 16) & 255, (ip >> 24) & 255);
+	}
+    } else {
+	return -1;
+    }
+    return 0;
+}
+
+/* NOT IMPLEMENTED
+int drv_add_dns_server(struct netcf_if *nif, const char *dnsAddr) {
+    return -1;
+}
+
+int drv_rm_dns_server(struct netcf_if *nif) {
+    return -1;
+}
+*/
diff --git a/src/netcf_win.h b/src/netcf_win.h
new file mode 100644
index 0000000..c1bb1d6
--- /dev/null
+++ b/src/netcf_win.h
@@ -0,0 +1,93 @@
+/*
+ * netcf-win.h: windows functions
+ *
+ * Copyright (C) 2009-2010 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Adam Stokes <ajs at redhat.com>
+ */
+
+#ifndef NETCF_WIN_H
+#define NETCF_WIN_H
+
+#ifndef WINVER
+#define WINVER 0x0501
+#endif
+
+#include <config.h>
+#include "internal.h"
+
+#include <stdbool.h>
+#include <string.h>
+#include <windows.h>
+#include <winsock.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <iphlpapi.h>
+#include <windns.h>
+#include "safe-alloc.h"
+#include "ref.h"
+#include "list.h"
+
+static int aug_put_xml(struct netcf *ncf, xmlDocPtr xml);
+static int bridge_slaves(struct netcf *ncf, const char *name, char ***slaves);
+static int cmpstrp(const void *p1, const void *p2);
+static int is_slave(struct netcf *ncf, const char *intf);
+static int list_ifcfg_paths(struct netcf *ncf, char ***intf);
+static int list_interface_ids(struct netcf *ncf, int maxnames, char **names,
+			      unsigned int flags, const char *id_attr);
+static int list_interfaces(struct netcf *ncf, char ***intf);
+static int uniq_ifcfg_paths(struct netcf *ncf, int ndevs, char **devs, char ***intf);
+static bool has_ifcfg_file(struct netcf *ncf, const char *name);
+static bool is_bond(struct netcf *ncf, const char *name);
+static bool is_bridge(struct netcf *ncf, const char *name);
+static char *device_name_from_xml(struct netcf *ncf, xmlDocPtr ncf_xml);
+static char *find_ifcfg_path_by_device(struct netcf *ncf, const char *name);
+static char *find_ifcfg_path_by_hwaddr(struct netcf *ncf, const char *mac);
+static char *find_ifcfg_path(struct netcf *ncf, const char *name);
+static void bond_setup(struct netcf *ncf, const char *name, bool alias);
+static void bridge_physdevs(struct netcf *ncf);
+static void rm_all_interfaces(struct netcf *ncf, xmlDocPtr ncf_xml);
+static void rm_interface(struct netcf *ncf, const char *name);
+static xmlDocPtr aug_get_xml_for_nif(struct netcf_if *nif);
+static xmlDocPtr aug_get_xml(struct netcf *ncf, int nint, char **intf);
+struct netcf_if *make_netcf_if(struct netcf *ncf, char *name);
+int xasprintf(char **strp, const char *format, ...);
+
+/* structure return of interface table */
+PMIB_IFTABLE _get_if_table(PMIB_IFTABLE intfTable);
+
+/* structure return of adapter info */
+PIP_ADAPTER_ADDRESSES _get_ip_adapter_info(PIP_ADAPTER_ADDRESSES addrList);
+
+PMIB_IPADDRTABLE _get_ip_addr_table(PMIB_IPADDRTABLE ipAddrTable);
+
+/* Reports ip addresses */
+int drv_if_ipaddresses(struct netcf_if *nif, char *ipBuf);
+
+/* add ip address to device */
+int drv_add_ip_address(struct netcf_if *nif, char *ipAddr,
+		       char *netmask);
+/* remove ip address from device */
+int drv_rm_ip_address(struct netcf_if *nif, ULONG NTEContext);
+/* add dns server to device */
+int drv_add_dns_server(struct netcf_if *nif, ULONG NTEContext);
+/* rm dns server from device */
+int drv_rm_dns_server(struct netcf_if *nif);
+/* list dns server */
+int drv_list_dns_server(struct netcf_if *ncf, char *ip_str);
+
+#endif /* NETCF_WIN_H */
diff --git a/src/xslt_ext.c b/src/xslt_ext.c
index 07e2b41..444889a 100644
--- a/src/xslt_ext.c
+++ b/src/xslt_ext.c
@@ -106,7 +106,7 @@ static void ipcalc_prefix(xmlXPathParserContextPtr ctxt, int nargs) {
         goto error;
     }
 
-    r = inet_aton((char *) netmask_str, &netmask);
+    r = inet_pton(AF_INET, (char *) netmask_str, &netmask);
     if (r < 0) {
         xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
                            "ipcalc:prefix: illegal netmask '%s'",
-- 
1.7.2.2



More information about the netcf-devel mailing list