blob: 6256e59c58ac61e05ccad9894ba54662b18a8139 [file] [log] [blame]
Benny Prijonob681a2f2007-03-25 18:44:51 +00001/* $Id$ */
2/*
3 * Copyright (C)2003-2007 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
Benny Prijonoa6bd7582007-03-28 15:49:48 +000019#include <pj/config.h>
Benny Prijonob681a2f2007-03-25 18:44:51 +000020
21#define WIN32_LEAN_AND_MEAN
22#include <windows.h>
23
Benny Prijonoa6bd7582007-03-28 15:49:48 +000024/* PMIB_ICMP_EX is not declared in VC6, causing error.
25 * But EVC4, which also claims to be VC6, does have it!
26 */
27#if defined(_MSC_VER) && _MSC_VER==1200 && !defined(PJ_WIN32_WINCE)
Benny Prijonob681a2f2007-03-25 18:44:51 +000028# define PMIB_ICMP_EX void*
29#endif
30#include <Iphlpapi.h>
31
32#include <pj/ip_helper.h>
33#include <pj/assert.h>
34#include <pj/errno.h>
35#include <pj/string.h>
36
37
38/*
39 * Enumerate the local IP interface currently active in the host.
40 */
41PJ_DEF(pj_status_t) pj_enum_ip_interface(unsigned *p_cnt,
42 pj_in_addr ifs[])
43{
44 /* Provide enough buffer or otherwise it will fail with
45 * error 22 ("Not Enough Buffer") error.
46 */
Benny Prijono6b5b6602007-03-30 18:54:46 +000047 char ipTabBuff[1024];
Benny Prijonob681a2f2007-03-25 18:44:51 +000048 MIB_IPADDRTABLE *pTab;
49 ULONG tabSize;
50 unsigned i, count;
51 DWORD rc;
52
53 PJ_ASSERT_RETURN(p_cnt && ifs, PJ_EINVAL);
54
Benny Prijono6b5b6602007-03-30 18:54:46 +000055 pTab = (MIB_IPADDRTABLE*)ipTabBuff;
Benny Prijonob681a2f2007-03-25 18:44:51 +000056
57 /* Get IP address table */
58 tabSize = sizeof(ipTabBuff);
Benny Prijono6b5b6602007-03-30 18:54:46 +000059 rc = GetIpAddrTable(pTab, &tabSize, FALSE);
Benny Prijonob681a2f2007-03-25 18:44:51 +000060 if (rc != NO_ERROR)
61 return PJ_RETURN_OS_ERROR(rc);
62
63 /* Reset result */
64 pj_bzero(ifs, sizeof(ifs[0]) * (*p_cnt));
65
66 /* Now fill out the entries */
67 count = (pTab->dwNumEntries < *p_cnt) ? pTab->dwNumEntries : *p_cnt;
Benny Prijonofed1af92007-03-27 23:29:27 +000068 *p_cnt = 0;
Benny Prijonob681a2f2007-03-25 18:44:51 +000069 for (i=0; i<count; ++i) {
Benny Prijonofed1af92007-03-27 23:29:27 +000070 /* Some Windows returns 0.0.0.0! */
71 if (pTab->table[i].dwAddr == 0)
72 continue;
73 ifs[*p_cnt].s_addr = pTab->table[i].dwAddr;
74 (*p_cnt)++;
Benny Prijonob681a2f2007-03-25 18:44:51 +000075 }
76
Benny Prijonob681a2f2007-03-25 18:44:51 +000077 return PJ_SUCCESS;
78
79}
80
81
82/*
83 * Enumerate the IP routing table for this host.
84 */
85PJ_DEF(pj_status_t) pj_enum_ip_route(unsigned *p_cnt,
86 pj_ip_route_entry routes[])
87{
Benny Prijono6b5b6602007-03-30 18:54:46 +000088 char ipTabBuff[1024];
Benny Prijonob681a2f2007-03-25 18:44:51 +000089 MIB_IPADDRTABLE *pIpTab;
Benny Prijono6b5b6602007-03-30 18:54:46 +000090 char rtabBuff[1024];
Benny Prijonob681a2f2007-03-25 18:44:51 +000091 MIB_IPFORWARDTABLE *prTab;
92 ULONG tabSize;
93 unsigned i, count;
94 DWORD rc;
95
96 PJ_ASSERT_RETURN(p_cnt && routes, PJ_EINVAL);
97
Benny Prijono6b5b6602007-03-30 18:54:46 +000098 pIpTab = (MIB_IPADDRTABLE *)ipTabBuff;
99 prTab = (MIB_IPFORWARDTABLE *)rtabBuff;
Benny Prijonob681a2f2007-03-25 18:44:51 +0000100
101 /* First get IP address table */
102 tabSize = sizeof(ipTabBuff);
Benny Prijono6b5b6602007-03-30 18:54:46 +0000103 rc = GetIpAddrTable(pIpTab, &tabSize, FALSE);
Benny Prijonob681a2f2007-03-25 18:44:51 +0000104 if (rc != NO_ERROR)
105 return PJ_RETURN_OS_ERROR(rc);
106
107 /* Next get IP route table */
108 tabSize = sizeof(rtabBuff);
Benny Prijono6b5b6602007-03-30 18:54:46 +0000109 rc = GetIpForwardTable(prTab, &tabSize, 1);
Benny Prijonob681a2f2007-03-25 18:44:51 +0000110 if (rc != NO_ERROR)
111 return PJ_RETURN_OS_ERROR(rc);
112
113 /* Reset routes */
114 pj_bzero(routes, sizeof(routes[0]) * (*p_cnt));
115
116 /* Now fill out the route entries */
117 count = (prTab->dwNumEntries < *p_cnt) ? prTab->dwNumEntries : *p_cnt;
118 *p_cnt = 0;
119 for (i=0; i<count; ++i) {
120 unsigned j;
121
122 /* Find interface entry */
123 for (j=0; j<pIpTab->dwNumEntries; ++j) {
124 if (pIpTab->table[j].dwIndex == prTab->table[i].dwForwardIfIndex)
125 break;
126 }
127
128 if (j==pIpTab->dwNumEntries)
129 continue; /* Interface not found */
130
131 routes[*p_cnt].ipv4.if_addr.s_addr = pIpTab->table[j].dwAddr;
132 routes[*p_cnt].ipv4.dst_addr.s_addr = prTab->table[i].dwForwardDest;
133 routes[*p_cnt].ipv4.mask.s_addr = prTab->table[i].dwForwardMask;
134
135 (*p_cnt)++;
136 }
137
138 return PJ_SUCCESS;
139}
140
141
142