Last active
August 15, 2016 09:02
-
-
Save gvanem/2a0915e13f208fd150b8 to your computer and use it in GitHub Desktop.
Modified libdnet + Nmap route-win32.c file for those MinGW-distros which doesn't have <NetioApi.h>. Also uses some IpHlpAPI functions dynamically to better support Win-XP. The .diff at bottom.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * route-win32.c | |
| * | |
| * Copyright (c) 2002 Dug Song <dugsong@monkey.org> | |
| * | |
| * $Id: route-win32.c 589 2005-02-15 07:11:32Z dugsong $ | |
| */ | |
| #ifdef _WIN32 | |
| #include "dnet_winconfig.h" | |
| #else | |
| #include "config.h" | |
| #endif | |
| #include <ws2tcpip.h> | |
| #include <iphlpapi.h> | |
| #include <errno.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include "dnet.h" | |
| #if defined(_MSC_VER) && 0 && (_WIN32_WINNT >= 0x0600) /* 0x0600 == _WIN32_WINNT_VISTA */ | |
| #include <netioapi.h> | |
| #define HAVE_NETIOAPI_H | |
| typedef DWORD (WINAPI *GETIPFORWARDTABLE2)(ADDRESS_FAMILY, PMIB_IPFORWARD_TABLE2 *); | |
| #else | |
| typedef DWORD (WINAPI *GETIPFORWARDTABLE2)(void *, void *); | |
| #endif | |
| typedef VOID (WINAPI *FREEMIBTABLE) (void *); | |
| struct route_handle { /* the implementation details of 'route_t' in <dnet.h> */ | |
| HINSTANCE iphlpapi; | |
| GETIPFORWARDTABLE2 p_GetIpForwardTable2; | |
| FREEMIBTABLE p_FreeMibTable; | |
| MIB_IPFORWARDTABLE *ipftable; | |
| #ifdef HAVE_NETIOAPI_H | |
| MIB_IPFORWARD_TABLE2 *ipftable2; | |
| #endif | |
| }; | |
| route_t * | |
| route_open(void) | |
| { | |
| route_t *r; | |
| r = calloc(1, sizeof(route_t)); | |
| if (r == NULL) | |
| return NULL; | |
| r->iphlpapi = GetModuleHandle("iphlpapi.dll"); | |
| /* GetIpForwardTable2 + FreeMibTable are only available on Vista and later, dynamic load. */ | |
| if (r->iphlpapi) { | |
| r->p_GetIpForwardTable2 = (GETIPFORWARDTABLE2) GetProcAddress(r->iphlpapi, "GetIpForwardTable2"); | |
| r->p_FreeMibTable = (FREEMIBTABLE) GetProcAddress(r->iphlpapi, "FreeMibTable"); | |
| } | |
| return r; | |
| } | |
| int | |
| route_add(route_t *route, const struct route_entry *entry) | |
| { | |
| MIB_IPFORWARDROW ipfrow; | |
| struct addr net; | |
| memset(&ipfrow, 0, sizeof(ipfrow)); | |
| if (GetBestInterface(entry->route_gw.addr_ip, | |
| &ipfrow.dwForwardIfIndex) != NO_ERROR) | |
| return (-1); | |
| if (addr_net(&entry->route_dst, &net) < 0 || | |
| net.addr_type != ADDR_TYPE_IP) | |
| return (-1); | |
| ipfrow.dwForwardDest = net.addr_ip; | |
| addr_btom(entry->route_dst.addr_bits, | |
| &ipfrow.dwForwardMask, IP_ADDR_LEN); | |
| ipfrow.dwForwardNextHop = entry->route_gw.addr_ip; | |
| ipfrow.dwForwardType = 4; /* XXX - next hop != final dest */ | |
| ipfrow.dwForwardProto = 3; /* XXX - MIB_PROTO_NETMGMT */ | |
| if (CreateIpForwardEntry(&ipfrow) != NO_ERROR) | |
| return (-1); | |
| return (0); | |
| } | |
| int | |
| route_delete(route_t *route, const struct route_entry *entry) | |
| { | |
| MIB_IPFORWARDROW ipfrow; | |
| DWORD mask; | |
| if (entry->route_dst.addr_type != ADDR_TYPE_IP || | |
| GetBestRoute(entry->route_dst.addr_ip, | |
| IP_ADDR_ANY, &ipfrow) != NO_ERROR) | |
| return (-1); | |
| addr_btom(entry->route_dst.addr_bits, &mask, IP_ADDR_LEN); | |
| if (ipfrow.dwForwardDest != entry->route_dst.addr_ip || | |
| ipfrow.dwForwardMask != mask) { | |
| errno = ENXIO; | |
| SetLastError(ERROR_NO_DATA); | |
| return (-1); | |
| } | |
| if (DeleteIpForwardEntry(&ipfrow) != NO_ERROR) | |
| return (-1); | |
| return (0); | |
| } | |
| int | |
| route_get(route_t *route, struct route_entry *entry) | |
| { | |
| MIB_IPFORWARDROW ipfrow; | |
| DWORD mask; | |
| intf_t *intf; | |
| struct intf_entry intf_entry; | |
| if (entry->route_dst.addr_type != ADDR_TYPE_IP || | |
| GetBestRoute(entry->route_dst.addr_ip, | |
| IP_ADDR_ANY, &ipfrow) != NO_ERROR) | |
| return (-1); | |
| if (ipfrow.dwForwardProto == 2 && /* XXX - MIB_IPPROTO_LOCAL */ | |
| (ipfrow.dwForwardNextHop|IP_CLASSA_NET) != | |
| (IP_ADDR_LOOPBACK|IP_CLASSA_NET) && | |
| !IP_LOCAL_GROUP(ipfrow.dwForwardNextHop)) { | |
| errno = ENXIO; | |
| SetLastError(ERROR_NO_DATA); | |
| return (-1); | |
| } | |
| addr_btom(entry->route_dst.addr_bits, &mask, IP_ADDR_LEN); | |
| entry->route_gw.addr_type = ADDR_TYPE_IP; | |
| entry->route_gw.addr_bits = IP_ADDR_BITS; | |
| entry->route_gw.addr_ip = ipfrow.dwForwardNextHop; | |
| entry->metric = ipfrow.dwForwardMetric1; | |
| entry->intf_name[0] = '\0'; | |
| intf = intf_open(); | |
| if (intf_get_index(intf, &intf_entry, | |
| AF_INET, ipfrow.dwForwardIfIndex) == 0) { | |
| strlcpy(entry->intf_name, intf_entry.intf_name, sizeof(entry->intf_name)); | |
| } | |
| intf_close(intf); | |
| return (0); | |
| } | |
| static int | |
| route_loop_getipforwardtable(route_t *r, route_handler callback, void *arg) | |
| { | |
| struct route_entry entry; | |
| intf_t *intf; | |
| ULONG len; | |
| int i, ret; | |
| for (len = sizeof(r->ipftable[0]); ; ) { | |
| if (r->ipftable) | |
| free(r->ipftable); | |
| r->ipftable = malloc(len); | |
| if (r->ipftable == NULL) | |
| return (-1); | |
| ret = GetIpForwardTable(r->ipftable, &len, FALSE); | |
| if (ret == NO_ERROR) | |
| break; | |
| else if (ret != ERROR_INSUFFICIENT_BUFFER) | |
| return (-1); | |
| } | |
| intf = intf_open(); | |
| ret = 0; | |
| for (i = 0; i < (int)r->ipftable->dwNumEntries; i++) { | |
| struct intf_entry intf_entry; | |
| entry.route_dst.addr_type = ADDR_TYPE_IP; | |
| entry.route_dst.addr_bits = IP_ADDR_BITS; | |
| entry.route_gw.addr_type = ADDR_TYPE_IP; | |
| entry.route_gw.addr_bits = IP_ADDR_BITS; | |
| entry.route_dst.addr_ip = r->ipftable->table[i].dwForwardDest; | |
| addr_mtob(&r->ipftable->table[i].dwForwardMask, IP_ADDR_LEN, | |
| &entry.route_dst.addr_bits); | |
| entry.route_gw.addr_ip = | |
| r->ipftable->table[i].dwForwardNextHop; | |
| entry.metric = r->ipftable->table[i].dwForwardMetric1; | |
| /* Look up the interface name. */ | |
| entry.intf_name[0] = '\0'; | |
| intf_entry.intf_len = sizeof(intf_entry); | |
| if (intf_get_index(intf, &intf_entry, | |
| AF_INET, r->ipftable->table[i].dwForwardIfIndex) == 0) { | |
| strlcpy(entry.intf_name, intf_entry.intf_name, sizeof(entry.intf_name)); | |
| } | |
| if ((ret = (*callback)(&entry, arg)) != 0) | |
| break; | |
| } | |
| intf_close(intf); | |
| return ret; | |
| } | |
| #ifdef HAVE_NETIOAPI_H | |
| static int | |
| route_loop_getipforwardtable2(GETIPFORWARDTABLE2 p_GetIpForwardTable2, | |
| route_t *r, route_handler callback, void *arg) | |
| { | |
| struct route_entry entry; | |
| intf_t *intf; | |
| ULONG i; | |
| int ret; | |
| ret = (*p_GetIpForwardTable2)(AF_UNSPEC, &r->ipftable2); | |
| if (ret != NO_ERROR) | |
| return (-1); | |
| intf = intf_open(); | |
| ret = 0; | |
| for (i = 0; i < r->ipftable2->NumEntries; i++) { | |
| struct intf_entry intf_entry; | |
| MIB_IPFORWARD_ROW2 *row; | |
| MIB_IPINTERFACE_ROW ifrow; | |
| ULONG metric; | |
| row = &r->ipftable2->Table[i]; | |
| addr_ston((struct sockaddr *) &row->DestinationPrefix.Prefix, &entry.route_dst); | |
| entry.route_dst.addr_bits = row->DestinationPrefix.PrefixLength; | |
| addr_ston((struct sockaddr *) &row->NextHop, &entry.route_gw); | |
| /* Look up the interface name. */ | |
| entry.intf_name[0] = '\0'; | |
| intf_entry.intf_len = sizeof(intf_entry); | |
| if (intf_get_index(intf, &intf_entry, | |
| row->DestinationPrefix.Prefix.si_family, | |
| row->InterfaceIndex) == 0) { | |
| strlcpy(entry.intf_name, intf_entry.intf_name, sizeof(entry.intf_name)); | |
| } | |
| ifrow.Family = row->DestinationPrefix.Prefix.si_family; | |
| ifrow.InterfaceLuid = row->InterfaceLuid; | |
| ifrow.InterfaceIndex = row->InterfaceIndex; | |
| if (GetIpInterfaceEntry(&ifrow) != NO_ERROR) { | |
| return (-1); | |
| } | |
| metric = ifrow.Metric + row->Metric; | |
| if (metric < INT_MAX) | |
| entry.metric = metric; | |
| else | |
| entry.metric = INT_MAX; | |
| if ((ret = (*callback)(&entry, arg)) != 0) | |
| break; | |
| } | |
| intf_close(intf); | |
| return ret; | |
| } | |
| #endif /* HAVE_NETIOAPI_H */ | |
| int | |
| route_loop(route_t *r, route_handler callback, void *arg) | |
| { | |
| #ifdef HAVE_NETIOAPI_H | |
| if (r->p_GetIpForwardTable2) | |
| return route_loop_getipforwardtable2(r->p_GetIpForwardTable2, r, callback, arg); | |
| #endif | |
| return route_loop_getipforwardtable(r, callback, arg); | |
| } | |
| route_t * | |
| route_close(route_t *r) | |
| { | |
| if (r != NULL) { | |
| if (r->iphlpapi != NULL) | |
| FreeLibrary(r->iphlpapi); | |
| if (r->ipftable != NULL) | |
| free(r->ipftable); | |
| #ifdef HAVE_NETIOAPI_H | |
| if (r->ipftable2 != NULL && r->p_FreeMibTable) | |
| (*r->p_FreeMibTable) (r->ipftable2); | |
| #endif | |
| free(r); | |
| } | |
| return (NULL); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- a/libdnet-stripped/src/route-win32.c 2015-02-10 02:27:30 +0000 | |
| +++ b/libdnet-stripped/src/route-win32.c 2015-03-04 23:03:27 +0000 | |
| @@ -21,12 +21,25 @@ | |
| #include "dnet.h" | |
| -typedef DWORD (WINAPI *GETIPFORWARDTABLE2)(ADDRESS_FAMILY, PMIB_IPFORWARD_TABLE2 *); | |
| +#if defined(_MSC_VER) && 0 && (_WIN32_WINNT >= 0x0600) /* 0x0600 == _WIN32_WINNT_VISTA */ | |
| + #include <netioapi.h> | |
| + #define HAVE_NETIOAPI_H | |
| + | |
| + typedef DWORD (WINAPI *GETIPFORWARDTABLE2)(ADDRESS_FAMILY, PMIB_IPFORWARD_TABLE2 *); | |
| +#else | |
| + typedef DWORD (WINAPI *GETIPFORWARDTABLE2)(void *, void *); | |
| +#endif | |
| -struct route_handle { | |
| +typedef VOID (WINAPI *FREEMIBTABLE) (void *); | |
| + | |
| +struct route_handle { /* the implementation details of 'route_t' in <dnet.h> */ | |
| HINSTANCE iphlpapi; | |
| + GETIPFORWARDTABLE2 p_GetIpForwardTable2; | |
| + FREEMIBTABLE p_FreeMibTable; | |
| MIB_IPFORWARDTABLE *ipftable; | |
| +#ifdef HAVE_NETIOAPI_H | |
| MIB_IPFORWARD_TABLE2 *ipftable2; | |
| +#endif | |
| }; | |
| route_t * | |
| @@ -39,6 +52,11 @@ | |
| return NULL; | |
| r->iphlpapi = GetModuleHandle("iphlpapi.dll"); | |
| + /* GetIpForwardTable2 + FreeMibTable are only available on Vista and later, dynamic load. */ | |
| + if (r->iphlpapi) { | |
| + r->p_GetIpForwardTable2 = (GETIPFORWARDTABLE2) GetProcAddress(r->iphlpapi, "GetIpForwardTable2"); | |
| + r->p_FreeMibTable = (FREEMIBTABLE) GetProcAddress(r->iphlpapi, "FreeMibTable"); | |
| + } | |
| return r; | |
| } | |
| @@ -192,8 +210,9 @@ | |
| return ret; | |
| } | |
| +#ifdef HAVE_NETIOAPI_H | |
| static int | |
| -route_loop_getipforwardtable2(GETIPFORWARDTABLE2 GetIpForwardTable2, | |
| +route_loop_getipforwardtable2(GETIPFORWARDTABLE2 p_GetIpForwardTable2, | |
| route_t *r, route_handler callback, void *arg) | |
| { | |
| struct route_entry entry; | |
| @@ -201,7 +220,7 @@ | |
| ULONG i; | |
| int ret; | |
| - ret = GetIpForwardTable2(AF_UNSPEC, &r->ipftable2); | |
| + ret = (*p_GetIpForwardTable2)(AF_UNSPEC, &r->ipftable2); | |
| if (ret != NO_ERROR) | |
| return (-1); | |
| @@ -248,21 +267,16 @@ | |
| return ret; | |
| } | |
| +#endif /* HAVE_NETIOAPI_H */ | |
| int | |
| route_loop(route_t *r, route_handler callback, void *arg) | |
| { | |
| - GETIPFORWARDTABLE2 GetIpForwardTable2; | |
| - | |
| - /* GetIpForwardTable2 is only available on Vista and later, dynamic load. */ | |
| - GetIpForwardTable2 = NULL; | |
| - if (r->iphlpapi != NULL) | |
| - GetIpForwardTable2 = (GETIPFORWARDTABLE2) GetProcAddress(r->iphlpapi, "GetIpForwardTable2"); | |
| - | |
| - if (GetIpForwardTable2 == NULL) | |
| +#ifdef HAVE_NETIOAPI_H | |
| + if (r->p_GetIpForwardTable2) | |
| + return route_loop_getipforwardtable2(r->p_GetIpForwardTable2, r, callback, arg); | |
| +#endif | |
| return route_loop_getipforwardtable(r, callback, arg); | |
| - else | |
| - return route_loop_getipforwardtable2(GetIpForwardTable2, r, callback, arg); | |
| } | |
| route_t * | |
| @@ -273,8 +287,10 @@ | |
| FreeLibrary(r->iphlpapi); | |
| if (r->ipftable != NULL) | |
| free(r->ipftable); | |
| - if (r->ipftable2 != NULL) | |
| - FreeMibTable(r->ipftable2); | |
| +#ifdef HAVE_NETIOAPI_H | |
| + if (r->ipftable2 != NULL && r->p_FreeMibTable) | |
| + (*r->p_FreeMibTable) (r->ipftable2); | |
| +#endif | |
| free(r); | |
| } | |
| return (NULL); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment