---
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(a)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(a)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