[netcf-devel] [PATCH 1/5] Windows port of netcf api calls

Adam Stokes astokes at fedoraproject.org
Fri Sep 17 16:28:56 UTC 2010


---
 mingw32-netcf.spec.in |   67 +++++++++
 netcf-wininst.nsi     |   37 +++++
 src/netcf_win.c       |  358 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/netcf_win.h       |   70 ++++++++++
 4 files changed, 532 insertions(+), 0 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/mingw32-netcf.spec.in b/mingw32-netcf.spec.in
new file mode 100644
index 0000000..fe0e073
--- /dev/null
+++ b/mingw32-netcf.spec.in
@@ -0,0 +1,67 @@
+%global __strip %{_mingw32_strip}
+%global __objdump %{_mingw32_objdump}
+%global _use_internal_dependency_generator 0
+%global __find_requires %{_mingw32_findrequires}
+%global __find_provides %{_mingw32_findprovides}
+%define __debug_install_post %{_mingw32_debug_install_post}
+
+Name:           mingw32-netcf
+Version:        @VERSION@
+Release:        1%{?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_includedir}/*.h
+%{_mingw32_libdir}/pkgconfig/netcf.pc
+%{_mingw32_libdir}/libnetcf.dll.a
+%{_mingw32_libdir}/libnetcf.la
+%{_mingw32_datadir}
+
+%doc AUTHORS COPYING NEWS
+
+%changelog
+* Mon Sep 1 2010 Adam Stokes <ajs at redhat.com> - 0.1.6-1
+- MinGW Port
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/netcf_win.c b/src/netcf_win.c
new file mode 100644
index 0000000..f0a9818
--- /dev/null
+++ b/src/netcf_win.c
@@ -0,0 +1,358 @@
+#include <config.h>
+#include <internal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "netcf_win.h"
+
+#define ADDR_BLOCK 5
+#define GAA_FLAGS ( GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST )
+#define BUFSIZE 1024
+
+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 < ADDR_BLOCK; 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);
+}
+
+/* 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[BUFSIZE];
+	    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[BUFSIZE];
+	    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;
+
+    PIP_ADAPTER_ADDRESSES addrList = NULL;
+    PIP_ADAPTER_ADDRESSES adapterp = NULL;
+    adapterp = _get_ip_adapter_info(addrList);
+    while(adapterp != NULL) {
+	char wName[BUFSIZE];
+	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 */
+	    nif->mac = asprintf(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]);
+	    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[BUFSIZE];
+	    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[BUFSIZE];
+	    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[BUFSIZE];
+	    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..1b88772
--- /dev/null
+++ b/src/netcf_win.h
@@ -0,0 +1,70 @@
+/*
+ * netcf-win.h: windows functions
+ *
+ * Copyright (C) 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"
+
+struct netcf_if *make_netcf_if(struct netcf *ncf, char *name);
+
+/* 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 */
-- 
1.7.2.3



More information about the netcf-devel mailing list